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