Mercurial > mplayer.hg
annotate libmpdemux/demux_avi.c @ 20902:bfb6eacd9c4a
Update OSD contents only after the correct values for the frame are known.
The most visible inaccuracy caused by the previous update location was
that the OSD always showed position 0 after seeking with demux_mkv.
Split frame decoding and filtering because with -correct-pts the pts
value that should be displayed for the frame is only known after
decoding but is needed before filtering (during which the OSD is drawn).
author | uau |
---|---|
date | Tue, 14 Nov 2006 12:29:20 +0000 |
parents | 7baa2ab8da05 |
children | 8621736097f8 |
rev | line source |
---|---|
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
1 // AVI file parser for DEMUXER v2.9 by A'rpi/ESP-team |
1 | 2 |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
3 #include <stdio.h> |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
4 #include <stdlib.h> |
1430 | 5 #include <unistd.h> |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
6 |
1567 | 7 #include "config.h" |
8 #include "mp_msg.h" | |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
9 #include "help_mp.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
10 |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
11 #include "stream.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
12 #include "demuxer.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
13 #include "stheader.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
14 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
15 #include "aviheader.h" |
1 | 16 |
16175 | 17 extern demuxer_t* init_avi_with_ogg(demuxer_t* demuxer); |
18 extern int demux_ogg_open(demuxer_t* demuxer); | |
19 | |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
20 extern demuxer_desc_t demuxer_desc_avi_ni; |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
21 extern demuxer_desc_t demuxer_desc_avi_nini; |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
22 |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
23 // PTS: 0=interleaved 1=BPS-based |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
24 int pts_from_bps=1; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
25 |
1 | 26 // Select ds from ID |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
27 demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){ |
1 | 28 int stream_id=avi_stream_id(id); |
426 | 29 |
30 | |
31 if(demux->video->id==-1) | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
32 if(demux->v_streams[stream_id]) |
426 | 33 demux->video->id=stream_id; |
34 | |
35 if(demux->audio->id==-1) | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
36 if(demux->a_streams[stream_id]) |
426 | 37 demux->audio->id=stream_id; |
38 | |
39 if(stream_id==demux->audio->id){ | |
40 if(!demux->audio->sh){ | |
7785
ffe8bfaa2851
fix & workaround possible sig8/sig11 in blocksize calculation
arpi
parents:
7501
diff
changeset
|
41 sh_audio_t* sh; |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
42 avi_priv_t *priv=demux->priv; |
7785
ffe8bfaa2851
fix & workaround possible sig8/sig11 in blocksize calculation
arpi
parents:
7501
diff
changeset
|
43 sh=demux->audio->sh=demux->a_streams[stream_id]; |
1567 | 44 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected AVI audio ID = %d\n",demux->audio->id); |
7785
ffe8bfaa2851
fix & workaround possible sig8/sig11 in blocksize calculation
arpi
parents:
7501
diff
changeset
|
45 if(sh->wf){ |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
46 priv->audio_block_size=sh->wf->nBlockAlign; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
47 if(!priv->audio_block_size){ |
7785
ffe8bfaa2851
fix & workaround possible sig8/sig11 in blocksize calculation
arpi
parents:
7501
diff
changeset
|
48 // for PCM audio we can calculate the blocksize: |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
49 if(sh->format==1) |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
50 priv->audio_block_size=sh->wf->nChannels*(sh->wf->wBitsPerSample/8); |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
51 else |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
52 priv->audio_block_size=1; // hope the best... |
8059 | 53 } else { |
54 // workaround old mencoder's bug: | |
55 if(sh->audio.dwSampleSize==1 && sh->audio.dwScale==1 && | |
56 (sh->wf->nBlockAlign==1152 || sh->wf->nBlockAlign==576)){ | |
20700 | 57 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_WorkAroundBlockAlignHeaderBug); |
8059 | 58 priv->audio_block_size=1; |
59 } | |
7785
ffe8bfaa2851
fix & workaround possible sig8/sig11 in blocksize calculation
arpi
parents:
7501
diff
changeset
|
60 } |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
61 } else { |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
62 priv->audio_block_size=sh->audio.dwSampleSize; |
7785
ffe8bfaa2851
fix & workaround possible sig8/sig11 in blocksize calculation
arpi
parents:
7501
diff
changeset
|
63 } |
426 | 64 } |
65 return demux->audio; | |
66 } | |
67 if(stream_id==demux->video->id){ | |
68 if(!demux->video->sh){ | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
426
diff
changeset
|
69 demux->video->sh=demux->v_streams[stream_id]; |
1567 | 70 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected AVI video ID = %d\n",demux->video->id); |
426 | 71 } |
72 return demux->video; | |
73 } | |
1 | 74 if(id!=mmioFOURCC('J','U','N','K')){ |
75 // unknown | |
1998 | 76 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
|
77 //abort(); |
1 | 78 } |
79 return NULL; | |
80 } | |
81 | |
2438 | 82 static int valid_fourcc(unsigned int id){ |
20400
f4518826ea84
Allow lowercase letters in AVI stream id, fixes bug #277
reimar
parents:
20337
diff
changeset
|
83 static const char valid[] = "0123456789abcdefghijklmnopqrstuvwxyz" |
f4518826ea84
Allow lowercase letters in AVI stream id, fixes bug #277
reimar
parents:
20337
diff
changeset
|
84 "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; |
2438 | 85 unsigned char* fcc=(unsigned char*)(&id); |
20400
f4518826ea84
Allow lowercase letters in AVI stream id, fixes bug #277
reimar
parents:
20337
diff
changeset
|
86 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
|
87 strchr(valid, fcc[2]) && strchr(valid, fcc[3]); |
2438 | 88 } |
89 | |
90 static int choose_chunk_len(unsigned int len1,unsigned int len2){ | |
91 // len1 has a bit more priority than len2. len1!=len2 | |
92 // Note: this is a first-idea-logic, may be wrong. comments welcomed. | |
93 | |
94 // prefer small frames rather than 0 | |
95 if(!len1) return (len2>0x80000) ? len1 : len2; | |
96 if(!len2) return (len1>0x100000) ? len2 : len1; | |
97 | |
98 // choose the smaller value: | |
99 return (len1<len2)? len1 : len2; | |
100 } | |
101 | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
102 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
|
103 avi_priv_t *priv=demux->priv; |
1 | 104 int skip; |
105 float pts=0; | |
106 | |
1567 | 107 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_avi.read_packet: %X\n",id); |
1 | 108 |
109 if(ds==demux->audio){ | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
110 if(priv->pts_corrected==0){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
111 if(priv->pts_has_video){ |
1455 | 112 // we have video pts now |
2826 | 113 float delay=0; |
114 if(((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec) | |
115 delay=(float)priv->pts_corr_bytes/((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec; | |
1567 | 116 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
|
117 //priv->pts_correction=-priv->avi_audio_pts+delay; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
118 priv->pts_correction=delay-priv->avi_audio_pts; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
119 priv->avi_audio_pts+=priv->pts_correction; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
120 priv->pts_corrected=1; |
1455 | 121 } else |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
122 priv->pts_corr_bytes+=len; |
1455 | 123 } |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
124 if(pts_from_bps){ |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
125 pts = priv->audio_block_no * |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
126 (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
|
127 (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
|
128 } else |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
129 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
|
130 priv->avi_audio_pts=0; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
131 // update blockcount: |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
132 priv->audio_block_no+=priv->audio_block_size ? |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
133 ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1; |
1 | 134 } else |
1409 | 135 if(ds==demux->video){ |
1 | 136 // video |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
137 if(priv->skip_video_frames>0){ |
1 | 138 // drop frame (seeking) |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
139 --priv->skip_video_frames; |
1 | 140 ds=NULL; |
141 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
142 |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
143 pts = priv->avi_video_pts = priv->video_pack_no * |
1368 | 144 (float)((sh_video_t*)demux->video->sh)->video.dwScale / |
145 (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
|
146 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
147 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
|
148 priv->pts_has_video=1; |
1455 | 149 |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
150 if(ds) ++priv->video_pack_no; |
1498 | 151 |
1 | 152 } |
153 | |
154 skip=(len+1)&(~1); // total bytes in this chunk | |
155 | |
156 if(ds){ | |
1567 | 157 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Read %d data bytes from packet %04X\n",len,id); |
979 | 158 ds_read_packet(ds,demux->stream,len,pts,idxpos,flags); |
1 | 159 skip-=len; |
160 } | |
161 if(skip){ | |
1567 | 162 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Skipping %d bytes from packet %04X\n",skip,id); |
1 | 163 stream_skip(demux->stream,skip); |
164 } | |
165 return ds?1:0; | |
166 } | |
167 | |
168 // return value: | |
169 // 0 = EOF or no stream found | |
170 // 1 = successfully read a packet | |
16175 | 171 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
|
172 avi_priv_t *priv=demux->priv; |
1 | 173 unsigned int id=0; |
174 unsigned int len; | |
175 int ret=0; | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
176 demux_stream_t *ds; |
1 | 177 |
178 do{ | |
9228 | 179 int flags=1; |
1 | 180 AVIINDEXENTRY *idx=NULL; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
181 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
|
182 off_t pos; |
1 | 183 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
184 idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++]; |
1 | 185 |
186 if(idx->dwFlags&AVIIF_LIST){ | |
187 // LIST | |
188 continue; | |
189 } | |
190 if(!demux_avi_select_stream(demux,idx->ckid)){ | |
1567 | 191 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid); |
1 | 192 continue; // skip this chunk |
193 } | |
194 | |
12036 | 195 pos = (off_t)priv->idx_offset+AVI_IDX_OFFSET(idx); |
11965 | 196 if((pos<demux->movi_start || pos>=demux->movi_end) && (demux->movi_end>demux->movi_start) && (demux->stream->flags & STREAM_SEEK)){ |
17366 | 197 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkOffset out of range! idx=0x%"PRIX64" \n",(int64_t)pos); |
1 | 198 continue; |
199 } | |
200 stream_seek(demux->stream,pos); | |
1421 | 201 demux->filepos=stream_tell(demux->stream); |
1 | 202 id=stream_read_dword_le(demux->stream); |
1421 | 203 if(stream_eof(demux->stream)) return 0; // EOF! |
204 | |
1 | 205 if(id!=idx->ckid){ |
1567 | 206 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); |
2438 | 207 if(valid_fourcc(idx->ckid)) |
208 id=idx->ckid; // use index if valid | |
209 else | |
210 if(!valid_fourcc(id)) continue; // drop chunk if both id and idx bad | |
1 | 211 } |
212 len=stream_read_dword_le(demux->stream); | |
213 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ | |
17366 | 214 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%d \n",len,idx->dwChunkLength); |
2438 | 215 if(len>0x200000 && idx->dwChunkLength>0x200000) continue; // both values bad :( |
216 len=choose_chunk_len(idx->dwChunkLength,len); | |
1 | 217 } |
9228 | 218 if(!(idx->dwFlags&AVIIF_KEYFRAME)) flags=0; |
1 | 219 } else { |
1421 | 220 demux->filepos=stream_tell(demux->stream); |
11965 | 221 if(demux->filepos>=demux->movi_end && demux->movi_end>demux->movi_start && (demux->stream->flags & STREAM_SEEK)){ |
1421 | 222 demux->stream->eof=1; |
223 return 0; | |
224 } | |
1 | 225 id=stream_read_dword_le(demux->stream); |
226 len=stream_read_dword_le(demux->stream); | |
1421 | 227 if(stream_eof(demux->stream)) return 0; // EOF! |
228 | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
229 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
|
230 id=stream_read_dword_le(demux->stream); // list or RIFF type |
1 | 231 continue; |
232 } | |
233 } | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
234 |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
235 ds=demux_avi_select_stream(demux,id); |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
236 if(ds) |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
237 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
|
238 // this packet will cause a buffer overflow, switch to -ni mode!!! |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
239 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_SwitchToNi); |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
240 if(priv->idx_size>0){ |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
241 // has index |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
242 demux->type=DEMUXER_TYPE_AVI_NI; |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
243 demux->desc=&demuxer_desc_avi_ni; |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
244 --priv->idx_pos; // hack |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
245 } else { |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
246 // no index |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
247 demux->type=DEMUXER_TYPE_AVI_NINI; |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
248 demux->desc=&demuxer_desc_avi_nini; |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
249 priv->idx_pos=demux->filepos; // hack |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
250 } |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
251 priv->idx_pos_v=priv->idx_pos_a=priv->idx_pos; |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
252 // 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
|
253 return -1; |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
254 } |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
255 |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
256 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,flags); |
1 | 257 } while(ret!=1); |
258 return 1; | |
259 } | |
260 | |
261 | |
262 // return value: | |
263 // 0 = EOF or no stream found | |
264 // 1 = successfully read a packet | |
265 int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){ | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
266 avi_priv_t *priv=demux->priv; |
1 | 267 unsigned int id=0; |
268 unsigned int len; | |
269 int ret=0; | |
270 | |
271 do{ | |
9228 | 272 int flags=1; |
1 | 273 AVIINDEXENTRY *idx=NULL; |
274 int idx_pos=0; | |
275 demux->filepos=stream_tell(demux->stream); | |
276 | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
277 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
|
278 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
|
279 idx_pos=priv->idx_pos++; |
1 | 280 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
281 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
|
282 off_t pos; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
283 idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos]; |
1 | 284 |
285 if(idx->dwFlags&AVIIF_LIST){ | |
286 // LIST | |
287 continue; | |
288 } | |
289 if(ds && demux_avi_select_stream(demux,idx->ckid)!=ds){ | |
1567 | 290 mp_dbg(MSGT_DEMUX,MSGL_DBG3,"Skip chunk %.4s (0x%X) \n",(char *)&idx->ckid,(unsigned int)idx->ckid); |
1 | 291 continue; // skip this chunk |
292 } | |
293 | |
12036 | 294 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
|
295 if((pos<demux->movi_start || pos>=demux->movi_end) && (demux->movi_end>demux->movi_start)){ |
17366 | 296 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 | 297 continue; |
298 } | |
299 stream_seek(demux->stream,pos); | |
300 | |
301 id=stream_read_dword_le(demux->stream); | |
302 | |
303 if(stream_eof(demux->stream)) return 0; | |
304 | |
305 if(id!=idx->ckid){ | |
1567 | 306 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkID mismatch! raw=%.4s idx=%.4s \n",(char *)&id,(char *)&idx->ckid); |
2438 | 307 if(valid_fourcc(idx->ckid)) |
308 id=idx->ckid; // use index if valid | |
309 else | |
310 if(!valid_fourcc(id)) continue; // drop chunk if both id and idx bad | |
1 | 311 } |
312 len=stream_read_dword_le(demux->stream); | |
313 if((len!=idx->dwChunkLength)&&((len+1)!=idx->dwChunkLength)){ | |
17366 | 314 mp_msg(MSGT_DEMUX,MSGL_V,"ChunkSize mismatch! raw=%d idx=%d \n",len,idx->dwChunkLength); |
2438 | 315 if(len>0x200000 && idx->dwChunkLength>0x200000) continue; // both values bad :( |
316 len=choose_chunk_len(idx->dwChunkLength,len); | |
1 | 317 } |
9228 | 318 if(!(idx->dwFlags&AVIIF_KEYFRAME)) flags=0; |
1 | 319 } else return 0; |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
320 ret=demux_avi_read_packet(demux,demux_avi_select_stream(demux,id),id,len,idx_pos,flags); |
1 | 321 } while(ret!=1); |
322 return 1; | |
323 } | |
324 | |
325 | |
326 // return value: | |
327 // 0 = EOF or no stream found | |
328 // 1 = successfully read a packet | |
329 int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){ | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
330 avi_priv_t *priv=demux->priv; |
1 | 331 unsigned int id=0; |
332 unsigned int len; | |
333 int ret=0; | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
334 off_t *fpos=NULL; |
1 | 335 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
336 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
|
337 if(ds==demux->audio) fpos=&priv->idx_pos_a; else |
1 | 338 return 0; |
339 | |
340 stream_seek(demux->stream,fpos[0]); | |
341 | |
342 do{ | |
343 | |
344 demux->filepos=stream_tell(demux->stream); | |
2439
022a7e7fec2d
while_encoding.avi (ffmpeg) fix (ignoring movi_ check if end<=start)
arpi
parents:
2438
diff
changeset
|
345 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
|
346 ds->eof=1; |
1 | 347 return 0; |
348 } | |
349 | |
350 id=stream_read_dword_le(demux->stream); | |
351 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
|
352 |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
353 if(stream_eof(demux->stream)) return 0; |
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
354 |
1 | 355 if(id==mmioFOURCC('L','I','S','T')){ |
356 id=stream_read_dword_le(demux->stream); // list type | |
357 continue; | |
358 } | |
359 | |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
360 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
|
361 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
|
362 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
|
363 continue; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
364 } |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
365 |
1 | 366 if(ds==demux_avi_select_stream(demux,id)){ |
367 // read it! | |
6884
37946a0a155a
detection of badly interleaved avi files and auto-switch to -ni
arpi
parents:
6871
diff
changeset
|
368 ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,0); |
1 | 369 } else { |
370 // skip it! | |
371 int skip=(len+1)&(~1); // total bytes in this chunk | |
372 stream_skip(demux->stream,skip); | |
373 } | |
374 | |
375 } while(ret!=1); | |
376 fpos[0]=stream_tell(demux->stream); | |
377 return 1; | |
378 } | |
379 | |
2314 | 380 // AVI demuxer parameters: |
381 int index_mode=-1; // -1=untouched 0=don't use index 1=use (geneate) index | |
11234
9767665d49e0
Saving and loading external index file. Patch by Jason Tackaberry <tack@auc.ca>
alex
parents:
10709
diff
changeset
|
382 char *index_file_save = NULL, *index_file_load = NULL; |
2314 | 383 int force_ni=0; // force non-interleaved AVI parsing |
384 | |
2050 | 385 void read_avi_header(demuxer_t *demuxer,int index_mode); |
386 | |
16175 | 387 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
|
388 demux_stream_t *d_audio=demuxer->audio; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
389 demux_stream_t *d_video=demuxer->video; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
390 sh_audio_t *sh_audio=NULL; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
391 sh_video_t *sh_video=NULL; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
392 avi_priv_t* priv=malloc(sizeof(avi_priv_t)); |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
393 |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
394 // priv struct: |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
395 priv->avi_audio_pts=priv->avi_video_pts=0.0f; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
396 priv->pts_correction=0.0f; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
397 priv->skip_video_frames=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
398 priv->pts_corr_bytes=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
399 priv->pts_has_video=priv->pts_corrected=0; |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
400 priv->video_pack_no=0; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
401 priv->audio_block_no=0; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
402 priv->audio_block_size=0; |
12036 | 403 priv->isodml = 0; |
404 priv->suidx_size = 0; | |
405 priv->suidx = NULL; | |
406 | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
407 demuxer->priv=(void*)priv; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
408 |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
409 //---- AVI header: |
12018 | 410 read_avi_header(demuxer,(demuxer->stream->flags & STREAM_SEEK_BW)?index_mode:-2); |
7501 | 411 |
412 if(demuxer->audio->id>=0 && !demuxer->a_streams[demuxer->audio->id]){ | |
20695 | 413 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamNosound,demuxer->audio->id); |
7501 | 414 demuxer->audio->id=-2; // disabled |
415 } | |
416 if(demuxer->video->id>=0 && !demuxer->v_streams[demuxer->video->id]){ | |
20695 | 417 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_InvalidAudioStreamUsingDefault,demuxer->video->id); |
7501 | 418 demuxer->video->id=-1; // autodetect |
419 } | |
420 | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
421 stream_reset(demuxer->stream); |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
422 stream_seek(demuxer->stream,demuxer->movi_start); |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
423 priv->idx_pos=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
424 priv->idx_pos_a=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
425 priv->idx_pos_v=0; |
4665 | 426 if(priv->idx_size>1){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
427 // decide index format: |
4665 | 428 #if 1 |
12036 | 429 if((AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[0])<demuxer->movi_start || |
430 AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[1])<demuxer->movi_start )&& !priv->isodml) | |
4665 | 431 priv->idx_offset=demuxer->movi_start-4; |
432 else | |
433 priv->idx_offset=0; | |
434 #else | |
12036 | 435 if(AVI_IDX_OFFSET(&((AVIINDEXENTRY *)priv->idx)[0])<demuxer->movi_start) |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
436 priv->idx_offset=demuxer->movi_start-4; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
437 else |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
438 priv->idx_offset=0; |
4665 | 439 #endif |
440 mp_msg(MSGT_DEMUX,MSGL_V,"AVI index offset: 0x%X (movi=0x%X idx0=0x%X idx1=0x%X)\n", | |
441 (int)priv->idx_offset,(int)demuxer->movi_start, | |
442 (int)((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset, | |
443 (int)((AVIINDEXENTRY *)priv->idx)[1].dwChunkOffset); | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
444 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
445 |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
446 if(priv->idx_size>0){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
447 // check that file is non-interleaved: |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
448 int i; |
6056
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
449 off_t a_pos=-1; |
f980563afdbc
big (>2GB) AVI files support - patch by Wolfram Gloger <wg@malloc.de>
arpi
parents:
4665
diff
changeset
|
450 off_t v_pos=-1; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
451 for(i=0;i<priv->idx_size;i++){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
452 AVIINDEXENTRY* idx=&((AVIINDEXENTRY *)priv->idx)[i]; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
453 demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid); |
12036 | 454 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
|
455 if(a_pos==-1 && ds==demuxer->audio){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
456 a_pos=pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
457 if(v_pos!=-1) break; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
458 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
459 if(v_pos==-1 && ds==demuxer->video){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
460 v_pos=pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
461 if(a_pos!=-1) break; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
462 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
463 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
464 if(v_pos==-1){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
465 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
|
466 return NULL; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
467 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
468 if(a_pos==-1){ |
20337
fccb66884d60
Avoid crash after "AVI: No audio stream found -> no sound." message,
reimar
parents:
20246
diff
changeset
|
469 d_audio->sh=sh_audio=NULL; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
470 } else { |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
471 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
|
472 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
|
473 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
|
474 demuxer->desc=&demuxer_desc_avi_ni; // HACK!!!! |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
475 pts_from_bps=1; // force BPS sync! |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
476 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
477 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
478 } else { |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
479 // no index |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
480 if(force_ni){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
481 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
|
482 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
|
483 demuxer->desc=&demuxer_desc_avi_nini; // HACK!!!! |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
484 priv->idx_pos_a= |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
485 priv->idx_pos_v=demuxer->movi_start; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
486 pts_from_bps=1; // force BPS sync! |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
487 } |
1623
5908dd344067
added demuxer->seekable flag to generalize seeking ability test
arpi
parents:
1567
diff
changeset
|
488 demuxer->seekable=0; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
489 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
490 if(!ds_fill_buffer(d_video)){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
491 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
|
492 return NULL; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
493 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
494 sh_video=d_video->sh;sh_video->ds=d_video; |
1496 | 495 if(d_audio->id!=-2){ |
1567 | 496 mp_msg(MSGT_DEMUX,MSGL_V,"AVI: Searching for audio stream (id:%d)\n",d_audio->id); |
2330 | 497 if(!priv->audio_streams || !ds_fill_buffer(d_audio)){ |
1973
5216f108cb4f
all error/warn/info messages moved to help_mp-en.h for translation
arpi
parents:
1737
diff
changeset
|
498 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
|
499 d_audio->sh=sh_audio=NULL; |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
500 } else { |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
501 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
|
502 sh_audio->format=sh_audio->wf->wFormatTag; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
503 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
504 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
505 // calc. FPS: |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
506 sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
507 sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
508 |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
509 // calculating audio/video bitrate: |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
510 if(priv->idx_size>0){ |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
511 // we have index, let's count 'em! |
18393
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
512 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
|
513 int64_t asize=0; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
514 size_t vsamples=0; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
515 size_t asamples=0; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
516 int i; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
517 for(i=0;i<priv->idx_size;i++){ |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
518 int id=avi_stream_id(((AVIINDEXENTRY *)priv->idx)[i].ckid); |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
519 int len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
520 if(sh_video->ds->id == id) { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
521 vsize+=len; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
522 ++vsamples; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
523 } |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
524 else if(sh_audio && sh_audio->ds->id == id) { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
525 asize+=len; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
526 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
|
527 } |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
528 } |
18393
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
529 mp_msg(MSGT_DEMUX,MSGL_V,"AVI video size=%"PRId64" (%u) audio size=%"PRId64" (%u)\n",vsize,vsamples,asize,asamples); |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
530 priv->numberofframes=vsamples; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
531 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
|
532 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
|
533 } else { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
534 // 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
|
535 int64_t vsize; |
09b64c87b29a
Fix calculation of stream sizes when they are too big for a 32-bit variable
pacman
parents:
17643
diff
changeset
|
536 int64_t asize=0; |
8516
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
537 |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
538 if((priv->numberofframes=sh_video->video.dwLength)<=1) |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
539 // bad video header, try to get number of frames from audio |
8646 | 540 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
|
541 if(priv->numberofframes<=1){ |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
542 mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CouldntDetFNo); |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
543 priv->numberofframes=0; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
544 } |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
545 |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
546 if(sh_audio){ |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
547 if(sh_audio->wf->nAvgBytesPerSec && sh_audio->audio.dwSampleSize!=1){ |
8646 | 548 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
|
549 sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
550 } else { |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
551 asize=sh_audio->audio.dwLength; |
71e2ba5d6cdc
accurate bitrate calculation using index, and more accurate guessing
arpi
parents:
8254
diff
changeset
|
552 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
|
553 } |
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 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
|
556 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
|
557 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
|
558 } |
17643 | 559 |
560 if (sh_video) | |
561 sh_video->stream_delay = (float)sh_video->video.dwStart * sh_video->video.dwScale/sh_video->video.dwRate; | |
562 if (sh_audio) | |
563 sh_audio->stream_delay = (float)sh_audio->audio.dwStart * sh_audio->audio.dwScale/sh_audio->audio.dwRate; | |
564 | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
565 return demuxer; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
566 |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
567 } |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
568 |
1 | 569 |
17636 | 570 void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
571 avi_priv_t *priv=demuxer->priv; |
1466 | 572 demux_stream_t *d_audio=demuxer->audio; |
573 demux_stream_t *d_video=demuxer->video; | |
574 sh_audio_t *sh_audio=d_audio->sh; | |
575 sh_video_t *sh_video=d_video->sh; | |
576 float skip_audio_secs=0; | |
577 | |
578 //FIXME: OFF_T - Didn't check AVI case yet (avi files can't be >2G anyway?) | |
579 //================= seek in AVI ========================== | |
580 int rel_seek_frames=rel_seek_secs*sh_video->fps; | |
581 int video_chunk_pos=d_video->pos; | |
582 int i; | |
1628
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
583 |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
584 if(flags&1){ |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
585 // seek absolute |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
586 video_chunk_pos=0; |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
587 } |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
588 |
bd1ef18cdf33
seeking flags implemented: 0x1=rel/abs and 0x2=time/percent
arpi
parents:
1623
diff
changeset
|
589 if(flags&2){ |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
590 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
|
591 } |
1466 | 592 |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
593 priv->skip_video_frames=0; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
594 priv->avi_audio_pts=0; |
1466 | 595 |
1481 | 596 // ------------ STEP 1: find nearest video keyframe chunk ------------ |
1466 | 597 // find nearest video keyframe chunk pos: |
598 if(rel_seek_frames>0){ | |
599 // seek forward | |
7002
518faaa2aee4
corrects an off-by-one error when trying to seek beyond the end of file.
arpi
parents:
6884
diff
changeset
|
600 while(video_chunk_pos<priv->idx_size-1){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
601 int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid; |
1466 | 602 if(avi_stream_id(id)==d_video->id){ // video frame |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
603 if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; |
1466 | 604 } |
605 ++video_chunk_pos; | |
606 } | |
607 } else { | |
608 // seek backward | |
1498 | 609 while(video_chunk_pos>0){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
610 int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid; |
1466 | 611 if(avi_stream_id(id)==d_video->id){ // video frame |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
612 if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; |
1466 | 613 } |
614 --video_chunk_pos; | |
615 } | |
616 } | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
617 priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=video_chunk_pos; |
1466 | 618 |
619 // re-calc video pts: | |
620 d_video->pack_no=0; | |
621 for(i=0;i<video_chunk_pos;i++){ | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
622 int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; |
1466 | 623 if(avi_stream_id(id)==d_video->id) ++d_video->pack_no; |
624 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
625 priv->video_pack_no= |
1546 | 626 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
|
627 priv->avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; |
1481 | 628 d_video->pos=video_chunk_pos; |
1498 | 629 |
1567 | 630 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 | 631 |
632 // ------------ STEP 2: seek audio, find the right chunk & pos ------------ | |
633 | |
634 d_audio->pack_no=0; | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
635 priv->audio_block_no=0; |
1481 | 636 d_audio->dpos=0; |
1466 | 637 |
638 if(sh_audio){ | |
639 int i; | |
640 int len=0; | |
641 int skip_audio_bytes=0; | |
1481 | 642 int curr_audio_pos=-1; |
643 int audio_chunk_pos=-1; | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
644 int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:priv->idx_size; |
1481 | 645 |
646 if(sh_audio->audio.dwSampleSize){ | |
647 // constant rate audio stream | |
17636 | 648 /* immediate seeking to audio position, including when streams are delayed */ |
649 curr_audio_pos=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; | |
1481 | 650 curr_audio_pos*=sh_audio->audio.dwSampleSize; |
1466 | 651 |
652 // find audio chunk pos: | |
1481 | 653 for(i=0;i<chunk_max;i++){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
654 int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; |
1466 | 655 if(avi_stream_id(id)==d_audio->id){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
656 len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength; |
1481 | 657 if(d_audio->dpos<=curr_audio_pos && curr_audio_pos<(d_audio->dpos+len)){ |
1466 | 658 break; |
659 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
660 ++d_audio->pack_no; |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
661 priv->audio_block_no+=priv->audio_block_size ? |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
662 ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1; |
1481 | 663 d_audio->dpos+=len; |
1466 | 664 } |
665 } | |
6640
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
666 audio_chunk_pos=i; |
1481 | 667 skip_audio_bytes=curr_audio_pos-d_audio->dpos; |
1466 | 668 |
6640
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
669 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
|
670 i,chunk_max,(int)d_audio->dpos,curr_audio_pos); |
2d3d4c628ece
hopefully fixed last A-V sync bug, and also fixed largefile bug in debug printf
arpi
parents:
6056
diff
changeset
|
671 |
1481 | 672 } else { |
673 // VBR audio | |
17636 | 674 /* immediate seeking to audio position, including when streams are delayed */ |
675 int chunks=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale; | |
1481 | 676 audio_chunk_pos=0; |
677 | |
678 // find audio chunk pos: | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
679 for(i=0;i<priv->idx_size && chunks>0;i++){ |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
680 int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; |
1481 | 681 if(avi_stream_id(id)==d_audio->id){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
682 len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength; |
1481 | 683 if(i>chunk_max){ |
684 skip_audio_bytes+=len; | |
685 } else { | |
686 ++d_audio->pack_no; | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
687 priv->audio_block_no+=priv->audio_block_size ? |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
688 ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1; |
1481 | 689 d_audio->dpos+=len; |
690 audio_chunk_pos=i; | |
691 } | |
8030
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
692 if(priv->audio_block_size) |
2b39ff3860b7
cleanup of .AVI timestamp calculation (ugly hack from mplayer.c removed,
arpi
parents:
7785
diff
changeset
|
693 chunks-=(len+priv->audio_block_size-1)/priv->audio_block_size; |
1481 | 694 } |
695 } | |
696 } | |
697 | |
698 // Now we have: | |
699 // audio_chunk_pos = chunk no in index table (it's <=chunk_max) | |
700 // skip_audio_bytes = bytes to be skipped after chunk seek | |
701 // d-audio->pack_no = chunk_no in stream at audio_chunk_pos | |
702 // d_audio->dpos = bytepos in stream at audio_chunk_pos | |
703 // let's seek! | |
704 | |
1466 | 705 // update stream position: |
706 d_audio->pos=audio_chunk_pos; | |
1481 | 707 |
708 if(demuxer->type==DEMUXER_TYPE_AVI){ | |
709 // interleaved stream: | |
710 if(audio_chunk_pos<video_chunk_pos){ | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
711 // calc priv->skip_video_frames & adjust video pts counter: |
1481 | 712 for(i=audio_chunk_pos;i<video_chunk_pos;i++){ |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
713 int id=((AVIINDEXENTRY *)priv->idx)[i].ckid; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
714 if(avi_stream_id(id)==d_video->id) ++priv->skip_video_frames; |
1481 | 715 } |
716 // requires for correct audio pts calculation (demuxer): | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
717 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
|
718 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
|
719 // set index position: |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
720 priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=audio_chunk_pos; |
1481 | 721 } |
722 } else { | |
723 // non-interleaved stream: | |
1485
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
724 priv->idx_pos_a=audio_chunk_pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
725 priv->idx_pos_v=video_chunk_pos; |
b895f95e7657
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
arpi
parents:
1481
diff
changeset
|
726 priv->idx_pos=(audio_chunk_pos<video_chunk_pos)?audio_chunk_pos:video_chunk_pos; |
1481 | 727 } |
1466 | 728 |
1567 | 729 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
|
730 (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
|
731 (int)priv->skip_video_frames,skip_audio_bytes,skip_audio_secs); |
1466 | 732 |
733 if(skip_audio_bytes){ | |
734 demux_read_data(d_audio,NULL,skip_audio_bytes); | |
735 } | |
736 | |
737 } | |
1508
6e752419c7e8
update pts to obtain OSD time display change while rewinding/forwarding
atlka
parents:
1498
diff
changeset
|
738 d_video->pts=priv->avi_video_pts; // OSD |
1466 | 739 |
740 } | |
741 | |
742 | |
6816 | 743 void demux_close_avi(demuxer_t *demuxer) { |
744 avi_priv_t* priv=demuxer->priv; | |
1466 | 745 |
6816 | 746 if(!priv) |
747 return; | |
748 | |
749 if(priv->idx_size > 0) | |
750 free(priv->idx); | |
751 free(priv); | |
752 } | |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
753 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
754 |
16199
acb7885f916d
demux_avi_control() missing in avi's demuxer struct.
ods15
parents:
16175
diff
changeset
|
755 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
|
756 avi_priv_t *priv=demuxer->priv; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
757 demux_stream_t *d_video=demuxer->video; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
758 sh_video_t *sh_video=d_video->sh; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
759 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
760 switch(cmd) { |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
761 case DEMUXER_CTRL_GET_TIME_LENGTH: |
17342 | 762 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
|
763 *((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
|
764 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
|
765 return DEMUXER_CTRL_OK; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
766 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
767 case DEMUXER_CTRL_GET_PERCENT_POS: |
17342 | 768 if (!priv->numberofframes || !sh_video) { |
14502
8769fa370f83
Move generic length and percent pos calculation to demuxer.c
reimar
parents:
12036
diff
changeset
|
769 return DEMUXER_CTRL_DONTKNOW; |
8208
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
770 } |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
771 *((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
|
772 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
|
773 return DEMUXER_CTRL_OK; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
774 |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
775 default: |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
776 return DEMUXER_CTRL_NOTIMPL; |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
777 } |
ae5a2ae1c349
demuxer_control(), percent position and time length query implemented in
arpi
parents:
8123
diff
changeset
|
778 } |
16175 | 779 |
780 | |
781 static int avi_check_file(demuxer_t *demuxer) | |
782 { | |
783 int id=stream_read_dword_le(demuxer->stream); // "RIFF" | |
784 | |
785 if((id==mmioFOURCC('R','I','F','F')) || (id==mmioFOURCC('O','N','2',' '))) { | |
786 stream_read_dword_le(demuxer->stream); //filesize | |
787 id=stream_read_dword_le(demuxer->stream); // "AVI " | |
788 if(id==formtypeAVI) | |
789 return DEMUXER_TYPE_AVI; | |
790 if(id==mmioFOURCC('O','N','2','f')){ | |
20695 | 791 mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_ON2AviFormat); |
16175 | 792 return DEMUXER_TYPE_AVI; |
793 } | |
794 } | |
795 | |
796 return 0; | |
797 } | |
798 | |
799 | |
800 static demuxer_t* demux_open_hack_avi(demuxer_t *demuxer) | |
801 { | |
802 sh_audio_t* sh_a; | |
803 | |
804 demuxer = (demuxer_t*) demux_open_avi(demuxer); | |
805 if(!demuxer) return NULL; // failed to open | |
806 sh_a = (sh_audio_t*)demuxer->audio->sh; | |
807 if(demuxer->audio->id != -2 && sh_a) { | |
808 #ifdef HAVE_OGGVORBIS | |
809 // support for Ogg-in-AVI: | |
810 if(sh_a->format == 0xFFFE) | |
811 demuxer = init_avi_with_ogg(demuxer); | |
812 else if(sh_a->format == 0x674F) { | |
813 stream_t* s; | |
814 demuxer_t *od; | |
815 s = new_ds_stream(demuxer->audio); | |
816 od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL); | |
817 if(!demux_ogg_open(od)) { | |
818 mp_msg( MSGT_DEMUXER,MSGL_ERR,MSGTR_ErrorOpeningOGGDemuxer); | |
819 free_stream(s); | |
820 demuxer->audio->id = -2; | |
821 } else | |
822 demuxer = new_demuxers_demuxer(demuxer,od,demuxer); | |
823 } | |
824 #endif | |
825 } | |
826 | |
827 return demuxer; | |
828 } | |
829 | |
830 | |
831 demuxer_desc_t demuxer_desc_avi = { | |
832 "AVI demuxer", | |
833 "avi", | |
834 "AVI", | |
835 "Arpi?", | |
836 "AVI files, including non interleaved files", | |
837 DEMUXER_TYPE_AVI, | |
838 1, // safe autodetect | |
839 avi_check_file, | |
840 demux_avi_fill_buffer, | |
841 demux_open_hack_avi, | |
842 demux_close_avi, | |
843 demux_seek_avi, | |
16199
acb7885f916d
demux_avi_control() missing in avi's demuxer struct.
ods15
parents:
16175
diff
changeset
|
844 demux_avi_control |
16175 | 845 }; |
16211
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
846 |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
847 demuxer_desc_t demuxer_desc_avi_ni = { |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
848 "AVI demuxer, non-interleaved", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
849 "avini", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
850 "AVI", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
851 "Arpi?", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
852 "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
|
853 DEMUXER_TYPE_AVI, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
854 1, // safe autodetect |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
855 avi_check_file, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
856 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
|
857 demux_open_hack_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
858 demux_close_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
859 demux_seek_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
860 demux_avi_control |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
861 }; |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
862 |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
863 demuxer_desc_t demuxer_desc_avi_nini = { |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
864 "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
|
865 "avinini", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
866 "AVI", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
867 "Arpi?", |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
868 "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
|
869 DEMUXER_TYPE_AVI, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
870 1, // safe autodetect |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
871 avi_check_file, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
872 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
|
873 demux_open_hack_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
874 demux_close_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
875 demux_seek_avi, |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
876 demux_avi_control |
391b89e20a56
100l: fix avi demuxing for ni and nini cases, allow forcing ni and nini
rtognimp
parents:
16199
diff
changeset
|
877 }; |