static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb)

{

    int j, k, l, sb_x, sb_y;

    int coding_mode;

    int motion_x[6];

    int motion_y[6];

    int last_motion_x = 0;

    int last_motion_y = 0;

    int prior_last_motion_x = 0;

    int prior_last_motion_y = 0;

    int current_macroblock;

    int current_fragment;



    if (s->keyframe)

        return 0;



    memset(motion_x, 0, 6 * sizeof(int));

    memset(motion_y, 0, 6 * sizeof(int));



    /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */

    coding_mode = get_bits1(gb);



    /* iterate through all of the macroblocks that contain 1 or more

     * coded fragments */

    for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {

        for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {



        for (j = 0; j < 4; j++) {

            int mb_x = 2*sb_x +   (j>>1);

            int mb_y = 2*sb_y + (((j>>1)+j)&1);

            current_macroblock = mb_y * s->macroblock_width + mb_x;



            if (mb_x >= s->macroblock_width || mb_y >= s->macroblock_height ||

                (s->macroblock_coding[current_macroblock] == MODE_COPY))

                continue;



            switch (s->macroblock_coding[current_macroblock]) {



            case MODE_INTER_PLUS_MV:

            case MODE_GOLDEN_MV:

                /* all 6 fragments use the same motion vector */

                if (coding_mode == 0) {

                    motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                    motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                } else {

                    motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)];

                    motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)];

                }



                /* vector maintenance, only on MODE_INTER_PLUS_MV */

                if (s->macroblock_coding[current_macroblock] ==

                    MODE_INTER_PLUS_MV) {

                    prior_last_motion_x = last_motion_x;

                    prior_last_motion_y = last_motion_y;

                    last_motion_x = motion_x[0];

                    last_motion_y = motion_y[0];

                }

                break;



            case MODE_INTER_FOURMV:

                /* vector maintenance */

                prior_last_motion_x = last_motion_x;

                prior_last_motion_y = last_motion_y;



                /* fetch 4 vectors from the bitstream, one for each

                 * Y fragment, then average for the C fragment vectors */

                motion_x[4] = motion_y[4] = 0;

                for (k = 0; k < 4; k++) {

                    current_fragment = BLOCK_Y*s->fragment_width + BLOCK_X;

                    for (l = 0; l < s->coded_fragment_list_index; l++)

                        if (s->coded_fragment_list[l] == current_fragment)

                            break;

                    if (l < s->coded_fragment_list_index) {

                        if (coding_mode == 0) {

                            motion_x[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                            motion_y[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                        } else {

                            motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)];

                            motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)];

                        }

                        last_motion_x = motion_x[k];

                        last_motion_y = motion_y[k];

                    } else {

                        motion_x[k] = 0;

                        motion_y[k] = 0;

                    }

                    motion_x[4] += motion_x[k];

                    motion_y[4] += motion_y[k];

                }



                motion_x[5]=

                motion_x[4]= RSHIFT(motion_x[4], 2);

                motion_y[5]=

                motion_y[4]= RSHIFT(motion_y[4], 2);

                break;



            case MODE_INTER_LAST_MV:

                /* all 6 fragments use the last motion vector */

                motion_x[0] = last_motion_x;

                motion_y[0] = last_motion_y;



                /* no vector maintenance (last vector remains the

                 * last vector) */

                break;



            case MODE_INTER_PRIOR_LAST:

                /* all 6 fragments use the motion vector prior to the

                 * last motion vector */

                motion_x[0] = prior_last_motion_x;

                motion_y[0] = prior_last_motion_y;



                /* vector maintenance */

                prior_last_motion_x = last_motion_x;

                prior_last_motion_y = last_motion_y;

                last_motion_x = motion_x[0];

                last_motion_y = motion_y[0];

                break;



            default:

                /* covers intra, inter without MV, golden without MV */

                motion_x[0] = 0;

                motion_y[0] = 0;



                /* no vector maintenance */

                break;

            }



            /* assign the motion vectors to the correct fragments */

            for (k = 0; k < 4; k++) {

                current_fragment =

                    BLOCK_Y*s->fragment_width + BLOCK_X;

                if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {

                    s->all_fragments[current_fragment].motion_x = motion_x[k];

                    s->all_fragments[current_fragment].motion_y = motion_y[k];

                } else {

                    s->all_fragments[current_fragment].motion_x = motion_x[0];

                    s->all_fragments[current_fragment].motion_y = motion_y[0];

                }

            }

            for (k = 0; k < 2; k++) {

                current_fragment = s->fragment_start[k+1] +

                    mb_y*(s->fragment_width>>1) + mb_x;

                if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {

                    s->all_fragments[current_fragment].motion_x = motion_x[k+4];

                    s->all_fragments[current_fragment].motion_y = motion_y[k+4];

                } else {

                    s->all_fragments[current_fragment].motion_x = motion_x[0];

                    s->all_fragments[current_fragment].motion_y = motion_y[0];

                }

            }

        }

        }

    }



    return 0;

}

