Mercurial > libavformat.hg
annotate avidec.c @ 3068:9cc9ff5aff9c libavformat
set bps to uncompressed original sound data for compressed audio
according to aiff specs, qt set it to 16 for mace and ima4,
fail if block align is not set.
author | bcoudurier |
---|---|
date | Mon, 25 Feb 2008 12:00:31 +0000 |
parents | f0665d1388ad |
children | 0f8d91124c84 |
rev | line source |
---|---|
0 | 1 /* |
1415
3b00fb8ef8e4
replace coder/decoder file description in libavformat by muxer/demuxer
aurel
parents:
1358
diff
changeset
|
2 * AVI demuxer |
0 | 3 * Copyright (c) 2001 Fabrice Bellard. |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1298
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1298
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1298
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1298
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1298
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1298
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
21 #include "avformat.h" | |
22 #include "avi.h" | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
23 #include "dv.h" |
1172
6a5e58d2114b
move common stuff from avienc.c and wav.c to new file riff.c
mru
parents:
1169
diff
changeset
|
24 #include "riff.h" |
0 | 25 |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
26 #undef NDEBUG |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
27 #include <assert.h> |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
28 |
0 | 29 //#define DEBUG |
311 | 30 //#define DEBUG_SEEK |
0 | 31 |
311 | 32 typedef struct AVIStream { |
701 | 33 int64_t frame_offset; /* current frame (video) or byte (audio) counter |
311 | 34 (used to compute the pts) */ |
701 | 35 int remaining; |
36 int packet_size; | |
37 | |
311 | 38 int scale; |
885 | 39 int rate; |
982 | 40 int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */ |
885 | 41 |
977 | 42 int64_t cum_len; /* temporary storage (used during seek) */ |
885 | 43 |
519 | 44 int prefix; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b' |
45 int prefix_count; | |
311 | 46 } AVIStream; |
0 | 47 |
48 typedef struct { | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
49 int64_t riff_end; |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
50 int64_t movi_end; |
2383 | 51 int64_t fsize; |
0 | 52 offset_t movi_list; |
311 | 53 int index_loaded; |
510 | 54 int is_odml; |
701 | 55 int non_interleaved; |
56 int stream_index; | |
296
252946de6d3f
* DV demuxer is now capable of decoding auxilary audio stream. So,
romansh
parents:
262
diff
changeset
|
57 DVDemuxContext* dv_demux; |
0 | 58 } AVIContext; |
59 | |
2578 | 60 static const char avi_headers[][8] = { |
61 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' }, | |
62 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' }, | |
63 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19}, | |
2579 | 64 { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' }, |
2584 | 65 { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' }, |
2578 | 66 { 0 } |
67 }; | |
68 | |
469
6a4cc19e8d9b
exporting keyframe flags, fixes keyframe stuff with streamcopy
michael
parents:
466
diff
changeset
|
69 static int avi_load_index(AVFormatContext *s); |
979 | 70 static int guess_ni_flag(AVFormatContext *s); |
469
6a4cc19e8d9b
exporting keyframe flags, fixes keyframe stuff with streamcopy
michael
parents:
466
diff
changeset
|
71 |
0 | 72 #ifdef DEBUG |
73 static void print_tag(const char *str, unsigned int tag, int size) | |
74 { | |
75 printf("%s: tag=%c%c%c%c size=0x%x\n", | |
76 str, tag & 0xff, | |
77 (tag >> 8) & 0xff, | |
78 (tag >> 16) & 0xff, | |
79 (tag >> 24) & 0xff, | |
80 size); | |
81 } | |
82 #endif | |
83 | |
92
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
84 static int get_riff(AVIContext *avi, ByteIOContext *pb) |
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
85 { |
2578 | 86 char header[8]; |
87 int i; | |
88 | |
92
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
89 /* check RIFF header */ |
2578 | 90 get_buffer(pb, header, 4); |
92
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
91 avi->riff_end = get_le32(pb); /* RIFF chunk size */ |
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
92 avi->riff_end += url_ftell(pb); /* RIFF chunk end */ |
2578 | 93 get_buffer(pb, header+4, 4); |
94 | |
95 for(i=0; avi_headers[i][0]; i++) | |
96 if(!memcmp(header, avi_headers[i], 8)) | |
97 break; | |
98 if(!avi_headers[i][0]) | |
99 return -1; | |
100 | |
101 if(header[7] == 0x19) | |
1761 | 102 av_log(NULL, AV_LOG_INFO, "file has been generated with a totally broken muxer\n"); |
885 | 103 |
92
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
104 return 0; |
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
105 } |
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
106 |
977 | 107 static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){ |
984
b644fe79f7a2
fixing av sync in videotest.avi (index doesnt match chunks, header doesnt indicate that)
michael
parents:
983
diff
changeset
|
108 AVIContext *avi = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
109 ByteIOContext *pb = s->pb; |
977 | 110 int longs_pre_entry= get_le16(pb); |
111 int index_sub_type = get_byte(pb); | |
112 int index_type = get_byte(pb); | |
113 int entries_in_use = get_le32(pb); | |
114 int chunk_id = get_le32(pb); | |
115 int64_t base = get_le64(pb); | |
116 int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0'); | |
117 AVStream *st; | |
118 AVIStream *ast; | |
119 int i; | |
984
b644fe79f7a2
fixing av sync in videotest.avi (index doesnt match chunks, header doesnt indicate that)
michael
parents:
983
diff
changeset
|
120 int64_t last_pos= -1; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
121 int64_t filesize= url_fsize(s->pb); |
977 | 122 |
1277 | 123 #ifdef DEBUG_SEEK |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
124 av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n", |
1277 | 125 longs_pre_entry,index_type, entries_in_use, chunk_id, base); |
126 #endif | |
977 | 127 |
128 if(stream_id > s->nb_streams || stream_id < 0) | |
129 return -1; | |
130 st= s->streams[stream_id]; | |
131 ast = st->priv_data; | |
132 | |
133 if(index_sub_type) | |
134 return -1; | |
135 | |
136 get_le32(pb); | |
137 | |
138 if(index_type && longs_pre_entry != 2) | |
139 return -1; | |
140 if(index_type>1) | |
141 return -1; | |
142 | |
1277 | 143 if(filesize > 0 && base >= filesize){ |
144 av_log(s, AV_LOG_ERROR, "ODML index invalid\n"); | |
145 if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF) | |
146 base &= 0xFFFFFFFF; | |
147 else | |
148 return -1; | |
149 } | |
150 | |
977 | 151 for(i=0; i<entries_in_use; i++){ |
152 if(index_type){ | |
979 | 153 int64_t pos= get_le32(pb) + base - 8; |
977 | 154 int len = get_le32(pb); |
979 | 155 int key= len >= 0; |
156 len &= 0x7FFFFFFF; | |
977 | 157 |
1277 | 158 #ifdef DEBUG_SEEK |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
159 av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len); |
1277 | 160 #endif |
984
b644fe79f7a2
fixing av sync in videotest.avi (index doesnt match chunks, header doesnt indicate that)
michael
parents:
983
diff
changeset
|
161 if(last_pos == pos || pos == base - 8) |
b644fe79f7a2
fixing av sync in videotest.avi (index doesnt match chunks, header doesnt indicate that)
michael
parents:
983
diff
changeset
|
162 avi->non_interleaved= 1; |
b644fe79f7a2
fixing av sync in videotest.avi (index doesnt match chunks, header doesnt indicate that)
michael
parents:
983
diff
changeset
|
163 else |
1522
68620a6be643
fix support for avis with sample_size > packet size
michael
parents:
1489
diff
changeset
|
164 av_add_index_entry(st, pos, ast->cum_len / FFMAX(1, ast->sample_size), len, 0, key ? AVINDEX_KEYFRAME : 0); |
977 | 165 |
166 if(ast->sample_size) | |
1522
68620a6be643
fix support for avis with sample_size > packet size
michael
parents:
1489
diff
changeset
|
167 ast->cum_len += len; |
977 | 168 else |
169 ast->cum_len ++; | |
984
b644fe79f7a2
fixing av sync in videotest.avi (index doesnt match chunks, header doesnt indicate that)
michael
parents:
983
diff
changeset
|
170 last_pos= pos; |
977 | 171 }else{ |
1144 | 172 int64_t offset, pos; |
173 int duration; | |
174 offset = get_le64(pb); | |
175 get_le32(pb); /* size */ | |
176 duration = get_le32(pb); | |
177 pos = url_ftell(pb); | |
977 | 178 |
179 url_fseek(pb, offset+8, SEEK_SET); | |
180 read_braindead_odml_indx(s, frame_num); | |
181 frame_num += duration; | |
182 | |
183 url_fseek(pb, pos, SEEK_SET); | |
184 } | |
185 } | |
1277 | 186 avi->index_loaded=1; |
977 | 187 return 0; |
188 } | |
189 | |
983
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
190 static void clean_index(AVFormatContext *s){ |
1277 | 191 int i; |
192 int64_t j; | |
983
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
193 |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
194 for(i=0; i<s->nb_streams; i++){ |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
195 AVStream *st = s->streams[i]; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
196 AVIStream *ast = st->priv_data; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
197 int n= st->nb_index_entries; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
198 int max= ast->sample_size; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
199 int64_t pos, size, ts; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
200 |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
201 if(n != 1 || ast->sample_size==0) |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
202 continue; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
203 |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
204 while(max < 1024) max+=max; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
205 |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
206 pos= st->index_entries[0].pos; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
207 size= st->index_entries[0].size; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
208 ts= st->index_entries[0].timestamp; |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
209 |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
210 for(j=0; j<size; j+=max){ |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
211 av_add_index_entry(st, pos+j, ts + j/ast->sample_size, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME); |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
212 } |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
213 } |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
214 } |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
215 |
1256 | 216 static int avi_read_tag(ByteIOContext *pb, char *buf, int maxlen, unsigned int size) |
217 { | |
218 offset_t i = url_ftell(pb); | |
219 size += (size & 1); | |
220 get_strz(pb, buf, maxlen); | |
221 url_fseek(pb, i+size, SEEK_SET); | |
222 return 0; | |
223 } | |
224 | |
0 | 225 static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) |
226 { | |
227 AVIContext *avi = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
228 ByteIOContext *pb = s->pb; |
98
cae6ddfadf51
AVI type 1 support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
92
diff
changeset
|
229 uint32_t tag, tag1, handler; |
703 | 230 int codec_type, stream_index, frame_period, bit_rate; |
188
6c9d6422a2f6
update duration and start_time - add av_new_stream() usage
bellard
parents:
149
diff
changeset
|
231 unsigned int size, nb_frames; |
1785
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
232 int i; |
0 | 233 AVStream *st; |
1144 | 234 AVIStream *ast = NULL; |
1298
29fba975df47
Allow to get the the track number in the IPRT (part) tag in AVI.
gpoirier
parents:
1296
diff
changeset
|
235 char str_track[4]; |
2584 | 236 int avih_width=0, avih_height=0; |
237 int amv_file_format=0; | |
0 | 238 |
701 | 239 avi->stream_index= -1; |
885 | 240 |
92
5a4b5f03d13e
OpenDML AVI > 2Gb support patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
91
diff
changeset
|
241 if (get_riff(avi, pb) < 0) |
0 | 242 return -1; |
243 | |
2383 | 244 avi->fsize = url_fsize(pb); |
245 if(avi->fsize<=0) | |
246 avi->fsize= avi->riff_end; | |
247 | |
0 | 248 /* first list tag */ |
249 stream_index = -1; | |
250 codec_type = -1; | |
251 frame_period = 0; | |
252 for(;;) { | |
253 if (url_feof(pb)) | |
254 goto fail; | |
255 tag = get_le32(pb); | |
256 size = get_le32(pb); | |
257 #ifdef DEBUG | |
258 print_tag("tag", tag, size); | |
259 #endif | |
260 | |
261 switch(tag) { | |
262 case MKTAG('L', 'I', 'S', 'T'): | |
263 /* ignored, except when start of video packets */ | |
264 tag1 = get_le32(pb); | |
265 #ifdef DEBUG | |
266 print_tag("list", tag1, 0); | |
267 #endif | |
268 if (tag1 == MKTAG('m', 'o', 'v', 'i')) { | |
311 | 269 avi->movi_list = url_ftell(pb) - 4; |
1286 | 270 if(size) avi->movi_end = avi->movi_list + size + (size & 1); |
764
cdb845a57ae4
drop most url_fileno() calls (allows to use ByteIOContext directly in caller apps instead of URLProtocol)
aurel
parents:
743
diff
changeset
|
271 else avi->movi_end = url_fsize(pb); |
0 | 272 #ifdef DEBUG |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
273 printf("movi end=%"PRIx64"\n", avi->movi_end); |
0 | 274 #endif |
275 goto end_of_header; | |
276 } | |
277 break; | |
510 | 278 case MKTAG('d', 'm', 'l', 'h'): |
887 | 279 avi->is_odml = 1; |
280 url_fskip(pb, size + (size & 1)); | |
281 break; | |
2584 | 282 case MKTAG('a', 'm', 'v', 'h'): |
283 amv_file_format=1; | |
0 | 284 case MKTAG('a', 'v', 'i', 'h'): |
887 | 285 /* avi header */ |
0 | 286 /* using frame_period is bad idea */ |
287 frame_period = get_le32(pb); | |
288 bit_rate = get_le32(pb) * 8; | |
981
55519fa957c3
fix demuxing of XviD_with_3_AAC-HE_audio_streams.avi
michael
parents:
980
diff
changeset
|
289 get_le32(pb); |
55519fa957c3
fix demuxing of XviD_with_3_AAC-HE_audio_streams.avi
michael
parents:
980
diff
changeset
|
290 avi->non_interleaved |= get_le32(pb) & AVIF_MUSTUSEINDEX; |
55519fa957c3
fix demuxing of XviD_with_3_AAC-HE_audio_streams.avi
michael
parents:
980
diff
changeset
|
291 |
55519fa957c3
fix demuxing of XviD_with_3_AAC-HE_audio_streams.avi
michael
parents:
980
diff
changeset
|
292 url_fskip(pb, 2 * 4); |
1785
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
293 get_le32(pb); |
2584 | 294 get_le32(pb); |
295 avih_width=get_le32(pb); | |
296 avih_height=get_le32(pb); | |
1785
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
297 |
2584 | 298 url_fskip(pb, size - 10 * 4); |
1785
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
299 break; |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
300 case MKTAG('s', 't', 'r', 'h'): |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
301 /* stream header */ |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
302 |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
303 tag1 = get_le32(pb); |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
304 handler = get_le32(pb); /* codec tag */ |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
305 |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
306 if(tag1 == MKTAG('p', 'a', 'd', 's')){ |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
307 url_fskip(pb, size - 8); |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
308 break; |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
309 }else{ |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
310 stream_index++; |
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
311 st = av_new_stream(s, stream_index); |
0 | 312 if (!st) |
313 goto fail; | |
462
b69898ffc92a
move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents:
457
diff
changeset
|
314 |
311 | 315 ast = av_mallocz(sizeof(AVIStream)); |
316 if (!ast) | |
317 goto fail; | |
318 st->priv_data = ast; | |
887 | 319 } |
2584 | 320 if(amv_file_format) |
321 tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s'); | |
1785
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
322 |
471 | 323 #ifdef DEBUG |
1441
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
324 print_tag("strh", tag1, -1); |
471 | 325 #endif |
703 | 326 if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){ |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
327 int64_t dv_dur; |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
328 |
885 | 329 /* |
887 | 330 * After some consideration -- I don't think we |
331 * have to support anything but DV in a type1 AVIs. | |
332 */ | |
333 if (s->nb_streams != 1) | |
334 goto fail; | |
885 | 335 |
887 | 336 if (handler != MKTAG('d', 'v', 's', 'd') && |
337 handler != MKTAG('d', 'v', 'h', 'd') && | |
338 handler != MKTAG('d', 'v', 's', 'l')) | |
339 goto fail; | |
885 | 340 |
887 | 341 ast = s->streams[0]->priv_data; |
342 av_freep(&s->streams[0]->codec->extradata); | |
343 av_freep(&s->streams[0]); | |
344 s->nb_streams = 0; | |
1488
41a7ed2b064a
Fix avidec.c compilation when dv demuxer is disabled.
aurel
parents:
1472
diff
changeset
|
345 if (ENABLE_DV_DEMUXER) { |
1489 | 346 avi->dv_demux = dv_init_demux(s); |
347 if (!avi->dv_demux) | |
348 goto fail; | |
1488
41a7ed2b064a
Fix avidec.c compilation when dv demuxer is disabled.
aurel
parents:
1472
diff
changeset
|
349 } |
887 | 350 s->streams[0]->priv_data = ast; |
351 url_fskip(pb, 3 * 4); | |
352 ast->scale = get_le32(pb); | |
353 ast->rate = get_le32(pb); | |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
354 url_fskip(pb, 4); /* start time */ |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
355 |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
356 dv_dur = get_le32(pb); |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
357 if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) { |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
358 dv_dur *= AV_TIME_BASE; |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
359 s->duration = av_rescale(dv_dur, ast->scale, ast->rate); |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
360 } |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
361 /* |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
362 * else, leave duration alone; timing estimation in utils.c |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
363 * will make a guess based on bit rate. |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
364 */ |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
365 |
887 | 366 stream_index = s->nb_streams - 1; |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
367 url_fskip(pb, size - 9*4); |
703 | 368 break; |
369 } | |
370 | |
1785
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
371 assert(stream_index < s->nb_streams); |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
372 st->codec->stream_codec_tag= handler; |
703 | 373 |
374 get_le32(pb); /* flags */ | |
375 get_le16(pb); /* priority */ | |
376 get_le16(pb); /* language */ | |
377 get_le32(pb); /* initial frame */ | |
378 ast->scale = get_le32(pb); | |
379 ast->rate = get_le32(pb); | |
380 if(ast->scale && ast->rate){ | |
381 }else if(frame_period){ | |
382 ast->rate = 1000000; | |
383 ast->scale = frame_period; | |
384 }else{ | |
385 ast->rate = 25; | |
386 ast->scale = 1; | |
387 } | |
388 av_set_pts_info(st, 64, ast->scale, ast->rate); | |
885 | 389 |
989 | 390 ast->cum_len=get_le32(pb); /* start */ |
703 | 391 nb_frames = get_le32(pb); |
392 | |
393 st->start_time = 0; | |
743 | 394 st->duration = nb_frames; |
703 | 395 get_le32(pb); /* buffer size */ |
396 get_le32(pb); /* quality */ | |
397 ast->sample_size = get_le32(pb); /* sample ssize */ | |
1522
68620a6be643
fix support for avis with sample_size > packet size
michael
parents:
1489
diff
changeset
|
398 ast->cum_len *= FFMAX(1, ast->sample_size); |
703 | 399 // av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d\n", ast->rate, ast->scale, ast->start, ast->sample_size); |
400 | |
401 switch(tag1) { | |
887 | 402 case MKTAG('v', 'i', 'd', 's'): |
0 | 403 codec_type = CODEC_TYPE_VIDEO; |
75
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
404 |
703 | 405 ast->sample_size = 0; |
0 | 406 break; |
407 case MKTAG('a', 'u', 'd', 's'): | |
703 | 408 codec_type = CODEC_TYPE_AUDIO; |
73
d40ddc73858a
reversing not yet reversed changes from r1.7 -> r1.8 except the static/const stuff
michaelni
parents:
65
diff
changeset
|
409 break; |
471 | 410 case MKTAG('t', 'x', 't', 's'): |
885 | 411 //FIXME |
471 | 412 codec_type = CODEC_TYPE_DATA; //CODEC_TYPE_SUB ? FIXME |
413 break; | |
73
d40ddc73858a
reversing not yet reversed changes from r1.7 -> r1.8 except the static/const stuff
michaelni
parents:
65
diff
changeset
|
414 default: |
534 | 415 av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1); |
73
d40ddc73858a
reversing not yet reversed changes from r1.7 -> r1.8 except the static/const stuff
michaelni
parents:
65
diff
changeset
|
416 goto fail; |
0 | 417 } |
1522
68620a6be643
fix support for avis with sample_size > packet size
michael
parents:
1489
diff
changeset
|
418 ast->frame_offset= ast->cum_len; |
703 | 419 url_fskip(pb, size - 12 * 4); |
0 | 420 break; |
421 case MKTAG('s', 't', 'r', 'f'): | |
422 /* stream header */ | |
1785
2376ab11ea73
support yet another broken avi (filedoesitbetter.avi) which has a wrong stream count
michael
parents:
1761
diff
changeset
|
423 if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) { |
0 | 424 url_fskip(pb, size); |
425 } else { | |
426 st = s->streams[stream_index]; | |
427 switch(codec_type) { | |
428 case CODEC_TYPE_VIDEO: | |
2584 | 429 if(amv_file_format){ |
430 st->codec->width=avih_width; | |
431 st->codec->height=avih_height; | |
432 st->codec->codec_type = CODEC_TYPE_VIDEO; | |
433 st->codec->codec_id = CODEC_ID_AMV; | |
434 url_fskip(pb, size); | |
435 break; | |
436 } | |
0 | 437 get_le32(pb); /* size */ |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
438 st->codec->width = get_le32(pb); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
439 st->codec->height = get_le32(pb); |
0 | 440 get_le16(pb); /* panes */ |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
441 st->codec->bits_per_sample= get_le16(pb); /* depth */ |
0 | 442 tag1 = get_le32(pb); |
75
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
443 get_le32(pb); /* ImageSize */ |
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
444 get_le32(pb); /* XPelsPerMeter */ |
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
445 get_le32(pb); /* YPelsPerMeter */ |
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
446 get_le32(pb); /* ClrUsed */ |
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
447 get_le32(pb); /* ClrImportant */ |
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
448 |
2315 | 449 if (tag1 == MKTAG('D', 'X', 'S', 'B')) { |
450 st->codec->codec_type = CODEC_TYPE_SUBTITLE; | |
451 st->codec->codec_tag = tag1; | |
452 st->codec->codec_id = CODEC_ID_XSUB; | |
453 break; | |
454 } | |
455 | |
1441
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
456 if(size > 10*4 && size<(1<<30)){ |
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
457 st->codec->extradata_size= size - 10*4; |
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
458 st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
459 get_buffer(pb, st->codec->extradata, st->codec->extradata_size); |
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
460 } |
885 | 461 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
462 if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly |
76 | 463 get_byte(pb); |
75
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
464 |
297
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
465 /* Extract palette from extradata if bpp <= 8 */ |
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
466 /* This code assumes that extradata contains only palette */ |
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
467 /* This is true for all paletted codecs implemented in ffmpeg */ |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
468 if (st->codec->extradata_size && (st->codec->bits_per_sample <= 8)) { |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
469 st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); |
297
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
470 #ifdef WORDS_BIGENDIAN |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
471 for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
472 st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]); |
297
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
473 #else |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
474 memcpy(st->codec->palctrl->palette, st->codec->extradata, |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
475 FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); |
297
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
476 #endif |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
477 st->codec->palctrl->palette_changed = 1; |
297
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
478 } |
85d558a18134
Make avi and asf demuxer export palette in palctrl
rtognimp
parents:
296
diff
changeset
|
479 |
0 | 480 #ifdef DEBUG |
481 print_tag("video", tag1, 0); | |
482 #endif | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
483 st->codec->codec_type = CODEC_TYPE_VIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
484 st->codec->codec_tag = tag1; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
485 st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1); |
2023 | 486 st->need_parsing = AVSTREAM_PARSE_HEADERS; // this is needed to get the pict type which is needed for generating correct pts |
75
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
73
diff
changeset
|
487 // url_fskip(pb, size - 5 * 4); |
0 | 488 break; |
73
d40ddc73858a
reversing not yet reversed changes from r1.7 -> r1.8 except the static/const stuff
michaelni
parents:
65
diff
changeset
|
489 case CODEC_TYPE_AUDIO: |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
490 get_wav_header(pb, st->codec, size); |
988 | 491 if(ast->sample_size && st->codec->block_align && ast->sample_size % st->codec->block_align) |
492 av_log(s, AV_LOG_DEBUG, "invalid sample size or block align detected\n"); | |
13
8a5285a0ca2f
Fix for odd strf tag in Stargate SG-1 - 3x18 - Shades of Grey.avi
mmu_man
parents:
5
diff
changeset
|
493 if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ |
8a5285a0ca2f
Fix for odd strf tag in Stargate SG-1 - 3x18 - Shades of Grey.avi
mmu_man
parents:
5
diff
changeset
|
494 url_fskip(pb, 1); |
1527 | 495 /* Force parsing as several audio frames can be in |
2020 | 496 * one packet and timestamps refer to packet start*/ |
497 st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; | |
1472
49d5a5ca2987
get rid of CODEC_ID_MPEG4AAC after next version bump, and change it to CODEC_ID_AAC where used
bcoudurier
parents:
1443
diff
changeset
|
498 /* ADTS header is in extradata, AAC without header must be stored as exact frames, parser not needed and it will fail */ |
49d5a5ca2987
get rid of CODEC_ID_MPEG4AAC after next version bump, and change it to CODEC_ID_AAC where used
bcoudurier
parents:
1443
diff
changeset
|
499 if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size) |
2023 | 500 st->need_parsing = AVSTREAM_PARSE_NONE; |
1526
135565ec768d
Clean up XAN DPCM hack and set codec_tag to 0 for XAN DPCM, AVI files
diego
parents:
1522
diff
changeset
|
501 /* AVI files with Xan DPCM audio (wrongly) declare PCM |
135565ec768d
Clean up XAN DPCM hack and set codec_tag to 0 for XAN DPCM, AVI files
diego
parents:
1522
diff
changeset
|
502 * audio in the header but have Axan as stream_code_tag. */ |
135565ec768d
Clean up XAN DPCM hack and set codec_tag to 0 for XAN DPCM, AVI files
diego
parents:
1522
diff
changeset
|
503 if (st->codec->stream_codec_tag == ff_get_fourcc("Axan")){ |
135565ec768d
Clean up XAN DPCM hack and set codec_tag to 0 for XAN DPCM, AVI files
diego
parents:
1522
diff
changeset
|
504 st->codec->codec_id = CODEC_ID_XAN_DPCM; |
135565ec768d
Clean up XAN DPCM hack and set codec_tag to 0 for XAN DPCM, AVI files
diego
parents:
1522
diff
changeset
|
505 st->codec->codec_tag = 0; |
135565ec768d
Clean up XAN DPCM hack and set codec_tag to 0 for XAN DPCM, AVI files
diego
parents:
1522
diff
changeset
|
506 } |
2584 | 507 if (amv_file_format) |
508 st->codec->codec_id = CODEC_ID_ADPCM_IMA_AMV; | |
0 | 509 break; |
510 default: | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
511 st->codec->codec_type = CODEC_TYPE_DATA; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
512 st->codec->codec_id= CODEC_ID_NONE; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
513 st->codec->codec_tag= 0; |
0 | 514 url_fskip(pb, size); |
515 break; | |
516 } | |
517 } | |
518 break; | |
977 | 519 case MKTAG('i', 'n', 'd', 'x'): |
520 i= url_ftell(pb); | |
1294
12398b868e18
ignore index parameter to ignore the ODML index in avi
michael
parents:
1286
diff
changeset
|
521 if(!url_is_streamed(pb) && !(s->flags & AVFMT_FLAG_IGNIDX)){ |
1115 | 522 read_braindead_odml_indx(s, 0); |
523 } | |
977 | 524 url_fseek(pb, i+size, SEEK_SET); |
525 break; | |
2877 | 526 case MKTAG('v', 'p', 'r', 'p'): |
527 if(stream_index < (unsigned)s->nb_streams && size > 9*4){ | |
528 AVRational active, active_aspect; | |
529 | |
530 st = s->streams[stream_index]; | |
531 get_le32(pb); | |
532 get_le32(pb); | |
533 get_le32(pb); | |
534 get_le32(pb); | |
535 get_le32(pb); | |
536 | |
537 active_aspect.num= get_le16(pb); | |
538 active_aspect.den= get_le16(pb); | |
539 active.num = get_le32(pb); | |
540 active.den = get_le32(pb); | |
541 get_le32(pb); //nbFieldsPerFrame | |
542 | |
543 if(active_aspect.num && active_aspect.den && active.num && active.den){ | |
544 st->codec->sample_aspect_ratio= av_div_q(active_aspect, active); | |
545 //av_log(s, AV_LOG_ERROR, "vprp %d/%d %d/%d\n", active_aspect.num, active_aspect.den, active.num, active.den); | |
546 } | |
547 size -= 9*4; | |
548 } | |
549 url_fseek(pb, size, SEEK_CUR); | |
550 break; | |
1256 | 551 case MKTAG('I', 'N', 'A', 'M'): |
552 avi_read_tag(pb, s->title, sizeof(s->title), size); | |
553 break; | |
554 case MKTAG('I', 'A', 'R', 'T'): | |
555 avi_read_tag(pb, s->author, sizeof(s->author), size); | |
556 break; | |
557 case MKTAG('I', 'C', 'O', 'P'): | |
558 avi_read_tag(pb, s->copyright, sizeof(s->copyright), size); | |
559 break; | |
560 case MKTAG('I', 'C', 'M', 'T'): | |
561 avi_read_tag(pb, s->comment, sizeof(s->comment), size); | |
562 break; | |
563 case MKTAG('I', 'G', 'N', 'R'): | |
564 avi_read_tag(pb, s->genre, sizeof(s->genre), size); | |
565 break; | |
1296 | 566 case MKTAG('I', 'P', 'R', 'D'): |
567 avi_read_tag(pb, s->album, sizeof(s->album), size); | |
568 break; | |
1298
29fba975df47
Allow to get the the track number in the IPRT (part) tag in AVI.
gpoirier
parents:
1296
diff
changeset
|
569 case MKTAG('I', 'P', 'R', 'T'): |
29fba975df47
Allow to get the the track number in the IPRT (part) tag in AVI.
gpoirier
parents:
1296
diff
changeset
|
570 avi_read_tag(pb, str_track, sizeof(str_track), size); |
29fba975df47
Allow to get the the track number in the IPRT (part) tag in AVI.
gpoirier
parents:
1296
diff
changeset
|
571 sscanf(str_track, "%d", &s->track); |
29fba975df47
Allow to get the the track number in the IPRT (part) tag in AVI.
gpoirier
parents:
1296
diff
changeset
|
572 break; |
0 | 573 default: |
1894 | 574 if(size > 1000000){ |
575 av_log(s, AV_LOG_ERROR, "well something went wrong during header parsing, " | |
576 "ill ignore it and try to continue anyway\n"); | |
577 avi->movi_list = url_ftell(pb) - 4; | |
578 avi->movi_end = url_fsize(pb); | |
579 goto end_of_header; | |
580 } | |
0 | 581 /* skip tag */ |
582 size += (size & 1); | |
583 url_fskip(pb, size); | |
584 break; | |
585 } | |
586 } | |
587 end_of_header: | |
588 /* check stream number */ | |
589 if (stream_index != s->nb_streams - 1) { | |
590 fail: | |
591 for(i=0;i<s->nb_streams;i++) { | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
592 av_freep(&s->streams[i]->codec->extradata); |
0 | 593 av_freep(&s->streams[i]); |
594 } | |
595 return -1; | |
596 } | |
597 | |
1115 | 598 if(!avi->index_loaded && !url_is_streamed(pb)) |
977 | 599 avi_load_index(s); |
469
6a4cc19e8d9b
exporting keyframe flags, fixes keyframe stuff with streamcopy
michael
parents:
466
diff
changeset
|
600 avi->index_loaded = 1; |
979 | 601 avi->non_interleaved |= guess_ni_flag(s); |
983
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
602 if(avi->non_interleaved) |
558381bf97d2
support seeking in RenderAvi.avi (audio stream == single huge chunk)
michael
parents:
982
diff
changeset
|
603 clean_index(s); |
885 | 604 |
0 | 605 return 0; |
606 } | |
607 | |
608 static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) | |
609 { | |
610 AVIContext *avi = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
611 ByteIOContext *pb = s->pb; |
510 | 612 int n, d[8], size; |
569 | 613 offset_t i, sync; |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
614 void* dstr; |
885 | 615 |
1488
41a7ed2b064a
Fix avidec.c compilation when dv demuxer is disabled.
aurel
parents:
1472
diff
changeset
|
616 if (ENABLE_DV_DEMUXER && avi->dv_demux) { |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
617 size = dv_get_packet(avi->dv_demux, pkt); |
887 | 618 if (size >= 0) |
619 return size; | |
149 | 620 } |
885 | 621 |
701 | 622 if(avi->non_interleaved){ |
851
62e66722e9bb
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
842
diff
changeset
|
623 int best_stream_index = 0; |
701 | 624 AVStream *best_st= NULL; |
625 AVIStream *best_ast; | |
626 int64_t best_ts= INT64_MAX; | |
627 int i; | |
885 | 628 |
701 | 629 for(i=0; i<s->nb_streams; i++){ |
630 AVStream *st = s->streams[i]; | |
631 AVIStream *ast = st->priv_data; | |
632 int64_t ts= ast->frame_offset; | |
569 | 633 |
701 | 634 if(ast->sample_size) |
635 ts /= ast->sample_size; | |
636 ts= av_rescale(ts, AV_TIME_BASE * (int64_t)st->time_base.num, st->time_base.den); | |
637 | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
638 // av_log(NULL, AV_LOG_DEBUG, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset); |
701 | 639 if(ts < best_ts){ |
640 best_ts= ts; | |
641 best_st= st; | |
642 best_stream_index= i; | |
643 } | |
644 } | |
645 best_ast = best_st->priv_data; | |
646 best_ts= av_rescale(best_ts, best_st->time_base.den, AV_TIME_BASE * (int64_t)best_st->time_base.num); //FIXME a little ugly | |
647 if(best_ast->remaining) | |
648 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); | |
649 else | |
650 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY); | |
651 | |
652 // av_log(NULL, AV_LOG_DEBUG, "%d\n", i); | |
653 if(i>=0){ | |
654 int64_t pos= best_st->index_entries[i].pos; | |
980 | 655 pos += best_ast->packet_size - best_ast->remaining; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
656 url_fseek(s->pb, pos + 8, SEEK_SET); |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
657 // av_log(NULL, AV_LOG_DEBUG, "pos=%"PRId64"\n", pos); |
885 | 658 |
982 | 659 assert(best_ast->remaining <= best_ast->packet_size); |
660 | |
981
55519fa957c3
fix demuxing of XviD_with_3_AAC-HE_audio_streams.avi
michael
parents:
980
diff
changeset
|
661 avi->stream_index= best_stream_index; |
55519fa957c3
fix demuxing of XviD_with_3_AAC-HE_audio_streams.avi
michael
parents:
980
diff
changeset
|
662 if(!best_ast->remaining) |
982 | 663 best_ast->packet_size= |
981
55519fa957c3
fix demuxing of XviD_with_3_AAC-HE_audio_streams.avi
michael
parents:
980
diff
changeset
|
664 best_ast->remaining= best_st->index_entries[i].size; |
701 | 665 } |
666 } | |
885 | 667 |
569 | 668 resync: |
701 | 669 if(avi->stream_index >= 0){ |
670 AVStream *st= s->streams[ avi->stream_index ]; | |
671 AVIStream *ast= st->priv_data; | |
672 int size; | |
885 | 673 |
988 | 674 if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM |
701 | 675 size= INT_MAX; |
885 | 676 else if(ast->sample_size < 32) |
701 | 677 size= 64*ast->sample_size; |
678 else | |
679 size= ast->sample_size; | |
680 | |
681 if(size > ast->remaining) | |
682 size= ast->remaining; | |
775 | 683 av_get_packet(pb, pkt, size); |
885 | 684 |
1488
41a7ed2b064a
Fix avidec.c compilation when dv demuxer is disabled.
aurel
parents:
1472
diff
changeset
|
685 if (ENABLE_DV_DEMUXER && avi->dv_demux) { |
701 | 686 dstr = pkt->destruct; |
687 size = dv_produce_packet(avi->dv_demux, pkt, | |
688 pkt->data, pkt->size); | |
689 pkt->destruct = dstr; | |
690 pkt->flags |= PKT_FLAG_KEY; | |
691 } else { | |
692 /* XXX: how to handle B frames in avi ? */ | |
693 pkt->dts = ast->frame_offset; | |
694 // pkt->dts += ast->start; | |
695 if(ast->sample_size) | |
696 pkt->dts /= ast->sample_size; | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
697 //av_log(NULL, AV_LOG_DEBUG, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n", pkt->dts, ast->frame_offset, ast->scale, ast->rate, ast->sample_size, AV_TIME_BASE, avi->stream_index, size); |
701 | 698 pkt->stream_index = avi->stream_index; |
699 | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
700 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { |
1758 | 701 AVIndexEntry *e; |
702 int index; | |
1757
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
703 assert(st->index_entries); |
701 | 704 |
1758 | 705 index= av_index_search_timestamp(st, pkt->dts, 0); |
706 e= &st->index_entries[index]; | |
885 | 707 |
1758 | 708 if(index >= 0 && e->timestamp == ast->frame_offset){ |
709 if (e->flags & AVINDEX_KEYFRAME) | |
710 pkt->flags |= PKT_FLAG_KEY; | |
711 } | |
701 | 712 } else { |
885 | 713 pkt->flags |= PKT_FLAG_KEY; |
701 | 714 } |
715 if(ast->sample_size) | |
716 ast->frame_offset += pkt->size; | |
717 else | |
718 ast->frame_offset++; | |
719 } | |
720 ast->remaining -= size; | |
721 if(!ast->remaining){ | |
722 avi->stream_index= -1; | |
723 ast->packet_size= 0; | |
724 } | |
725 | |
726 return size; | |
727 } | |
728 | |
569 | 729 memset(d, -1, sizeof(int)*8); |
730 for(i=sync=url_ftell(pb); !url_feof(pb); i++) { | |
82 | 731 int j; |
732 | |
733 for(j=0; j<7; j++) | |
734 d[j]= d[j+1]; | |
735 d[7]= get_byte(pb); | |
885 | 736 |
82 | 737 size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24); |
885 | 738 |
519 | 739 if( d[2] >= '0' && d[2] <= '9' |
740 && d[3] >= '0' && d[3] <= '9'){ | |
741 n= (d[2] - '0') * 10 + (d[3] - '0'); | |
742 }else{ | |
743 n= 100; //invalid stream id | |
744 } | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
745 //av_log(NULL, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n); |
2383 | 746 if(i + size > avi->fsize || d[0]<0) |
519 | 747 continue; |
885 | 748 |
82 | 749 //parse ix## |
519 | 750 if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) |
887 | 751 //parse JUNK |
2384 | 752 ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') |
753 ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){ | |
82 | 754 url_fskip(pb, size); |
519 | 755 //av_log(NULL, AV_LOG_DEBUG, "SKIP\n"); |
569 | 756 goto resync; |
82 | 757 } |
510 | 758 |
519 | 759 if( d[0] >= '0' && d[0] <= '9' |
760 && d[1] >= '0' && d[1] <= '9'){ | |
761 n= (d[0] - '0') * 10 + (d[1] - '0'); | |
762 }else{ | |
763 n= 100; //invalid stream id | |
510 | 764 } |
885 | 765 |
82 | 766 //parse ##dc/##wb |
705 | 767 if(n < s->nb_streams){ |
519 | 768 AVStream *st; |
769 AVIStream *ast; | |
770 st = s->streams[n]; | |
771 ast = st->priv_data; | |
885 | 772 |
708 | 773 if( (st->discard >= AVDISCARD_DEFAULT && size==0) |
774 /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & PKT_FLAG_KEY))*/ //FIXME needs a little reordering | |
775 || st->discard >= AVDISCARD_ALL){ | |
776 if(ast->sample_size) ast->frame_offset += pkt->size; | |
777 else ast->frame_offset++; | |
650 | 778 url_fskip(pb, size); |
779 goto resync; | |
780 } | |
519 | 781 |
885 | 782 if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) || |
519 | 783 d[2]*256+d[3] == ast->prefix /*|| |
885 | 784 (d[2] == 'd' && d[3] == 'c') || |
887 | 785 (d[2] == 'w' && d[3] == 'b')*/) { |
519 | 786 |
787 //av_log(NULL, AV_LOG_DEBUG, "OK\n"); | |
788 if(d[2]*256+d[3] == ast->prefix) | |
789 ast->prefix_count++; | |
790 else{ | |
791 ast->prefix= d[2]*256+d[3]; | |
792 ast->prefix_count= 0; | |
793 } | |
794 | |
701 | 795 avi->stream_index= n; |
796 ast->packet_size= size + 8; | |
797 ast->remaining= size; | |
1757
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
798 |
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
799 { |
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
800 uint64_t pos= url_ftell(pb) - 8; |
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
801 if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){ |
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
802 av_add_index_entry(st, pos, ast->frame_offset / FFMAX(1, ast->sample_size), size, 0, AVINDEX_KEYFRAME); |
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
803 } |
9d217a18aa49
dynamic index building so forward and backward seeking in avi without an index is possible
michael
parents:
1721
diff
changeset
|
804 } |
701 | 805 goto resync; |
519 | 806 } |
82 | 807 } |
520
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
808 /* palette changed chunk */ |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
809 if ( d[0] >= '0' && d[0] <= '9' |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
810 && d[1] >= '0' && d[1] <= '9' |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
811 && ((d[2] == 'p' && d[3] == 'c')) |
2383 | 812 && n < s->nb_streams && i + size <= avi->fsize) { |
520
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
813 |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
814 AVStream *st; |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
815 int first, clr, flags, k, p; |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
816 |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
817 st = s->streams[n]; |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
818 |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
819 first = get_byte(pb); |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
820 clr = get_byte(pb); |
887 | 821 if(!clr) /* all 256 colors used */ |
822 clr = 256; | |
520
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
823 flags = get_le16(pb); |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
824 p = 4; |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
825 for (k = first; k < clr + first; k++) { |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
826 int r, g, b; |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
827 r = get_byte(pb); |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
828 g = get_byte(pb); |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
829 b = get_byte(pb); |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
830 get_byte(pb); |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
831 st->codec->palctrl->palette[k] = b + (g << 8) + (r << 16); |
520
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
832 } |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
833 st->codec->palctrl->palette_changed = 1; |
569 | 834 goto resync; |
520
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
835 } |
5d96fe8f6560
added support for the elusive AVI palette change chunk, courtesy of
melanson
parents:
519
diff
changeset
|
836 |
82 | 837 } |
519 | 838 |
82 | 839 return -1; |
0 | 840 } |
841 | |
311 | 842 /* XXX: we make the implicit supposition that the position are sorted |
843 for each stream */ | |
844 static int avi_read_idx1(AVFormatContext *s, int size) | |
845 { | |
701 | 846 AVIContext *avi = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
847 ByteIOContext *pb = s->pb; |
311 | 848 int nb_index_entries, i; |
849 AVStream *st; | |
850 AVIStream *ast; | |
851 unsigned int index, tag, flags, pos, len; | |
701 | 852 unsigned last_pos= -1; |
885 | 853 |
311 | 854 nb_index_entries = size / 16; |
855 if (nb_index_entries <= 0) | |
856 return -1; | |
857 | |
858 /* read the entries and sort them in each stream component */ | |
859 for(i = 0; i < nb_index_entries; i++) { | |
860 tag = get_le32(pb); | |
861 flags = get_le32(pb); | |
862 pos = get_le32(pb); | |
863 len = get_le32(pb); | |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
864 #if defined(DEBUG_SEEK) |
885 | 865 av_log(NULL, AV_LOG_DEBUG, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", |
311 | 866 i, tag, flags, pos, len); |
867 #endif | |
701 | 868 if(i==0 && pos > avi->movi_list) |
869 avi->movi_list= 0; //FIXME better check | |
980 | 870 pos += avi->movi_list; |
701 | 871 |
311 | 872 index = ((tag & 0xff) - '0') * 10; |
873 index += ((tag >> 8) & 0xff) - '0'; | |
874 if (index >= s->nb_streams) | |
875 continue; | |
876 st = s->streams[index]; | |
877 ast = st->priv_data; | |
885 | 878 |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
879 #if defined(DEBUG_SEEK) |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
880 av_log(NULL, AV_LOG_DEBUG, "%d cum_len=%"PRId64"\n", len, ast->cum_len); |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
881 #endif |
705 | 882 if(last_pos == pos) |
883 avi->non_interleaved= 1; | |
884 else | |
1522
68620a6be643
fix support for avis with sample_size > packet size
michael
parents:
1489
diff
changeset
|
885 av_add_index_entry(st, pos, ast->cum_len / FFMAX(1, ast->sample_size), len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0); |
701 | 886 if(ast->sample_size) |
1522
68620a6be643
fix support for avis with sample_size > packet size
michael
parents:
1489
diff
changeset
|
887 ast->cum_len += len; |
701 | 888 else |
889 ast->cum_len ++; | |
890 last_pos= pos; | |
311 | 891 } |
892 return 0; | |
893 } | |
894 | |
701 | 895 static int guess_ni_flag(AVFormatContext *s){ |
896 int i; | |
897 int64_t last_start=0; | |
898 int64_t first_end= INT64_MAX; | |
885 | 899 |
701 | 900 for(i=0; i<s->nb_streams; i++){ |
901 AVStream *st = s->streams[i]; | |
902 int n= st->nb_index_entries; | |
903 | |
904 if(n <= 0) | |
905 continue; | |
906 | |
907 if(st->index_entries[0].pos > last_start) | |
908 last_start= st->index_entries[0].pos; | |
909 if(st->index_entries[n-1].pos < first_end) | |
910 first_end= st->index_entries[n-1].pos; | |
911 } | |
912 return last_start > first_end; | |
913 } | |
914 | |
311 | 915 static int avi_load_index(AVFormatContext *s) |
916 { | |
917 AVIContext *avi = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
918 ByteIOContext *pb = s->pb; |
311 | 919 uint32_t tag, size; |
343 | 920 offset_t pos= url_ftell(pb); |
885 | 921 |
311 | 922 url_fseek(pb, avi->movi_end, SEEK_SET); |
923 #ifdef DEBUG_SEEK | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
924 printf("movi_end=0x%"PRIx64"\n", avi->movi_end); |
311 | 925 #endif |
926 for(;;) { | |
927 if (url_feof(pb)) | |
928 break; | |
929 tag = get_le32(pb); | |
930 size = get_le32(pb); | |
931 #ifdef DEBUG_SEEK | |
932 printf("tag=%c%c%c%c size=0x%x\n", | |
933 tag & 0xff, | |
934 (tag >> 8) & 0xff, | |
935 (tag >> 16) & 0xff, | |
936 (tag >> 24) & 0xff, | |
937 size); | |
938 #endif | |
939 switch(tag) { | |
940 case MKTAG('i', 'd', 'x', '1'): | |
941 if (avi_read_idx1(s, size) < 0) | |
942 goto skip; | |
943 else | |
944 goto the_end; | |
945 break; | |
946 default: | |
947 skip: | |
948 size += (size & 1); | |
949 url_fskip(pb, size); | |
950 break; | |
951 } | |
952 } | |
953 the_end: | |
343 | 954 url_fseek(pb, pos, SEEK_SET); |
311 | 955 return 0; |
956 } | |
957 | |
558 | 958 static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) |
311 | 959 { |
960 AVIContext *avi = s->priv_data; | |
961 AVStream *st; | |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
962 int i, index; |
311 | 963 int64_t pos; |
964 | |
965 if (!avi->index_loaded) { | |
966 /* we only load the index on demand */ | |
967 avi_load_index(s); | |
968 avi->index_loaded = 1; | |
969 } | |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
970 assert(stream_index>= 0); |
311 | 971 |
972 st = s->streams[stream_index]; | |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
973 index= av_index_search_timestamp(st, timestamp, flags); |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
974 if(index<0) |
311 | 975 return -1; |
885 | 976 |
311 | 977 /* find the position */ |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
978 pos = st->index_entries[index].pos; |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
979 timestamp = st->index_entries[index].timestamp; |
311 | 980 |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
981 // av_log(NULL, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp); |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
982 |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
983 if (ENABLE_DV_DEMUXER && avi->dv_demux) { |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
984 /* One and only one real stream for DV in AVI, and it has video */ |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
985 /* offsets. Calling with other stream indices should have failed */ |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
986 /* the av_index_search_timestamp call above. */ |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
987 assert(stream_index == 0); |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
988 |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
989 /* Feed the DV video stream version of the timestamp to the */ |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
990 /* DV demux so it can synth correct timestamps */ |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
991 dv_offset_reset(avi->dv_demux, timestamp); |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
992 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
993 url_fseek(s->pb, pos, SEEK_SET); |
1629
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
994 avi->stream_index= -1; |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
995 return 0; |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
996 } |
aedce96c28ff
* Fixing seeking with DV-AVI (by Jeff Downs <heydowns at borg dot com>)
romansh
parents:
1527
diff
changeset
|
997 |
311 | 998 for(i = 0; i < s->nb_streams; i++) { |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
999 AVStream *st2 = s->streams[i]; |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1000 AVIStream *ast2 = st2->priv_data; |
701 | 1001 |
1002 ast2->packet_size= | |
1003 ast2->remaining= 0; | |
1004 | |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1005 if (st2->nb_index_entries <= 0) |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1006 continue; |
885 | 1007 |
988 | 1008 // assert(st2->codec->block_align); |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1009 assert(st2->time_base.den == ast2->rate); |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1010 assert(st2->time_base.num == ast2->scale); |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1011 index = av_index_search_timestamp( |
885 | 1012 st2, |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1013 av_rescale(timestamp, st2->time_base.den*(int64_t)st->time_base.num, st->time_base.den * (int64_t)st2->time_base.num), |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1014 flags | AVSEEK_FLAG_BACKWARD); |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1015 if(index<0) |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1016 index=0; |
885 | 1017 |
701 | 1018 if(!avi->non_interleaved){ |
1019 while(index>0 && st2->index_entries[index].pos > pos) | |
1020 index--; | |
1021 while(index+1 < st2->nb_index_entries && st2->index_entries[index].pos < pos) | |
1022 index++; | |
1023 } | |
1024 | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
1025 // av_log(NULL, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp); |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1026 /* extract the current frame number */ |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1027 ast2->frame_offset = st2->index_entries[index].timestamp; |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1028 if(ast2->sample_size) |
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1029 ast2->frame_offset *=ast2->sample_size; |
311 | 1030 } |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1031 |
311 | 1032 /* do the seek */ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2584
diff
changeset
|
1033 url_fseek(s->pb, pos, SEEK_SET); |
701 | 1034 avi->stream_index= -1; |
311 | 1035 return 0; |
1036 } | |
1037 | |
0 | 1038 static int avi_read_close(AVFormatContext *s) |
1039 { | |
110 | 1040 int i; |
1041 AVIContext *avi = s->priv_data; | |
1042 | |
1043 for(i=0;i<s->nb_streams;i++) { | |
1044 AVStream *st = s->streams[i]; | |
311 | 1045 AVIStream *ast = st->priv_data; |
700
a5e6e0e61e24
use libavformats index system instead of the half duplicated mess in avidec.c
michael
parents:
673
diff
changeset
|
1046 av_free(ast); |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
1047 av_free(st->codec->palctrl); |
110 | 1048 } |
1049 | |
262
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
1050 if (avi->dv_demux) |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
1051 av_free(avi->dv_demux); |
f174d9c00bce
* DV handling was streamlined for both muxing/demuxing and
romansh
parents:
227
diff
changeset
|
1052 |
0 | 1053 return 0; |
1054 } | |
1055 | |
1056 static int avi_probe(AVProbeData *p) | |
1057 { | |
2578 | 1058 int i; |
1059 | |
0 | 1060 /* check file header */ |
2578 | 1061 for(i=0; avi_headers[i][0]; i++) |
1062 if(!memcmp(p->buf , avi_headers[i] , 4) && | |
1063 !memcmp(p->buf+8, avi_headers[i]+4, 4)) | |
1064 return AVPROBE_SCORE_MAX; | |
1065 | |
1066 return 0; | |
0 | 1067 } |
1068 | |
1169 | 1069 AVInputFormat avi_demuxer = { |
0 | 1070 "avi", |
1071 "avi format", | |
1072 sizeof(AVIContext), | |
1073 avi_probe, | |
1074 avi_read_header, | |
1075 avi_read_packet, | |
1076 avi_read_close, | |
311 | 1077 avi_read_seek, |
0 | 1078 }; |