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

📄 vp56.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * @file vp56.c * VP5 and VP6 compatible video decoder (common features) * * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org> * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "avcodec.h"#include "bytestream.h"#include "vp56.h"#include "vp56data.h"void vp56_init_dequant(vp56_context_t *s, int quantizer){    s->quantizer = quantizer;    s->dequant_dc = vp56_dc_dequant[quantizer] << 2;    s->dequant_ac = vp56_ac_dequant[quantizer] << 2;}static int vp56_get_vectors_predictors(vp56_context_t *s, int row, int col,                                       vp56_frame_t ref_frame){    int nb_pred = 0;    vp56_mv_t vect[2] = {{0,0}, {0,0}};    int pos, offset;    vp56_mv_t mvp;    for (pos=0; pos<12; pos++) {        mvp.x = col + vp56_candidate_predictor_pos[pos][0];        mvp.y = row + vp56_candidate_predictor_pos[pos][1];        if (mvp.x < 0 || mvp.x >= s->mb_width ||            mvp.y < 0 || mvp.y >= s->mb_height)            continue;        offset = mvp.x + s->mb_width*mvp.y;        if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)            continue;        if ((s->macroblocks[offset].mv.x == vect[0].x &&             s->macroblocks[offset].mv.y == vect[0].y) ||            (s->macroblocks[offset].mv.x == 0 &&             s->macroblocks[offset].mv.y == 0))            continue;        vect[nb_pred++] = s->macroblocks[offset].mv;        if (nb_pred > 1) {            nb_pred = -1;            break;        }        s->vector_candidate_pos = pos;    }    s->vector_candidate[0] = vect[0];    s->vector_candidate[1] = vect[1];    return nb_pred+1;}static void vp56_parse_mb_type_models(vp56_context_t *s){    vp56_range_coder_t *c = &s->c;    vp56_model_t *model = s->modelp;    int i, ctx, type;    for (ctx=0; ctx<3; ctx++) {        if (vp56_rac_get_prob(c, 174)) {            int idx = vp56_rac_gets(c, 4);            memcpy(model->mb_types_stats[ctx],                   vp56_pre_def_mb_type_stats[idx][ctx],                   sizeof(model->mb_types_stats[ctx]));        }        if (vp56_rac_get_prob(c, 254)) {            for (type=0; type<10; type++) {                for(i=0; i<2; i++) {                    if (vp56_rac_get_prob(c, 205)) {                        int delta, sign = vp56_rac_get(c);                        delta = vp56_rac_get_tree(c, vp56_pmbtm_tree,                                                  vp56_mb_type_model_model);                        if (!delta)                            delta = 4 * vp56_rac_gets(c, 7);                        model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign;                    }                }            }        }    }    /* compute MB type probability tables based on previous MB type */    for (ctx=0; ctx<3; ctx++) {        int p[10];        for (type=0; type<10; type++)            p[type] = 100 * model->mb_types_stats[ctx][type][1];        for (type=0; type<10; type++) {            int p02, p34, p0234, p17, p56, p89, p5689, p156789;            /* conservative MB type probability */            model->mb_type[ctx][type][0] = 255 - (255 * model->mb_types_stats[ctx][type][0]) / (1 + model->mb_types_stats[ctx][type][0] + model->mb_types_stats[ctx][type][1]);            p[type] = 0;    /* same MB type => weight is null */            /* binary tree parsing probabilities */            p02 = p[0] + p[2];            p34 = p[3] + p[4];            p0234 = p02 + p34;            p17 = p[1] + p[7];            p56 = p[5] + p[6];            p89 = p[8] + p[9];            p5689 = p56 + p89;            p156789 = p17 + p5689;            model->mb_type[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789);            model->mb_type[ctx][type][2] = 1 + 255 * p02  / (1+p0234);            model->mb_type[ctx][type][3] = 1 + 255 * p17  / (1+p156789);            model->mb_type[ctx][type][4] = 1 + 255 * p[0] / (1+p02);            model->mb_type[ctx][type][5] = 1 + 255 * p[3] / (1+p34);            model->mb_type[ctx][type][6] = 1 + 255 * p[1] / (1+p17);            model->mb_type[ctx][type][7] = 1 + 255 * p56  / (1+p5689);            model->mb_type[ctx][type][8] = 1 + 255 * p[5] / (1+p56);            model->mb_type[ctx][type][9] = 1 + 255 * p[8] / (1+p89);            /* restore initial value */            p[type] = 100 * model->mb_types_stats[ctx][type][1];        }    }}static vp56_mb_t vp56_parse_mb_type(vp56_context_t *s,                                    vp56_mb_t prev_type, int ctx){    uint8_t *mb_type_model = s->modelp->mb_type[ctx][prev_type];    vp56_range_coder_t *c = &s->c;    if (vp56_rac_get_prob(c, mb_type_model[0]))        return prev_type;    else        return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model);}static void vp56_decode_4mv(vp56_context_t *s, int row, int col){    vp56_mv_t mv = {0,0};    int type[4];    int b;    /* parse each block type */    for (b=0; b<4; b++) {        type[b] = vp56_rac_gets(&s->c, 2);        if (type[b])            type[b]++;  /* only returns 0, 2, 3 or 4 (all INTER_PF) */    }    /* get vectors */    for (b=0; b<4; b++) {        switch (type[b]) {            case VP56_MB_INTER_NOVEC_PF:                s->mv[b] = (vp56_mv_t) {0,0};                break;            case VP56_MB_INTER_DELTA_PF:                s->parse_vector_adjustment(s, &s->mv[b]);                break;            case VP56_MB_INTER_V1_PF:                s->mv[b] = s->vector_candidate[0];                break;            case VP56_MB_INTER_V2_PF:                s->mv[b] = s->vector_candidate[1];                break;        }        mv.x += s->mv[b].x;        mv.y += s->mv[b].y;    }    /* this is the one selected for the whole MB for prediction */    s->macroblocks[row * s->mb_width + col].mv = s->mv[3];    /* chroma vectors are average luma vectors */    if (s->avctx->codec->id == CODEC_ID_VP5) {        s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2);        s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2);    } else {        s->mv[4] = s->mv[5] = (vp56_mv_t) {mv.x/4, mv.y/4};    }}static vp56_mb_t vp56_decode_mv(vp56_context_t *s, int row, int col){    vp56_mv_t *mv, vect = {0,0};    int ctx, b;    ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS);    s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx);    s->macroblocks[row * s->mb_width + col].type = s->mb_type;    switch (s->mb_type) {        case VP56_MB_INTER_V1_PF:            mv = &s->vector_candidate[0];            break;        case VP56_MB_INTER_V2_PF:            mv = &s->vector_candidate[1];            break;        case VP56_MB_INTER_V1_GF:            vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);            mv = &s->vector_candidate[0];            break;        case VP56_MB_INTER_V2_GF:            vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);            mv = &s->vector_candidate[1];            break;        case VP56_MB_INTER_DELTA_PF:            s->parse_vector_adjustment(s, &vect);            mv = &vect;            break;        case VP56_MB_INTER_DELTA_GF:            vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);            s->parse_vector_adjustment(s, &vect);            mv = &vect;            break;        case VP56_MB_INTER_4V:            vp56_decode_4mv(s, row, col);            return s->mb_type;        default:            mv = &vect;            break;    }    s->macroblocks[row*s->mb_width + col].mv = *mv;    /* same vector for all blocks */    for (b=0; b<6; b++)        s->mv[b] = *mv;    return s->mb_type;}static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame){    int idx = s->scantable.permutated[0];    int b;    for (b=0; b<6; b++) {        vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[b]];        vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[b]];        int count = 0;        int dc = 0;        int i;        if (ref_frame == lb->ref_frame) {            dc += lb->dc_coeff;            count++;        }        if (ref_frame == ab->ref_frame) {            dc += ab->dc_coeff;            count++;        }        if (s->avctx->codec->id == CODEC_ID_VP5)            for (i=0; i<2; i++)                if (count < 2 && ref_frame == ab[-1+2*i].ref_frame) {                    dc += ab[-1+2*i].dc_coeff;                    count++;                }        if (count == 0)            dc = s->prev_dc[vp56_b2p[b]][ref_frame];        else if (count == 2)            dc /= 2;        s->block_coeff[b][idx] += dc;        s->prev_dc[vp56_b2p[b]][ref_frame] = s->block_coeff[b][idx];        ab->dc_coeff = s->block_coeff[b][idx];        ab->ref_frame = ref_frame;        lb->dc_coeff = s->block_coeff[b][idx];        lb->ref_frame = ref_frame;        s->block_coeff[b][idx] *= s->dequant_dc;    }}static void vp56_edge_filter(vp56_context_t *s, uint8_t *yuv,                             int pix_inc, int line_inc, int t){    int pix2_inc = 2 * pix_inc;    int i, v;    for (i=0; i<12; i++) {        v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4) >>3;        v = s->adjust(v, t);        yuv[-pix_inc] = av_clip_uint8(yuv[-pix_inc] + v);        yuv[0] = av_clip_uint8(yuv[0] - v);        yuv += line_inc;    }}static void vp56_deblock_filter(vp56_context_t *s, uint8_t *yuv,                                int stride, int dx, int dy){    int t = vp56_filter_threshold[s->quantizer];    if (dx)  vp56_edge_filter(s, yuv +         10-dx ,      1, stride, t);    if (dy)  vp56_edge_filter(s, yuv + stride*(10-dy), stride,      1, t);}static void vp56_mc(vp56_context_t *s, int b, int plane, uint8_t *src,                    int stride, int x, int y){    uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b];    uint8_t *src_block;    int src_offset;    int overlap_offset = 0;    int mask = s->vp56_coord_div[b] - 1;    int deblock_filtering = s->deblock_filtering;    int dx;    int dy;    if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||        (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY         && !s->framep[VP56_FRAME_CURRENT]->key_frame))        deblock_filtering = 0;    dx = s->mv[b].x / s->vp56_coord_div[b];    dy = s->mv[b].y / s->vp56_coord_div[b];    if (b >= 4) {        x /= 2;        y /= 2;    }    x += dx - 2;    y += dy - 2;

⌨️ 快捷键说明

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