static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb)

{

    int j, k, l, sb_x, sb_y;

    int coding_mode;

    int motion_x[6];

    int motion_y[6];

    int last_motion_x = 0;

    int last_motion_y = 0;

    int prior_last_motion_x = 0;

    int prior_last_motion_y = 0;

    int current_macroblock;

    int current_fragment;



    if (s->keyframe)

        return 0;



    memset(motion_x, 0, 6 * sizeof(int));

    memset(motion_y, 0, 6 * sizeof(int));



    

    coding_mode = get_bits1(gb);



    



    for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {

        for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {



        for (j = 0; j < 4; j++) {

            int mb_x = 2*sb_x +   (j>>1);

            int mb_y = 2*sb_y + (((j>>1)+j)&1);

            current_macroblock = mb_y * s->macroblock_width + mb_x;



            if (mb_x >= s->macroblock_width || mb_y >= s->macroblock_height ||

                (s->macroblock_coding[current_macroblock] == MODE_COPY))

                continue;



            switch (s->macroblock_coding[current_macroblock]) {



            case MODE_INTER_PLUS_MV:

            case MODE_GOLDEN_MV:

                

                if (coding_mode == 0) {

                    motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                    motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                } else {

                    motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)];

                    motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)];

                }



                

                if (s->macroblock_coding[current_macroblock] ==

                    MODE_INTER_PLUS_MV) {

                    prior_last_motion_x = last_motion_x;

                    prior_last_motion_y = last_motion_y;

                    last_motion_x = motion_x[0];

                    last_motion_y = motion_y[0];

                }

                break;



            case MODE_INTER_FOURMV:

                

                prior_last_motion_x = last_motion_x;

                prior_last_motion_y = last_motion_y;



                



                motion_x[4] = motion_y[4] = 0;

                for (k = 0; k < 4; k++) {

                    current_fragment = BLOCK_Y*s->fragment_width + BLOCK_X;

                    for (l = 0; l < s->coded_fragment_list_index; l++)

                        if (s->coded_fragment_list[l] == current_fragment)

                            break;

                    if (l < s->coded_fragment_list_index) {

                        if (coding_mode == 0) {

                            motion_x[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                            motion_y[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)];

                        } else {

                            motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)];

                            motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)];

                        }

                        last_motion_x = motion_x[k];

                        last_motion_y = motion_y[k];

                    } else {

                        motion_x[k] = 0;

                        motion_y[k] = 0;

                    }

                    motion_x[4] += motion_x[k];

                    motion_y[4] += motion_y[k];

                }



                motion_x[5]=

                motion_x[4]= RSHIFT(motion_x[4], 2);

                motion_y[5]=

                motion_y[4]= RSHIFT(motion_y[4], 2);

                break;



            case MODE_INTER_LAST_MV:

                

                motion_x[0] = last_motion_x;

                motion_y[0] = last_motion_y;



                



                break;



            case MODE_INTER_PRIOR_LAST:

                



                motion_x[0] = prior_last_motion_x;

                motion_y[0] = prior_last_motion_y;



                

                prior_last_motion_x = last_motion_x;

                prior_last_motion_y = last_motion_y;

                last_motion_x = motion_x[0];

                last_motion_y = motion_y[0];

                break;



            default:

                

                motion_x[0] = 0;

                motion_y[0] = 0;



                

                break;

            }



            

            for (k = 0; k < 4; k++) {

                current_fragment =

                    BLOCK_Y*s->fragment_width + BLOCK_X;

                if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {

                    s->all_fragments[current_fragment].motion_x = motion_x[k];

                    s->all_fragments[current_fragment].motion_y = motion_y[k];

                } else {

                    s->all_fragments[current_fragment].motion_x = motion_x[0];

                    s->all_fragments[current_fragment].motion_y = motion_y[0];

                }

            }

            for (k = 0; k < 2; k++) {

                current_fragment = s->fragment_start[k+1] +

                    mb_y*(s->fragment_width>>1) + mb_x;

                if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {

                    s->all_fragments[current_fragment].motion_x = motion_x[k+4];

                    s->all_fragments[current_fragment].motion_y = motion_y[k+4];

                } else {

                    s->all_fragments[current_fragment].motion_x = motion_x[0];

                    s->all_fragments[current_fragment].motion_y = motion_y[0];

                }

            }

        }

        }

    }



    return 0;

}

