diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/rv10.c')
-rw-r--r-- | src/libffmpeg/libavcodec/rv10.c | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/src/libffmpeg/libavcodec/rv10.c b/src/libffmpeg/libavcodec/rv10.c index 248305929..72a412eb5 100644 --- a/src/libffmpeg/libavcodec/rv10.c +++ b/src/libffmpeg/libavcodec/rv10.c @@ -22,7 +22,7 @@ //#define DEBUG -#define DC_VLC_BITS 9 +#define DC_VLC_BITS 14 //FIXME find a better solution static const UINT16 rv_lum_code[256] = { @@ -210,6 +210,7 @@ int rv_decode_dc(MpegEncContext *s, int n) get_bits(&s->gb, 9); code = 1; } else { + fprintf(stderr, "chroma dc error\n"); return 0xffff; } } else { @@ -222,8 +223,18 @@ int rv_decode_dc(MpegEncContext *s, int n) /* write RV 1.0 compatible frame header */ void rv10_encode_picture_header(MpegEncContext *s, int picture_number) { + int full_frame= 1; + align_put_bits(&s->pb); + + if(full_frame){ + put_bits(&s->pb, 8, 0xc0); /* packet header */ + put_bits(&s->pb, 16, 0x4000); /* len */ + put_bits(&s->pb, 16, 0x4000); /* pos */ + } + put_bits(&s->pb, 8, picture_number&0xFF); + put_bits(&s->pb, 1, 1); /* marker */ put_bits(&s->pb, 1, (s->pict_type == P_TYPE)); @@ -237,9 +248,11 @@ void rv10_encode_picture_header(MpegEncContext *s, int picture_number) } /* if multiple packets per frame are sent, the position at which to display the macro blocks is coded here */ - put_bits(&s->pb, 6, 0); /* mb_x */ - put_bits(&s->pb, 6, 0); /* mb_y */ - put_bits(&s->pb, 12, s->mb_width * s->mb_height); + if(!full_frame){ + put_bits(&s->pb, 6, 0); /* mb_x */ + put_bits(&s->pb, 6, 0); /* mb_y */ + put_bits(&s->pb, 12, s->mb_width * s->mb_height); + } put_bits(&s->pb, 3, 0); /* ignored */ } @@ -261,6 +274,7 @@ static int get_num(GetBitContext *gb) static int rv10_decode_picture_header(MpegEncContext *s) { int mb_count, pb_frame, marker, h, full_frame; + int pic_num, unk; /* skip packet header */ h = get_bits(&s->gb, 8); @@ -269,15 +283,17 @@ static int rv10_decode_picture_header(MpegEncContext *s) full_frame = 1; len = get_num(&s->gb); pos = get_num(&s->gb); +//printf("pos:%d\n",len); } else { int seq, frame_size, pos; full_frame = 0; seq = get_bits(&s->gb, 8); frame_size = get_num(&s->gb); pos = get_num(&s->gb); +//printf("seq:%d, size:%d, pos:%d\n",seq,frame_size,pos); } /* picture number */ - get_bits(&s->gb, 8); + pic_num= get_bits(&s->gb, 8); marker = get_bits(&s->gb, 1); @@ -285,17 +301,24 @@ static int rv10_decode_picture_header(MpegEncContext *s) s->pict_type = P_TYPE; else s->pict_type = I_TYPE; - +//printf("h:%d ver:%d\n",h,s->rv10_version); + if(!marker) printf("marker missing\n"); pb_frame = get_bits(&s->gb, 1); #ifdef DEBUG printf("pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame); #endif - if (pb_frame) + if (pb_frame){ + fprintf(stderr, "pb frame not supported\n"); return -1; + } s->qscale = get_bits(&s->gb, 5); + if(s->qscale==0){ + fprintf(stderr, "error, qscale:0\n"); + return -1; + } if (s->pict_type == I_TYPE) { if (s->rv10_version == 3) { @@ -322,13 +345,11 @@ static int rv10_decode_picture_header(MpegEncContext *s) s->mb_y = 0; mb_count = s->mb_width * s->mb_height; } - - get_bits(&s->gb, 3); /* ignored */ + unk= get_bits(&s->gb, 3); /* ignored */ +//printf("%d\n", unk); s->f_code = 1; s->unrestricted_mv = 1; -#if 0 - s->h263_long_vectors = 1; -#endif + return mb_count; } @@ -337,14 +358,34 @@ static int rv10_decode_init(AVCodecContext *avctx) MpegEncContext *s = avctx->priv_data; static int done; -// s->avctx= avctx; + s->avctx= avctx; s->out_format = FMT_H263; s->width = avctx->width; s->height = avctx->height; s->h263_rv10 = 1; - s->rv10_version = avctx->sub_id; + if(avctx->extradata_size >= 8){ + switch(((uint32_t*)avctx->extradata)[1]){ + case 0x10000000: + s->rv10_version= 0; + s->h263_long_vectors=0; + break; + case 0x10003000: + s->rv10_version= 3; + s->h263_long_vectors=1; + break; + case 0x10003001: + s->rv10_version= 3; + s->h263_long_vectors=0; + break; + default: + fprintf(stderr, "unknown header %X\n", ((uint32_t*)avctx->extradata)[1]); + } + }else{ + // for backward compatibility + s->rv10_version= avctx->sub_id; + } s->flags= avctx->flags; @@ -353,6 +394,9 @@ static int rv10_decode_init(AVCodecContext *avctx) h263_decode_init_vlc(s); + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + /* init rv vlc */ if (!done) { init_vlc(&rv_dc_lum, DC_VLC_BITS, 256, @@ -398,25 +442,19 @@ static int rv10_decode_frame(AVCodecContext *avctx, mb_count = rv10_decode_picture_header(s); if (mb_count < 0) { -#ifdef DEBUG - printf("HEADER ERROR\n"); -#endif + fprintf(stderr, "HEADER ERROR\n"); return -1; } if (s->mb_x >= s->mb_width || s->mb_y >= s->mb_height) { -#ifdef DEBUG - printf("POS ERROR %d %d\n", s->mb_x, s->mb_y); -#endif + fprintf(stderr, "POS ERROR %d %d\n", s->mb_x, s->mb_y); return -1; } mb_pos = s->mb_y * s->mb_width + s->mb_x; left = s->mb_width * s->mb_height - mb_pos; if (mb_count > left) { -#ifdef DEBUG - printf("COUNT ERROR\n"); -#endif + fprintf(stderr, "COUNT ERROR\n"); return -1; } @@ -463,9 +501,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; if (h263_decode_mb(s, block) < 0) { -#ifdef DEBUG - printf("ERROR\n"); -#endif + fprintf(stderr, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); return -1; } MPV_decode_mb(s, block); |