From d07f90433af9b830efc47c19723d23d176be9c55 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 22 May 2003 14:12:22 +0000 Subject: [PATCH] truncated h263 decoding support / H263-ES "demuxer" Originally committed as revision 1898 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/h263.c | 58 +++++++++++++++++++++++++++++++++++--------- libavcodec/h263dec.c | 41 ++++++++++++++++++++++++++++++- libavformat/raw.c | 29 ++++++++++++++++++++++ 3 files changed, 115 insertions(+), 13 deletions(-) diff --git a/libavcodec/h263.c b/libavcodec/h263.c index cfaec76b56..5b3119ac9c 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -3902,10 +3902,21 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, /* most is hardcoded. should extend to handle all h263 streams */ int h263_decode_picture_header(MpegEncContext *s) { - int format, width, height; + int format, width, height, i; + uint32_t startcode; + + align_get_bits(&s->gb); - /* picture start code */ - if (get_bits_long(&s->gb, 22) != 0x20) { + startcode= get_bits(&s->gb, 22-8); + + for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>0; i--) { + startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF; + + if(startcode == 0x20) + break; + } + + if (startcode != 0x20) { fprintf(stderr, "Bad picture start code\n"); return -1; } @@ -3988,15 +3999,26 @@ int h263_decode_picture_header(MpegEncContext *s) s->h263_aic = 1; } - skip_bits(&s->gb, 7); - /* these are the 7 bits: (in order of appearence */ - /* Deblocking Filter */ - /* Slice Structured */ - /* Reference Picture Selection */ - /* Independent Segment Decoding */ - /* Alternative Inter VLC */ - /* Modified Quantization */ - /* Prevent start code emulation */ + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Deblocking Filter not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Slice Structured not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Reference Picture Selection not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Independent Segment Decoding not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Alternative Inter VLC not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + fprintf(stderr, "Modified Quantization not supported\n"); + } + + skip_bits(&s->gb, 1); /* Prevent start code emulation */ skip_bits(&s->gb, 3); /* Reserved */ } else if (ufep != 0) { @@ -4072,6 +4094,18 @@ int h263_decode_picture_header(MpegEncContext *s) s->c_dc_scale_table= ff_mpeg1_dc_scale_table; } + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + printf("qp:%d %c size:%d rnd:%d %s %s %s %s\n", + s->qscale, av_get_pict_type_char(s->pict_type), + s->gb.size_in_bits, 1-s->no_rounding, + s->mv_type == MV_TYPE_8X8 ? "ADV" : "", + s->umvplus ? "UMV" : "", + s->h263_long_vectors ? "LONG" : "", + s->h263_plus ? "+" : "" + ); + } + + return 0; } diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 4f42489ccc..5ba0e16291 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -341,6 +341,42 @@ static int mpeg4_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){ return END_NOT_FOUND; } +static int h263_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){ + ParseContext *pc= &s->parse_context; + int vop_found, i; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + i=0; + if(!vop_found){ + for(i=0; i>(32-22) == 0x20){ + i++; + vop_found=1; + break; + } + } + } + + if(vop_found){ + for(; i>(32-22) == 0x20){ + pc->frame_start_found=0; + pc->state=-1; + return i-3; + } + } + } + pc->frame_start_found= vop_found; + pc->state= state; + + return END_NOT_FOUND; +} + /** * draws an line from (ex, ey) -> (sx, sy). * @param w width of the image @@ -440,6 +476,8 @@ uint64_t time= rdtsc(); if(s->codec_id==CODEC_ID_MPEG4){ next= mpeg4_find_frame_end(s, buf, buf_size); + }else if(s->codec_id==CODEC_ID_H263){ + next= h263_find_frame_end(s, buf, buf_size); }else{ fprintf(stderr, "this codec doesnt support truncated bitstreams\n"); return -1; @@ -753,6 +791,7 @@ retry: #ifdef PRINT_FRAME_TIME printf("%Ld\n", rdtsc()-time); #endif + return get_consumed_bytes(s, buf_size); } @@ -784,7 +823,7 @@ AVCodec h263_decoder = { NULL, ff_h263_decode_end, ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, }; AVCodec msmpeg4v1_decoder = { diff --git a/libavformat/raw.c b/libavformat/raw.c index 1c528c17a0..2354ad15cf 100644 --- a/libavformat/raw.c +++ b/libavformat/raw.c @@ -208,6 +208,22 @@ static int mpegvideo_probe(AVProbeData *p) return 0; } +static int h263_probe(AVProbeData *p) +{ + int code; + const uint8_t *d; + + if (p->buf_size < 6) + return 0; + d = p->buf; + code = (d[0] << 14) | (d[1] << 6) | (d[2] >> 2); + if (code == 0x20) { + return 50; + } + return 0; +} + + AVInputFormat mp3_iformat = { "mp3", "MPEG audio", @@ -275,6 +291,18 @@ AVOutputFormat ac3_oformat = { raw_write_trailer, }; +AVInputFormat h263_iformat = { + "h263", + "raw h263", + 0, + h263_probe, + video_read_header, + raw_read_packet, + raw_read_close, +// .extensions = "h263", //FIXME remove after writing mpeg4_probe + .value = CODEC_ID_H263, +}; + AVOutputFormat h263_oformat = { "h263", "raw h263", @@ -538,6 +566,7 @@ int raw_init(void) av_register_input_format(&ac3_iformat); av_register_output_format(&ac3_oformat); + av_register_input_format(&h263_iformat); av_register_output_format(&h263_oformat); av_register_input_format(&m4v_iformat);