[FFmpeg-soc] [soc]: r1043 - rv40/rv40.c
Michael Niedermayer
michaelni at gmx.at
Mon Aug 20 14:46:54 CEST 2007
Hi
On Mon, Aug 20, 2007 at 11:50:08AM +0200, kostya wrote:
> Author: kostya
> Date: Mon Aug 20 11:50:07 2007
> New Revision: 1043
>
> Log:
> B-frames motion prediction and compensation
>
> Modified:
> rv40/rv40.c
>
> Modified: rv40/rv40.c
> ==============================================================================
> --- rv40/rv40.c (original)
> +++ rv40/rv40.c Mon Aug 20 11:50:07 2007
> @@ -879,6 +879,160 @@ static void rv40_pred_mv(RV40DecContext
> }
>
> /**
> + * Predict motion vector for B-frame macroblock.
> + */
> +static inline void rv40_pred_b_vector(int A[2], int B[2], int C[2], int no_A, int no_B, int no_C, int *mx, int *my)
> +{
> + switch(no_A + no_B + no_C){
> + case 0:
> + *mx = mid_pred(A[0], B[0], C[0]);
> + *my = mid_pred(A[1], B[1], C[1]);
> + break;
> + case 1:
> + if(no_A){
> + *mx = (B[0] + C[0]) / 2;
> + *my = (B[1] + C[1]) / 2;
> + }else if(no_B){
> + *mx = (A[0] + C[0]) / 2;
> + *my = (A[1] + C[1]) / 2;
> + }else{
> + *mx = (A[0] + B[0]) / 2;
> + *my = (A[1] + B[1]) / 2;
> + }
> + break;
> + case 2:
> + if(!no_A){
> + *mx = A[0];
> + *my = A[1];
> + }else if(!no_B){
> + *mx = B[0];
> + *my = B[1];
> + }else{
> + *mx = C[0];
> + *my = C[1];
> + }
> + break;
> + default:
> + *mx = *my = 0;
> + break;
> + }
> +}
i assume A/B/C are 0 if no_A/B/C are 1
if so you could do
if(no_A + no_B + no_C){
*mx = *my = 0;
if(!no_A){
*mx += A[0];
*my += A[1];
}
if(!no_B){
*mx += B[0];
*my += B[1];
}
if(!no_C){
*mx += C[0];
*my += C[1];
}
if(no_A + no_B + no_C == 1){
*mx /=2;
*my /=2;
}
}else{
*mx = mid_pred(A[0], B[0], C[0]);
*my = mid_pred(A[1], B[1], C[1]);
}
[...]
> @@ -983,16 +1242,28 @@ static int rv40_decode_mv(RV40DecContext
> rv40_mc(r, block_type, 0, 0, 0, 2, 2);
> break;
> case RV40_MB_B_INTERP:
> + r->dmv[0][0] = 0;
> + r->dmv[0][1] = 0;
> + r->dmv[1][0] = 0;
> + r->dmv[1][1] = 0;
> + rv40_pred_mv_b (r, block_type);
> + rv40_mc_b (r, block_type);
> + rv40_mc_b_interp(r, block_type);
> break;
> case RV40_MB_P_16x16:
> - case RV40_MB_B_FORWARD:
> - case RV40_MB_B_BACKWARD:
> case RV40_MB_P_MIX16x16:
> r->dmv[0][0] = get_omega_signed(gb);
> r->dmv[0][1] = get_omega_signed(gb);
> rv40_pred_mv(r, block_type, 0);
> rv40_mc(r, block_type, 0, 0, 0, 2, 2);
> break;
> + case RV40_MB_B_FORWARD:
> + case RV40_MB_B_BACKWARD:
> + r->dmv[0][0] = get_omega_signed(gb);
> + r->dmv[0][1] = get_omega_signed(gb);
> + rv40_pred_mv_b (r, block_type);
> + rv40_mc_b (r, block_type);
> + break;
> case RV40_MB_P_16x8:
> case RV40_MB_P_8x16:
> case RV40_MB_B_DIRECT:
> @@ -1010,6 +1281,11 @@ static int rv40_decode_mv(RV40DecContext
> rv40_mc(r, block_type, 0, 0, 0, 1, 2);
> rv40_mc(r, block_type, 8, 0, 1, 1, 2);
> }
> + if(block_type == RV40_MB_B_DIRECT){
> + rv40_pred_mv_b (r, block_type);
> + rv40_mc_b (r, block_type);
> + rv40_mc_b_interp(r, block_type);
> + }
> break;
your code looks odd
that what you call RV40_MB_B_INTERP looks like DIRECT, that what you call
direct looks like bidirectional
direct uses the motion vectors from another frame (not the surrounding blocks)
(that is in early h264 and mpeg4 later h264 can use the surrounding blocks
too IIRC)
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Observe your enemies, for they first find out your faults. -- Antisthenes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-soc/attachments/20070820/e08e6cd1/attachment.pgp>
More information about the FFmpeg-soc
mailing list