static int FUNC_0(Vp3DecodeContext *VAR_0, GetBitContext *VAR_1)

{

    int VAR_2, VAR_3, VAR_4, VAR_5, VAR_6;

    int VAR_7;

    int VAR_8[6];

    int VAR_9[6];

    int VAR_10 = 0;

    int VAR_11 = 0;

    int VAR_12 = 0;

    int VAR_13 = 0;

    int VAR_14;

    int VAR_15;



    if (VAR_0->keyframe)

        return 0;



    memset(VAR_8, 0, 6 * sizeof(int));

    memset(VAR_9, 0, 6 * sizeof(int));



    

    VAR_7 = get_bits1(VAR_1);



    



    for (VAR_6 = 0; VAR_6 < VAR_0->y_superblock_height; VAR_6++) {

        for (VAR_5 = 0; VAR_5 < VAR_0->y_superblock_width; VAR_5++) {



        for (VAR_2 = 0; VAR_2 < 4; VAR_2++) {

            int mb_x = 2*VAR_5 +   (VAR_2>>1);

            int mb_y = 2*VAR_6 + (((VAR_2>>1)+VAR_2)&1);

            VAR_14 = mb_y * VAR_0->macroblock_width + mb_x;



            if (mb_x >= VAR_0->macroblock_width || mb_y >= VAR_0->macroblock_height ||

                (VAR_0->macroblock_coding[VAR_14] == MODE_COPY))

                continue;



            switch (VAR_0->macroblock_coding[VAR_14]) {



            case MODE_INTER_PLUS_MV:

            case MODE_GOLDEN_MV:

                

                if (VAR_7 == 0) {

                    VAR_8[0] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)];

                    VAR_9[0] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)];

                } else {

                    VAR_8[0] = fixed_motion_vector_table[get_bits(VAR_1, 6)];

                    VAR_9[0] = fixed_motion_vector_table[get_bits(VAR_1, 6)];

                }



                

                if (VAR_0->macroblock_coding[VAR_14] ==

                    MODE_INTER_PLUS_MV) {

                    VAR_12 = VAR_10;

                    VAR_13 = VAR_11;

                    VAR_10 = VAR_8[0];

                    VAR_11 = VAR_9[0];

                }

                break;



            case MODE_INTER_FOURMV:

                

                VAR_12 = VAR_10;

                VAR_13 = VAR_11;



                



                VAR_8[4] = VAR_9[4] = 0;

                for (VAR_3 = 0; VAR_3 < 4; VAR_3++) {

                    VAR_15 = BLOCK_Y*VAR_0->fragment_width + BLOCK_X;

                    for (VAR_4 = 0; VAR_4 < VAR_0->coded_fragment_list_index; VAR_4++)

                        if (VAR_0->coded_fragment_list[VAR_4] == VAR_15)

                            break;

                    if (VAR_4 < VAR_0->coded_fragment_list_index) {

                        if (VAR_7 == 0) {

                            VAR_8[VAR_3] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)];

                            VAR_9[VAR_3] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)];

                        } else {

                            VAR_8[VAR_3] = fixed_motion_vector_table[get_bits(VAR_1, 6)];

                            VAR_9[VAR_3] = fixed_motion_vector_table[get_bits(VAR_1, 6)];

                        }

                        VAR_10 = VAR_8[VAR_3];

                        VAR_11 = VAR_9[VAR_3];

                    } else {

                        VAR_8[VAR_3] = 0;

                        VAR_9[VAR_3] = 0;

                    }

                    VAR_8[4] += VAR_8[VAR_3];

                    VAR_9[4] += VAR_9[VAR_3];

                }



                VAR_8[5]=

                VAR_8[4]= RSHIFT(VAR_8[4], 2);

                VAR_9[5]=

                VAR_9[4]= RSHIFT(VAR_9[4], 2);

                break;



            case MODE_INTER_LAST_MV:

                

                VAR_8[0] = VAR_10;

                VAR_9[0] = VAR_11;



                



                break;



            case MODE_INTER_PRIOR_LAST:

                



                VAR_8[0] = VAR_12;

                VAR_9[0] = VAR_13;



                

                VAR_12 = VAR_10;

                VAR_13 = VAR_11;

                VAR_10 = VAR_8[0];

                VAR_11 = VAR_9[0];

                break;



            default:

                

                VAR_8[0] = 0;

                VAR_9[0] = 0;



                

                break;

            }



            

            for (VAR_3 = 0; VAR_3 < 4; VAR_3++) {

                VAR_15 =

                    BLOCK_Y*VAR_0->fragment_width + BLOCK_X;

                if (VAR_0->macroblock_coding[VAR_14] == MODE_INTER_FOURMV) {

                    VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[VAR_3];

                    VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[VAR_3];

                } else {

                    VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[0];

                    VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[0];

                }

            }

            for (VAR_3 = 0; VAR_3 < 2; VAR_3++) {

                VAR_15 = VAR_0->fragment_start[VAR_3+1] +

                    mb_y*(VAR_0->fragment_width>>1) + mb_x;

                if (VAR_0->macroblock_coding[VAR_14] == MODE_INTER_FOURMV) {

                    VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[VAR_3+4];

                    VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[VAR_3+4];

                } else {

                    VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[0];

                    VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[0];

                }

            }

        }

        }

    }



    return 0;

}

