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

📄 vp3.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* This table shows which types of blocks can use other blocks for     * prediction. For example, INTRA is the only mode in this table to     * have a frame number of 0. That means INTRA blocks can only predict     * from other INTRA blocks. There are 2 golden frame coding types;     * blocks encoding in these modes can only predict from other blocks     * that were encoded with these 1 of these 2 modes. */    unsigned char compatible_frame[8] = {        1,    /* MODE_INTER_NO_MV */        0,    /* MODE_INTRA */        1,    /* MODE_INTER_PLUS_MV */        1,    /* MODE_INTER_LAST_MV */        1,    /* MODE_INTER_PRIOR_MV */        2,    /* MODE_USING_GOLDEN */        2,    /* MODE_GOLDEN_MV */        1     /* MODE_INTER_FOUR_MV */    };    int current_frame_type;    /* there is a last DC predictor for each of the 3 frame types */    short last_dc[3];    int transform = 0;    debug_vp3("  vp3: reversing DC prediction\n");    vul = vu = vur = vl = 0;    last_dc[0] = last_dc[1] = last_dc[2] = 0;    /* for each fragment row... */    for (y = 0; y < fragment_height; y++) {        /* for each fragment in a row... */        for (x = 0; x < fragment_width; x++, i++) {            /* reverse prediction if this block was coded */            if (s->all_fragments[i].coding_method != MODE_COPY) {                current_frame_type =                    compatible_frame[s->all_fragments[i].coding_method];                debug_dc_pred(" frag %d: orig DC = %d, ",                    i, DC_COEFF(i));                transform= 0;                if(x){                    l= i-1;                    vl = DC_COEFF(l);                    if(FRAME_CODED(l) && COMPATIBLE_FRAME(l))                        transform |= PL;                }                if(y){                    u= i-fragment_width;                    vu = DC_COEFF(u);                    if(FRAME_CODED(u) && COMPATIBLE_FRAME(u))                        transform |= PU;                    if(x){                        ul= i-fragment_width-1;                        vul = DC_COEFF(ul);                        if(FRAME_CODED(ul) && COMPATIBLE_FRAME(ul))                            transform |= PUL;                    }                    if(x + 1 < fragment_width){                        ur= i-fragment_width+1;                        vur = DC_COEFF(ur);                        if(FRAME_CODED(ur) && COMPATIBLE_FRAME(ur))                            transform |= PUR;                    }                }                debug_dc_pred("transform = %d, ", transform);                if (transform == 0) {                    /* if there were no fragments to predict from, use last                     * DC saved */                    predicted_dc = last_dc[current_frame_type];                    debug_dc_pred("from last DC (%d) = %d\n",                        current_frame_type, DC_COEFF(i));                } else {                    /* apply the appropriate predictor transform */                    predicted_dc =                        (predictor_transform[transform][0] * vul) +                        (predictor_transform[transform][1] * vu) +                        (predictor_transform[transform][2] * vur) +                        (predictor_transform[transform][3] * vl);                    predicted_dc /= 128;                    /* check for outranging on the [ul u l] and                     * [ul u ur l] predictors */                    if ((transform == 13) || (transform == 15)) {                        if (FFABS(predicted_dc - vu) > 128)                            predicted_dc = vu;                        else if (FFABS(predicted_dc - vl) > 128)                            predicted_dc = vl;                        else if (FFABS(predicted_dc - vul) > 128)                            predicted_dc = vul;                    }                    debug_dc_pred("from pred DC = %d\n",                    DC_COEFF(i));                }                /* at long last, apply the predictor */                if(s->coeffs[i].index){                    *s->next_coeff= s->coeffs[i];                    s->coeffs[i].index=0;                    s->coeffs[i].coeff=0;                    s->coeffs[i].next= s->next_coeff++;                }                s->coeffs[i].coeff += predicted_dc;                /* save the DC */                last_dc[current_frame_type] = DC_COEFF(i);                if(DC_COEFF(i) && !(s->coeff_counts[i]&127)){                    s->coeff_counts[i]= 129;//                    s->all_fragments[i].next_coeff= s->next_coeff;                    s->coeffs[i].next= s->next_coeff;                    (s->next_coeff++)->next=NULL;                }            }        }    }}static void horizontal_filter(unsigned char *first_pixel, int stride,    int *bounding_values);static void vertical_filter(unsigned char *first_pixel, int stride,    int *bounding_values);/* * Perform the final rendering for a particular slice of data. * The slice number ranges from 0..(macroblock_height - 1). */static void render_slice(Vp3DecodeContext *s, int slice){    int x;    int m, n;    int16_t *dequantizer;    DECLARE_ALIGNED_16(DCTELEM, block[64]);    int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;    int motion_halfpel_index;    uint8_t *motion_source;    int plane;    int current_macroblock_entry = slice * s->macroblock_width * 6;    if (slice >= s->macroblock_height)        return;    for (plane = 0; plane < 3; plane++) {        uint8_t *output_plane = s->current_frame.data    [plane];        uint8_t *  last_plane = s->   last_frame.data    [plane];        uint8_t *golden_plane = s-> golden_frame.data    [plane];        int stride            = s->current_frame.linesize[plane];        int plane_width       = s->width  >> !!plane;        int plane_height      = s->height >> !!plane;        int y =        slice *  FRAGMENT_PIXELS << !plane ;        int slice_height = y + (FRAGMENT_PIXELS << !plane);        int i = s->macroblock_fragments[current_macroblock_entry + plane + 3*!!plane];        if (!s->flipped_image) stride = -stride;        if(FFABS(stride) > 2048)            return; //various tables are fixed size        /* for each fragment row in the slice (both of them)... */        for (; y < slice_height; y += 8) {            /* for each fragment in a row... */            for (x = 0; x < plane_width; x += 8, i++) {                if ((i < 0) || (i >= s->fragment_count)) {                    av_log(s->avctx, AV_LOG_ERROR, "  vp3:render_slice(): bad fragment number (%d)\n", i);                    return;                }                /* transform if this block was coded */                if ((s->all_fragments[i].coding_method != MODE_COPY) &&                    !((s->avctx->flags & CODEC_FLAG_GRAY) && plane)) {                    if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) ||                        (s->all_fragments[i].coding_method == MODE_GOLDEN_MV))                        motion_source= golden_plane;                    else                        motion_source= last_plane;                    motion_source += s->all_fragments[i].first_pixel;                    motion_halfpel_index = 0;                    /* sort out the motion vector if this fragment is coded                     * using a motion vector method */                    if ((s->all_fragments[i].coding_method > MODE_INTRA) &&                        (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) {                        int src_x, src_y;                        motion_x = s->all_fragments[i].motion_x;                        motion_y = s->all_fragments[i].motion_y;                        if(plane){                            motion_x= (motion_x>>1) | (motion_x&1);                            motion_y= (motion_y>>1) | (motion_y&1);                        }                        src_x= (motion_x>>1) + x;                        src_y= (motion_y>>1) + y;                        if ((motion_x == 127) || (motion_y == 127))                            av_log(s->avctx, AV_LOG_ERROR, " help! got invalid motion vector! (%X, %X)\n", motion_x, motion_y);                        motion_halfpel_index = motion_x & 0x01;                        motion_source += (motion_x >> 1);                        motion_halfpel_index |= (motion_y & 0x01) << 1;                        motion_source += ((motion_y >> 1) * stride);                        if(src_x<0 || src_y<0 || src_x + 9 >= plane_width || src_y + 9 >= plane_height){                            uint8_t *temp= s->edge_emu_buffer;                            if(stride<0) temp -= 9*stride;                            else temp += 9*stride;                            ff_emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height);                            motion_source= temp;                        }                    }                    /* first, take care of copying a block from either the                     * previous or the golden frame */                    if (s->all_fragments[i].coding_method != MODE_INTRA) {                        /* Note, it is possible to implement all MC cases with                           put_no_rnd_pixels_l2 which would look more like the                           VP3 source but this would be slower as                           put_no_rnd_pixels_tab is better optimzed */                        if(motion_halfpel_index != 3){                            s->dsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](                                output_plane + s->all_fragments[i].first_pixel,                                motion_source, stride, 8);                        }else{                            int d= (motion_x ^ motion_y)>>31; // d is 0 if motion_x and _y have the same sign, else -1                            s->dsp.put_no_rnd_pixels_l2[1](                                output_plane + s->all_fragments[i].first_pixel,                                motion_source - d,                                motion_source + stride + 1 + d,                                stride, 8);                        }                        dequantizer = s->qmat[1][plane];                    }else{                        dequantizer = s->qmat[0][plane];                    }                    /* dequantize the DCT coefficients */                    debug_idct("fragment %d, coding mode %d, DC = %d, dequant = %d:\n",                        i, s->all_fragments[i].coding_method,                        DC_COEFF(i), dequantizer[0]);                    if(s->avctx->idct_algo==FF_IDCT_VP3){                        Coeff *coeff= s->coeffs + i;                        memset(block, 0, sizeof(block));                        while(coeff->next){                            block[coeff->index]= coeff->coeff * dequantizer[coeff->index];                            coeff= coeff->next;                        }                    }else{                        Coeff *coeff= s->coeffs + i;                        memset(block, 0, sizeof(block));                        while(coeff->next){                            block[coeff->index]= (coeff->coeff * dequantizer[coeff->index] + 2)>>2;                            coeff= coeff->next;                        }                    }                    /* invert DCT and place (or add) in final output */                    if (s->all_fragments[i].coding_method == MODE_INTRA) {                        if(s->avctx->idct_algo!=FF_IDCT_VP3)                            block[0] += 128<<3;                        s->dsp.idct_put(                            output_plane + s->all_fragments[i].first_pixel,                            stride,                            block);                    } else {                        s->dsp.idct_add(                            output_plane + s->all_fragments[i].first_pixel,                            stride,                            block);                    }                    debug_idct("block after idct_%s():\n",                        (s->all_fragments[i].coding_method == MODE_INTRA)?                        "put" : "add");                    for (m = 0; m < 8; m++) {                        for (n = 0; n < 8; n++) {                            debug_idct(" %3d", *(output_plane +                                s->all_fragments[i].first_pixel + (m * stride + n)));                        }                        debug_idct("\n");                    }                    debug_idct("\n");                } else {                    /* copy directly from the previous frame */                    s->dsp.put_pixels_tab[1][0](                        output_plane + s->all_fragments[i].first_pixel,                        last_plane + s->all_fragments[i].first_pixel,                        stride, 8);                }#if 0                /* perform the left edge filter if:                 *   - the fragment is not on the left column                 *   - the fragment is coded in this frame                 *   - the fragment is not coded in this frame but the left                 *     fragment is coded in this frame (this is done instead                 *     of a right edge filter when rendering the left fragment                 *     since this fragment is not available yet) */                if ((x > 0) &&                    ((s->all_fragments[i].coding_method != MODE_COPY) ||                     ((s->all_fragments[i].coding_method == MODE_COPY) &&                      (s->all_fragments[i - 1].coding_method != MODE_COPY)) )) {                    horizontal_filter(                        output_plane + s->all_fragments[i].first_pixel + 7*stride,                        -stride, s->bounding_values_array + 127);                }                /* perform the top edge filter if:                 *   - the fragment is not on the top row                 *   - the fragment is coded in this frame                 *   - the fragment is not coded in this frame but the above                 *     fragment is coded in this frame (this is done instead                 *     of a bottom edge filter when rendering the above                 *     fragment since this fragment is not available yet) */                if ((y > 0) &&                    ((s->all_fragments[i].coding_method != MODE_COPY) ||                     ((s->all_fragments[i].coding_method == MODE_COPY) &&                      (s->all_fragments[i - fragment_width].coding_method != MODE_COPY)) )) {                    vertical_filter(                        output_plane + s->all_fragments[i].first_pixel - stride,                        -stride, s->bounding_values_array + 127);                }#end

⌨️ 快捷键说明

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