Mercurial > mplayer.hg
annotate libmpdemux/demux_avi.c @ 35418:cedb0ba2b5c6
Move the code to set guiInfo's Track, Chapter and Angle start values.
Set them before checking whether there is any media opened, because
with no media opened we clear the counters.
author | ib |
---|---|
date | Thu, 29 Nov 2012 14:11:03 +0000 |
parents | 1c991ec0e6da |
children | 92dd1764392a |
rev | line source |
---|---|
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
1 /* |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
2 * AVI file parser for DEMUXER v2.9 |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
3 * Copyright (c) 2001 A'rpi/ESP-team |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
4 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
5 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
6 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
7 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
10 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
11 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
12 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
15 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
16 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
17 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
18 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28189
diff
changeset
|
20 */ |
1 | 21 |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
22 #include <stdio.h> |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
23 #include <stdlib.h> |
1430 | 24 #include <unistd.h> |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
25 |
1567 | 26 #include "config.h" |
27 #include "mp_msg.h" | |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
28 #include "help_mp.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
29 |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
22148
diff
changeset
|
30 #include "stream/stream.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
31 #include "demuxer.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
32 #include "stheader.h" |
30585
2ed1972eb23b
Add header for demux_ogg_open, init_avi_with_ogg; avoids forward declarations.
diego
parents:
30581
diff
changeset
|
33 #include "demux_ogg.h" |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
34 #include "aviheader.h" |
1 | 35 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25200
diff
changeset
|
36 extern const demuxer_desc_t demuxer_desc_avi_ni; |
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25200
diff
changeset
|
37 extern const demuxer_desc_t demuxer_desc_avi_nini; |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
38 |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
39 // PTS: 0=interleaved 1=BPS-based |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
40 int pts_from_bps=1; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
41 |
32535
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
42 static void update_audio_block_size(demuxer_t *demux) |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
43 { |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
44 avi_priv_t *priv = demux->priv; |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
45 sh_audio_t *sh = demux->audio->sh; |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
46 if (!sh) |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
47 return; |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
48 priv->audio_block_size = sh->audio.dwSampleSize; |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
49 if (sh->wf) { |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
50 priv->audio_block_size = sh->wf->nBlockAlign; |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
51 if (!priv->audio_block_size) { |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
52 // for PCM audio we can calculate the blocksize: |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
53 if (sh->format == 1) |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
54 priv->audio_block_size = sh->wf->nChannels*(sh->wf->wBitsPerSample/8); |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
55 else |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
56 priv->audio_block_size = 1; // hope the best... |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
57 } else { |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
58 // workaround old mencoder bug: |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
59 if (sh->audio.dwSampleSize == 1 && sh->audio.dwScale == 1 && |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
60 (sh->wf->nBlockAlign == 1152 || sh->wf->nBlockAlign == 576)) { |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
61 mp_msg(MSGT_DEMUX, MSGL_WARN, MSGTR_WorkAroundBlockAlignHeaderBug); |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
62 priv->audio_block_size = 1; |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
63 } |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
64 } |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
65 } |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
66 } |
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
67 |
1 | 68 // Select ds from ID |
30570
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
69 static demux_stream_t *demux_avi_select_stream(demuxer_t *demux, |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
70 unsigned int id) |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
71 { |
1 | 72 int stream_id=avi_stream_id(id); |
426 | 73 |
74 | |
75 if(demux->video->id==-1) | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
76 if(demux->v_streams[stream_id]) |
426 | 77 demux->video->id=stream_id; |
78 | |
79 if(demux->audio->id==-1) | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
80 if(demux->a_streams[stream_id]) |
426 | 81 demux->audio->id=stream_id; |
82 | |
83 if(stream_id==demux->audio->id){ | |
84 if(!demux->audio->sh){ | |
32535
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
85 demux->audio->sh=demux->a_streams[stream_id]; |
1567 | 86 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected AVI audio ID = %d\n",demux->audio->id); |
32535
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
87 update_audio_block_size(demux); |
426 | 88 } |
89 return demux->audio; | |
90 } | |
91 if(stream_id==demux->video->id){ | |
92 if(!demux->video->sh){ | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
93 demux->video->sh=demux->v_streams[stream_id]; |
1567 | 94 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected AVI video ID = %d\n",demux->video->id); |
426 | 95 } |
96 return demux->video; | |
97 } | |
1 | 98 if(id!=mmioFOURCC('J','U','N','K')){ |
99 // unknown | |
1998 | 100 mp_msg(MSGT_DEMUX,MSGL_DBG2,"Unknown chunk: %.4s (%X)\n",(char *) &id,id); |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
101 //abort(); |
1 | 102 } |
103 return NULL; | |
104 } | |
105 | |
2438 | 106 static int valid_fourcc(unsigned int id){ |
20400
f4518826ea84
Allow lowercase letters in AVI stream id, fixes bug #277
reimar
parents:
20337
diff
changeset
|
107 static const char valid[] = "0123456789abcdefghijklmnopqrstuvwxyz" |
f4518826ea84
Allow lowercase letters in AVI stream id, fixes bug #277
reimar
parents:
20337
diff
changeset
|
108 "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; |
2438 | 109 unsigned char* fcc=(unsigned char*)(&id); |
20400
f4518826ea84
Allow lowercase letters in AVI stream id, fixes bug #277
reimar
parents:
20337
diff
changeset
|
110 return strchr(valid, fcc[0]) && strchr(valid, fcc[1]) && |
f4518826ea84
Allow lowercase letters in AVI stream id, fixes bug #277
reimar
parents:
20337
diff
changeset
|
111 strchr(valid, fcc[2]) && strchr(valid, fcc[3]); |
2438 | 112 } |
113 | |
29871 | 114 static int valid_stream_id(unsigned int id) { |
115 unsigned char* fcc=(unsigned char*)(&id); | |
116 return fcc[0] >= '0' && fcc[0] <= '9' && fcc[1] >= '0' && fcc[1] <= '9' && | |
117 ((fcc[2] == 'w' && fcc[3] == 'b') || (fcc[2] == 'd' && fcc[3] == 'c')); | |
118 } | |
119 | |
2438 | 120 static int choose_chunk_len(unsigned int len1,unsigned int len2){ |
121 // len1 has a bit more priority than len2. len1!=len2 | |
122 // Note: this is a first-idea-logic, may be wrong. comments welcomed. | |
123 | |
124 // prefer small frames rather than 0 | |
125 if(!len1) return (len2>0x80000) ? len1 : len2; | |
126 if(!len2) return (len1>0x100000) ? len2 : len1; | |
127 | |
128 // choose the smaller value: | |
129 return (len1<len2)? len1 : len2; | |
130 } | |
131 | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
132 static int demux_avi_read_packet(demuxer_t *demux,demux_stream_t *ds,unsigned int id,unsigned int len,int idxpos,int flags){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
133 avi_priv_t *priv=demux->priv; |
1 | 134 int skip; |
135 float pts=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
136 |
1567 | 137 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_avi.read_packet: %X\n",id); |
1 | 138 |
139 if(ds==demux->audio){ | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
140 if(priv->pts_corrected==0){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
141 if(priv->pts_has_video){ |
1455 | 142 // we have video pts now |
2826 | 143 float delay=0; |
144 if(((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec) | |
145 delay=(float)priv->pts_corr_bytes/((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec; | |
1567 | 146 mp_msg(MSGT_DEMUX,MSGL_V,"XXX initial v_pts=%5.3f a_pos=%d (%5.3f) \n",priv->avi_audio_pts,priv->pts_corr_bytes,delay); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
147 //priv->pts_correction=-priv->avi_audio_pts+delay; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
148 priv->pts_correction=delay-priv->avi_audio_pts; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
149 priv->avi_audio_pts+=priv->pts_correction; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
150 priv->pts_corrected=1; |
1455 | 151 } else |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
152 priv->pts_corr_bytes+=len; |
1455 | 153 } |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
154 if(pts_from_bps){ |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
155 pts = priv->audio_block_no * |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
156 (float)((sh_audio_t*)demux->audio->sh)->audio.dwScale / |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
157 (float)((sh_audio_t*)demux->audio->sh)->audio.dwRate; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
158 } else |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
159 pts=priv->avi_audio_pts; //+priv->pts_correction; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
160 priv->avi_audio_pts=0; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
161 // update blockcount: |
32536
187f26cba0ce
If audio_block_size is 0 that is a bug (and will result in a division by 0
reimar
parents:
32535
diff
changeset
|
162 priv->audio_block_no+= |
187f26cba0ce
If audio_block_size is 0 that is a bug (and will result in a division by 0
reimar
parents:
32535
diff
changeset
|
163 (len+priv->audio_block_size-1)/priv->audio_block_size; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
164 } else |
1409 | 165 if(ds==demux->video){ |
1 | 166 // video |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
167 if(priv->skip_video_frames>0){ |
1 | 168 // drop frame (seeking) |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
169 --priv->skip_video_frames; |
1 | 170 ds=NULL; |
171 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
172 |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
173 pts = priv->avi_video_pts = priv->video_pack_no * |
1368 | 174 (float)((sh_video_t*)demux->video->sh)->video.dwScale / |
175 (float)((sh_video_t*)demux->video->sh)->video.dwRate; | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
176 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
177 priv->avi_audio_pts=priv->avi_video_pts+priv->pts_correction; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
178 priv->pts_has_video=1; |
1455 | 179 |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
180 if(ds) ++priv->video_pack_no; |
1498 | 181 |
1 | 182 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
183 |
1 | 184 skip=(len+1)&(~1); // total bytes in this chunk |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
185 |
1 | 186 if(ds){ |
1567 | 187 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Read %d data bytes from packet %04X\n",len,id); |
979 | 188 ds_read_packet(ds,demux->stream,len,pts,idxpos,flags); |
1 | 189 skip-=len; |
190 } | |
28189
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
191 skip = FFMAX(skip, 0); |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
192 if (avi_stream_id(id) > 99 && id != mmioFOURCC('J','U','N','K')) |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
193 skip = FFMIN(skip, 65536); |
1 | 194 if(skip){ |
1567 | 195 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Skipping %d bytes from packet %04X\n",skip,id); |
1 | 196 stream_skip(demux->stream,skip); |
197 } | |
198 return ds?1:0; | |
199 } | |
200 | |
28189
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
201 static uint32_t avi_find_id(stream_t *stream) { |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
202 uint32_t id = stream_read_dword_le(stream); |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
203 if (!id) { |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
204 mp_msg(MSGT_DEMUX, MSGL_WARN, "Incomplete stream? Trying resync.\n"); |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
205 do { |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
206 id = stream_read_dword_le(stream); |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
207 if (stream_eof(stream)) return 0; |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
208 } while (avi_stream_id(id) > 99); |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
209 } |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
210 return id; |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
211 } |
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
212 |
35404
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
213 static void switch_to_ni(demuxer_t *demux) { |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
214 avi_priv_t *priv=demux->priv; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
215 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_SwitchToNi); |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
216 if(priv->idx_size>0){ |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
217 // has index |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
218 demux->type=DEMUXER_TYPE_AVI_NI; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
219 demux->desc=&demuxer_desc_avi_ni; |
35406 | 220 if (priv->idx_pos > 0) |
221 --priv->idx_pos; // hack | |
35404
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
222 } else { |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
223 // no index |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
224 demux->type=DEMUXER_TYPE_AVI_NINI; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
225 demux->desc=&demuxer_desc_avi_nini; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
226 priv->idx_pos=demux->filepos; // hack |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
227 } |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
228 priv->idx_pos_v=priv->idx_pos_a=priv->idx_pos; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
229 } |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
230 |
1 | 231 // return value: |
232 // 0 = EOF or no stream found | |
233 // 1 = successfully read a packet | |
16175 | 234 static int demux_avi_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
235 avi_priv_t *priv=demux->priv; |
1 | 236 unsigned int id=0; |
237 unsigned int len; | |
238 int ret=0; | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
239 demux_stream_t *ds; |
1 | 240 |
241 do{ | |
9228 | 242 int flags=1; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
243 if(priv->idx_size>0 && priv->idx_pos<priv->idx_size){ |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
244 off_t pos; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
245 |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
246 AVIINDEXENTRY *idx = priv->idx + priv->idx_pos++; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
247 |
1 | 248 if(idx->dwFlags&AVIIF_LIST){ |
29871 | 249 if (!valid_stream_id(idx->ckid)) |
1 | 250 // LIST |
251 continue; | |
29871 | 252 if (!priv->warned_unaligned) |
253 mp_msg(MSGT_DEMUX, MSGL_WARN, "Looks like unaligned chunk in index, broken AVI file!\n"); | |
254 priv->warned_unaligned = 1; | |
1 | 255 } |
256 if(!demux_avi_select_stream(demux,idx->ckid)){ | |
1567 | 257 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid); |
1 | 258 continue; // skip this chunk |
259 } | |
260 | |
12036 | 261 pos = (off_t)priv->idx_offset+AVI_IDX_OFFSET(idx); |
29920
4f740437ed2b
Finally rename the STREAM_SEEK define to MP_STREAM_SEEK, there are just too many
reimar
parents:
29872
diff
changeset
|
262 if((pos<demux->movi_start || pos>=demux->movi_end) && (demux->movi_end>demux->movi_start) && (demux->stream->flags & MP_STREAM_SEEK)){ |
17366 | 263 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkOffset out of range! idx=0x%"PRIX64" \n",(int64_t)pos); |
1 | 264 continue; |
265 } | |
266 stream_seek(demux->stream,pos); | |
1421 | 267 demux->filepos=stream_tell(demux->stream); |
1 | 268 id=stream_read_dword_le(demux->stream); |
1421 | 269 if(stream_eof(demux->stream)) return 0; // EOF! |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
270 |
1 | 271 if(id!=idx->ckid){ |
1567 | 272 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); |
2438 | 273 if(valid_fourcc(idx->ckid)) |
274 id=idx->ckid; // use index if valid | |
275 else | |
276 if(!valid_fourcc(id)) continue; // drop chunk if both id and idx bad | |
1 | 277 } |
278 len=stream_read_dword_le(demux->stream); | |
279 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ | |
17366 | 280 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%d \n",len,idx->dwChunkLength); |
2438 | 281 if(len>0x200000 && idx->dwChunkLength>0x200000) continue; // both values bad :( |
282 len=choose_chunk_len(idx->dwChunkLength,len); | |
1 | 283 } |
9228 | 284 if(!(idx->dwFlags&AVIIF_KEYFRAME)) flags=0; |
1 | 285 } else { |
1421 | 286 demux->filepos=stream_tell(demux->stream); |
29920
4f740437ed2b
Finally rename the STREAM_SEEK define to MP_STREAM_SEEK, there are just too many
reimar
parents:
29872
diff
changeset
|
287 if(demux->filepos>=demux->movi_end && demux->movi_end>demux->movi_start && (demux->stream->flags & MP_STREAM_SEEK)){ |
1421 | 288 demux->stream->eof=1; |
289 return 0; | |
290 } | |
28189
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
291 id=avi_find_id(demux->stream); |
1 | 292 len=stream_read_dword_le(demux->stream); |
1421 | 293 if(stream_eof(demux->stream)) return 0; // EOF! |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
294 |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
295 if(id==mmioFOURCC('L','I','S','T') || id==mmioFOURCC('R', 'I', 'F', 'F')){ |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
296 id=stream_read_dword_le(demux->stream); // list or RIFF type |
1 | 297 continue; |
298 } | |
299 } | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
300 |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
301 ds=demux_avi_select_stream(demux,id); |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
302 if(ds) |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
303 if(ds->packs+1>=MAX_PACKS || ds->bytes+len>=MAX_PACK_BYTES){ |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
304 // this packet will cause a buffer overflow, switch to -ni mode!!! |
35404
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
305 switch_to_ni(demux); |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
306 // quit now, we can't even (no enough buffer memory) read this packet :( |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
307 return -1; |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
308 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
309 |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
310 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,flags); |
1 | 311 } while(ret!=1); |
312 return 1; | |
313 } | |
314 | |
315 | |
316 // return value: | |
317 // 0 = EOF or no stream found | |
318 // 1 = successfully read a packet | |
30570
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
319 static int demux_avi_fill_buffer_ni(demuxer_t *demux, demux_stream_t *ds) |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
320 { |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
321 avi_priv_t *priv=demux->priv; |
1 | 322 unsigned int id=0; |
323 unsigned int len; | |
324 int ret=0; | |
325 | |
326 do{ | |
9228 | 327 int flags=1; |
1 | 328 int idx_pos=0; |
329 demux->filepos=stream_tell(demux->stream); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
330 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
331 if(ds==demux->video) idx_pos=priv->idx_pos_v++; else |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
332 if(ds==demux->audio) idx_pos=priv->idx_pos_a++; else |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
333 idx_pos=priv->idx_pos++; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
334 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
335 if(priv->idx_size>0 && idx_pos<priv->idx_size){ |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
336 off_t pos; |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
337 AVIINDEXENTRY *idx = priv->idx + idx_pos; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
338 |
1 | 339 if(idx->dwFlags&AVIIF_LIST){ |
29871 | 340 if (!valid_stream_id(idx->ckid)) |
1 | 341 // LIST |
342 continue; | |
29871 | 343 if (!priv->warned_unaligned) |
344 mp_msg(MSGT_DEMUX, MSGL_WARN, "Looks like unaligned chunk in index, broken AVI file!\n"); | |
345 priv->warned_unaligned = 1; | |
1 | 346 } |
347 if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){ | |
1567 | 348 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid); |
1 | 349 continue; // skip this chunk |
350 } | |
351 | |
12036 | 352 pos = priv->idx_offset+AVI_IDX_OFFSET(idx); |
2439
022a7e7fec2d
while_encoding.avi (ffmpeg) fix (ignoring movi_ check if end<=start)
arpi
parents:
2438
diff
changeset
|
353 if((pos<demux->movi_start || pos>=demux->movi_end) && (demux->movi_end>demux->movi_start)){ |
17366 | 354 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkOffset out of range! current=0x%"PRIX64" idx=0x%"PRIX64" \n",(int64_t)demux->filepos,(int64_t)pos); |
1 | 355 continue; |
356 } | |
357 stream_seek(demux->stream,pos); | |
358 | |
359 id=stream_read_dword_le(demux->stream); | |
360 | |
361 if(stream_eof(demux->stream)) return 0; | |
362 | |
363 if(id!=idx->ckid){ | |
1567 | 364 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); |
2438 | 365 if(valid_fourcc(idx->ckid)) |
366 id=idx->ckid; // use index if valid | |
367 else | |
368 if(!valid_fourcc(id)) continue; // drop chunk if both id and idx bad | |
1 | 369 } |
370 len=stream_read_dword_le(demux->stream); | |
371 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ | |
17366 | 372 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%d \n",len,idx->dwChunkLength); |
2438 | 373 if(len>0x200000 && idx->dwChunkLength>0x200000) continue; // both values bad :( |
374 len=choose_chunk_len(idx->dwChunkLength,len); | |
1 | 375 } |
9228 | 376 if(!(idx->dwFlags&AVIIF_KEYFRAME)) flags=0; |
1 | 377 } else return 0; |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
378 ret=demux_avi_read_packet(demux,demux_avi_select_stream(demux,id),id,len,idx_pos,flags); |
1 | 379 } while(ret!=1); |
380 return 1; | |
381 } | |
382 | |
383 | |
384 // return value: | |
385 // 0 = EOF or no stream found | |
386 // 1 = successfully read a packet | |
30570
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
387 static int demux_avi_fill_buffer_nini(demuxer_t *demux, demux_stream_t *ds) |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
388 { |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
389 avi_priv_t *priv=demux->priv; |
1 | 390 unsigned int id=0; |
391 unsigned int len; | |
392 int ret=0; | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
393 off_t *fpos=NULL; |
1 | 394 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
395 if(ds==demux->video) fpos=&priv->idx_pos_v; else |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
396 if(ds==demux->audio) fpos=&priv->idx_pos_a; else |
1 | 397 return 0; |
398 | |
399 stream_seek(demux->stream,fpos[0]); | |
400 | |
401 do{ | |
402 | |
403 demux->filepos=stream_tell(demux->stream); | |
2439
022a7e7fec2d
while_encoding.avi (ffmpeg) fix (ignoring movi_ check if end<=start)
arpi
parents:
2438
diff
changeset
|
404 if(demux->filepos>=demux->movi_end && (demux->movi_end>demux->movi_start)){ |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
405 ds->eof=1; |
1 | 406 return 0; |
407 } | |
408 | |
28189
dd53119e77c8
Make AVI demuxer more resilient against broken or incomplete files.
reimar
parents:
28051
diff
changeset
|
409 id=avi_find_id(demux->stream); |
1 | 410 len=stream_read_dword_le(demux->stream); |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
411 |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
412 if(stream_eof(demux->stream)) return 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
413 |
1 | 414 if(id==mmioFOURCC('L','I','S','T')){ |
415 id=stream_read_dword_le(demux->stream); // list type | |
416 continue; | |
417 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
418 |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
419 if(id==mmioFOURCC('R','I','F','F')){ |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
420 mp_msg(MSGT_DEMUX,MSGL_V,"additional RIFF header...\n"); |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
421 id=stream_read_dword_le(demux->stream); // "AVIX" |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
422 continue; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
423 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
424 |
1 | 425 if(ds==demux_avi_select_stream(demux,id)){ |
426 // read it! | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
427 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,0); |
1 | 428 } else { |
429 // skip it! | |
430 int skip=(len+1)&(~1); // total bytes in this chunk | |
431 stream_skip(demux->stream,skip); | |
432 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
433 |
1 | 434 } while(ret!=1); |
435 fpos[0]=stream_tell(demux->stream); | |
436 return 1; | |
437 } | |
438 | |
2314 | 439 // AVI demuxer parameters: |
25932 | 440 int index_mode=-1; // -1=untouched 0=don't use index 1=use (generate) index |
11234
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
10709
diff
changeset
|
441 char *index_file_save = NULL, *index_file_load = NULL; |
2314 | 442 int force_ni=0; // force non-interleaved AVI parsing |
443 | |
35404
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
444 static int try_ds_fill(demuxer_t *demux, demux_stream_t *ds) { |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
445 int is_ni = demux->type != DEMUXER_TYPE_AVI; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
446 if (ds_fill_buffer(ds)) |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
447 return 1; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
448 if (is_ni) |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
449 return 0; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
450 switch_to_ni(demux); |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
451 ds->eof = 0; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
452 ds->fill_count = 0; |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
453 return ds_fill_buffer(ds); |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
454 } |
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
455 |
16175 | 456 static demuxer_t* demux_open_avi(demuxer_t* demuxer){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
457 demux_stream_t *d_audio=demuxer->audio; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
458 demux_stream_t *d_video=demuxer->video; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
459 sh_audio_t *sh_audio=NULL; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
460 sh_video_t *sh_video=NULL; |
29872
76e81f47bce2
Use calloc instead of initializing each struct member individually to 0.
reimar
parents:
29871
diff
changeset
|
461 avi_priv_t* priv=calloc(1, sizeof(avi_priv_t)); |
12036 | 462 |
35407 | 463 demuxer->priv=priv; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
464 |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
465 //---- AVI header: |
29920
4f740437ed2b
Finally rename the STREAM_SEEK define to MP_STREAM_SEEK, there are just too many
reimar
parents:
29872
diff
changeset
|
466 read_avi_header(demuxer,(demuxer->stream->flags & MP_STREAM_SEEK_BW)?index_mode:-2); |
32535
6320065226a6
Fix possible division by 0 if -aid is used for AVI files.
reimar
parents:
31856
diff
changeset
|
467 update_audio_block_size(demuxer); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
468 |
7501 | 469 if(demuxer->audio->id>=0 && !demuxer->a_streams[demuxer->audio->id]){ |
20695 | 470 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamNosound,demuxer->audio->id); |
7501 | 471 demuxer->audio->id=-2; // disabled |
472 } | |
473 if(demuxer->video->id>=0 && !demuxer->v_streams[demuxer->video->id]){ | |
20695 | 474 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamUsingDefault,demuxer->video->id); |
7501 | 475 demuxer->video->id=-1; // autodetect |
476 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
477 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
478 stream_reset(demuxer->stream); |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
479 stream_seek(demuxer->stream,demuxer->movi_start); |
4665 | 480 if(priv->idx_size>1){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
481 // decide index format: |
4665 | 482 #if 1 |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
483 if((AVI_IDX_OFFSET(priv->idx + 0)<demuxer->movi_start || |
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
484 AVI_IDX_OFFSET(priv->idx + 1)<demuxer->movi_start )&& !priv->isodml) |
4665 | 485 priv->idx_offset=demuxer->movi_start-4; |
486 #else | |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
487 if(AVI_IDX_OFFSET(priv->idx)<demuxer->movi_start) |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
488 priv->idx_offset=demuxer->movi_start-4; |
4665 | 489 #endif |
490 mp_msg(MSGT_DEMUX,MSGL_V,"AVI index offset: 0x%X (movi=0x%X idx0=0x%X idx1=0x%X)\n", | |
491 (int)priv->idx_offset,(int)demuxer->movi_start, | |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
492 (int)priv->idx[0].dwChunkOffset, |
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
493 (int)priv->idx[1].dwChunkOffset); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
494 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
495 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
496 if(priv->idx_size>0){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
497 // check that file is non-interleaved: |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
498 int i; |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
499 off_t a_pos=-1; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
500 off_t v_pos=-1; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
501 for(i=0;i<priv->idx_size;i++){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
502 AVIINDEXENTRY *idx = priv->idx + i; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
503 demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid); |
12036 | 504 off_t pos = priv->idx_offset + AVI_IDX_OFFSET(idx); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
505 if(a_pos==-1 && ds==demuxer->audio){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
506 a_pos=pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
507 if(v_pos!=-1) break; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
508 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
509 if(v_pos==-1 && ds==demuxer->video){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
510 v_pos=pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
511 if(a_pos!=-1) break; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
512 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
513 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
514 if(v_pos==-1){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
515 mp_msg(MSGT_DEMUX,MSGL_ERR,"AVI_NI: " MSGTR_MissingVideoStream); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
516 return NULL; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
517 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
518 if(a_pos==-1){ |
20337
fccb66884d60
Avoid crash after "AVI: No audio stream found -> no sound." message,
reimar
parents:
20246
diff
changeset
|
519 d_audio->sh=sh_audio=NULL; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
520 } else { |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
521 if(force_ni || abs(a_pos-v_pos)>0x100000){ // distance > 1MB |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
522 mp_msg(MSGT_DEMUX,MSGL_INFO,MSGTR_NI_Message,force_ni?MSGTR_NI_Forced:MSGTR_NI_Detected); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
523 demuxer->type=DEMUXER_TYPE_AVI_NI; // HACK!!!! |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
524 demuxer->desc=&demuxer_desc_avi_ni; // HACK!!!! |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
525 pts_from_bps=1; // force BPS sync! |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
526 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
527 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
528 } else { |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
529 // no index |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
530 if(force_ni){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
531 mp_msg(MSGT_DEMUX,MSGL_INFO,MSGTR_UsingNINI); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
532 demuxer->type=DEMUXER_TYPE_AVI_NINI; // HACK!!!! |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
533 demuxer->desc=&demuxer_desc_avi_nini; // HACK!!!! |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
534 priv->idx_pos_a= |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
535 priv->idx_pos_v=demuxer->movi_start; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
536 pts_from_bps=1; // force BPS sync! |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
537 } |
1623
5908dd344067
added demuxer->seekable flag to generalize seeking ability test
arpi
parents:
1567
diff
changeset
|
538 demuxer->seekable=0; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
539 } |
35404
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
540 if(!try_ds_fill(demuxer, d_video)){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
541 mp_msg(MSGT_DEMUX,MSGL_ERR,"AVI: " MSGTR_MissingVideoStreamBug); |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
542 return NULL; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
543 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
544 sh_video=d_video->sh;sh_video->ds=d_video; |
1496 | 545 if(d_audio->id!=-2){ |
1567 | 546 mp_msg(MSGT_DEMUX,MSGL_V,"AVI: Searching for audio stream (id:%d)\n",d_audio->id); |
35404
0ab323ecb781
AVI: when we cannot find packets for video or audio stream,
reimar
parents:
32536
diff
changeset
|
547 if(!priv->audio_streams || !try_ds_fill(demuxer, d_audio)){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
548 mp_msg(MSGT_DEMUX,MSGL_INFO,"AVI: " MSGTR_MissingAudioStream); |
20337
fccb66884d60
Avoid crash after "AVI: No audio stream found -> no sound." message,
reimar
parents:
20246
diff
changeset
|
549 d_audio->sh=sh_audio=NULL; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
550 } else { |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
551 sh_audio=d_audio->sh;sh_audio->ds=d_audio; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
552 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
553 } |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
554 |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
555 // calculating audio/video bitrate: |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
556 if(priv->idx_size>0){ |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
557 // we have index, let's count 'em! |
30538 | 558 AVIINDEXENTRY *idx = priv->idx; |
18393
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
559 int64_t vsize=0; |
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
560 int64_t asize=0; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
561 size_t vsamples=0; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
562 size_t asamples=0; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
563 int i; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
564 for(i=0;i<priv->idx_size;i++){ |
30538 | 565 int id=avi_stream_id(idx[i].ckid); |
30542
4995c42045c9
Make len unsigned. More correct anyway and avoids sign extension to 64 bit
reimar
parents:
30538
diff
changeset
|
566 unsigned len=idx[i].dwChunkLength; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
567 if(sh_video->ds->id == id) { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
568 vsize+=len; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
569 ++vsamples; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
570 } |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
571 else if(sh_audio && sh_audio->ds->id == id) { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
572 asize+=len; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
573 asamples+=(len+priv->audio_block_size-1)/priv->audio_block_size; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
574 } |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
575 } |
31856
7b02012e9581
Add 'z' length modifier to %d printf format specifiers for size_t arguments.
diego
parents:
30937
diff
changeset
|
576 mp_msg(MSGT_DEMUX, MSGL_V, |
7b02012e9581
Add 'z' length modifier to %d printf format specifiers for size_t arguments.
diego
parents:
30937
diff
changeset
|
577 "AVI video size=%"PRId64" (%zu) audio size=%"PRId64" (%zu)\n", |
7b02012e9581
Add 'z' length modifier to %d printf format specifiers for size_t arguments.
diego
parents:
30937
diff
changeset
|
578 vsize, vsamples, asize, asamples); |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
579 priv->numberofframes=vsamples; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
580 sh_video->i_bps=((float)vsize/(float)vsamples)*(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
581 if(sh_audio) sh_audio->i_bps=((float)asize/(float)asamples)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
582 } else { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
583 // guessing, results may be inaccurate: |
18393
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
584 int64_t vsize; |
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
585 int64_t asize=0; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
586 |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
587 if((priv->numberofframes=sh_video->video.dwLength)<=1) |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
588 // bad video header, try to get number of frames from audio |
8646 | 589 if(sh_audio && sh_audio->wf->nAvgBytesPerSec) priv->numberofframes=sh_video->fps*sh_audio->audio.dwLength/sh_audio->audio.dwRate*sh_audio->audio.dwScale; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
590 if(priv->numberofframes<=1){ |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
591 mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo); |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
592 priv->numberofframes=0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
593 } |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
594 |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
595 if(sh_audio){ |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
596 if(sh_audio->wf->nAvgBytesPerSec && sh_audio->audio.dwSampleSize!=1){ |
8646 | 597 asize=(float)sh_audio->wf->nAvgBytesPerSec*sh_audio->audio.dwLength*sh_audio->audio.dwScale/sh_audio->audio.dwRate; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
598 } else { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
599 asize=sh_audio->audio.dwLength; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
600 sh_audio->i_bps=(float)asize/(sh_video->frametime*priv->numberofframes); |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
601 } |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
602 } |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
603 vsize=demuxer->movi_end-demuxer->movi_start-asize-8*priv->numberofframes; |
18393
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
604 mp_msg(MSGT_DEMUX,MSGL_V,"AVI video size=%"PRId64" (%u) audio size=%"PRId64"\n",vsize,priv->numberofframes,asize); |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
605 sh_video->i_bps=(float)vsize/(sh_video->frametime*priv->numberofframes); |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
606 } |
17643 | 607 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
608 return demuxer; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
609 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
610 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
611 |
1 | 612 |
30570
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
613 static void demux_seek_avi(demuxer_t *demuxer, float rel_seek_secs, |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
614 float audio_delay, int flags) |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
615 { |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
616 avi_priv_t *priv=demuxer->priv; |
1466 | 617 demux_stream_t *d_audio=demuxer->audio; |
618 demux_stream_t *d_video=demuxer->video; | |
619 sh_audio_t *sh_audio=d_audio->sh; | |
620 sh_video_t *sh_video=d_video->sh; | |
621 float skip_audio_secs=0; | |
622 | |
623 //FIXME: OFF_T - Didn't check AVI case yet (avi files can't be >2G anyway?) | |
624 //================= seek in AVI ========================== | |
625 int rel_seek_frames=rel_seek_secs*sh_video->fps; | |
626 int video_chunk_pos=d_video->pos; | |
627 int i; | |
1628
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
628 |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
629 if(flags&SEEK_ABSOLUTE){ |
1628
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
630 // seek absolute |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
631 video_chunk_pos=0; |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
632 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
633 |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25707
diff
changeset
|
634 if(flags&SEEK_FACTOR){ |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
635 rel_seek_frames=rel_seek_secs*priv->numberofframes; |
1628
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
636 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
637 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
638 priv->skip_video_frames=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
639 priv->avi_audio_pts=0; |
1466 | 640 |
1481 | 641 // ------------ STEP 1: find nearest video keyframe chunk ------------ |
1466 | 642 // find nearest video keyframe chunk pos: |
643 if(rel_seek_frames>0){ | |
644 // seek forward | |
7002
518faaa2aee4
corrects an off-by-one error when trying to seek beyond the end of file.
arpi
parents:
6884
diff
changeset
|
645 while(video_chunk_pos<priv->idx_size-1){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
646 int id=priv->idx[video_chunk_pos].ckid; |
1466 | 647 if(avi_stream_id(id)==d_video->id){ // video frame |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
648 if((--rel_seek_frames)<0 && priv->idx[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; |
1466 | 649 } |
650 ++video_chunk_pos; | |
651 } | |
652 } else { | |
653 // seek backward | |
1498 | 654 while(video_chunk_pos>0){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
655 int id=priv->idx[video_chunk_pos].ckid; |
1466 | 656 if(avi_stream_id(id)==d_video->id){ // video frame |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
657 if((++rel_seek_frames)>0 && priv->idx[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; |
1466 | 658 } |
659 --video_chunk_pos; | |
660 } | |
661 } | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
662 priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=video_chunk_pos; |
1466 | 663 |
664 // re-calc video pts: | |
665 d_video->pack_no=0; | |
666 for(i=0;i<video_chunk_pos;i++){ | |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
667 int id=priv->idx[i].ckid; |
1466 | 668 if(avi_stream_id(id)==d_video->id) ++d_video->pack_no; |
669 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
670 priv->video_pack_no= |
1546 | 671 sh_video->num_frames=sh_video->num_frames_decoded=d_video->pack_no; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
672 priv->avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; |
1481 | 673 d_video->pos=video_chunk_pos; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
674 |
1567 | 675 mp_msg(MSGT_SEEK,MSGL_DBG2,"V_SEEK: pack=%d pts=%5.3f chunk=%d \n",d_video->pack_no,priv->avi_video_pts,video_chunk_pos); |
1481 | 676 |
677 // ------------ STEP 2: seek audio, find the right chunk & pos ------------ | |
678 | |
679 d_audio->pack_no=0; | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
680 priv->audio_block_no=0; |
1481 | 681 d_audio->dpos=0; |
1466 | 682 |
683 if(sh_audio){ | |
684 int i; | |
685 int len=0; | |
686 int skip_audio_bytes=0; | |
1481 | 687 int curr_audio_pos=-1; |
688 int audio_chunk_pos=-1; | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
689 int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:priv->idx_size; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
690 |
1481 | 691 if(sh_audio->audio.dwSampleSize){ |
692 // constant rate audio stream | |
17636 | 693 /* immediate seeking to audio position, including when streams are delayed */ |
694 curr_audio_pos=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; | |
1481 | 695 curr_audio_pos*=sh_audio->audio.dwSampleSize; |
1466 | 696 |
697 // find audio chunk pos: | |
1481 | 698 for(i=0;i<chunk_max;i++){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
699 int id=priv->idx[i].ckid; |
1466 | 700 if(avi_stream_id(id)==d_audio->id){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
701 len=priv->idx[i].dwChunkLength; |
1481 | 702 if(d_audio->dpos<=curr_audio_pos && curr_audio_pos<(d_audio->dpos+len)){ |
1466 | 703 break; |
704 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
705 ++d_audio->pack_no; |
32536
187f26cba0ce
If audio_block_size is 0 that is a bug (and will result in a division by 0
reimar
parents:
32535
diff
changeset
|
706 priv->audio_block_no+= |
187f26cba0ce
If audio_block_size is 0 that is a bug (and will result in a division by 0
reimar
parents:
32535
diff
changeset
|
707 (len+priv->audio_block_size-1)/priv->audio_block_size; |
1481 | 708 d_audio->dpos+=len; |
1466 | 709 } |
710 } | |
6640
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
711 audio_chunk_pos=i; |
1481 | 712 skip_audio_bytes=curr_audio_pos-d_audio->dpos; |
1466 | 713 |
6640
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
714 mp_msg(MSGT_SEEK,MSGL_V,"SEEK: i=%d (max:%d) dpos=%d (wanted:%d) \n", |
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
715 i,chunk_max,(int)d_audio->dpos,curr_audio_pos); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
716 |
1481 | 717 } else { |
718 // VBR audio | |
17636 | 719 /* immediate seeking to audio position, including when streams are delayed */ |
720 int chunks=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; | |
1481 | 721 audio_chunk_pos=0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
722 |
1481 | 723 // find audio chunk pos: |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
724 for(i=0;i<priv->idx_size && chunks>0;i++){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
725 int id=priv->idx[i].ckid; |
1481 | 726 if(avi_stream_id(id)==d_audio->id){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
727 len=priv->idx[i].dwChunkLength; |
1481 | 728 if(i>chunk_max){ |
729 skip_audio_bytes+=len; | |
730 } else { | |
731 ++d_audio->pack_no; | |
32536
187f26cba0ce
If audio_block_size is 0 that is a bug (and will result in a division by 0
reimar
parents:
32535
diff
changeset
|
732 priv->audio_block_no+= |
187f26cba0ce
If audio_block_size is 0 that is a bug (and will result in a division by 0
reimar
parents:
32535
diff
changeset
|
733 (len+priv->audio_block_size-1)/priv->audio_block_size; |
1481 | 734 d_audio->dpos+=len; |
735 audio_chunk_pos=i; | |
736 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
737 chunks-=(len+priv->audio_block_size-1)/priv->audio_block_size; |
1481 | 738 } |
739 } | |
740 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
741 |
1481 | 742 // Now we have: |
743 // audio_chunk_pos = chunk no in index table (it's <=chunk_max) | |
744 // skip_audio_bytes = bytes to be skipped after chunk seek | |
745 // d-audio->pack_no = chunk_no in stream at audio_chunk_pos | |
746 // d_audio->dpos = bytepos in stream at audio_chunk_pos | |
747 // let's seek! | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
748 |
1466 | 749 // update stream position: |
750 d_audio->pos=audio_chunk_pos; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
751 |
1481 | 752 if(demuxer->type==DEMUXER_TYPE_AVI){ |
753 // interleaved stream: | |
754 if(audio_chunk_pos<video_chunk_pos){ | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
755 // calc priv->skip_video_frames & adjust video pts counter: |
1481 | 756 for(i=audio_chunk_pos;i<video_chunk_pos;i++){ |
35410
1c991ec0e6da
Change declaration to use proper type to avoid a ridiculous
reimar
parents:
35409
diff
changeset
|
757 int id=priv->idx[i].ckid; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
758 if(avi_stream_id(id)==d_video->id) ++priv->skip_video_frames; |
1481 | 759 } |
760 // requires for correct audio pts calculation (demuxer): | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
761 priv->avi_video_pts-=priv->skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
762 priv->avi_audio_pts=priv->avi_video_pts; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
763 // set index position: |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
764 priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=audio_chunk_pos; |
1481 | 765 } |
766 } else { | |
767 // non-interleaved stream: | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
768 priv->idx_pos_a=audio_chunk_pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
769 priv->idx_pos_v=video_chunk_pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
770 priv->idx_pos=(audio_chunk_pos<video_chunk_pos)?audio_chunk_pos:video_chunk_pos; |
1481 | 771 } |
1466 | 772 |
1567 | 773 mp_msg(MSGT_SEEK,MSGL_V,"SEEK: idx=%d (a:%d v:%d) v.skip=%d a.skip=%d/%4.3f \n", |
6640
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
774 (int)priv->idx_pos,audio_chunk_pos,video_chunk_pos, |
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
775 (int)priv->skip_video_frames,skip_audio_bytes,skip_audio_secs); |
1466 | 776 |
777 if(skip_audio_bytes){ | |
778 demux_read_data(d_audio,NULL,skip_audio_bytes); | |
779 } | |
780 | |
781 } | |
1508
6e752419c7e8
update pts to obtain OSD time display change while rewinding/forwarding
atlka
parents:
1498
diff
changeset
|
782 d_video->pts=priv->avi_video_pts; // OSD |
1466 | 783 |
784 } | |
785 | |
786 | |
30570
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
787 static void demux_close_avi(demuxer_t *demuxer) |
98dc6ae7ede2
libmpdemux: Mark functions not used outside of their files as static.
diego
parents:
30542
diff
changeset
|
788 { |
6816 | 789 avi_priv_t* priv=demuxer->priv; |
1466 | 790 |
6816 | 791 if(!priv) |
792 return; | |
793 | |
794 if(priv->idx_size > 0) | |
795 free(priv->idx); | |
796 free(priv); | |
797 } | |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
798 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
799 |
16199
acb7885f916d
demux_avi_control() missing in avi's demuxer struct.
ods15
parents:
16175
diff
changeset
|
800 static int demux_avi_control(demuxer_t *demuxer,int cmd, void *arg){ |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
801 avi_priv_t *priv=demuxer->priv; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
802 demux_stream_t *d_video=demuxer->video; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
803 sh_video_t *sh_video=d_video->sh; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
804 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
805 switch(cmd) { |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
806 case DEMUXER_CTRL_GET_TIME_LENGTH: |
17342 | 807 if (!priv->numberofframes || !sh_video) return DEMUXER_CTRL_DONTKNOW; |
16346
6ff303d2876b
Make -identify's 'ID_LENGTH=' print a float and not an integer.. The
ods15
parents:
16211
diff
changeset
|
808 *((double *)arg)=(double)priv->numberofframes/sh_video->fps; |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
809 if (sh_video->video.dwLength<=1) return DEMUXER_CTRL_GUESS; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
810 return DEMUXER_CTRL_OK; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
811 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
812 case DEMUXER_CTRL_GET_PERCENT_POS: |
17342 | 813 if (!priv->numberofframes || !sh_video) { |
14502
8769fa370f83
Move generic length and percent pos calculation to demuxer.c
reimar
parents:
12036
diff
changeset
|
814 return DEMUXER_CTRL_DONTKNOW; |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
815 } |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
816 *((int *)arg)=(int)(priv->video_pack_no*100/priv->numberofframes); |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
817 if (sh_video->video.dwLength<=1) return DEMUXER_CTRL_GUESS; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
818 return DEMUXER_CTRL_OK; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
819 |
21403 | 820 case DEMUXER_CTRL_SWITCH_AUDIO: |
821 case DEMUXER_CTRL_SWITCH_VIDEO: { | |
822 int audio = (cmd == DEMUXER_CTRL_SWITCH_AUDIO); | |
823 demux_stream_t *ds = audio ? demuxer->audio : demuxer->video; | |
824 void **streams = audio ? demuxer->a_streams : demuxer->v_streams; | |
21406 | 825 int maxid = FFMIN(100, audio ? MAX_A_STREAMS : MAX_V_STREAMS); |
21403 | 826 int chunkid; |
827 if (ds->id < -1) | |
30937
f87bfe2885f2
Make audio switching with AVI demuxer chose the first audio stream
reimar
parents:
30585
diff
changeset
|
828 ds->id = -1; |
21403 | 829 |
830 if (*(int *)arg >= 0) | |
831 ds->id = *(int *)arg; | |
832 else { | |
21405
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
833 int i; |
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
834 for (i = 0; i < maxid; i++) { |
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
835 if (++ds->id >= maxid) ds->id = 0; |
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
836 if (streams[ds->id]) break; |
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
837 } |
21403 | 838 } |
839 | |
840 chunkid = (ds->id / 10 + '0') | (ds->id % 10 + '0') << 8; | |
841 ds->sh = NULL; | |
21405
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
842 if (!streams[ds->id]) // stream not available |
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
843 ds->id = -1; |
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
844 else |
a120cda87e3e
Proper fix for last demux_avi commit, stream switching now really should
reimar
parents:
21404
diff
changeset
|
845 demux_avi_select_stream(demuxer, chunkid); |
21403 | 846 *(int *)arg = ds->id; |
847 return DEMUXER_CTRL_OK; | |
848 } | |
849 | |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
850 default: |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
851 return DEMUXER_CTRL_NOTIMPL; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
852 } |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
853 } |
16175 | 854 |
855 | |
856 static int avi_check_file(demuxer_t *demuxer) | |
857 { | |
858 int id=stream_read_dword_le(demuxer->stream); // "RIFF" | |
859 | |
860 if((id==mmioFOURCC('R','I','F','F')) || (id==mmioFOURCC('O','N','2',' '))) { | |
861 stream_read_dword_le(demuxer->stream); //filesize | |
862 id=stream_read_dword_le(demuxer->stream); // "AVI " | |
863 if(id==formtypeAVI) | |
864 return DEMUXER_TYPE_AVI; | |
22148 | 865 // "Samsung Digimax i6 PMP" crap according to bug 742 |
866 if(id==mmioFOURCC('A','V','I',0x19)) | |
867 return DEMUXER_TYPE_AVI; | |
16175 | 868 if(id==mmioFOURCC('O','N','2','f')){ |
20695 | 869 mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_ON2AviFormat); |
16175 | 870 return DEMUXER_TYPE_AVI; |
871 } | |
872 } | |
873 | |
874 return 0; | |
875 } | |
876 | |
877 | |
878 static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer) | |
879 { | |
880 sh_audio_t* sh_a; | |
881 | |
25200 | 882 demuxer = demux_open_avi(demuxer); |
16175 | 883 if(!demuxer) return NULL; // failed to open |
25200 | 884 sh_a = demuxer->audio->sh; |
16175 | 885 if(demuxer->audio->id != -2 && sh_a) { |
27363
40057010b1fa
Change a bunch of codec-specific preprocessor directives from a HAVE_
diego
parents:
25932
diff
changeset
|
886 #ifdef CONFIG_OGGVORBIS |
16175 | 887 // support for Ogg-in-AVI: |
888 if(sh_a->format == 0xFFFE) | |
889 demuxer = init_avi_with_ogg(demuxer); | |
890 else if(sh_a->format == 0x674F) { | |
891 stream_t* s; | |
892 demuxer_t *od; | |
893 s = new_ds_stream(demuxer->audio); | |
894 od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL); | |
895 if(!demux_ogg_open(od)) { | |
896 mp_msg( MSGT_DEMUXER,MSGL_ERR,MSGTR_ErrorOpeningOGGDemuxer); | |
897 free_stream(s); | |
898 demuxer->audio->id = -2; | |
899 } else | |
900 demuxer = new_demuxers_demuxer(demuxer,od,demuxer); | |
901 } | |
902 #endif | |
903 } | |
904 | |
905 return demuxer; | |
906 } | |
907 | |
908 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25200
diff
changeset
|
909 const demuxer_desc_t demuxer_desc_avi = { |
16175 | 910 "AVI demuxer", |
911 "avi", | |
912 "AVI", | |
913 "Arpi?", | |
914 "AVI files, including non interleaved files", | |
915 DEMUXER_TYPE_AVI, | |
916 1, // safe autodetect | |
917 avi_check_file, | |
918 demux_avi_fill_buffer, | |
919 demux_open_hack_avi, | |
920 demux_close_avi, | |
921 demux_seek_avi, | |
16199
acb7885f916d
demux_avi_control() missing in avi's demuxer struct.
ods15
parents:
16175
diff
changeset
|
922 demux_avi_control |
16175 | 923 }; |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
924 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25200
diff
changeset
|
925 const demuxer_desc_t demuxer_desc_avi_ni = { |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
926 "AVI demuxer, non-interleaved", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
927 "avini", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
928 "AVI", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
929 "Arpi?", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
930 "AVI files, including non interleaved files", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
931 DEMUXER_TYPE_AVI, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
932 1, // safe autodetect |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
933 avi_check_file, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
934 demux_avi_fill_buffer_ni, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
935 demux_open_hack_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
936 demux_close_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
937 demux_seek_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
938 demux_avi_control |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
939 }; |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
940 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25200
diff
changeset
|
941 const demuxer_desc_t demuxer_desc_avi_nini = { |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
942 "AVI demuxer, non-interleaved and no index", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
943 "avinini", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
944 "AVI", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
945 "Arpi?", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
946 "AVI files, including non interleaved files", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
947 DEMUXER_TYPE_AVI, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
948 1, // safe autodetect |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
949 avi_check_file, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
950 demux_avi_fill_buffer_nini, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
951 demux_open_hack_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
952 demux_close_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
953 demux_seek_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
954 demux_avi_control |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
955 }; |