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