diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/rv10.c')
-rw-r--r-- | src/libffmpeg/libavcodec/rv10.c | 173 |
1 files changed, 79 insertions, 94 deletions
diff --git a/src/libffmpeg/libavcodec/rv10.c b/src/libffmpeg/libavcodec/rv10.c index 72a412eb5..5932126c8 100644 --- a/src/libffmpeg/libavcodec/rv10.c +++ b/src/libffmpeg/libavcodec/rv10.c @@ -223,18 +223,10 @@ 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; + int full_frame= 0; 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)); @@ -273,35 +265,17 @@ static int get_num(GetBitContext *gb) /* read RV 1.0 compatible frame header */ static int rv10_decode_picture_header(MpegEncContext *s) { - int mb_count, pb_frame, marker, h, full_frame; - int pic_num, unk; + int mb_count, pb_frame, marker, full_frame, unk; - /* skip packet header */ - h = get_bits(&s->gb, 8); - if ((h & 0xc0) == 0xc0) { - int len, pos; - 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 */ - pic_num= get_bits(&s->gb, 8); - + full_frame= s->avctx->slice_count==1; +//printf("ff:%d\n", full_frame); marker = get_bits(&s->gb, 1); if (get_bits(&s->gb, 1)) s->pict_type = P_TYPE; else s->pict_type = I_TYPE; -//printf("h:%d ver:%d\n",h,s->rv10_version); +//printf("h:%X ver:%d\n",h,s->rv10_version); if(!marker) printf("marker missing\n"); pb_frame = get_bits(&s->gb, 1); @@ -336,7 +310,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) } /* if multiple packets per frame are sent, the position at which to display the macro blocks is coded here */ - if (!full_frame) { + if ((!full_frame) || show_bits(&s->gb, 12)==0) { s->mb_x = get_bits(&s->gb, 6); /* mb_x */ s->mb_y = get_bits(&s->gb, 6); /* mb_y */ mb_count = get_bits(&s->gb, 12); @@ -365,28 +339,23 @@ static int rv10_decode_init(AVCodecContext *avctx) s->height = avctx->height; s->h263_rv10 = 1; - 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; + switch(avctx->sub_id){ + 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", avctx->sub_id); } - +//printf("ver:%X\n", avctx->sub_id); s->flags= avctx->flags; if (MPV_common_init(s) < 0) @@ -396,6 +365,7 @@ static int rv10_decode_init(AVCodecContext *avctx) s->y_dc_scale_table= s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + s->progressive_sequence=1; /* init rv vlc */ if (!done) { @@ -419,27 +389,14 @@ static int rv10_decode_end(AVCodecContext *avctx) return 0; } -static int rv10_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, +static int rv10_decode_packet(AVCodecContext *avctx, UINT8 *buf, int buf_size) { MpegEncContext *s = avctx->priv_data; int i, mb_count, mb_pos, left; - DCTELEM block[6][64]; - AVPicture *pict = data; - -#ifdef DEBUG - printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); -#endif - - /* no supplementary picture */ - if (buf_size == 0) { - *data_size = 0; - return 0; - } init_get_bits(&s->gb, buf, buf_size); - + mb_count = rv10_decode_picture_header(s); if (mb_count < 0) { fprintf(stderr, "HEADER ERROR\n"); @@ -459,7 +416,8 @@ static int rv10_decode_frame(AVCodecContext *avctx, } if (s->mb_x == 0 && s->mb_y == 0) { - MPV_frame_start(s, avctx); + if(MPV_frame_start(s, avctx) < 0) + return -1; } #ifdef DEBUG @@ -473,52 +431,78 @@ static int rv10_decode_frame(AVCodecContext *avctx, s->rv10_first_dc_coded[1] = 0; s->rv10_first_dc_coded[2] = 0; + if(s->mb_y==0) s->first_slice_line=1; + s->block_wrap[0]= s->block_wrap[1]= s->block_wrap[2]= s->block_wrap[3]= s->mb_width*2 + 2; s->block_wrap[4]= s->block_wrap[5]= s->mb_width + 2; - s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1 + s->mb_x*2; - s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1) + s->mb_x*2; - s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1 + s->mb_x*2; - s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2) + s->mb_x*2; - s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x; - s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x; + ff_init_block_index(s); /* decode each macroblock */ for(i=0;i<mb_count;i++) { - s->block_index[0]+=2; - s->block_index[1]+=2; - s->block_index[2]+=2; - s->block_index[3]+=2; - s->block_index[4]++; - s->block_index[5]++; + ff_update_block_index(s); #ifdef DEBUG printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); #endif - memset(block, 0, sizeof(block)); + clear_blocks(s->block[0]); s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; - if (h263_decode_mb(s, block) < 0) { + if (ff_h263_decode_mb(s, s->block) == SLICE_ERROR) { fprintf(stderr, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); return -1; } - MPV_decode_mb(s, block); + MPV_decode_mb(s, s->block); if (++s->mb_x == s->mb_width) { s->mb_x = 0; s->mb_y++; - s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1; - s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1); - s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1; - s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2); - s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1) + s->block_wrap[0]*(s->mb_height*2 + 2); - s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2); + ff_init_block_index(s); + s->first_slice_line=0; + } + } + + return buf_size; +} + +static int rv10_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + UINT8 *buf, int buf_size) +{ + MpegEncContext *s = avctx->priv_data; + int i; + AVPicture *pict = data; + +#ifdef DEBUG + printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); +#endif + + /* no supplementary picture */ + if (buf_size == 0) { + *data_size = 0; + return 0; + } + + if(avctx->slice_count){ + for(i=0; i<avctx->slice_count; i++){ + int offset= avctx->slice_offset[i]; + int size; + + if(i+1 == avctx->slice_count) + size= buf_size - offset; + else + size= avctx->slice_offset[i+1] - offset; + + if( rv10_decode_packet(avctx, buf+offset, size) < 0 ) + return -1; } + }else{ + if( rv10_decode_packet(avctx, buf, buf_size) < 0 ) + return -1; } - if (s->mb_x == 0 && - s->mb_y == s->mb_height) { + if(s->mb_y>=s->mb_height){ MPV_frame_end(s); pict->data[0] = s->current_picture[0]; @@ -527,12 +511,13 @@ static int rv10_decode_frame(AVCodecContext *avctx, pict->linesize[0] = s->linesize; pict->linesize[1] = s->uvlinesize; pict->linesize[2] = s->uvlinesize; - + avctx->quality = s->qscale; *data_size = sizeof(AVPicture); - } else { + }else{ *data_size = 0; } + return buf_size; } |