diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/h263.c')
-rw-r--r-- | src/libffmpeg/libavcodec/h263.c | 201 |
1 files changed, 75 insertions, 126 deletions
diff --git a/src/libffmpeg/libavcodec/h263.c b/src/libffmpeg/libavcodec/h263.c index 8a60ff08b..ec776eb98 100644 --- a/src/libffmpeg/libavcodec/h263.c +++ b/src/libffmpeg/libavcodec/h263.c @@ -75,7 +75,7 @@ static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr); static void mpeg4_encode_visual_object_header(MpegEncContext * s); static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number); #endif //CONFIG_ENCODERS -static void mpeg4_decode_sprite_trajectory(MpegEncContext * s); +static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb); static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr, int *dir_ptr); #ifdef CONFIG_ENCODERS @@ -577,12 +577,13 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ } else if(IS_INTERLACED(colocated_mb_type)){ s->mv_type = MV_TYPE_FIELD; for(i=0; i<2; i++){ + int field_select= s->next_picture.ref_index[0][s->block_index[2*i]]; if(s->top_field_first){ - 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; + time_pp= s->pp_field_time - field_select + i; + time_pb= s->pb_field_time - field_select + i; }else{ - 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; + time_pp= s->pp_field_time + field_select - i; + time_pb= s->pb_field_time + field_select - i; } 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; @@ -610,7 +611,7 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ void ff_h263_update_motion_val(MpegEncContext * s){ const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; //FIXME a lot of thet is only needed for !low_delay - const int wrap = s->block_wrap[0]; + const int wrap = s->b8_stride; const int xy = s->block_index[0]; s->current_picture.mbskip_table[mb_xy]= s->mb_skiped; @@ -631,10 +632,13 @@ void ff_h263_update_motion_val(MpegEncContext * s){ for(i=0; i<2; 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]; } + s->current_picture.ref_index[0][xy ]= + s->current_picture.ref_index[0][xy + 1]= s->field_select[0][0]; + s->current_picture.ref_index[0][xy + wrap ]= + s->current_picture.ref_index[0][xy + wrap + 1]= s->field_select[0][1]; } - + /* no update if 8X8 because it has been done during parsing */ s->current_picture.motion_val[0][xy][0] = motion_x; s->current_picture.motion_val[0][xy][1] = motion_y; @@ -985,7 +989,7 @@ void mpeg4_encode_mb(MpegEncContext * s, } /* motion vectors: 16x16 mode */ - h263_pred_motion(s, 0, &pred_x, &pred_y); + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); h263_encode_motion(s, motion_x - pred_x, s->f_code); h263_encode_motion(s, motion_y - pred_y, s->f_code); @@ -1009,7 +1013,7 @@ void mpeg4_encode_mb(MpegEncContext * s, } /* motion vectors: 16x8 interlaced mode */ - h263_pred_motion(s, 0, &pred_x, &pred_y); + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); pred_y /=2; put_bits(&s->pb, 1, s->field_select[0][0]); @@ -1037,7 +1041,7 @@ void mpeg4_encode_mb(MpegEncContext * s, for(i=0; i<4; i++){ /* motion vectors: 8x8 mode*/ - h263_pred_motion(s, i, &pred_x, &pred_y); + h263_pred_motion(s, i, 0, &pred_x, &pred_y); h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, s->f_code); h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); @@ -1185,7 +1189,7 @@ void h263_encode_mb(MpegEncContext * s, } /* motion vectors: 16x16 mode */ - h263_pred_motion(s, 0, &pred_x, &pred_y); + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (!s->umvplus) { h263_encode_motion(s, motion_x - pred_x, 1); @@ -1212,7 +1216,7 @@ void h263_encode_mb(MpegEncContext * s, for(i=0; i<4; i++){ /* motion vectors: 8x8 mode*/ - h263_pred_motion(s, i, &pred_x, &pred_y); + h263_pred_motion(s, i, 0, &pred_x, &pred_y); motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0]; motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1]; @@ -1435,16 +1439,16 @@ static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr) /* find prediction */ if (n < 4) { - x = 2 * s->mb_x + 1 + (n & 1); - y = 2 * s->mb_y + 1 + ((n & 2) >> 1); - wrap = s->mb_width * 2 + 2; + x = 2 * s->mb_x + (n & 1); + y = 2 * s->mb_y + ((n & 2) >> 1); + wrap = s->b8_stride; dc_val = s->dc_val[0]; ac_val = s->ac_val[0][0]; scale = s->y_dc_scale; } else { - x = s->mb_x + 1; - y = s->mb_y + 1; - wrap = s->mb_width + 2; + x = s->mb_x; + y = s->mb_y; + wrap = s->mb_stride; dc_val = s->dc_val[n - 4 + 1]; ac_val = s->ac_val[n - 4 + 1][0]; scale = s->c_dc_scale; @@ -1456,8 +1460,10 @@ static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr) c = dc_val[(x) + (y - 1) * wrap]; /* No prediction outside GOB boundary */ - if (s->first_slice_line && ((n < 2) || (n > 3))) - c = 1024; + if(s->first_slice_line && n!=3){ + if(n!=2) c= 1024; + if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024; + } pred_dc = 1024; /* just DC prediction */ if (a != 1024 && c != 1024) @@ -1480,16 +1486,16 @@ static void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) /* find prediction */ if (n < 4) { - x = 2 * s->mb_x + 1 + (n & 1); - y = 2 * s->mb_y + 1 + (n>> 1); - wrap = s->mb_width * 2 + 2; + x = 2 * s->mb_x + (n & 1); + y = 2 * s->mb_y + (n>> 1); + wrap = s->b8_stride; dc_val = s->dc_val[0]; ac_val = s->ac_val[0][0]; scale = s->y_dc_scale; } else { - x = s->mb_x + 1; - y = s->mb_y + 1; - wrap = s->mb_width + 2; + x = s->mb_x; + y = s->mb_y; + wrap = s->mb_stride; dc_val = s->dc_val[n - 4 + 1]; ac_val = s->ac_val[n - 4 + 1][0]; scale = s->c_dc_scale; @@ -1560,78 +1566,15 @@ static void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]]; } -int16_t *h263_pred_motion(MpegEncContext * s, int block, +int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, int *px, int *py) { - int xy, wrap; - int16_t *A, *B, *C, *mot_val; - static const int off[4]= {2, 1, 1, -1}; - - wrap = s->block_wrap[0]; - xy = s->block_index[block]; - - mot_val = s->current_picture.motion_val[0][xy]; - - A = s->current_picture.motion_val[0][xy - 1]; - /* special case for first (slice) line */ - if (s->first_slice_line && block<3) { - // we cant just change some MVs to simulate that as we need them for the B frames (and ME) - // and if we ever support non rectangular objects than we need to do a few ifs here anyway :( - if(block==0){ //most common case - if(s->mb_x == s->resync_mb_x){ //rare - *px= *py = 0; - }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare - C = s->current_picture.motion_val[0][xy + off[block] - wrap]; - if(s->mb_x==0){ - *px = C[0]; - *py = C[1]; - }else{ - *px = mid_pred(A[0], 0, C[0]); - *py = mid_pred(A[1], 0, C[1]); - } - }else{ - *px = A[0]; - *py = A[1]; - } - }else if(block==1){ - if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare - C = s->current_picture.motion_val[0][xy + off[block] - wrap]; - *px = mid_pred(A[0], 0, C[0]); - *py = mid_pred(A[1], 0, C[1]); - }else{ - *px = A[0]; - *py = A[1]; - } - }else{ /* block==2*/ - B = s->current_picture.motion_val[0][xy - wrap]; - C = s->current_picture.motion_val[0][xy + off[block] - wrap]; - if(s->mb_x == s->resync_mb_x) //rare - A[0]=A[1]=0; - - *px = mid_pred(A[0], B[0], C[0]); - *py = mid_pred(A[1], B[1], C[1]); - } - } else { - B = s->current_picture.motion_val[0][xy - wrap]; - C = s->current_picture.motion_val[0][xy + off[block] - wrap]; - *px = mid_pred(A[0], B[0], C[0]); - *py = mid_pred(A[1], B[1], C[1]); - } - return mot_val; -} - -// identical to above but with s->current_picture->motion_val, the above one will be removed, and this renamed to it -int16_t *h263_pred_motion2(MpegEncContext * s, int block, int dir, - int *px, int *py) -{ - int xy, wrap; + int wrap; int16_t *A, *B, *C, (*mot_val)[2]; static const int off[4]= {2, 1, 1, -1}; wrap = s->b8_stride; - xy = 2*(s->mb_x + s->mb_y * wrap); - - mot_val = s->current_picture.motion_val[dir] + xy; + mot_val = s->current_picture.motion_val[dir] + s->block_index[block]; A = mot_val[ - 1]; /* special case for first (slice) line */ @@ -1785,7 +1728,7 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s) else{ int val, bit_size, range, code; - bit_size = s->f_code - 1; + bit_size = f_code - 1; range = 1 << bit_size; val=mv; @@ -2386,6 +2329,7 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) time_div= s->time/s->time_increment_resolution; time_mod= s->time%s->time_increment_resolution; time_incr= time_div - s->last_time_base; + assert(time_incr >= 0); while(time_incr--) put_bits(&s->pb, 1, 1); @@ -2994,13 +2938,12 @@ void ff_mpeg4_init_partitions(MpegEncContext *s) uint8_t *start= pbBufPtr(&s->pb); uint8_t *end= s->pb.buf_end; int size= end - start; - int pb_size = size/3; - int pb2_size= size/3; - int tex_size= size - pb_size - pb2_size; + int pb_size = (((int)start + size/3)&(~3)) - (int)start; + int tex_size= (size - 2*pb_size)&(~3); set_put_bits_buffer_size(&s->pb, pb_size); init_put_bits(&s->tex_pb, start + pb_size , tex_size); - init_put_bits(&s->pb2 , start + pb_size + tex_size, pb2_size); + init_put_bits(&s->pb2 , start + pb_size + tex_size, pb_size); } void ff_mpeg4_merge_partitions(MpegEncContext *s) @@ -3165,7 +3108,7 @@ static int mpeg4_decode_video_packet_header(MpegEncContext *s) skip_bits(&s->gb, 3); /* intra dc vlc threshold */ //FIXME dont just ignore everything if(s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ - mpeg4_decode_sprite_trajectory(s); + mpeg4_decode_sprite_trajectory(s, &s->gb); av_log(s->avctx, AV_LOG_ERROR, "untested\n"); } @@ -3196,10 +3139,10 @@ void ff_mpeg4_clean_buffers(MpegEncContext *s) { int c_wrap, c_xy, l_wrap, l_xy; - l_wrap= s->block_wrap[0]; - l_xy= s->mb_y*l_wrap*2 + s->mb_x*2; - c_wrap= s->block_wrap[4]; - c_xy= s->mb_y*c_wrap + s->mb_x; + l_wrap= s->b8_stride; + l_xy= (2*s->mb_y-1)*l_wrap + s->mb_x*2 - 1; + c_wrap= s->mb_stride; + c_xy= (s->mb_y-1)*c_wrap + s->mb_x - 1; #if 0 /* clean DC */ @@ -3372,7 +3315,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ }else{ /* P/S_TYPE */ int mx, my, pred_x, pred_y, bits; int16_t * const mot_val= s->current_picture.motion_val[0][s->block_index[0]]; - const int stride= s->block_wrap[0]*2; + const int stride= s->b8_stride*2; try_again: bits= show_bits(&s->gb, 17); @@ -3430,7 +3373,7 @@ try_again: if ((cbpc & 16) == 0) { /* 16x16 motion prediction */ - h263_pred_motion(s, 0, &pred_x, &pred_y); + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if(!s->mcsel){ mx = h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) @@ -3454,7 +3397,7 @@ try_again: int i; s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { - int16_t *mot_val= h263_pred_motion(s, i, &pred_x, &pred_y); + int16_t *mot_val= h263_pred_motion(s, i, 0, &pred_x, &pred_y); mx = h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; @@ -3708,7 +3651,7 @@ static void preview_obmc(MpegEncContext *s){ int cbpc, i, pred_x, pred_y, mx, my; int16_t *mot_val; const int xy= s->mb_x + 1 + s->mb_y * s->mb_stride; - const int stride= s->block_wrap[0]*2; + const int stride= s->b8_stride*2; for(i=0; i<4; i++) s->block_index[i]+= 2; @@ -3748,7 +3691,7 @@ static void preview_obmc(MpegEncContext *s){ if ((cbpc & 16) == 0) { s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ - mot_val= h263_pred_motion(s, 0, &pred_x, &pred_y); + mot_val= h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else @@ -3766,7 +3709,7 @@ static void preview_obmc(MpegEncContext *s){ } else { s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, &pred_x, &pred_y); + mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else @@ -3858,7 +3801,7 @@ int ff_h263_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; - h263_pred_motion(s, 0, &pred_x, &pred_y); + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else @@ -3883,7 +3826,7 @@ int ff_h263_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, &pred_x, &pred_y); + mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else @@ -3977,7 +3920,7 @@ int ff_h263_decode_mb(MpegEncContext *s, //FIXME UMV if(USES_LIST(mb_type, 0)){ - int16_t *mot_val= h263_pred_motion2(s, 0, 0, &mx, &my); + int16_t *mot_val= h263_pred_motion(s, 0, 0, &mx, &my); s->mv_dir = MV_DIR_FORWARD; mx = h263_decode_motion(s, mx, 1); @@ -3990,7 +3933,7 @@ int ff_h263_decode_mb(MpegEncContext *s, } if(USES_LIST(mb_type, 1)){ - int16_t *mot_val= h263_pred_motion2(s, 0, 1, &mx, &my); + int16_t *mot_val= h263_pred_motion(s, 0, 1, &mx, &my); s->mv_dir |= MV_DIR_BACKWARD; mx = h263_decode_motion(s, mx, 1); @@ -4145,7 +4088,7 @@ int ff_mpeg4_decode_mb(MpegEncContext *s, s->field_select[0][0]= get_bits1(&s->gb); s->field_select[0][1]= get_bits1(&s->gb); - h263_pred_motion(s, 0, &pred_x, &pred_y); + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); for(i=0; i<2; i++){ mx = h263_decode_motion(s, pred_x, s->f_code); @@ -4163,7 +4106,7 @@ int ff_mpeg4_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; - h263_pred_motion(s, 0, &pred_x, &pred_y); + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); mx = h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) @@ -4180,7 +4123,7 @@ int ff_mpeg4_decode_mb(MpegEncContext *s, s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, &pred_x, &pred_y); + mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); mx = h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; @@ -5117,11 +5060,15 @@ int h263_decode_picture_header(MpegEncContext *s) s->qscale = get_bits(&s->gb, 5); } + s->mb_width = (s->width + 15) / 16; + s->mb_height = (s->height + 15) / 16; + s->mb_num = s->mb_width * s->mb_height; + /* PEI */ while (get_bits1(&s->gb) != 0) { skip_bits(&s->gb, 8); } - + if(s->h263_slice_structured){ if (get_bits1(&s->gb) != 1) { av_log(s->avctx, AV_LOG_ERROR, "SEPB1 marker missing\n"); @@ -5181,7 +5128,7 @@ int h263_decode_picture_header(MpegEncContext *s) return 0; } -static void mpeg4_decode_sprite_trajectory(MpegEncContext * s) +static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) { int i; int a= 2<<s->sprite_warping_accuracy; @@ -5201,17 +5148,17 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s) int length; int x=0, y=0; - length= get_vlc(&s->gb, &sprite_trajectory); + length= get_vlc(gb, &sprite_trajectory); if(length){ - x= get_xbits(&s->gb, length); + x= get_xbits(gb, length); } - if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(&s->gb); /* marker bit */ + if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(gb); /* marker bit */ - length= get_vlc(&s->gb, &sprite_trajectory); + length= get_vlc(gb, &sprite_trajectory); if(length){ - y=get_xbits(&s->gb, length); + y=get_xbits(gb, length); } - skip_bits1(&s->gb); /* marker bit */ + skip_bits1(gb); /* marker bit */ //printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy); d[i][0]= x; d[i][1]= y; @@ -5840,7 +5787,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ } if(s->pict_type == S_TYPE && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ - mpeg4_decode_sprite_trajectory(s); + mpeg4_decode_sprite_trajectory(s, gb); if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n"); if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); } @@ -6111,8 +6058,10 @@ int flv_h263_decode_picture_header(MpegEncContext *s) s->height = height; s->pict_type = I_TYPE + get_bits(&s->gb, 2); - if (s->pict_type > P_TYPE) + s->dropable= s->pict_type > P_TYPE; + if (s->dropable) s->pict_type = P_TYPE; + skip_bits1(&s->gb); /* deblocking flag */ s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); |