From 7866eeff46f3807696100d1061b6cd07af0dd9eb Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 12 Sep 2002 11:10:33 +0000 Subject: [PATCH] m4v input support return the correct number of bytes consumed for decding h263 like formats (needed for reading raw streams) this could break some divx files with b frames, so please tell me ASAP if u notice any problems Originally committed as revision 924 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libav/raw.c | 27 +++++++++++++++++++++++---- libavcodec/h263dec.c | 31 ++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/libav/raw.c b/libav/raw.c index 47efe1af06..6cfa268e13 100644 --- a/libav/raw.c +++ b/libav/raw.c @@ -81,13 +81,19 @@ static int raw_read_header(AVFormatContext *s, int raw_read_packet(AVFormatContext *s, AVPacket *pkt) { - int ret; + int ret, size; + AVStream *st = s->streams[0]; + + if(st->codec.codec_id == CODEC_ID_MPEG4) + size= 1024*1024; //cant handle partial frames + else + size= RAW_PACKET_SIZE; - if (av_new_packet(pkt, RAW_PACKET_SIZE) < 0) + if (av_new_packet(pkt, size) < 0) return -EIO; pkt->stream_index = 0; - ret = get_buffer(&s->pb, pkt->data, RAW_PACKET_SIZE); + ret = get_buffer(&s->pb, pkt->data, size); if (ret <= 0) { av_free_packet(pkt); return -EIO; @@ -132,7 +138,8 @@ static int video_read_header(AVFormatContext *s, st->codec.codec_type = CODEC_TYPE_VIDEO; st->codec.codec_id = s->iformat->value; /* for mjpeg, specify frame rate */ - if (st->codec.codec_id == CODEC_ID_MJPEG) { + /* for mpeg4 specify it too (most mpeg4 streams dont have the fixed_vop_rate set ...)*/ + if (st->codec.codec_id == CODEC_ID_MJPEG || st->codec.codec_id == CODEC_ID_MPEG4) { if (ap) { st->codec.frame_rate = ap->frame_rate; } else { @@ -233,6 +240,17 @@ AVOutputFormat h263_oformat = { raw_write_trailer, }; +AVInputFormat m4v_iformat = { + "m4v", + "raw MPEG4 video format", + 0, + mpegvideo_probe, + video_read_header, + raw_read_packet, + raw_read_close, + value: CODEC_ID_MPEG4, +}; + AVOutputFormat m4v_oformat = { "m4v", "raw MPEG4 video format", @@ -434,6 +452,7 @@ int raw_init(void) av_register_output_format(&h263_oformat); + av_register_input_format(&m4v_iformat); av_register_output_format(&m4v_oformat); av_register_input_format(&mpegvideo_iformat); diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 0d83a5633f..4b30180db4 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -110,6 +110,23 @@ static int h263_decode_end(AVCodecContext *avctx) return 0; } +/** + * retunrs the number of bytes consumed for building the current frame + */ +static int get_consumed_bytes(MpegEncContext *s, int buf_size){ + int pos= (get_bits_count(&s->gb)+7)>>3; + + if(s->divx_version>=500){ + //we would have to scan through the whole buf to handle the weird reordering ... + return buf_size; + }else{ + if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) + if(pos>buf_size) pos=buf_size; // oops ;) + + return pos; + } +} + static int h263_decode_frame(AVCodecContext *avctx, void *data, int *data_size, UINT8 *buf, int buf_size) @@ -179,20 +196,20 @@ uint64_t time= rdtsc(); return -1; } - if(ret==FRAME_SKIPED) return buf_size; + if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size); /* skip if the header was thrashed */ if (ret < 0){ fprintf(stderr, "header damaged\n"); return -1; } /* skip b frames if we dont have reference frames */ - if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return buf_size; + if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size); /* skip b frames if we are in a hurry */ - if(s->hurry_up && s->pict_type==B_TYPE) return buf_size; + if(s->hurry_up && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size); if(s->next_p_frame_damaged){ if(s->pict_type==B_TYPE) - return buf_size; + return get_consumed_bytes(s, buf_size); else s->next_p_frame_damaged=0; } @@ -354,14 +371,14 @@ uint64_t time= rdtsc(); if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1; /* divx 5.01+ bistream reorder stuff */ - if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0){ + if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_version>=500){ int current_pos= get_bits_count(&s->gb)>>3; if( buf_size - current_pos > 5 && buf_size - current_pos < BITSTREAM_BUFFER_SIZE){ int i; int startcode_found=0; - for(i=current_pos; i