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