FFmpeg
Loading...
Searching...
No Matches
liboapvenc.c
Go to the documentation of this file.
1/*
2 * liboapv encoder
3 * Advanced Professional Video codec library
4 *
5 * Copyright (C) 2025 Dawid Kozinski <d.kozinski@samsung.com>
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <stdint.h>
25#include <stdlib.h>
26
27#include <oapv/oapv.h>
28
29#include "libavutil/avassert.h"
31#include "libavutil/imgutils.h"
32#include "libavutil/internal.h"
33#include "libavutil/mem.h"
34#include "libavutil/opt.h"
35#include "libavutil/pixdesc.h"
36#include "libavutil/pixfmt.h"
38
39#include "avcodec.h"
40#include "apv.h"
41#include "codec_internal.h"
42#include "encode.h"
43#include "profiles.h"
44
45#define MAX_BS_BUF (128 * 1024 * 1024)
46#define MAX_NUM_FRMS (1) // supports only 1-frame in an access unit
47#define FRM_IDX (0) // supports only 1-frame in an access unit
48#define MAX_NUM_CC (OAPV_MAX_CC) // Max number of color components (upto 4:4:4:4)
49
50#define MAX_METADATA_PAYLOADS (8)
51
53{
54 return av_rescale(a.num, b, a.den);
55}
56
57/**
58 * The structure stores all the states associated with the instance of APV encoder
59 */
60typedef struct ApvEncContext {
61 const AVClass *class;
62
63 oapve_t id; // APV instance identifier
64 oapvm_t mid;
65 oapve_cdesc_t cdsc; // coding parameters i.e profile, width & height of input frame, num of therads, frame rate ...
66 oapv_bitb_t bitb; // bitstream buffer (output)
67 oapve_stat_t stat; // encoding status (output)
68
69 oapv_frms_t ifrms; // frames for input
70
71 int preset_id; // preset of apv ( fastest, fast, medium, slow, placebo)
72
73 int qp; // quantization parameter (QP) [0,63]
74
75 oapvm_payload_mdcv_t mdcv;
76 oapvm_payload_cll_t cll;
77
78 oapvm_payload_t *payloads;
79 unsigned nb_payloads;
80
83
84static int apv_imgb_release(oapv_imgb_t *imgb)
85{
86 int refcnt = --imgb->refcnt;
87 if (refcnt == 0) {
88 for (int i = 0; i < imgb->np; i++)
89 av_freep(&imgb->baddr[i]);
90 av_free(imgb);
91 }
92
93 return refcnt;
94}
95
96static int apv_imgb_addref(oapv_imgb_t * imgb)
97{
98 int refcnt = ++imgb->refcnt;
99 return refcnt;
100}
101
102static int apv_imgb_getref(oapv_imgb_t * imgb)
103{
104 return imgb->refcnt;
105}
106
107/**
108 * Convert FFmpeg pixel format (AVPixelFormat) into APV pre-defined color format
109 *
110 * @return APV pre-defined color format (@see oapv.h) on success, OAPV_CF_UNKNOWN on failure
111 */
113{
114 switch (pix_fmt) {
115 default:
116 av_unreachable("Already checked via CODEC_PIXFMTS");
118 return OAPV_CF_YCBCR400;
120 return OAPV_CF_YCBCR422;
122 return OAPV_CF_YCBCR422;
124 return OAPV_CF_YCBCR444;
126 return OAPV_CF_YCBCR444;
128 return OAPV_CF_YCBCR4444;
130 return OAPV_CF_YCBCR4444;
131 }
132}
133
135{
136 switch (pix_fmt) {
137 default:
138 av_unreachable("Already checked via CODEC_PIXFMTS");
150 }
151}
152
153static inline int get_min_profile(enum AVPixelFormat pix_fmt)
154{
155 switch (pix_fmt) {
156 default:
157 av_unreachable("Already checked via CODEC_PIXFMTS");
172 }
173}
174
176{
178 const int chroma_format_idc = get_chroma_format_idc(pix_fmt);
179 const int bit_depth = desc->comp[0].depth;
180
182
183 switch (profile) {
185 return chroma_format_idc == APV_CHROMA_FORMAT_422 && bit_depth == 10;
187 return chroma_format_idc == APV_CHROMA_FORMAT_422 &&
188 bit_depth >= 10 && bit_depth <= 12;
190 return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
191 chroma_format_idc <= APV_CHROMA_FORMAT_444 &&
192 bit_depth == 10;
194 return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
195 chroma_format_idc <= APV_CHROMA_FORMAT_444 &&
196 bit_depth >= 10 && bit_depth <= 12;
198 return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
199 chroma_format_idc <= APV_CHROMA_FORMAT_4444 &&
200 bit_depth == 10;
202 return chroma_format_idc >= APV_CHROMA_FORMAT_422 &&
203 chroma_format_idc <= APV_CHROMA_FORMAT_4444 &&
204 bit_depth >= 10 && bit_depth <= 12;
206 return chroma_format_idc == APV_CHROMA_FORMAT_400 && bit_depth == 10;
207 default:
208 return 0;
209 }
210}
211
213{
214 const int minimum = get_min_profile(avctx->pix_fmt);
215 const char *profile_name = av_get_profile_name(avctx->codec, profile);
216 const char *minimum_name = av_get_profile_name(avctx->codec, minimum);
217
218 if (!profile_is_compatible(avctx->pix_fmt, profile)) {
219 av_log(avctx, AV_LOG_ERROR,
220 "Profile %s (%d) is incompatible with pixel format %s; minimum compatible profile is %s (%d)\n",
221 profile_name ? profile_name : "unknown", profile,
223 minimum_name ? minimum_name : "unknown", minimum);
224 return AVERROR(EINVAL);
225 }
226
227 return 0;
228}
229
230static oapv_imgb_t *apv_imgb_create(AVCodecContext *avctx)
231{
233 oapv_imgb_t *imgb;
234 int input_depth;
235 int cfmt; // color format
236 int cs;
237
239
240 imgb = av_mallocz(sizeof(oapv_imgb_t));
241 if (!imgb)
242 goto fail;
243
244 input_depth = desc->comp[0].depth;
245 cfmt = get_color_format(avctx->pix_fmt);
246 cs = OAPV_CS_SET(cfmt, input_depth, AV_HAVE_BIGENDIAN);
247
248 imgb->np = desc->nb_components;
249
250 for (int i = 0; i < imgb->np; i++) {
251 imgb->w[i] = avctx->width >> ((i == 1 || i == 2) ? desc->log2_chroma_w : 0);
252 imgb->h[i] = avctx->height;
253 imgb->aw[i] = FFALIGN(imgb->w[i], OAPV_MB_W);
254 imgb->ah[i] = FFALIGN(imgb->h[i], OAPV_MB_H);
255 imgb->s[i] = imgb->aw[i] * OAPV_CS_GET_BYTE_DEPTH(cs);
256
257 imgb->bsize[i] = imgb->e[i] = imgb->s[i] * imgb->ah[i];
258 imgb->a[i] = imgb->baddr[i] = av_mallocz(imgb->bsize[i]);
259 if (imgb->a[i] == NULL)
260 goto fail;
261 }
262
263 imgb->cs = cs;
264 imgb->addref = apv_imgb_addref;
265 imgb->getref = apv_imgb_getref;
266 imgb->release = apv_imgb_release;
267 imgb->refcnt = 1;
268
269 return imgb;
270fail:
271 av_log(avctx, AV_LOG_ERROR, "cannot create image buffer\n");
272 if (imgb) {
273 for (int i = 0; i < imgb->np; i++)
274 av_freep(&imgb->a[i]);
275 av_freep(&imgb);
276 }
277 return NULL;
278}
279
281 uint32_t group_id, uint32_t type, const void *data, uint32_t size)
282{
283 oapvm_payload_t *tmp;
284
285 if (apv->nb_payloads >= MAX_METADATA_PAYLOADS || !data || size == 0) {
286 return AVERROR_INVALIDDATA;
287 }
288
289 tmp = av_realloc_array(apv->payloads, apv->nb_payloads + 1, sizeof(oapvm_payload_t));
290 if (!tmp) {
291 return AVERROR(ENOMEM);
292 }
293 apv->payloads = tmp;
294
295 // Copying data into internal buffer
296 void *new_data = av_malloc(size);
297 if (!new_data) {
298 return AVERROR(ENOMEM);
299 }
300 memcpy(new_data, data, size);
301
302 apv->payloads[apv->nb_payloads].group_id = group_id;
303 apv->payloads[apv->nb_payloads].type = type;
304 apv->payloads[apv->nb_payloads].size = size;
305 apv->payloads[apv->nb_payloads].data = new_data;
306 apv->nb_payloads++;
307
308 return 0;
309}
310
311/**
312 * Populate the liboapv configuration from AVCodecContext and encoder options.
313 *
314 * AVCodecContext fields are applied first, followed by liboapv private options
315 * and finally oapv-params. The APV profile defaults to the minimum profile
316 * implied by pix_fmt, and later overrides must remain compatible with that
317 * pixel format.
318 *
319 * @param[in] avctx codec context (AVCodecContext)
320 * @param[out] cdsc contains all APV encoder encoder parameters that should be initialized before the encoder is use
321 *
322 * @return 0 on success, negative error code on failure
323 */
324static int get_conf(AVCodecContext *avctx, oapve_cdesc_t *cdsc)
325{
326 ApvEncContext *apv = avctx->priv_data;
327
328 /* initialize apv_param struct with default values */
329 int ret = oapve_param_default(&cdsc->param[FRM_IDX]);
330 if (OAPV_FAILED(ret)) {
331 av_log(avctx, AV_LOG_ERROR, "Cannot set default parameter\n");
332 return AVERROR_EXTERNAL;
333 }
334
335 /* read options from AVCodecContext */
336 cdsc->param[FRM_IDX].w = avctx->width;
337 cdsc->param[FRM_IDX].h = avctx->height;
338
339 if (avctx->framerate.num > 0) {
340 cdsc->param[FRM_IDX].fps_num = avctx->framerate.num;
341 cdsc->param[FRM_IDX].fps_den = avctx->framerate.den;
342 } else if (avctx->time_base.num > 0) {
343 cdsc->param[FRM_IDX].fps_num = avctx->time_base.den;
344 cdsc->param[FRM_IDX].fps_den = avctx->time_base.num;
345 }
346
347 cdsc->param[FRM_IDX].profile_idc = get_min_profile(avctx->pix_fmt);
348 if (avctx->profile != AV_PROFILE_UNKNOWN) {
349 ret = validate_profile(avctx, avctx->profile);
350 if (ret < 0)
351 return ret;
352 cdsc->param[FRM_IDX].profile_idc = avctx->profile;
353 }
354 cdsc->param[FRM_IDX].preset = apv->preset_id;
355 cdsc->param[FRM_IDX].qp = apv->qp;
356 if (avctx->bit_rate / 1000 > INT_MAX || avctx->rc_max_rate / 1000 > INT_MAX) {
357 av_log(avctx, AV_LOG_ERROR, "bit_rate and rc_max_rate > %d000 is not supported\n", INT_MAX);
358 return AVERROR(EINVAL);
359 }
360 cdsc->param[FRM_IDX].bitrate = (int)(avctx->bit_rate / 1000);
361 if (cdsc->param[FRM_IDX].bitrate) {
362 if (cdsc->param[FRM_IDX].qp) {
363 av_log(avctx, AV_LOG_WARNING, "You cannot set both the bitrate and the QP parameter at the same time.\n"
364 "If the bitrate is set, the rate control type is set to ABR, which means that the QP value is ignored.\n");
365 }
366 cdsc->param[FRM_IDX].rc_type = OAPV_RC_ABR;
367 }
368
369 cdsc->threads = avctx->thread_count;
370
372 cdsc->param[FRM_IDX].color_primaries = avctx->color_primaries;
373 cdsc->param[FRM_IDX].color_description_present_flag = 1;
374 }
375
376 if (avctx->color_trc != AVCOL_TRC_UNSPECIFIED) {
377 cdsc->param[FRM_IDX].transfer_characteristics = avctx->color_trc;
378 cdsc->param[FRM_IDX].color_description_present_flag = 1;
379 }
380
381 if (avctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
382 cdsc->param[FRM_IDX].matrix_coefficients = avctx->colorspace;
383 cdsc->param[FRM_IDX].color_description_present_flag = 1;
384 }
385
386 if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED) {
387 cdsc->param[FRM_IDX].full_range_flag = (avctx->color_range == AVCOL_RANGE_JPEG);
388 cdsc->param[FRM_IDX].color_description_present_flag = 1;
389 }
390
391 cdsc->max_bs_buf_size = MAX_BS_BUF; /* maximum bitstream buffer size */
392 cdsc->max_num_frms = MAX_NUM_FRMS;
393
394 const AVDictionaryEntry *en = NULL;
395 while ((en = av_dict_iterate(apv->oapv_params, en))) {
396 ret = oapve_param_parse(&cdsc->param[FRM_IDX], en->key, en->value);
397 if (ret < 0) {
398 av_log(avctx, AV_LOG_WARNING, "Error parsing option '%s = %s'.\n", en->key, en->value);
399 }
400 }
401
402 ret = validate_profile(avctx, cdsc->param[FRM_IDX].profile_idc);
403 if (ret < 0)
404 return ret;
405
406 avctx->profile = cdsc->param[FRM_IDX].profile_idc;
407
408
409 return 0;
410}
411
413{
414 int size = 0;
415 uint8_t payload[64];
416
417 const AVFrameSideData *cll_sd =
420 const AVFrameSideData *mdcv_sd =
424
425 if (cll_sd) {
426 const AVContentLightMetadata *cll = (AVContentLightMetadata *)cll_sd->data;
427
428 apv->cll.max_cll = cll->MaxCLL;
429 apv->cll.max_fall = cll->MaxFALL;
430
431 oapvm_write_cll(&apv->cll, payload, &size);
432
433 int ret = apv_metadata_add_payload(avctx, apv, 1, OAPV_METADATA_CLL, payload, size);
434 if (ret < 0) {
435 av_log(avctx, AV_LOG_WARNING, "Error adding content light metadata\n");
436 return ret;
437 }
438 }
439
440 if (mdcv_sd) {
442
443 // According to APV specification, i = 0, 1, 2 specifies Red, Green, Blue respectively
444 apv->mdcv.primary_chromaticity_x[0] = rescale_rational(mdcv->display_primaries[0][0], 50000); // Red X
445 apv->mdcv.primary_chromaticity_y[0] = rescale_rational(mdcv->display_primaries[0][1], 50000); // Red Y
446 apv->mdcv.primary_chromaticity_x[1] = rescale_rational(mdcv->display_primaries[1][0], 50000); // Green X
447 apv->mdcv.primary_chromaticity_y[1] = rescale_rational(mdcv->display_primaries[1][1], 50000); // Green Y
448 apv->mdcv.primary_chromaticity_x[2] = rescale_rational(mdcv->display_primaries[2][0], 50000); // Blue X
449 apv->mdcv.primary_chromaticity_y[2] = rescale_rational(mdcv->display_primaries[2][1], 50000); // Blue Y
450
451 apv->mdcv.white_point_chromaticity_x = rescale_rational(mdcv->white_point[0], 50000);
452 apv->mdcv.white_point_chromaticity_y = rescale_rational(mdcv->white_point[1], 50000);
453
454 apv->mdcv.max_mastering_luminance = rescale_rational(mdcv->max_luminance, 10000);
455 apv->mdcv.min_mastering_luminance = rescale_rational(mdcv->min_luminance, 10000);
456
457 oapvm_write_mdcv(&apv->mdcv, payload, &size);
458
459 int ret = apv_metadata_add_payload(avctx, apv, 1, OAPV_METADATA_MDCV, payload, size);
460 if (ret < 0) {
461 av_log(avctx, AV_LOG_WARNING, "Error adding master display metadata\n");
462 return ret;
463 }
464 }
465
466 return 0;
467}
468
469/**
470 * @brief Initialize APV codec
471 * Create an encoder instance and allocate all the needed resources
472 *
473 * @param avctx codec context
474 * @return 0 on success, negative error code on failure
475 */
477{
478 ApvEncContext *apv = avctx->priv_data;
479 oapve_cdesc_t *cdsc = &apv->cdsc;
480 unsigned char *bs_buf;
481 int ret;
482
483 apv->nb_payloads = 0;
484 apv->payloads = NULL;
485
486 /* allocate bitstream buffer */
487 bs_buf = (unsigned char *)av_malloc(MAX_BS_BUF);
488 if (bs_buf == NULL) {
489 av_log(avctx, AV_LOG_ERROR, "Cannot allocate bitstream buffer, size=%d\n", MAX_BS_BUF);
490 return AVERROR(ENOMEM);
491 }
492 apv->bitb.addr = bs_buf;
493 apv->bitb.bsize = MAX_BS_BUF;
494
495 /* read configurations and set values for created descriptor (APV_CDSC) */
496 ret = get_conf(avctx, cdsc);
497 if (ret < 0) {
498 av_log(avctx, AV_LOG_ERROR, "Cannot get OAPV configuration\n");
499 return ret;
500 }
501
502 /* create encoder */
503 apv->id = oapve_create(cdsc, &ret);
504 if (apv->id == NULL) {
505 av_log(avctx, AV_LOG_ERROR, "Cannot create OAPV encoder\n");
506 if (ret == OAPV_ERR_INVALID_LEVEL)
507 av_log(avctx, AV_LOG_ERROR, "Invalid level idc: %d\n", cdsc->param[0].level_idc);
508 return AVERROR_EXTERNAL;
509 }
510
511 /* create metadata handler */
512 apv->mid = oapvm_create(&ret);
513 if (apv->mid == NULL || OAPV_FAILED(ret)) {
514 av_log(avctx, AV_LOG_ERROR, "cannot create OAPV metadata handler\n");
515 return AVERROR_EXTERNAL;
516 }
517
518 ret = handle_side_data(avctx, apv);
519 if (ret < 0) {
520 av_log(avctx, AV_LOG_ERROR, "Failed handling side data! (%s)\n",
521 av_err2str(ret));
522 return ret;
523 }
524
525 if (apv->nb_payloads > 0) {
526 ret = oapvm_set_all(apv->mid, apv->payloads, apv->nb_payloads);
527 if (OAPV_FAILED(ret)) {
528 av_log(avctx, AV_LOG_ERROR, "cannot set metadata\n");
529 return AVERROR_EXTERNAL;
530 }
531 }
532
533 int value = OAPV_CFG_VAL_AU_BS_FMT_NONE;
534 int size = 4;
535 ret = oapve_config(apv->id, OAPV_CFG_SET_AU_BS_FMT, &value, &size);
536 if (OAPV_FAILED(ret)) {
537 av_log(avctx, AV_LOG_ERROR, "Failed to set config for using encoder output format\n");
538 return AVERROR_EXTERNAL;
539 }
540
541 apv->ifrms.frm[FRM_IDX].imgb = apv_imgb_create(avctx);
542 if (apv->ifrms.frm[FRM_IDX].imgb == NULL)
543 return AVERROR(ENOMEM);
544 apv->ifrms.num_frms++;
545
546 /* color description values */
547 if (cdsc->param[FRM_IDX].color_description_present_flag) {
548 avctx->color_primaries = cdsc->param[FRM_IDX].color_primaries;
549 avctx->color_trc = cdsc->param[FRM_IDX].transfer_characteristics;
550 avctx->colorspace = cdsc->param[FRM_IDX].matrix_coefficients;
551 avctx->color_range = (cdsc->param[FRM_IDX].full_range_flag) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
552 }
553
554 return 0;
555}
556
557/**
558 * Encode raw data frame into APV packet
559 *
560 * @param[in] avctx codec context
561 * @param[out] avpkt output AVPacket containing encoded data
562 * @param[in] frame AVFrame containing the raw data to be encoded
563 * @param[out] got_packet encoder sets to 0 or 1 to indicate that a
564 * non-empty packet was returned in pkt
565 *
566 * @return 0 on success, negative error code on failure
567 */
568static int liboapve_encode(AVCodecContext *avctx, AVPacket *avpkt,
569 const AVFrame *frame, int *got_packet)
570{
571 ApvEncContext *apv = avctx->priv_data;
572 const oapve_cdesc_t *cdsc = &apv->cdsc;
573 oapv_frm_t *frm = &apv->ifrms.frm[FRM_IDX];
574 oapv_imgb_t *imgb = frm->imgb;
575 int ret;
576
577 av_image_copy2((uint8_t **)imgb->a, imgb->s, frame->data, frame->linesize,
578 frame->format, frame->width, frame->height);
579
580 imgb->ts[0] = frame->pts;
581
582 frm->group_id = 1; // @todo FIX-ME : need to set properly in case of multi-frame
583 frm->pbu_type = OAPV_PBU_TYPE_PRIMARY_FRAME;
584
585 ret = oapve_encode(apv->id, &apv->ifrms, apv->mid, &apv->bitb, &apv->stat, NULL);
586 if (OAPV_FAILED(ret)) {
587 av_log(avctx, AV_LOG_ERROR, "oapve_encode() failed\n");
588 return AVERROR_EXTERNAL;
589 }
590
591 /* store bitstream */
592 if (OAPV_SUCCEEDED(ret) && apv->stat.write > 0) {
593 uint8_t *data = apv->bitb.addr;
594 int size = apv->stat.write;
595
596 // The encoder may return a "Raw bitstream" formatted AU, including au_size.
597 // Discard it as we only need the access_unit() structure.
598 if (size > 4 && AV_RB32(data) != APV_SIGNATURE) {
599 data += 4;
600 size -= 4;
601 }
602
603 ret = ff_get_encode_buffer(avctx, avpkt, size, 0);
604 if (ret < 0)
605 return ret;
606
607 memcpy(avpkt->data, data, size);
608 avpkt->pts = avpkt->dts = frame->pts;
609 avpkt->flags |= AV_PKT_FLAG_KEY;
610
611 if (cdsc->param[FRM_IDX].qp)
613
614 *got_packet = 1;
615 }
616
617 return 0;
618}
619
620/**
621 * Destroy the encoder and release all the allocated resources
622 *
623 * @param avctx codec context
624 * @return 0 on success, negative error code on failure
625 */
627{
628 ApvEncContext *apv = avctx->priv_data;
629
630 for (unsigned int i = 0; i < apv->nb_payloads; i++) {
631 av_freep(&apv->payloads[i].data);
632 }
633 av_freep(&apv->payloads);
634
635 for (int i = 0; i < apv->ifrms.num_frms; i++) {
636 if (apv->ifrms.frm[i].imgb != NULL)
637 apv->ifrms.frm[i].imgb->release(apv->ifrms.frm[i].imgb);
638 apv->ifrms.frm[i].imgb = NULL;
639 }
640
641 if (apv->mid) {
642 oapvm_rem_all(apv->mid);
643 }
644
645 if (apv->id) {
646 oapve_delete(apv->id);
647 apv->id = NULL;
648 }
649
650 if (apv->mid) {
651 oapvm_delete(apv->mid);
652 apv->mid = NULL;
653 }
654
655 av_freep(&apv->bitb.addr); /* release bitstream buffer */
656
657 return 0;
658}
659
660#define OFFSET(x) offsetof(ApvEncContext, x)
661#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
662
663static const AVOption liboapv_options[] = {
664 { "preset", "Encoding preset for setting encoding speed (optimization level control)", OFFSET(preset_id), AV_OPT_TYPE_INT, { .i64 = OAPV_PRESET_DEFAULT }, OAPV_PRESET_FASTEST, OAPV_PRESET_PLACEBO, VE, .unit = "preset" },
665 { "fastest", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_FASTEST }, 0, 0, VE, .unit = "preset" },
666 { "fast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_FAST }, 0, 0, VE, .unit = "preset" },
667 { "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_MEDIUM }, 0, 0, VE, .unit = "preset" },
668 { "slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_SLOW }, 0, 0, VE, .unit = "preset" },
669 { "placebo", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_PLACEBO }, 0, 0, VE, .unit = "preset" },
670 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_DEFAULT }, 0, 0, VE, .unit = "preset" },
671
672 { "qp", "Quantization parameter value for CQP rate control mode", OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 63, VE, .unit = NULL },
673 { "oapv-params", "Override the apv configuration using a :-separated list of key=value parameters", OFFSET(oapv_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE, .unit = NULL },
674
675 { NULL }
676};
677
678static const AVClass liboapve_class = {
679 .class_name = "liboapv",
680 .item_name = av_default_item_name,
681 .option = liboapv_options,
682 .version = LIBAVUTIL_VERSION_INT,
683};
684
686 { "b", "0" }, // bitrate in terms of kilo-bits per second (support for bit-rates from a few hundred Mbps to a few Gbps for 2K, 4K and 8K resolution content)
687 { NULL },
688};
689
691 .p.name = "liboapv",
692 .p.long_name = NULL_IF_CONFIG_SMALL("liboapv APV"),
693 .p.type = AVMEDIA_TYPE_VIDEO,
694 .p.id = AV_CODEC_ID_APV,
695 .init = liboapve_init,
697 .close = liboapve_close,
698 .priv_data_size = sizeof(ApvEncContext),
699 .p.priv_class = &liboapve_class,
700 .defaults = liboapve_defaults,
702 .p.wrapper_name = "liboapv",
709};
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition af_astats.c:246
const FFCodec ff_liboapv_encoder
Definition liboapvenc.c:690
#define VE
Definition amfenc_av1.c:30
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define CODEC_PIXFMTS(...)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_ENCODE_CB(func)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
#define AV_PROFILE_APV_444_12
Definition defs.h:203
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define AV_PROFILE_APV_422_10
Definition defs.h:200
#define AV_PROFILE_APV_444_10
Definition defs.h:202
#define AV_PROFILE_APV_422_12
Definition defs.h:201
#define AV_PROFILE_APV_4444_10
Definition defs.h:204
#define AV_PROFILE_APV_400_10
Definition defs.h:206
#define AV_PROFILE_APV_4444_12
Definition defs.h:205
static enum AVPixelFormat pix_fmt
static AVFrame * frame
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition encode.c:106
int ff_encode_add_stats_side_data(AVPacket *pkt, int quality, const int64_t error[], int error_count, enum AVPictureType pict_type)
Definition encode.c:1070
double value
Definition eval.c:102
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
Definition opt.h:289
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition codec.h:112
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
const char * av_get_profile_name(const AVCodec *codec, int profile)
Return a name for the specified profile, if available.
Definition utils.c:433
@ AV_CODEC_ID_APV
Definition codec_id.h:323
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition avutil.h:226
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
static const AVFrameSideData * av_frame_side_data_get(AVFrameSideData *const *sd, const int nb_sd, enum AVFrameSideDataType type)
Wrapper around av_frame_side_data_get_c() to workaround the limitation that for any type T the conver...
Definition frame.h:1196
@ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition frame.h:137
@ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata associated with a video frame.
Definition frame.h:120
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition imgutils.h:184
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int a
cl_device_type type
misc image utilities
#define b
Definition input.c:43
#define AV_RB32(p)
@ APV_CHROMA_FORMAT_422
Definition apv.h:48
@ APV_CHROMA_FORMAT_400
Definition apv.h:47
@ APV_CHROMA_FORMAT_4444
Definition apv.h:50
@ APV_CHROMA_FORMAT_444
Definition apv.h:49
#define APV_SIGNATURE
Definition apv.h:23
#define av_cold
Definition attributes.h:117
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static int apv_metadata_add_payload(const AVCodecContext *avctx, ApvEncContext *apv, uint32_t group_id, uint32_t type, const void *data, uint32_t size)
Definition liboapvenc.c:280
#define MAX_BS_BUF
Definition liboapvenc.c:45
static const AVClass liboapve_class
Definition liboapvenc.c:678
static int apv_imgb_addref(oapv_imgb_t *imgb)
Definition liboapvenc.c:96
static int liboapve_encode(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet)
Encode raw data frame into APV packet.
Definition liboapvenc.c:568
static oapv_imgb_t * apv_imgb_create(AVCodecContext *avctx)
Definition liboapvenc.c:230
#define MAX_METADATA_PAYLOADS
Definition liboapvenc.c:50
static const AVOption liboapv_options[]
Definition liboapvenc.c:663
static int get_min_profile(enum AVPixelFormat pix_fmt)
Definition liboapvenc.c:153
static int handle_side_data(AVCodecContext *avctx, ApvEncContext *apv)
Definition liboapvenc.c:412
static int64_t rescale_rational(AVRational a, int b)
Definition liboapvenc.c:52
static int validate_profile(AVCodecContext *avctx, int profile)
Definition liboapvenc.c:212
#define FRM_IDX
Definition liboapvenc.c:47
static av_cold int liboapve_init(AVCodecContext *avctx)
Initialize APV codec Create an encoder instance and allocate all the needed resources.
Definition liboapvenc.c:476
static const FFCodecDefault liboapve_defaults[]
Definition liboapvenc.c:685
static av_cold int liboapve_close(AVCodecContext *avctx)
Destroy the encoder and release all the allocated resources.
Definition liboapvenc.c:626
static int get_conf(AVCodecContext *avctx, oapve_cdesc_t *cdsc)
Populate the liboapv configuration from AVCodecContext and encoder options.
Definition liboapvenc.c:324
#define MAX_NUM_FRMS
Definition liboapvenc.c:46
static int apv_imgb_release(oapv_imgb_t *imgb)
Definition liboapvenc.c:84
static int apv_imgb_getref(oapv_imgb_t *imgb)
Definition liboapvenc.c:102
#define OFFSET(x)
Definition liboapvenc.c:660
static int get_chroma_format_idc(enum AVPixelFormat pix_fmt)
Definition liboapvenc.c:134
static int get_color_format(enum AVPixelFormat pix_fmt)
Convert FFmpeg pixel format (AVPixelFormat) into APV pre-defined color format.
Definition liboapvenc.c:112
static int profile_is_compatible(enum AVPixelFormat pix_fmt, int profile)
Definition liboapvenc.c:175
const char * desc
Definition libsvtav1.c:83
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
const char data[16]
Definition mxf.c:149
int profile
Definition mxfenc.c:2299
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3380
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
pixel format definitions
#define AV_PIX_FMT_YUV444P12
Definition pixfmt.h:552
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:749
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_YUVA444P10
Definition pixfmt.h:598
#define AV_PIX_FMT_YUV422P12
Definition pixfmt.h:550
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
#define AV_PIX_FMT_GRAY10
Definition pixfmt.h:525
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
#define AV_PIX_FMT_YUVA444P12
Definition pixfmt.h:600
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
const AVProfile ff_apv_profiles[]
Definition profiles.c:212
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
AVRational framerate
Definition avcodec.h:563
int64_t bit_rate
the average bitrate
Definition avcodec.h:493
const struct AVCodec * codec
Definition avcodec.h:452
int profile
profile
Definition avcodec.h:1636
int nb_decoded_side_data
Definition avcodec.h:1930
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
int64_t rc_max_rate
maximum bitrate
Definition avcodec.h:1288
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avcodec.h:547
AVFrameSideData ** decoded_side_data
Array containing static side data, such as HDR10 CLL / MDCV structures.
Definition avcodec.h:1929
void * priv_data
Definition avcodec.h:470
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
unsigned MaxFALL
Max average light level per frame (cd/m^2).
unsigned MaxCLL
Max content light level (cd/m^2).
char * key
Definition dict.h:91
char * value
Definition dict.h:92
Structure to hold side data for an AVFrame.
Definition frame.h:327
uint8_t * data
Definition frame.h:329
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
Mastering display metadata capable of representing the color volume of the display used to master the...
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
int flags
A combination of AV_PKT_FLAG values.
Definition packet.h:609
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition packet.h:602
uint8_t * data
Definition packet.h:603
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
The structure stores all the states associated with the instance of APV encoder.
Definition liboapvenc.c:60
oapve_cdesc_t cdsc
Definition liboapvenc.c:65
oapve_stat_t stat
Definition liboapvenc.c:67
oapv_bitb_t bitb
Definition liboapvenc.c:66
unsigned nb_payloads
Definition liboapvenc.c:79
oapvm_payload_mdcv_t mdcv
Definition liboapvenc.c:75
oapvm_t mid
Definition liboapvenc.c:64
oapvm_payload_t * payloads
Definition liboapvenc.c:78
oapv_frms_t ifrms
Definition liboapvenc.c:69
AVDictionary * oapv_params
Definition liboapvenc.c:81
oapvm_payload_cll_t cll
Definition liboapvenc.c:76
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
int size