diff options
Diffstat (limited to 'libavcodec/h263dec.c')
-rw-r--r-- | libavcodec/h263dec.c | 124 |
1 files changed, 91 insertions, 33 deletions
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index cb473ea..d88464f 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -344,6 +344,42 @@ static int mpeg4_find_frame_end(MpegEncContext *s, UINT8 *buf, int buf_size){ return -1; } +static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){ + int t, x, y, f; + + ex= clip(ex, 0, w-1); + ey= clip(ey, 0, h-1); + + buf[sy*stride + sx]+= color; + + if(ABS(ex - sx) > ABS(ey - sy)){ + if(sx > ex){ + t=sx; sx=ex; ex=t; + t=sy; sy=ey; ey=t; + } + buf+= sx + sy*stride; + ex-= sx; + f= ((ey-sy)<<16)/ex; + for(x= 0; x <= ex; x++){ + y= ((x*f) + (1<<15))>>16; + buf[y*stride + x]+= color; + } + }else{ + if(sy > ey){ + t=sx; sx=ex; ex=t; + t=sy; sy=ey; ey=t; + } + buf+= sx + sy*stride; + ey-= sy; + if(ey) f= ((ex-sx)<<16)/ey; + else f= 0; + for(y= 0; y <= ey; y++){ + x= ((y*f) + (1<<15))>>16; + buf[y*stride + x]+= color; + } + } +} + int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *data_size, UINT8 *buf, int buf_size) @@ -472,6 +508,14 @@ retry: if(s->xvid_build && s->xvid_build<=1) s->workaround_bugs|= FF_BUG_QPEL_CHROMA; +#define SET_QPEL_FUNC(postfix1, postfix2) \ + s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\ + s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\ + s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2; + + if(s->lavc_build && s->lavc_build<4653) + s->workaround_bugs|= FF_BUG_STD_QPEL; + //printf("padding_bug_score: %d\n", s->padding_bug_score); #if 0 if(s->divx_version==500) @@ -489,6 +533,21 @@ retry: #endif } + if(s->workaround_bugs& FF_BUG_STD_QPEL){ + SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c) + + SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c) + } #if 0 // dump bits per frame / qp / complexity { @@ -645,41 +704,40 @@ retry: } MPV_frame_end(s); -#if 0 //dirty show MVs, we should export the MV tables and write a filter to show them -{ - int mb_y; - s->has_b_frames=1; - for(mb_y=0; mb_y<s->mb_height; mb_y++){ - int mb_x; - int y= mb_y*16 + 8; - for(mb_x=0; mb_x<s->mb_width; mb_x++){ - int x= mb_x*16 + 8; - uint8_t *ptr= s->last_picture.data[0]; - int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2); - int mx= (s->motion_val[xy][0]>>1) + x; - int my= (s->motion_val[xy][1]>>1) + y; - int i; - int max; - - if(mx<0) mx=0; - if(my<0) my=0; - if(mx>=s->width) mx= s->width -1; - if(my>=s->height) my= s->height-1; - max= ABS(mx-x); - if(ABS(my-y) > max) max= ABS(my-y); - /* the ugliest linedrawing routine ... */ - for(i=0; i<max; i++){ - int x1= x + (mx-x)*i/max; - int y1= y + (my-y)*i/max; - ptr[y1*s->linesize + x1]+=100; - } - ptr[y*s->linesize + x]+=100; - s->mbskip_table[mb_x + mb_y*s->mb_width]=0; + + if((avctx->debug&FF_DEBUG_VIS_MV) && s->last_picture.data[0]){ + const int shift= 1 + s->quarter_sample; + int mb_y; + uint8_t *ptr= s->last_picture.data[0]; + s->low_delay=0; //needed to see the vectors without trashing the buffers + + for(mb_y=0; mb_y<s->mb_height; mb_y++){ + int mb_x; + for(mb_x=0; mb_x<s->mb_width; mb_x++){ + const int mb_index= mb_x + mb_y*s->mb_width; + if(s->co_located_type_table[mb_index] == MV_TYPE_8X8){ + int i; + for(i=0; i<4; i++){ + int sx= mb_x*16 + 4 + 8*(i&1); + int sy= mb_y*16 + 4 + 8*(i>>1); + int xy= 1 + mb_x*2 + (i&1) + (mb_y*2 + 1 + (i>>1))*(s->mb_width*2 + 2); + int mx= (s->motion_val[xy][0]>>shift) + sx; + int my= (s->motion_val[xy][1]>>shift) + sy; + draw_line(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100); + } + }else{ + int sx= mb_x*16 + 8; + int sy= mb_y*16 + 8; + int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2); + int mx= (s->motion_val[xy][0]>>shift) + sx; + int my= (s->motion_val[xy][1]>>shift) + sy; + draw_line(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100); + } + s->mbskip_table[mb_index]=0; + } + } } - } -} -#endif if(s->pict_type==B_TYPE || s->low_delay){ *pict= *(AVFrame*)&s->current_picture; |