static int FUNC_0(Vp3DecodeContext *VAR_0, GetBitContext *VAR_1)
{ int VAR_2, VAR_3, VAR_4, VAR_5, VAR_6; int VAR_7; int VAR_8[6]; int VAR_9[6]; int VAR_10 = 0; int VAR_11 = 0; int VAR_12 = 0; int VAR_13 = 0; int VAR_14; int VAR_15; if (VAR_0->keyframe)
return 0; memset(VAR_8, 0, 6 * sizeof(int)); memset(VAR_9, 0, 6 * sizeof(int)); VAR_7 = get_bits1(VAR_1); for (VAR_6 = 0; VAR_6 < VAR_0->y_superblock_height; VAR_6++) { for (VAR_5 = 0; VAR_5 < VAR_0->y_superblock_width; VAR_5++) { for (VAR_2 = 0; VAR_2 < 4; VAR_2++) { int mb_x = 2*VAR_5 +   (VAR_2>>1); int mb_y = 2*VAR_6 + (((VAR_2>>1)+VAR_2)&1); VAR_14 = mb_y * VAR_0->macroblock_width + mb_x; if (mb_x >= VAR_0->macroblock_width || mb_y >= VAR_0->macroblock_height ||
(VAR_0->macroblock_coding[VAR_14] == MODE_COPY))
continue; switch (VAR_0->macroblock_coding[VAR_14]) { case MODE_INTER_PLUS_MV:
case MODE_GOLDEN_MV:
if (VAR_7 == 0) { VAR_8[0] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)]; VAR_9[0] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)]; } else { VAR_8[0] = fixed_motion_vector_table[get_bits(VAR_1, 6)]; VAR_9[0] = fixed_motion_vector_table[get_bits(VAR_1, 6)]; } if (VAR_0->macroblock_coding[VAR_14] ==
MODE_INTER_PLUS_MV) { VAR_12 = VAR_10; VAR_13 = VAR_11; VAR_10 = VAR_8[0]; VAR_11 = VAR_9[0]; } break; case MODE_INTER_FOURMV:
VAR_12 = VAR_10; VAR_13 = VAR_11; VAR_8[4] = VAR_9[4] = 0; for (VAR_3 = 0; VAR_3 < 4; VAR_3++) { VAR_15 = BLOCK_Y*VAR_0->fragment_width + BLOCK_X; for (VAR_4 = 0; VAR_4 < VAR_0->coded_fragment_list_index; VAR_4++) if (VAR_0->coded_fragment_list[VAR_4] == VAR_15)
break; if (VAR_4 < VAR_0->coded_fragment_list_index) { if (VAR_7 == 0) { VAR_8[VAR_3] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)]; VAR_9[VAR_3] = motion_vector_table[get_vlc2(VAR_1, VAR_0->motion_vector_vlc.table, 6, 2)]; } else { VAR_8[VAR_3] = fixed_motion_vector_table[get_bits(VAR_1, 6)]; VAR_9[VAR_3] = fixed_motion_vector_table[get_bits(VAR_1, 6)]; } VAR_10 = VAR_8[VAR_3]; VAR_11 = VAR_9[VAR_3]; } else { VAR_8[VAR_3] = 0; VAR_9[VAR_3] = 0; } VAR_8[4] += VAR_8[VAR_3]; VAR_9[4] += VAR_9[VAR_3]; } VAR_8[5]=
VAR_8[4]= RSHIFT(VAR_8[4], 2); VAR_9[5]=
VAR_9[4]= RSHIFT(VAR_9[4], 2); break; case MODE_INTER_LAST_MV:
VAR_8[0] = VAR_10; VAR_9[0] = VAR_11; break; case MODE_INTER_PRIOR_LAST:
VAR_8[0] = VAR_12; VAR_9[0] = VAR_13; VAR_12 = VAR_10; VAR_13 = VAR_11; VAR_10 = VAR_8[0]; VAR_11 = VAR_9[0]; break; default:
VAR_8[0] = 0; VAR_9[0] = 0; break; } for (VAR_3 = 0; VAR_3 < 4; VAR_3++) { VAR_15 =
BLOCK_Y*VAR_0->fragment_width + BLOCK_X; if (VAR_0->macroblock_coding[VAR_14] == MODE_INTER_FOURMV) { VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[VAR_3]; VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[VAR_3]; } else { VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[0]; VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[0]; } } for (VAR_3 = 0; VAR_3 < 2; VAR_3++) { VAR_15 = VAR_0->fragment_start[VAR_3+1] +
mb_y*(VAR_0->fragment_width>>1) + mb_x; if (VAR_0->macroblock_coding[VAR_14] == MODE_INTER_FOURMV) { VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[VAR_3+4]; VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[VAR_3+4]; } else { VAR_0->all_fragments[VAR_15].VAR_8 = VAR_8[0]; VAR_0->all_fragments[VAR_15].VAR_9 = VAR_9[0]; } } } } } return 0; }