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