Mercurial > libavcodec.hg
diff h263.c @ 1708:dea5b2946999 libavcodec
interlaced motion estimation
interlaced mpeg2 encoding
P & B frames
rate distored interlaced mb decission
alternate scantable support
4mv encoding fixes (thats also why the regression tests change)
passing height to most dsp functions
interlaced mpeg4 encoding (no direct mode MBs yet)
various related cleanups
disabled old motion estimaton algorithms (log, full, ...) they will either be fixed or removed
author | michael |
---|---|
date | Tue, 30 Dec 2003 16:07:57 +0000 |
parents | 95b7ac3344df |
children | 07a484280a82 |
line wrap: on
line diff
--- a/h263.c Tue Dec 30 15:29:38 2003 +0000 +++ b/h263.c Tue Dec 30 16:07:57 2003 +0000 @@ -479,9 +479,9 @@ for(i=1; i<s->mb_num; i++){ int mb_xy= s->mb_index2xy[i]; - if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&MB_TYPE_INTER4V)){ - s->mb_type[mb_xy]&= ~MB_TYPE_INTER4V; - s->mb_type[mb_xy]|= MB_TYPE_INTER; + if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTER4V)){ + s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_INTER4V; + s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER; } } @@ -508,9 +508,9 @@ for(i=1; i<s->mb_num; i++){ int mb_xy= s->mb_index2xy[i]; - if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&MB_TYPE_DIRECT)){ - s->mb_type[mb_xy]&= ~MB_TYPE_DIRECT; - s->mb_type[mb_xy]|= MB_TYPE_BIDIR; + if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){ + s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_DIRECT; + s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR; } } } @@ -523,7 +523,7 @@ */ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ const int mb_index= s->mb_x + s->mb_y*s->mb_stride; - const int colocated_mb_type= s->next_picture.mb_type[mb_index]; //FIXME or next? + const int colocated_mb_type= s->next_picture.mb_type[mb_index]; int xy= s->block_index[0]; uint16_t time_pp= s->pp_time; uint16_t time_pb= s->pb_time; @@ -547,18 +547,18 @@ s->mv_type = MV_TYPE_FIELD; for(i=0; i<2; i++){ if(s->top_field_first){ - time_pp= s->pp_field_time - s->field_select_table[mb_index][i] + i; - time_pb= s->pb_field_time - s->field_select_table[mb_index][i] + i; + time_pp= s->pp_field_time - s->p_field_select_table[i][mb_index] + i; + time_pb= s->pb_field_time - s->p_field_select_table[i][mb_index] + i; }else{ - time_pp= s->pp_field_time + s->field_select_table[mb_index][i] - i; - time_pb= s->pb_field_time + s->field_select_table[mb_index][i] - i; + time_pp= s->pp_field_time + s->p_field_select_table[i][mb_index] - i; + time_pb= s->pb_field_time + s->p_field_select_table[i][mb_index] - i; } - s->mv[0][i][0] = s->field_mv_table[mb_index][i][0]*time_pb/time_pp + mx; - s->mv[0][i][1] = s->field_mv_table[mb_index][i][1]*time_pb/time_pp + my; - s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->field_mv_table[mb_index][i][0] - : s->field_mv_table[mb_index][i][0]*(time_pb - time_pp)/time_pp; - s->mv[1][i][1] = my ? s->mv[0][i][1] - s->field_mv_table[mb_index][i][1] - : s->field_mv_table[mb_index][i][1]*(time_pb - time_pp)/time_pp; + s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx; + s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my; + s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0] + : s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp; + s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1] + : s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp; } return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; }else{ @@ -598,9 +598,9 @@ motion_y = s->mv[0][0][1] + s->mv[0][1][1]; motion_x = (motion_x>>1) | (motion_x&1); for(i=0; i<2; i++){ - s->field_mv_table[mb_xy][i][0]= s->mv[0][i][0]; - s->field_mv_table[mb_xy][i][1]= s->mv[0][i][1]; - s->field_select_table[mb_xy][i]= s->field_select[0][i]; + s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0]; + s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1]; + s->p_field_select_table[i][mb_xy]= s->field_select[0][i]; } } @@ -744,12 +744,14 @@ if(s->pict_type==B_TYPE){ static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ int mb_type= mb_type_table[s->mv_dir]; - + if(s->mb_x==0){ - s->last_mv[0][0][0]= - s->last_mv[0][0][1]= - s->last_mv[1][0][0]= - s->last_mv[1][0][1]= 0; + for(i=0; i<2; i++){ + s->last_mv[i][0][0]= + s->last_mv[i][0][1]= + s->last_mv[i][1][0]= + s->last_mv[i][1][1]= 0; + } } assert(s->dquant>=-2 && s->dquant<=2); @@ -803,50 +805,64 @@ if(cbp) put_bits(&s->pb, 1, s->interlaced_dct); if(mb_type) // not diect mode - put_bits(&s->pb, 1, 0); // no interlaced ME yet + put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD); } if(interleaved_stats){ s->misc_bits+= get_bits_diff(s); } - switch(mb_type) - { - case 0: /* direct */ + if(mb_type == 0){ + assert(s->mv_dir & MV_DIRECT); h263_encode_motion(s, motion_x, 1); h263_encode_motion(s, motion_y, 1); s->b_count++; s->f_count++; - break; - case 1: /* bidir */ - h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); - h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); - h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); - h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); - s->last_mv[0][0][0]= s->mv[0][0][0]; - s->last_mv[0][0][1]= s->mv[0][0][1]; - s->last_mv[1][0][0]= s->mv[1][0][0]; - s->last_mv[1][0][1]= s->mv[1][0][1]; - s->b_count++; - s->f_count++; - break; - case 2: /* backward */ - h263_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code); - h263_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code); - s->last_mv[1][0][0]= motion_x; - s->last_mv[1][0][1]= motion_y; - s->b_count++; - break; - case 3: /* forward */ - h263_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); - h263_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); - s->last_mv[0][0][0]= motion_x; - s->last_mv[0][0][1]= motion_y; - s->f_count++; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown mb type\n"); - return; + }else{ + assert(mb_type > 0 && mb_type < 4); + if(s->mv_type != MV_TYPE_FIELD){ + if(s->mv_dir & MV_DIR_FORWARD){ + h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); + h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); + s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; + s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; + s->f_count++; + } + if(s->mv_dir & MV_DIR_BACKWARD){ + h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); + h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); + s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; + s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; + s->b_count++; + } + }else{ + if(s->mv_dir & MV_DIR_FORWARD){ + put_bits(&s->pb, 1, s->field_select[0][0]); + put_bits(&s->pb, 1, s->field_select[0][1]); + } + if(s->mv_dir & MV_DIR_BACKWARD){ + put_bits(&s->pb, 1, s->field_select[1][0]); + put_bits(&s->pb, 1, s->field_select[1][1]); + } + if(s->mv_dir & MV_DIR_FORWARD){ + for(i=0; i<2; i++){ + h263_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); + h263_encode_motion(s, s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0]; + s->last_mv[0][i][1]= s->mv[0][i][1]*2; + } + s->f_count++; + } + if(s->mv_dir & MV_DIR_BACKWARD){ + for(i=0; i<2; i++){ + h263_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); + h263_encode_motion(s, s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); + s->last_mv[1][i][0]= s->mv[1][i][0]; + s->last_mv[1][i][1]= s->mv[1][i][1]*2; + } + s->b_count++; + } + } } if(interleaved_stats){ @@ -861,6 +877,7 @@ if(interleaved_stats){ s->p_tex_bits+= get_bits_diff(s); } + }else{ /* s->pict_type==B_TYPE */ cbp= get_p_cbp(s, block, motion_x, motion_y); @@ -889,7 +906,7 @@ if(pic==NULL || pic->pict_type!=B_TYPE) break; b_pic= pic->data[0] + offset + 16; //FIXME +16 - diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize); + diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); if(diff>s->qscale*70){ //FIXME check that 70 is optimal s->mb_skiped=0; break; @@ -929,7 +946,7 @@ if(!s->progressive_sequence){ if(cbp) put_bits(pb2, 1, s->interlaced_dct); - put_bits(pb2, 1, 0); // no interlaced ME yet + put_bits(pb2, 1, 0); } if(interleaved_stats){ @@ -941,7 +958,38 @@ h263_encode_motion(s, motion_x - pred_x, s->f_code); h263_encode_motion(s, motion_y - pred_y, s->f_code); + }else if(s->mv_type==MV_TYPE_FIELD){ + if(s->dquant) cbpc+= 8; + put_bits(&s->pb, + inter_MCBPC_bits[cbpc], + inter_MCBPC_code[cbpc]); + + put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + if(s->dquant) + put_bits(pb2, 2, dquant_code[s->dquant+2]); + + assert(!s->progressive_sequence); + if(cbp) + put_bits(pb2, 1, s->interlaced_dct); + put_bits(pb2, 1, 1); + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + /* motion vectors: 16x8 interlaced mode */ + h263_pred_motion(s, 0, &pred_x, &pred_y); + pred_y /=2; + + put_bits(&s->pb, 1, s->field_select[0][0]); + put_bits(&s->pb, 1, s->field_select[0][1]); + + h263_encode_motion(s, s->mv[0][0][0] - pred_x, s->f_code); + h263_encode_motion(s, s->mv[0][0][1] - pred_y, s->f_code); + h263_encode_motion(s, s->mv[0][1][0] - pred_x, s->f_code); + h263_encode_motion(s, s->mv[0][1][1] - pred_y, s->f_code); }else{ + assert(s->mv_type==MV_TYPE_8X8); put_bits(&s->pb, inter_MCBPC_bits[cbpc+16], inter_MCBPC_code[cbpc+16]);