annotate ffmpeg/libavformat/avidec.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * AVI demuxer
yading@11 3 * Copyright (c) 2001 Fabrice Bellard
yading@11 4 *
yading@11 5 * This file is part of FFmpeg.
yading@11 6 *
yading@11 7 * FFmpeg is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * FFmpeg is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with FFmpeg; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 #include "libavutil/intreadwrite.h"
yading@11 23 #include "libavutil/mathematics.h"
yading@11 24 #include "libavutil/bswap.h"
yading@11 25 #include "libavutil/opt.h"
yading@11 26 #include "libavutil/dict.h"
yading@11 27 #include "libavutil/avstring.h"
yading@11 28 #include "libavutil/avassert.h"
yading@11 29 #include "avformat.h"
yading@11 30 #include "internal.h"
yading@11 31 #include "avi.h"
yading@11 32 #include "dv.h"
yading@11 33 #include "riff.h"
yading@11 34
yading@11 35 typedef struct AVIStream {
yading@11 36 int64_t frame_offset; /* current frame (video) or byte (audio) counter
yading@11 37 (used to compute the pts) */
yading@11 38 int remaining;
yading@11 39 int packet_size;
yading@11 40
yading@11 41 uint32_t scale;
yading@11 42 uint32_t rate;
yading@11 43 int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
yading@11 44
yading@11 45 int64_t cum_len; /* temporary storage (used during seek) */
yading@11 46
yading@11 47 int prefix; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
yading@11 48 int prefix_count;
yading@11 49 uint32_t pal[256];
yading@11 50 int has_pal;
yading@11 51 int dshow_block_align; ///< block align variable used to emulate bugs in the MS dshow demuxer
yading@11 52
yading@11 53 AVFormatContext *sub_ctx;
yading@11 54 AVPacket sub_pkt;
yading@11 55 uint8_t *sub_buffer;
yading@11 56
yading@11 57 int64_t seek_pos;
yading@11 58 } AVIStream;
yading@11 59
yading@11 60 typedef struct {
yading@11 61 const AVClass *class;
yading@11 62 int64_t riff_end;
yading@11 63 int64_t movi_end;
yading@11 64 int64_t fsize;
yading@11 65 int64_t io_fsize;
yading@11 66 int64_t movi_list;
yading@11 67 int64_t last_pkt_pos;
yading@11 68 int index_loaded;
yading@11 69 int is_odml;
yading@11 70 int non_interleaved;
yading@11 71 int stream_index;
yading@11 72 DVDemuxContext* dv_demux;
yading@11 73 int odml_depth;
yading@11 74 int use_odml;
yading@11 75 #define MAX_ODML_DEPTH 1000
yading@11 76 int64_t dts_max;
yading@11 77 } AVIContext;
yading@11 78
yading@11 79
yading@11 80 static const AVOption options[] = {
yading@11 81 { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
yading@11 82 { NULL },
yading@11 83 };
yading@11 84
yading@11 85 static const AVClass demuxer_class = {
yading@11 86 .class_name = "avi",
yading@11 87 .item_name = av_default_item_name,
yading@11 88 .option = options,
yading@11 89 .version = LIBAVUTIL_VERSION_INT,
yading@11 90 .category = AV_CLASS_CATEGORY_DEMUXER,
yading@11 91 };
yading@11 92
yading@11 93
yading@11 94 static const char avi_headers[][8] = {
yading@11 95 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
yading@11 96 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
yading@11 97 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19},
yading@11 98 { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' },
yading@11 99 { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
yading@11 100 { 0 }
yading@11 101 };
yading@11 102
yading@11 103 static const AVMetadataConv avi_metadata_conv[] = {
yading@11 104 { "strn", "title" },
yading@11 105 { 0 },
yading@11 106 };
yading@11 107
yading@11 108 static int avi_load_index(AVFormatContext *s);
yading@11 109 static int guess_ni_flag(AVFormatContext *s);
yading@11 110
yading@11 111 #define print_tag(str, tag, size) \
yading@11 112 av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \
yading@11 113 str, tag & 0xff, \
yading@11 114 (tag >> 8) & 0xff, \
yading@11 115 (tag >> 16) & 0xff, \
yading@11 116 (tag >> 24) & 0xff, \
yading@11 117 size)
yading@11 118
yading@11 119 static inline int get_duration(AVIStream *ast, int len){
yading@11 120 if(ast->sample_size){
yading@11 121 return len;
yading@11 122 }else if (ast->dshow_block_align){
yading@11 123 return (len + ast->dshow_block_align - 1)/ast->dshow_block_align;
yading@11 124 }else
yading@11 125 return 1;
yading@11 126 }
yading@11 127
yading@11 128 static int get_riff(AVFormatContext *s, AVIOContext *pb)
yading@11 129 {
yading@11 130 AVIContext *avi = s->priv_data;
yading@11 131 char header[8];
yading@11 132 int i;
yading@11 133
yading@11 134 /* check RIFF header */
yading@11 135 avio_read(pb, header, 4);
yading@11 136 avi->riff_end = avio_rl32(pb); /* RIFF chunk size */
yading@11 137 avi->riff_end += avio_tell(pb); /* RIFF chunk end */
yading@11 138 avio_read(pb, header+4, 4);
yading@11 139
yading@11 140 for(i=0; avi_headers[i][0]; i++)
yading@11 141 if(!memcmp(header, avi_headers[i], 8))
yading@11 142 break;
yading@11 143 if(!avi_headers[i][0])
yading@11 144 return AVERROR_INVALIDDATA;
yading@11 145
yading@11 146 if(header[7] == 0x19)
yading@11 147 av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n");
yading@11 148
yading@11 149 return 0;
yading@11 150 }
yading@11 151
yading@11 152 static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
yading@11 153 AVIContext *avi = s->priv_data;
yading@11 154 AVIOContext *pb = s->pb;
yading@11 155 int longs_pre_entry= avio_rl16(pb);
yading@11 156 int index_sub_type = avio_r8(pb);
yading@11 157 int index_type = avio_r8(pb);
yading@11 158 int entries_in_use = avio_rl32(pb);
yading@11 159 int chunk_id = avio_rl32(pb);
yading@11 160 int64_t base = avio_rl64(pb);
yading@11 161 int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
yading@11 162 AVStream *st;
yading@11 163 AVIStream *ast;
yading@11 164 int i;
yading@11 165 int64_t last_pos= -1;
yading@11 166 int64_t filesize= avi->fsize;
yading@11 167
yading@11 168 av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
yading@11 169 longs_pre_entry,index_type, entries_in_use, chunk_id, base);
yading@11 170
yading@11 171 if(stream_id >= s->nb_streams || stream_id < 0)
yading@11 172 return AVERROR_INVALIDDATA;
yading@11 173 st= s->streams[stream_id];
yading@11 174 ast = st->priv_data;
yading@11 175
yading@11 176 if(index_sub_type)
yading@11 177 return AVERROR_INVALIDDATA;
yading@11 178
yading@11 179 avio_rl32(pb);
yading@11 180
yading@11 181 if(index_type && longs_pre_entry != 2)
yading@11 182 return AVERROR_INVALIDDATA;
yading@11 183 if(index_type>1)
yading@11 184 return AVERROR_INVALIDDATA;
yading@11 185
yading@11 186 if(filesize > 0 && base >= filesize){
yading@11 187 av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
yading@11 188 if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
yading@11 189 base &= 0xFFFFFFFF;
yading@11 190 else
yading@11 191 return AVERROR_INVALIDDATA;
yading@11 192 }
yading@11 193
yading@11 194 for(i=0; i<entries_in_use; i++){
yading@11 195 if(index_type){
yading@11 196 int64_t pos= avio_rl32(pb) + base - 8;
yading@11 197 int len = avio_rl32(pb);
yading@11 198 int key= len >= 0;
yading@11 199 len &= 0x7FFFFFFF;
yading@11 200
yading@11 201 #ifdef DEBUG_SEEK
yading@11 202 av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
yading@11 203 #endif
yading@11 204 if(url_feof(pb))
yading@11 205 return AVERROR_INVALIDDATA;
yading@11 206
yading@11 207 if(last_pos == pos || pos == base - 8)
yading@11 208 avi->non_interleaved= 1;
yading@11 209 if(last_pos != pos && (len || !ast->sample_size))
yading@11 210 av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);
yading@11 211
yading@11 212 ast->cum_len += get_duration(ast, len);
yading@11 213 last_pos= pos;
yading@11 214 }else{
yading@11 215 int64_t offset, pos;
yading@11 216 int duration;
yading@11 217 offset = avio_rl64(pb);
yading@11 218 avio_rl32(pb); /* size */
yading@11 219 duration = avio_rl32(pb);
yading@11 220
yading@11 221 if(url_feof(pb))
yading@11 222 return AVERROR_INVALIDDATA;
yading@11 223
yading@11 224 pos = avio_tell(pb);
yading@11 225
yading@11 226 if(avi->odml_depth > MAX_ODML_DEPTH){
yading@11 227 av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
yading@11 228 return AVERROR_INVALIDDATA;
yading@11 229 }
yading@11 230
yading@11 231 if(avio_seek(pb, offset+8, SEEK_SET) < 0)
yading@11 232 return -1;
yading@11 233 avi->odml_depth++;
yading@11 234 read_braindead_odml_indx(s, frame_num);
yading@11 235 avi->odml_depth--;
yading@11 236 frame_num += duration;
yading@11 237
yading@11 238 if(avio_seek(pb, pos, SEEK_SET) < 0) {
yading@11 239 av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
yading@11 240 return -1;
yading@11 241 }
yading@11 242
yading@11 243 }
yading@11 244 }
yading@11 245 avi->index_loaded=2;
yading@11 246 return 0;
yading@11 247 }
yading@11 248
yading@11 249 static void clean_index(AVFormatContext *s){
yading@11 250 int i;
yading@11 251 int64_t j;
yading@11 252
yading@11 253 for(i=0; i<s->nb_streams; i++){
yading@11 254 AVStream *st = s->streams[i];
yading@11 255 AVIStream *ast = st->priv_data;
yading@11 256 int n= st->nb_index_entries;
yading@11 257 int max= ast->sample_size;
yading@11 258 int64_t pos, size, ts;
yading@11 259
yading@11 260 if(n != 1 || ast->sample_size==0)
yading@11 261 continue;
yading@11 262
yading@11 263 while(max < 1024) max+=max;
yading@11 264
yading@11 265 pos= st->index_entries[0].pos;
yading@11 266 size= st->index_entries[0].size;
yading@11 267 ts= st->index_entries[0].timestamp;
yading@11 268
yading@11 269 for(j=0; j<size; j+=max){
yading@11 270 av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
yading@11 271 }
yading@11 272 }
yading@11 273 }
yading@11 274
yading@11 275 static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
yading@11 276 {
yading@11 277 AVIOContext *pb = s->pb;
yading@11 278 char key[5] = {0}, *value;
yading@11 279
yading@11 280 size += (size & 1);
yading@11 281
yading@11 282 if (size == UINT_MAX)
yading@11 283 return AVERROR(EINVAL);
yading@11 284 value = av_malloc(size+1);
yading@11 285 if (!value)
yading@11 286 return AVERROR(ENOMEM);
yading@11 287 avio_read(pb, value, size);
yading@11 288 value[size]=0;
yading@11 289
yading@11 290 AV_WL32(key, tag);
yading@11 291
yading@11 292 return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
yading@11 293 AV_DICT_DONT_STRDUP_VAL);
yading@11 294 }
yading@11 295
yading@11 296 static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
yading@11 297 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
yading@11 298
yading@11 299 static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
yading@11 300 {
yading@11 301 char month[4], time[9], buffer[64];
yading@11 302 int i, day, year;
yading@11 303 /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
yading@11 304 if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
yading@11 305 month, &day, time, &year) == 4) {
yading@11 306 for (i=0; i<12; i++)
yading@11 307 if (!av_strcasecmp(month, months[i])) {
yading@11 308 snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
yading@11 309 year, i+1, day, time);
yading@11 310 av_dict_set(metadata, "creation_time", buffer, 0);
yading@11 311 }
yading@11 312 } else if (date[4] == '/' && date[7] == '/') {
yading@11 313 date[4] = date[7] = '-';
yading@11 314 av_dict_set(metadata, "creation_time", date, 0);
yading@11 315 }
yading@11 316 }
yading@11 317
yading@11 318 static void avi_read_nikon(AVFormatContext *s, uint64_t end)
yading@11 319 {
yading@11 320 while (avio_tell(s->pb) < end) {
yading@11 321 uint32_t tag = avio_rl32(s->pb);
yading@11 322 uint32_t size = avio_rl32(s->pb);
yading@11 323 switch (tag) {
yading@11 324 case MKTAG('n', 'c', 't', 'g'): { /* Nikon Tags */
yading@11 325 uint64_t tag_end = avio_tell(s->pb) + size;
yading@11 326 while (avio_tell(s->pb) < tag_end) {
yading@11 327 uint16_t tag = avio_rl16(s->pb);
yading@11 328 uint16_t size = avio_rl16(s->pb);
yading@11 329 const char *name = NULL;
yading@11 330 char buffer[64] = {0};
yading@11 331 size -= avio_read(s->pb, buffer,
yading@11 332 FFMIN(size, sizeof(buffer)-1));
yading@11 333 switch (tag) {
yading@11 334 case 0x03: name = "maker"; break;
yading@11 335 case 0x04: name = "model"; break;
yading@11 336 case 0x13: name = "creation_time";
yading@11 337 if (buffer[4] == ':' && buffer[7] == ':')
yading@11 338 buffer[4] = buffer[7] = '-';
yading@11 339 break;
yading@11 340 }
yading@11 341 if (name)
yading@11 342 av_dict_set(&s->metadata, name, buffer, 0);
yading@11 343 avio_skip(s->pb, size);
yading@11 344 }
yading@11 345 break;
yading@11 346 }
yading@11 347 default:
yading@11 348 avio_skip(s->pb, size);
yading@11 349 break;
yading@11 350 }
yading@11 351 }
yading@11 352 }
yading@11 353
yading@11 354 static int avi_read_header(AVFormatContext *s)
yading@11 355 {
yading@11 356 AVIContext *avi = s->priv_data;
yading@11 357 AVIOContext *pb = s->pb;
yading@11 358 unsigned int tag, tag1, handler;
yading@11 359 int codec_type, stream_index, frame_period;
yading@11 360 unsigned int size;
yading@11 361 int i;
yading@11 362 AVStream *st;
yading@11 363 AVIStream *ast = NULL;
yading@11 364 int avih_width=0, avih_height=0;
yading@11 365 int amv_file_format=0;
yading@11 366 uint64_t list_end = 0;
yading@11 367 int ret;
yading@11 368
yading@11 369 avi->stream_index= -1;
yading@11 370
yading@11 371 ret = get_riff(s, pb);
yading@11 372 if (ret < 0)
yading@11 373 return ret;
yading@11 374
yading@11 375 av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
yading@11 376
yading@11 377 avi->io_fsize = avi->fsize = avio_size(pb);
yading@11 378 if(avi->fsize<=0 || avi->fsize < avi->riff_end)
yading@11 379 avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
yading@11 380
yading@11 381 /* first list tag */
yading@11 382 stream_index = -1;
yading@11 383 codec_type = -1;
yading@11 384 frame_period = 0;
yading@11 385 for(;;) {
yading@11 386 if (url_feof(pb))
yading@11 387 goto fail;
yading@11 388 tag = avio_rl32(pb);
yading@11 389 size = avio_rl32(pb);
yading@11 390
yading@11 391 print_tag("tag", tag, size);
yading@11 392
yading@11 393 switch(tag) {
yading@11 394 case MKTAG('L', 'I', 'S', 'T'):
yading@11 395 list_end = avio_tell(pb) + size;
yading@11 396 /* Ignored, except at start of video packets. */
yading@11 397 tag1 = avio_rl32(pb);
yading@11 398
yading@11 399 print_tag("list", tag1, 0);
yading@11 400
yading@11 401 if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
yading@11 402 avi->movi_list = avio_tell(pb) - 4;
yading@11 403 if(size) avi->movi_end = avi->movi_list + size + (size & 1);
yading@11 404 else avi->movi_end = avi->fsize;
yading@11 405 av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
yading@11 406 goto end_of_header;
yading@11 407 }
yading@11 408 else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
yading@11 409 ff_read_riff_info(s, size - 4);
yading@11 410 else if (tag1 == MKTAG('n', 'c', 'd', 't'))
yading@11 411 avi_read_nikon(s, list_end);
yading@11 412
yading@11 413 break;
yading@11 414 case MKTAG('I', 'D', 'I', 'T'): {
yading@11 415 unsigned char date[64] = {0};
yading@11 416 size += (size & 1);
yading@11 417 size -= avio_read(pb, date, FFMIN(size, sizeof(date)-1));
yading@11 418 avio_skip(pb, size);
yading@11 419 avi_metadata_creation_time(&s->metadata, date);
yading@11 420 break;
yading@11 421 }
yading@11 422 case MKTAG('d', 'm', 'l', 'h'):
yading@11 423 avi->is_odml = 1;
yading@11 424 avio_skip(pb, size + (size & 1));
yading@11 425 break;
yading@11 426 case MKTAG('a', 'm', 'v', 'h'):
yading@11 427 amv_file_format=1;
yading@11 428 case MKTAG('a', 'v', 'i', 'h'):
yading@11 429 /* AVI header */
yading@11 430 /* using frame_period is bad idea */
yading@11 431 frame_period = avio_rl32(pb);
yading@11 432 avio_rl32(pb); /* max. bytes per second */
yading@11 433 avio_rl32(pb);
yading@11 434 avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
yading@11 435
yading@11 436 avio_skip(pb, 2 * 4);
yading@11 437 avio_rl32(pb);
yading@11 438 avio_rl32(pb);
yading@11 439 avih_width=avio_rl32(pb);
yading@11 440 avih_height=avio_rl32(pb);
yading@11 441
yading@11 442 avio_skip(pb, size - 10 * 4);
yading@11 443 break;
yading@11 444 case MKTAG('s', 't', 'r', 'h'):
yading@11 445 /* stream header */
yading@11 446
yading@11 447 tag1 = avio_rl32(pb);
yading@11 448 handler = avio_rl32(pb); /* codec tag */
yading@11 449
yading@11 450 if(tag1 == MKTAG('p', 'a', 'd', 's')){
yading@11 451 avio_skip(pb, size - 8);
yading@11 452 break;
yading@11 453 }else{
yading@11 454 stream_index++;
yading@11 455 st = avformat_new_stream(s, NULL);
yading@11 456 if (!st)
yading@11 457 goto fail;
yading@11 458
yading@11 459 st->id = stream_index;
yading@11 460 ast = av_mallocz(sizeof(AVIStream));
yading@11 461 if (!ast)
yading@11 462 goto fail;
yading@11 463 st->priv_data = ast;
yading@11 464 }
yading@11 465 if(amv_file_format)
yading@11 466 tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s');
yading@11 467
yading@11 468 print_tag("strh", tag1, -1);
yading@11 469
yading@11 470 if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
yading@11 471 int64_t dv_dur;
yading@11 472
yading@11 473 /*
yading@11 474 * After some consideration -- I don't think we
yading@11 475 * have to support anything but DV in type1 AVIs.
yading@11 476 */
yading@11 477 if (s->nb_streams != 1)
yading@11 478 goto fail;
yading@11 479
yading@11 480 if (handler != MKTAG('d', 'v', 's', 'd') &&
yading@11 481 handler != MKTAG('d', 'v', 'h', 'd') &&
yading@11 482 handler != MKTAG('d', 'v', 's', 'l'))
yading@11 483 goto fail;
yading@11 484
yading@11 485 ast = s->streams[0]->priv_data;
yading@11 486 av_freep(&s->streams[0]->codec->extradata);
yading@11 487 av_freep(&s->streams[0]->codec);
yading@11 488 if (s->streams[0]->info)
yading@11 489 av_freep(&s->streams[0]->info->duration_error);
yading@11 490 av_freep(&s->streams[0]->info);
yading@11 491 av_freep(&s->streams[0]);
yading@11 492 s->nb_streams = 0;
yading@11 493 if (CONFIG_DV_DEMUXER) {
yading@11 494 avi->dv_demux = avpriv_dv_init_demux(s);
yading@11 495 if (!avi->dv_demux)
yading@11 496 goto fail;
yading@11 497 }
yading@11 498 s->streams[0]->priv_data = ast;
yading@11 499 avio_skip(pb, 3 * 4);
yading@11 500 ast->scale = avio_rl32(pb);
yading@11 501 ast->rate = avio_rl32(pb);
yading@11 502 avio_skip(pb, 4); /* start time */
yading@11 503
yading@11 504 dv_dur = avio_rl32(pb);
yading@11 505 if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
yading@11 506 dv_dur *= AV_TIME_BASE;
yading@11 507 s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
yading@11 508 }
yading@11 509 /*
yading@11 510 * else, leave duration alone; timing estimation in utils.c
yading@11 511 * will make a guess based on bitrate.
yading@11 512 */
yading@11 513
yading@11 514 stream_index = s->nb_streams - 1;
yading@11 515 avio_skip(pb, size - 9*4);
yading@11 516 break;
yading@11 517 }
yading@11 518
yading@11 519 av_assert0(stream_index < s->nb_streams);
yading@11 520 st->codec->stream_codec_tag= handler;
yading@11 521
yading@11 522 avio_rl32(pb); /* flags */
yading@11 523 avio_rl16(pb); /* priority */
yading@11 524 avio_rl16(pb); /* language */
yading@11 525 avio_rl32(pb); /* initial frame */
yading@11 526 ast->scale = avio_rl32(pb);
yading@11 527 ast->rate = avio_rl32(pb);
yading@11 528 if(!(ast->scale && ast->rate)){
yading@11 529 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);
yading@11 530 if(frame_period){
yading@11 531 ast->rate = 1000000;
yading@11 532 ast->scale = frame_period;
yading@11 533 }else{
yading@11 534 ast->rate = 25;
yading@11 535 ast->scale = 1;
yading@11 536 }
yading@11 537 }
yading@11 538 avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
yading@11 539
yading@11 540 ast->cum_len=avio_rl32(pb); /* start */
yading@11 541 st->nb_frames = avio_rl32(pb);
yading@11 542
yading@11 543 st->start_time = 0;
yading@11 544 avio_rl32(pb); /* buffer size */
yading@11 545 avio_rl32(pb); /* quality */
yading@11 546 if (ast->cum_len*ast->scale/ast->rate > 3600) {
yading@11 547 av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
yading@11 548 return AVERROR_INVALIDDATA;
yading@11 549 }
yading@11 550 ast->sample_size = avio_rl32(pb); /* sample ssize */
yading@11 551 ast->cum_len *= FFMAX(1, ast->sample_size);
yading@11 552 av_dlog(s, "%"PRIu32" %"PRIu32" %d\n",
yading@11 553 ast->rate, ast->scale, ast->sample_size);
yading@11 554
yading@11 555 switch(tag1) {
yading@11 556 case MKTAG('v', 'i', 'd', 's'):
yading@11 557 codec_type = AVMEDIA_TYPE_VIDEO;
yading@11 558
yading@11 559 ast->sample_size = 0;
yading@11 560 break;
yading@11 561 case MKTAG('a', 'u', 'd', 's'):
yading@11 562 codec_type = AVMEDIA_TYPE_AUDIO;
yading@11 563 break;
yading@11 564 case MKTAG('t', 'x', 't', 's'):
yading@11 565 codec_type = AVMEDIA_TYPE_SUBTITLE;
yading@11 566 break;
yading@11 567 case MKTAG('d', 'a', 't', 's'):
yading@11 568 codec_type = AVMEDIA_TYPE_DATA;
yading@11 569 break;
yading@11 570 default:
yading@11 571 av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
yading@11 572 }
yading@11 573 if(ast->sample_size == 0) {
yading@11 574 st->duration = st->nb_frames;
yading@11 575 if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {
yading@11 576 av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");
yading@11 577 st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);
yading@11 578 }
yading@11 579 }
yading@11 580 ast->frame_offset= ast->cum_len;
yading@11 581 avio_skip(pb, size - 12 * 4);
yading@11 582 break;
yading@11 583 case MKTAG('s', 't', 'r', 'f'):
yading@11 584 /* stream header */
yading@11 585 if (!size)
yading@11 586 break;
yading@11 587 if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
yading@11 588 avio_skip(pb, size);
yading@11 589 } else {
yading@11 590 uint64_t cur_pos = avio_tell(pb);
yading@11 591 unsigned esize;
yading@11 592 if (cur_pos < list_end)
yading@11 593 size = FFMIN(size, list_end - cur_pos);
yading@11 594 st = s->streams[stream_index];
yading@11 595 switch(codec_type) {
yading@11 596 case AVMEDIA_TYPE_VIDEO:
yading@11 597 if(amv_file_format){
yading@11 598 st->codec->width=avih_width;
yading@11 599 st->codec->height=avih_height;
yading@11 600 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@11 601 st->codec->codec_id = AV_CODEC_ID_AMV;
yading@11 602 avio_skip(pb, size);
yading@11 603 break;
yading@11 604 }
yading@11 605 tag1 = ff_get_bmp_header(pb, st, &esize);
yading@11 606
yading@11 607 if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
yading@11 608 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
yading@11 609 st->codec->codec_tag = tag1;
yading@11 610 st->codec->codec_id = AV_CODEC_ID_XSUB;
yading@11 611 break;
yading@11 612 }
yading@11 613
yading@11 614 if(size > 10*4 && size<(1<<30) && size < avi->fsize){
yading@11 615 if(esize == size-1 && (esize&1)) st->codec->extradata_size= esize - 10*4;
yading@11 616 else st->codec->extradata_size= size - 10*4;
yading@11 617 st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@11 618 if (!st->codec->extradata) {
yading@11 619 st->codec->extradata_size= 0;
yading@11 620 return AVERROR(ENOMEM);
yading@11 621 }
yading@11 622 avio_read(pb, st->codec->extradata, st->codec->extradata_size);
yading@11 623 }
yading@11 624
yading@11 625 if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
yading@11 626 avio_r8(pb);
yading@11 627
yading@11 628 /* Extract palette from extradata if bpp <= 8. */
yading@11 629 /* This code assumes that extradata contains only palette. */
yading@11 630 /* This is true for all paletted codecs implemented in FFmpeg. */
yading@11 631 if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
yading@11 632 int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
yading@11 633 const uint8_t *pal_src;
yading@11 634
yading@11 635 pal_size = FFMIN(pal_size, st->codec->extradata_size);
yading@11 636 pal_src = st->codec->extradata + st->codec->extradata_size - pal_size;
yading@11 637 for (i = 0; i < pal_size/4; i++)
yading@11 638 ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
yading@11 639 ast->has_pal = 1;
yading@11 640 }
yading@11 641
yading@11 642 print_tag("video", tag1, 0);
yading@11 643
yading@11 644 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@11 645 st->codec->codec_tag = tag1;
yading@11 646 st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
yading@11 647 st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
yading@11 648
yading@11 649 if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
yading@11 650 st->codec->extradata_size+= 9;
yading@11 651 st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@11 652 if(st->codec->extradata)
yading@11 653 memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
yading@11 654 }
yading@11 655 st->codec->height= FFABS(st->codec->height);
yading@11 656
yading@11 657 // avio_skip(pb, size - 5 * 4);
yading@11 658 break;
yading@11 659 case AVMEDIA_TYPE_AUDIO:
yading@11 660 ret = ff_get_wav_header(pb, st->codec, size);
yading@11 661 if (ret < 0)
yading@11 662 return ret;
yading@11 663 ast->dshow_block_align= st->codec->block_align;
yading@11 664 if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
yading@11 665 av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
yading@11 666 ast->sample_size= st->codec->block_align;
yading@11 667 }
yading@11 668 if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
yading@11 669 avio_skip(pb, 1);
yading@11 670 /* Force parsing as several audio frames can be in
yading@11 671 * one packet and timestamps refer to packet start. */
yading@11 672 st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
yading@11 673 /* ADTS header is in extradata, AAC without header must be
yading@11 674 * stored as exact frames. Parser not needed and it will
yading@11 675 * fail. */
yading@11 676 if (st->codec->codec_id == AV_CODEC_ID_AAC && st->codec->extradata_size)
yading@11 677 st->need_parsing = AVSTREAM_PARSE_NONE;
yading@11 678 /* AVI files with Xan DPCM audio (wrongly) declare PCM
yading@11 679 * audio in the header but have Axan as stream_code_tag. */
yading@11 680 if (st->codec->stream_codec_tag == AV_RL32("Axan")){
yading@11 681 st->codec->codec_id = AV_CODEC_ID_XAN_DPCM;
yading@11 682 st->codec->codec_tag = 0;
yading@11 683 ast->dshow_block_align = 0;
yading@11 684 }
yading@11 685 if (amv_file_format){
yading@11 686 st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV;
yading@11 687 ast->dshow_block_align = 0;
yading@11 688 }
yading@11 689 if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
yading@11 690 av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
yading@11 691 ast->dshow_block_align = 0;
yading@11 692 }
yading@11 693 if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
yading@11 694 st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
yading@11 695 st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
yading@11 696 av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
yading@11 697 ast->sample_size = 0;
yading@11 698 }
yading@11 699 break;
yading@11 700 case AVMEDIA_TYPE_SUBTITLE:
yading@11 701 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
yading@11 702 st->request_probe= 1;
yading@11 703 avio_skip(pb, size);
yading@11 704 break;
yading@11 705 default:
yading@11 706 st->codec->codec_type = AVMEDIA_TYPE_DATA;
yading@11 707 st->codec->codec_id= AV_CODEC_ID_NONE;
yading@11 708 st->codec->codec_tag= 0;
yading@11 709 avio_skip(pb, size);
yading@11 710 break;
yading@11 711 }
yading@11 712 }
yading@11 713 break;
yading@11 714 case MKTAG('s', 't', 'r', 'd'):
yading@11 715 if (stream_index >= (unsigned)s->nb_streams || s->streams[stream_index]->codec->extradata_size) {
yading@11 716 avio_skip(pb, size);
yading@11 717 } else {
yading@11 718 uint64_t cur_pos = avio_tell(pb);
yading@11 719 if (cur_pos < list_end)
yading@11 720 size = FFMIN(size, list_end - cur_pos);
yading@11 721 st = s->streams[stream_index];
yading@11 722
yading@11 723 if(size<(1<<30)){
yading@11 724 st->codec->extradata_size= size;
yading@11 725 st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@11 726 if (!st->codec->extradata) {
yading@11 727 st->codec->extradata_size= 0;
yading@11 728 return AVERROR(ENOMEM);
yading@11 729 }
yading@11 730 avio_read(pb, st->codec->extradata, st->codec->extradata_size);
yading@11 731 }
yading@11 732
yading@11 733 if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
yading@11 734 avio_r8(pb);
yading@11 735 }
yading@11 736 break;
yading@11 737 case MKTAG('i', 'n', 'd', 'x'):
yading@11 738 i= avio_tell(pb);
yading@11 739 if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml &&
yading@11 740 read_braindead_odml_indx(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE))
yading@11 741 goto fail;
yading@11 742 avio_seek(pb, i+size, SEEK_SET);
yading@11 743 break;
yading@11 744 case MKTAG('v', 'p', 'r', 'p'):
yading@11 745 if(stream_index < (unsigned)s->nb_streams && size > 9*4){
yading@11 746 AVRational active, active_aspect;
yading@11 747
yading@11 748 st = s->streams[stream_index];
yading@11 749 avio_rl32(pb);
yading@11 750 avio_rl32(pb);
yading@11 751 avio_rl32(pb);
yading@11 752 avio_rl32(pb);
yading@11 753 avio_rl32(pb);
yading@11 754
yading@11 755 active_aspect.den= avio_rl16(pb);
yading@11 756 active_aspect.num= avio_rl16(pb);
yading@11 757 active.num = avio_rl32(pb);
yading@11 758 active.den = avio_rl32(pb);
yading@11 759 avio_rl32(pb); //nbFieldsPerFrame
yading@11 760
yading@11 761 if(active_aspect.num && active_aspect.den && active.num && active.den){
yading@11 762 st->sample_aspect_ratio= av_div_q(active_aspect, active);
yading@11 763 av_dlog(s, "vprp %d/%d %d/%d\n",
yading@11 764 active_aspect.num, active_aspect.den,
yading@11 765 active.num, active.den);
yading@11 766 }
yading@11 767 size -= 9*4;
yading@11 768 }
yading@11 769 avio_skip(pb, size);
yading@11 770 break;
yading@11 771 case MKTAG('s', 't', 'r', 'n'):
yading@11 772 if(s->nb_streams){
yading@11 773 ret = avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
yading@11 774 if (ret < 0)
yading@11 775 return ret;
yading@11 776 break;
yading@11 777 }
yading@11 778 default:
yading@11 779 if(size > 1000000){
yading@11 780 av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
yading@11 781 "I will ignore it and try to continue anyway.\n");
yading@11 782 if (s->error_recognition & AV_EF_EXPLODE)
yading@11 783 goto fail;
yading@11 784 avi->movi_list = avio_tell(pb) - 4;
yading@11 785 avi->movi_end = avi->fsize;
yading@11 786 goto end_of_header;
yading@11 787 }
yading@11 788 /* skip tag */
yading@11 789 size += (size & 1);
yading@11 790 avio_skip(pb, size);
yading@11 791 break;
yading@11 792 }
yading@11 793 }
yading@11 794 end_of_header:
yading@11 795 /* check stream number */
yading@11 796 if (stream_index != s->nb_streams - 1) {
yading@11 797 fail:
yading@11 798 return AVERROR_INVALIDDATA;
yading@11 799 }
yading@11 800
yading@11 801 if(!avi->index_loaded && pb->seekable)
yading@11 802 avi_load_index(s);
yading@11 803 avi->index_loaded |= 1;
yading@11 804 avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
yading@11 805 for(i=0; i<s->nb_streams; i++){
yading@11 806 AVStream *st = s->streams[i];
yading@11 807 if(st->nb_index_entries)
yading@11 808 break;
yading@11 809 }
yading@11 810 // DV-in-AVI cannot be non-interleaved, if set this must be
yading@11 811 // a mis-detection.
yading@11 812 if(avi->dv_demux)
yading@11 813 avi->non_interleaved=0;
yading@11 814 if(i==s->nb_streams && avi->non_interleaved) {
yading@11 815 av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
yading@11 816 avi->non_interleaved=0;
yading@11 817 }
yading@11 818
yading@11 819 if(avi->non_interleaved) {
yading@11 820 av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
yading@11 821 clean_index(s);
yading@11 822 }
yading@11 823
yading@11 824 ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
yading@11 825 ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
yading@11 826
yading@11 827 return 0;
yading@11 828 }
yading@11 829
yading@11 830 static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
yading@11 831 if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
yading@11 832 uint8_t desc[256];
yading@11 833 int score = AVPROBE_SCORE_MAX / 2, ret;
yading@11 834 AVIStream *ast = st->priv_data;
yading@11 835 AVInputFormat *sub_demuxer;
yading@11 836 AVRational time_base;
yading@11 837 AVIOContext *pb = avio_alloc_context( pkt->data + 7,
yading@11 838 pkt->size - 7,
yading@11 839 0, NULL, NULL, NULL, NULL);
yading@11 840 AVProbeData pd;
yading@11 841 unsigned int desc_len = avio_rl32(pb);
yading@11 842
yading@11 843 if (desc_len > pb->buf_end - pb->buf_ptr)
yading@11 844 goto error;
yading@11 845
yading@11 846 ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
yading@11 847 avio_skip(pb, desc_len - ret);
yading@11 848 if (*desc)
yading@11 849 av_dict_set(&st->metadata, "title", desc, 0);
yading@11 850
yading@11 851 avio_rl16(pb); /* flags? */
yading@11 852 avio_rl32(pb); /* data size */
yading@11 853
yading@11 854 pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
yading@11 855 if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
yading@11 856 goto error;
yading@11 857
yading@11 858 if (!(ast->sub_ctx = avformat_alloc_context()))
yading@11 859 goto error;
yading@11 860
yading@11 861 ast->sub_ctx->pb = pb;
yading@11 862 if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
yading@11 863 ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
yading@11 864 *st->codec = *ast->sub_ctx->streams[0]->codec;
yading@11 865 ast->sub_ctx->streams[0]->codec->extradata = NULL;
yading@11 866 time_base = ast->sub_ctx->streams[0]->time_base;
yading@11 867 avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
yading@11 868 }
yading@11 869 ast->sub_buffer = pkt->data;
yading@11 870 memset(pkt, 0, sizeof(*pkt));
yading@11 871 return 1;
yading@11 872 error:
yading@11 873 av_freep(&pb);
yading@11 874 }
yading@11 875 return 0;
yading@11 876 }
yading@11 877
yading@11 878 static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
yading@11 879 AVPacket *pkt)
yading@11 880 {
yading@11 881 AVIStream *ast, *next_ast = next_st->priv_data;
yading@11 882 int64_t ts, next_ts, ts_min = INT64_MAX;
yading@11 883 AVStream *st, *sub_st = NULL;
yading@11 884 int i;
yading@11 885
yading@11 886 next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
yading@11 887 AV_TIME_BASE_Q);
yading@11 888
yading@11 889 for (i=0; i<s->nb_streams; i++) {
yading@11 890 st = s->streams[i];
yading@11 891 ast = st->priv_data;
yading@11 892 if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
yading@11 893 ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q);
yading@11 894 if (ts <= next_ts && ts < ts_min) {
yading@11 895 ts_min = ts;
yading@11 896 sub_st = st;
yading@11 897 }
yading@11 898 }
yading@11 899 }
yading@11 900
yading@11 901 if (sub_st) {
yading@11 902 ast = sub_st->priv_data;
yading@11 903 *pkt = ast->sub_pkt;
yading@11 904 pkt->stream_index = sub_st->index;
yading@11 905 if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
yading@11 906 ast->sub_pkt.data = NULL;
yading@11 907 }
yading@11 908 return sub_st;
yading@11 909 }
yading@11 910
yading@11 911 static int get_stream_idx(int *d){
yading@11 912 if( d[0] >= '0' && d[0] <= '9'
yading@11 913 && d[1] >= '0' && d[1] <= '9'){
yading@11 914 return (d[0] - '0') * 10 + (d[1] - '0');
yading@11 915 }else{
yading@11 916 return 100; //invalid stream ID
yading@11 917 }
yading@11 918 }
yading@11 919
yading@11 920 /**
yading@11 921 *
yading@11 922 * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
yading@11 923 */
yading@11 924 static int avi_sync(AVFormatContext *s, int exit_early)
yading@11 925 {
yading@11 926 AVIContext *avi = s->priv_data;
yading@11 927 AVIOContext *pb = s->pb;
yading@11 928 int n;
yading@11 929 unsigned int d[8];
yading@11 930 unsigned int size;
yading@11 931 int64_t i, sync;
yading@11 932
yading@11 933 start_sync:
yading@11 934 memset(d, -1, sizeof(d));
yading@11 935 for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
yading@11 936 int j;
yading@11 937
yading@11 938 for(j=0; j<7; j++)
yading@11 939 d[j]= d[j+1];
yading@11 940 d[7]= avio_r8(pb);
yading@11 941
yading@11 942 size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
yading@11 943
yading@11 944 n= get_stream_idx(d+2);
yading@11 945 av_dlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
yading@11 946 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
yading@11 947 if(i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
yading@11 948 continue;
yading@11 949
yading@11 950 //parse ix##
yading@11 951 if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
yading@11 952 //parse JUNK
yading@11 953 ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
yading@11 954 ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
yading@11 955 avio_skip(pb, size);
yading@11 956 goto start_sync;
yading@11 957 }
yading@11 958
yading@11 959 //parse stray LIST
yading@11 960 if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
yading@11 961 avio_skip(pb, 4);
yading@11 962 goto start_sync;
yading@11 963 }
yading@11 964
yading@11 965 n= get_stream_idx(d);
yading@11 966
yading@11 967 if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
yading@11 968 continue;
yading@11 969
yading@11 970 //detect ##ix chunk and skip
yading@11 971 if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
yading@11 972 avio_skip(pb, size);
yading@11 973 goto start_sync;
yading@11 974 }
yading@11 975
yading@11 976 //parse ##dc/##wb
yading@11 977 if(n < s->nb_streams){
yading@11 978 AVStream *st;
yading@11 979 AVIStream *ast;
yading@11 980 st = s->streams[n];
yading@11 981 ast = st->priv_data;
yading@11 982
yading@11 983 if (!ast) {
yading@11 984 av_log(s, AV_LOG_WARNING, "Skiping foreign stream %d packet\n", n);
yading@11 985 continue;
yading@11 986 }
yading@11 987
yading@11 988 if(s->nb_streams>=2){
yading@11 989 AVStream *st1 = s->streams[1];
yading@11 990 AVIStream *ast1= st1->priv_data;
yading@11 991 //workaround for broken small-file-bug402.avi
yading@11 992 if( d[2] == 'w' && d[3] == 'b'
yading@11 993 && n==0
yading@11 994 && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
yading@11 995 && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
yading@11 996 && ast->prefix == 'd'*256+'c'
yading@11 997 && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
yading@11 998 ){
yading@11 999 n=1;
yading@11 1000 st = st1;
yading@11 1001 ast = ast1;
yading@11 1002 av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
yading@11 1003 }
yading@11 1004 }
yading@11 1005
yading@11 1006
yading@11 1007 if( (st->discard >= AVDISCARD_DEFAULT && size==0)
yading@11 1008 /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
yading@11 1009 || st->discard >= AVDISCARD_ALL){
yading@11 1010 if (!exit_early) {
yading@11 1011 ast->frame_offset += get_duration(ast, size);
yading@11 1012 }
yading@11 1013 avio_skip(pb, size);
yading@11 1014 goto start_sync;
yading@11 1015 }
yading@11 1016
yading@11 1017 if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
yading@11 1018 int k = avio_r8(pb);
yading@11 1019 int last = (k + avio_r8(pb) - 1) & 0xFF;
yading@11 1020
yading@11 1021 avio_rl16(pb); //flags
yading@11 1022
yading@11 1023 for (; k <= last; k++)
yading@11 1024 ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
yading@11 1025 ast->has_pal= 1;
yading@11 1026 goto start_sync;
yading@11 1027 } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
yading@11 1028 d[2]*256+d[3] == ast->prefix /*||
yading@11 1029 (d[2] == 'd' && d[3] == 'c') ||
yading@11 1030 (d[2] == 'w' && d[3] == 'b')*/) {
yading@11 1031
yading@11 1032 if (exit_early)
yading@11 1033 return 0;
yading@11 1034 if(d[2]*256+d[3] == ast->prefix)
yading@11 1035 ast->prefix_count++;
yading@11 1036 else{
yading@11 1037 ast->prefix= d[2]*256+d[3];
yading@11 1038 ast->prefix_count= 0;
yading@11 1039 }
yading@11 1040
yading@11 1041 avi->stream_index= n;
yading@11 1042 ast->packet_size= size + 8;
yading@11 1043 ast->remaining= size;
yading@11 1044
yading@11 1045 if(size || !ast->sample_size){
yading@11 1046 uint64_t pos= avio_tell(pb) - 8;
yading@11 1047 if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
yading@11 1048 av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
yading@11 1049 }
yading@11 1050 }
yading@11 1051 return 0;
yading@11 1052 }
yading@11 1053 }
yading@11 1054 }
yading@11 1055
yading@11 1056 if(pb->error)
yading@11 1057 return pb->error;
yading@11 1058 return AVERROR_EOF;
yading@11 1059 }
yading@11 1060
yading@11 1061 static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
yading@11 1062 {
yading@11 1063 AVIContext *avi = s->priv_data;
yading@11 1064 AVIOContext *pb = s->pb;
yading@11 1065 int err;
yading@11 1066 #if FF_API_DESTRUCT_PACKET
yading@11 1067 void* dstr;
yading@11 1068 #endif
yading@11 1069
yading@11 1070 if (CONFIG_DV_DEMUXER && avi->dv_demux) {
yading@11 1071 int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
yading@11 1072 if (size >= 0)
yading@11 1073 return size;
yading@11 1074 }
yading@11 1075
yading@11 1076 if(avi->non_interleaved){
yading@11 1077 int best_stream_index = 0;
yading@11 1078 AVStream *best_st= NULL;
yading@11 1079 AVIStream *best_ast;
yading@11 1080 int64_t best_ts= INT64_MAX;
yading@11 1081 int i;
yading@11 1082
yading@11 1083 for(i=0; i<s->nb_streams; i++){
yading@11 1084 AVStream *st = s->streams[i];
yading@11 1085 AVIStream *ast = st->priv_data;
yading@11 1086 int64_t ts= ast->frame_offset;
yading@11 1087 int64_t last_ts;
yading@11 1088
yading@11 1089 if(!st->nb_index_entries)
yading@11 1090 continue;
yading@11 1091
yading@11 1092 last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
yading@11 1093 if(!ast->remaining && ts > last_ts)
yading@11 1094 continue;
yading@11 1095
yading@11 1096 ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE});
yading@11 1097
yading@11 1098 av_dlog(s, "%"PRId64" %d/%d %"PRId64"\n", ts,
yading@11 1099 st->time_base.num, st->time_base.den, ast->frame_offset);
yading@11 1100 if(ts < best_ts){
yading@11 1101 best_ts= ts;
yading@11 1102 best_st= st;
yading@11 1103 best_stream_index= i;
yading@11 1104 }
yading@11 1105 }
yading@11 1106 if(!best_st)
yading@11 1107 return AVERROR_EOF;
yading@11 1108
yading@11 1109 best_ast = best_st->priv_data;
yading@11 1110 best_ts = best_ast->frame_offset;
yading@11 1111 if(best_ast->remaining)
yading@11 1112 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
yading@11 1113 else{
yading@11 1114 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
yading@11 1115 if(i>=0)
yading@11 1116 best_ast->frame_offset= best_st->index_entries[i].timestamp;
yading@11 1117 }
yading@11 1118
yading@11 1119 if(i>=0){
yading@11 1120 int64_t pos= best_st->index_entries[i].pos;
yading@11 1121 pos += best_ast->packet_size - best_ast->remaining;
yading@11 1122 if(avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
yading@11 1123 return AVERROR_EOF;
yading@11 1124
yading@11 1125 av_assert0(best_ast->remaining <= best_ast->packet_size);
yading@11 1126
yading@11 1127 avi->stream_index= best_stream_index;
yading@11 1128 if(!best_ast->remaining)
yading@11 1129 best_ast->packet_size=
yading@11 1130 best_ast->remaining= best_st->index_entries[i].size;
yading@11 1131 }
yading@11 1132 else
yading@11 1133 return AVERROR_EOF;
yading@11 1134 }
yading@11 1135
yading@11 1136 resync:
yading@11 1137 if(avi->stream_index >= 0){
yading@11 1138 AVStream *st= s->streams[ avi->stream_index ];
yading@11 1139 AVIStream *ast= st->priv_data;
yading@11 1140 int size, err;
yading@11 1141
yading@11 1142 if(get_subtitle_pkt(s, st, pkt))
yading@11 1143 return 0;
yading@11 1144
yading@11 1145 if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
yading@11 1146 size= INT_MAX;
yading@11 1147 else if(ast->sample_size < 32)
yading@11 1148 // arbitrary multiplier to avoid tiny packets for raw PCM data
yading@11 1149 size= 1024*ast->sample_size;
yading@11 1150 else
yading@11 1151 size= ast->sample_size;
yading@11 1152
yading@11 1153 if(size > ast->remaining)
yading@11 1154 size= ast->remaining;
yading@11 1155 avi->last_pkt_pos= avio_tell(pb);
yading@11 1156 err= av_get_packet(pb, pkt, size);
yading@11 1157 if(err<0)
yading@11 1158 return err;
yading@11 1159 size = err;
yading@11 1160
yading@11 1161 if(ast->has_pal && pkt->size<(unsigned)INT_MAX/2){
yading@11 1162 uint8_t *pal;
yading@11 1163 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
yading@11 1164 if(!pal){
yading@11 1165 av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n");
yading@11 1166 }else{
yading@11 1167 memcpy(pal, ast->pal, AVPALETTE_SIZE);
yading@11 1168 ast->has_pal = 0;
yading@11 1169 }
yading@11 1170 }
yading@11 1171
yading@11 1172 if (CONFIG_DV_DEMUXER && avi->dv_demux) {
yading@11 1173 AVBufferRef *avbuf = pkt->buf;
yading@11 1174 #if FF_API_DESTRUCT_PACKET
yading@11 1175 dstr = pkt->destruct;
yading@11 1176 #endif
yading@11 1177 size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
yading@11 1178 pkt->data, pkt->size, pkt->pos);
yading@11 1179 #if FF_API_DESTRUCT_PACKET
yading@11 1180 pkt->destruct = dstr;
yading@11 1181 #endif
yading@11 1182 pkt->buf = avbuf;
yading@11 1183 pkt->flags |= AV_PKT_FLAG_KEY;
yading@11 1184 if (size < 0)
yading@11 1185 av_free_packet(pkt);
yading@11 1186 } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
yading@11 1187 && !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
yading@11 1188 ast->frame_offset++;
yading@11 1189 avi->stream_index = -1;
yading@11 1190 ast->remaining = 0;
yading@11 1191 goto resync;
yading@11 1192 } else {
yading@11 1193 /* XXX: How to handle B-frames in AVI? */
yading@11 1194 pkt->dts = ast->frame_offset;
yading@11 1195 // pkt->dts += ast->start;
yading@11 1196 if(ast->sample_size)
yading@11 1197 pkt->dts /= ast->sample_size;
yading@11 1198 av_dlog(s, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n",
yading@11 1199 pkt->dts, ast->frame_offset, ast->scale, ast->rate,
yading@11 1200 ast->sample_size, AV_TIME_BASE, avi->stream_index, size);
yading@11 1201 pkt->stream_index = avi->stream_index;
yading@11 1202
yading@11 1203 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
yading@11 1204 AVIndexEntry *e;
yading@11 1205 int index;
yading@11 1206 av_assert0(st->index_entries);
yading@11 1207
yading@11 1208 index= av_index_search_timestamp(st, ast->frame_offset, 0);
yading@11 1209 e= &st->index_entries[index];
yading@11 1210
yading@11 1211 if(index >= 0 && e->timestamp == ast->frame_offset){
yading@11 1212 if (index == st->nb_index_entries-1){
yading@11 1213 int key=1;
yading@11 1214 int i;
yading@11 1215 uint32_t state=-1;
yading@11 1216 for(i=0; i<FFMIN(size,256); i++){
yading@11 1217 if(st->codec->codec_id == AV_CODEC_ID_MPEG4){
yading@11 1218 if(state == 0x1B6){
yading@11 1219 key= !(pkt->data[i]&0xC0);
yading@11 1220 break;
yading@11 1221 }
yading@11 1222 }else
yading@11 1223 break;
yading@11 1224 state= (state<<8) + pkt->data[i];
yading@11 1225 }
yading@11 1226 if(!key)
yading@11 1227 e->flags &= ~AVINDEX_KEYFRAME;
yading@11 1228 }
yading@11 1229 if (e->flags & AVINDEX_KEYFRAME)
yading@11 1230 pkt->flags |= AV_PKT_FLAG_KEY;
yading@11 1231 }
yading@11 1232 } else {
yading@11 1233 pkt->flags |= AV_PKT_FLAG_KEY;
yading@11 1234 }
yading@11 1235 ast->frame_offset += get_duration(ast, pkt->size);
yading@11 1236 }
yading@11 1237 ast->remaining -= err;
yading@11 1238 if(!ast->remaining){
yading@11 1239 avi->stream_index= -1;
yading@11 1240 ast->packet_size= 0;
yading@11 1241 }
yading@11 1242
yading@11 1243 if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
yading@11 1244 av_free_packet(pkt);
yading@11 1245 goto resync;
yading@11 1246 }
yading@11 1247 ast->seek_pos= 0;
yading@11 1248
yading@11 1249 if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){
yading@11 1250 int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
yading@11 1251
yading@11 1252 if(avi->dts_max - dts > 2*AV_TIME_BASE){
yading@11 1253 avi->non_interleaved= 1;
yading@11 1254 av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
yading@11 1255 }else if(avi->dts_max < dts)
yading@11 1256 avi->dts_max = dts;
yading@11 1257 }
yading@11 1258
yading@11 1259 return 0;
yading@11 1260 }
yading@11 1261
yading@11 1262 if ((err = avi_sync(s, 0)) < 0)
yading@11 1263 return err;
yading@11 1264 goto resync;
yading@11 1265 }
yading@11 1266
yading@11 1267 /* XXX: We make the implicit supposition that the positions are sorted
yading@11 1268 for each stream. */
yading@11 1269 static int avi_read_idx1(AVFormatContext *s, int size)
yading@11 1270 {
yading@11 1271 AVIContext *avi = s->priv_data;
yading@11 1272 AVIOContext *pb = s->pb;
yading@11 1273 int nb_index_entries, i;
yading@11 1274 AVStream *st;
yading@11 1275 AVIStream *ast;
yading@11 1276 unsigned int index, tag, flags, pos, len, first_packet = 1;
yading@11 1277 unsigned last_pos= -1;
yading@11 1278 unsigned last_idx= -1;
yading@11 1279 int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
yading@11 1280 int anykey = 0;
yading@11 1281
yading@11 1282 nb_index_entries = size / 16;
yading@11 1283 if (nb_index_entries <= 0)
yading@11 1284 return AVERROR_INVALIDDATA;
yading@11 1285
yading@11 1286 idx1_pos = avio_tell(pb);
yading@11 1287 avio_seek(pb, avi->movi_list+4, SEEK_SET);
yading@11 1288 if (avi_sync(s, 1) == 0) {
yading@11 1289 first_packet_pos = avio_tell(pb) - 8;
yading@11 1290 }
yading@11 1291 avi->stream_index = -1;
yading@11 1292 avio_seek(pb, idx1_pos, SEEK_SET);
yading@11 1293
yading@11 1294 if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")){
yading@11 1295 first_packet_pos = 0;
yading@11 1296 data_offset = avi->movi_list;
yading@11 1297 }
yading@11 1298
yading@11 1299 /* Read the entries and sort them in each stream component. */
yading@11 1300 for(i = 0; i < nb_index_entries; i++) {
yading@11 1301 if(url_feof(pb))
yading@11 1302 return -1;
yading@11 1303
yading@11 1304 tag = avio_rl32(pb);
yading@11 1305 flags = avio_rl32(pb);
yading@11 1306 pos = avio_rl32(pb);
yading@11 1307 len = avio_rl32(pb);
yading@11 1308 av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
yading@11 1309 i, tag, flags, pos, len);
yading@11 1310
yading@11 1311 index = ((tag & 0xff) - '0') * 10;
yading@11 1312 index += ((tag >> 8) & 0xff) - '0';
yading@11 1313 if (index >= s->nb_streams)
yading@11 1314 continue;
yading@11 1315 st = s->streams[index];
yading@11 1316 ast = st->priv_data;
yading@11 1317
yading@11 1318 if(first_packet && first_packet_pos && len) {
yading@11 1319 data_offset = first_packet_pos - pos;
yading@11 1320 first_packet = 0;
yading@11 1321 }
yading@11 1322 pos += data_offset;
yading@11 1323
yading@11 1324 av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
yading@11 1325
yading@11 1326 // even if we have only a single stream, we should
yading@11 1327 // switch to non-interleaved to get correct timestamps
yading@11 1328 if(last_pos == pos)
yading@11 1329 avi->non_interleaved= 1;
yading@11 1330 if(last_idx != pos && len) {
yading@11 1331 av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
yading@11 1332 last_idx= pos;
yading@11 1333 }
yading@11 1334 ast->cum_len += get_duration(ast, len);
yading@11 1335 last_pos= pos;
yading@11 1336 anykey |= flags&AVIIF_INDEX;
yading@11 1337 }
yading@11 1338 if (!anykey) {
yading@11 1339 for (index = 0; index < s->nb_streams; index++) {
yading@11 1340 st = s->streams[index];
yading@11 1341 if (st->nb_index_entries)
yading@11 1342 st->index_entries[0].flags |= AVINDEX_KEYFRAME;
yading@11 1343 }
yading@11 1344 }
yading@11 1345 return 0;
yading@11 1346 }
yading@11 1347
yading@11 1348 static int guess_ni_flag(AVFormatContext *s){
yading@11 1349 int i;
yading@11 1350 int64_t last_start=0;
yading@11 1351 int64_t first_end= INT64_MAX;
yading@11 1352 int64_t oldpos= avio_tell(s->pb);
yading@11 1353 int *idx;
yading@11 1354 int64_t min_pos, pos;
yading@11 1355
yading@11 1356 for(i=0; i<s->nb_streams; i++){
yading@11 1357 AVStream *st = s->streams[i];
yading@11 1358 int n= st->nb_index_entries;
yading@11 1359 unsigned int size;
yading@11 1360
yading@11 1361 if(n <= 0)
yading@11 1362 continue;
yading@11 1363
yading@11 1364 if(n >= 2){
yading@11 1365 int64_t pos= st->index_entries[0].pos;
yading@11 1366 avio_seek(s->pb, pos + 4, SEEK_SET);
yading@11 1367 size= avio_rl32(s->pb);
yading@11 1368 if(pos + size > st->index_entries[1].pos)
yading@11 1369 last_start= INT64_MAX;
yading@11 1370 }
yading@11 1371
yading@11 1372 if(st->index_entries[0].pos > last_start)
yading@11 1373 last_start= st->index_entries[0].pos;
yading@11 1374 if(st->index_entries[n-1].pos < first_end)
yading@11 1375 first_end= st->index_entries[n-1].pos;
yading@11 1376 }
yading@11 1377 avio_seek(s->pb, oldpos, SEEK_SET);
yading@11 1378 if (last_start > first_end)
yading@11 1379 return 1;
yading@11 1380 idx= av_mallocz(sizeof(*idx) * s->nb_streams);
yading@11 1381 for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) {
yading@11 1382 int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2;
yading@11 1383 min_pos = INT64_MAX;
yading@11 1384
yading@11 1385 for (i=0; i<s->nb_streams; i++) {
yading@11 1386 AVStream *st = s->streams[i];
yading@11 1387 int n= st->nb_index_entries;
yading@11 1388 while (idx[i]<n && st->index_entries[idx[i]].pos < pos)
yading@11 1389 idx[i]++;
yading@11 1390 if (idx[i] < n) {
yading@11 1391 min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp, st->time_base, AV_TIME_BASE_Q));
yading@11 1392 min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
yading@11 1393 }
yading@11 1394 if (idx[i])
yading@11 1395 max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp, st->time_base, AV_TIME_BASE_Q));
yading@11 1396 }
yading@11 1397 if(max_dts - min_dts > 2*AV_TIME_BASE) {
yading@11 1398 av_free(idx);
yading@11 1399 return 1;
yading@11 1400 }
yading@11 1401 }
yading@11 1402 av_free(idx);
yading@11 1403 return 0;
yading@11 1404 }
yading@11 1405
yading@11 1406 static int avi_load_index(AVFormatContext *s)
yading@11 1407 {
yading@11 1408 AVIContext *avi = s->priv_data;
yading@11 1409 AVIOContext *pb = s->pb;
yading@11 1410 uint32_t tag, size;
yading@11 1411 int64_t pos= avio_tell(pb);
yading@11 1412 int64_t next;
yading@11 1413 int ret = -1;
yading@11 1414
yading@11 1415 if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
yading@11 1416 goto the_end; // maybe truncated file
yading@11 1417 av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
yading@11 1418 for(;;) {
yading@11 1419 tag = avio_rl32(pb);
yading@11 1420 size = avio_rl32(pb);
yading@11 1421 if (url_feof(pb))
yading@11 1422 break;
yading@11 1423 next = avio_tell(pb) + size + (size & 1);
yading@11 1424
yading@11 1425 av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
yading@11 1426 tag & 0xff,
yading@11 1427 (tag >> 8) & 0xff,
yading@11 1428 (tag >> 16) & 0xff,
yading@11 1429 (tag >> 24) & 0xff,
yading@11 1430 size);
yading@11 1431
yading@11 1432 if (tag == MKTAG('i', 'd', 'x', '1') &&
yading@11 1433 avi_read_idx1(s, size) >= 0) {
yading@11 1434 avi->index_loaded=2;
yading@11 1435 ret = 0;
yading@11 1436 }else if(tag == MKTAG('L', 'I', 'S', 'T')) {
yading@11 1437 uint32_t tag1 = avio_rl32(pb);
yading@11 1438
yading@11 1439 if (tag1 == MKTAG('I', 'N', 'F', 'O'))
yading@11 1440 ff_read_riff_info(s, size - 4);
yading@11 1441 }else if(!ret)
yading@11 1442 break;
yading@11 1443
yading@11 1444 if (avio_seek(pb, next, SEEK_SET) < 0)
yading@11 1445 break; // something is wrong here
yading@11 1446 }
yading@11 1447 the_end:
yading@11 1448 avio_seek(pb, pos, SEEK_SET);
yading@11 1449 return ret;
yading@11 1450 }
yading@11 1451
yading@11 1452 static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
yading@11 1453 {
yading@11 1454 AVIStream *ast2 = st2->priv_data;
yading@11 1455 int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
yading@11 1456 av_free_packet(&ast2->sub_pkt);
yading@11 1457 if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
yading@11 1458 avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
yading@11 1459 ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
yading@11 1460 }
yading@11 1461
yading@11 1462 static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
yading@11 1463 {
yading@11 1464 AVIContext *avi = s->priv_data;
yading@11 1465 AVStream *st;
yading@11 1466 int i, index;
yading@11 1467 int64_t pos, pos_min;
yading@11 1468 AVIStream *ast;
yading@11 1469
yading@11 1470 if (!avi->index_loaded) {
yading@11 1471 /* we only load the index on demand */
yading@11 1472 avi_load_index(s);
yading@11 1473 avi->index_loaded |= 1;
yading@11 1474 }
yading@11 1475 av_assert0(stream_index>= 0);
yading@11 1476
yading@11 1477 st = s->streams[stream_index];
yading@11 1478 ast= st->priv_data;
yading@11 1479 index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
yading@11 1480 if (index<0) {
yading@11 1481 if (st->nb_index_entries > 0)
yading@11 1482 av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
yading@11 1483 timestamp * FFMAX(ast->sample_size, 1),
yading@11 1484 st->index_entries[0].timestamp,
yading@11 1485 st->index_entries[st->nb_index_entries - 1].timestamp);
yading@11 1486 return AVERROR_INVALIDDATA;
yading@11 1487 }
yading@11 1488
yading@11 1489 /* find the position */
yading@11 1490 pos = st->index_entries[index].pos;
yading@11 1491 timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
yading@11 1492
yading@11 1493 av_dlog(s, "XX %"PRId64" %d %"PRId64"\n",
yading@11 1494 timestamp, index, st->index_entries[index].timestamp);
yading@11 1495
yading@11 1496 if (CONFIG_DV_DEMUXER && avi->dv_demux) {
yading@11 1497 /* One and only one real stream for DV in AVI, and it has video */
yading@11 1498 /* offsets. Calling with other stream indexes should have failed */
yading@11 1499 /* the av_index_search_timestamp call above. */
yading@11 1500 av_assert0(stream_index == 0);
yading@11 1501
yading@11 1502 if(avio_seek(s->pb, pos, SEEK_SET) < 0)
yading@11 1503 return -1;
yading@11 1504
yading@11 1505 /* Feed the DV video stream version of the timestamp to the */
yading@11 1506 /* DV demux so it can synthesize correct timestamps. */
yading@11 1507 ff_dv_offset_reset(avi->dv_demux, timestamp);
yading@11 1508
yading@11 1509 avi->stream_index= -1;
yading@11 1510 return 0;
yading@11 1511 }
yading@11 1512
yading@11 1513 pos_min= pos;
yading@11 1514 for(i = 0; i < s->nb_streams; i++) {
yading@11 1515 AVStream *st2 = s->streams[i];
yading@11 1516 AVIStream *ast2 = st2->priv_data;
yading@11 1517
yading@11 1518 ast2->packet_size=
yading@11 1519 ast2->remaining= 0;
yading@11 1520
yading@11 1521 if (ast2->sub_ctx) {
yading@11 1522 seek_subtitle(st, st2, timestamp);
yading@11 1523 continue;
yading@11 1524 }
yading@11 1525
yading@11 1526 if (st2->nb_index_entries <= 0)
yading@11 1527 continue;
yading@11 1528
yading@11 1529 // av_assert1(st2->codec->block_align);
yading@11 1530 av_assert0((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
yading@11 1531 index = av_index_search_timestamp(
yading@11 1532 st2,
yading@11 1533 av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
yading@11 1534 flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
yading@11 1535 if(index<0)
yading@11 1536 index=0;
yading@11 1537 ast2->seek_pos= st2->index_entries[index].pos;
yading@11 1538 pos_min= FFMIN(pos_min,ast2->seek_pos);
yading@11 1539 }
yading@11 1540 for(i = 0; i < s->nb_streams; i++) {
yading@11 1541 AVStream *st2 = s->streams[i];
yading@11 1542 AVIStream *ast2 = st2->priv_data;
yading@11 1543
yading@11 1544 if (ast2->sub_ctx || st2->nb_index_entries <= 0)
yading@11 1545 continue;
yading@11 1546
yading@11 1547 index = av_index_search_timestamp(
yading@11 1548 st2,
yading@11 1549 av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
yading@11 1550 flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
yading@11 1551 if(index<0)
yading@11 1552 index=0;
yading@11 1553 while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
yading@11 1554 index--;
yading@11 1555 ast2->frame_offset = st2->index_entries[index].timestamp;
yading@11 1556 }
yading@11 1557
yading@11 1558 /* do the seek */
yading@11 1559 if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
yading@11 1560 av_log(s, AV_LOG_ERROR, "Seek failed\n");
yading@11 1561 return -1;
yading@11 1562 }
yading@11 1563 avi->stream_index= -1;
yading@11 1564 avi->dts_max= INT_MIN;
yading@11 1565 return 0;
yading@11 1566 }
yading@11 1567
yading@11 1568 static int avi_read_close(AVFormatContext *s)
yading@11 1569 {
yading@11 1570 int i;
yading@11 1571 AVIContext *avi = s->priv_data;
yading@11 1572
yading@11 1573 for(i=0;i<s->nb_streams;i++) {
yading@11 1574 AVStream *st = s->streams[i];
yading@11 1575 AVIStream *ast = st->priv_data;
yading@11 1576 if (ast) {
yading@11 1577 if (ast->sub_ctx) {
yading@11 1578 av_freep(&ast->sub_ctx->pb);
yading@11 1579 avformat_close_input(&ast->sub_ctx);
yading@11 1580 }
yading@11 1581 av_free(ast->sub_buffer);
yading@11 1582 av_free_packet(&ast->sub_pkt);
yading@11 1583 }
yading@11 1584 }
yading@11 1585
yading@11 1586 av_free(avi->dv_demux);
yading@11 1587
yading@11 1588 return 0;
yading@11 1589 }
yading@11 1590
yading@11 1591 static int avi_probe(AVProbeData *p)
yading@11 1592 {
yading@11 1593 int i;
yading@11 1594
yading@11 1595 /* check file header */
yading@11 1596 for(i=0; avi_headers[i][0]; i++)
yading@11 1597 if(!memcmp(p->buf , avi_headers[i] , 4) &&
yading@11 1598 !memcmp(p->buf+8, avi_headers[i]+4, 4))
yading@11 1599 return AVPROBE_SCORE_MAX;
yading@11 1600
yading@11 1601 return 0;
yading@11 1602 }
yading@11 1603
yading@11 1604 AVInputFormat ff_avi_demuxer = {
yading@11 1605 .name = "avi",
yading@11 1606 .long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
yading@11 1607 .priv_data_size = sizeof(AVIContext),
yading@11 1608 .read_probe = avi_probe,
yading@11 1609 .read_header = avi_read_header,
yading@11 1610 .read_packet = avi_read_packet,
yading@11 1611 .read_close = avi_read_close,
yading@11 1612 .read_seek = avi_read_seek,
yading@11 1613 .priv_class = &demuxer_class,
yading@11 1614 };