Libav
|
00001 /* 00002 * AVI demuxer 00003 * Copyright (c) 2001 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 //#define DEBUG 00023 //#define DEBUG_SEEK 00024 00025 #include "libavutil/intreadwrite.h" 00026 #include "libavutil/bswap.h" 00027 #include "avformat.h" 00028 #include "avi.h" 00029 #include "dv.h" 00030 #include "riff.h" 00031 00032 #undef NDEBUG 00033 #include <assert.h> 00034 00035 typedef struct AVIStream { 00036 int64_t frame_offset; /* current frame (video) or byte (audio) counter 00037 (used to compute the pts) */ 00038 int remaining; 00039 int packet_size; 00040 00041 int scale; 00042 int rate; 00043 int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */ 00044 00045 int64_t cum_len; /* temporary storage (used during seek) */ 00046 00047 int prefix; 00048 int prefix_count; 00049 uint32_t pal[256]; 00050 int has_pal; 00051 } AVIStream; 00052 00053 typedef struct { 00054 int64_t riff_end; 00055 int64_t movi_end; 00056 int64_t fsize; 00057 int64_t movi_list; 00058 int64_t last_pkt_pos; 00059 int index_loaded; 00060 int is_odml; 00061 int non_interleaved; 00062 int stream_index; 00063 DVDemuxContext* dv_demux; 00064 } AVIContext; 00065 00066 static const char avi_headers[][8] = { 00067 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' }, 00068 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' }, 00069 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19}, 00070 { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' }, 00071 { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' }, 00072 { 0 } 00073 }; 00074 00075 static int avi_load_index(AVFormatContext *s); 00076 static int guess_ni_flag(AVFormatContext *s); 00077 00078 #ifdef DEBUG 00079 static void print_tag(const char *str, unsigned int tag, int size) 00080 { 00081 dprintf(NULL, "%s: tag=%c%c%c%c size=0x%x\n", 00082 str, tag & 0xff, 00083 (tag >> 8) & 0xff, 00084 (tag >> 16) & 0xff, 00085 (tag >> 24) & 0xff, 00086 size); 00087 } 00088 #endif 00089 00090 static int get_riff(AVFormatContext *s, ByteIOContext *pb) 00091 { 00092 AVIContext *avi = s->priv_data; 00093 char header[8]; 00094 int i; 00095 00096 /* check RIFF header */ 00097 get_buffer(pb, header, 4); 00098 avi->riff_end = get_le32(pb); /* RIFF chunk size */ 00099 avi->riff_end += url_ftell(pb); /* RIFF chunk end */ 00100 get_buffer(pb, header+4, 4); 00101 00102 for(i=0; avi_headers[i][0]; i++) 00103 if(!memcmp(header, avi_headers[i], 8)) 00104 break; 00105 if(!avi_headers[i][0]) 00106 return -1; 00107 00108 if(header[7] == 0x19) 00109 av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n"); 00110 00111 return 0; 00112 } 00113 00114 static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){ 00115 AVIContext *avi = s->priv_data; 00116 ByteIOContext *pb = s->pb; 00117 int longs_pre_entry= get_le16(pb); 00118 int index_sub_type = get_byte(pb); 00119 int index_type = get_byte(pb); 00120 int entries_in_use = get_le32(pb); 00121 int chunk_id = get_le32(pb); 00122 int64_t base = get_le64(pb); 00123 int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0'); 00124 AVStream *st; 00125 AVIStream *ast; 00126 int i; 00127 int64_t last_pos= -1; 00128 int64_t filesize= url_fsize(s->pb); 00129 00130 #ifdef DEBUG_SEEK 00131 av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n", 00132 longs_pre_entry,index_type, entries_in_use, chunk_id, base); 00133 #endif 00134 00135 if(stream_id >= s->nb_streams || stream_id < 0) 00136 return -1; 00137 st= s->streams[stream_id]; 00138 ast = st->priv_data; 00139 00140 if(index_sub_type) 00141 return -1; 00142 00143 get_le32(pb); 00144 00145 if(index_type && longs_pre_entry != 2) 00146 return -1; 00147 if(index_type>1) 00148 return -1; 00149 00150 if(filesize > 0 && base >= filesize){ 00151 av_log(s, AV_LOG_ERROR, "ODML index invalid\n"); 00152 if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF) 00153 base &= 0xFFFFFFFF; 00154 else 00155 return -1; 00156 } 00157 00158 for(i=0; i<entries_in_use; i++){ 00159 if(index_type){ 00160 int64_t pos= get_le32(pb) + base - 8; 00161 int len = get_le32(pb); 00162 int key= len >= 0; 00163 len &= 0x7FFFFFFF; 00164 00165 #ifdef DEBUG_SEEK 00166 av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len); 00167 #endif 00168 if(url_feof(pb)) 00169 return -1; 00170 00171 if(last_pos == pos || pos == base - 8) 00172 avi->non_interleaved= 1; 00173 if(last_pos != pos && (len || !ast->sample_size)) 00174 av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0); 00175 00176 if(ast->sample_size) 00177 ast->cum_len += len; 00178 else 00179 ast->cum_len ++; 00180 last_pos= pos; 00181 }else{ 00182 int64_t offset, pos; 00183 int duration; 00184 offset = get_le64(pb); 00185 get_le32(pb); /* size */ 00186 duration = get_le32(pb); 00187 00188 if(url_feof(pb)) 00189 return -1; 00190 00191 pos = url_ftell(pb); 00192 00193 url_fseek(pb, offset+8, SEEK_SET); 00194 read_braindead_odml_indx(s, frame_num); 00195 frame_num += duration; 00196 00197 url_fseek(pb, pos, SEEK_SET); 00198 } 00199 } 00200 avi->index_loaded=1; 00201 return 0; 00202 } 00203 00204 static void clean_index(AVFormatContext *s){ 00205 int i; 00206 int64_t j; 00207 00208 for(i=0; i<s->nb_streams; i++){ 00209 AVStream *st = s->streams[i]; 00210 AVIStream *ast = st->priv_data; 00211 int n= st->nb_index_entries; 00212 int max= ast->sample_size; 00213 int64_t pos, size, ts; 00214 00215 if(n != 1 || ast->sample_size==0) 00216 continue; 00217 00218 while(max < 1024) max+=max; 00219 00220 pos= st->index_entries[0].pos; 00221 size= st->index_entries[0].size; 00222 ts= st->index_entries[0].timestamp; 00223 00224 for(j=0; j<size; j+=max){ 00225 av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME); 00226 } 00227 } 00228 } 00229 00230 static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size) 00231 { 00232 ByteIOContext *pb = s->pb; 00233 char key[5] = {0}, *value; 00234 00235 size += (size & 1); 00236 00237 if (size == UINT_MAX) 00238 return -1; 00239 value = av_malloc(size+1); 00240 if (!value) 00241 return -1; 00242 get_buffer(pb, value, size); 00243 value[size]=0; 00244 00245 AV_WL32(key, tag); 00246 00247 if(st) 00248 return av_metadata_set2(&st->metadata, key, value, 00249 AV_METADATA_DONT_STRDUP_VAL); 00250 else 00251 return av_metadata_set2(&s->metadata, key, value, 00252 AV_METADATA_DONT_STRDUP_VAL); 00253 } 00254 00255 static void avi_read_info(AVFormatContext *s, uint64_t end) 00256 { 00257 while (url_ftell(s->pb) < end) { 00258 uint32_t tag = get_le32(s->pb); 00259 uint32_t size = get_le32(s->pb); 00260 avi_read_tag(s, NULL, tag, size); 00261 } 00262 } 00263 00264 static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) 00265 { 00266 AVIContext *avi = s->priv_data; 00267 ByteIOContext *pb = s->pb; 00268 unsigned int tag, tag1, handler; 00269 int codec_type, stream_index, frame_period, bit_rate; 00270 unsigned int size; 00271 int i; 00272 AVStream *st; 00273 AVIStream *ast = NULL; 00274 int avih_width=0, avih_height=0; 00275 int amv_file_format=0; 00276 uint64_t list_end = 0; 00277 00278 avi->stream_index= -1; 00279 00280 if (get_riff(s, pb) < 0) 00281 return -1; 00282 00283 avi->fsize = url_fsize(pb); 00284 if(avi->fsize<=0) 00285 avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end; 00286 00287 /* first list tag */ 00288 stream_index = -1; 00289 codec_type = -1; 00290 frame_period = 0; 00291 for(;;) { 00292 if (url_feof(pb)) 00293 goto fail; 00294 tag = get_le32(pb); 00295 size = get_le32(pb); 00296 #ifdef DEBUG 00297 print_tag("tag", tag, size); 00298 #endif 00299 00300 switch(tag) { 00301 case MKTAG('L', 'I', 'S', 'T'): 00302 list_end = url_ftell(pb) + size; 00303 /* Ignored, except at start of video packets. */ 00304 tag1 = get_le32(pb); 00305 #ifdef DEBUG 00306 print_tag("list", tag1, 0); 00307 #endif 00308 if (tag1 == MKTAG('m', 'o', 'v', 'i')) { 00309 avi->movi_list = url_ftell(pb) - 4; 00310 if(size) avi->movi_end = avi->movi_list + size + (size & 1); 00311 else avi->movi_end = url_fsize(pb); 00312 dprintf(NULL, "movi end=%"PRIx64"\n", avi->movi_end); 00313 goto end_of_header; 00314 } 00315 else if (tag1 == MKTAG('I', 'N', 'F', 'O')) 00316 avi_read_info(s, list_end); 00317 00318 break; 00319 case MKTAG('d', 'm', 'l', 'h'): 00320 avi->is_odml = 1; 00321 url_fskip(pb, size + (size & 1)); 00322 break; 00323 case MKTAG('a', 'm', 'v', 'h'): 00324 amv_file_format=1; 00325 case MKTAG('a', 'v', 'i', 'h'): 00326 /* AVI header */ 00327 /* using frame_period is bad idea */ 00328 frame_period = get_le32(pb); 00329 bit_rate = get_le32(pb) * 8; 00330 get_le32(pb); 00331 avi->non_interleaved |= get_le32(pb) & AVIF_MUSTUSEINDEX; 00332 00333 url_fskip(pb, 2 * 4); 00334 get_le32(pb); 00335 get_le32(pb); 00336 avih_width=get_le32(pb); 00337 avih_height=get_le32(pb); 00338 00339 url_fskip(pb, size - 10 * 4); 00340 break; 00341 case MKTAG('s', 't', 'r', 'h'): 00342 /* stream header */ 00343 00344 tag1 = get_le32(pb); 00345 handler = get_le32(pb); /* codec tag */ 00346 00347 if(tag1 == MKTAG('p', 'a', 'd', 's')){ 00348 url_fskip(pb, size - 8); 00349 break; 00350 }else{ 00351 stream_index++; 00352 st = av_new_stream(s, stream_index); 00353 if (!st) 00354 goto fail; 00355 00356 ast = av_mallocz(sizeof(AVIStream)); 00357 if (!ast) 00358 goto fail; 00359 st->priv_data = ast; 00360 } 00361 if(amv_file_format) 00362 tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s'); 00363 00364 #ifdef DEBUG 00365 print_tag("strh", tag1, -1); 00366 #endif 00367 if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){ 00368 int64_t dv_dur; 00369 00370 /* 00371 * After some consideration -- I don't think we 00372 * have to support anything but DV in type1 AVIs. 00373 */ 00374 if (s->nb_streams != 1) 00375 goto fail; 00376 00377 if (handler != MKTAG('d', 'v', 's', 'd') && 00378 handler != MKTAG('d', 'v', 'h', 'd') && 00379 handler != MKTAG('d', 'v', 's', 'l')) 00380 goto fail; 00381 00382 ast = s->streams[0]->priv_data; 00383 av_freep(&s->streams[0]->codec->extradata); 00384 av_freep(&s->streams[0]); 00385 s->nb_streams = 0; 00386 if (CONFIG_DV_DEMUXER) { 00387 avi->dv_demux = dv_init_demux(s); 00388 if (!avi->dv_demux) 00389 goto fail; 00390 } 00391 s->streams[0]->priv_data = ast; 00392 url_fskip(pb, 3 * 4); 00393 ast->scale = get_le32(pb); 00394 ast->rate = get_le32(pb); 00395 url_fskip(pb, 4); /* start time */ 00396 00397 dv_dur = get_le32(pb); 00398 if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) { 00399 dv_dur *= AV_TIME_BASE; 00400 s->duration = av_rescale(dv_dur, ast->scale, ast->rate); 00401 } 00402 /* 00403 * else, leave duration alone; timing estimation in utils.c 00404 * will make a guess based on bitrate. 00405 */ 00406 00407 stream_index = s->nb_streams - 1; 00408 url_fskip(pb, size - 9*4); 00409 break; 00410 } 00411 00412 assert(stream_index < s->nb_streams); 00413 st->codec->stream_codec_tag= handler; 00414 00415 get_le32(pb); /* flags */ 00416 get_le16(pb); /* priority */ 00417 get_le16(pb); /* language */ 00418 get_le32(pb); /* initial frame */ 00419 ast->scale = get_le32(pb); 00420 ast->rate = get_le32(pb); 00421 if(!(ast->scale && ast->rate)){ 00422 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); 00423 if(frame_period){ 00424 ast->rate = 1000000; 00425 ast->scale = frame_period; 00426 }else{ 00427 ast->rate = 25; 00428 ast->scale = 1; 00429 } 00430 } 00431 av_set_pts_info(st, 64, ast->scale, ast->rate); 00432 00433 ast->cum_len=get_le32(pb); /* start */ 00434 st->nb_frames = get_le32(pb); 00435 00436 st->start_time = 0; 00437 get_le32(pb); /* buffer size */ 00438 get_le32(pb); /* quality */ 00439 ast->sample_size = get_le32(pb); /* sample ssize */ 00440 ast->cum_len *= FFMAX(1, ast->sample_size); 00441 // av_log(s, AV_LOG_DEBUG, "%d %d %d %d\n", ast->rate, ast->scale, ast->start, ast->sample_size); 00442 00443 switch(tag1) { 00444 case MKTAG('v', 'i', 'd', 's'): 00445 codec_type = AVMEDIA_TYPE_VIDEO; 00446 00447 ast->sample_size = 0; 00448 break; 00449 case MKTAG('a', 'u', 'd', 's'): 00450 codec_type = AVMEDIA_TYPE_AUDIO; 00451 break; 00452 case MKTAG('t', 'x', 't', 's'): 00453 //FIXME 00454 codec_type = AVMEDIA_TYPE_DATA; //AVMEDIA_TYPE_SUB ? FIXME 00455 break; 00456 case MKTAG('d', 'a', 't', 's'): 00457 codec_type = AVMEDIA_TYPE_DATA; 00458 break; 00459 default: 00460 av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1); 00461 goto fail; 00462 } 00463 if(ast->sample_size == 0) 00464 st->duration = st->nb_frames; 00465 ast->frame_offset= ast->cum_len; 00466 url_fskip(pb, size - 12 * 4); 00467 break; 00468 case MKTAG('s', 't', 'r', 'f'): 00469 /* stream header */ 00470 if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) { 00471 url_fskip(pb, size); 00472 } else { 00473 uint64_t cur_pos = url_ftell(pb); 00474 if (cur_pos < list_end) 00475 size = FFMIN(size, list_end - cur_pos); 00476 st = s->streams[stream_index]; 00477 switch(codec_type) { 00478 case AVMEDIA_TYPE_VIDEO: 00479 if(amv_file_format){ 00480 st->codec->width=avih_width; 00481 st->codec->height=avih_height; 00482 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 00483 st->codec->codec_id = CODEC_ID_AMV; 00484 url_fskip(pb, size); 00485 break; 00486 } 00487 get_le32(pb); /* size */ 00488 st->codec->width = get_le32(pb); 00489 st->codec->height = (int32_t)get_le32(pb); 00490 get_le16(pb); /* panes */ 00491 st->codec->bits_per_coded_sample= get_le16(pb); /* depth */ 00492 tag1 = get_le32(pb); 00493 get_le32(pb); /* ImageSize */ 00494 get_le32(pb); /* XPelsPerMeter */ 00495 get_le32(pb); /* YPelsPerMeter */ 00496 get_le32(pb); /* ClrUsed */ 00497 get_le32(pb); /* ClrImportant */ 00498 00499 if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) { 00500 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; 00501 st->codec->codec_tag = tag1; 00502 st->codec->codec_id = CODEC_ID_XSUB; 00503 break; 00504 } 00505 00506 if(size > 10*4 && size<(1<<30)){ 00507 st->codec->extradata_size= size - 10*4; 00508 st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); 00509 if (!st->codec->extradata) { 00510 st->codec->extradata_size= 0; 00511 return AVERROR(ENOMEM); 00512 } 00513 get_buffer(pb, st->codec->extradata, st->codec->extradata_size); 00514 } 00515 00516 if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly 00517 get_byte(pb); 00518 00519 /* Extract palette from extradata if bpp <= 8. */ 00520 /* This code assumes that extradata contains only palette. */ 00521 /* This is true for all paletted codecs implemented in FFmpeg. */ 00522 if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { 00523 st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); 00524 #if HAVE_BIGENDIAN 00525 for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) 00526 st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]); 00527 #else 00528 memcpy(st->codec->palctrl->palette, st->codec->extradata, 00529 FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); 00530 #endif 00531 st->codec->palctrl->palette_changed = 1; 00532 } 00533 00534 #ifdef DEBUG 00535 print_tag("video", tag1, 0); 00536 #endif 00537 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 00538 st->codec->codec_tag = tag1; 00539 st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); 00540 st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts. 00541 // Support "Resolution 1:1" for Avid AVI Codec 00542 if(tag1 == MKTAG('A', 'V', 'R', 'n') && 00543 st->codec->extradata_size >= 31 && 00544 !memcmp(&st->codec->extradata[28], "1:1", 3)) 00545 st->codec->codec_id = CODEC_ID_RAWVIDEO; 00546 00547 if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){ 00548 st->codec->extradata_size+= 9; 00549 st->codec->extradata= av_realloc(st->codec->extradata, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); 00550 if(st->codec->extradata) 00551 memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9); 00552 } 00553 st->codec->height= FFABS(st->codec->height); 00554 00555 // url_fskip(pb, size - 5 * 4); 00556 break; 00557 case AVMEDIA_TYPE_AUDIO: 00558 ff_get_wav_header(pb, st->codec, size); 00559 if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){ 00560 av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align); 00561 ast->sample_size= st->codec->block_align; 00562 } 00563 if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ 00564 url_fskip(pb, 1); 00565 /* Force parsing as several audio frames can be in 00566 * one packet and timestamps refer to packet start. */ 00567 st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; 00568 /* ADTS header is in extradata, AAC without header must be 00569 * stored as exact frames. Parser not needed and it will 00570 * fail. */ 00571 if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size) 00572 st->need_parsing = AVSTREAM_PARSE_NONE; 00573 /* AVI files with Xan DPCM audio (wrongly) declare PCM 00574 * audio in the header but have Axan as stream_code_tag. */ 00575 if (st->codec->stream_codec_tag == AV_RL32("Axan")){ 00576 st->codec->codec_id = CODEC_ID_XAN_DPCM; 00577 st->codec->codec_tag = 0; 00578 } 00579 if (amv_file_format) 00580 st->codec->codec_id = CODEC_ID_ADPCM_IMA_AMV; 00581 break; 00582 default: 00583 st->codec->codec_type = AVMEDIA_TYPE_DATA; 00584 st->codec->codec_id= CODEC_ID_NONE; 00585 st->codec->codec_tag= 0; 00586 url_fskip(pb, size); 00587 break; 00588 } 00589 } 00590 break; 00591 case MKTAG('i', 'n', 'd', 'x'): 00592 i= url_ftell(pb); 00593 if(!url_is_streamed(pb) && !(s->flags & AVFMT_FLAG_IGNIDX)){ 00594 read_braindead_odml_indx(s, 0); 00595 } 00596 url_fseek(pb, i+size, SEEK_SET); 00597 break; 00598 case MKTAG('v', 'p', 'r', 'p'): 00599 if(stream_index < (unsigned)s->nb_streams && size > 9*4){ 00600 AVRational active, active_aspect; 00601 00602 st = s->streams[stream_index]; 00603 get_le32(pb); 00604 get_le32(pb); 00605 get_le32(pb); 00606 get_le32(pb); 00607 get_le32(pb); 00608 00609 active_aspect.den= get_le16(pb); 00610 active_aspect.num= get_le16(pb); 00611 active.num = get_le32(pb); 00612 active.den = get_le32(pb); 00613 get_le32(pb); //nbFieldsPerFrame 00614 00615 if(active_aspect.num && active_aspect.den && active.num && active.den){ 00616 st->sample_aspect_ratio= av_div_q(active_aspect, active); 00617 //av_log(s, AV_LOG_ERROR, "vprp %d/%d %d/%d\n", active_aspect.num, active_aspect.den, active.num, active.den); 00618 } 00619 size -= 9*4; 00620 } 00621 url_fseek(pb, size, SEEK_CUR); 00622 break; 00623 case MKTAG('s', 't', 'r', 'n'): 00624 if(s->nb_streams){ 00625 avi_read_tag(s, s->streams[s->nb_streams-1], tag, size); 00626 break; 00627 } 00628 default: 00629 if(size > 1000000){ 00630 av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, " 00631 "I will ignore it and try to continue anyway.\n"); 00632 avi->movi_list = url_ftell(pb) - 4; 00633 avi->movi_end = url_fsize(pb); 00634 goto end_of_header; 00635 } 00636 /* skip tag */ 00637 size += (size & 1); 00638 url_fskip(pb, size); 00639 break; 00640 } 00641 } 00642 end_of_header: 00643 /* check stream number */ 00644 if (stream_index != s->nb_streams - 1) { 00645 fail: 00646 return -1; 00647 } 00648 00649 if(!avi->index_loaded && !url_is_streamed(pb)) 00650 avi_load_index(s); 00651 avi->index_loaded = 1; 00652 avi->non_interleaved |= guess_ni_flag(s); 00653 for(i=0; i<s->nb_streams; i++){ 00654 AVStream *st = s->streams[i]; 00655 if(st->nb_index_entries) 00656 break; 00657 } 00658 if(i==s->nb_streams && avi->non_interleaved) { 00659 av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n"); 00660 avi->non_interleaved=0; 00661 } 00662 00663 if(avi->non_interleaved) { 00664 av_log(s, AV_LOG_INFO, "non-interleaved AVI\n"); 00665 clean_index(s); 00666 } 00667 00668 return 0; 00669 } 00670 00671 static int get_stream_idx(int *d){ 00672 if( d[0] >= '0' && d[0] <= '9' 00673 && d[1] >= '0' && d[1] <= '9'){ 00674 return (d[0] - '0') * 10 + (d[1] - '0'); 00675 }else{ 00676 return 100; //invalid stream ID 00677 } 00678 } 00679 00680 static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) 00681 { 00682 AVIContext *avi = s->priv_data; 00683 ByteIOContext *pb = s->pb; 00684 int n, d[8]; 00685 unsigned int size; 00686 int64_t i, sync; 00687 void* dstr; 00688 00689 if (CONFIG_DV_DEMUXER && avi->dv_demux) { 00690 int size = dv_get_packet(avi->dv_demux, pkt); 00691 if (size >= 0) 00692 return size; 00693 } 00694 00695 if(avi->non_interleaved){ 00696 int best_stream_index = 0; 00697 AVStream *best_st= NULL; 00698 AVIStream *best_ast; 00699 int64_t best_ts= INT64_MAX; 00700 int i; 00701 00702 for(i=0; i<s->nb_streams; i++){ 00703 AVStream *st = s->streams[i]; 00704 AVIStream *ast = st->priv_data; 00705 int64_t ts= ast->frame_offset; 00706 int64_t last_ts; 00707 00708 if(!st->nb_index_entries) 00709 continue; 00710 00711 last_ts = st->index_entries[st->nb_index_entries - 1].timestamp; 00712 if(!ast->remaining && ts > last_ts) 00713 continue; 00714 00715 ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE}); 00716 00717 // av_log(s, AV_LOG_DEBUG, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset); 00718 if(ts < best_ts){ 00719 best_ts= ts; 00720 best_st= st; 00721 best_stream_index= i; 00722 } 00723 } 00724 if(!best_st) 00725 return -1; 00726 00727 best_ast = best_st->priv_data; 00728 best_ts = av_rescale_q(best_ts, (AVRational){FFMAX(1, best_ast->sample_size), AV_TIME_BASE}, best_st->time_base); 00729 if(best_ast->remaining) 00730 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); 00731 else{ 00732 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY); 00733 if(i>=0) 00734 best_ast->frame_offset= best_st->index_entries[i].timestamp; 00735 } 00736 00737 // av_log(s, AV_LOG_DEBUG, "%d\n", i); 00738 if(i>=0){ 00739 int64_t pos= best_st->index_entries[i].pos; 00740 pos += best_ast->packet_size - best_ast->remaining; 00741 url_fseek(s->pb, pos + 8, SEEK_SET); 00742 // av_log(s, AV_LOG_DEBUG, "pos=%"PRId64"\n", pos); 00743 00744 assert(best_ast->remaining <= best_ast->packet_size); 00745 00746 avi->stream_index= best_stream_index; 00747 if(!best_ast->remaining) 00748 best_ast->packet_size= 00749 best_ast->remaining= best_st->index_entries[i].size; 00750 } 00751 } 00752 00753 resync: 00754 if(avi->stream_index >= 0){ 00755 AVStream *st= s->streams[ avi->stream_index ]; 00756 AVIStream *ast= st->priv_data; 00757 int size, err; 00758 00759 if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM 00760 size= INT_MAX; 00761 else if(ast->sample_size < 32) 00762 // arbitrary multiplier to avoid tiny packets for raw PCM data 00763 size= 1024*ast->sample_size; 00764 else 00765 size= ast->sample_size; 00766 00767 if(size > ast->remaining) 00768 size= ast->remaining; 00769 avi->last_pkt_pos= url_ftell(pb); 00770 err= av_get_packet(pb, pkt, size); 00771 if(err<0) 00772 return err; 00773 00774 if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){ 00775 void *ptr= av_realloc(pkt->data, pkt->size + 4*256 + FF_INPUT_BUFFER_PADDING_SIZE); 00776 if(ptr){ 00777 ast->has_pal=0; 00778 pkt->size += 4*256; 00779 pkt->data= ptr; 00780 memcpy(pkt->data + pkt->size - 4*256, ast->pal, 4*256); 00781 }else 00782 av_log(s, AV_LOG_ERROR, "Failed to append palette\n"); 00783 } 00784 00785 if (CONFIG_DV_DEMUXER && avi->dv_demux) { 00786 dstr = pkt->destruct; 00787 size = dv_produce_packet(avi->dv_demux, pkt, 00788 pkt->data, pkt->size); 00789 pkt->destruct = dstr; 00790 pkt->flags |= AV_PKT_FLAG_KEY; 00791 } else { 00792 /* XXX: How to handle B-frames in AVI? */ 00793 pkt->dts = ast->frame_offset; 00794 // pkt->dts += ast->start; 00795 if(ast->sample_size) 00796 pkt->dts /= ast->sample_size; 00797 //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); 00798 pkt->stream_index = avi->stream_index; 00799 00800 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { 00801 AVIndexEntry *e; 00802 int index; 00803 assert(st->index_entries); 00804 00805 index= av_index_search_timestamp(st, ast->frame_offset, 0); 00806 e= &st->index_entries[index]; 00807 00808 if(index >= 0 && e->timestamp == ast->frame_offset){ 00809 if (e->flags & AVINDEX_KEYFRAME) 00810 pkt->flags |= AV_PKT_FLAG_KEY; 00811 } 00812 } else { 00813 pkt->flags |= AV_PKT_FLAG_KEY; 00814 } 00815 if(ast->sample_size) 00816 ast->frame_offset += pkt->size; 00817 else 00818 ast->frame_offset++; 00819 } 00820 ast->remaining -= size; 00821 if(!ast->remaining){ 00822 avi->stream_index= -1; 00823 ast->packet_size= 0; 00824 } 00825 00826 return size; 00827 } 00828 00829 memset(d, -1, sizeof(int)*8); 00830 for(i=sync=url_ftell(pb); !url_feof(pb); i++) { 00831 int j; 00832 00833 for(j=0; j<7; j++) 00834 d[j]= d[j+1]; 00835 d[7]= get_byte(pb); 00836 00837 size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24); 00838 00839 n= get_stream_idx(d+2); 00840 //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); 00841 if(i + (uint64_t)size > avi->fsize || d[0]<0) 00842 continue; 00843 00844 //parse ix## 00845 if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) 00846 //parse JUNK 00847 ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') 00848 ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){ 00849 url_fskip(pb, size); 00850 //av_log(s, AV_LOG_DEBUG, "SKIP\n"); 00851 goto resync; 00852 } 00853 00854 //parse stray LIST 00855 if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){ 00856 url_fskip(pb, 4); 00857 goto resync; 00858 } 00859 00860 n= get_stream_idx(d); 00861 00862 if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams) 00863 continue; 00864 00865 //detect ##ix chunk and skip 00866 if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){ 00867 url_fskip(pb, size); 00868 goto resync; 00869 } 00870 00871 //parse ##dc/##wb 00872 if(n < s->nb_streams){ 00873 AVStream *st; 00874 AVIStream *ast; 00875 st = s->streams[n]; 00876 ast = st->priv_data; 00877 00878 if(s->nb_streams>=2){ 00879 AVStream *st1 = s->streams[1]; 00880 AVIStream *ast1= st1->priv_data; 00881 //workaround for broken small-file-bug402.avi 00882 if( d[2] == 'w' && d[3] == 'b' 00883 && n==0 00884 && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO 00885 && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO 00886 && ast->prefix == 'd'*256+'c' 00887 && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count) 00888 ){ 00889 n=1; 00890 st = st1; 00891 ast = ast1; 00892 av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n"); 00893 } 00894 } 00895 00896 00897 if( (st->discard >= AVDISCARD_DEFAULT && size==0) 00898 /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering 00899 || st->discard >= AVDISCARD_ALL){ 00900 if(ast->sample_size) ast->frame_offset += size; 00901 else ast->frame_offset++; 00902 url_fskip(pb, size); 00903 goto resync; 00904 } 00905 00906 if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) { 00907 int k = get_byte(pb); 00908 int last = (k + get_byte(pb) - 1) & 0xFF; 00909 00910 get_le16(pb); //flags 00911 00912 for (; k <= last; k++) 00913 ast->pal[k] = get_be32(pb)>>8;// b + (g << 8) + (r << 16); 00914 ast->has_pal= 1; 00915 goto resync; 00916 } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) || 00917 d[2]*256+d[3] == ast->prefix /*|| 00918 (d[2] == 'd' && d[3] == 'c') || 00919 (d[2] == 'w' && d[3] == 'b')*/) { 00920 00921 //av_log(s, AV_LOG_DEBUG, "OK\n"); 00922 if(d[2]*256+d[3] == ast->prefix) 00923 ast->prefix_count++; 00924 else{ 00925 ast->prefix= d[2]*256+d[3]; 00926 ast->prefix_count= 0; 00927 } 00928 00929 avi->stream_index= n; 00930 ast->packet_size= size + 8; 00931 ast->remaining= size; 00932 00933 if(size || !ast->sample_size){ 00934 uint64_t pos= url_ftell(pb) - 8; 00935 if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){ 00936 av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME); 00937 } 00938 } 00939 goto resync; 00940 } 00941 } 00942 } 00943 00944 return AVERROR_EOF; 00945 } 00946 00947 /* XXX: We make the implicit supposition that the positions are sorted 00948 for each stream. */ 00949 static int avi_read_idx1(AVFormatContext *s, int size) 00950 { 00951 AVIContext *avi = s->priv_data; 00952 ByteIOContext *pb = s->pb; 00953 int nb_index_entries, i; 00954 AVStream *st; 00955 AVIStream *ast; 00956 unsigned int index, tag, flags, pos, len; 00957 unsigned last_pos= -1; 00958 00959 nb_index_entries = size / 16; 00960 if (nb_index_entries <= 0) 00961 return -1; 00962 00963 /* Read the entries and sort them in each stream component. */ 00964 for(i = 0; i < nb_index_entries; i++) { 00965 tag = get_le32(pb); 00966 flags = get_le32(pb); 00967 pos = get_le32(pb); 00968 len = get_le32(pb); 00969 #if defined(DEBUG_SEEK) 00970 av_log(s, AV_LOG_DEBUG, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", 00971 i, tag, flags, pos, len); 00972 #endif 00973 if(i==0 && pos > avi->movi_list) 00974 avi->movi_list= 0; //FIXME better check 00975 pos += avi->movi_list; 00976 00977 index = ((tag & 0xff) - '0') * 10; 00978 index += ((tag >> 8) & 0xff) - '0'; 00979 if (index >= s->nb_streams) 00980 continue; 00981 st = s->streams[index]; 00982 ast = st->priv_data; 00983 00984 #if defined(DEBUG_SEEK) 00985 av_log(s, AV_LOG_DEBUG, "%d cum_len=%"PRId64"\n", len, ast->cum_len); 00986 #endif 00987 if(url_feof(pb)) 00988 return -1; 00989 00990 if(last_pos == pos) 00991 avi->non_interleaved= 1; 00992 else if(len || !ast->sample_size) 00993 av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0); 00994 if(ast->sample_size) 00995 ast->cum_len += len; 00996 else 00997 ast->cum_len ++; 00998 last_pos= pos; 00999 } 01000 return 0; 01001 } 01002 01003 static int guess_ni_flag(AVFormatContext *s){ 01004 int i; 01005 int64_t last_start=0; 01006 int64_t first_end= INT64_MAX; 01007 int64_t oldpos= url_ftell(s->pb); 01008 01009 for(i=0; i<s->nb_streams; i++){ 01010 AVStream *st = s->streams[i]; 01011 int n= st->nb_index_entries; 01012 unsigned int size; 01013 01014 if(n <= 0) 01015 continue; 01016 01017 if(n >= 2){ 01018 int64_t pos= st->index_entries[0].pos; 01019 url_fseek(s->pb, pos + 4, SEEK_SET); 01020 size= get_le32(s->pb); 01021 if(pos + size > st->index_entries[1].pos) 01022 last_start= INT64_MAX; 01023 } 01024 01025 if(st->index_entries[0].pos > last_start) 01026 last_start= st->index_entries[0].pos; 01027 if(st->index_entries[n-1].pos < first_end) 01028 first_end= st->index_entries[n-1].pos; 01029 } 01030 url_fseek(s->pb, oldpos, SEEK_SET); 01031 return last_start > first_end; 01032 } 01033 01034 static int avi_load_index(AVFormatContext *s) 01035 { 01036 AVIContext *avi = s->priv_data; 01037 ByteIOContext *pb = s->pb; 01038 uint32_t tag, size; 01039 int64_t pos= url_ftell(pb); 01040 int ret = -1; 01041 01042 if (url_fseek(pb, avi->movi_end, SEEK_SET) < 0) 01043 goto the_end; // maybe truncated file 01044 #ifdef DEBUG_SEEK 01045 printf("movi_end=0x%"PRIx64"\n", avi->movi_end); 01046 #endif 01047 for(;;) { 01048 if (url_feof(pb)) 01049 break; 01050 tag = get_le32(pb); 01051 size = get_le32(pb); 01052 #ifdef DEBUG_SEEK 01053 printf("tag=%c%c%c%c size=0x%x\n", 01054 tag & 0xff, 01055 (tag >> 8) & 0xff, 01056 (tag >> 16) & 0xff, 01057 (tag >> 24) & 0xff, 01058 size); 01059 #endif 01060 switch(tag) { 01061 case MKTAG('i', 'd', 'x', '1'): 01062 if (avi_read_idx1(s, size) < 0) 01063 goto skip; 01064 ret = 0; 01065 goto the_end; 01066 break; 01067 default: 01068 skip: 01069 size += (size & 1); 01070 if (url_fseek(pb, size, SEEK_CUR) < 0) 01071 goto the_end; // something is wrong here 01072 break; 01073 } 01074 } 01075 the_end: 01076 url_fseek(pb, pos, SEEK_SET); 01077 return ret; 01078 } 01079 01080 static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) 01081 { 01082 AVIContext *avi = s->priv_data; 01083 AVStream *st; 01084 int i, index; 01085 int64_t pos; 01086 AVIStream *ast; 01087 01088 if (!avi->index_loaded) { 01089 /* we only load the index on demand */ 01090 avi_load_index(s); 01091 avi->index_loaded = 1; 01092 } 01093 assert(stream_index>= 0); 01094 01095 st = s->streams[stream_index]; 01096 ast= st->priv_data; 01097 index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags); 01098 if(index<0) 01099 return -1; 01100 01101 /* find the position */ 01102 pos = st->index_entries[index].pos; 01103 timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); 01104 01105 // av_log(s, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp); 01106 01107 if (CONFIG_DV_DEMUXER && avi->dv_demux) { 01108 /* One and only one real stream for DV in AVI, and it has video */ 01109 /* offsets. Calling with other stream indexes should have failed */ 01110 /* the av_index_search_timestamp call above. */ 01111 assert(stream_index == 0); 01112 01113 /* Feed the DV video stream version of the timestamp to the */ 01114 /* DV demux so it can synthesize correct timestamps. */ 01115 dv_offset_reset(avi->dv_demux, timestamp); 01116 01117 url_fseek(s->pb, pos, SEEK_SET); 01118 avi->stream_index= -1; 01119 return 0; 01120 } 01121 01122 for(i = 0; i < s->nb_streams; i++) { 01123 AVStream *st2 = s->streams[i]; 01124 AVIStream *ast2 = st2->priv_data; 01125 01126 ast2->packet_size= 01127 ast2->remaining= 0; 01128 01129 if (st2->nb_index_entries <= 0) 01130 continue; 01131 01132 // assert(st2->codec->block_align); 01133 assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale); 01134 index = av_index_search_timestamp( 01135 st2, 01136 av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1), 01137 flags | AVSEEK_FLAG_BACKWARD); 01138 if(index<0) 01139 index=0; 01140 01141 if(!avi->non_interleaved){ 01142 while(index>0 && st2->index_entries[index].pos > pos) 01143 index--; 01144 while(index+1 < st2->nb_index_entries && st2->index_entries[index].pos < pos) 01145 index++; 01146 } 01147 01148 // av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp); 01149 /* extract the current frame number */ 01150 ast2->frame_offset = st2->index_entries[index].timestamp; 01151 } 01152 01153 /* do the seek */ 01154 url_fseek(s->pb, pos, SEEK_SET); 01155 avi->stream_index= -1; 01156 return 0; 01157 } 01158 01159 static int avi_read_close(AVFormatContext *s) 01160 { 01161 int i; 01162 AVIContext *avi = s->priv_data; 01163 01164 for(i=0;i<s->nb_streams;i++) { 01165 AVStream *st = s->streams[i]; 01166 av_free(st->codec->palctrl); 01167 } 01168 01169 if (avi->dv_demux) 01170 av_free(avi->dv_demux); 01171 01172 return 0; 01173 } 01174 01175 static int avi_probe(AVProbeData *p) 01176 { 01177 int i; 01178 01179 /* check file header */ 01180 for(i=0; avi_headers[i][0]; i++) 01181 if(!memcmp(p->buf , avi_headers[i] , 4) && 01182 !memcmp(p->buf+8, avi_headers[i]+4, 4)) 01183 return AVPROBE_SCORE_MAX; 01184 01185 return 0; 01186 } 01187 01188 AVInputFormat avi_demuxer = { 01189 "avi", 01190 NULL_IF_CONFIG_SMALL("AVI format"), 01191 sizeof(AVIContext), 01192 avi_probe, 01193 avi_read_header, 01194 avi_read_packet, 01195 avi_read_close, 01196 avi_read_seek, 01197 .metadata_conv = ff_avi_metadata_conv, 01198 };