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

📄 vp6.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/** * @file vp6.c * VP6 compatible video decoder * * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org> * * The VP6F decoder accepts an optional 1 byte extradata. It is composed of: *  - upper 4bits: difference between encoded width and visible width *  - lower 4bits: difference between encoded height and visible height * * 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 <stdlib.h>#include "avcodec.h"#include "dsputil.h"#include "bitstream.h"#include "huffman.h"#include "mpegvideo.h"#include "vp56.h"#include "vp56data.h"#include "vp6data.h"static void vp6_parse_coeff(vp56_context_t *s);static void vp6_parse_coeff_huffman(vp56_context_t *s);static int vp6_parse_header(vp56_context_t *s, const uint8_t *buf, int buf_size,                            int *golden_frame){    vp56_range_coder_t *c = &s->c;    int parse_filter_info = 0;    int coeff_offset = 0;    int vrt_shift = 0;    int sub_version;    int rows, cols;    int res = 1;    int separated_coeff = buf[0] & 1;    s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);    vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);    if (s->framep[VP56_FRAME_CURRENT]->key_frame) {        sub_version = buf[1] >> 3;        if (sub_version > 8)            return 0;        s->filter_header = buf[1] & 0x06;        if (buf[1] & 1) {            av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");            return 0;        }        if (separated_coeff || !s->filter_header) {            coeff_offset = AV_RB16(buf+2) - 2;            buf += 2;            buf_size -= 2;        }        rows = buf[2];  /* number of stored macroblock rows */        cols = buf[3];  /* number of stored macroblock cols */        /* buf[4] is number of displayed macroblock rows */        /* buf[5] is number of displayed macroblock cols */        if (16*cols != s->avctx->coded_width ||            16*rows != s->avctx->coded_height) {            avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);            if (s->avctx->extradata_size == 1) {                s->avctx->width  -= s->avctx->extradata[0] >> 4;                s->avctx->height -= s->avctx->extradata[0] & 0x0F;            }            res = 2;        }        vp56_init_range_decoder(c, buf+6, buf_size-6);        vp56_rac_gets(c, 2);        parse_filter_info = s->filter_header;        if (sub_version < 8)            vrt_shift = 5;        s->sub_version = sub_version;    } else {        if (!s->sub_version)            return 0;        if (separated_coeff || !s->filter_header) {            coeff_offset = AV_RB16(buf+1) - 2;            buf += 2;            buf_size -= 2;        }        vp56_init_range_decoder(c, buf+1, buf_size-1);        *golden_frame = vp56_rac_get(c);        if (s->filter_header) {            s->deblock_filtering = vp56_rac_get(c);            if (s->deblock_filtering)                vp56_rac_get(c);            if (s->sub_version > 7)                parse_filter_info = vp56_rac_get(c);        }    }    if (parse_filter_info) {        if (vp56_rac_get(c)) {            s->filter_mode = 2;            s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift;            s->max_vector_length = 2 << vp56_rac_gets(c, 3);        } else if (vp56_rac_get(c)) {            s->filter_mode = 1;        } else {            s->filter_mode = 0;        }        if (s->sub_version > 7)            s->filter_selection = vp56_rac_gets(c, 4);        else            s->filter_selection = 16;    }    s->use_huffman = vp56_rac_get(c);    s->parse_coeff = vp6_parse_coeff;    if (coeff_offset) {        buf      += coeff_offset;        buf_size -= coeff_offset;        if (s->use_huffman) {            s->parse_coeff = vp6_parse_coeff_huffman;            init_get_bits(&s->gb, buf, buf_size<<3);        } else {            vp56_init_range_decoder(&s->cc, buf, buf_size);            s->ccp = &s->cc;        }    } else {        s->ccp = &s->c;    }    return res;}static void vp6_coeff_order_table_init(vp56_context_t *s){    int i, pos, idx = 1;    s->modelp->coeff_index_to_pos[0] = 0;    for (i=0; i<16; i++)        for (pos=1; pos<64; pos++)            if (s->modelp->coeff_reorder[pos] == i)                s->modelp->coeff_index_to_pos[idx++] = pos;}static void vp6_default_models_init(vp56_context_t *s){    vp56_model_t *model = s->modelp;    model->vector_dct[0] = 0xA2;    model->vector_dct[1] = 0xA4;    model->vector_sig[0] = 0x80;    model->vector_sig[1] = 0x80;    memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats));    memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv));    memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv));    memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv));    memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder));    vp6_coeff_order_table_init(s);}static void vp6_parse_vector_models(vp56_context_t *s){    vp56_range_coder_t *c = &s->c;    vp56_model_t *model = s->modelp;    int comp, node;    for (comp=0; comp<2; comp++) {        if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0]))            model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);        if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1]))            model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);    }    for (comp=0; comp<2; comp++)        for (node=0; node<7; node++)            if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node]))                model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);    for (comp=0; comp<2; comp++)        for (node=0; node<8; node++)            if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node]))                model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7);}static int vp6_huff_cmp(const void *va, const void *vb){    const Node *a = va, *b = vb;    return a->count >= b->count;}static void vp6_build_huff_tree(vp56_context_t *s, uint8_t coeff_model[],                                const uint8_t *map, unsigned size, VLC *vlc){    Node nodes[2*size], *tmp = &nodes[size];    int a, b, i;    /* first compute probabilities from model */    tmp[0].count = 256;    for (i=0; i<size-1; i++) {        a = tmp[i].count *        coeff_model[i]  >> 8;        b = tmp[i].count * (255 - coeff_model[i]) >> 8;        nodes[map[2*i  ]].count = a + !a;        nodes[map[2*i+1]].count = b + !b;    }    /* then build the huffman tree accodring to probabilities */    ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, 1);}static void vp6_parse_coeff_models(vp56_context_t *s){    vp56_range_coder_t *c = &s->c;    vp56_model_t *model = s->modelp;    int def_prob[11];    int node, cg, ctx, pos;    int ct;    /* code type */    int pt;    /* plane type (0 for Y, 1 for U or V) */    memset(def_prob, 0x80, sizeof(def_prob));    for (pt=0; pt<2; pt++)        for (node=0; node<11; node++)            if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) {                def_prob[node] = vp56_rac_gets_nn(c, 7);                model->coeff_dccv[pt][node] = def_prob[node];            } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {                model->coeff_dccv[pt][node] = def_prob[node];            }    if (vp56_rac_get(c)) {        for (pos=1; pos<64; pos++)            if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos]))                model->coeff_reorder[pos] = vp56_rac_gets(c, 4);        vp6_coeff_order_table_init(s);    }    for (cg=0; cg<2; cg++)        for (node=0; node<14; node++)            if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node]))                model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7);    for (ct=0; ct<3; ct++)        for (pt=0; pt<2; pt++)            for (cg=0; cg<6; cg++)                for (node=0; node<11; node++)                    if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) {                        def_prob[node] = vp56_rac_gets_nn(c, 7);                        model->coeff_ract[pt][ct][cg][node] = def_prob[node];                    } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {                        model->coeff_ract[pt][ct][cg][node] = def_prob[node];                    }    if (s->use_huffman) {        for (pt=0; pt<2; pt++) {            vp6_build_huff_tree(s, model->coeff_dccv[pt],                                vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]);            vp6_build_huff_tree(s, model->coeff_runv[pt],                                vp6_huff_run_map, 9, &s->runv_vlc[pt]);            for (ct=0; ct<3; ct++)                for (cg = 0; cg < 6; cg++)                    vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg],                                        vp6_huff_coeff_map, 12,                                        &s->ract_vlc[pt][ct][cg]);        }        memset(s->nb_null, 0, sizeof(s->nb_null));    } else {    /* coeff_dcct is a linear combination of coeff_dccv */    for (pt=0; pt<2; pt++)        for (ctx=0; ctx<3; ctx++)            for (node=0; node<5; node++)                model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255);    }}static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect){    vp56_range_coder_t *c = &s->c;    vp56_model_t *model = s->modelp;    int comp;    *vect = (vp56_mv_t) {0,0};    if (s->vector_candidate_pos < 2)        *vect = s->vector_candidate[0];    for (comp=0; comp<2; comp++) {        int i, delta = 0;        if (vp56_rac_get_prob(c, model->vector_dct[comp])) {            static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4};            for (i=0; i<sizeof(prob_order); i++) {                int j = prob_order[i];                delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j;            }            if (delta & 0xF0)                delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3;            else                delta |= 8;        } else {            delta = vp56_rac_get_tree(c, vp56_pva_tree,                                      model->vector_pdv[comp]);        }        if (delta && vp56_rac_get_prob(c, model->vector_sig[comp]))            delta = -delta;        if (!comp)            vect->x += delta;        else            vect->y += delta;    }}/**

⌨️ 快捷键说明

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