1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (C) 2016 Open Broadcast Systems Ltd.
3cabdff1aSopenharmony_ci * Author        2016 Rostislav Pehlivanov <atomnuker@gmail.com>
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h"
23cabdff1aSopenharmony_ci#include "libavutil/opt.h"
24cabdff1aSopenharmony_ci#include "libavutil/version.h"
25cabdff1aSopenharmony_ci#include "codec_internal.h"
26cabdff1aSopenharmony_ci#include "dirac.h"
27cabdff1aSopenharmony_ci#include "encode.h"
28cabdff1aSopenharmony_ci#include "put_bits.h"
29cabdff1aSopenharmony_ci#include "version.h"
30cabdff1aSopenharmony_ci
31cabdff1aSopenharmony_ci#include "vc2enc_dwt.h"
32cabdff1aSopenharmony_ci#include "diractab.h"
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_ci/* The limited size resolution of each slice forces us to do this */
35cabdff1aSopenharmony_ci#define SSIZE_ROUND(b) (FFALIGN((b), s->size_scaler) + 4 + s->prefix_bytes)
36cabdff1aSopenharmony_ci
37cabdff1aSopenharmony_ci/* Decides the cutoff point in # of slices to distribute the leftover bytes */
38cabdff1aSopenharmony_ci#define SLICE_REDIST_TOTAL 150
39cabdff1aSopenharmony_ci
40cabdff1aSopenharmony_citypedef struct VC2BaseVideoFormat {
41cabdff1aSopenharmony_ci    enum AVPixelFormat pix_fmt;
42cabdff1aSopenharmony_ci    AVRational time_base;
43cabdff1aSopenharmony_ci    int width, height, interlaced, level;
44cabdff1aSopenharmony_ci    const char *name;
45cabdff1aSopenharmony_ci} VC2BaseVideoFormat;
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_cistatic const VC2BaseVideoFormat base_video_fmts[] = {
48cabdff1aSopenharmony_ci    { 0 }, /* Custom format, here just to make indexing equal to base_vf */
49cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV420P,   { 1001, 15000 },  176,  120, 0, 1,     "QSIF525" },
50cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV420P,   {    2,    25 },  176,  144, 0, 1,     "QCIF"    },
51cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV420P,   { 1001, 15000 },  352,  240, 0, 1,     "SIF525"  },
52cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV420P,   {    2,    25 },  352,  288, 0, 1,     "CIF"     },
53cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV420P,   { 1001, 15000 },  704,  480, 0, 1,     "4SIF525" },
54cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV420P,   {    2,    25 },  704,  576, 0, 1,     "4CIF"    },
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 30000 },  720,  480, 1, 2,   "SD480I-60" },
57cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, {    1,    25 },  720,  576, 1, 2,   "SD576I-50" },
58cabdff1aSopenharmony_ci
59cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 1280,  720, 0, 3,  "HD720P-60"  },
60cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, {    1,    50 }, 1280,  720, 0, 3,  "HD720P-50"  },
61cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 30000 }, 1920, 1080, 1, 3,  "HD1080I-60" },
62cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, {    1,    25 }, 1920, 1080, 1, 3,  "HD1080I-50" },
63cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 1920, 1080, 0, 3,  "HD1080P-60" },
64cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, {    1,    50 }, 1920, 1080, 0, 3,  "HD1080P-50" },
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV444P12, {    1,    24 }, 2048, 1080, 0, 4,        "DC2K" },
67cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV444P12, {    1,    24 }, 4096, 2160, 0, 5,        "DC4K" },
68cabdff1aSopenharmony_ci
69cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 3840, 2160, 0, 6, "UHDTV 4K-60" },
70cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, {    1,    50 }, 3840, 2160, 0, 6, "UHDTV 4K-50" },
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 7680, 4320, 0, 7, "UHDTV 8K-60" },
73cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, {    1,    50 }, 7680, 4320, 0, 7, "UHDTV 8K-50" },
74cabdff1aSopenharmony_ci
75cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 24000 }, 1920, 1080, 0, 3,  "HD1080P-24" },
76cabdff1aSopenharmony_ci    { AV_PIX_FMT_YUV422P10, { 1001, 30000 },  720,  486, 1, 2,  "SD Pro486"  },
77cabdff1aSopenharmony_ci};
78cabdff1aSopenharmony_cistatic const int base_video_fmts_len = FF_ARRAY_ELEMS(base_video_fmts);
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_cienum VC2_QM {
81cabdff1aSopenharmony_ci    VC2_QM_DEF = 0,
82cabdff1aSopenharmony_ci    VC2_QM_COL,
83cabdff1aSopenharmony_ci    VC2_QM_FLAT,
84cabdff1aSopenharmony_ci
85cabdff1aSopenharmony_ci    VC2_QM_NB
86cabdff1aSopenharmony_ci};
87cabdff1aSopenharmony_ci
88cabdff1aSopenharmony_citypedef struct SubBand {
89cabdff1aSopenharmony_ci    dwtcoef *buf;
90cabdff1aSopenharmony_ci    ptrdiff_t stride;
91cabdff1aSopenharmony_ci    int width;
92cabdff1aSopenharmony_ci    int height;
93cabdff1aSopenharmony_ci} SubBand;
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_citypedef struct Plane {
96cabdff1aSopenharmony_ci    SubBand band[MAX_DWT_LEVELS][4];
97cabdff1aSopenharmony_ci    dwtcoef *coef_buf;
98cabdff1aSopenharmony_ci    int width;
99cabdff1aSopenharmony_ci    int height;
100cabdff1aSopenharmony_ci    int dwt_width;
101cabdff1aSopenharmony_ci    int dwt_height;
102cabdff1aSopenharmony_ci    ptrdiff_t coef_stride;
103cabdff1aSopenharmony_ci} Plane;
104cabdff1aSopenharmony_ci
105cabdff1aSopenharmony_citypedef struct SliceArgs {
106cabdff1aSopenharmony_ci    PutBitContext pb;
107cabdff1aSopenharmony_ci    int cache[DIRAC_MAX_QUANT_INDEX];
108cabdff1aSopenharmony_ci    void *ctx;
109cabdff1aSopenharmony_ci    int x;
110cabdff1aSopenharmony_ci    int y;
111cabdff1aSopenharmony_ci    int quant_idx;
112cabdff1aSopenharmony_ci    int bits_ceil;
113cabdff1aSopenharmony_ci    int bits_floor;
114cabdff1aSopenharmony_ci    int bytes;
115cabdff1aSopenharmony_ci} SliceArgs;
116cabdff1aSopenharmony_ci
117cabdff1aSopenharmony_citypedef struct TransformArgs {
118cabdff1aSopenharmony_ci    void *ctx;
119cabdff1aSopenharmony_ci    Plane *plane;
120cabdff1aSopenharmony_ci    void *idata;
121cabdff1aSopenharmony_ci    ptrdiff_t istride;
122cabdff1aSopenharmony_ci    int field;
123cabdff1aSopenharmony_ci    VC2TransformContext t;
124cabdff1aSopenharmony_ci} TransformArgs;
125cabdff1aSopenharmony_ci
126cabdff1aSopenharmony_citypedef struct VC2EncContext {
127cabdff1aSopenharmony_ci    AVClass *av_class;
128cabdff1aSopenharmony_ci    PutBitContext pb;
129cabdff1aSopenharmony_ci    Plane plane[3];
130cabdff1aSopenharmony_ci    AVCodecContext *avctx;
131cabdff1aSopenharmony_ci    DiracVersionInfo ver;
132cabdff1aSopenharmony_ci
133cabdff1aSopenharmony_ci    SliceArgs *slice_args;
134cabdff1aSopenharmony_ci    TransformArgs transform_args[3];
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci    /* For conversion from unsigned pixel values to signed */
137cabdff1aSopenharmony_ci    int diff_offset;
138cabdff1aSopenharmony_ci    int bpp;
139cabdff1aSopenharmony_ci    int bpp_idx;
140cabdff1aSopenharmony_ci
141cabdff1aSopenharmony_ci    /* Picture number */
142cabdff1aSopenharmony_ci    uint32_t picture_number;
143cabdff1aSopenharmony_ci
144cabdff1aSopenharmony_ci    /* Base video format */
145cabdff1aSopenharmony_ci    int base_vf;
146cabdff1aSopenharmony_ci    int level;
147cabdff1aSopenharmony_ci    int profile;
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_ci    /* Quantization matrix */
150cabdff1aSopenharmony_ci    uint8_t quant[MAX_DWT_LEVELS][4];
151cabdff1aSopenharmony_ci    int custom_quant_matrix;
152cabdff1aSopenharmony_ci
153cabdff1aSopenharmony_ci    /* Division LUT */
154cabdff1aSopenharmony_ci    uint32_t qmagic_lut[116][2];
155cabdff1aSopenharmony_ci
156cabdff1aSopenharmony_ci    int num_x; /* #slices horizontally */
157cabdff1aSopenharmony_ci    int num_y; /* #slices vertically */
158cabdff1aSopenharmony_ci    int prefix_bytes;
159cabdff1aSopenharmony_ci    int size_scaler;
160cabdff1aSopenharmony_ci    int chroma_x_shift;
161cabdff1aSopenharmony_ci    int chroma_y_shift;
162cabdff1aSopenharmony_ci
163cabdff1aSopenharmony_ci    /* Rate control stuff */
164cabdff1aSopenharmony_ci    int frame_max_bytes;
165cabdff1aSopenharmony_ci    int slice_max_bytes;
166cabdff1aSopenharmony_ci    int slice_min_bytes;
167cabdff1aSopenharmony_ci    int q_ceil;
168cabdff1aSopenharmony_ci    int q_avg;
169cabdff1aSopenharmony_ci
170cabdff1aSopenharmony_ci    /* Options */
171cabdff1aSopenharmony_ci    double tolerance;
172cabdff1aSopenharmony_ci    int wavelet_idx;
173cabdff1aSopenharmony_ci    int wavelet_depth;
174cabdff1aSopenharmony_ci    int strict_compliance;
175cabdff1aSopenharmony_ci    int slice_height;
176cabdff1aSopenharmony_ci    int slice_width;
177cabdff1aSopenharmony_ci    int interlaced;
178cabdff1aSopenharmony_ci    enum VC2_QM quant_matrix;
179cabdff1aSopenharmony_ci
180cabdff1aSopenharmony_ci    /* Parse code state */
181cabdff1aSopenharmony_ci    uint32_t next_parse_offset;
182cabdff1aSopenharmony_ci    enum DiracParseCodes last_parse_code;
183cabdff1aSopenharmony_ci} VC2EncContext;
184cabdff1aSopenharmony_ci
185cabdff1aSopenharmony_cistatic av_always_inline void put_vc2_ue_uint(PutBitContext *pb, uint32_t val)
186cabdff1aSopenharmony_ci{
187cabdff1aSopenharmony_ci    int i;
188cabdff1aSopenharmony_ci    int pbits = 0, bits = 0, topbit = 1, maxval = 1;
189cabdff1aSopenharmony_ci
190cabdff1aSopenharmony_ci    if (!val++) {
191cabdff1aSopenharmony_ci        put_bits(pb, 1, 1);
192cabdff1aSopenharmony_ci        return;
193cabdff1aSopenharmony_ci    }
194cabdff1aSopenharmony_ci
195cabdff1aSopenharmony_ci    while (val > maxval) {
196cabdff1aSopenharmony_ci        topbit <<= 1;
197cabdff1aSopenharmony_ci        maxval <<= 1;
198cabdff1aSopenharmony_ci        maxval |=  1;
199cabdff1aSopenharmony_ci    }
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    bits = ff_log2(topbit);
202cabdff1aSopenharmony_ci
203cabdff1aSopenharmony_ci    for (i = 0; i < bits; i++) {
204cabdff1aSopenharmony_ci        topbit >>= 1;
205cabdff1aSopenharmony_ci        pbits <<= 2;
206cabdff1aSopenharmony_ci        if (val & topbit)
207cabdff1aSopenharmony_ci            pbits |= 0x1;
208cabdff1aSopenharmony_ci    }
209cabdff1aSopenharmony_ci
210cabdff1aSopenharmony_ci    put_bits(pb, bits*2 + 1, (pbits << 1) | 1);
211cabdff1aSopenharmony_ci}
212cabdff1aSopenharmony_ci
213cabdff1aSopenharmony_cistatic av_always_inline int count_vc2_ue_uint(uint32_t val)
214cabdff1aSopenharmony_ci{
215cabdff1aSopenharmony_ci    int topbit = 1, maxval = 1;
216cabdff1aSopenharmony_ci
217cabdff1aSopenharmony_ci    if (!val++)
218cabdff1aSopenharmony_ci        return 1;
219cabdff1aSopenharmony_ci
220cabdff1aSopenharmony_ci    while (val > maxval) {
221cabdff1aSopenharmony_ci        topbit <<= 1;
222cabdff1aSopenharmony_ci        maxval <<= 1;
223cabdff1aSopenharmony_ci        maxval |=  1;
224cabdff1aSopenharmony_ci    }
225cabdff1aSopenharmony_ci
226cabdff1aSopenharmony_ci    return ff_log2(topbit)*2 + 1;
227cabdff1aSopenharmony_ci}
228cabdff1aSopenharmony_ci
229cabdff1aSopenharmony_ci/* VC-2 10.4 - parse_info() */
230cabdff1aSopenharmony_cistatic void encode_parse_info(VC2EncContext *s, enum DiracParseCodes pcode)
231cabdff1aSopenharmony_ci{
232cabdff1aSopenharmony_ci    uint32_t cur_pos, dist;
233cabdff1aSopenharmony_ci
234cabdff1aSopenharmony_ci    align_put_bits(&s->pb);
235cabdff1aSopenharmony_ci
236cabdff1aSopenharmony_ci    cur_pos = put_bits_count(&s->pb) >> 3;
237cabdff1aSopenharmony_ci
238cabdff1aSopenharmony_ci    /* Magic string */
239cabdff1aSopenharmony_ci    ff_put_string(&s->pb, "BBCD", 0);
240cabdff1aSopenharmony_ci
241cabdff1aSopenharmony_ci    /* Parse code */
242cabdff1aSopenharmony_ci    put_bits(&s->pb, 8, pcode);
243cabdff1aSopenharmony_ci
244cabdff1aSopenharmony_ci    /* Next parse offset */
245cabdff1aSopenharmony_ci    dist = cur_pos - s->next_parse_offset;
246cabdff1aSopenharmony_ci    AV_WB32(s->pb.buf + s->next_parse_offset + 5, dist);
247cabdff1aSopenharmony_ci    s->next_parse_offset = cur_pos;
248cabdff1aSopenharmony_ci    put_bits32(&s->pb, pcode == DIRAC_PCODE_END_SEQ ? 13 : 0);
249cabdff1aSopenharmony_ci
250cabdff1aSopenharmony_ci    /* Last parse offset */
251cabdff1aSopenharmony_ci    put_bits32(&s->pb, s->last_parse_code == DIRAC_PCODE_END_SEQ ? 13 : dist);
252cabdff1aSopenharmony_ci
253cabdff1aSopenharmony_ci    s->last_parse_code = pcode;
254cabdff1aSopenharmony_ci}
255cabdff1aSopenharmony_ci
256cabdff1aSopenharmony_ci/* VC-2 11.1 - parse_parameters()
257cabdff1aSopenharmony_ci * The level dictates what the decoder should expect in terms of resolution
258cabdff1aSopenharmony_ci * and allows it to quickly reject whatever it can't support. Remember,
259cabdff1aSopenharmony_ci * this codec kinda targets cheapo FPGAs without much memory. Unfortunately
260cabdff1aSopenharmony_ci * it also limits us greatly in our choice of formats, hence the flag to disable
261cabdff1aSopenharmony_ci * strict_compliance */
262cabdff1aSopenharmony_cistatic void encode_parse_params(VC2EncContext *s)
263cabdff1aSopenharmony_ci{
264cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->ver.major); /* VC-2 demands this to be 2 */
265cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->ver.minor); /* ^^ and this to be 0       */
266cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->profile);   /* 3 to signal HQ profile    */
267cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->level);     /* 3 - 1080/720, 6 - 4K      */
268cabdff1aSopenharmony_ci}
269cabdff1aSopenharmony_ci
270cabdff1aSopenharmony_ci/* VC-2 11.3 - frame_size() */
271cabdff1aSopenharmony_cistatic void encode_frame_size(VC2EncContext *s)
272cabdff1aSopenharmony_ci{
273cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, !s->strict_compliance);
274cabdff1aSopenharmony_ci    if (!s->strict_compliance) {
275cabdff1aSopenharmony_ci        AVCodecContext *avctx = s->avctx;
276cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, avctx->width);
277cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, avctx->height);
278cabdff1aSopenharmony_ci    }
279cabdff1aSopenharmony_ci}
280cabdff1aSopenharmony_ci
281cabdff1aSopenharmony_ci/* VC-2 11.3.3 - color_diff_sampling_format() */
282cabdff1aSopenharmony_cistatic void encode_sample_fmt(VC2EncContext *s)
283cabdff1aSopenharmony_ci{
284cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, !s->strict_compliance);
285cabdff1aSopenharmony_ci    if (!s->strict_compliance) {
286cabdff1aSopenharmony_ci        int idx;
287cabdff1aSopenharmony_ci        if (s->chroma_x_shift == 1 && s->chroma_y_shift == 0)
288cabdff1aSopenharmony_ci            idx = 1; /* 422 */
289cabdff1aSopenharmony_ci        else if (s->chroma_x_shift == 1 && s->chroma_y_shift == 1)
290cabdff1aSopenharmony_ci            idx = 2; /* 420 */
291cabdff1aSopenharmony_ci        else
292cabdff1aSopenharmony_ci            idx = 0; /* 444 */
293cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, idx);
294cabdff1aSopenharmony_ci    }
295cabdff1aSopenharmony_ci}
296cabdff1aSopenharmony_ci
297cabdff1aSopenharmony_ci/* VC-2 11.3.4 - scan_format() */
298cabdff1aSopenharmony_cistatic void encode_scan_format(VC2EncContext *s)
299cabdff1aSopenharmony_ci{
300cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, !s->strict_compliance);
301cabdff1aSopenharmony_ci    if (!s->strict_compliance)
302cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, s->interlaced);
303cabdff1aSopenharmony_ci}
304cabdff1aSopenharmony_ci
305cabdff1aSopenharmony_ci/* VC-2 11.3.5 - frame_rate() */
306cabdff1aSopenharmony_cistatic void encode_frame_rate(VC2EncContext *s)
307cabdff1aSopenharmony_ci{
308cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, !s->strict_compliance);
309cabdff1aSopenharmony_ci    if (!s->strict_compliance) {
310cabdff1aSopenharmony_ci        AVCodecContext *avctx = s->avctx;
311cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, 0);
312cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, avctx->time_base.den);
313cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, avctx->time_base.num);
314cabdff1aSopenharmony_ci    }
315cabdff1aSopenharmony_ci}
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_ci/* VC-2 11.3.6 - aspect_ratio() */
318cabdff1aSopenharmony_cistatic void encode_aspect_ratio(VC2EncContext *s)
319cabdff1aSopenharmony_ci{
320cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, !s->strict_compliance);
321cabdff1aSopenharmony_ci    if (!s->strict_compliance) {
322cabdff1aSopenharmony_ci        AVCodecContext *avctx = s->avctx;
323cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, 0);
324cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, avctx->sample_aspect_ratio.num);
325cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, avctx->sample_aspect_ratio.den);
326cabdff1aSopenharmony_ci    }
327cabdff1aSopenharmony_ci}
328cabdff1aSopenharmony_ci
329cabdff1aSopenharmony_ci/* VC-2 11.3.7 - clean_area() */
330cabdff1aSopenharmony_cistatic void encode_clean_area(VC2EncContext *s)
331cabdff1aSopenharmony_ci{
332cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, 0);
333cabdff1aSopenharmony_ci}
334cabdff1aSopenharmony_ci
335cabdff1aSopenharmony_ci/* VC-2 11.3.8 - signal_range() */
336cabdff1aSopenharmony_cistatic void encode_signal_range(VC2EncContext *s)
337cabdff1aSopenharmony_ci{
338cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, !s->strict_compliance);
339cabdff1aSopenharmony_ci    if (!s->strict_compliance)
340cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, s->bpp_idx);
341cabdff1aSopenharmony_ci}
342cabdff1aSopenharmony_ci
343cabdff1aSopenharmony_ci/* VC-2 11.3.9 - color_spec() */
344cabdff1aSopenharmony_cistatic void encode_color_spec(VC2EncContext *s)
345cabdff1aSopenharmony_ci{
346cabdff1aSopenharmony_ci    AVCodecContext *avctx = s->avctx;
347cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, !s->strict_compliance);
348cabdff1aSopenharmony_ci    if (!s->strict_compliance) {
349cabdff1aSopenharmony_ci        int val;
350cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, 0);
351cabdff1aSopenharmony_ci
352cabdff1aSopenharmony_ci        /* primaries */
353cabdff1aSopenharmony_ci        put_bits(&s->pb, 1, 1);
354cabdff1aSopenharmony_ci        if (avctx->color_primaries == AVCOL_PRI_BT470BG)
355cabdff1aSopenharmony_ci            val = 2;
356cabdff1aSopenharmony_ci        else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M)
357cabdff1aSopenharmony_ci            val = 1;
358cabdff1aSopenharmony_ci        else if (avctx->color_primaries == AVCOL_PRI_SMPTE240M)
359cabdff1aSopenharmony_ci            val = 1;
360cabdff1aSopenharmony_ci        else
361cabdff1aSopenharmony_ci            val = 0;
362cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, val);
363cabdff1aSopenharmony_ci
364cabdff1aSopenharmony_ci        /* color matrix */
365cabdff1aSopenharmony_ci        put_bits(&s->pb, 1, 1);
366cabdff1aSopenharmony_ci        if (avctx->colorspace == AVCOL_SPC_RGB)
367cabdff1aSopenharmony_ci            val = 3;
368cabdff1aSopenharmony_ci        else if (avctx->colorspace == AVCOL_SPC_YCOCG)
369cabdff1aSopenharmony_ci            val = 2;
370cabdff1aSopenharmony_ci        else if (avctx->colorspace == AVCOL_SPC_BT470BG)
371cabdff1aSopenharmony_ci            val = 1;
372cabdff1aSopenharmony_ci        else
373cabdff1aSopenharmony_ci            val = 0;
374cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, val);
375cabdff1aSopenharmony_ci
376cabdff1aSopenharmony_ci        /* transfer function */
377cabdff1aSopenharmony_ci        put_bits(&s->pb, 1, 1);
378cabdff1aSopenharmony_ci        if (avctx->color_trc == AVCOL_TRC_LINEAR)
379cabdff1aSopenharmony_ci            val = 2;
380cabdff1aSopenharmony_ci        else if (avctx->color_trc == AVCOL_TRC_BT1361_ECG)
381cabdff1aSopenharmony_ci            val = 1;
382cabdff1aSopenharmony_ci        else
383cabdff1aSopenharmony_ci            val = 0;
384cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, val);
385cabdff1aSopenharmony_ci    }
386cabdff1aSopenharmony_ci}
387cabdff1aSopenharmony_ci
388cabdff1aSopenharmony_ci/* VC-2 11.3 - source_parameters() */
389cabdff1aSopenharmony_cistatic void encode_source_params(VC2EncContext *s)
390cabdff1aSopenharmony_ci{
391cabdff1aSopenharmony_ci    encode_frame_size(s);
392cabdff1aSopenharmony_ci    encode_sample_fmt(s);
393cabdff1aSopenharmony_ci    encode_scan_format(s);
394cabdff1aSopenharmony_ci    encode_frame_rate(s);
395cabdff1aSopenharmony_ci    encode_aspect_ratio(s);
396cabdff1aSopenharmony_ci    encode_clean_area(s);
397cabdff1aSopenharmony_ci    encode_signal_range(s);
398cabdff1aSopenharmony_ci    encode_color_spec(s);
399cabdff1aSopenharmony_ci}
400cabdff1aSopenharmony_ci
401cabdff1aSopenharmony_ci/* VC-2 11 - sequence_header() */
402cabdff1aSopenharmony_cistatic void encode_seq_header(VC2EncContext *s)
403cabdff1aSopenharmony_ci{
404cabdff1aSopenharmony_ci    align_put_bits(&s->pb);
405cabdff1aSopenharmony_ci    encode_parse_params(s);
406cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->base_vf);
407cabdff1aSopenharmony_ci    encode_source_params(s);
408cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->interlaced); /* Frames or fields coding */
409cabdff1aSopenharmony_ci}
410cabdff1aSopenharmony_ci
411cabdff1aSopenharmony_ci/* VC-2 12.1 - picture_header() */
412cabdff1aSopenharmony_cistatic void encode_picture_header(VC2EncContext *s)
413cabdff1aSopenharmony_ci{
414cabdff1aSopenharmony_ci    align_put_bits(&s->pb);
415cabdff1aSopenharmony_ci    put_bits32(&s->pb, s->picture_number++);
416cabdff1aSopenharmony_ci}
417cabdff1aSopenharmony_ci
418cabdff1aSopenharmony_ci/* VC-2 12.3.4.1 - slice_parameters() */
419cabdff1aSopenharmony_cistatic void encode_slice_params(VC2EncContext *s)
420cabdff1aSopenharmony_ci{
421cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->num_x);
422cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->num_y);
423cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->prefix_bytes);
424cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->size_scaler);
425cabdff1aSopenharmony_ci}
426cabdff1aSopenharmony_ci
427cabdff1aSopenharmony_ci/* 1st idx = LL, second - vertical, third - horizontal, fourth - total */
428cabdff1aSopenharmony_cistatic const uint8_t vc2_qm_col_tab[][4] = {
429cabdff1aSopenharmony_ci    {20,  9, 15,  4},
430cabdff1aSopenharmony_ci    { 0,  6,  6,  4},
431cabdff1aSopenharmony_ci    { 0,  3,  3,  5},
432cabdff1aSopenharmony_ci    { 0,  3,  5,  1},
433cabdff1aSopenharmony_ci    { 0, 11, 10, 11}
434cabdff1aSopenharmony_ci};
435cabdff1aSopenharmony_ci
436cabdff1aSopenharmony_cistatic const uint8_t vc2_qm_flat_tab[][4] = {
437cabdff1aSopenharmony_ci    { 0,  0,  0,  0},
438cabdff1aSopenharmony_ci    { 0,  0,  0,  0},
439cabdff1aSopenharmony_ci    { 0,  0,  0,  0},
440cabdff1aSopenharmony_ci    { 0,  0,  0,  0},
441cabdff1aSopenharmony_ci    { 0,  0,  0,  0}
442cabdff1aSopenharmony_ci};
443cabdff1aSopenharmony_ci
444cabdff1aSopenharmony_cistatic void init_quant_matrix(VC2EncContext *s)
445cabdff1aSopenharmony_ci{
446cabdff1aSopenharmony_ci    int level, orientation;
447cabdff1aSopenharmony_ci
448cabdff1aSopenharmony_ci    if (s->wavelet_depth <= 4 && s->quant_matrix == VC2_QM_DEF) {
449cabdff1aSopenharmony_ci        s->custom_quant_matrix = 0;
450cabdff1aSopenharmony_ci        for (level = 0; level < s->wavelet_depth; level++) {
451cabdff1aSopenharmony_ci            s->quant[level][0] = ff_dirac_default_qmat[s->wavelet_idx][level][0];
452cabdff1aSopenharmony_ci            s->quant[level][1] = ff_dirac_default_qmat[s->wavelet_idx][level][1];
453cabdff1aSopenharmony_ci            s->quant[level][2] = ff_dirac_default_qmat[s->wavelet_idx][level][2];
454cabdff1aSopenharmony_ci            s->quant[level][3] = ff_dirac_default_qmat[s->wavelet_idx][level][3];
455cabdff1aSopenharmony_ci        }
456cabdff1aSopenharmony_ci        return;
457cabdff1aSopenharmony_ci    }
458cabdff1aSopenharmony_ci
459cabdff1aSopenharmony_ci    s->custom_quant_matrix = 1;
460cabdff1aSopenharmony_ci
461cabdff1aSopenharmony_ci    if (s->quant_matrix == VC2_QM_DEF) {
462cabdff1aSopenharmony_ci        for (level = 0; level < s->wavelet_depth; level++) {
463cabdff1aSopenharmony_ci            for (orientation = 0; orientation < 4; orientation++) {
464cabdff1aSopenharmony_ci                if (level <= 3)
465cabdff1aSopenharmony_ci                    s->quant[level][orientation] = ff_dirac_default_qmat[s->wavelet_idx][level][orientation];
466cabdff1aSopenharmony_ci                else
467cabdff1aSopenharmony_ci                    s->quant[level][orientation] = vc2_qm_col_tab[level][orientation];
468cabdff1aSopenharmony_ci            }
469cabdff1aSopenharmony_ci        }
470cabdff1aSopenharmony_ci    } else if (s->quant_matrix == VC2_QM_COL) {
471cabdff1aSopenharmony_ci        for (level = 0; level < s->wavelet_depth; level++) {
472cabdff1aSopenharmony_ci            for (orientation = 0; orientation < 4; orientation++) {
473cabdff1aSopenharmony_ci                s->quant[level][orientation] = vc2_qm_col_tab[level][orientation];
474cabdff1aSopenharmony_ci            }
475cabdff1aSopenharmony_ci        }
476cabdff1aSopenharmony_ci    } else {
477cabdff1aSopenharmony_ci        for (level = 0; level < s->wavelet_depth; level++) {
478cabdff1aSopenharmony_ci            for (orientation = 0; orientation < 4; orientation++) {
479cabdff1aSopenharmony_ci                s->quant[level][orientation] = vc2_qm_flat_tab[level][orientation];
480cabdff1aSopenharmony_ci            }
481cabdff1aSopenharmony_ci        }
482cabdff1aSopenharmony_ci    }
483cabdff1aSopenharmony_ci}
484cabdff1aSopenharmony_ci
485cabdff1aSopenharmony_ci/* VC-2 12.3.4.2 - quant_matrix() */
486cabdff1aSopenharmony_cistatic void encode_quant_matrix(VC2EncContext *s)
487cabdff1aSopenharmony_ci{
488cabdff1aSopenharmony_ci    int level;
489cabdff1aSopenharmony_ci    put_bits(&s->pb, 1, s->custom_quant_matrix);
490cabdff1aSopenharmony_ci    if (s->custom_quant_matrix) {
491cabdff1aSopenharmony_ci        put_vc2_ue_uint(&s->pb, s->quant[0][0]);
492cabdff1aSopenharmony_ci        for (level = 0; level < s->wavelet_depth; level++) {
493cabdff1aSopenharmony_ci            put_vc2_ue_uint(&s->pb, s->quant[level][1]);
494cabdff1aSopenharmony_ci            put_vc2_ue_uint(&s->pb, s->quant[level][2]);
495cabdff1aSopenharmony_ci            put_vc2_ue_uint(&s->pb, s->quant[level][3]);
496cabdff1aSopenharmony_ci        }
497cabdff1aSopenharmony_ci    }
498cabdff1aSopenharmony_ci}
499cabdff1aSopenharmony_ci
500cabdff1aSopenharmony_ci/* VC-2 12.3 - transform_parameters() */
501cabdff1aSopenharmony_cistatic void encode_transform_params(VC2EncContext *s)
502cabdff1aSopenharmony_ci{
503cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->wavelet_idx);
504cabdff1aSopenharmony_ci    put_vc2_ue_uint(&s->pb, s->wavelet_depth);
505cabdff1aSopenharmony_ci
506cabdff1aSopenharmony_ci    encode_slice_params(s);
507cabdff1aSopenharmony_ci    encode_quant_matrix(s);
508cabdff1aSopenharmony_ci}
509cabdff1aSopenharmony_ci
510cabdff1aSopenharmony_ci/* VC-2 12.2 - wavelet_transform() */
511cabdff1aSopenharmony_cistatic void encode_wavelet_transform(VC2EncContext *s)
512cabdff1aSopenharmony_ci{
513cabdff1aSopenharmony_ci    encode_transform_params(s);
514cabdff1aSopenharmony_ci    align_put_bits(&s->pb);
515cabdff1aSopenharmony_ci}
516cabdff1aSopenharmony_ci
517cabdff1aSopenharmony_ci/* VC-2 12 - picture_parse() */
518cabdff1aSopenharmony_cistatic void encode_picture_start(VC2EncContext *s)
519cabdff1aSopenharmony_ci{
520cabdff1aSopenharmony_ci    align_put_bits(&s->pb);
521cabdff1aSopenharmony_ci    encode_picture_header(s);
522cabdff1aSopenharmony_ci    align_put_bits(&s->pb);
523cabdff1aSopenharmony_ci    encode_wavelet_transform(s);
524cabdff1aSopenharmony_ci}
525cabdff1aSopenharmony_ci
526cabdff1aSopenharmony_ci#define QUANT(c, mul, add, shift) (((mul) * (c) + (add)) >> (shift))
527cabdff1aSopenharmony_ci
528cabdff1aSopenharmony_ci/* VC-2 13.5.5.2 - slice_band() */
529cabdff1aSopenharmony_cistatic void encode_subband(VC2EncContext *s, PutBitContext *pb, int sx, int sy,
530cabdff1aSopenharmony_ci                           SubBand *b, int quant)
531cabdff1aSopenharmony_ci{
532cabdff1aSopenharmony_ci    int x, y;
533cabdff1aSopenharmony_ci
534cabdff1aSopenharmony_ci    const int left   = b->width  * (sx+0) / s->num_x;
535cabdff1aSopenharmony_ci    const int right  = b->width  * (sx+1) / s->num_x;
536cabdff1aSopenharmony_ci    const int top    = b->height * (sy+0) / s->num_y;
537cabdff1aSopenharmony_ci    const int bottom = b->height * (sy+1) / s->num_y;
538cabdff1aSopenharmony_ci
539cabdff1aSopenharmony_ci    dwtcoef *coeff = b->buf + top * b->stride;
540cabdff1aSopenharmony_ci    const uint64_t q_m = ((uint64_t)(s->qmagic_lut[quant][0])) << 2;
541cabdff1aSopenharmony_ci    const uint64_t q_a = s->qmagic_lut[quant][1];
542cabdff1aSopenharmony_ci    const int q_s = av_log2(ff_dirac_qscale_tab[quant]) + 32;
543cabdff1aSopenharmony_ci
544cabdff1aSopenharmony_ci    for (y = top; y < bottom; y++) {
545cabdff1aSopenharmony_ci        for (x = left; x < right; x++) {
546cabdff1aSopenharmony_ci            uint32_t c_abs = QUANT(FFABS(coeff[x]), q_m, q_a, q_s);
547cabdff1aSopenharmony_ci            put_vc2_ue_uint(pb, c_abs);
548cabdff1aSopenharmony_ci            if (c_abs)
549cabdff1aSopenharmony_ci                put_bits(pb, 1, coeff[x] < 0);
550cabdff1aSopenharmony_ci        }
551cabdff1aSopenharmony_ci        coeff += b->stride;
552cabdff1aSopenharmony_ci    }
553cabdff1aSopenharmony_ci}
554cabdff1aSopenharmony_ci
555cabdff1aSopenharmony_cistatic int count_hq_slice(SliceArgs *slice, int quant_idx)
556cabdff1aSopenharmony_ci{
557cabdff1aSopenharmony_ci    int x, y;
558cabdff1aSopenharmony_ci    uint8_t quants[MAX_DWT_LEVELS][4];
559cabdff1aSopenharmony_ci    int bits = 0, p, level, orientation;
560cabdff1aSopenharmony_ci    VC2EncContext *s = slice->ctx;
561cabdff1aSopenharmony_ci
562cabdff1aSopenharmony_ci    if (slice->cache[quant_idx])
563cabdff1aSopenharmony_ci        return slice->cache[quant_idx];
564cabdff1aSopenharmony_ci
565cabdff1aSopenharmony_ci    bits += 8*s->prefix_bytes;
566cabdff1aSopenharmony_ci    bits += 8; /* quant_idx */
567cabdff1aSopenharmony_ci
568cabdff1aSopenharmony_ci    for (level = 0; level < s->wavelet_depth; level++)
569cabdff1aSopenharmony_ci        for (orientation = !!level; orientation < 4; orientation++)
570cabdff1aSopenharmony_ci            quants[level][orientation] = FFMAX(quant_idx - s->quant[level][orientation], 0);
571cabdff1aSopenharmony_ci
572cabdff1aSopenharmony_ci    for (p = 0; p < 3; p++) {
573cabdff1aSopenharmony_ci        int bytes_start, bytes_len, pad_s, pad_c;
574cabdff1aSopenharmony_ci        bytes_start = bits >> 3;
575cabdff1aSopenharmony_ci        bits += 8;
576cabdff1aSopenharmony_ci        for (level = 0; level < s->wavelet_depth; level++) {
577cabdff1aSopenharmony_ci            for (orientation = !!level; orientation < 4; orientation++) {
578cabdff1aSopenharmony_ci                SubBand *b = &s->plane[p].band[level][orientation];
579cabdff1aSopenharmony_ci
580cabdff1aSopenharmony_ci                const int q_idx = quants[level][orientation];
581cabdff1aSopenharmony_ci                const uint64_t q_m = ((uint64_t)s->qmagic_lut[q_idx][0]) << 2;
582cabdff1aSopenharmony_ci                const uint64_t q_a = s->qmagic_lut[q_idx][1];
583cabdff1aSopenharmony_ci                const int q_s = av_log2(ff_dirac_qscale_tab[q_idx]) + 32;
584cabdff1aSopenharmony_ci
585cabdff1aSopenharmony_ci                const int left   = b->width  * slice->x    / s->num_x;
586cabdff1aSopenharmony_ci                const int right  = b->width  *(slice->x+1) / s->num_x;
587cabdff1aSopenharmony_ci                const int top    = b->height * slice->y    / s->num_y;
588cabdff1aSopenharmony_ci                const int bottom = b->height *(slice->y+1) / s->num_y;
589cabdff1aSopenharmony_ci
590cabdff1aSopenharmony_ci                dwtcoef *buf = b->buf + top * b->stride;
591cabdff1aSopenharmony_ci
592cabdff1aSopenharmony_ci                for (y = top; y < bottom; y++) {
593cabdff1aSopenharmony_ci                    for (x = left; x < right; x++) {
594cabdff1aSopenharmony_ci                        uint32_t c_abs = QUANT(FFABS(buf[x]), q_m, q_a, q_s);
595cabdff1aSopenharmony_ci                        bits += count_vc2_ue_uint(c_abs);
596cabdff1aSopenharmony_ci                        bits += !!c_abs;
597cabdff1aSopenharmony_ci                    }
598cabdff1aSopenharmony_ci                    buf += b->stride;
599cabdff1aSopenharmony_ci                }
600cabdff1aSopenharmony_ci            }
601cabdff1aSopenharmony_ci        }
602cabdff1aSopenharmony_ci        bits += FFALIGN(bits, 8) - bits;
603cabdff1aSopenharmony_ci        bytes_len = (bits >> 3) - bytes_start - 1;
604cabdff1aSopenharmony_ci        pad_s = FFALIGN(bytes_len, s->size_scaler)/s->size_scaler;
605cabdff1aSopenharmony_ci        pad_c = (pad_s*s->size_scaler) - bytes_len;
606cabdff1aSopenharmony_ci        bits += pad_c*8;
607cabdff1aSopenharmony_ci    }
608cabdff1aSopenharmony_ci
609cabdff1aSopenharmony_ci    slice->cache[quant_idx] = bits;
610cabdff1aSopenharmony_ci
611cabdff1aSopenharmony_ci    return bits;
612cabdff1aSopenharmony_ci}
613cabdff1aSopenharmony_ci
614cabdff1aSopenharmony_ci/* Approaches the best possible quantizer asymptotically, its kinda exaustive
615cabdff1aSopenharmony_ci * but we have a LUT to get the coefficient size in bits. Guaranteed to never
616cabdff1aSopenharmony_ci * overshoot, which is apparently very important when streaming */
617cabdff1aSopenharmony_cistatic int rate_control(AVCodecContext *avctx, void *arg)
618cabdff1aSopenharmony_ci{
619cabdff1aSopenharmony_ci    SliceArgs *slice_dat = arg;
620cabdff1aSopenharmony_ci    VC2EncContext *s = slice_dat->ctx;
621cabdff1aSopenharmony_ci    const int top = slice_dat->bits_ceil;
622cabdff1aSopenharmony_ci    const int bottom = slice_dat->bits_floor;
623cabdff1aSopenharmony_ci    int quant_buf[2] = {-1, -1};
624cabdff1aSopenharmony_ci    int quant = slice_dat->quant_idx, step = 1;
625cabdff1aSopenharmony_ci    int bits_last, bits = count_hq_slice(slice_dat, quant);
626cabdff1aSopenharmony_ci    while ((bits > top) || (bits < bottom)) {
627cabdff1aSopenharmony_ci        const int signed_step = bits > top ? +step : -step;
628cabdff1aSopenharmony_ci        quant  = av_clip(quant + signed_step, 0, s->q_ceil-1);
629cabdff1aSopenharmony_ci        bits   = count_hq_slice(slice_dat, quant);
630cabdff1aSopenharmony_ci        if (quant_buf[1] == quant) {
631cabdff1aSopenharmony_ci            quant = FFMAX(quant_buf[0], quant);
632cabdff1aSopenharmony_ci            bits  = quant == quant_buf[0] ? bits_last : bits;
633cabdff1aSopenharmony_ci            break;
634cabdff1aSopenharmony_ci        }
635cabdff1aSopenharmony_ci        step         = av_clip(step/2, 1, (s->q_ceil-1)/2);
636cabdff1aSopenharmony_ci        quant_buf[1] = quant_buf[0];
637cabdff1aSopenharmony_ci        quant_buf[0] = quant;
638cabdff1aSopenharmony_ci        bits_last    = bits;
639cabdff1aSopenharmony_ci    }
640cabdff1aSopenharmony_ci    slice_dat->quant_idx = av_clip(quant, 0, s->q_ceil-1);
641cabdff1aSopenharmony_ci    slice_dat->bytes = SSIZE_ROUND(bits >> 3);
642cabdff1aSopenharmony_ci    return 0;
643cabdff1aSopenharmony_ci}
644cabdff1aSopenharmony_ci
645cabdff1aSopenharmony_cistatic int calc_slice_sizes(VC2EncContext *s)
646cabdff1aSopenharmony_ci{
647cabdff1aSopenharmony_ci    int i, j, slice_x, slice_y, bytes_left = 0;
648cabdff1aSopenharmony_ci    int bytes_top[SLICE_REDIST_TOTAL] = {0};
649cabdff1aSopenharmony_ci    int64_t total_bytes_needed = 0;
650cabdff1aSopenharmony_ci    int slice_redist_range = FFMIN(SLICE_REDIST_TOTAL, s->num_x*s->num_y);
651cabdff1aSopenharmony_ci    SliceArgs *enc_args = s->slice_args;
652cabdff1aSopenharmony_ci    SliceArgs *top_loc[SLICE_REDIST_TOTAL] = {NULL};
653cabdff1aSopenharmony_ci
654cabdff1aSopenharmony_ci    init_quant_matrix(s);
655cabdff1aSopenharmony_ci
656cabdff1aSopenharmony_ci    for (slice_y = 0; slice_y < s->num_y; slice_y++) {
657cabdff1aSopenharmony_ci        for (slice_x = 0; slice_x < s->num_x; slice_x++) {
658cabdff1aSopenharmony_ci            SliceArgs *args = &enc_args[s->num_x*slice_y + slice_x];
659cabdff1aSopenharmony_ci            args->ctx = s;
660cabdff1aSopenharmony_ci            args->x   = slice_x;
661cabdff1aSopenharmony_ci            args->y   = slice_y;
662cabdff1aSopenharmony_ci            args->bits_ceil  = s->slice_max_bytes << 3;
663cabdff1aSopenharmony_ci            args->bits_floor = s->slice_min_bytes << 3;
664cabdff1aSopenharmony_ci            memset(args->cache, 0, s->q_ceil*sizeof(*args->cache));
665cabdff1aSopenharmony_ci        }
666cabdff1aSopenharmony_ci    }
667cabdff1aSopenharmony_ci
668cabdff1aSopenharmony_ci    /* First pass - determine baseline slice sizes w.r.t. max_slice_size */
669cabdff1aSopenharmony_ci    s->avctx->execute(s->avctx, rate_control, enc_args, NULL, s->num_x*s->num_y,
670cabdff1aSopenharmony_ci                      sizeof(SliceArgs));
671cabdff1aSopenharmony_ci
672cabdff1aSopenharmony_ci    for (i = 0; i < s->num_x*s->num_y; i++) {
673cabdff1aSopenharmony_ci        SliceArgs *args = &enc_args[i];
674cabdff1aSopenharmony_ci        bytes_left += args->bytes;
675cabdff1aSopenharmony_ci        for (j = 0; j < slice_redist_range; j++) {
676cabdff1aSopenharmony_ci            if (args->bytes > bytes_top[j]) {
677cabdff1aSopenharmony_ci                bytes_top[j] = args->bytes;
678cabdff1aSopenharmony_ci                top_loc[j]   = args;
679cabdff1aSopenharmony_ci                break;
680cabdff1aSopenharmony_ci            }
681cabdff1aSopenharmony_ci        }
682cabdff1aSopenharmony_ci    }
683cabdff1aSopenharmony_ci
684cabdff1aSopenharmony_ci    bytes_left = s->frame_max_bytes - bytes_left;
685cabdff1aSopenharmony_ci
686cabdff1aSopenharmony_ci    /* Second pass - distribute leftover bytes */
687cabdff1aSopenharmony_ci    while (bytes_left > 0) {
688cabdff1aSopenharmony_ci        int distributed = 0;
689cabdff1aSopenharmony_ci        for (i = 0; i < slice_redist_range; i++) {
690cabdff1aSopenharmony_ci            SliceArgs *args;
691cabdff1aSopenharmony_ci            int bits, bytes, diff, prev_bytes, new_idx;
692cabdff1aSopenharmony_ci            if (bytes_left <= 0)
693cabdff1aSopenharmony_ci                break;
694cabdff1aSopenharmony_ci            if (!top_loc[i] || !top_loc[i]->quant_idx)
695cabdff1aSopenharmony_ci                break;
696cabdff1aSopenharmony_ci            args = top_loc[i];
697cabdff1aSopenharmony_ci            prev_bytes = args->bytes;
698cabdff1aSopenharmony_ci            new_idx = FFMAX(args->quant_idx - 1, 0);
699cabdff1aSopenharmony_ci            bits  = count_hq_slice(args, new_idx);
700cabdff1aSopenharmony_ci            bytes = SSIZE_ROUND(bits >> 3);
701cabdff1aSopenharmony_ci            diff  = bytes - prev_bytes;
702cabdff1aSopenharmony_ci            if ((bytes_left - diff) > 0) {
703cabdff1aSopenharmony_ci                args->quant_idx = new_idx;
704cabdff1aSopenharmony_ci                args->bytes = bytes;
705cabdff1aSopenharmony_ci                bytes_left -= diff;
706cabdff1aSopenharmony_ci                distributed++;
707cabdff1aSopenharmony_ci            }
708cabdff1aSopenharmony_ci        }
709cabdff1aSopenharmony_ci        if (!distributed)
710cabdff1aSopenharmony_ci            break;
711cabdff1aSopenharmony_ci    }
712cabdff1aSopenharmony_ci
713cabdff1aSopenharmony_ci    for (i = 0; i < s->num_x*s->num_y; i++) {
714cabdff1aSopenharmony_ci        SliceArgs *args = &enc_args[i];
715cabdff1aSopenharmony_ci        total_bytes_needed += args->bytes;
716cabdff1aSopenharmony_ci        s->q_avg = (s->q_avg + args->quant_idx)/2;
717cabdff1aSopenharmony_ci    }
718cabdff1aSopenharmony_ci
719cabdff1aSopenharmony_ci    return total_bytes_needed;
720cabdff1aSopenharmony_ci}
721cabdff1aSopenharmony_ci
722cabdff1aSopenharmony_ci/* VC-2 13.5.3 - hq_slice */
723cabdff1aSopenharmony_cistatic int encode_hq_slice(AVCodecContext *avctx, void *arg)
724cabdff1aSopenharmony_ci{
725cabdff1aSopenharmony_ci    SliceArgs *slice_dat = arg;
726cabdff1aSopenharmony_ci    VC2EncContext *s = slice_dat->ctx;
727cabdff1aSopenharmony_ci    PutBitContext *pb = &slice_dat->pb;
728cabdff1aSopenharmony_ci    const int slice_x = slice_dat->x;
729cabdff1aSopenharmony_ci    const int slice_y = slice_dat->y;
730cabdff1aSopenharmony_ci    const int quant_idx = slice_dat->quant_idx;
731cabdff1aSopenharmony_ci    const int slice_bytes_max = slice_dat->bytes;
732cabdff1aSopenharmony_ci    uint8_t quants[MAX_DWT_LEVELS][4];
733cabdff1aSopenharmony_ci    int p, level, orientation;
734cabdff1aSopenharmony_ci
735cabdff1aSopenharmony_ci    /* The reference decoder ignores it, and its typical length is 0 */
736cabdff1aSopenharmony_ci    memset(put_bits_ptr(pb), 0, s->prefix_bytes);
737cabdff1aSopenharmony_ci    skip_put_bytes(pb, s->prefix_bytes);
738cabdff1aSopenharmony_ci
739cabdff1aSopenharmony_ci    put_bits(pb, 8, quant_idx);
740cabdff1aSopenharmony_ci
741cabdff1aSopenharmony_ci    /* Slice quantization (slice_quantizers() in the specs) */
742cabdff1aSopenharmony_ci    for (level = 0; level < s->wavelet_depth; level++)
743cabdff1aSopenharmony_ci        for (orientation = !!level; orientation < 4; orientation++)
744cabdff1aSopenharmony_ci            quants[level][orientation] = FFMAX(quant_idx - s->quant[level][orientation], 0);
745cabdff1aSopenharmony_ci
746cabdff1aSopenharmony_ci    /* Luma + 2 Chroma planes */
747cabdff1aSopenharmony_ci    for (p = 0; p < 3; p++) {
748cabdff1aSopenharmony_ci        int bytes_start, bytes_len, pad_s, pad_c;
749cabdff1aSopenharmony_ci        bytes_start = put_bits_count(pb) >> 3;
750cabdff1aSopenharmony_ci        put_bits(pb, 8, 0);
751cabdff1aSopenharmony_ci        for (level = 0; level < s->wavelet_depth; level++) {
752cabdff1aSopenharmony_ci            for (orientation = !!level; orientation < 4; orientation++) {
753cabdff1aSopenharmony_ci                encode_subband(s, pb, slice_x, slice_y,
754cabdff1aSopenharmony_ci                               &s->plane[p].band[level][orientation],
755cabdff1aSopenharmony_ci                               quants[level][orientation]);
756cabdff1aSopenharmony_ci            }
757cabdff1aSopenharmony_ci        }
758cabdff1aSopenharmony_ci        align_put_bits(pb);
759cabdff1aSopenharmony_ci        bytes_len = (put_bits_count(pb) >> 3) - bytes_start - 1;
760cabdff1aSopenharmony_ci        if (p == 2) {
761cabdff1aSopenharmony_ci            int len_diff = slice_bytes_max - (put_bits_count(pb) >> 3);
762cabdff1aSopenharmony_ci            pad_s = FFALIGN((bytes_len + len_diff), s->size_scaler)/s->size_scaler;
763cabdff1aSopenharmony_ci            pad_c = (pad_s*s->size_scaler) - bytes_len;
764cabdff1aSopenharmony_ci        } else {
765cabdff1aSopenharmony_ci            pad_s = FFALIGN(bytes_len, s->size_scaler)/s->size_scaler;
766cabdff1aSopenharmony_ci            pad_c = (pad_s*s->size_scaler) - bytes_len;
767cabdff1aSopenharmony_ci        }
768cabdff1aSopenharmony_ci        pb->buf[bytes_start] = pad_s;
769cabdff1aSopenharmony_ci        flush_put_bits(pb);
770cabdff1aSopenharmony_ci        /* vc2-reference uses that padding that decodes to '0' coeffs */
771cabdff1aSopenharmony_ci        memset(put_bits_ptr(pb), 0xFF, pad_c);
772cabdff1aSopenharmony_ci        skip_put_bytes(pb, pad_c);
773cabdff1aSopenharmony_ci    }
774cabdff1aSopenharmony_ci
775cabdff1aSopenharmony_ci    return 0;
776cabdff1aSopenharmony_ci}
777cabdff1aSopenharmony_ci
778cabdff1aSopenharmony_ci/* VC-2 13.5.1 - low_delay_transform_data() */
779cabdff1aSopenharmony_cistatic int encode_slices(VC2EncContext *s)
780cabdff1aSopenharmony_ci{
781cabdff1aSopenharmony_ci    uint8_t *buf;
782cabdff1aSopenharmony_ci    int slice_x, slice_y, skip = 0;
783cabdff1aSopenharmony_ci    SliceArgs *enc_args = s->slice_args;
784cabdff1aSopenharmony_ci
785cabdff1aSopenharmony_ci    flush_put_bits(&s->pb);
786cabdff1aSopenharmony_ci    buf = put_bits_ptr(&s->pb);
787cabdff1aSopenharmony_ci
788cabdff1aSopenharmony_ci    for (slice_y = 0; slice_y < s->num_y; slice_y++) {
789cabdff1aSopenharmony_ci        for (slice_x = 0; slice_x < s->num_x; slice_x++) {
790cabdff1aSopenharmony_ci            SliceArgs *args = &enc_args[s->num_x*slice_y + slice_x];
791cabdff1aSopenharmony_ci            init_put_bits(&args->pb, buf + skip, args->bytes+s->prefix_bytes);
792cabdff1aSopenharmony_ci            skip += args->bytes;
793cabdff1aSopenharmony_ci        }
794cabdff1aSopenharmony_ci    }
795cabdff1aSopenharmony_ci
796cabdff1aSopenharmony_ci    s->avctx->execute(s->avctx, encode_hq_slice, enc_args, NULL, s->num_x*s->num_y,
797cabdff1aSopenharmony_ci                      sizeof(SliceArgs));
798cabdff1aSopenharmony_ci
799cabdff1aSopenharmony_ci    skip_put_bytes(&s->pb, skip);
800cabdff1aSopenharmony_ci
801cabdff1aSopenharmony_ci    return 0;
802cabdff1aSopenharmony_ci}
803cabdff1aSopenharmony_ci
804cabdff1aSopenharmony_ci/*
805cabdff1aSopenharmony_ci * Transform basics for a 3 level transform
806cabdff1aSopenharmony_ci * |---------------------------------------------------------------------|
807cabdff1aSopenharmony_ci * |  LL-0  | HL-0  |                 |                                  |
808cabdff1aSopenharmony_ci * |--------|-------|      HL-1       |                                  |
809cabdff1aSopenharmony_ci * |  LH-0  | HH-0  |                 |                                  |
810cabdff1aSopenharmony_ci * |----------------|-----------------|              HL-2                |
811cabdff1aSopenharmony_ci * |                |                 |                                  |
812cabdff1aSopenharmony_ci * |     LH-1       |      HH-1       |                                  |
813cabdff1aSopenharmony_ci * |                |                 |                                  |
814cabdff1aSopenharmony_ci * |----------------------------------|----------------------------------|
815cabdff1aSopenharmony_ci * |                                  |                                  |
816cabdff1aSopenharmony_ci * |                                  |                                  |
817cabdff1aSopenharmony_ci * |                                  |                                  |
818cabdff1aSopenharmony_ci * |              LH-2                |              HH-2                |
819cabdff1aSopenharmony_ci * |                                  |                                  |
820cabdff1aSopenharmony_ci * |                                  |                                  |
821cabdff1aSopenharmony_ci * |                                  |                                  |
822cabdff1aSopenharmony_ci * |---------------------------------------------------------------------|
823cabdff1aSopenharmony_ci *
824cabdff1aSopenharmony_ci * DWT transforms are generally applied by splitting the image in two vertically
825cabdff1aSopenharmony_ci * and applying a low pass transform on the left part and a corresponding high
826cabdff1aSopenharmony_ci * pass transform on the right hand side. This is known as the horizontal filter
827cabdff1aSopenharmony_ci * stage.
828cabdff1aSopenharmony_ci * After that, the same operation is performed except the image is divided
829cabdff1aSopenharmony_ci * horizontally, with the high pass on the lower and the low pass on the higher
830cabdff1aSopenharmony_ci * side.
831cabdff1aSopenharmony_ci * Therefore, you're left with 4 subdivisions - known as  low-low, low-high,
832cabdff1aSopenharmony_ci * high-low and high-high. They're referred to as orientations in the decoder
833cabdff1aSopenharmony_ci * and encoder.
834cabdff1aSopenharmony_ci *
835cabdff1aSopenharmony_ci * The LL (low-low) area contains the original image downsampled by the amount
836cabdff1aSopenharmony_ci * of levels. The rest of the areas can be thought as the details needed
837cabdff1aSopenharmony_ci * to restore the image perfectly to its original size.
838cabdff1aSopenharmony_ci */
839cabdff1aSopenharmony_cistatic int dwt_plane(AVCodecContext *avctx, void *arg)
840cabdff1aSopenharmony_ci{
841cabdff1aSopenharmony_ci    TransformArgs *transform_dat = arg;
842cabdff1aSopenharmony_ci    VC2EncContext *s = transform_dat->ctx;
843cabdff1aSopenharmony_ci    const void *frame_data = transform_dat->idata;
844cabdff1aSopenharmony_ci    const ptrdiff_t linesize = transform_dat->istride;
845cabdff1aSopenharmony_ci    const int field = transform_dat->field;
846cabdff1aSopenharmony_ci    const Plane *p = transform_dat->plane;
847cabdff1aSopenharmony_ci    VC2TransformContext *t = &transform_dat->t;
848cabdff1aSopenharmony_ci    dwtcoef *buf = p->coef_buf;
849cabdff1aSopenharmony_ci    const int idx = s->wavelet_idx;
850cabdff1aSopenharmony_ci    const int skip = 1 + s->interlaced;
851cabdff1aSopenharmony_ci
852cabdff1aSopenharmony_ci    int x, y, level, offset;
853cabdff1aSopenharmony_ci    ptrdiff_t pix_stride = linesize >> (s->bpp - 1);
854cabdff1aSopenharmony_ci
855cabdff1aSopenharmony_ci    if (field == 1) {
856cabdff1aSopenharmony_ci        offset = 0;
857cabdff1aSopenharmony_ci        pix_stride <<= 1;
858cabdff1aSopenharmony_ci    } else if (field == 2) {
859cabdff1aSopenharmony_ci        offset = pix_stride;
860cabdff1aSopenharmony_ci        pix_stride <<= 1;
861cabdff1aSopenharmony_ci    } else {
862cabdff1aSopenharmony_ci        offset = 0;
863cabdff1aSopenharmony_ci    }
864cabdff1aSopenharmony_ci
865cabdff1aSopenharmony_ci    if (s->bpp == 1) {
866cabdff1aSopenharmony_ci        const uint8_t *pix = (const uint8_t *)frame_data + offset;
867cabdff1aSopenharmony_ci        for (y = 0; y < p->height*skip; y+=skip) {
868cabdff1aSopenharmony_ci            for (x = 0; x < p->width; x++) {
869cabdff1aSopenharmony_ci                buf[x] = pix[x] - s->diff_offset;
870cabdff1aSopenharmony_ci            }
871cabdff1aSopenharmony_ci            memset(&buf[x], 0, (p->coef_stride - p->width)*sizeof(dwtcoef));
872cabdff1aSopenharmony_ci            buf += p->coef_stride;
873cabdff1aSopenharmony_ci            pix += pix_stride;
874cabdff1aSopenharmony_ci        }
875cabdff1aSopenharmony_ci    } else {
876cabdff1aSopenharmony_ci        const uint16_t *pix = (const uint16_t *)frame_data + offset;
877cabdff1aSopenharmony_ci        for (y = 0; y < p->height*skip; y+=skip) {
878cabdff1aSopenharmony_ci            for (x = 0; x < p->width; x++) {
879cabdff1aSopenharmony_ci                buf[x] = pix[x] - s->diff_offset;
880cabdff1aSopenharmony_ci            }
881cabdff1aSopenharmony_ci            memset(&buf[x], 0, (p->coef_stride - p->width)*sizeof(dwtcoef));
882cabdff1aSopenharmony_ci            buf += p->coef_stride;
883cabdff1aSopenharmony_ci            pix += pix_stride;
884cabdff1aSopenharmony_ci        }
885cabdff1aSopenharmony_ci    }
886cabdff1aSopenharmony_ci
887cabdff1aSopenharmony_ci    memset(buf, 0, p->coef_stride * (p->dwt_height - p->height) * sizeof(dwtcoef));
888cabdff1aSopenharmony_ci
889cabdff1aSopenharmony_ci    for (level = s->wavelet_depth-1; level >= 0; level--) {
890cabdff1aSopenharmony_ci        const SubBand *b = &p->band[level][0];
891cabdff1aSopenharmony_ci        t->vc2_subband_dwt[idx](t, p->coef_buf, p->coef_stride,
892cabdff1aSopenharmony_ci                                b->width, b->height);
893cabdff1aSopenharmony_ci    }
894cabdff1aSopenharmony_ci
895cabdff1aSopenharmony_ci    return 0;
896cabdff1aSopenharmony_ci}
897cabdff1aSopenharmony_ci
898cabdff1aSopenharmony_cistatic int encode_frame(VC2EncContext *s, AVPacket *avpkt, const AVFrame *frame,
899cabdff1aSopenharmony_ci                        const char *aux_data, const int header_size, int field)
900cabdff1aSopenharmony_ci{
901cabdff1aSopenharmony_ci    int i, ret;
902cabdff1aSopenharmony_ci    int64_t max_frame_bytes;
903cabdff1aSopenharmony_ci
904cabdff1aSopenharmony_ci     /* Threaded DWT transform */
905cabdff1aSopenharmony_ci    for (i = 0; i < 3; i++) {
906cabdff1aSopenharmony_ci        s->transform_args[i].ctx   = s;
907cabdff1aSopenharmony_ci        s->transform_args[i].field = field;
908cabdff1aSopenharmony_ci        s->transform_args[i].plane = &s->plane[i];
909cabdff1aSopenharmony_ci        s->transform_args[i].idata = frame->data[i];
910cabdff1aSopenharmony_ci        s->transform_args[i].istride = frame->linesize[i];
911cabdff1aSopenharmony_ci    }
912cabdff1aSopenharmony_ci    s->avctx->execute(s->avctx, dwt_plane, s->transform_args, NULL, 3,
913cabdff1aSopenharmony_ci                      sizeof(TransformArgs));
914cabdff1aSopenharmony_ci
915cabdff1aSopenharmony_ci    /* Calculate per-slice quantizers and sizes */
916cabdff1aSopenharmony_ci    max_frame_bytes = header_size + calc_slice_sizes(s);
917cabdff1aSopenharmony_ci
918cabdff1aSopenharmony_ci    if (field < 2) {
919cabdff1aSopenharmony_ci        ret = ff_get_encode_buffer(s->avctx, avpkt,
920cabdff1aSopenharmony_ci                                   max_frame_bytes << s->interlaced, 0);
921cabdff1aSopenharmony_ci        if (ret) {
922cabdff1aSopenharmony_ci            av_log(s->avctx, AV_LOG_ERROR, "Error getting output packet.\n");
923cabdff1aSopenharmony_ci            return ret;
924cabdff1aSopenharmony_ci        }
925cabdff1aSopenharmony_ci        init_put_bits(&s->pb, avpkt->data, avpkt->size);
926cabdff1aSopenharmony_ci    }
927cabdff1aSopenharmony_ci
928cabdff1aSopenharmony_ci    /* Sequence header */
929cabdff1aSopenharmony_ci    encode_parse_info(s, DIRAC_PCODE_SEQ_HEADER);
930cabdff1aSopenharmony_ci    encode_seq_header(s);
931cabdff1aSopenharmony_ci
932cabdff1aSopenharmony_ci    /* Encoder version */
933cabdff1aSopenharmony_ci    if (aux_data) {
934cabdff1aSopenharmony_ci        encode_parse_info(s, DIRAC_PCODE_AUX);
935cabdff1aSopenharmony_ci        ff_put_string(&s->pb, aux_data, 1);
936cabdff1aSopenharmony_ci    }
937cabdff1aSopenharmony_ci
938cabdff1aSopenharmony_ci    /* Picture header */
939cabdff1aSopenharmony_ci    encode_parse_info(s, DIRAC_PCODE_PICTURE_HQ);
940cabdff1aSopenharmony_ci    encode_picture_start(s);
941cabdff1aSopenharmony_ci
942cabdff1aSopenharmony_ci    /* Encode slices */
943cabdff1aSopenharmony_ci    encode_slices(s);
944cabdff1aSopenharmony_ci
945cabdff1aSopenharmony_ci    /* End sequence */
946cabdff1aSopenharmony_ci    encode_parse_info(s, DIRAC_PCODE_END_SEQ);
947cabdff1aSopenharmony_ci
948cabdff1aSopenharmony_ci    return 0;
949cabdff1aSopenharmony_ci}
950cabdff1aSopenharmony_ci
951cabdff1aSopenharmony_cistatic av_cold int vc2_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
952cabdff1aSopenharmony_ci                                      const AVFrame *frame, int *got_packet)
953cabdff1aSopenharmony_ci{
954cabdff1aSopenharmony_ci    int ret = 0;
955cabdff1aSopenharmony_ci    int slice_ceil, sig_size = 256;
956cabdff1aSopenharmony_ci    VC2EncContext *s = avctx->priv_data;
957cabdff1aSopenharmony_ci    const int bitexact = avctx->flags & AV_CODEC_FLAG_BITEXACT;
958cabdff1aSopenharmony_ci    const char *aux_data = bitexact ? "Lavc" : LIBAVCODEC_IDENT;
959cabdff1aSopenharmony_ci    const int aux_data_size = bitexact ? sizeof("Lavc") : sizeof(LIBAVCODEC_IDENT);
960cabdff1aSopenharmony_ci    const int header_size = 100 + aux_data_size;
961cabdff1aSopenharmony_ci    int64_t r_bitrate = avctx->bit_rate >> (s->interlaced);
962cabdff1aSopenharmony_ci
963cabdff1aSopenharmony_ci    s->avctx = avctx;
964cabdff1aSopenharmony_ci    s->size_scaler = 2;
965cabdff1aSopenharmony_ci    s->prefix_bytes = 0;
966cabdff1aSopenharmony_ci    s->last_parse_code = 0;
967cabdff1aSopenharmony_ci    s->next_parse_offset = 0;
968cabdff1aSopenharmony_ci
969cabdff1aSopenharmony_ci    /* Rate control */
970cabdff1aSopenharmony_ci    s->frame_max_bytes = (av_rescale(r_bitrate, s->avctx->time_base.num,
971cabdff1aSopenharmony_ci                                     s->avctx->time_base.den) >> 3) - header_size;
972cabdff1aSopenharmony_ci    s->slice_max_bytes = slice_ceil = av_rescale(s->frame_max_bytes, 1, s->num_x*s->num_y);
973cabdff1aSopenharmony_ci
974cabdff1aSopenharmony_ci    /* Find an appropriate size scaler */
975cabdff1aSopenharmony_ci    while (sig_size > 255) {
976cabdff1aSopenharmony_ci        int r_size = SSIZE_ROUND(s->slice_max_bytes);
977cabdff1aSopenharmony_ci        if (r_size > slice_ceil) {
978cabdff1aSopenharmony_ci            s->slice_max_bytes -= r_size - slice_ceil;
979cabdff1aSopenharmony_ci            r_size = SSIZE_ROUND(s->slice_max_bytes);
980cabdff1aSopenharmony_ci        }
981cabdff1aSopenharmony_ci        sig_size = r_size/s->size_scaler; /* Signalled slize size */
982cabdff1aSopenharmony_ci        s->size_scaler <<= 1;
983cabdff1aSopenharmony_ci    }
984cabdff1aSopenharmony_ci
985cabdff1aSopenharmony_ci    s->slice_min_bytes = s->slice_max_bytes - s->slice_max_bytes*(s->tolerance/100.0f);
986cabdff1aSopenharmony_ci    if (s->slice_min_bytes < 0)
987cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
988cabdff1aSopenharmony_ci
989cabdff1aSopenharmony_ci    ret = encode_frame(s, avpkt, frame, aux_data, header_size, s->interlaced);
990cabdff1aSopenharmony_ci    if (ret)
991cabdff1aSopenharmony_ci        return ret;
992cabdff1aSopenharmony_ci    if (s->interlaced) {
993cabdff1aSopenharmony_ci        ret = encode_frame(s, avpkt, frame, aux_data, header_size, 2);
994cabdff1aSopenharmony_ci        if (ret)
995cabdff1aSopenharmony_ci            return ret;
996cabdff1aSopenharmony_ci    }
997cabdff1aSopenharmony_ci
998cabdff1aSopenharmony_ci    flush_put_bits(&s->pb);
999cabdff1aSopenharmony_ci    av_shrink_packet(avpkt, put_bytes_output(&s->pb));
1000cabdff1aSopenharmony_ci
1001cabdff1aSopenharmony_ci    *got_packet = 1;
1002cabdff1aSopenharmony_ci
1003cabdff1aSopenharmony_ci    return 0;
1004cabdff1aSopenharmony_ci}
1005cabdff1aSopenharmony_ci
1006cabdff1aSopenharmony_cistatic av_cold int vc2_encode_end(AVCodecContext *avctx)
1007cabdff1aSopenharmony_ci{
1008cabdff1aSopenharmony_ci    int i;
1009cabdff1aSopenharmony_ci    VC2EncContext *s = avctx->priv_data;
1010cabdff1aSopenharmony_ci
1011cabdff1aSopenharmony_ci    av_log(avctx, AV_LOG_INFO, "Qavg: %i\n", s->q_avg);
1012cabdff1aSopenharmony_ci
1013cabdff1aSopenharmony_ci    for (i = 0; i < 3; i++) {
1014cabdff1aSopenharmony_ci        ff_vc2enc_free_transforms(&s->transform_args[i].t);
1015cabdff1aSopenharmony_ci        av_freep(&s->plane[i].coef_buf);
1016cabdff1aSopenharmony_ci    }
1017cabdff1aSopenharmony_ci
1018cabdff1aSopenharmony_ci    av_freep(&s->slice_args);
1019cabdff1aSopenharmony_ci
1020cabdff1aSopenharmony_ci    return 0;
1021cabdff1aSopenharmony_ci}
1022cabdff1aSopenharmony_ci
1023cabdff1aSopenharmony_cistatic av_cold int vc2_encode_init(AVCodecContext *avctx)
1024cabdff1aSopenharmony_ci{
1025cabdff1aSopenharmony_ci    Plane *p;
1026cabdff1aSopenharmony_ci    SubBand *b;
1027cabdff1aSopenharmony_ci    int i, level, o, shift, ret;
1028cabdff1aSopenharmony_ci    const AVPixFmtDescriptor *fmt = av_pix_fmt_desc_get(avctx->pix_fmt);
1029cabdff1aSopenharmony_ci    const int depth = fmt->comp[0].depth;
1030cabdff1aSopenharmony_ci    VC2EncContext *s = avctx->priv_data;
1031cabdff1aSopenharmony_ci
1032cabdff1aSopenharmony_ci    s->picture_number = 0;
1033cabdff1aSopenharmony_ci
1034cabdff1aSopenharmony_ci    /* Total allowed quantization range */
1035cabdff1aSopenharmony_ci    s->q_ceil    = DIRAC_MAX_QUANT_INDEX;
1036cabdff1aSopenharmony_ci
1037cabdff1aSopenharmony_ci    s->ver.major = 2;
1038cabdff1aSopenharmony_ci    s->ver.minor = 0;
1039cabdff1aSopenharmony_ci    s->profile   = 3;
1040cabdff1aSopenharmony_ci    s->level     = 3;
1041cabdff1aSopenharmony_ci
1042cabdff1aSopenharmony_ci    s->base_vf   = -1;
1043cabdff1aSopenharmony_ci    s->strict_compliance = 1;
1044cabdff1aSopenharmony_ci
1045cabdff1aSopenharmony_ci    s->q_avg = 0;
1046cabdff1aSopenharmony_ci    s->slice_max_bytes = 0;
1047cabdff1aSopenharmony_ci    s->slice_min_bytes = 0;
1048cabdff1aSopenharmony_ci
1049cabdff1aSopenharmony_ci    /* Mark unknown as progressive */
1050cabdff1aSopenharmony_ci    s->interlaced = !((avctx->field_order == AV_FIELD_UNKNOWN) ||
1051cabdff1aSopenharmony_ci                      (avctx->field_order == AV_FIELD_PROGRESSIVE));
1052cabdff1aSopenharmony_ci
1053cabdff1aSopenharmony_ci    for (i = 0; i < base_video_fmts_len; i++) {
1054cabdff1aSopenharmony_ci        const VC2BaseVideoFormat *fmt = &base_video_fmts[i];
1055cabdff1aSopenharmony_ci        if (avctx->pix_fmt != fmt->pix_fmt)
1056cabdff1aSopenharmony_ci            continue;
1057cabdff1aSopenharmony_ci        if (avctx->time_base.num != fmt->time_base.num)
1058cabdff1aSopenharmony_ci            continue;
1059cabdff1aSopenharmony_ci        if (avctx->time_base.den != fmt->time_base.den)
1060cabdff1aSopenharmony_ci            continue;
1061cabdff1aSopenharmony_ci        if (avctx->width != fmt->width)
1062cabdff1aSopenharmony_ci            continue;
1063cabdff1aSopenharmony_ci        if (avctx->height != fmt->height)
1064cabdff1aSopenharmony_ci            continue;
1065cabdff1aSopenharmony_ci        if (s->interlaced != fmt->interlaced)
1066cabdff1aSopenharmony_ci            continue;
1067cabdff1aSopenharmony_ci        s->base_vf = i;
1068cabdff1aSopenharmony_ci        s->level   = base_video_fmts[i].level;
1069cabdff1aSopenharmony_ci        break;
1070cabdff1aSopenharmony_ci    }
1071cabdff1aSopenharmony_ci
1072cabdff1aSopenharmony_ci    if (s->interlaced)
1073cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_WARNING, "Interlacing enabled!\n");
1074cabdff1aSopenharmony_ci
1075cabdff1aSopenharmony_ci    if ((s->slice_width  & (s->slice_width  - 1)) ||
1076cabdff1aSopenharmony_ci        (s->slice_height & (s->slice_height - 1))) {
1077cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Slice size is not a power of two!\n");
1078cabdff1aSopenharmony_ci        return AVERROR_UNKNOWN;
1079cabdff1aSopenharmony_ci    }
1080cabdff1aSopenharmony_ci
1081cabdff1aSopenharmony_ci    if ((s->slice_width > avctx->width) ||
1082cabdff1aSopenharmony_ci        (s->slice_height > avctx->height)) {
1083cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Slice size is bigger than the image!\n");
1084cabdff1aSopenharmony_ci        return AVERROR_UNKNOWN;
1085cabdff1aSopenharmony_ci    }
1086cabdff1aSopenharmony_ci
1087cabdff1aSopenharmony_ci    if (s->base_vf <= 0) {
1088cabdff1aSopenharmony_ci        if (avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) {
1089cabdff1aSopenharmony_ci            s->strict_compliance = s->base_vf = 0;
1090cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING, "Format does not strictly comply with VC2 specs\n");
1091cabdff1aSopenharmony_ci        } else {
1092cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_WARNING, "Given format does not strictly comply with "
1093cabdff1aSopenharmony_ci                   "the specifications, decrease strictness to use it.\n");
1094cabdff1aSopenharmony_ci            return AVERROR_UNKNOWN;
1095cabdff1aSopenharmony_ci        }
1096cabdff1aSopenharmony_ci    } else {
1097cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_INFO, "Selected base video format = %i (%s)\n",
1098cabdff1aSopenharmony_ci               s->base_vf, base_video_fmts[s->base_vf].name);
1099cabdff1aSopenharmony_ci    }
1100cabdff1aSopenharmony_ci
1101cabdff1aSopenharmony_ci    /* Chroma subsampling */
1102cabdff1aSopenharmony_ci    ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
1103cabdff1aSopenharmony_ci    if (ret)
1104cabdff1aSopenharmony_ci        return ret;
1105cabdff1aSopenharmony_ci
1106cabdff1aSopenharmony_ci    /* Bit depth and color range index */
1107cabdff1aSopenharmony_ci    if (depth == 8 && avctx->color_range == AVCOL_RANGE_JPEG) {
1108cabdff1aSopenharmony_ci        s->bpp = 1;
1109cabdff1aSopenharmony_ci        s->bpp_idx = 1;
1110cabdff1aSopenharmony_ci        s->diff_offset = 128;
1111cabdff1aSopenharmony_ci    } else if (depth == 8 && (avctx->color_range == AVCOL_RANGE_MPEG ||
1112cabdff1aSopenharmony_ci               avctx->color_range == AVCOL_RANGE_UNSPECIFIED)) {
1113cabdff1aSopenharmony_ci        s->bpp = 1;
1114cabdff1aSopenharmony_ci        s->bpp_idx = 2;
1115cabdff1aSopenharmony_ci        s->diff_offset = 128;
1116cabdff1aSopenharmony_ci    } else if (depth == 10) {
1117cabdff1aSopenharmony_ci        s->bpp = 2;
1118cabdff1aSopenharmony_ci        s->bpp_idx = 3;
1119cabdff1aSopenharmony_ci        s->diff_offset = 512;
1120cabdff1aSopenharmony_ci    } else {
1121cabdff1aSopenharmony_ci        s->bpp = 2;
1122cabdff1aSopenharmony_ci        s->bpp_idx = 4;
1123cabdff1aSopenharmony_ci        s->diff_offset = 2048;
1124cabdff1aSopenharmony_ci    }
1125cabdff1aSopenharmony_ci
1126cabdff1aSopenharmony_ci    /* Planes initialization */
1127cabdff1aSopenharmony_ci    for (i = 0; i < 3; i++) {
1128cabdff1aSopenharmony_ci        int w, h;
1129cabdff1aSopenharmony_ci        p = &s->plane[i];
1130cabdff1aSopenharmony_ci        p->width      = avctx->width  >> (i ? s->chroma_x_shift : 0);
1131cabdff1aSopenharmony_ci        p->height     = avctx->height >> (i ? s->chroma_y_shift : 0);
1132cabdff1aSopenharmony_ci        if (s->interlaced)
1133cabdff1aSopenharmony_ci            p->height >>= 1;
1134cabdff1aSopenharmony_ci        p->dwt_width  = w = FFALIGN(p->width,  (1 << s->wavelet_depth));
1135cabdff1aSopenharmony_ci        p->dwt_height = h = FFALIGN(p->height, (1 << s->wavelet_depth));
1136cabdff1aSopenharmony_ci        p->coef_stride = FFALIGN(p->dwt_width, 32);
1137cabdff1aSopenharmony_ci        p->coef_buf = av_mallocz(p->coef_stride*p->dwt_height*sizeof(dwtcoef));
1138cabdff1aSopenharmony_ci        if (!p->coef_buf)
1139cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
1140cabdff1aSopenharmony_ci        for (level = s->wavelet_depth-1; level >= 0; level--) {
1141cabdff1aSopenharmony_ci            w = w >> 1;
1142cabdff1aSopenharmony_ci            h = h >> 1;
1143cabdff1aSopenharmony_ci            for (o = 0; o < 4; o++) {
1144cabdff1aSopenharmony_ci                b = &p->band[level][o];
1145cabdff1aSopenharmony_ci                b->width  = w;
1146cabdff1aSopenharmony_ci                b->height = h;
1147cabdff1aSopenharmony_ci                b->stride = p->coef_stride;
1148cabdff1aSopenharmony_ci                shift = (o > 1)*b->height*b->stride + (o & 1)*b->width;
1149cabdff1aSopenharmony_ci                b->buf = p->coef_buf + shift;
1150cabdff1aSopenharmony_ci            }
1151cabdff1aSopenharmony_ci        }
1152cabdff1aSopenharmony_ci
1153cabdff1aSopenharmony_ci        /* DWT init */
1154cabdff1aSopenharmony_ci        if (ff_vc2enc_init_transforms(&s->transform_args[i].t,
1155cabdff1aSopenharmony_ci                                      s->plane[i].coef_stride,
1156cabdff1aSopenharmony_ci                                      s->plane[i].dwt_height,
1157cabdff1aSopenharmony_ci                                      s->slice_width, s->slice_height))
1158cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
1159cabdff1aSopenharmony_ci    }
1160cabdff1aSopenharmony_ci
1161cabdff1aSopenharmony_ci    /* Slices */
1162cabdff1aSopenharmony_ci    s->num_x = s->plane[0].dwt_width/s->slice_width;
1163cabdff1aSopenharmony_ci    s->num_y = s->plane[0].dwt_height/s->slice_height;
1164cabdff1aSopenharmony_ci
1165cabdff1aSopenharmony_ci    s->slice_args = av_calloc(s->num_x*s->num_y, sizeof(SliceArgs));
1166cabdff1aSopenharmony_ci    if (!s->slice_args)
1167cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
1168cabdff1aSopenharmony_ci
1169cabdff1aSopenharmony_ci    for (i = 0; i < 116; i++) {
1170cabdff1aSopenharmony_ci        const uint64_t qf = ff_dirac_qscale_tab[i];
1171cabdff1aSopenharmony_ci        const uint32_t m = av_log2(qf);
1172cabdff1aSopenharmony_ci        const uint32_t t = (1ULL << (m + 32)) / qf;
1173cabdff1aSopenharmony_ci        const uint32_t r = (t*qf + qf) & UINT32_MAX;
1174cabdff1aSopenharmony_ci        if (!(qf & (qf - 1))) {
1175cabdff1aSopenharmony_ci            s->qmagic_lut[i][0] = 0xFFFFFFFF;
1176cabdff1aSopenharmony_ci            s->qmagic_lut[i][1] = 0xFFFFFFFF;
1177cabdff1aSopenharmony_ci        } else if (r <= 1 << m) {
1178cabdff1aSopenharmony_ci            s->qmagic_lut[i][0] = t + 1;
1179cabdff1aSopenharmony_ci            s->qmagic_lut[i][1] = 0;
1180cabdff1aSopenharmony_ci        } else {
1181cabdff1aSopenharmony_ci            s->qmagic_lut[i][0] = t;
1182cabdff1aSopenharmony_ci            s->qmagic_lut[i][1] = t;
1183cabdff1aSopenharmony_ci        }
1184cabdff1aSopenharmony_ci    }
1185cabdff1aSopenharmony_ci
1186cabdff1aSopenharmony_ci    return 0;
1187cabdff1aSopenharmony_ci}
1188cabdff1aSopenharmony_ci
1189cabdff1aSopenharmony_ci#define VC2ENC_FLAGS (AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
1190cabdff1aSopenharmony_cistatic const AVOption vc2enc_options[] = {
1191cabdff1aSopenharmony_ci    {"tolerance",     "Max undershoot in percent", offsetof(VC2EncContext, tolerance), AV_OPT_TYPE_DOUBLE, {.dbl = 5.0f}, 0.0f, 45.0f, VC2ENC_FLAGS, "tolerance"},
1192cabdff1aSopenharmony_ci    {"slice_width",   "Slice width",  offsetof(VC2EncContext, slice_width), AV_OPT_TYPE_INT, {.i64 = 32}, 32, 1024, VC2ENC_FLAGS, "slice_width"},
1193cabdff1aSopenharmony_ci    {"slice_height",  "Slice height", offsetof(VC2EncContext, slice_height), AV_OPT_TYPE_INT, {.i64 = 16}, 8, 1024, VC2ENC_FLAGS, "slice_height"},
1194cabdff1aSopenharmony_ci    {"wavelet_depth", "Transform depth", offsetof(VC2EncContext, wavelet_depth), AV_OPT_TYPE_INT, {.i64 = 4}, 1, 5, VC2ENC_FLAGS, "wavelet_depth"},
1195cabdff1aSopenharmony_ci    {"wavelet_type",  "Transform type",  offsetof(VC2EncContext, wavelet_idx), AV_OPT_TYPE_INT, {.i64 = VC2_TRANSFORM_9_7}, 0, VC2_TRANSFORMS_NB, VC2ENC_FLAGS, "wavelet_idx"},
1196cabdff1aSopenharmony_ci        {"9_7",          "Deslauriers-Dubuc (9,7)", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_9_7},    INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"},
1197cabdff1aSopenharmony_ci        {"5_3",          "LeGall (5,3)",            0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_5_3},    INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"},
1198cabdff1aSopenharmony_ci        {"haar",         "Haar (with shift)",       0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_HAAR_S}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"},
1199cabdff1aSopenharmony_ci        {"haar_noshift", "Haar (without shift)",    0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_HAAR},   INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"},
1200cabdff1aSopenharmony_ci    {"qm", "Custom quantization matrix", offsetof(VC2EncContext, quant_matrix), AV_OPT_TYPE_INT, {.i64 = VC2_QM_DEF}, 0, VC2_QM_NB, VC2ENC_FLAGS, "quant_matrix"},
1201cabdff1aSopenharmony_ci        {"default",   "Default from the specifications", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_QM_DEF}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "quant_matrix"},
1202cabdff1aSopenharmony_ci        {"color",     "Prevents low bitrate discoloration", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_QM_COL}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "quant_matrix"},
1203cabdff1aSopenharmony_ci        {"flat",      "Optimize for PSNR", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_QM_FLAT}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "quant_matrix"},
1204cabdff1aSopenharmony_ci    {NULL}
1205cabdff1aSopenharmony_ci};
1206cabdff1aSopenharmony_ci
1207cabdff1aSopenharmony_cistatic const AVClass vc2enc_class = {
1208cabdff1aSopenharmony_ci    .class_name = "SMPTE VC-2 encoder",
1209cabdff1aSopenharmony_ci    .category = AV_CLASS_CATEGORY_ENCODER,
1210cabdff1aSopenharmony_ci    .option = vc2enc_options,
1211cabdff1aSopenharmony_ci    .item_name = av_default_item_name,
1212cabdff1aSopenharmony_ci    .version = LIBAVUTIL_VERSION_INT
1213cabdff1aSopenharmony_ci};
1214cabdff1aSopenharmony_ci
1215cabdff1aSopenharmony_cistatic const FFCodecDefault vc2enc_defaults[] = {
1216cabdff1aSopenharmony_ci    { "b",              "600000000"   },
1217cabdff1aSopenharmony_ci    { NULL },
1218cabdff1aSopenharmony_ci};
1219cabdff1aSopenharmony_ci
1220cabdff1aSopenharmony_cistatic const enum AVPixelFormat allowed_pix_fmts[] = {
1221cabdff1aSopenharmony_ci    AV_PIX_FMT_YUV420P,   AV_PIX_FMT_YUV422P,   AV_PIX_FMT_YUV444P,
1222cabdff1aSopenharmony_ci    AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
1223cabdff1aSopenharmony_ci    AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12,
1224cabdff1aSopenharmony_ci    AV_PIX_FMT_NONE
1225cabdff1aSopenharmony_ci};
1226cabdff1aSopenharmony_ci
1227cabdff1aSopenharmony_ciconst FFCodec ff_vc2_encoder = {
1228cabdff1aSopenharmony_ci    .p.name         = "vc2",
1229cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("SMPTE VC-2"),
1230cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
1231cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_DIRAC,
1232cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
1233cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1234cabdff1aSopenharmony_ci    .priv_data_size = sizeof(VC2EncContext),
1235cabdff1aSopenharmony_ci    .init           = vc2_encode_init,
1236cabdff1aSopenharmony_ci    .close          = vc2_encode_end,
1237cabdff1aSopenharmony_ci    FF_CODEC_ENCODE_CB(vc2_encode_frame),
1238cabdff1aSopenharmony_ci    .p.priv_class   = &vc2enc_class,
1239cabdff1aSopenharmony_ci    .defaults       = vc2enc_defaults,
1240cabdff1aSopenharmony_ci    .p.pix_fmts     = allowed_pix_fmts
1241cabdff1aSopenharmony_ci};
1242