1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * libkvazaar encoder
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * Copyright (c) 2015 Tampere University of Technology
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * This file is part of FFmpeg.
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16cabdff1aSopenharmony_ci * Lesser General Public License for more details.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21cabdff1aSopenharmony_ci */
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#include <kvazaar.h>
24cabdff1aSopenharmony_ci#include <stdint.h>
25cabdff1aSopenharmony_ci#include <string.h>
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#include "libavutil/attributes.h"
28cabdff1aSopenharmony_ci#include "libavutil/avassert.h"
29cabdff1aSopenharmony_ci#include "libavutil/dict.h"
30cabdff1aSopenharmony_ci#include "libavutil/error.h"
31cabdff1aSopenharmony_ci#include "libavutil/imgutils.h"
32cabdff1aSopenharmony_ci#include "libavutil/internal.h"
33cabdff1aSopenharmony_ci#include "libavutil/log.h"
34cabdff1aSopenharmony_ci#include "libavutil/mem.h"
35cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h"
36cabdff1aSopenharmony_ci#include "libavutil/opt.h"
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci#include "avcodec.h"
39cabdff1aSopenharmony_ci#include "codec_internal.h"
40cabdff1aSopenharmony_ci#include "encode.h"
41cabdff1aSopenharmony_ci#include "packet_internal.h"
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_citypedef struct LibkvazaarContext {
44cabdff1aSopenharmony_ci    const AVClass *class;
45cabdff1aSopenharmony_ci
46cabdff1aSopenharmony_ci    const kvz_api *api;
47cabdff1aSopenharmony_ci    kvz_encoder *encoder;
48cabdff1aSopenharmony_ci    kvz_config *config;
49cabdff1aSopenharmony_ci
50cabdff1aSopenharmony_ci    char *kvz_params;
51cabdff1aSopenharmony_ci} LibkvazaarContext;
52cabdff1aSopenharmony_ci
53cabdff1aSopenharmony_cistatic av_cold int libkvazaar_init(AVCodecContext *avctx)
54cabdff1aSopenharmony_ci{
55cabdff1aSopenharmony_ci    LibkvazaarContext *const ctx = avctx->priv_data;
56cabdff1aSopenharmony_ci    const kvz_api *const api = ctx->api = kvz_api_get(8);
57cabdff1aSopenharmony_ci    kvz_config *cfg = NULL;
58cabdff1aSopenharmony_ci    kvz_encoder *enc = NULL;
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_ci    /* Kvazaar requires width and height to be multiples of eight. */
61cabdff1aSopenharmony_ci    if (avctx->width % 8 || avctx->height % 8) {
62cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
63cabdff1aSopenharmony_ci               "Video dimensions are not a multiple of 8 (%dx%d).\n",
64cabdff1aSopenharmony_ci               avctx->width, avctx->height);
65cabdff1aSopenharmony_ci        return AVERROR(ENOSYS);
66cabdff1aSopenharmony_ci    }
67cabdff1aSopenharmony_ci
68cabdff1aSopenharmony_ci    ctx->config = cfg = api->config_alloc();
69cabdff1aSopenharmony_ci    if (!cfg) {
70cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
71cabdff1aSopenharmony_ci               "Could not allocate kvazaar config structure.\n");
72cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
73cabdff1aSopenharmony_ci    }
74cabdff1aSopenharmony_ci
75cabdff1aSopenharmony_ci    if (!api->config_init(cfg)) {
76cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
77cabdff1aSopenharmony_ci               "Could not initialize kvazaar config structure.\n");
78cabdff1aSopenharmony_ci        return AVERROR_BUG;
79cabdff1aSopenharmony_ci    }
80cabdff1aSopenharmony_ci
81cabdff1aSopenharmony_ci    cfg->width  = avctx->width;
82cabdff1aSopenharmony_ci    cfg->height = avctx->height;
83cabdff1aSopenharmony_ci
84cabdff1aSopenharmony_ci    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
85cabdff1aSopenharmony_ci        cfg->framerate_num   = avctx->framerate.num;
86cabdff1aSopenharmony_ci        cfg->framerate_denom = avctx->framerate.den;
87cabdff1aSopenharmony_ci    } else {
88cabdff1aSopenharmony_ci        if (avctx->ticks_per_frame > INT_MAX / avctx->time_base.num) {
89cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR,
90cabdff1aSopenharmony_ci                   "Could not set framerate for kvazaar: integer overflow\n");
91cabdff1aSopenharmony_ci            return AVERROR(EINVAL);
92cabdff1aSopenharmony_ci        }
93cabdff1aSopenharmony_ci        cfg->framerate_num   = avctx->time_base.den;
94cabdff1aSopenharmony_ci        cfg->framerate_denom = avctx->time_base.num * avctx->ticks_per_frame;
95cabdff1aSopenharmony_ci    }
96cabdff1aSopenharmony_ci    cfg->target_bitrate = avctx->bit_rate;
97cabdff1aSopenharmony_ci    cfg->vui.sar_width  = avctx->sample_aspect_ratio.num;
98cabdff1aSopenharmony_ci    cfg->vui.sar_height = avctx->sample_aspect_ratio.den;
99cabdff1aSopenharmony_ci    if (avctx->bit_rate) {
100cabdff1aSopenharmony_ci        cfg->rc_algorithm = KVZ_LAMBDA;
101cabdff1aSopenharmony_ci    }
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_ci    if (ctx->kvz_params) {
104cabdff1aSopenharmony_ci        AVDictionary *dict = NULL;
105cabdff1aSopenharmony_ci        if (!av_dict_parse_string(&dict, ctx->kvz_params, "=", ",", 0)) {
106cabdff1aSopenharmony_ci            AVDictionaryEntry *entry = NULL;
107cabdff1aSopenharmony_ci            while ((entry = av_dict_get(dict, "", entry, AV_DICT_IGNORE_SUFFIX))) {
108cabdff1aSopenharmony_ci                if (!api->config_parse(cfg, entry->key, entry->value)) {
109cabdff1aSopenharmony_ci                    av_log(avctx, AV_LOG_WARNING, "Invalid option: %s=%s.\n",
110cabdff1aSopenharmony_ci                           entry->key, entry->value);
111cabdff1aSopenharmony_ci                }
112cabdff1aSopenharmony_ci            }
113cabdff1aSopenharmony_ci        }
114cabdff1aSopenharmony_ci        av_dict_free(&dict);
115cabdff1aSopenharmony_ci    }
116cabdff1aSopenharmony_ci
117cabdff1aSopenharmony_ci    ctx->encoder = enc = api->encoder_open(cfg);
118cabdff1aSopenharmony_ci    if (!enc) {
119cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Could not open kvazaar encoder.\n");
120cabdff1aSopenharmony_ci        return AVERROR_BUG;
121cabdff1aSopenharmony_ci    }
122cabdff1aSopenharmony_ci
123cabdff1aSopenharmony_ci    if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
124cabdff1aSopenharmony_ci        kvz_data_chunk *data_out = NULL;
125cabdff1aSopenharmony_ci        kvz_data_chunk *chunk = NULL;
126cabdff1aSopenharmony_ci        uint32_t len_out;
127cabdff1aSopenharmony_ci        uint8_t *p;
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci        if (!api->encoder_headers(enc, &data_out, &len_out))
130cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci        avctx->extradata = p = av_mallocz(len_out + AV_INPUT_BUFFER_PADDING_SIZE);
133cabdff1aSopenharmony_ci        if (!p) {
134cabdff1aSopenharmony_ci            ctx->api->chunk_free(data_out);
135cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
136cabdff1aSopenharmony_ci        }
137cabdff1aSopenharmony_ci
138cabdff1aSopenharmony_ci        avctx->extradata_size = len_out;
139cabdff1aSopenharmony_ci
140cabdff1aSopenharmony_ci        for (chunk = data_out; chunk != NULL; chunk = chunk->next) {
141cabdff1aSopenharmony_ci            memcpy(p, chunk->data, chunk->len);
142cabdff1aSopenharmony_ci            p += chunk->len;
143cabdff1aSopenharmony_ci        }
144cabdff1aSopenharmony_ci
145cabdff1aSopenharmony_ci        ctx->api->chunk_free(data_out);
146cabdff1aSopenharmony_ci    }
147cabdff1aSopenharmony_ci
148cabdff1aSopenharmony_ci    return 0;
149cabdff1aSopenharmony_ci}
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_cistatic av_cold int libkvazaar_close(AVCodecContext *avctx)
152cabdff1aSopenharmony_ci{
153cabdff1aSopenharmony_ci    LibkvazaarContext *ctx = avctx->priv_data;
154cabdff1aSopenharmony_ci
155cabdff1aSopenharmony_ci    if (ctx->api) {
156cabdff1aSopenharmony_ci        ctx->api->encoder_close(ctx->encoder);
157cabdff1aSopenharmony_ci        ctx->api->config_destroy(ctx->config);
158cabdff1aSopenharmony_ci    }
159cabdff1aSopenharmony_ci
160cabdff1aSopenharmony_ci    return 0;
161cabdff1aSopenharmony_ci}
162cabdff1aSopenharmony_ci
163cabdff1aSopenharmony_cistatic int libkvazaar_encode(AVCodecContext *avctx,
164cabdff1aSopenharmony_ci                             AVPacket *avpkt,
165cabdff1aSopenharmony_ci                             const AVFrame *frame,
166cabdff1aSopenharmony_ci                             int *got_packet_ptr)
167cabdff1aSopenharmony_ci{
168cabdff1aSopenharmony_ci    LibkvazaarContext *ctx = avctx->priv_data;
169cabdff1aSopenharmony_ci    kvz_picture *input_pic = NULL;
170cabdff1aSopenharmony_ci    kvz_picture *recon_pic = NULL;
171cabdff1aSopenharmony_ci    kvz_frame_info frame_info;
172cabdff1aSopenharmony_ci    kvz_data_chunk *data_out = NULL;
173cabdff1aSopenharmony_ci    uint32_t len_out = 0;
174cabdff1aSopenharmony_ci    int retval = 0;
175cabdff1aSopenharmony_ci    int pict_type;
176cabdff1aSopenharmony_ci
177cabdff1aSopenharmony_ci    *got_packet_ptr = 0;
178cabdff1aSopenharmony_ci
179cabdff1aSopenharmony_ci    if (frame) {
180cabdff1aSopenharmony_ci        if (frame->width != ctx->config->width ||
181cabdff1aSopenharmony_ci            frame->height != ctx->config->height) {
182cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR,
183cabdff1aSopenharmony_ci                   "Changing video dimensions during encoding is not supported. "
184cabdff1aSopenharmony_ci                   "(changed from %dx%d to %dx%d)\n",
185cabdff1aSopenharmony_ci                   ctx->config->width, ctx->config->height,
186cabdff1aSopenharmony_ci                   frame->width, frame->height);
187cabdff1aSopenharmony_ci            retval = AVERROR_INVALIDDATA;
188cabdff1aSopenharmony_ci            goto done;
189cabdff1aSopenharmony_ci        }
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_ci        if (frame->format != avctx->pix_fmt) {
192cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR,
193cabdff1aSopenharmony_ci                   "Changing pixel format during encoding is not supported. "
194cabdff1aSopenharmony_ci                   "(changed from %s to %s)\n",
195cabdff1aSopenharmony_ci                   av_get_pix_fmt_name(avctx->pix_fmt),
196cabdff1aSopenharmony_ci                   av_get_pix_fmt_name(frame->format));
197cabdff1aSopenharmony_ci            retval = AVERROR_INVALIDDATA;
198cabdff1aSopenharmony_ci            goto done;
199cabdff1aSopenharmony_ci        }
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci        // Allocate input picture for kvazaar.
202cabdff1aSopenharmony_ci        input_pic = ctx->api->picture_alloc(frame->width, frame->height);
203cabdff1aSopenharmony_ci        if (!input_pic) {
204cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "Failed to allocate picture.\n");
205cabdff1aSopenharmony_ci            retval = AVERROR(ENOMEM);
206cabdff1aSopenharmony_ci            goto done;
207cabdff1aSopenharmony_ci        }
208cabdff1aSopenharmony_ci
209cabdff1aSopenharmony_ci        // Copy pixels from frame to input_pic.
210cabdff1aSopenharmony_ci        {
211cabdff1aSopenharmony_ci            uint8_t *dst[4] = {
212cabdff1aSopenharmony_ci                input_pic->data[0],
213cabdff1aSopenharmony_ci                input_pic->data[1],
214cabdff1aSopenharmony_ci                input_pic->data[2],
215cabdff1aSopenharmony_ci                NULL,
216cabdff1aSopenharmony_ci            };
217cabdff1aSopenharmony_ci            int dst_linesizes[4] = {
218cabdff1aSopenharmony_ci              frame->width,
219cabdff1aSopenharmony_ci              frame->width / 2,
220cabdff1aSopenharmony_ci              frame->width / 2,
221cabdff1aSopenharmony_ci              0
222cabdff1aSopenharmony_ci            };
223cabdff1aSopenharmony_ci            av_image_copy(dst, dst_linesizes,
224cabdff1aSopenharmony_ci                          (const uint8_t **)frame->data, frame->linesize,
225cabdff1aSopenharmony_ci                          frame->format, frame->width, frame->height);
226cabdff1aSopenharmony_ci        }
227cabdff1aSopenharmony_ci
228cabdff1aSopenharmony_ci        input_pic->pts = frame->pts;
229cabdff1aSopenharmony_ci    }
230cabdff1aSopenharmony_ci
231cabdff1aSopenharmony_ci    retval = ctx->api->encoder_encode(ctx->encoder,
232cabdff1aSopenharmony_ci                                      input_pic,
233cabdff1aSopenharmony_ci                                      &data_out, &len_out,
234cabdff1aSopenharmony_ci                                      &recon_pic, NULL,
235cabdff1aSopenharmony_ci                                      &frame_info);
236cabdff1aSopenharmony_ci    if (!retval) {
237cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Failed to encode frame.\n");
238cabdff1aSopenharmony_ci        retval = AVERROR_INVALIDDATA;
239cabdff1aSopenharmony_ci        goto done;
240cabdff1aSopenharmony_ci    } else
241cabdff1aSopenharmony_ci        retval = 0; /* kvazaar returns 1 on success */
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_ci    if (data_out) {
244cabdff1aSopenharmony_ci        kvz_data_chunk *chunk = NULL;
245cabdff1aSopenharmony_ci        uint64_t written = 0;
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_ci        retval = ff_get_encode_buffer(avctx, avpkt, len_out, 0);
248cabdff1aSopenharmony_ci        if (retval < 0) {
249cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n");
250cabdff1aSopenharmony_ci            goto done;
251cabdff1aSopenharmony_ci        }
252cabdff1aSopenharmony_ci
253cabdff1aSopenharmony_ci        for (chunk = data_out; chunk != NULL; chunk = chunk->next) {
254cabdff1aSopenharmony_ci            av_assert0(written + chunk->len <= len_out);
255cabdff1aSopenharmony_ci            memcpy(avpkt->data + written, chunk->data, chunk->len);
256cabdff1aSopenharmony_ci            written += chunk->len;
257cabdff1aSopenharmony_ci        }
258cabdff1aSopenharmony_ci
259cabdff1aSopenharmony_ci        avpkt->pts = recon_pic->pts;
260cabdff1aSopenharmony_ci        avpkt->dts = recon_pic->dts;
261cabdff1aSopenharmony_ci        avpkt->flags = 0;
262cabdff1aSopenharmony_ci        // IRAP VCL NAL unit types span the range
263cabdff1aSopenharmony_ci        // [BLA_W_LP (16), RSV_IRAP_VCL23 (23)].
264cabdff1aSopenharmony_ci        if (frame_info.nal_unit_type >= KVZ_NAL_BLA_W_LP &&
265cabdff1aSopenharmony_ci            frame_info.nal_unit_type <= KVZ_NAL_RSV_IRAP_VCL23) {
266cabdff1aSopenharmony_ci            avpkt->flags |= AV_PKT_FLAG_KEY;
267cabdff1aSopenharmony_ci        }
268cabdff1aSopenharmony_ci
269cabdff1aSopenharmony_ci        switch (frame_info.slice_type) {
270cabdff1aSopenharmony_ci        case KVZ_SLICE_I:
271cabdff1aSopenharmony_ci            pict_type = AV_PICTURE_TYPE_I;
272cabdff1aSopenharmony_ci            break;
273cabdff1aSopenharmony_ci        case KVZ_SLICE_P:
274cabdff1aSopenharmony_ci            pict_type = AV_PICTURE_TYPE_P;
275cabdff1aSopenharmony_ci            break;
276cabdff1aSopenharmony_ci        case KVZ_SLICE_B:
277cabdff1aSopenharmony_ci            pict_type = AV_PICTURE_TYPE_B;
278cabdff1aSopenharmony_ci            break;
279cabdff1aSopenharmony_ci        default:
280cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered.\n");
281cabdff1aSopenharmony_ci            return AVERROR_EXTERNAL;
282cabdff1aSopenharmony_ci        }
283cabdff1aSopenharmony_ci
284cabdff1aSopenharmony_ci        ff_side_data_set_encoder_stats(avpkt, frame_info.qp * FF_QP2LAMBDA, NULL, 0, pict_type);
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_ci        *got_packet_ptr = 1;
287cabdff1aSopenharmony_ci    }
288cabdff1aSopenharmony_ci
289cabdff1aSopenharmony_cidone:
290cabdff1aSopenharmony_ci    ctx->api->picture_free(input_pic);
291cabdff1aSopenharmony_ci    ctx->api->picture_free(recon_pic);
292cabdff1aSopenharmony_ci    ctx->api->chunk_free(data_out);
293cabdff1aSopenharmony_ci    return retval;
294cabdff1aSopenharmony_ci}
295cabdff1aSopenharmony_ci
296cabdff1aSopenharmony_cistatic const enum AVPixelFormat pix_fmts[] = {
297cabdff1aSopenharmony_ci    AV_PIX_FMT_YUV420P,
298cabdff1aSopenharmony_ci    AV_PIX_FMT_NONE
299cabdff1aSopenharmony_ci};
300cabdff1aSopenharmony_ci
301cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(LibkvazaarContext, x)
302cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
303cabdff1aSopenharmony_cistatic const AVOption options[] = {
304cabdff1aSopenharmony_ci    { "kvazaar-params", "Set kvazaar parameters as a comma-separated list of key=value pairs.",
305cabdff1aSopenharmony_ci        OFFSET(kvz_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE },
306cabdff1aSopenharmony_ci    { NULL },
307cabdff1aSopenharmony_ci};
308cabdff1aSopenharmony_ci
309cabdff1aSopenharmony_cistatic const AVClass class = {
310cabdff1aSopenharmony_ci    .class_name = "libkvazaar",
311cabdff1aSopenharmony_ci    .item_name  = av_default_item_name,
312cabdff1aSopenharmony_ci    .option     = options,
313cabdff1aSopenharmony_ci    .version    = LIBAVUTIL_VERSION_INT,
314cabdff1aSopenharmony_ci};
315cabdff1aSopenharmony_ci
316cabdff1aSopenharmony_cistatic const FFCodecDefault defaults[] = {
317cabdff1aSopenharmony_ci    { "b", "0" },
318cabdff1aSopenharmony_ci    { NULL },
319cabdff1aSopenharmony_ci};
320cabdff1aSopenharmony_ci
321cabdff1aSopenharmony_ciconst FFCodec ff_libkvazaar_encoder = {
322cabdff1aSopenharmony_ci    .p.name           = "libkvazaar",
323cabdff1aSopenharmony_ci    .p.long_name      = NULL_IF_CONFIG_SMALL("libkvazaar H.265 / HEVC"),
324cabdff1aSopenharmony_ci    .p.type           = AVMEDIA_TYPE_VIDEO,
325cabdff1aSopenharmony_ci    .p.id             = AV_CODEC_ID_HEVC,
326cabdff1aSopenharmony_ci    .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
327cabdff1aSopenharmony_ci                        AV_CODEC_CAP_OTHER_THREADS,
328cabdff1aSopenharmony_ci    .p.pix_fmts       = pix_fmts,
329cabdff1aSopenharmony_ci
330cabdff1aSopenharmony_ci    .p.priv_class     = &class,
331cabdff1aSopenharmony_ci    .priv_data_size   = sizeof(LibkvazaarContext),
332cabdff1aSopenharmony_ci    .defaults         = defaults,
333cabdff1aSopenharmony_ci
334cabdff1aSopenharmony_ci    .init             = libkvazaar_init,
335cabdff1aSopenharmony_ci    FF_CODEC_ENCODE_CB(libkvazaar_encode),
336cabdff1aSopenharmony_ci    .close            = libkvazaar_close,
337cabdff1aSopenharmony_ci
338cabdff1aSopenharmony_ci    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
339cabdff1aSopenharmony_ci                        FF_CODEC_CAP_AUTO_THREADS,
340cabdff1aSopenharmony_ci
341cabdff1aSopenharmony_ci    .p.wrapper_name   = "libkvazaar",
342cabdff1aSopenharmony_ci};
343