xref: /third_party/ffmpeg/libavcodec/av1dec.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * AV1 video decoder
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#include "config_components.h"
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#include "libavutil/film_grain_params.h"
24cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h"
25cabdff1aSopenharmony_ci#include "libavutil/opt.h"
26cabdff1aSopenharmony_ci#include "avcodec.h"
27cabdff1aSopenharmony_ci#include "av1dec.h"
28cabdff1aSopenharmony_ci#include "bytestream.h"
29cabdff1aSopenharmony_ci#include "codec_internal.h"
30cabdff1aSopenharmony_ci#include "hwconfig.h"
31cabdff1aSopenharmony_ci#include "internal.h"
32cabdff1aSopenharmony_ci#include "profiles.h"
33cabdff1aSopenharmony_ci#include "thread.h"
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_ci/**< same with Div_Lut defined in spec 7.11.3.7 */
36cabdff1aSopenharmony_cistatic const uint16_t div_lut[AV1_DIV_LUT_NUM] = {
37cabdff1aSopenharmony_ci  16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768,
38cabdff1aSopenharmony_ci  15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 15142,
39cabdff1aSopenharmony_ci  15087, 15033, 14980, 14926, 14873, 14821, 14769, 14717, 14665, 14614, 14564,
40cabdff1aSopenharmony_ci  14513, 14463, 14413, 14364, 14315, 14266, 14218, 14170, 14122, 14075, 14028,
41cabdff1aSopenharmony_ci  13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662, 13618, 13574, 13530,
42cabdff1aSopenharmony_ci  13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, 13107, 13066,
43cabdff1aSopenharmony_ci  13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, 12672, 12633,
44cabdff1aSopenharmony_ci  12596, 12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, 12264, 12228,
45cabdff1aSopenharmony_ci  12193, 12157, 12122, 12087, 12053, 12018, 11984, 11950, 11916, 11882, 11848,
46cabdff1aSopenharmony_ci  11815, 11782, 11749, 11716, 11683, 11651, 11619, 11586, 11555, 11523, 11491,
47cabdff1aSopenharmony_ci  11460, 11429, 11398, 11367, 11336, 11305, 11275, 11245, 11215, 11185, 11155,
48cabdff1aSopenharmony_ci  11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894, 10866, 10838,
49cabdff1aSopenharmony_ci  10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, 10565, 10538,
50cabdff1aSopenharmony_ci  10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, 10280, 10255,
51cabdff1aSopenharmony_ci  10230, 10205, 10180, 10156, 10131, 10107, 10082, 10058, 10034, 10010, 9986,
52cabdff1aSopenharmony_ci  9963,  9939,  9916,  9892,  9869,  9846,  9823,  9800,  9777,  9754,  9732,
53cabdff1aSopenharmony_ci  9709,  9687,  9664,  9642,  9620,  9598,  9576,  9554,  9533,  9511,  9489,
54cabdff1aSopenharmony_ci  9468,  9447,  9425,  9404,  9383,  9362,  9341,  9321,  9300,  9279,  9259,
55cabdff1aSopenharmony_ci  9239,  9218,  9198,  9178,  9158,  9138,  9118,  9098,  9079,  9059,  9039,
56cabdff1aSopenharmony_ci  9020,  9001,  8981,  8962,  8943,  8924,  8905,  8886,  8867,  8849,  8830,
57cabdff1aSopenharmony_ci  8812,  8793,  8775,  8756,  8738,  8720,  8702,  8684,  8666,  8648,  8630,
58cabdff1aSopenharmony_ci  8613,  8595,  8577,  8560,  8542,  8525,  8508,  8490,  8473,  8456,  8439,
59cabdff1aSopenharmony_ci  8422,  8405,  8389,  8372,  8355,  8339,  8322,  8306,  8289,  8273,  8257,
60cabdff1aSopenharmony_ci  8240,  8224,  8208,  8192
61cabdff1aSopenharmony_ci};
62cabdff1aSopenharmony_ci
63cabdff1aSopenharmony_cistatic uint32_t inverse_recenter(int r, uint32_t v)
64cabdff1aSopenharmony_ci{
65cabdff1aSopenharmony_ci    if (v > 2 * r)
66cabdff1aSopenharmony_ci        return v;
67cabdff1aSopenharmony_ci    else if (v & 1)
68cabdff1aSopenharmony_ci        return r - ((v + 1) >> 1);
69cabdff1aSopenharmony_ci    else
70cabdff1aSopenharmony_ci        return r + (v >> 1);
71cabdff1aSopenharmony_ci}
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_cistatic uint32_t decode_unsigned_subexp_with_ref(uint32_t sub_exp,
74cabdff1aSopenharmony_ci                                                int mx, int r)
75cabdff1aSopenharmony_ci{
76cabdff1aSopenharmony_ci    if ((r << 1) <= mx) {
77cabdff1aSopenharmony_ci        return inverse_recenter(r, sub_exp);
78cabdff1aSopenharmony_ci    } else {
79cabdff1aSopenharmony_ci        return mx - 1 - inverse_recenter(mx - 1 - r, sub_exp);
80cabdff1aSopenharmony_ci    }
81cabdff1aSopenharmony_ci}
82cabdff1aSopenharmony_ci
83cabdff1aSopenharmony_cistatic int32_t decode_signed_subexp_with_ref(uint32_t sub_exp, int low,
84cabdff1aSopenharmony_ci                                             int high, int r)
85cabdff1aSopenharmony_ci{
86cabdff1aSopenharmony_ci    int32_t x = decode_unsigned_subexp_with_ref(sub_exp, high - low, r - low);
87cabdff1aSopenharmony_ci    return x + low;
88cabdff1aSopenharmony_ci}
89cabdff1aSopenharmony_ci
90cabdff1aSopenharmony_cistatic void read_global_param(AV1DecContext *s, int type, int ref, int idx)
91cabdff1aSopenharmony_ci{
92cabdff1aSopenharmony_ci    uint8_t primary_frame, prev_frame;
93cabdff1aSopenharmony_ci    uint32_t abs_bits, prec_bits, round, prec_diff, sub, mx;
94cabdff1aSopenharmony_ci    int32_t r, prev_gm_param;
95cabdff1aSopenharmony_ci
96cabdff1aSopenharmony_ci    primary_frame = s->raw_frame_header->primary_ref_frame;
97cabdff1aSopenharmony_ci    prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame];
98cabdff1aSopenharmony_ci    abs_bits = AV1_GM_ABS_ALPHA_BITS;
99cabdff1aSopenharmony_ci    prec_bits = AV1_GM_ALPHA_PREC_BITS;
100cabdff1aSopenharmony_ci
101cabdff1aSopenharmony_ci    /* setup_past_independence() sets PrevGmParams to default values. We can
102cabdff1aSopenharmony_ci     * simply point to the current's frame gm_params as they will be initialized
103cabdff1aSopenharmony_ci     * with defaults at this point.
104cabdff1aSopenharmony_ci     */
105cabdff1aSopenharmony_ci    if (s->raw_frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE)
106cabdff1aSopenharmony_ci        prev_gm_param = s->cur_frame.gm_params[ref][idx];
107cabdff1aSopenharmony_ci    else
108cabdff1aSopenharmony_ci        prev_gm_param = s->ref[prev_frame].gm_params[ref][idx];
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ci    if (idx < 2) {
111cabdff1aSopenharmony_ci        if (type == AV1_WARP_MODEL_TRANSLATION) {
112cabdff1aSopenharmony_ci            abs_bits = AV1_GM_ABS_TRANS_ONLY_BITS -
113cabdff1aSopenharmony_ci                !s->raw_frame_header->allow_high_precision_mv;
114cabdff1aSopenharmony_ci            prec_bits = AV1_GM_TRANS_ONLY_PREC_BITS -
115cabdff1aSopenharmony_ci                !s->raw_frame_header->allow_high_precision_mv;
116cabdff1aSopenharmony_ci        } else {
117cabdff1aSopenharmony_ci            abs_bits = AV1_GM_ABS_TRANS_BITS;
118cabdff1aSopenharmony_ci            prec_bits = AV1_GM_TRANS_PREC_BITS;
119cabdff1aSopenharmony_ci        }
120cabdff1aSopenharmony_ci    }
121cabdff1aSopenharmony_ci    round = (idx % 3) == 2 ? (1 << AV1_WARPEDMODEL_PREC_BITS) : 0;
122cabdff1aSopenharmony_ci    prec_diff = AV1_WARPEDMODEL_PREC_BITS - prec_bits;
123cabdff1aSopenharmony_ci    sub = (idx % 3) == 2 ? (1 << prec_bits) : 0;
124cabdff1aSopenharmony_ci    mx = 1 << abs_bits;
125cabdff1aSopenharmony_ci    r = (prev_gm_param >> prec_diff) - sub;
126cabdff1aSopenharmony_ci
127cabdff1aSopenharmony_ci    s->cur_frame.gm_params[ref][idx] =
128cabdff1aSopenharmony_ci        (decode_signed_subexp_with_ref(s->raw_frame_header->gm_params[ref][idx],
129cabdff1aSopenharmony_ci                                       -mx, mx + 1, r) << prec_diff) + round;
130cabdff1aSopenharmony_ci}
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_cistatic uint64_t round_two(uint64_t x, uint16_t n)
133cabdff1aSopenharmony_ci{
134cabdff1aSopenharmony_ci    if (n == 0)
135cabdff1aSopenharmony_ci        return x;
136cabdff1aSopenharmony_ci    return ((x + ((uint64_t)1 << (n - 1))) >> n);
137cabdff1aSopenharmony_ci}
138cabdff1aSopenharmony_ci
139cabdff1aSopenharmony_cistatic int64_t round_two_signed(int64_t x, uint16_t n)
140cabdff1aSopenharmony_ci{
141cabdff1aSopenharmony_ci    return ((x<0) ? -((int64_t)round_two(-x, n)) : (int64_t)round_two(x, n));
142cabdff1aSopenharmony_ci}
143cabdff1aSopenharmony_ci
144cabdff1aSopenharmony_ci/**
145cabdff1aSopenharmony_ci * Resolve divisor process.
146cabdff1aSopenharmony_ci * see spec 7.11.3.7
147cabdff1aSopenharmony_ci */
148cabdff1aSopenharmony_cistatic int16_t resolve_divisor(uint32_t d, uint16_t *shift)
149cabdff1aSopenharmony_ci{
150cabdff1aSopenharmony_ci    int32_t e, f;
151cabdff1aSopenharmony_ci
152cabdff1aSopenharmony_ci    *shift = av_log2(d);
153cabdff1aSopenharmony_ci    e = d - (1 << (*shift));
154cabdff1aSopenharmony_ci    if (*shift > AV1_DIV_LUT_BITS)
155cabdff1aSopenharmony_ci        f = round_two(e, *shift - AV1_DIV_LUT_BITS);
156cabdff1aSopenharmony_ci    else
157cabdff1aSopenharmony_ci        f = e << (AV1_DIV_LUT_BITS - (*shift));
158cabdff1aSopenharmony_ci
159cabdff1aSopenharmony_ci    *shift += AV1_DIV_LUT_PREC_BITS;
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci    return div_lut[f];
162cabdff1aSopenharmony_ci}
163cabdff1aSopenharmony_ci
164cabdff1aSopenharmony_ci/**
165cabdff1aSopenharmony_ci * check if global motion params is valid.
166cabdff1aSopenharmony_ci * see spec 7.11.3.6
167cabdff1aSopenharmony_ci */
168cabdff1aSopenharmony_cistatic uint8_t get_shear_params_valid(AV1DecContext *s, int idx)
169cabdff1aSopenharmony_ci{
170cabdff1aSopenharmony_ci    int16_t alpha, beta, gamma, delta, divf, divs;
171cabdff1aSopenharmony_ci    int64_t v, w;
172cabdff1aSopenharmony_ci    int32_t *param = &s->cur_frame.gm_params[idx][0];
173cabdff1aSopenharmony_ci    if (param[2] <= 0)
174cabdff1aSopenharmony_ci        return 0;
175cabdff1aSopenharmony_ci
176cabdff1aSopenharmony_ci    alpha = av_clip_int16(param[2] - (1 << AV1_WARPEDMODEL_PREC_BITS));
177cabdff1aSopenharmony_ci    beta  = av_clip_int16(param[3]);
178cabdff1aSopenharmony_ci    divf  = resolve_divisor(abs(param[2]), &divs);
179cabdff1aSopenharmony_ci    v     = (int64_t)param[4] * (1 << AV1_WARPEDMODEL_PREC_BITS);
180cabdff1aSopenharmony_ci    w     = (int64_t)param[3] * param[4];
181cabdff1aSopenharmony_ci    gamma = av_clip_int16((int)round_two_signed((v * divf), divs));
182cabdff1aSopenharmony_ci    delta = av_clip_int16(param[5] - (int)round_two_signed((w * divf), divs) - (1 << AV1_WARPEDMODEL_PREC_BITS));
183cabdff1aSopenharmony_ci
184cabdff1aSopenharmony_ci    alpha = round_two_signed(alpha, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS;
185cabdff1aSopenharmony_ci    beta  = round_two_signed(beta,  AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS;
186cabdff1aSopenharmony_ci    gamma = round_two_signed(gamma, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS;
187cabdff1aSopenharmony_ci    delta = round_two_signed(delta, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS;
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_ci    if ((4 * abs(alpha) + 7 * abs(beta)) >= (1 << AV1_WARPEDMODEL_PREC_BITS) ||
190cabdff1aSopenharmony_ci        (4 * abs(gamma) + 4 * abs(delta)) >= (1 << AV1_WARPEDMODEL_PREC_BITS))
191cabdff1aSopenharmony_ci        return 0;
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci    return 1;
194cabdff1aSopenharmony_ci}
195cabdff1aSopenharmony_ci
196cabdff1aSopenharmony_ci/**
197cabdff1aSopenharmony_ci* update gm type/params, since cbs already implemented part of this funcation,
198cabdff1aSopenharmony_ci* so we don't need to full implement spec.
199cabdff1aSopenharmony_ci*/
200cabdff1aSopenharmony_cistatic void global_motion_params(AV1DecContext *s)
201cabdff1aSopenharmony_ci{
202cabdff1aSopenharmony_ci    const AV1RawFrameHeader *header = s->raw_frame_header;
203cabdff1aSopenharmony_ci    int type, ref;
204cabdff1aSopenharmony_ci
205cabdff1aSopenharmony_ci    for (ref = AV1_REF_FRAME_LAST; ref <= AV1_REF_FRAME_ALTREF; ref++) {
206cabdff1aSopenharmony_ci        s->cur_frame.gm_type[ref] = AV1_WARP_MODEL_IDENTITY;
207cabdff1aSopenharmony_ci        for (int i = 0; i < 6; i++)
208cabdff1aSopenharmony_ci            s->cur_frame.gm_params[ref][i] = (i % 3 == 2) ?
209cabdff1aSopenharmony_ci                                             1 << AV1_WARPEDMODEL_PREC_BITS : 0;
210cabdff1aSopenharmony_ci    }
211cabdff1aSopenharmony_ci    if (header->frame_type == AV1_FRAME_KEY ||
212cabdff1aSopenharmony_ci        header->frame_type == AV1_FRAME_INTRA_ONLY)
213cabdff1aSopenharmony_ci        return;
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci    for (ref = AV1_REF_FRAME_LAST; ref <= AV1_REF_FRAME_ALTREF; ref++) {
216cabdff1aSopenharmony_ci        if (header->is_global[ref]) {
217cabdff1aSopenharmony_ci            if (header->is_rot_zoom[ref]) {
218cabdff1aSopenharmony_ci                type = AV1_WARP_MODEL_ROTZOOM;
219cabdff1aSopenharmony_ci            } else {
220cabdff1aSopenharmony_ci                type = header->is_translation[ref] ? AV1_WARP_MODEL_TRANSLATION
221cabdff1aSopenharmony_ci                                                   : AV1_WARP_MODEL_AFFINE;
222cabdff1aSopenharmony_ci            }
223cabdff1aSopenharmony_ci        } else {
224cabdff1aSopenharmony_ci            type = AV1_WARP_MODEL_IDENTITY;
225cabdff1aSopenharmony_ci        }
226cabdff1aSopenharmony_ci        s->cur_frame.gm_type[ref] = type;
227cabdff1aSopenharmony_ci
228cabdff1aSopenharmony_ci        if (type >= AV1_WARP_MODEL_ROTZOOM) {
229cabdff1aSopenharmony_ci            read_global_param(s, type, ref, 2);
230cabdff1aSopenharmony_ci            read_global_param(s, type, ref, 3);
231cabdff1aSopenharmony_ci            if (type == AV1_WARP_MODEL_AFFINE) {
232cabdff1aSopenharmony_ci                read_global_param(s, type, ref, 4);
233cabdff1aSopenharmony_ci                read_global_param(s, type, ref, 5);
234cabdff1aSopenharmony_ci            } else {
235cabdff1aSopenharmony_ci                s->cur_frame.gm_params[ref][4] = -s->cur_frame.gm_params[ref][3];
236cabdff1aSopenharmony_ci                s->cur_frame.gm_params[ref][5] = s->cur_frame.gm_params[ref][2];
237cabdff1aSopenharmony_ci            }
238cabdff1aSopenharmony_ci        }
239cabdff1aSopenharmony_ci        if (type >= AV1_WARP_MODEL_TRANSLATION) {
240cabdff1aSopenharmony_ci            read_global_param(s, type, ref, 0);
241cabdff1aSopenharmony_ci            read_global_param(s, type, ref, 1);
242cabdff1aSopenharmony_ci        }
243cabdff1aSopenharmony_ci        if (type <= AV1_WARP_MODEL_AFFINE) {
244cabdff1aSopenharmony_ci            s->cur_frame.gm_invalid[ref] = !get_shear_params_valid(s, ref);
245cabdff1aSopenharmony_ci        }
246cabdff1aSopenharmony_ci    }
247cabdff1aSopenharmony_ci}
248cabdff1aSopenharmony_ci
249cabdff1aSopenharmony_cistatic int get_relative_dist(const AV1RawSequenceHeader *seq,
250cabdff1aSopenharmony_ci                             unsigned int a, unsigned int b)
251cabdff1aSopenharmony_ci{
252cabdff1aSopenharmony_ci    unsigned int diff = a - b;
253cabdff1aSopenharmony_ci    unsigned int m = 1 << seq->order_hint_bits_minus_1;
254cabdff1aSopenharmony_ci    return (diff & (m - 1)) - (diff & m);
255cabdff1aSopenharmony_ci}
256cabdff1aSopenharmony_ci
257cabdff1aSopenharmony_cistatic void skip_mode_params(AV1DecContext *s)
258cabdff1aSopenharmony_ci{
259cabdff1aSopenharmony_ci    const AV1RawFrameHeader *header = s->raw_frame_header;
260cabdff1aSopenharmony_ci    const AV1RawSequenceHeader *seq = s->raw_seq;
261cabdff1aSopenharmony_ci
262cabdff1aSopenharmony_ci    int forward_idx,  backward_idx;
263cabdff1aSopenharmony_ci    int forward_hint, backward_hint;
264cabdff1aSopenharmony_ci    int second_forward_idx, second_forward_hint;
265cabdff1aSopenharmony_ci    int ref_hint, dist, i;
266cabdff1aSopenharmony_ci
267cabdff1aSopenharmony_ci    if (!header->skip_mode_present)
268cabdff1aSopenharmony_ci        return;
269cabdff1aSopenharmony_ci
270cabdff1aSopenharmony_ci    forward_idx  = -1;
271cabdff1aSopenharmony_ci    backward_idx = -1;
272cabdff1aSopenharmony_ci    for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
273cabdff1aSopenharmony_ci        ref_hint = s->ref[header->ref_frame_idx[i]].raw_frame_header->order_hint;
274cabdff1aSopenharmony_ci        dist = get_relative_dist(seq, ref_hint, header->order_hint);
275cabdff1aSopenharmony_ci        if (dist < 0) {
276cabdff1aSopenharmony_ci            if (forward_idx < 0 ||
277cabdff1aSopenharmony_ci                get_relative_dist(seq, ref_hint, forward_hint) > 0) {
278cabdff1aSopenharmony_ci                forward_idx  = i;
279cabdff1aSopenharmony_ci                forward_hint = ref_hint;
280cabdff1aSopenharmony_ci            }
281cabdff1aSopenharmony_ci        } else if (dist > 0) {
282cabdff1aSopenharmony_ci            if (backward_idx < 0 ||
283cabdff1aSopenharmony_ci                get_relative_dist(seq, ref_hint, backward_hint) < 0) {
284cabdff1aSopenharmony_ci                backward_idx  = i;
285cabdff1aSopenharmony_ci                backward_hint = ref_hint;
286cabdff1aSopenharmony_ci            }
287cabdff1aSopenharmony_ci        }
288cabdff1aSopenharmony_ci    }
289cabdff1aSopenharmony_ci
290cabdff1aSopenharmony_ci    if (forward_idx < 0) {
291cabdff1aSopenharmony_ci        return;
292cabdff1aSopenharmony_ci    } else if (backward_idx >= 0) {
293cabdff1aSopenharmony_ci        s->cur_frame.skip_mode_frame_idx[0] =
294cabdff1aSopenharmony_ci            AV1_REF_FRAME_LAST + FFMIN(forward_idx, backward_idx);
295cabdff1aSopenharmony_ci        s->cur_frame.skip_mode_frame_idx[1] =
296cabdff1aSopenharmony_ci            AV1_REF_FRAME_LAST + FFMAX(forward_idx, backward_idx);
297cabdff1aSopenharmony_ci        return;
298cabdff1aSopenharmony_ci    }
299cabdff1aSopenharmony_ci
300cabdff1aSopenharmony_ci    second_forward_idx = -1;
301cabdff1aSopenharmony_ci    for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
302cabdff1aSopenharmony_ci        ref_hint = s->ref[header->ref_frame_idx[i]].raw_frame_header->order_hint;
303cabdff1aSopenharmony_ci        if (get_relative_dist(seq, ref_hint, forward_hint) < 0) {
304cabdff1aSopenharmony_ci            if (second_forward_idx < 0 ||
305cabdff1aSopenharmony_ci                get_relative_dist(seq, ref_hint, second_forward_hint) > 0) {
306cabdff1aSopenharmony_ci                second_forward_idx  = i;
307cabdff1aSopenharmony_ci                second_forward_hint = ref_hint;
308cabdff1aSopenharmony_ci            }
309cabdff1aSopenharmony_ci        }
310cabdff1aSopenharmony_ci    }
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci    if (second_forward_idx < 0)
313cabdff1aSopenharmony_ci        return;
314cabdff1aSopenharmony_ci
315cabdff1aSopenharmony_ci    s->cur_frame.skip_mode_frame_idx[0] =
316cabdff1aSopenharmony_ci        AV1_REF_FRAME_LAST + FFMIN(forward_idx, second_forward_idx);
317cabdff1aSopenharmony_ci    s->cur_frame.skip_mode_frame_idx[1] =
318cabdff1aSopenharmony_ci        AV1_REF_FRAME_LAST + FFMAX(forward_idx, second_forward_idx);
319cabdff1aSopenharmony_ci}
320cabdff1aSopenharmony_ci
321cabdff1aSopenharmony_cistatic void coded_lossless_param(AV1DecContext *s)
322cabdff1aSopenharmony_ci{
323cabdff1aSopenharmony_ci    const AV1RawFrameHeader *header = s->raw_frame_header;
324cabdff1aSopenharmony_ci    int i;
325cabdff1aSopenharmony_ci
326cabdff1aSopenharmony_ci    if (header->delta_q_y_dc || header->delta_q_u_ac ||
327cabdff1aSopenharmony_ci        header->delta_q_u_dc || header->delta_q_v_ac ||
328cabdff1aSopenharmony_ci        header->delta_q_v_dc) {
329cabdff1aSopenharmony_ci        s->cur_frame.coded_lossless = 0;
330cabdff1aSopenharmony_ci        return;
331cabdff1aSopenharmony_ci    }
332cabdff1aSopenharmony_ci
333cabdff1aSopenharmony_ci    s->cur_frame.coded_lossless = 1;
334cabdff1aSopenharmony_ci    for (i = 0; i < AV1_MAX_SEGMENTS; i++) {
335cabdff1aSopenharmony_ci        int qindex;
336cabdff1aSopenharmony_ci        if (header->feature_enabled[i][AV1_SEG_LVL_ALT_Q]) {
337cabdff1aSopenharmony_ci            qindex = (header->base_q_idx +
338cabdff1aSopenharmony_ci                      header->feature_value[i][AV1_SEG_LVL_ALT_Q]);
339cabdff1aSopenharmony_ci        } else {
340cabdff1aSopenharmony_ci            qindex = header->base_q_idx;
341cabdff1aSopenharmony_ci        }
342cabdff1aSopenharmony_ci        qindex = av_clip_uintp2(qindex, 8);
343cabdff1aSopenharmony_ci
344cabdff1aSopenharmony_ci        if (qindex) {
345cabdff1aSopenharmony_ci            s->cur_frame.coded_lossless = 0;
346cabdff1aSopenharmony_ci            return;
347cabdff1aSopenharmony_ci        }
348cabdff1aSopenharmony_ci    }
349cabdff1aSopenharmony_ci}
350cabdff1aSopenharmony_ci
351cabdff1aSopenharmony_cistatic void load_grain_params(AV1DecContext *s)
352cabdff1aSopenharmony_ci{
353cabdff1aSopenharmony_ci    const AV1RawFrameHeader *header = s->raw_frame_header;
354cabdff1aSopenharmony_ci    const AV1RawFilmGrainParams *film_grain = &header->film_grain, *src;
355cabdff1aSopenharmony_ci    AV1RawFilmGrainParams *dst = &s->cur_frame.film_grain;
356cabdff1aSopenharmony_ci
357cabdff1aSopenharmony_ci    if (!film_grain->apply_grain)
358cabdff1aSopenharmony_ci        return;
359cabdff1aSopenharmony_ci
360cabdff1aSopenharmony_ci    if (film_grain->update_grain) {
361cabdff1aSopenharmony_ci        memcpy(dst, film_grain, sizeof(*dst));
362cabdff1aSopenharmony_ci        return;
363cabdff1aSopenharmony_ci    }
364cabdff1aSopenharmony_ci
365cabdff1aSopenharmony_ci    src = &s->ref[film_grain->film_grain_params_ref_idx].film_grain;
366cabdff1aSopenharmony_ci
367cabdff1aSopenharmony_ci    memcpy(dst, src, sizeof(*dst));
368cabdff1aSopenharmony_ci    dst->grain_seed = film_grain->grain_seed;
369cabdff1aSopenharmony_ci}
370cabdff1aSopenharmony_ci
371cabdff1aSopenharmony_cistatic int init_tile_data(AV1DecContext *s)
372cabdff1aSopenharmony_ci
373cabdff1aSopenharmony_ci{
374cabdff1aSopenharmony_ci    int cur_tile_num =
375cabdff1aSopenharmony_ci        s->raw_frame_header->tile_cols * s->raw_frame_header->tile_rows;
376cabdff1aSopenharmony_ci    if (s->tile_num < cur_tile_num) {
377cabdff1aSopenharmony_ci        int ret = av_reallocp_array(&s->tile_group_info, cur_tile_num,
378cabdff1aSopenharmony_ci                                    sizeof(TileGroupInfo));
379cabdff1aSopenharmony_ci        if (ret < 0) {
380cabdff1aSopenharmony_ci            s->tile_num = 0;
381cabdff1aSopenharmony_ci            return ret;
382cabdff1aSopenharmony_ci        }
383cabdff1aSopenharmony_ci    }
384cabdff1aSopenharmony_ci    s->tile_num = cur_tile_num;
385cabdff1aSopenharmony_ci
386cabdff1aSopenharmony_ci    return 0;
387cabdff1aSopenharmony_ci}
388cabdff1aSopenharmony_ci
389cabdff1aSopenharmony_cistatic int get_tiles_info(AVCodecContext *avctx, const AV1RawTileGroup *tile_group)
390cabdff1aSopenharmony_ci{
391cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
392cabdff1aSopenharmony_ci    GetByteContext gb;
393cabdff1aSopenharmony_ci    uint16_t tile_num, tile_row, tile_col;
394cabdff1aSopenharmony_ci    uint32_t size = 0, size_bytes = 0;
395cabdff1aSopenharmony_ci
396cabdff1aSopenharmony_ci    bytestream2_init(&gb, tile_group->tile_data.data,
397cabdff1aSopenharmony_ci                     tile_group->tile_data.data_size);
398cabdff1aSopenharmony_ci    s->tg_start = tile_group->tg_start;
399cabdff1aSopenharmony_ci    s->tg_end = tile_group->tg_end;
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ci    for (tile_num = tile_group->tg_start; tile_num <= tile_group->tg_end; tile_num++) {
402cabdff1aSopenharmony_ci        tile_row = tile_num / s->raw_frame_header->tile_cols;
403cabdff1aSopenharmony_ci        tile_col = tile_num % s->raw_frame_header->tile_cols;
404cabdff1aSopenharmony_ci
405cabdff1aSopenharmony_ci        if (tile_num == tile_group->tg_end) {
406cabdff1aSopenharmony_ci            s->tile_group_info[tile_num].tile_size = bytestream2_get_bytes_left(&gb);
407cabdff1aSopenharmony_ci            s->tile_group_info[tile_num].tile_offset = bytestream2_tell(&gb);
408cabdff1aSopenharmony_ci            s->tile_group_info[tile_num].tile_row = tile_row;
409cabdff1aSopenharmony_ci            s->tile_group_info[tile_num].tile_column = tile_col;
410cabdff1aSopenharmony_ci            return 0;
411cabdff1aSopenharmony_ci        }
412cabdff1aSopenharmony_ci        size_bytes = s->raw_frame_header->tile_size_bytes_minus1 + 1;
413cabdff1aSopenharmony_ci        if (bytestream2_get_bytes_left(&gb) < size_bytes)
414cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
415cabdff1aSopenharmony_ci        size = 0;
416cabdff1aSopenharmony_ci        for (int i = 0; i < size_bytes; i++)
417cabdff1aSopenharmony_ci            size |= bytestream2_get_byteu(&gb) << 8 * i;
418cabdff1aSopenharmony_ci        if (bytestream2_get_bytes_left(&gb) <= size)
419cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
420cabdff1aSopenharmony_ci        size++;
421cabdff1aSopenharmony_ci
422cabdff1aSopenharmony_ci        s->tile_group_info[tile_num].tile_size = size;
423cabdff1aSopenharmony_ci        s->tile_group_info[tile_num].tile_offset = bytestream2_tell(&gb);
424cabdff1aSopenharmony_ci        s->tile_group_info[tile_num].tile_row = tile_row;
425cabdff1aSopenharmony_ci        s->tile_group_info[tile_num].tile_column = tile_col;
426cabdff1aSopenharmony_ci
427cabdff1aSopenharmony_ci        bytestream2_skipu(&gb, size);
428cabdff1aSopenharmony_ci    }
429cabdff1aSopenharmony_ci
430cabdff1aSopenharmony_ci    return 0;
431cabdff1aSopenharmony_ci
432cabdff1aSopenharmony_ci}
433cabdff1aSopenharmony_ci
434cabdff1aSopenharmony_cistatic int get_pixel_format(AVCodecContext *avctx)
435cabdff1aSopenharmony_ci{
436cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
437cabdff1aSopenharmony_ci    const AV1RawSequenceHeader *seq = s->raw_seq;
438cabdff1aSopenharmony_ci    uint8_t bit_depth;
439cabdff1aSopenharmony_ci    int ret;
440cabdff1aSopenharmony_ci    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
441cabdff1aSopenharmony_ci#define HWACCEL_MAX (CONFIG_AV1_DXVA2_HWACCEL + \
442cabdff1aSopenharmony_ci                     CONFIG_AV1_D3D11VA_HWACCEL * 2 + \
443cabdff1aSopenharmony_ci                     CONFIG_AV1_NVDEC_HWACCEL + \
444cabdff1aSopenharmony_ci                     CONFIG_AV1_VAAPI_HWACCEL + \
445cabdff1aSopenharmony_ci                     CONFIG_AV1_VDPAU_HWACCEL)
446cabdff1aSopenharmony_ci    enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;
447cabdff1aSopenharmony_ci
448cabdff1aSopenharmony_ci    if (seq->seq_profile == 2 && seq->color_config.high_bitdepth)
449cabdff1aSopenharmony_ci        bit_depth = seq->color_config.twelve_bit ? 12 : 10;
450cabdff1aSopenharmony_ci    else if (seq->seq_profile <= 2)
451cabdff1aSopenharmony_ci        bit_depth = seq->color_config.high_bitdepth ? 10 : 8;
452cabdff1aSopenharmony_ci    else {
453cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
454cabdff1aSopenharmony_ci               "Unknown AV1 profile %d.\n", seq->seq_profile);
455cabdff1aSopenharmony_ci        return -1;
456cabdff1aSopenharmony_ci    }
457cabdff1aSopenharmony_ci
458cabdff1aSopenharmony_ci    if (!seq->color_config.mono_chrome) {
459cabdff1aSopenharmony_ci        // 4:4:4 x:0 y:0, 4:2:2 x:1 y:0, 4:2:0 x:1 y:1
460cabdff1aSopenharmony_ci        if (seq->color_config.subsampling_x == 0 &&
461cabdff1aSopenharmony_ci            seq->color_config.subsampling_y == 0) {
462cabdff1aSopenharmony_ci            if (bit_depth == 8)
463cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV444P;
464cabdff1aSopenharmony_ci            else if (bit_depth == 10)
465cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV444P10;
466cabdff1aSopenharmony_ci            else if (bit_depth == 12)
467cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV444P12;
468cabdff1aSopenharmony_ci            else
469cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
470cabdff1aSopenharmony_ci        } else if (seq->color_config.subsampling_x == 1 &&
471cabdff1aSopenharmony_ci                   seq->color_config.subsampling_y == 0) {
472cabdff1aSopenharmony_ci            if (bit_depth == 8)
473cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV422P;
474cabdff1aSopenharmony_ci            else if (bit_depth == 10)
475cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV422P10;
476cabdff1aSopenharmony_ci            else if (bit_depth == 12)
477cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV422P12;
478cabdff1aSopenharmony_ci            else
479cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
480cabdff1aSopenharmony_ci        } else if (seq->color_config.subsampling_x == 1 &&
481cabdff1aSopenharmony_ci                   seq->color_config.subsampling_y == 1) {
482cabdff1aSopenharmony_ci            if (bit_depth == 8)
483cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV420P;
484cabdff1aSopenharmony_ci            else if (bit_depth == 10)
485cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV420P10;
486cabdff1aSopenharmony_ci            else if (bit_depth == 12)
487cabdff1aSopenharmony_ci                pix_fmt = AV_PIX_FMT_YUV420P12;
488cabdff1aSopenharmony_ci            else
489cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
490cabdff1aSopenharmony_ci        }
491cabdff1aSopenharmony_ci    } else {
492cabdff1aSopenharmony_ci        if (bit_depth == 8)
493cabdff1aSopenharmony_ci            pix_fmt = AV_PIX_FMT_GRAY8;
494cabdff1aSopenharmony_ci        else if (bit_depth == 10)
495cabdff1aSopenharmony_ci            pix_fmt = AV_PIX_FMT_GRAY10;
496cabdff1aSopenharmony_ci        else if (bit_depth == 12)
497cabdff1aSopenharmony_ci            pix_fmt = AV_PIX_FMT_GRAY12;
498cabdff1aSopenharmony_ci        else
499cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING, "Unknown AV1 pixel format.\n");
500cabdff1aSopenharmony_ci    }
501cabdff1aSopenharmony_ci
502cabdff1aSopenharmony_ci    av_log(avctx, AV_LOG_DEBUG, "AV1 decode get format: %s.\n",
503cabdff1aSopenharmony_ci           av_get_pix_fmt_name(pix_fmt));
504cabdff1aSopenharmony_ci
505cabdff1aSopenharmony_ci    if (pix_fmt == AV_PIX_FMT_NONE)
506cabdff1aSopenharmony_ci        return -1;
507cabdff1aSopenharmony_ci
508cabdff1aSopenharmony_ci    switch (pix_fmt) {
509cabdff1aSopenharmony_ci    case AV_PIX_FMT_YUV420P:
510cabdff1aSopenharmony_ci#if CONFIG_AV1_DXVA2_HWACCEL
511cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_DXVA2_VLD;
512cabdff1aSopenharmony_ci#endif
513cabdff1aSopenharmony_ci#if CONFIG_AV1_D3D11VA_HWACCEL
514cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_D3D11VA_VLD;
515cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_D3D11;
516cabdff1aSopenharmony_ci#endif
517cabdff1aSopenharmony_ci#if CONFIG_AV1_NVDEC_HWACCEL
518cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_CUDA;
519cabdff1aSopenharmony_ci#endif
520cabdff1aSopenharmony_ci#if CONFIG_AV1_VAAPI_HWACCEL
521cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_VAAPI;
522cabdff1aSopenharmony_ci#endif
523cabdff1aSopenharmony_ci#if CONFIG_AV1_VDPAU_HWACCEL
524cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_VDPAU;
525cabdff1aSopenharmony_ci#endif
526cabdff1aSopenharmony_ci        break;
527cabdff1aSopenharmony_ci    case AV_PIX_FMT_YUV420P10:
528cabdff1aSopenharmony_ci#if CONFIG_AV1_DXVA2_HWACCEL
529cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_DXVA2_VLD;
530cabdff1aSopenharmony_ci#endif
531cabdff1aSopenharmony_ci#if CONFIG_AV1_D3D11VA_HWACCEL
532cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_D3D11VA_VLD;
533cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_D3D11;
534cabdff1aSopenharmony_ci#endif
535cabdff1aSopenharmony_ci#if CONFIG_AV1_NVDEC_HWACCEL
536cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_CUDA;
537cabdff1aSopenharmony_ci#endif
538cabdff1aSopenharmony_ci#if CONFIG_AV1_VAAPI_HWACCEL
539cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_VAAPI;
540cabdff1aSopenharmony_ci#endif
541cabdff1aSopenharmony_ci#if CONFIG_AV1_VDPAU_HWACCEL
542cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_VDPAU;
543cabdff1aSopenharmony_ci#endif
544cabdff1aSopenharmony_ci        break;
545cabdff1aSopenharmony_ci    case AV_PIX_FMT_GRAY8:
546cabdff1aSopenharmony_ci#if CONFIG_AV1_NVDEC_HWACCEL
547cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_CUDA;
548cabdff1aSopenharmony_ci#endif
549cabdff1aSopenharmony_ci        break;
550cabdff1aSopenharmony_ci    case AV_PIX_FMT_GRAY10:
551cabdff1aSopenharmony_ci#if CONFIG_AV1_NVDEC_HWACCEL
552cabdff1aSopenharmony_ci        *fmtp++ = AV_PIX_FMT_CUDA;
553cabdff1aSopenharmony_ci#endif
554cabdff1aSopenharmony_ci        break;
555cabdff1aSopenharmony_ci    }
556cabdff1aSopenharmony_ci
557cabdff1aSopenharmony_ci    *fmtp++ = pix_fmt;
558cabdff1aSopenharmony_ci    *fmtp = AV_PIX_FMT_NONE;
559cabdff1aSopenharmony_ci
560cabdff1aSopenharmony_ci    ret = ff_thread_get_format(avctx, pix_fmts);
561cabdff1aSopenharmony_ci    if (ret < 0)
562cabdff1aSopenharmony_ci        return ret;
563cabdff1aSopenharmony_ci
564cabdff1aSopenharmony_ci    /**
565cabdff1aSopenharmony_ci     * check if the HW accel is inited correctly. If not, return un-implemented.
566cabdff1aSopenharmony_ci     * Since now the av1 decoder doesn't support native decode, if it will be
567cabdff1aSopenharmony_ci     * implemented in the future, need remove this check.
568cabdff1aSopenharmony_ci     */
569cabdff1aSopenharmony_ci    if (!avctx->hwaccel) {
570cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport"
571cabdff1aSopenharmony_ci               " hardware accelerated AV1 decoding.\n");
572cabdff1aSopenharmony_ci        return AVERROR(ENOSYS);
573cabdff1aSopenharmony_ci    }
574cabdff1aSopenharmony_ci
575cabdff1aSopenharmony_ci    s->pix_fmt = pix_fmt;
576cabdff1aSopenharmony_ci    avctx->pix_fmt = ret;
577cabdff1aSopenharmony_ci
578cabdff1aSopenharmony_ci    return 0;
579cabdff1aSopenharmony_ci}
580cabdff1aSopenharmony_ci
581cabdff1aSopenharmony_cistatic void av1_frame_unref(AVCodecContext *avctx, AV1Frame *f)
582cabdff1aSopenharmony_ci{
583cabdff1aSopenharmony_ci    ff_thread_release_buffer(avctx, f->f);
584cabdff1aSopenharmony_ci    av_buffer_unref(&f->hwaccel_priv_buf);
585cabdff1aSopenharmony_ci    f->hwaccel_picture_private = NULL;
586cabdff1aSopenharmony_ci    av_buffer_unref(&f->header_ref);
587cabdff1aSopenharmony_ci    f->raw_frame_header = NULL;
588cabdff1aSopenharmony_ci    f->spatial_id = f->temporal_id = 0;
589cabdff1aSopenharmony_ci    memset(f->skip_mode_frame_idx, 0,
590cabdff1aSopenharmony_ci           2 * sizeof(uint8_t));
591cabdff1aSopenharmony_ci    memset(&f->film_grain, 0, sizeof(f->film_grain));
592cabdff1aSopenharmony_ci    f->coded_lossless = 0;
593cabdff1aSopenharmony_ci}
594cabdff1aSopenharmony_ci
595cabdff1aSopenharmony_cistatic int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *src)
596cabdff1aSopenharmony_ci{
597cabdff1aSopenharmony_ci    int ret;
598cabdff1aSopenharmony_ci
599cabdff1aSopenharmony_ci    ret = av_buffer_replace(&dst->header_ref, src->header_ref);
600cabdff1aSopenharmony_ci    if (ret < 0)
601cabdff1aSopenharmony_ci        return ret;
602cabdff1aSopenharmony_ci
603cabdff1aSopenharmony_ci    dst->raw_frame_header = src->raw_frame_header;
604cabdff1aSopenharmony_ci
605cabdff1aSopenharmony_ci    if (!src->f->buf[0])
606cabdff1aSopenharmony_ci        return 0;
607cabdff1aSopenharmony_ci
608cabdff1aSopenharmony_ci    ret = av_frame_ref(dst->f, src->f);
609cabdff1aSopenharmony_ci    if (ret < 0)
610cabdff1aSopenharmony_ci        goto fail;
611cabdff1aSopenharmony_ci
612cabdff1aSopenharmony_ci    if (src->hwaccel_picture_private) {
613cabdff1aSopenharmony_ci        dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
614cabdff1aSopenharmony_ci        if (!dst->hwaccel_priv_buf)
615cabdff1aSopenharmony_ci            goto fail;
616cabdff1aSopenharmony_ci        dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
617cabdff1aSopenharmony_ci    }
618cabdff1aSopenharmony_ci
619cabdff1aSopenharmony_ci    dst->spatial_id = src->spatial_id;
620cabdff1aSopenharmony_ci    dst->temporal_id = src->temporal_id;
621cabdff1aSopenharmony_ci    memcpy(dst->gm_invalid,
622cabdff1aSopenharmony_ci           src->gm_invalid,
623cabdff1aSopenharmony_ci           AV1_NUM_REF_FRAMES * sizeof(uint8_t));
624cabdff1aSopenharmony_ci    memcpy(dst->gm_type,
625cabdff1aSopenharmony_ci           src->gm_type,
626cabdff1aSopenharmony_ci           AV1_NUM_REF_FRAMES * sizeof(uint8_t));
627cabdff1aSopenharmony_ci    memcpy(dst->gm_params,
628cabdff1aSopenharmony_ci           src->gm_params,
629cabdff1aSopenharmony_ci           AV1_NUM_REF_FRAMES * 6 * sizeof(int32_t));
630cabdff1aSopenharmony_ci    memcpy(dst->skip_mode_frame_idx,
631cabdff1aSopenharmony_ci           src->skip_mode_frame_idx,
632cabdff1aSopenharmony_ci           2 * sizeof(uint8_t));
633cabdff1aSopenharmony_ci    memcpy(&dst->film_grain,
634cabdff1aSopenharmony_ci           &src->film_grain,
635cabdff1aSopenharmony_ci           sizeof(dst->film_grain));
636cabdff1aSopenharmony_ci    dst->coded_lossless = src->coded_lossless;
637cabdff1aSopenharmony_ci
638cabdff1aSopenharmony_ci    return 0;
639cabdff1aSopenharmony_ci
640cabdff1aSopenharmony_cifail:
641cabdff1aSopenharmony_ci    av1_frame_unref(avctx, dst);
642cabdff1aSopenharmony_ci    return AVERROR(ENOMEM);
643cabdff1aSopenharmony_ci}
644cabdff1aSopenharmony_ci
645cabdff1aSopenharmony_cistatic av_cold int av1_decode_free(AVCodecContext *avctx)
646cabdff1aSopenharmony_ci{
647cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
648cabdff1aSopenharmony_ci
649cabdff1aSopenharmony_ci    for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
650cabdff1aSopenharmony_ci        av1_frame_unref(avctx, &s->ref[i]);
651cabdff1aSopenharmony_ci        av_frame_free(&s->ref[i].f);
652cabdff1aSopenharmony_ci    }
653cabdff1aSopenharmony_ci    av1_frame_unref(avctx, &s->cur_frame);
654cabdff1aSopenharmony_ci    av_frame_free(&s->cur_frame.f);
655cabdff1aSopenharmony_ci
656cabdff1aSopenharmony_ci    av_buffer_unref(&s->seq_ref);
657cabdff1aSopenharmony_ci    av_buffer_unref(&s->header_ref);
658cabdff1aSopenharmony_ci    av_freep(&s->tile_group_info);
659cabdff1aSopenharmony_ci
660cabdff1aSopenharmony_ci    ff_cbs_fragment_free(&s->current_obu);
661cabdff1aSopenharmony_ci    ff_cbs_close(&s->cbc);
662cabdff1aSopenharmony_ci
663cabdff1aSopenharmony_ci    return 0;
664cabdff1aSopenharmony_ci}
665cabdff1aSopenharmony_ci
666cabdff1aSopenharmony_cistatic int set_context_with_sequence(AVCodecContext *avctx,
667cabdff1aSopenharmony_ci                                     const AV1RawSequenceHeader *seq)
668cabdff1aSopenharmony_ci{
669cabdff1aSopenharmony_ci    int width = seq->max_frame_width_minus_1 + 1;
670cabdff1aSopenharmony_ci    int height = seq->max_frame_height_minus_1 + 1;
671cabdff1aSopenharmony_ci
672cabdff1aSopenharmony_ci    avctx->profile = seq->seq_profile;
673cabdff1aSopenharmony_ci    avctx->level = seq->seq_level_idx[0];
674cabdff1aSopenharmony_ci
675cabdff1aSopenharmony_ci    avctx->color_range =
676cabdff1aSopenharmony_ci        seq->color_config.color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
677cabdff1aSopenharmony_ci    avctx->color_primaries = seq->color_config.color_primaries;
678cabdff1aSopenharmony_ci    avctx->colorspace = seq->color_config.color_primaries;
679cabdff1aSopenharmony_ci    avctx->color_trc = seq->color_config.transfer_characteristics;
680cabdff1aSopenharmony_ci
681cabdff1aSopenharmony_ci    switch (seq->color_config.chroma_sample_position) {
682cabdff1aSopenharmony_ci    case AV1_CSP_VERTICAL:
683cabdff1aSopenharmony_ci        avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
684cabdff1aSopenharmony_ci        break;
685cabdff1aSopenharmony_ci    case AV1_CSP_COLOCATED:
686cabdff1aSopenharmony_ci        avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
687cabdff1aSopenharmony_ci        break;
688cabdff1aSopenharmony_ci    }
689cabdff1aSopenharmony_ci
690cabdff1aSopenharmony_ci    if (seq->film_grain_params_present)
691cabdff1aSopenharmony_ci        avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
692cabdff1aSopenharmony_ci    else
693cabdff1aSopenharmony_ci        avctx->properties &= ~FF_CODEC_PROPERTY_FILM_GRAIN;
694cabdff1aSopenharmony_ci
695cabdff1aSopenharmony_ci    if (avctx->width != width || avctx->height != height) {
696cabdff1aSopenharmony_ci        int ret = ff_set_dimensions(avctx, width, height);
697cabdff1aSopenharmony_ci        if (ret < 0)
698cabdff1aSopenharmony_ci            return ret;
699cabdff1aSopenharmony_ci    }
700cabdff1aSopenharmony_ci    avctx->sample_aspect_ratio = (AVRational) { 1, 1 };
701cabdff1aSopenharmony_ci
702cabdff1aSopenharmony_ci    if (seq->timing_info.num_units_in_display_tick &&
703cabdff1aSopenharmony_ci        seq->timing_info.time_scale) {
704cabdff1aSopenharmony_ci        av_reduce(&avctx->framerate.den, &avctx->framerate.num,
705cabdff1aSopenharmony_ci                  seq->timing_info.num_units_in_display_tick,
706cabdff1aSopenharmony_ci                  seq->timing_info.time_scale,
707cabdff1aSopenharmony_ci                  INT_MAX);
708cabdff1aSopenharmony_ci        if (seq->timing_info.equal_picture_interval)
709cabdff1aSopenharmony_ci            avctx->ticks_per_frame = seq->timing_info.num_ticks_per_picture_minus_1 + 1;
710cabdff1aSopenharmony_ci    }
711cabdff1aSopenharmony_ci
712cabdff1aSopenharmony_ci    return 0;
713cabdff1aSopenharmony_ci}
714cabdff1aSopenharmony_ci
715cabdff1aSopenharmony_cistatic int update_context_with_frame_header(AVCodecContext *avctx,
716cabdff1aSopenharmony_ci                                            const AV1RawFrameHeader *header)
717cabdff1aSopenharmony_ci{
718cabdff1aSopenharmony_ci    AVRational aspect_ratio;
719cabdff1aSopenharmony_ci    int width = header->frame_width_minus_1 + 1;
720cabdff1aSopenharmony_ci    int height = header->frame_height_minus_1 + 1;
721cabdff1aSopenharmony_ci    int r_width = header->render_width_minus_1 + 1;
722cabdff1aSopenharmony_ci    int r_height = header->render_height_minus_1 + 1;
723cabdff1aSopenharmony_ci    int ret;
724cabdff1aSopenharmony_ci
725cabdff1aSopenharmony_ci    if (avctx->width != width || avctx->height != height) {
726cabdff1aSopenharmony_ci        ret = ff_set_dimensions(avctx, width, height);
727cabdff1aSopenharmony_ci        if (ret < 0)
728cabdff1aSopenharmony_ci            return ret;
729cabdff1aSopenharmony_ci    }
730cabdff1aSopenharmony_ci
731cabdff1aSopenharmony_ci    av_reduce(&aspect_ratio.num, &aspect_ratio.den,
732cabdff1aSopenharmony_ci              (int64_t)height * r_width,
733cabdff1aSopenharmony_ci              (int64_t)width * r_height,
734cabdff1aSopenharmony_ci              INT_MAX);
735cabdff1aSopenharmony_ci
736cabdff1aSopenharmony_ci    if (av_cmp_q(avctx->sample_aspect_ratio, aspect_ratio)) {
737cabdff1aSopenharmony_ci        ret = ff_set_sar(avctx, aspect_ratio);
738cabdff1aSopenharmony_ci        if (ret < 0)
739cabdff1aSopenharmony_ci            return ret;
740cabdff1aSopenharmony_ci    }
741cabdff1aSopenharmony_ci
742cabdff1aSopenharmony_ci    return 0;
743cabdff1aSopenharmony_ci}
744cabdff1aSopenharmony_ci
745cabdff1aSopenharmony_cistatic av_cold int av1_decode_init(AVCodecContext *avctx)
746cabdff1aSopenharmony_ci{
747cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
748cabdff1aSopenharmony_ci    AV1RawSequenceHeader *seq;
749cabdff1aSopenharmony_ci    int ret;
750cabdff1aSopenharmony_ci
751cabdff1aSopenharmony_ci    s->avctx = avctx;
752cabdff1aSopenharmony_ci    s->pix_fmt = AV_PIX_FMT_NONE;
753cabdff1aSopenharmony_ci
754cabdff1aSopenharmony_ci    for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
755cabdff1aSopenharmony_ci        s->ref[i].f = av_frame_alloc();
756cabdff1aSopenharmony_ci        if (!s->ref[i].f) {
757cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR,
758cabdff1aSopenharmony_ci                   "Failed to allocate reference frame buffer %d.\n", i);
759cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
760cabdff1aSopenharmony_ci        }
761cabdff1aSopenharmony_ci    }
762cabdff1aSopenharmony_ci
763cabdff1aSopenharmony_ci    s->cur_frame.f = av_frame_alloc();
764cabdff1aSopenharmony_ci    if (!s->cur_frame.f) {
765cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
766cabdff1aSopenharmony_ci               "Failed to allocate current frame buffer.\n");
767cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
768cabdff1aSopenharmony_ci    }
769cabdff1aSopenharmony_ci
770cabdff1aSopenharmony_ci    ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_AV1, avctx);
771cabdff1aSopenharmony_ci    if (ret < 0)
772cabdff1aSopenharmony_ci        return ret;
773cabdff1aSopenharmony_ci
774cabdff1aSopenharmony_ci    av_opt_set_int(s->cbc->priv_data, "operating_point", s->operating_point, 0);
775cabdff1aSopenharmony_ci
776cabdff1aSopenharmony_ci    if (avctx->extradata && avctx->extradata_size) {
777cabdff1aSopenharmony_ci        ret = ff_cbs_read_extradata_from_codec(s->cbc,
778cabdff1aSopenharmony_ci                                               &s->current_obu,
779cabdff1aSopenharmony_ci                                               avctx);
780cabdff1aSopenharmony_ci        if (ret < 0) {
781cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING, "Failed to read extradata.\n");
782cabdff1aSopenharmony_ci            return ret;
783cabdff1aSopenharmony_ci        }
784cabdff1aSopenharmony_ci
785cabdff1aSopenharmony_ci        seq = ((CodedBitstreamAV1Context *)(s->cbc->priv_data))->sequence_header;
786cabdff1aSopenharmony_ci        if (!seq) {
787cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING, "No sequence header available.\n");
788cabdff1aSopenharmony_ci            goto end;
789cabdff1aSopenharmony_ci        }
790cabdff1aSopenharmony_ci
791cabdff1aSopenharmony_ci        ret = set_context_with_sequence(avctx, seq);
792cabdff1aSopenharmony_ci        if (ret < 0) {
793cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING, "Failed to set decoder context.\n");
794cabdff1aSopenharmony_ci            goto end;
795cabdff1aSopenharmony_ci        }
796cabdff1aSopenharmony_ci
797cabdff1aSopenharmony_ci        end:
798cabdff1aSopenharmony_ci        ff_cbs_fragment_reset(&s->current_obu);
799cabdff1aSopenharmony_ci    }
800cabdff1aSopenharmony_ci
801cabdff1aSopenharmony_ci    return ret;
802cabdff1aSopenharmony_ci}
803cabdff1aSopenharmony_ci
804cabdff1aSopenharmony_cistatic int av1_frame_alloc(AVCodecContext *avctx, AV1Frame *f)
805cabdff1aSopenharmony_ci{
806cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
807cabdff1aSopenharmony_ci    AV1RawFrameHeader *header= s->raw_frame_header;
808cabdff1aSopenharmony_ci    AVFrame *frame;
809cabdff1aSopenharmony_ci    int ret;
810cabdff1aSopenharmony_ci
811cabdff1aSopenharmony_ci    ret = update_context_with_frame_header(avctx, header);
812cabdff1aSopenharmony_ci    if (ret < 0) {
813cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Failed to update context with frame header\n");
814cabdff1aSopenharmony_ci        return ret;
815cabdff1aSopenharmony_ci    }
816cabdff1aSopenharmony_ci
817cabdff1aSopenharmony_ci    if ((ret = ff_thread_get_buffer(avctx, f->f, AV_GET_BUFFER_FLAG_REF)) < 0)
818cabdff1aSopenharmony_ci        goto fail;
819cabdff1aSopenharmony_ci
820cabdff1aSopenharmony_ci    frame = f->f;
821cabdff1aSopenharmony_ci    frame->key_frame = header->frame_type == AV1_FRAME_KEY;
822cabdff1aSopenharmony_ci
823cabdff1aSopenharmony_ci    switch (header->frame_type) {
824cabdff1aSopenharmony_ci    case AV1_FRAME_KEY:
825cabdff1aSopenharmony_ci    case AV1_FRAME_INTRA_ONLY:
826cabdff1aSopenharmony_ci        frame->pict_type = AV_PICTURE_TYPE_I;
827cabdff1aSopenharmony_ci        break;
828cabdff1aSopenharmony_ci    case AV1_FRAME_INTER:
829cabdff1aSopenharmony_ci        frame->pict_type = AV_PICTURE_TYPE_P;
830cabdff1aSopenharmony_ci        break;
831cabdff1aSopenharmony_ci    case AV1_FRAME_SWITCH:
832cabdff1aSopenharmony_ci        frame->pict_type = AV_PICTURE_TYPE_SP;
833cabdff1aSopenharmony_ci        break;
834cabdff1aSopenharmony_ci    }
835cabdff1aSopenharmony_ci
836cabdff1aSopenharmony_ci    if (avctx->hwaccel) {
837cabdff1aSopenharmony_ci        const AVHWAccel *hwaccel = avctx->hwaccel;
838cabdff1aSopenharmony_ci        if (hwaccel->frame_priv_data_size) {
839cabdff1aSopenharmony_ci            f->hwaccel_priv_buf =
840cabdff1aSopenharmony_ci                av_buffer_allocz(hwaccel->frame_priv_data_size);
841cabdff1aSopenharmony_ci            if (!f->hwaccel_priv_buf) {
842cabdff1aSopenharmony_ci                ret = AVERROR(ENOMEM);
843cabdff1aSopenharmony_ci                goto fail;
844cabdff1aSopenharmony_ci            }
845cabdff1aSopenharmony_ci            f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
846cabdff1aSopenharmony_ci        }
847cabdff1aSopenharmony_ci    }
848cabdff1aSopenharmony_ci    return 0;
849cabdff1aSopenharmony_ci
850cabdff1aSopenharmony_cifail:
851cabdff1aSopenharmony_ci    av1_frame_unref(avctx, f);
852cabdff1aSopenharmony_ci    return ret;
853cabdff1aSopenharmony_ci}
854cabdff1aSopenharmony_ci
855cabdff1aSopenharmony_cistatic int export_film_grain(AVCodecContext *avctx, AVFrame *frame)
856cabdff1aSopenharmony_ci{
857cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
858cabdff1aSopenharmony_ci    const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain;
859cabdff1aSopenharmony_ci    AVFilmGrainParams *fgp;
860cabdff1aSopenharmony_ci    AVFilmGrainAOMParams *aom;
861cabdff1aSopenharmony_ci
862cabdff1aSopenharmony_ci    if (!film_grain->apply_grain)
863cabdff1aSopenharmony_ci        return 0;
864cabdff1aSopenharmony_ci
865cabdff1aSopenharmony_ci    fgp = av_film_grain_params_create_side_data(frame);
866cabdff1aSopenharmony_ci    if (!fgp)
867cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
868cabdff1aSopenharmony_ci
869cabdff1aSopenharmony_ci    fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
870cabdff1aSopenharmony_ci    fgp->seed = film_grain->grain_seed;
871cabdff1aSopenharmony_ci
872cabdff1aSopenharmony_ci    aom = &fgp->codec.aom;
873cabdff1aSopenharmony_ci    aom->chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma;
874cabdff1aSopenharmony_ci    aom->scaling_shift = film_grain->grain_scaling_minus_8 + 8;
875cabdff1aSopenharmony_ci    aom->ar_coeff_lag = film_grain->ar_coeff_lag;
876cabdff1aSopenharmony_ci    aom->ar_coeff_shift = film_grain->ar_coeff_shift_minus_6 + 6;
877cabdff1aSopenharmony_ci    aom->grain_scale_shift = film_grain->grain_scale_shift;
878cabdff1aSopenharmony_ci    aom->overlap_flag = film_grain->overlap_flag;
879cabdff1aSopenharmony_ci    aom->limit_output_range = film_grain->clip_to_restricted_range;
880cabdff1aSopenharmony_ci
881cabdff1aSopenharmony_ci    aom->num_y_points = film_grain->num_y_points;
882cabdff1aSopenharmony_ci    for (int i = 0; i < film_grain->num_y_points; i++) {
883cabdff1aSopenharmony_ci        aom->y_points[i][0] = film_grain->point_y_value[i];
884cabdff1aSopenharmony_ci        aom->y_points[i][1] = film_grain->point_y_scaling[i];
885cabdff1aSopenharmony_ci    }
886cabdff1aSopenharmony_ci    aom->num_uv_points[0] = film_grain->num_cb_points;
887cabdff1aSopenharmony_ci    for (int i = 0; i < film_grain->num_cb_points; i++) {
888cabdff1aSopenharmony_ci        aom->uv_points[0][i][0] = film_grain->point_cb_value[i];
889cabdff1aSopenharmony_ci        aom->uv_points[0][i][1] = film_grain->point_cb_scaling[i];
890cabdff1aSopenharmony_ci    }
891cabdff1aSopenharmony_ci    aom->num_uv_points[1] = film_grain->num_cr_points;
892cabdff1aSopenharmony_ci    for (int i = 0; i < film_grain->num_cr_points; i++) {
893cabdff1aSopenharmony_ci        aom->uv_points[1][i][0] = film_grain->point_cr_value[i];
894cabdff1aSopenharmony_ci        aom->uv_points[1][i][1] = film_grain->point_cr_scaling[i];
895cabdff1aSopenharmony_ci    }
896cabdff1aSopenharmony_ci
897cabdff1aSopenharmony_ci    for (int i = 0; i < 24; i++) {
898cabdff1aSopenharmony_ci        aom->ar_coeffs_y[i] = film_grain->ar_coeffs_y_plus_128[i] - 128;
899cabdff1aSopenharmony_ci    }
900cabdff1aSopenharmony_ci    for (int i = 0; i < 25; i++) {
901cabdff1aSopenharmony_ci        aom->ar_coeffs_uv[0][i] = film_grain->ar_coeffs_cb_plus_128[i] - 128;
902cabdff1aSopenharmony_ci        aom->ar_coeffs_uv[1][i] = film_grain->ar_coeffs_cr_plus_128[i] - 128;
903cabdff1aSopenharmony_ci    }
904cabdff1aSopenharmony_ci
905cabdff1aSopenharmony_ci    aom->uv_mult[0] = film_grain->cb_mult;
906cabdff1aSopenharmony_ci    aom->uv_mult[1] = film_grain->cr_mult;
907cabdff1aSopenharmony_ci    aom->uv_mult_luma[0] = film_grain->cb_luma_mult;
908cabdff1aSopenharmony_ci    aom->uv_mult_luma[1] = film_grain->cr_luma_mult;
909cabdff1aSopenharmony_ci    aom->uv_offset[0] = film_grain->cb_offset;
910cabdff1aSopenharmony_ci    aom->uv_offset[1] = film_grain->cr_offset;
911cabdff1aSopenharmony_ci
912cabdff1aSopenharmony_ci    return 0;
913cabdff1aSopenharmony_ci}
914cabdff1aSopenharmony_ci
915cabdff1aSopenharmony_cistatic int set_output_frame(AVCodecContext *avctx, AVFrame *frame,
916cabdff1aSopenharmony_ci                            const AVPacket *pkt, int *got_frame)
917cabdff1aSopenharmony_ci{
918cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
919cabdff1aSopenharmony_ci    const AVFrame *srcframe = s->cur_frame.f;
920cabdff1aSopenharmony_ci    int ret;
921cabdff1aSopenharmony_ci
922cabdff1aSopenharmony_ci    // TODO: all layers
923cabdff1aSopenharmony_ci    if (s->operating_point_idc &&
924cabdff1aSopenharmony_ci        av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id)
925cabdff1aSopenharmony_ci        return 0;
926cabdff1aSopenharmony_ci
927cabdff1aSopenharmony_ci    ret = av_frame_ref(frame, srcframe);
928cabdff1aSopenharmony_ci    if (ret < 0)
929cabdff1aSopenharmony_ci        return ret;
930cabdff1aSopenharmony_ci
931cabdff1aSopenharmony_ci    if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) {
932cabdff1aSopenharmony_ci        ret = export_film_grain(avctx, frame);
933cabdff1aSopenharmony_ci        if (ret < 0) {
934cabdff1aSopenharmony_ci            av_frame_unref(frame);
935cabdff1aSopenharmony_ci            return ret;
936cabdff1aSopenharmony_ci        }
937cabdff1aSopenharmony_ci    }
938cabdff1aSopenharmony_ci
939cabdff1aSopenharmony_ci    frame->pts = pkt->pts;
940cabdff1aSopenharmony_ci    frame->pkt_dts = pkt->dts;
941cabdff1aSopenharmony_ci    frame->pkt_size = pkt->size;
942cabdff1aSopenharmony_ci
943cabdff1aSopenharmony_ci    *got_frame = 1;
944cabdff1aSopenharmony_ci
945cabdff1aSopenharmony_ci    return 0;
946cabdff1aSopenharmony_ci}
947cabdff1aSopenharmony_ci
948cabdff1aSopenharmony_cistatic int update_reference_list(AVCodecContext *avctx)
949cabdff1aSopenharmony_ci{
950cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
951cabdff1aSopenharmony_ci    const AV1RawFrameHeader *header = s->raw_frame_header;
952cabdff1aSopenharmony_ci    int ret;
953cabdff1aSopenharmony_ci
954cabdff1aSopenharmony_ci    for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) {
955cabdff1aSopenharmony_ci        if (header->refresh_frame_flags & (1 << i)) {
956cabdff1aSopenharmony_ci            av1_frame_unref(avctx, &s->ref[i]);
957cabdff1aSopenharmony_ci            if ((ret = av1_frame_ref(avctx, &s->ref[i], &s->cur_frame)) < 0) {
958cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR,
959cabdff1aSopenharmony_ci                       "Failed to update frame %d in reference list\n", i);
960cabdff1aSopenharmony_ci                return ret;
961cabdff1aSopenharmony_ci            }
962cabdff1aSopenharmony_ci        }
963cabdff1aSopenharmony_ci    }
964cabdff1aSopenharmony_ci    return 0;
965cabdff1aSopenharmony_ci}
966cabdff1aSopenharmony_ci
967cabdff1aSopenharmony_cistatic int get_current_frame(AVCodecContext *avctx)
968cabdff1aSopenharmony_ci{
969cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
970cabdff1aSopenharmony_ci    int ret;
971cabdff1aSopenharmony_ci
972cabdff1aSopenharmony_ci    av1_frame_unref(avctx, &s->cur_frame);
973cabdff1aSopenharmony_ci
974cabdff1aSopenharmony_ci    s->cur_frame.header_ref = av_buffer_ref(s->header_ref);
975cabdff1aSopenharmony_ci    if (!s->cur_frame.header_ref)
976cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
977cabdff1aSopenharmony_ci
978cabdff1aSopenharmony_ci    s->cur_frame.raw_frame_header = s->raw_frame_header;
979cabdff1aSopenharmony_ci
980cabdff1aSopenharmony_ci    ret = init_tile_data(s);
981cabdff1aSopenharmony_ci    if (ret < 0) {
982cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Failed to init tile data.\n");
983cabdff1aSopenharmony_ci        return ret;
984cabdff1aSopenharmony_ci    }
985cabdff1aSopenharmony_ci
986cabdff1aSopenharmony_ci    if ((avctx->skip_frame >= AVDISCARD_NONINTRA &&
987cabdff1aSopenharmony_ci            (s->raw_frame_header->frame_type != AV1_FRAME_KEY &&
988cabdff1aSopenharmony_ci             s->raw_frame_header->frame_type != AV1_FRAME_INTRA_ONLY)) ||
989cabdff1aSopenharmony_ci        (avctx->skip_frame >= AVDISCARD_NONKEY   &&
990cabdff1aSopenharmony_ci             s->raw_frame_header->frame_type != AV1_FRAME_KEY) ||
991cabdff1aSopenharmony_ci        avctx->skip_frame >= AVDISCARD_ALL)
992cabdff1aSopenharmony_ci        return 0;
993cabdff1aSopenharmony_ci
994cabdff1aSopenharmony_ci    ret = av1_frame_alloc(avctx, &s->cur_frame);
995cabdff1aSopenharmony_ci    if (ret < 0) {
996cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
997cabdff1aSopenharmony_ci               "Failed to allocate space for current frame.\n");
998cabdff1aSopenharmony_ci        return ret;
999cabdff1aSopenharmony_ci    }
1000cabdff1aSopenharmony_ci
1001cabdff1aSopenharmony_ci    global_motion_params(s);
1002cabdff1aSopenharmony_ci    skip_mode_params(s);
1003cabdff1aSopenharmony_ci    coded_lossless_param(s);
1004cabdff1aSopenharmony_ci    load_grain_params(s);
1005cabdff1aSopenharmony_ci
1006cabdff1aSopenharmony_ci    return ret;
1007cabdff1aSopenharmony_ci}
1008cabdff1aSopenharmony_ci
1009cabdff1aSopenharmony_cistatic int av1_decode_frame(AVCodecContext *avctx, AVFrame *frame,
1010cabdff1aSopenharmony_ci                            int *got_frame, AVPacket *pkt)
1011cabdff1aSopenharmony_ci{
1012cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
1013cabdff1aSopenharmony_ci    AV1RawTileGroup *raw_tile_group = NULL;
1014cabdff1aSopenharmony_ci    int ret;
1015cabdff1aSopenharmony_ci
1016cabdff1aSopenharmony_ci    ret = ff_cbs_read_packet(s->cbc, &s->current_obu, pkt);
1017cabdff1aSopenharmony_ci    if (ret < 0) {
1018cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Failed to read packet.\n");
1019cabdff1aSopenharmony_ci        goto end;
1020cabdff1aSopenharmony_ci    }
1021cabdff1aSopenharmony_ci    av_log(avctx, AV_LOG_DEBUG, "Total obu for this frame:%d.\n",
1022cabdff1aSopenharmony_ci           s->current_obu.nb_units);
1023cabdff1aSopenharmony_ci
1024cabdff1aSopenharmony_ci    for (int i = 0; i < s->current_obu.nb_units; i++) {
1025cabdff1aSopenharmony_ci        CodedBitstreamUnit *unit = &s->current_obu.units[i];
1026cabdff1aSopenharmony_ci        AV1RawOBU *obu = unit->content;
1027cabdff1aSopenharmony_ci        const AV1RawOBUHeader *header;
1028cabdff1aSopenharmony_ci
1029cabdff1aSopenharmony_ci        if (!obu)
1030cabdff1aSopenharmony_ci            continue;
1031cabdff1aSopenharmony_ci
1032cabdff1aSopenharmony_ci        header = &obu->header;
1033cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_DEBUG, "Obu idx:%d, obu type:%d.\n", i, unit->type);
1034cabdff1aSopenharmony_ci
1035cabdff1aSopenharmony_ci        switch (unit->type) {
1036cabdff1aSopenharmony_ci        case AV1_OBU_SEQUENCE_HEADER:
1037cabdff1aSopenharmony_ci            av_buffer_unref(&s->seq_ref);
1038cabdff1aSopenharmony_ci            s->seq_ref = av_buffer_ref(unit->content_ref);
1039cabdff1aSopenharmony_ci            if (!s->seq_ref) {
1040cabdff1aSopenharmony_ci                ret = AVERROR(ENOMEM);
1041cabdff1aSopenharmony_ci                goto end;
1042cabdff1aSopenharmony_ci            }
1043cabdff1aSopenharmony_ci
1044cabdff1aSopenharmony_ci            s->raw_seq = &obu->obu.sequence_header;
1045cabdff1aSopenharmony_ci
1046cabdff1aSopenharmony_ci            ret = set_context_with_sequence(avctx, s->raw_seq);
1047cabdff1aSopenharmony_ci            if (ret < 0) {
1048cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR, "Failed to set context.\n");
1049cabdff1aSopenharmony_ci                s->raw_seq = NULL;
1050cabdff1aSopenharmony_ci                goto end;
1051cabdff1aSopenharmony_ci            }
1052cabdff1aSopenharmony_ci
1053cabdff1aSopenharmony_ci            s->operating_point_idc = s->raw_seq->operating_point_idc[s->operating_point];
1054cabdff1aSopenharmony_ci
1055cabdff1aSopenharmony_ci            if (s->pix_fmt == AV_PIX_FMT_NONE) {
1056cabdff1aSopenharmony_ci                ret = get_pixel_format(avctx);
1057cabdff1aSopenharmony_ci                if (ret < 0) {
1058cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR,
1059cabdff1aSopenharmony_ci                           "Failed to get pixel format.\n");
1060cabdff1aSopenharmony_ci                    s->raw_seq = NULL;
1061cabdff1aSopenharmony_ci                    goto end;
1062cabdff1aSopenharmony_ci                }
1063cabdff1aSopenharmony_ci            }
1064cabdff1aSopenharmony_ci
1065cabdff1aSopenharmony_ci            if (avctx->hwaccel && avctx->hwaccel->decode_params) {
1066cabdff1aSopenharmony_ci                ret = avctx->hwaccel->decode_params(avctx, unit->type, unit->data,
1067cabdff1aSopenharmony_ci                                                    unit->data_size);
1068cabdff1aSopenharmony_ci                if (ret < 0) {
1069cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR, "HW accel decode params fail.\n");
1070cabdff1aSopenharmony_ci                    s->raw_seq = NULL;
1071cabdff1aSopenharmony_ci                    goto end;
1072cabdff1aSopenharmony_ci                }
1073cabdff1aSopenharmony_ci            }
1074cabdff1aSopenharmony_ci            break;
1075cabdff1aSopenharmony_ci        case AV1_OBU_REDUNDANT_FRAME_HEADER:
1076cabdff1aSopenharmony_ci            if (s->raw_frame_header)
1077cabdff1aSopenharmony_ci                break;
1078cabdff1aSopenharmony_ci        // fall-through
1079cabdff1aSopenharmony_ci        case AV1_OBU_FRAME:
1080cabdff1aSopenharmony_ci        case AV1_OBU_FRAME_HEADER:
1081cabdff1aSopenharmony_ci            if (!s->raw_seq) {
1082cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR, "Missing Sequence Header.\n");
1083cabdff1aSopenharmony_ci                ret = AVERROR_INVALIDDATA;
1084cabdff1aSopenharmony_ci                goto end;
1085cabdff1aSopenharmony_ci            }
1086cabdff1aSopenharmony_ci
1087cabdff1aSopenharmony_ci            av_buffer_unref(&s->header_ref);
1088cabdff1aSopenharmony_ci            s->header_ref = av_buffer_ref(unit->content_ref);
1089cabdff1aSopenharmony_ci            if (!s->header_ref) {
1090cabdff1aSopenharmony_ci                ret = AVERROR(ENOMEM);
1091cabdff1aSopenharmony_ci                goto end;
1092cabdff1aSopenharmony_ci            }
1093cabdff1aSopenharmony_ci
1094cabdff1aSopenharmony_ci            if (unit->type == AV1_OBU_FRAME)
1095cabdff1aSopenharmony_ci                s->raw_frame_header = &obu->obu.frame.header;
1096cabdff1aSopenharmony_ci            else
1097cabdff1aSopenharmony_ci                s->raw_frame_header = &obu->obu.frame_header;
1098cabdff1aSopenharmony_ci
1099cabdff1aSopenharmony_ci            if (s->raw_frame_header->show_existing_frame) {
1100cabdff1aSopenharmony_ci                av1_frame_unref(avctx, &s->cur_frame);
1101cabdff1aSopenharmony_ci
1102cabdff1aSopenharmony_ci                ret = av1_frame_ref(avctx, &s->cur_frame,
1103cabdff1aSopenharmony_ci                                    &s->ref[s->raw_frame_header->frame_to_show_map_idx]);
1104cabdff1aSopenharmony_ci                if (ret < 0) {
1105cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR, "Failed to get reference frame.\n");
1106cabdff1aSopenharmony_ci                    goto end;
1107cabdff1aSopenharmony_ci                }
1108cabdff1aSopenharmony_ci
1109cabdff1aSopenharmony_ci                ret = update_reference_list(avctx);
1110cabdff1aSopenharmony_ci                if (ret < 0) {
1111cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR, "Failed to update reference list.\n");
1112cabdff1aSopenharmony_ci                    goto end;
1113cabdff1aSopenharmony_ci                }
1114cabdff1aSopenharmony_ci
1115cabdff1aSopenharmony_ci                if (s->cur_frame.f->buf[0]) {
1116cabdff1aSopenharmony_ci                    ret = set_output_frame(avctx, frame, pkt, got_frame);
1117cabdff1aSopenharmony_ci                    if (ret < 0)
1118cabdff1aSopenharmony_ci                        av_log(avctx, AV_LOG_ERROR, "Set output frame error.\n");
1119cabdff1aSopenharmony_ci                }
1120cabdff1aSopenharmony_ci
1121cabdff1aSopenharmony_ci                s->raw_frame_header = NULL;
1122cabdff1aSopenharmony_ci
1123cabdff1aSopenharmony_ci                goto end;
1124cabdff1aSopenharmony_ci            }
1125cabdff1aSopenharmony_ci
1126cabdff1aSopenharmony_ci            ret = get_current_frame(avctx);
1127cabdff1aSopenharmony_ci            if (ret < 0) {
1128cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR, "Get current frame error\n");
1129cabdff1aSopenharmony_ci                goto end;
1130cabdff1aSopenharmony_ci            }
1131cabdff1aSopenharmony_ci
1132cabdff1aSopenharmony_ci            s->cur_frame.spatial_id  = header->spatial_id;
1133cabdff1aSopenharmony_ci            s->cur_frame.temporal_id = header->temporal_id;
1134cabdff1aSopenharmony_ci
1135cabdff1aSopenharmony_ci            if (avctx->hwaccel && s->cur_frame.f->buf[0]) {
1136cabdff1aSopenharmony_ci                ret = avctx->hwaccel->start_frame(avctx, unit->data,
1137cabdff1aSopenharmony_ci                                                  unit->data_size);
1138cabdff1aSopenharmony_ci                if (ret < 0) {
1139cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR, "HW accel start frame fail.\n");
1140cabdff1aSopenharmony_ci                    goto end;
1141cabdff1aSopenharmony_ci                }
1142cabdff1aSopenharmony_ci            }
1143cabdff1aSopenharmony_ci            if (unit->type != AV1_OBU_FRAME)
1144cabdff1aSopenharmony_ci                break;
1145cabdff1aSopenharmony_ci        // fall-through
1146cabdff1aSopenharmony_ci        case AV1_OBU_TILE_GROUP:
1147cabdff1aSopenharmony_ci            if (!s->raw_frame_header) {
1148cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR, "Missing Frame Header.\n");
1149cabdff1aSopenharmony_ci                ret = AVERROR_INVALIDDATA;
1150cabdff1aSopenharmony_ci                goto end;
1151cabdff1aSopenharmony_ci            }
1152cabdff1aSopenharmony_ci
1153cabdff1aSopenharmony_ci            if (unit->type == AV1_OBU_FRAME)
1154cabdff1aSopenharmony_ci                raw_tile_group = &obu->obu.frame.tile_group;
1155cabdff1aSopenharmony_ci            else
1156cabdff1aSopenharmony_ci                raw_tile_group = &obu->obu.tile_group;
1157cabdff1aSopenharmony_ci
1158cabdff1aSopenharmony_ci            ret = get_tiles_info(avctx, raw_tile_group);
1159cabdff1aSopenharmony_ci            if (ret < 0)
1160cabdff1aSopenharmony_ci                goto end;
1161cabdff1aSopenharmony_ci
1162cabdff1aSopenharmony_ci            if (avctx->hwaccel && s->cur_frame.f->buf[0]) {
1163cabdff1aSopenharmony_ci                ret = avctx->hwaccel->decode_slice(avctx,
1164cabdff1aSopenharmony_ci                                                   raw_tile_group->tile_data.data,
1165cabdff1aSopenharmony_ci                                                   raw_tile_group->tile_data.data_size);
1166cabdff1aSopenharmony_ci                if (ret < 0) {
1167cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR,
1168cabdff1aSopenharmony_ci                           "HW accel decode slice fail.\n");
1169cabdff1aSopenharmony_ci                    goto end;
1170cabdff1aSopenharmony_ci                }
1171cabdff1aSopenharmony_ci            }
1172cabdff1aSopenharmony_ci            break;
1173cabdff1aSopenharmony_ci        case AV1_OBU_TILE_LIST:
1174cabdff1aSopenharmony_ci        case AV1_OBU_TEMPORAL_DELIMITER:
1175cabdff1aSopenharmony_ci        case AV1_OBU_PADDING:
1176cabdff1aSopenharmony_ci        case AV1_OBU_METADATA:
1177cabdff1aSopenharmony_ci            break;
1178cabdff1aSopenharmony_ci        default:
1179cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_DEBUG,
1180cabdff1aSopenharmony_ci                   "Unknown obu type: %d (%"SIZE_SPECIFIER" bits).\n",
1181cabdff1aSopenharmony_ci                   unit->type, unit->data_size);
1182cabdff1aSopenharmony_ci        }
1183cabdff1aSopenharmony_ci
1184cabdff1aSopenharmony_ci        if (raw_tile_group && (s->tile_num == raw_tile_group->tg_end + 1)) {
1185cabdff1aSopenharmony_ci            if (avctx->hwaccel && s->cur_frame.f->buf[0]) {
1186cabdff1aSopenharmony_ci                ret = avctx->hwaccel->end_frame(avctx);
1187cabdff1aSopenharmony_ci                if (ret < 0) {
1188cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR, "HW accel end frame fail.\n");
1189cabdff1aSopenharmony_ci                    goto end;
1190cabdff1aSopenharmony_ci                }
1191cabdff1aSopenharmony_ci            }
1192cabdff1aSopenharmony_ci
1193cabdff1aSopenharmony_ci            ret = update_reference_list(avctx);
1194cabdff1aSopenharmony_ci            if (ret < 0) {
1195cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR, "Failed to update reference list.\n");
1196cabdff1aSopenharmony_ci                goto end;
1197cabdff1aSopenharmony_ci            }
1198cabdff1aSopenharmony_ci
1199cabdff1aSopenharmony_ci            if (s->raw_frame_header->show_frame && s->cur_frame.f->buf[0]) {
1200cabdff1aSopenharmony_ci                ret = set_output_frame(avctx, frame, pkt, got_frame);
1201cabdff1aSopenharmony_ci                if (ret < 0) {
1202cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_ERROR, "Set output frame error\n");
1203cabdff1aSopenharmony_ci                    goto end;
1204cabdff1aSopenharmony_ci                }
1205cabdff1aSopenharmony_ci            }
1206cabdff1aSopenharmony_ci            raw_tile_group = NULL;
1207cabdff1aSopenharmony_ci            s->raw_frame_header = NULL;
1208cabdff1aSopenharmony_ci        }
1209cabdff1aSopenharmony_ci    }
1210cabdff1aSopenharmony_ci
1211cabdff1aSopenharmony_ciend:
1212cabdff1aSopenharmony_ci    ff_cbs_fragment_reset(&s->current_obu);
1213cabdff1aSopenharmony_ci    if (ret < 0)
1214cabdff1aSopenharmony_ci        s->raw_frame_header = NULL;
1215cabdff1aSopenharmony_ci    return ret;
1216cabdff1aSopenharmony_ci}
1217cabdff1aSopenharmony_ci
1218cabdff1aSopenharmony_cistatic void av1_decode_flush(AVCodecContext *avctx)
1219cabdff1aSopenharmony_ci{
1220cabdff1aSopenharmony_ci    AV1DecContext *s = avctx->priv_data;
1221cabdff1aSopenharmony_ci
1222cabdff1aSopenharmony_ci    for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++)
1223cabdff1aSopenharmony_ci        av1_frame_unref(avctx, &s->ref[i]);
1224cabdff1aSopenharmony_ci
1225cabdff1aSopenharmony_ci    av1_frame_unref(avctx, &s->cur_frame);
1226cabdff1aSopenharmony_ci    s->operating_point_idc = 0;
1227cabdff1aSopenharmony_ci    s->raw_frame_header = NULL;
1228cabdff1aSopenharmony_ci    s->raw_seq = NULL;
1229cabdff1aSopenharmony_ci
1230cabdff1aSopenharmony_ci    ff_cbs_flush(s->cbc);
1231cabdff1aSopenharmony_ci}
1232cabdff1aSopenharmony_ci
1233cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(AV1DecContext, x)
1234cabdff1aSopenharmony_ci#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1235cabdff1aSopenharmony_cistatic const AVOption av1_options[] = {
1236cabdff1aSopenharmony_ci    { "operating_point",  "Select an operating point of the scalable bitstream",
1237cabdff1aSopenharmony_ci                          OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, AV1_MAX_OPERATING_POINTS - 1, VD },
1238cabdff1aSopenharmony_ci    { NULL }
1239cabdff1aSopenharmony_ci};
1240cabdff1aSopenharmony_ci
1241cabdff1aSopenharmony_cistatic const AVClass av1_class = {
1242cabdff1aSopenharmony_ci    .class_name = "AV1 decoder",
1243cabdff1aSopenharmony_ci    .item_name  = av_default_item_name,
1244cabdff1aSopenharmony_ci    .option     = av1_options,
1245cabdff1aSopenharmony_ci    .version    = LIBAVUTIL_VERSION_INT,
1246cabdff1aSopenharmony_ci};
1247cabdff1aSopenharmony_ci
1248cabdff1aSopenharmony_ciconst FFCodec ff_av1_decoder = {
1249cabdff1aSopenharmony_ci    .p.name                = "av1",
1250cabdff1aSopenharmony_ci    .p.long_name           = NULL_IF_CONFIG_SMALL("Alliance for Open Media AV1"),
1251cabdff1aSopenharmony_ci    .p.type                = AVMEDIA_TYPE_VIDEO,
1252cabdff1aSopenharmony_ci    .p.id                  = AV_CODEC_ID_AV1,
1253cabdff1aSopenharmony_ci    .priv_data_size        = sizeof(AV1DecContext),
1254cabdff1aSopenharmony_ci    .init                  = av1_decode_init,
1255cabdff1aSopenharmony_ci    .close                 = av1_decode_free,
1256cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(av1_decode_frame),
1257cabdff1aSopenharmony_ci    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING,
1258cabdff1aSopenharmony_ci    .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE |
1259cabdff1aSopenharmony_ci                             FF_CODEC_CAP_INIT_CLEANUP |
1260cabdff1aSopenharmony_ci                             FF_CODEC_CAP_SETS_PKT_DTS,
1261cabdff1aSopenharmony_ci    .flush                 = av1_decode_flush,
1262cabdff1aSopenharmony_ci    .p.profiles            = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
1263cabdff1aSopenharmony_ci    .p.priv_class          = &av1_class,
1264cabdff1aSopenharmony_ci    .bsfs                  = "av1_frame_split",
1265cabdff1aSopenharmony_ci    .hw_configs            = (const AVCodecHWConfigInternal *const []) {
1266cabdff1aSopenharmony_ci#if CONFIG_AV1_DXVA2_HWACCEL
1267cabdff1aSopenharmony_ci        HWACCEL_DXVA2(av1),
1268cabdff1aSopenharmony_ci#endif
1269cabdff1aSopenharmony_ci#if CONFIG_AV1_D3D11VA_HWACCEL
1270cabdff1aSopenharmony_ci        HWACCEL_D3D11VA(av1),
1271cabdff1aSopenharmony_ci#endif
1272cabdff1aSopenharmony_ci#if CONFIG_AV1_D3D11VA2_HWACCEL
1273cabdff1aSopenharmony_ci        HWACCEL_D3D11VA2(av1),
1274cabdff1aSopenharmony_ci#endif
1275cabdff1aSopenharmony_ci#if CONFIG_AV1_NVDEC_HWACCEL
1276cabdff1aSopenharmony_ci        HWACCEL_NVDEC(av1),
1277cabdff1aSopenharmony_ci#endif
1278cabdff1aSopenharmony_ci#if CONFIG_AV1_VAAPI_HWACCEL
1279cabdff1aSopenharmony_ci        HWACCEL_VAAPI(av1),
1280cabdff1aSopenharmony_ci#endif
1281cabdff1aSopenharmony_ci#if CONFIG_AV1_VDPAU_HWACCEL
1282cabdff1aSopenharmony_ci        HWACCEL_VDPAU(av1),
1283cabdff1aSopenharmony_ci#endif
1284cabdff1aSopenharmony_ci
1285cabdff1aSopenharmony_ci        NULL
1286cabdff1aSopenharmony_ci    },
1287cabdff1aSopenharmony_ci};
1288