xref: /third_party/ffmpeg/libavcodec/vp6.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci/**
22cabdff1aSopenharmony_ci * @file
23cabdff1aSopenharmony_ci * VP6 compatible video decoder
24cabdff1aSopenharmony_ci *
25cabdff1aSopenharmony_ci * The VP6F decoder accepts an optional 1 byte extradata. It is composed of:
26cabdff1aSopenharmony_ci *  - upper 4 bits: difference between encoded width and visible width
27cabdff1aSopenharmony_ci *  - lower 4 bits: difference between encoded height and visible height
28cabdff1aSopenharmony_ci */
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#include <stdlib.h>
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#include "avcodec.h"
33cabdff1aSopenharmony_ci#include "codec_internal.h"
34cabdff1aSopenharmony_ci#include "get_bits.h"
35cabdff1aSopenharmony_ci#include "huffman.h"
36cabdff1aSopenharmony_ci#include "internal.h"
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci#include "vp56.h"
39cabdff1aSopenharmony_ci#include "vp56data.h"
40cabdff1aSopenharmony_ci#include "vp6data.h"
41cabdff1aSopenharmony_ci
42cabdff1aSopenharmony_ci#define VP6_MAX_HUFF_SIZE 12
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_cistatic int vp6_parse_coeff(VP56Context *s);
45cabdff1aSopenharmony_cistatic int vp6_parse_coeff_huffman(VP56Context *s);
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_cistatic int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
48cabdff1aSopenharmony_ci{
49cabdff1aSopenharmony_ci    VP56RangeCoder *c = &s->c;
50cabdff1aSopenharmony_ci    int parse_filter_info = 0;
51cabdff1aSopenharmony_ci    int coeff_offset = 0;
52cabdff1aSopenharmony_ci    int vrt_shift = 0;
53cabdff1aSopenharmony_ci    int sub_version;
54cabdff1aSopenharmony_ci    int rows, cols;
55cabdff1aSopenharmony_ci    int res = 0;
56cabdff1aSopenharmony_ci    int ret;
57cabdff1aSopenharmony_ci    int separated_coeff = buf[0] & 1;
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_ci    s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
60cabdff1aSopenharmony_ci    ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci    if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
63cabdff1aSopenharmony_ci        sub_version = buf[1] >> 3;
64cabdff1aSopenharmony_ci        if (sub_version > 8)
65cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
66cabdff1aSopenharmony_ci        s->filter_header = buf[1] & 0x06;
67cabdff1aSopenharmony_ci        if (buf[1] & 1) {
68cabdff1aSopenharmony_ci            avpriv_report_missing_feature(s->avctx, "Interlacing");
69cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
70cabdff1aSopenharmony_ci        }
71cabdff1aSopenharmony_ci        if (separated_coeff || !s->filter_header) {
72cabdff1aSopenharmony_ci            coeff_offset = AV_RB16(buf+2) - 2;
73cabdff1aSopenharmony_ci            buf += 2;
74cabdff1aSopenharmony_ci            buf_size -= 2;
75cabdff1aSopenharmony_ci        }
76cabdff1aSopenharmony_ci
77cabdff1aSopenharmony_ci        rows = buf[2];  /* number of stored macroblock rows */
78cabdff1aSopenharmony_ci        cols = buf[3];  /* number of stored macroblock cols */
79cabdff1aSopenharmony_ci        /* buf[4] is number of displayed macroblock rows */
80cabdff1aSopenharmony_ci        /* buf[5] is number of displayed macroblock cols */
81cabdff1aSopenharmony_ci        if (!rows || !cols) {
82cabdff1aSopenharmony_ci            av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4);
83cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
84cabdff1aSopenharmony_ci        }
85cabdff1aSopenharmony_ci
86cabdff1aSopenharmony_ci        if (!s->macroblocks || /* first frame */
87cabdff1aSopenharmony_ci            16*cols != s->avctx->coded_width ||
88cabdff1aSopenharmony_ci            16*rows != s->avctx->coded_height) {
89cabdff1aSopenharmony_ci            if (s->avctx->extradata_size == 0 &&
90cabdff1aSopenharmony_ci                FFALIGN(s->avctx->width,  16) == 16 * cols &&
91cabdff1aSopenharmony_ci                FFALIGN(s->avctx->height, 16) == 16 * rows) {
92cabdff1aSopenharmony_ci                // We assume this is properly signalled container cropping,
93cabdff1aSopenharmony_ci                // in an F4V file. Just set the coded_width/height, don't
94cabdff1aSopenharmony_ci                // touch the cropped ones.
95cabdff1aSopenharmony_ci                s->avctx->coded_width  = 16 * cols;
96cabdff1aSopenharmony_ci                s->avctx->coded_height = 16 * rows;
97cabdff1aSopenharmony_ci            } else {
98cabdff1aSopenharmony_ci                ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
99cabdff1aSopenharmony_ci                if (ret < 0)
100cabdff1aSopenharmony_ci                    return ret;
101cabdff1aSopenharmony_ci
102cabdff1aSopenharmony_ci                if (s->avctx->extradata_size == 1) {
103cabdff1aSopenharmony_ci                    s->avctx->width  -= s->avctx->extradata[0] >> 4;
104cabdff1aSopenharmony_ci                    s->avctx->height -= s->avctx->extradata[0] & 0x0F;
105cabdff1aSopenharmony_ci                }
106cabdff1aSopenharmony_ci            }
107cabdff1aSopenharmony_ci            res = VP56_SIZE_CHANGE;
108cabdff1aSopenharmony_ci        }
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ci        ret = ff_vp56_init_range_decoder(c, buf+6, buf_size-6);
111cabdff1aSopenharmony_ci        if (ret < 0)
112cabdff1aSopenharmony_ci            goto fail;
113cabdff1aSopenharmony_ci        vp56_rac_gets(c, 2);
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_ci        parse_filter_info = s->filter_header;
116cabdff1aSopenharmony_ci        if (sub_version < 8)
117cabdff1aSopenharmony_ci            vrt_shift = 5;
118cabdff1aSopenharmony_ci        s->sub_version = sub_version;
119cabdff1aSopenharmony_ci        s->golden_frame = 0;
120cabdff1aSopenharmony_ci    } else {
121cabdff1aSopenharmony_ci        if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height)
122cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
123cabdff1aSopenharmony_ci
124cabdff1aSopenharmony_ci        if (separated_coeff || !s->filter_header) {
125cabdff1aSopenharmony_ci            coeff_offset = AV_RB16(buf+1) - 2;
126cabdff1aSopenharmony_ci            buf += 2;
127cabdff1aSopenharmony_ci            buf_size -= 2;
128cabdff1aSopenharmony_ci        }
129cabdff1aSopenharmony_ci        ret = ff_vp56_init_range_decoder(c, buf+1, buf_size-1);
130cabdff1aSopenharmony_ci        if (ret < 0)
131cabdff1aSopenharmony_ci            return ret;
132cabdff1aSopenharmony_ci
133cabdff1aSopenharmony_ci        s->golden_frame = vp56_rac_get(c);
134cabdff1aSopenharmony_ci        if (s->filter_header) {
135cabdff1aSopenharmony_ci            s->deblock_filtering = vp56_rac_get(c);
136cabdff1aSopenharmony_ci            if (s->deblock_filtering)
137cabdff1aSopenharmony_ci                vp56_rac_get(c);
138cabdff1aSopenharmony_ci            if (s->sub_version > 7)
139cabdff1aSopenharmony_ci                parse_filter_info = vp56_rac_get(c);
140cabdff1aSopenharmony_ci        }
141cabdff1aSopenharmony_ci    }
142cabdff1aSopenharmony_ci
143cabdff1aSopenharmony_ci    if (parse_filter_info) {
144cabdff1aSopenharmony_ci        if (vp56_rac_get(c)) {
145cabdff1aSopenharmony_ci            s->filter_mode = 2;
146cabdff1aSopenharmony_ci            s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift;
147cabdff1aSopenharmony_ci            s->max_vector_length = 2 << vp56_rac_gets(c, 3);
148cabdff1aSopenharmony_ci        } else if (vp56_rac_get(c)) {
149cabdff1aSopenharmony_ci            s->filter_mode = 1;
150cabdff1aSopenharmony_ci        } else {
151cabdff1aSopenharmony_ci            s->filter_mode = 0;
152cabdff1aSopenharmony_ci        }
153cabdff1aSopenharmony_ci        if (s->sub_version > 7)
154cabdff1aSopenharmony_ci            s->filter_selection = vp56_rac_gets(c, 4);
155cabdff1aSopenharmony_ci        else
156cabdff1aSopenharmony_ci            s->filter_selection = 16;
157cabdff1aSopenharmony_ci    }
158cabdff1aSopenharmony_ci
159cabdff1aSopenharmony_ci    s->use_huffman = vp56_rac_get(c);
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci    s->parse_coeff = vp6_parse_coeff;
162cabdff1aSopenharmony_ci    if (coeff_offset) {
163cabdff1aSopenharmony_ci        buf      += coeff_offset;
164cabdff1aSopenharmony_ci        buf_size -= coeff_offset;
165cabdff1aSopenharmony_ci        if (buf_size < 0) {
166cabdff1aSopenharmony_ci            ret = AVERROR_INVALIDDATA;
167cabdff1aSopenharmony_ci            goto fail;
168cabdff1aSopenharmony_ci        }
169cabdff1aSopenharmony_ci        if (s->use_huffman) {
170cabdff1aSopenharmony_ci            s->parse_coeff = vp6_parse_coeff_huffman;
171cabdff1aSopenharmony_ci            ret = init_get_bits8(&s->gb, buf, buf_size);
172cabdff1aSopenharmony_ci            if (ret < 0)
173cabdff1aSopenharmony_ci                return ret;
174cabdff1aSopenharmony_ci        } else {
175cabdff1aSopenharmony_ci            ret = ff_vp56_init_range_decoder(&s->cc, buf, buf_size);
176cabdff1aSopenharmony_ci            if (ret < 0)
177cabdff1aSopenharmony_ci                goto fail;
178cabdff1aSopenharmony_ci            s->ccp = &s->cc;
179cabdff1aSopenharmony_ci        }
180cabdff1aSopenharmony_ci    } else {
181cabdff1aSopenharmony_ci        s->ccp = &s->c;
182cabdff1aSopenharmony_ci    }
183cabdff1aSopenharmony_ci
184cabdff1aSopenharmony_ci    return res;
185cabdff1aSopenharmony_cifail:
186cabdff1aSopenharmony_ci    if (res == VP56_SIZE_CHANGE)
187cabdff1aSopenharmony_ci        ff_set_dimensions(s->avctx, 0, 0);
188cabdff1aSopenharmony_ci    return ret;
189cabdff1aSopenharmony_ci}
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_cistatic void vp6_coeff_order_table_init(VP56Context *s)
192cabdff1aSopenharmony_ci{
193cabdff1aSopenharmony_ci    int i, pos, idx = 1;
194cabdff1aSopenharmony_ci
195cabdff1aSopenharmony_ci    s->modelp->coeff_index_to_pos[0] = 0;
196cabdff1aSopenharmony_ci    for (i=0; i<16; i++)
197cabdff1aSopenharmony_ci        for (pos=1; pos<64; pos++)
198cabdff1aSopenharmony_ci            if (s->modelp->coeff_reorder[pos] == i)
199cabdff1aSopenharmony_ci                s->modelp->coeff_index_to_pos[idx++] = pos;
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    for (idx = 0; idx < 64; idx++) {
202cabdff1aSopenharmony_ci        int max = 0;
203cabdff1aSopenharmony_ci        for (i = 0; i <= idx; i++) {
204cabdff1aSopenharmony_ci            int v = s->modelp->coeff_index_to_pos[i];
205cabdff1aSopenharmony_ci            if (v > max)
206cabdff1aSopenharmony_ci                max = v;
207cabdff1aSopenharmony_ci        }
208cabdff1aSopenharmony_ci        if (s->sub_version > 6)
209cabdff1aSopenharmony_ci            max++;
210cabdff1aSopenharmony_ci        s->modelp->coeff_index_to_idct_selector[idx] = max;
211cabdff1aSopenharmony_ci    }
212cabdff1aSopenharmony_ci}
213cabdff1aSopenharmony_ci
214cabdff1aSopenharmony_cistatic void vp6_default_models_init(VP56Context *s)
215cabdff1aSopenharmony_ci{
216cabdff1aSopenharmony_ci    VP56Model *model = s->modelp;
217cabdff1aSopenharmony_ci
218cabdff1aSopenharmony_ci    model->vector_dct[0] = 0xA2;
219cabdff1aSopenharmony_ci    model->vector_dct[1] = 0xA4;
220cabdff1aSopenharmony_ci    model->vector_sig[0] = 0x80;
221cabdff1aSopenharmony_ci    model->vector_sig[1] = 0x80;
222cabdff1aSopenharmony_ci
223cabdff1aSopenharmony_ci    memcpy(model->mb_types_stats, ff_vp56_def_mb_types_stats, sizeof(model->mb_types_stats));
224cabdff1aSopenharmony_ci    memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv));
225cabdff1aSopenharmony_ci    memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv));
226cabdff1aSopenharmony_ci    memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv));
227cabdff1aSopenharmony_ci    memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder));
228cabdff1aSopenharmony_ci
229cabdff1aSopenharmony_ci    vp6_coeff_order_table_init(s);
230cabdff1aSopenharmony_ci}
231cabdff1aSopenharmony_ci
232cabdff1aSopenharmony_cistatic void vp6_parse_vector_models(VP56Context *s)
233cabdff1aSopenharmony_ci{
234cabdff1aSopenharmony_ci    VP56RangeCoder *c = &s->c;
235cabdff1aSopenharmony_ci    VP56Model *model = s->modelp;
236cabdff1aSopenharmony_ci    int comp, node;
237cabdff1aSopenharmony_ci
238cabdff1aSopenharmony_ci    for (comp=0; comp<2; comp++) {
239cabdff1aSopenharmony_ci        if (vp56_rac_get_prob_branchy(c, vp6_sig_dct_pct[comp][0]))
240cabdff1aSopenharmony_ci            model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);
241cabdff1aSopenharmony_ci        if (vp56_rac_get_prob_branchy(c, vp6_sig_dct_pct[comp][1]))
242cabdff1aSopenharmony_ci            model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);
243cabdff1aSopenharmony_ci    }
244cabdff1aSopenharmony_ci
245cabdff1aSopenharmony_ci    for (comp=0; comp<2; comp++)
246cabdff1aSopenharmony_ci        for (node=0; node<7; node++)
247cabdff1aSopenharmony_ci            if (vp56_rac_get_prob_branchy(c, vp6_pdv_pct[comp][node]))
248cabdff1aSopenharmony_ci                model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
249cabdff1aSopenharmony_ci
250cabdff1aSopenharmony_ci    for (comp=0; comp<2; comp++)
251cabdff1aSopenharmony_ci        for (node=0; node<8; node++)
252cabdff1aSopenharmony_ci            if (vp56_rac_get_prob_branchy(c, vp6_fdv_pct[comp][node]))
253cabdff1aSopenharmony_ci                model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7);
254cabdff1aSopenharmony_ci}
255cabdff1aSopenharmony_ci
256cabdff1aSopenharmony_ci/* nodes must ascend by count, but with descending symbol order */
257cabdff1aSopenharmony_cistatic int vp6_huff_cmp(const void *va, const void *vb)
258cabdff1aSopenharmony_ci{
259cabdff1aSopenharmony_ci    const Node *a = va, *b = vb;
260cabdff1aSopenharmony_ci    return (a->count - b->count)*16 + (b->sym - a->sym);
261cabdff1aSopenharmony_ci}
262cabdff1aSopenharmony_ci
263cabdff1aSopenharmony_cistatic int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
264cabdff1aSopenharmony_ci                               const uint8_t *map, unsigned size, VLC *vlc)
265cabdff1aSopenharmony_ci{
266cabdff1aSopenharmony_ci    Node nodes[2*VP6_MAX_HUFF_SIZE], *tmp = &nodes[size];
267cabdff1aSopenharmony_ci    int a, b, i;
268cabdff1aSopenharmony_ci
269cabdff1aSopenharmony_ci    /* first compute probabilities from model */
270cabdff1aSopenharmony_ci    tmp[0].count = 256;
271cabdff1aSopenharmony_ci    for (i=0; i<size-1; i++) {
272cabdff1aSopenharmony_ci        a = tmp[i].count *        coeff_model[i]  >> 8;
273cabdff1aSopenharmony_ci        b = tmp[i].count * (255 - coeff_model[i]) >> 8;
274cabdff1aSopenharmony_ci        nodes[map[2*i  ]].count = a + !a;
275cabdff1aSopenharmony_ci        nodes[map[2*i+1]].count = b + !b;
276cabdff1aSopenharmony_ci    }
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_ci    ff_free_vlc(vlc);
279cabdff1aSopenharmony_ci    /* then build the huffman tree according to probabilities */
280cabdff1aSopenharmony_ci    return ff_huff_build_tree(s->avctx, vlc, size, FF_HUFFMAN_BITS,
281cabdff1aSopenharmony_ci                              nodes, vp6_huff_cmp,
282cabdff1aSopenharmony_ci                              FF_HUFFMAN_FLAG_HNODE_FIRST);
283cabdff1aSopenharmony_ci}
284cabdff1aSopenharmony_ci
285cabdff1aSopenharmony_cistatic int vp6_parse_coeff_models(VP56Context *s)
286cabdff1aSopenharmony_ci{
287cabdff1aSopenharmony_ci    VP56RangeCoder *c = &s->c;
288cabdff1aSopenharmony_ci    VP56Model *model = s->modelp;
289cabdff1aSopenharmony_ci    int def_prob[11];
290cabdff1aSopenharmony_ci    int node, cg, ctx, pos;
291cabdff1aSopenharmony_ci    int ct;    /* code type */
292cabdff1aSopenharmony_ci    int pt;    /* plane type (0 for Y, 1 for U or V) */
293cabdff1aSopenharmony_ci
294cabdff1aSopenharmony_ci    memset(def_prob, 0x80, sizeof(def_prob));
295cabdff1aSopenharmony_ci
296cabdff1aSopenharmony_ci    for (pt=0; pt<2; pt++)
297cabdff1aSopenharmony_ci        for (node=0; node<11; node++)
298cabdff1aSopenharmony_ci            if (vp56_rac_get_prob_branchy(c, vp6_dccv_pct[pt][node])) {
299cabdff1aSopenharmony_ci                def_prob[node] = vp56_rac_gets_nn(c, 7);
300cabdff1aSopenharmony_ci                model->coeff_dccv[pt][node] = def_prob[node];
301cabdff1aSopenharmony_ci            } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
302cabdff1aSopenharmony_ci                model->coeff_dccv[pt][node] = def_prob[node];
303cabdff1aSopenharmony_ci            }
304cabdff1aSopenharmony_ci
305cabdff1aSopenharmony_ci    if (vp56_rac_get(c)) {
306cabdff1aSopenharmony_ci        for (pos=1; pos<64; pos++)
307cabdff1aSopenharmony_ci            if (vp56_rac_get_prob_branchy(c, vp6_coeff_reorder_pct[pos]))
308cabdff1aSopenharmony_ci                model->coeff_reorder[pos] = vp56_rac_gets(c, 4);
309cabdff1aSopenharmony_ci        vp6_coeff_order_table_init(s);
310cabdff1aSopenharmony_ci    }
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci    for (cg=0; cg<2; cg++)
313cabdff1aSopenharmony_ci        for (node=0; node<14; node++)
314cabdff1aSopenharmony_ci            if (vp56_rac_get_prob_branchy(c, vp6_runv_pct[cg][node]))
315cabdff1aSopenharmony_ci                model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7);
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_ci    for (ct=0; ct<3; ct++)
318cabdff1aSopenharmony_ci        for (pt=0; pt<2; pt++)
319cabdff1aSopenharmony_ci            for (cg=0; cg<6; cg++)
320cabdff1aSopenharmony_ci                for (node=0; node<11; node++)
321cabdff1aSopenharmony_ci                    if (vp56_rac_get_prob_branchy(c, vp6_ract_pct[ct][pt][cg][node])) {
322cabdff1aSopenharmony_ci                        def_prob[node] = vp56_rac_gets_nn(c, 7);
323cabdff1aSopenharmony_ci                        model->coeff_ract[pt][ct][cg][node] = def_prob[node];
324cabdff1aSopenharmony_ci                    } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
325cabdff1aSopenharmony_ci                        model->coeff_ract[pt][ct][cg][node] = def_prob[node];
326cabdff1aSopenharmony_ci                    }
327cabdff1aSopenharmony_ci
328cabdff1aSopenharmony_ci    if (s->use_huffman) {
329cabdff1aSopenharmony_ci        for (pt=0; pt<2; pt++) {
330cabdff1aSopenharmony_ci            if (vp6_build_huff_tree(s, model->coeff_dccv[pt],
331cabdff1aSopenharmony_ci                                    vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]))
332cabdff1aSopenharmony_ci                return -1;
333cabdff1aSopenharmony_ci            if (vp6_build_huff_tree(s, model->coeff_runv[pt],
334cabdff1aSopenharmony_ci                                    vp6_huff_run_map, 9, &s->runv_vlc[pt]))
335cabdff1aSopenharmony_ci                return -1;
336cabdff1aSopenharmony_ci            for (ct=0; ct<3; ct++)
337cabdff1aSopenharmony_ci                for (cg = 0; cg < 6; cg++)
338cabdff1aSopenharmony_ci                    if (vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg],
339cabdff1aSopenharmony_ci                                            vp6_huff_coeff_map, 12,
340cabdff1aSopenharmony_ci                                            &s->ract_vlc[pt][ct][cg]))
341cabdff1aSopenharmony_ci                        return -1;
342cabdff1aSopenharmony_ci        }
343cabdff1aSopenharmony_ci        memset(s->nb_null, 0, sizeof(s->nb_null));
344cabdff1aSopenharmony_ci    } else {
345cabdff1aSopenharmony_ci    /* coeff_dcct is a linear combination of coeff_dccv */
346cabdff1aSopenharmony_ci    for (pt=0; pt<2; pt++)
347cabdff1aSopenharmony_ci        for (ctx=0; ctx<3; ctx++)
348cabdff1aSopenharmony_ci            for (node=0; node<5; node++)
349cabdff1aSopenharmony_ci                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);
350cabdff1aSopenharmony_ci    }
351cabdff1aSopenharmony_ci    return 0;
352cabdff1aSopenharmony_ci}
353cabdff1aSopenharmony_ci
354cabdff1aSopenharmony_cistatic void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect)
355cabdff1aSopenharmony_ci{
356cabdff1aSopenharmony_ci    VP56RangeCoder *c = &s->c;
357cabdff1aSopenharmony_ci    VP56Model *model = s->modelp;
358cabdff1aSopenharmony_ci    int comp;
359cabdff1aSopenharmony_ci
360cabdff1aSopenharmony_ci    *vect = (VP56mv) {0,0};
361cabdff1aSopenharmony_ci    if (s->vector_candidate_pos < 2)
362cabdff1aSopenharmony_ci        *vect = s->vector_candidate[0];
363cabdff1aSopenharmony_ci
364cabdff1aSopenharmony_ci    for (comp=0; comp<2; comp++) {
365cabdff1aSopenharmony_ci        int i, delta = 0;
366cabdff1aSopenharmony_ci
367cabdff1aSopenharmony_ci        if (vp56_rac_get_prob_branchy(c, model->vector_dct[comp])) {
368cabdff1aSopenharmony_ci            static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4};
369cabdff1aSopenharmony_ci            for (i=0; i<sizeof(prob_order); i++) {
370cabdff1aSopenharmony_ci                int j = prob_order[i];
371cabdff1aSopenharmony_ci                delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j;
372cabdff1aSopenharmony_ci            }
373cabdff1aSopenharmony_ci            if (delta & 0xF0)
374cabdff1aSopenharmony_ci                delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3;
375cabdff1aSopenharmony_ci            else
376cabdff1aSopenharmony_ci                delta |= 8;
377cabdff1aSopenharmony_ci        } else {
378cabdff1aSopenharmony_ci            delta = vp56_rac_get_tree(c, ff_vp56_pva_tree,
379cabdff1aSopenharmony_ci                                      model->vector_pdv[comp]);
380cabdff1aSopenharmony_ci        }
381cabdff1aSopenharmony_ci
382cabdff1aSopenharmony_ci        if (delta && vp56_rac_get_prob_branchy(c, model->vector_sig[comp]))
383cabdff1aSopenharmony_ci            delta = -delta;
384cabdff1aSopenharmony_ci
385cabdff1aSopenharmony_ci        if (!comp)
386cabdff1aSopenharmony_ci            vect->x += delta;
387cabdff1aSopenharmony_ci        else
388cabdff1aSopenharmony_ci            vect->y += delta;
389cabdff1aSopenharmony_ci    }
390cabdff1aSopenharmony_ci}
391cabdff1aSopenharmony_ci
392cabdff1aSopenharmony_ci/**
393cabdff1aSopenharmony_ci * Read number of consecutive blocks with null DC or AC.
394cabdff1aSopenharmony_ci * This value is < 74.
395cabdff1aSopenharmony_ci */
396cabdff1aSopenharmony_cistatic unsigned vp6_get_nb_null(VP56Context *s)
397cabdff1aSopenharmony_ci{
398cabdff1aSopenharmony_ci    unsigned val = get_bits(&s->gb, 2);
399cabdff1aSopenharmony_ci    if (val == 2)
400cabdff1aSopenharmony_ci        val += get_bits(&s->gb, 2);
401cabdff1aSopenharmony_ci    else if (val == 3) {
402cabdff1aSopenharmony_ci        val = get_bits1(&s->gb) << 2;
403cabdff1aSopenharmony_ci        val = 6+val + get_bits(&s->gb, 2+val);
404cabdff1aSopenharmony_ci    }
405cabdff1aSopenharmony_ci    return val;
406cabdff1aSopenharmony_ci}
407cabdff1aSopenharmony_ci
408cabdff1aSopenharmony_cistatic int vp6_parse_coeff_huffman(VP56Context *s)
409cabdff1aSopenharmony_ci{
410cabdff1aSopenharmony_ci    VP56Model *model = s->modelp;
411cabdff1aSopenharmony_ci    uint8_t *permute = s->idct_scantable;
412cabdff1aSopenharmony_ci    VLC *vlc_coeff;
413cabdff1aSopenharmony_ci    int coeff, sign, coeff_idx;
414cabdff1aSopenharmony_ci    int b, cg, idx;
415cabdff1aSopenharmony_ci    int pt = 0;    /* plane type (0 for Y, 1 for U or V) */
416cabdff1aSopenharmony_ci
417cabdff1aSopenharmony_ci    for (b=0; b<6; b++) {
418cabdff1aSopenharmony_ci        int ct = 0;    /* code type */
419cabdff1aSopenharmony_ci        if (b > 3) pt = 1;
420cabdff1aSopenharmony_ci        vlc_coeff = &s->dccv_vlc[pt];
421cabdff1aSopenharmony_ci
422cabdff1aSopenharmony_ci        for (coeff_idx = 0;;) {
423cabdff1aSopenharmony_ci            int run = 1;
424cabdff1aSopenharmony_ci            if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) {
425cabdff1aSopenharmony_ci                s->nb_null[coeff_idx][pt]--;
426cabdff1aSopenharmony_ci                if (coeff_idx)
427cabdff1aSopenharmony_ci                    break;
428cabdff1aSopenharmony_ci            } else {
429cabdff1aSopenharmony_ci                if (get_bits_left(&s->gb) <= 0)
430cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
431cabdff1aSopenharmony_ci                coeff = get_vlc2(&s->gb, vlc_coeff->table, FF_HUFFMAN_BITS, 3);
432cabdff1aSopenharmony_ci                if (coeff == 0) {
433cabdff1aSopenharmony_ci                    if (coeff_idx) {
434cabdff1aSopenharmony_ci                        int pt = (coeff_idx >= 6);
435cabdff1aSopenharmony_ci                        run += get_vlc2(&s->gb, s->runv_vlc[pt].table, FF_HUFFMAN_BITS, 3);
436cabdff1aSopenharmony_ci                        if (run >= 9)
437cabdff1aSopenharmony_ci                            run += get_bits(&s->gb, 6);
438cabdff1aSopenharmony_ci                    } else
439cabdff1aSopenharmony_ci                        s->nb_null[0][pt] = vp6_get_nb_null(s);
440cabdff1aSopenharmony_ci                    ct = 0;
441cabdff1aSopenharmony_ci                } else if (coeff == 11) {  /* end of block */
442cabdff1aSopenharmony_ci                    if (coeff_idx == 1)    /* first AC coeff ? */
443cabdff1aSopenharmony_ci                        s->nb_null[1][pt] = vp6_get_nb_null(s);
444cabdff1aSopenharmony_ci                    break;
445cabdff1aSopenharmony_ci                } else {
446cabdff1aSopenharmony_ci                    int coeff2 = ff_vp56_coeff_bias[coeff];
447cabdff1aSopenharmony_ci                    if (coeff > 4)
448cabdff1aSopenharmony_ci                        coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11);
449cabdff1aSopenharmony_ci                    ct = 1 + (coeff2 > 1);
450cabdff1aSopenharmony_ci                    sign = get_bits1(&s->gb);
451cabdff1aSopenharmony_ci                    coeff2 = (coeff2 ^ -sign) + sign;
452cabdff1aSopenharmony_ci                    if (coeff_idx)
453cabdff1aSopenharmony_ci                        coeff2 *= s->dequant_ac;
454cabdff1aSopenharmony_ci                    idx = model->coeff_index_to_pos[coeff_idx];
455cabdff1aSopenharmony_ci                    s->block_coeff[b][permute[idx]] = coeff2;
456cabdff1aSopenharmony_ci                }
457cabdff1aSopenharmony_ci            }
458cabdff1aSopenharmony_ci            coeff_idx+=run;
459cabdff1aSopenharmony_ci            if (coeff_idx >= 64)
460cabdff1aSopenharmony_ci                break;
461cabdff1aSopenharmony_ci            cg = FFMIN(vp6_coeff_groups[coeff_idx], 3);
462cabdff1aSopenharmony_ci            vlc_coeff = &s->ract_vlc[pt][ct][cg];
463cabdff1aSopenharmony_ci        }
464cabdff1aSopenharmony_ci        s->idct_selector[b] = model->coeff_index_to_idct_selector[FFMIN(coeff_idx, 63)];
465cabdff1aSopenharmony_ci    }
466cabdff1aSopenharmony_ci    return 0;
467cabdff1aSopenharmony_ci}
468cabdff1aSopenharmony_ci
469cabdff1aSopenharmony_cistatic int vp6_parse_coeff(VP56Context *s)
470cabdff1aSopenharmony_ci{
471cabdff1aSopenharmony_ci    VP56RangeCoder *c = s->ccp;
472cabdff1aSopenharmony_ci    VP56Model *model = s->modelp;
473cabdff1aSopenharmony_ci    uint8_t *permute = s->idct_scantable;
474cabdff1aSopenharmony_ci    uint8_t *model1, *model2, *model3;
475cabdff1aSopenharmony_ci    int coeff, sign, coeff_idx;
476cabdff1aSopenharmony_ci    int b, i, cg, idx, ctx;
477cabdff1aSopenharmony_ci    int pt = 0;    /* plane type (0 for Y, 1 for U or V) */
478cabdff1aSopenharmony_ci
479cabdff1aSopenharmony_ci    if (vpX_rac_is_end(c)) {
480cabdff1aSopenharmony_ci        av_log(s->avctx, AV_LOG_ERROR, "End of AC stream reached in vp6_parse_coeff\n");
481cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
482cabdff1aSopenharmony_ci    }
483cabdff1aSopenharmony_ci
484cabdff1aSopenharmony_ci    for (b=0; b<6; b++) {
485cabdff1aSopenharmony_ci        int ct = 1;    /* code type */
486cabdff1aSopenharmony_ci        int run = 1;
487cabdff1aSopenharmony_ci
488cabdff1aSopenharmony_ci        if (b > 3) pt = 1;
489cabdff1aSopenharmony_ci
490cabdff1aSopenharmony_ci        ctx = s->left_block[ff_vp56_b6to4[b]].not_null_dc
491cabdff1aSopenharmony_ci              + s->above_blocks[s->above_block_idx[b]].not_null_dc;
492cabdff1aSopenharmony_ci        model1 = model->coeff_dccv[pt];
493cabdff1aSopenharmony_ci        model2 = model->coeff_dcct[pt][ctx];
494cabdff1aSopenharmony_ci
495cabdff1aSopenharmony_ci        coeff_idx = 0;
496cabdff1aSopenharmony_ci        for (;;) {
497cabdff1aSopenharmony_ci            if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob_branchy(c, model2[0])) {
498cabdff1aSopenharmony_ci                /* parse a coeff */
499cabdff1aSopenharmony_ci                if (vp56_rac_get_prob_branchy(c, model2[2])) {
500cabdff1aSopenharmony_ci                    if (vp56_rac_get_prob_branchy(c, model2[3])) {
501cabdff1aSopenharmony_ci                        idx = vp56_rac_get_tree(c, ff_vp56_pc_tree, model1);
502cabdff1aSopenharmony_ci                        coeff = ff_vp56_coeff_bias[idx+5];
503cabdff1aSopenharmony_ci                        for (i=ff_vp56_coeff_bit_length[idx]; i>=0; i--)
504cabdff1aSopenharmony_ci                            coeff += vp56_rac_get_prob(c, ff_vp56_coeff_parse_table[idx][i]) << i;
505cabdff1aSopenharmony_ci                    } else {
506cabdff1aSopenharmony_ci                        if (vp56_rac_get_prob_branchy(c, model2[4]))
507cabdff1aSopenharmony_ci                            coeff = 3 + vp56_rac_get_prob(c, model1[5]);
508cabdff1aSopenharmony_ci                        else
509cabdff1aSopenharmony_ci                            coeff = 2;
510cabdff1aSopenharmony_ci                    }
511cabdff1aSopenharmony_ci                    ct = 2;
512cabdff1aSopenharmony_ci                } else {
513cabdff1aSopenharmony_ci                    ct = 1;
514cabdff1aSopenharmony_ci                    coeff = 1;
515cabdff1aSopenharmony_ci                }
516cabdff1aSopenharmony_ci                sign = vp56_rac_get(c);
517cabdff1aSopenharmony_ci                coeff = (coeff ^ -sign) + sign;
518cabdff1aSopenharmony_ci                if (coeff_idx)
519cabdff1aSopenharmony_ci                    coeff *= s->dequant_ac;
520cabdff1aSopenharmony_ci                idx = model->coeff_index_to_pos[coeff_idx];
521cabdff1aSopenharmony_ci                s->block_coeff[b][permute[idx]] = coeff;
522cabdff1aSopenharmony_ci                run = 1;
523cabdff1aSopenharmony_ci            } else {
524cabdff1aSopenharmony_ci                /* parse a run */
525cabdff1aSopenharmony_ci                ct = 0;
526cabdff1aSopenharmony_ci                if (coeff_idx > 0) {
527cabdff1aSopenharmony_ci                    if (!vp56_rac_get_prob_branchy(c, model2[1]))
528cabdff1aSopenharmony_ci                        break;
529cabdff1aSopenharmony_ci
530cabdff1aSopenharmony_ci                    model3 = model->coeff_runv[coeff_idx >= 6];
531cabdff1aSopenharmony_ci                    run = vp56_rac_get_tree(c, vp6_pcr_tree, model3);
532cabdff1aSopenharmony_ci                    if (!run)
533cabdff1aSopenharmony_ci                        for (run=9, i=0; i<6; i++)
534cabdff1aSopenharmony_ci                            run += vp56_rac_get_prob(c, model3[i+8]) << i;
535cabdff1aSopenharmony_ci                }
536cabdff1aSopenharmony_ci            }
537cabdff1aSopenharmony_ci            coeff_idx += run;
538cabdff1aSopenharmony_ci            if (coeff_idx >= 64)
539cabdff1aSopenharmony_ci                break;
540cabdff1aSopenharmony_ci            cg = vp6_coeff_groups[coeff_idx];
541cabdff1aSopenharmony_ci            model1 = model2 = model->coeff_ract[pt][ct][cg];
542cabdff1aSopenharmony_ci        }
543cabdff1aSopenharmony_ci
544cabdff1aSopenharmony_ci        s->left_block[ff_vp56_b6to4[b]].not_null_dc =
545cabdff1aSopenharmony_ci        s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0];
546cabdff1aSopenharmony_ci        s->idct_selector[b] = model->coeff_index_to_idct_selector[FFMIN(coeff_idx, 63)];
547cabdff1aSopenharmony_ci    }
548cabdff1aSopenharmony_ci    return 0;
549cabdff1aSopenharmony_ci}
550cabdff1aSopenharmony_ci
551cabdff1aSopenharmony_cistatic int vp6_block_variance(uint8_t *src, ptrdiff_t stride)
552cabdff1aSopenharmony_ci{
553cabdff1aSopenharmony_ci    int sum = 0, square_sum = 0;
554cabdff1aSopenharmony_ci    int y, x;
555cabdff1aSopenharmony_ci
556cabdff1aSopenharmony_ci    for (y=0; y<8; y+=2) {
557cabdff1aSopenharmony_ci        for (x=0; x<8; x+=2) {
558cabdff1aSopenharmony_ci            sum += src[x];
559cabdff1aSopenharmony_ci            square_sum += src[x]*src[x];
560cabdff1aSopenharmony_ci        }
561cabdff1aSopenharmony_ci        src += 2*stride;
562cabdff1aSopenharmony_ci    }
563cabdff1aSopenharmony_ci    return (16*square_sum - sum*sum) >> 8;
564cabdff1aSopenharmony_ci}
565cabdff1aSopenharmony_ci
566cabdff1aSopenharmony_cistatic void vp6_filter_hv4(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
567cabdff1aSopenharmony_ci                           int delta, const int16_t *weights)
568cabdff1aSopenharmony_ci{
569cabdff1aSopenharmony_ci    int x, y;
570cabdff1aSopenharmony_ci
571cabdff1aSopenharmony_ci    for (y=0; y<8; y++) {
572cabdff1aSopenharmony_ci        for (x=0; x<8; x++) {
573cabdff1aSopenharmony_ci            dst[x] = av_clip_uint8((  src[x-delta  ] * weights[0]
574cabdff1aSopenharmony_ci                                 + src[x        ] * weights[1]
575cabdff1aSopenharmony_ci                                 + src[x+delta  ] * weights[2]
576cabdff1aSopenharmony_ci                                 + src[x+2*delta] * weights[3] + 64) >> 7);
577cabdff1aSopenharmony_ci        }
578cabdff1aSopenharmony_ci        src += stride;
579cabdff1aSopenharmony_ci        dst += stride;
580cabdff1aSopenharmony_ci    }
581cabdff1aSopenharmony_ci}
582cabdff1aSopenharmony_ci
583cabdff1aSopenharmony_cistatic void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src,
584cabdff1aSopenharmony_ci                             ptrdiff_t stride, int h_weight, int v_weight)
585cabdff1aSopenharmony_ci{
586cabdff1aSopenharmony_ci    uint8_t *tmp = s->edge_emu_buffer+16;
587cabdff1aSopenharmony_ci    s->h264chroma.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
588cabdff1aSopenharmony_ci    s->h264chroma.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
589cabdff1aSopenharmony_ci}
590cabdff1aSopenharmony_ci
591cabdff1aSopenharmony_cistatic void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
592cabdff1aSopenharmony_ci                       int offset1, int offset2, ptrdiff_t stride,
593cabdff1aSopenharmony_ci                       VP56mv mv, int mask, int select, int luma)
594cabdff1aSopenharmony_ci{
595cabdff1aSopenharmony_ci    int filter4 = 0;
596cabdff1aSopenharmony_ci    int x8 = mv.x & mask;
597cabdff1aSopenharmony_ci    int y8 = mv.y & mask;
598cabdff1aSopenharmony_ci
599cabdff1aSopenharmony_ci    if (luma) {
600cabdff1aSopenharmony_ci        x8 *= 2;
601cabdff1aSopenharmony_ci        y8 *= 2;
602cabdff1aSopenharmony_ci        filter4 = s->filter_mode;
603cabdff1aSopenharmony_ci        if (filter4 == 2) {
604cabdff1aSopenharmony_ci            if (s->max_vector_length &&
605cabdff1aSopenharmony_ci                (FFABS(mv.x) > s->max_vector_length ||
606cabdff1aSopenharmony_ci                 FFABS(mv.y) > s->max_vector_length)) {
607cabdff1aSopenharmony_ci                filter4 = 0;
608cabdff1aSopenharmony_ci            } else if (s->sample_variance_threshold
609cabdff1aSopenharmony_ci                       && (vp6_block_variance(src+offset1, stride)
610cabdff1aSopenharmony_ci                           < s->sample_variance_threshold)) {
611cabdff1aSopenharmony_ci                filter4 = 0;
612cabdff1aSopenharmony_ci            }
613cabdff1aSopenharmony_ci        }
614cabdff1aSopenharmony_ci    }
615cabdff1aSopenharmony_ci
616cabdff1aSopenharmony_ci    if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) {
617cabdff1aSopenharmony_ci        offset1 = offset2;
618cabdff1aSopenharmony_ci    }
619cabdff1aSopenharmony_ci
620cabdff1aSopenharmony_ci    if (filter4) {
621cabdff1aSopenharmony_ci        if (!y8) {                      /* left or right combine */
622cabdff1aSopenharmony_ci            vp6_filter_hv4(dst, src+offset1, stride, 1,
623cabdff1aSopenharmony_ci                           vp6_block_copy_filter[select][x8]);
624cabdff1aSopenharmony_ci        } else if (!x8) {               /* above or below combine */
625cabdff1aSopenharmony_ci            vp6_filter_hv4(dst, src+offset1, stride, stride,
626cabdff1aSopenharmony_ci                           vp6_block_copy_filter[select][y8]);
627cabdff1aSopenharmony_ci        } else {
628cabdff1aSopenharmony_ci            s->vp56dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride,
629cabdff1aSopenharmony_ci                             vp6_block_copy_filter[select][x8],
630cabdff1aSopenharmony_ci                             vp6_block_copy_filter[select][y8]);
631cabdff1aSopenharmony_ci        }
632cabdff1aSopenharmony_ci    } else {
633cabdff1aSopenharmony_ci        if (!x8 || !y8) {
634cabdff1aSopenharmony_ci            s->h264chroma.put_h264_chroma_pixels_tab[0](dst, src + offset1, stride, 8, x8, y8);
635cabdff1aSopenharmony_ci        } else {
636cabdff1aSopenharmony_ci            vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8);
637cabdff1aSopenharmony_ci        }
638cabdff1aSopenharmony_ci    }
639cabdff1aSopenharmony_ci}
640cabdff1aSopenharmony_ci
641cabdff1aSopenharmony_cistatic av_cold int vp6_decode_init_context(AVCodecContext *avctx,
642cabdff1aSopenharmony_ci                                           VP56Context *s, int flip, int has_alpha)
643cabdff1aSopenharmony_ci{
644cabdff1aSopenharmony_ci    int ret = ff_vp56_init_context(avctx, s, flip, has_alpha);
645cabdff1aSopenharmony_ci    if (ret < 0)
646cabdff1aSopenharmony_ci        return ret;
647cabdff1aSopenharmony_ci
648cabdff1aSopenharmony_ci    ff_vp6dsp_init(&s->vp56dsp);
649cabdff1aSopenharmony_ci
650cabdff1aSopenharmony_ci    s->deblock_filtering = 0;
651cabdff1aSopenharmony_ci    s->vp56_coord_div = vp6_coord_div;
652cabdff1aSopenharmony_ci    s->parse_vector_adjustment = vp6_parse_vector_adjustment;
653cabdff1aSopenharmony_ci    s->filter = vp6_filter;
654cabdff1aSopenharmony_ci    s->default_models_init = vp6_default_models_init;
655cabdff1aSopenharmony_ci    s->parse_vector_models = vp6_parse_vector_models;
656cabdff1aSopenharmony_ci    s->parse_coeff_models = vp6_parse_coeff_models;
657cabdff1aSopenharmony_ci    s->parse_header = vp6_parse_header;
658cabdff1aSopenharmony_ci
659cabdff1aSopenharmony_ci    return 0;
660cabdff1aSopenharmony_ci}
661cabdff1aSopenharmony_ci
662cabdff1aSopenharmony_cistatic av_cold int vp6_decode_init(AVCodecContext *avctx)
663cabdff1aSopenharmony_ci{
664cabdff1aSopenharmony_ci    VP56Context *s = avctx->priv_data;
665cabdff1aSopenharmony_ci    int ret;
666cabdff1aSopenharmony_ci
667cabdff1aSopenharmony_ci    ret = vp6_decode_init_context(avctx, s, avctx->codec_id == AV_CODEC_ID_VP6,
668cabdff1aSopenharmony_ci                                  avctx->codec_id == AV_CODEC_ID_VP6A);
669cabdff1aSopenharmony_ci    if (ret < 0)
670cabdff1aSopenharmony_ci        return ret;
671cabdff1aSopenharmony_ci
672cabdff1aSopenharmony_ci    if (s->has_alpha) {
673cabdff1aSopenharmony_ci        /* Can only happen for ff_vp6a_decoder */
674cabdff1aSopenharmony_ci        s->alpha_context = &s[1];
675cabdff1aSopenharmony_ci        ret = vp6_decode_init_context(avctx, s->alpha_context,
676cabdff1aSopenharmony_ci                                      s->flip == -1, s->has_alpha);
677cabdff1aSopenharmony_ci        if (ret < 0)
678cabdff1aSopenharmony_ci            return ret;
679cabdff1aSopenharmony_ci    }
680cabdff1aSopenharmony_ci
681cabdff1aSopenharmony_ci    return 0;
682cabdff1aSopenharmony_ci}
683cabdff1aSopenharmony_ci
684cabdff1aSopenharmony_cistatic av_cold void vp6_decode_free_context(VP56Context *s);
685cabdff1aSopenharmony_ci
686cabdff1aSopenharmony_cistatic av_cold int vp6_decode_free(AVCodecContext *avctx)
687cabdff1aSopenharmony_ci{
688cabdff1aSopenharmony_ci    VP56Context *s = avctx->priv_data;
689cabdff1aSopenharmony_ci
690cabdff1aSopenharmony_ci    vp6_decode_free_context(s);
691cabdff1aSopenharmony_ci
692cabdff1aSopenharmony_ci    if (s->alpha_context) {
693cabdff1aSopenharmony_ci        vp6_decode_free_context(s->alpha_context);
694cabdff1aSopenharmony_ci        s->alpha_context = NULL;
695cabdff1aSopenharmony_ci    }
696cabdff1aSopenharmony_ci
697cabdff1aSopenharmony_ci    return 0;
698cabdff1aSopenharmony_ci}
699cabdff1aSopenharmony_ci
700cabdff1aSopenharmony_cistatic av_cold void vp6_decode_free_context(VP56Context *s)
701cabdff1aSopenharmony_ci{
702cabdff1aSopenharmony_ci    int pt, ct, cg;
703cabdff1aSopenharmony_ci
704cabdff1aSopenharmony_ci    ff_vp56_free_context(s);
705cabdff1aSopenharmony_ci
706cabdff1aSopenharmony_ci    for (pt=0; pt<2; pt++) {
707cabdff1aSopenharmony_ci        ff_free_vlc(&s->dccv_vlc[pt]);
708cabdff1aSopenharmony_ci        ff_free_vlc(&s->runv_vlc[pt]);
709cabdff1aSopenharmony_ci        for (ct=0; ct<3; ct++)
710cabdff1aSopenharmony_ci            for (cg=0; cg<6; cg++)
711cabdff1aSopenharmony_ci                ff_free_vlc(&s->ract_vlc[pt][ct][cg]);
712cabdff1aSopenharmony_ci    }
713cabdff1aSopenharmony_ci}
714cabdff1aSopenharmony_ci
715cabdff1aSopenharmony_ciconst FFCodec ff_vp6_decoder = {
716cabdff1aSopenharmony_ci    .p.name         = "vp6",
717cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("On2 VP6"),
718cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
719cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_VP6,
720cabdff1aSopenharmony_ci    .priv_data_size = sizeof(VP56Context),
721cabdff1aSopenharmony_ci    .init           = vp6_decode_init,
722cabdff1aSopenharmony_ci    .close          = vp6_decode_free,
723cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(ff_vp56_decode_frame),
724cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1,
725cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
726cabdff1aSopenharmony_ci};
727cabdff1aSopenharmony_ci
728cabdff1aSopenharmony_ci/* flash version, not flipped upside-down */
729cabdff1aSopenharmony_ciconst FFCodec ff_vp6f_decoder = {
730cabdff1aSopenharmony_ci    .p.name         = "vp6f",
731cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
732cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
733cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_VP6F,
734cabdff1aSopenharmony_ci    .priv_data_size = sizeof(VP56Context),
735cabdff1aSopenharmony_ci    .init           = vp6_decode_init,
736cabdff1aSopenharmony_ci    .close          = vp6_decode_free,
737cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(ff_vp56_decode_frame),
738cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1,
739cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
740cabdff1aSopenharmony_ci};
741cabdff1aSopenharmony_ci
742cabdff1aSopenharmony_ci/* flash version, not flipped upside-down, with alpha channel */
743cabdff1aSopenharmony_ciconst FFCodec ff_vp6a_decoder = {
744cabdff1aSopenharmony_ci    .p.name         = "vp6a",
745cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
746cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
747cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_VP6A,
748cabdff1aSopenharmony_ci    .priv_data_size = 2 /* Main context + alpha context */ * sizeof(VP56Context),
749cabdff1aSopenharmony_ci    .init           = vp6_decode_init,
750cabdff1aSopenharmony_ci    .close          = vp6_decode_free,
751cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(ff_vp56_decode_frame),
752cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
753cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
754cabdff1aSopenharmony_ci};
755