⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vp3.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 5 页
字号:
        s->first_coded_y_fragment,        s->last_coded_y_fragment,        s->first_coded_c_fragment,        s->last_coded_c_fragment);    return 0;}/* * This function unpacks all the coding mode data for individual macroblocks * from the bitstream. */static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb){    int i, j, k;    int scheme;    int current_macroblock;    int current_fragment;    int coding_mode;    debug_vp3("  vp3: unpacking encoding modes\n");    if (s->keyframe) {        debug_vp3("    keyframe-- all blocks are coded as INTRA\n");        for (i = 0; i < s->fragment_count; i++)            s->all_fragments[i].coding_method = MODE_INTRA;    } else {        /* fetch the mode coding scheme for this frame */        scheme = get_bits(gb, 3);        debug_modes("    using mode alphabet %d\n", scheme);        /* is it a custom coding scheme? */        if (scheme == 0) {            debug_modes("    custom mode alphabet ahead:\n");            for (i = 0; i < 8; i++)                ModeAlphabet[scheme][get_bits(gb, 3)] = i;        }        for (i = 0; i < 8; i++)            debug_modes("      mode[%d][%d] = %d\n", scheme, i,                 ModeAlphabet[scheme][i]);        /* iterate through all of the macroblocks that contain 1 or more         * coded fragments */        for (i = 0; i < s->u_superblock_start; i++) {            for (j = 0; j < 4; j++) {                current_macroblock = s->superblock_macroblocks[i * 4 + j];                if ((current_macroblock == -1) ||                    (s->macroblock_coding[current_macroblock] == MODE_COPY))                    continue;                if (current_macroblock >= s->macroblock_count) {                    av_log(s->avctx, AV_LOG_ERROR, "  vp3:unpack_modes(): bad macroblock number (%d >= %d)\n",                        current_macroblock, s->macroblock_count);                    return 1;                }                /* mode 7 means get 3 bits for each coding mode */                if (scheme == 7)                    coding_mode = get_bits(gb, 3);                else                    coding_mode = ModeAlphabet[scheme][get_mode_code(gb)];                s->macroblock_coding[current_macroblock] = coding_mode;                for (k = 0; k < 6; k++) {                    current_fragment =                         s->macroblock_fragments[current_macroblock * 6 + k];                    if (current_fragment == -1)                        continue;                    if (current_fragment >= s->fragment_count) {                        av_log(s->avctx, AV_LOG_ERROR, "  vp3:unpack_modes(): bad fragment number (%d >= %d)\n",                            current_fragment, s->fragment_count);                        return 1;                    }                    if (s->all_fragments[current_fragment].coding_method !=                         MODE_COPY)                        s->all_fragments[current_fragment].coding_method =                            coding_mode;                }                debug_modes("    coding method for macroblock starting @ fragment %d = %d\n",                    s->macroblock_fragments[current_macroblock * 6], coding_mode);            }        }    }    return 0;}/* * This function unpacks all the motion vectors for the individual * macroblocks from the bitstream. */static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb){    int i, j, k;    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;    debug_vp3("  vp3: unpacking motion vectors\n");    if (s->keyframe) {        debug_vp3("    keyframe-- there are no motion vectors\n");    } else {        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_bits(gb, 1);        debug_vectors("    using %s scheme for unpacking motion vectors\n",            (coding_mode == 0) ? "VLC" : "fixed-length");        /* iterate through all of the macroblocks that contain 1 or more         * coded fragments */        for (i = 0; i < s->u_superblock_start; i++) {            for (j = 0; j < 4; j++) {                current_macroblock = s->superblock_macroblocks[i * 4 + j];                if ((current_macroblock == -1) ||                    (s->macroblock_coding[current_macroblock] == MODE_COPY))                    continue;                if (current_macroblock >= s->macroblock_count) {                    av_log(s->avctx, AV_LOG_ERROR, "  vp3:unpack_vectors(): bad macroblock number (%d >= %d)\n",                        current_macroblock, s->macroblock_count);                    return 1;                }                current_fragment = s->macroblock_fragments[current_macroblock * 6];                if (current_fragment >= s->fragment_count) {                    av_log(s->avctx, AV_LOG_ERROR, "  vp3:unpack_vectors(): bad fragment number (%d >= %d\n",                        current_fragment, s->fragment_count);                    return 1;                }                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] = get_motion_vector_vlc(gb);                        motion_y[0] = get_motion_vector_vlc(gb);                    } else {                        motion_x[0] = get_motion_vector_fixed(gb);                        motion_y[0] = get_motion_vector_fixed(gb);                    }                    for (k = 1; k < 6; k++) {                        motion_x[k] = motion_x[0];                        motion_y[k] = motion_y[0];                    }                    /* 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:                    /* 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++) {                        if (coding_mode == 0) {                            motion_x[k] = get_motion_vector_vlc(gb);                            motion_y[k] = get_motion_vector_vlc(gb);                        } else {                            motion_x[k] = get_motion_vector_fixed(gb);                            motion_y[k] = get_motion_vector_fixed(gb);                        }                        motion_x[4] += motion_x[k];                        motion_y[4] += motion_y[k];                    }                    if (motion_x[4] >= 0)                         motion_x[4] = (motion_x[4] + 2) / 4;                    else                        motion_x[4] = (motion_x[4] - 2) / 4;                    motion_x[5] = motion_x[4];                    if (motion_y[4] >= 0)                         motion_y[4] = (motion_y[4] + 2) / 4;                    else                        motion_y[4] = (motion_y[4] - 2) / 4;                    motion_y[5] = motion_y[4];                    /* vector maintenance; vector[3] is treated as the                     * last vector in this case */                    prior_last_motion_x = last_motion_x;                    prior_last_motion_y = last_motion_y;                    last_motion_x = motion_x[3];                    last_motion_y = motion_y[3];                    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;                    for (k = 1; k < 6; k++) {                        motion_x[k] = motion_x[0];                        motion_y[k] = motion_y[0];                    }                    /* 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;                    for (k = 1; k < 6; k++) {                        motion_x[k] = motion_x[0];                        motion_y[k] = motion_y[0];                    }                    /* 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 */                    memset(motion_x, 0, 6 * sizeof(int));                    memset(motion_y, 0, 6 * sizeof(int));                    /* no vector maintenance */                    break;                }                /* assign the motion vectors to the correct fragments */                debug_vectors("    vectors for macroblock starting @ fragment %d (coding method %d):\n",                    current_fragment,                    s->macroblock_coding[current_macroblock]);                for (k = 0; k < 6; k++) {                    current_fragment =                         s->macroblock_fragments[current_macroblock * 6 + k];                    if (current_fragment == -1)                        continue;                    if (current_fragment >= s->fragment_count) {                        av_log(s->avctx, AV_LOG_ERROR, "  vp3:unpack_vectors(): bad fragment number (%d >= %d)\n",                            current_fragment, s->fragment_count);                        return 1;                    }                    s->all_fragments[current_fragment].motion_x = motion_x[k];                    s->all_fragments[current_fragment].motion_y = motion_y[k];                    debug_vectors("    vector %d: fragment %d = (%d, %d)\n",                        k, current_fragment, motion_x[k], motion_y[k]);                }            }        }    }    return 0;}/*  * This function is called by unpack_dct_coeffs() to extract the VLCs from * the bitstream. The VLCs encode tokens which are used to unpack DCT * data. This function unpacks all the VLCs for either the Y plane or both * C planes, and is called for DC coefficients or different AC coefficient * levels (since different coefficient types require different VLC tables. * * This function returns a residual eob run. E.g, if a particular token gave * instructions to EOB the next 5 fragments and there were only 2 fragments * left in the current fragment range, 3 would be returned so that it could * be passed into the next call to this same function. */static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,                        VLC *table, int coeff_index,                        int first_fragment, int last_fragment,                        int eob_run){    int i;    int token;    int zero_run;    DCTELEM coeff;    Vp3Fragment *fragment;    if ((first_fragment >= s->fragment_count) ||        (last_fragment >= s->fragment_count)) {        av_log(s->avctx, AV_LOG_ERROR, "  vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n",            first_fragment, last_fragment);        return 0;    }    for (i = first_fragment; i <= last_fragment; i++) {        fragment = &s->all_fragments[s->coded_fragment_list[i]];        if (fragment->coeff_count > coeff_index)            continue;        if (!eob_run) {            /* decode a VLC into a token */            token = get_vlc2(gb, table->table, 5, 3);            debug_vlc(" token = %2d, ", token);            /* use the token to get a zero run, a coefficient, and an eob run */            unpack_token(gb, token, &zero_run, &coeff, &eob_run);        }        if (!eob_run) {            fragment->coeff_count += zero_run;            if (fragment->coeff_count < 64)                fragment->coeffs[fragment->coeff_count++] = coeff;            debug_vlc(" fragment %d coeff = %d\n",                s->coded_fragment_list[i], fragment->coeffs[coeff_index]);        } else {            fragment->last_coeff = fragment->coeff_count;            fragment->coeff_count = 64;            debug_vlc(" fragment %d eob with %d coefficients\n",                 s->coded_fragment_list[i], fragment->last_coeff);            eob_run--;        }    }    return eob_run;}/* * This function unpacks all of the DCT coefficient data from the * bitstream. */static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb){    int i;    int dc_y_table;    int dc_c_table;    int ac_y_table;    int ac_c_table;    int residual_eob_run = 0;    /* fetch the DC table indices */    dc_y_table = get_bits(gb, 4);    dc_c_table = get_bits(gb, 4);    /* unpack the Y plane DC coefficients */    debug_vp3("  vp3: unpacking Y plane DC coefficients using table %d\n",        dc_y_table);    residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0,         s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run);    /* unpack the C plane DC coefficients */    debug_vp3("  vp3: unpacking C plane DC coefficients using table %d\n",        dc_c_table);    residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0,        s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run);    /* fetch the AC table indices */    ac_y_table = get_bits(gb, 4);    ac_c_table = get_bits(gb, 4);    /* unpack the group 1 AC coefficients (coeffs 1-5) */    for (i = 1; i <= 5; i++) {        debug_vp3("  vp3: unpacking level %d Y plane AC coefficients using table %d\n",            i, ac_y_table);        residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_y_table], i,             s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run);        debug_vp3("  vp3: unpacking level %d C plane AC coefficients using table %d\n",            i, ac_c_table);        residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_c_table], i,             s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run);    }    /* unpack the group 2 AC coefficients (coeffs 6-14) */    for (i = 6; i <= 14; i++) {        debug_vp3("  vp3: unpacking level %d Y plane AC coefficients using table %d\n",            i, ac_y_table);        residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_y_table], i,             s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run);        debug_vp3("  vp3: unpacking level %d C plane AC coefficients using table %d\n",            i, ac_c_table);        residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_c_table], i,             s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run);    }    /* unpack the group 3 AC coefficients (coeffs 15-27) */    for (i = 15; i <= 27; i++) {        debug_vp3("  vp3: unpacking level %d Y plane AC coefficients using table %d\n",            i, ac_y_table);        residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_3[ac_y_table], i,             s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -