History

avcodec: add APV encoder using liboapv

Dawid Kozinski committed 1 year ago

Commit fab691e1 parent 7faa56010 files · +547 −1Browse files

Unified · Split

10 files
  1. Changelog +1 −0
  2. configure +4 −0
  3. doc/encoders.texi +36 −0
  4. libavcodec/Makefile +1 −0
  5. libavcodec/allcodecs.c +1 −0
  6. libavcodec/defs.h +8 −0
  7. libavcodec/liboapvenc.c +483 −0
  8. libavcodec/profiles.c +11 −0
  9. libavcodec/profiles.h +1 −0
  10. libavcodec/version.h +1 −1
Changelog+1−0
@@ -15,6 +15,7 @@ version <next>: · 14 unmodified lines
1515 - pngenc: set default prediction method to PAETH
1616 - APV decoder and APV raw bitstream muxing and demuxing
1717 - APV parser
18+- APV encoding support through a libopenapv wrapper
1819
1920
2021 version 7.1:
configure+4−0
@@ -250,6 +250,7 @@ External library support: · 249 unmodified lines
250250 --enable-liblensfun enable lensfun lens correction [no]
251251 --enable-libmodplug enable ModPlug via libmodplug [no]
252252 --enable-libmp3lame enable MP3 encoding via libmp3lame [no]
253+ --enable-liboapv enable APV encoding/decoding via liboapv [no]
253254 --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
254255 --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
255256 --enable-libopencv enable video filtering via libopencv [no]
@@ -1951,6 +1952,7 @@ EXTERNAL_LIBRARY_LIST=" · 1695 unmodified lines
19511952 libmodplug
19521953 libmp3lame
19531954 libmysofa
1955+ liboapv
19541956 libopencv
19551957 libopenh264
19561958 libopenjpeg
@@ -3590,6 +3592,7 @@ liblc3_encoder_select="audio_frame_queue" · 1633 unmodified lines
35903592 libmodplug_demuxer_deps="libmodplug"
35913593 libmp3lame_encoder_deps="libmp3lame"
35923594 libmp3lame_encoder_select="audio_frame_queue mpegaudioheader"
3595+liboapv_encoder_deps="liboapv"
35933596 libopencore_amrnb_decoder_deps="libopencore_amrnb"
35943597 libopencore_amrnb_encoder_deps="libopencore_amrnb"
35953598 libopencore_amrnb_encoder_select="audio_frame_queue"
@@ -6930,6 +6933,7 @@ enabled jni && { [ $target_os = "android" ] && check_headers jni.h · 3334 unmodified lines
69306933 enabled ladspa && require_headers "ladspa.h dlfcn.h"
69316934 enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext
69326935 enabled libaom && require_pkg_config libaom "aom >= 2.0.0" aom/aom_codec.h aom_codec_version
6936+enabled liboapv && require_pkg_config liboapv "oapv >= 0.1.13" "oapv/oapv.h" oapve_encode
69336937 enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new ||
69346938 { enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } ||
69356939 die "ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl."; }
doc/encoders.texi+36−0
@@ -1889,6 +1889,42 @@ ffmpeg -i input -c:v libaom-av1 -b:v 500K -aom-params tune=psnr:enable-tpl-model · 1888 unmodified lines
18891889
18901890 @end table
18911891
1892+@section liboapv
1893+
1894+Advanced Professional Video codec encoder wrapper.
1895+
1896+This encoder requires the presence of the liboapv headers and library
1897+during configuration. You need to explicitly configure the build with
1898+@option{--enable-liboapv}.
1899+
1900+@float NOTE
1901+Many liboapv encoder options are mapped to FFmpeg global codec options,
1902+while unique encoder options are provided through private options.
1903+@end float
1904+
1905+The apv project website is at @url{https://github.com/AcademySoftwareFoundation/openapv}.
1906+
1907+@subsection Options
1908+
1909+The following options are supported by the liboapv wrapper.
1910+
1911+@float NOTE
1912+To get a more extensive documentation of the liboapv options, consult the
1913+liboapv documentation.
1914+@end float
1915+
1916+@table @option
1917+@item preset
1918+Set the quality-speed tradeoff [fastest, fast, medium, slow, placebo, default]
1919+
1920+@item qp
1921+Set the quantization parameter value for CQP rate control mode.
1922+
1923+@item oapv-params (@emph{parse_apv_params})
1924+Set liboapvenc options using a list of @var{key}=@var{value} pairs separated
1925+by ":". See the liboapv encoder user guide for a list of accepted parameters.
1926+@end table
1927+
18921928 @section libsvtav1
18931929
18941930 SVT-AV1 encoder wrapper.
libavcodec/Makefile+1−0
@@ -1151,6 +1151,7 @@ OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o · 1150 unmodified lines
11511151 OBJS-$(CONFIG_LIBLC3_ENCODER) += liblc3enc.o
11521152 OBJS-$(CONFIG_LIBLC3_DECODER) += liblc3dec.o
11531153 OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o
1154+OBJS-$(CONFIG_LIBOAPV_ENCODER) += liboapvenc.o
11541155 OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o
11551156 OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o
11561157 OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o
libavcodec/allcodecs.c+1−0
@@ -787,6 +787,7 @@ extern const FFCodec ff_libjxl_encoder; · 786 unmodified lines
787787 extern const FFCodec ff_liblc3_encoder;
788788 extern const FFCodec ff_liblc3_decoder;
789789 extern const FFCodec ff_libmp3lame_encoder;
790+extern const FFCodec ff_liboapv_encoder;
790791 extern const FFCodec ff_libopencore_amrnb_encoder;
791792 extern const FFCodec ff_libopencore_amrnb_decoder;
792793 extern const FFCodec ff_libopencore_amrwb_decoder;
libavcodec/defs.h+8−0
@@ -194,6 +194,14 @@ · 193 unmodified lines
194194 #define AV_PROFILE_EVC_BASELINE 0
195195 #define AV_PROFILE_EVC_MAIN 1
196196
197+#define AV_PROFILE_APV_422_10 33
198+#define AV_PROFILE_APV_422_12 44
199+#define AV_PROFILE_APV_444_10 55
200+#define AV_PROFILE_APV_444_12 66
201+#define AV_PROFILE_APV_4444_10 77
202+#define AV_PROFILE_APV_4444_12 88
203+#define AV_PROFILE_APV_400_10 99
204+
197205
198206 #define AV_LEVEL_UNKNOWN -99
199207
libavcodec/liboapvenc.c+483−0
@@ -0,0 +1,483 @@
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"
30+#include "libavutil/intreadwrite.h"
31+#include "libavutil/imgutils.h"
32+#include "libavutil/mem.h"
33+#include "libavutil/opt.h"
34+#include "libavutil/pixdesc.h"
35+#include "libavutil/pixfmt.h"
36+
37+#include "avcodec.h"
38+#include "apv.h"
39+#include "codec_internal.h"
40+#include "encode.h"
41+#include "packet_internal.h"
42+#include "profiles.h"
43+
44+#define MAX_BS_BUF (128 * 1024 * 1024)
45+#define MAX_NUM_FRMS (1) // supports only 1-frame in an access unit
46+#define FRM_IDX (0) // supports only 1-frame in an access unit
47+#define MAX_NUM_CC (OAPV_MAX_CC) // Max number of color componets (upto 4:4:4:4)
48+
49+/**
50+ * The structure stores all the states associated with the instance of APV encoder
51+ */
52+typedef struct ApvEncContext {
53+ const AVClass *class;
54+
55+ oapve_t id; // APV instance identifier
56+ oapvm_t mid;
57+ oapve_cdesc_t cdsc; // coding parameters i.e profile, width & height of input frame, num of therads, frame rate ...
58+ oapv_bitb_t bitb; // bitstream buffer (output)
59+ oapve_stat_t stat; // encoding status (output)
60+
61+ oapv_frms_t ifrms; // frames for input
62+
63+ int num_frames; // number of frames in an access unit
64+
65+ int preset_id; // preset of apv ( fastest, fast, medium, slow, placebo)
66+
67+ int qp; // quantization parameter (QP) [0,63]
68+
69+ AVDictionary *oapv_params;
70+} ApvEncContext;
71+
72+static int apv_imgb_release(oapv_imgb_t *imgb)
73+{
74+ int refcnt = --imgb->refcnt;
75+ if (refcnt == 0) {
76+ for (int i = 0; i < imgb->np; i++)
77+ av_freep(&imgb->baddr[i]);
78+ av_free(imgb);
79+ }
80+
81+ return refcnt;
82+}
83+
84+static int apv_imgb_addref(oapv_imgb_t * imgb)
85+{
86+ int refcnt = ++imgb->refcnt;
87+ return refcnt;
88+}
89+
90+static int apv_imgb_getref(oapv_imgb_t * imgb)
91+{
92+ return imgb->refcnt;
93+}
94+
95+/**
96+ * Convert FFmpeg pixel format (AVPixelFormat) into APV pre-defined color format
97+ *
98+ * @return APV pre-defined color format (@see oapv.h) on success, OAPV_CF_UNKNOWN on failure
99+ */
100+static inline int get_color_format(enum AVPixelFormat pix_fmt)
101+{
102+ int cf = OAPV_CF_UNKNOWN;
103+
104+ switch (pix_fmt) {
105+ case AV_PIX_FMT_YUV422P10:
106+ cf = OAPV_CF_YCBCR422;
107+ break;
108+ case AV_PIX_FMT_YUV444P10:
109+ cf = OAPV_CF_YCBCR444;
110+ break;
111+ default:
112+ av_assert0(cf != OAPV_CF_UNKNOWN);
113+ }
114+
115+ return cf;
116+}
117+
118+static oapv_imgb_t *apv_imgb_create(AVCodecContext *avctx)
119+{
120+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
121+ oapv_imgb_t *imgb;
122+ int input_depth;
123+ int cfmt; // color format
124+ int cs;
125+
126+ av_assert0(desc);
127+
128+ imgb = av_mallocz(sizeof(oapv_imgb_t));
129+ if (!imgb)
130+ goto fail;
131+
132+ input_depth = desc->comp[0].depth;
133+ cfmt = get_color_format(avctx->pix_fmt);
134+ cs = OAPV_CS_SET(cfmt, input_depth, AV_HAVE_BIGENDIAN);
135+
136+ imgb->np = desc->nb_components;
137+
138+ for (int i = 0; i < imgb->np; i++) {
139+ imgb->w[i] = avctx->width >> ((i == 1 || i == 2) ? desc->log2_chroma_w : 0);
140+ imgb->h[i] = avctx->height;
141+ imgb->aw[i] = FFALIGN(imgb->w[i], OAPV_MB_W);
142+ imgb->ah[i] = FFALIGN(imgb->h[i], OAPV_MB_H);
143+ imgb->s[i] = imgb->aw[i] * OAPV_CS_GET_BYTE_DEPTH(cs);
144+
145+ imgb->bsize[i] = imgb->e[i] = imgb->s[i] * imgb->ah[i];
146+ imgb->a[i] = imgb->baddr[i] = av_mallocz(imgb->bsize[i]);
147+ if (imgb->a[i] == NULL)
148+ goto fail;
149+ }
150+
151+ imgb->cs = cs;
152+ imgb->addref = apv_imgb_addref;
153+ imgb->getref = apv_imgb_getref;
154+ imgb->release = apv_imgb_release;
155+ imgb->refcnt = 1;
156+
157+ return imgb;
158+fail:
159+ av_log(avctx, AV_LOG_ERROR, "cannot create image buffer\n");
160+ if (imgb) {
161+ for (int i = 0; i < imgb->np; i++)
162+ av_freep(&imgb->a[i]);
163+ av_freep(&imgb);
164+ }
165+ return NULL;
166+}
167+
168+/**
169+ * The function returns a pointer to the object of the oapve_cdesc_t type.
170+ * oapve_cdesc_t contains all encoder parameters that should be initialized before the encoder is used.
171+ *
172+ * The field values of the oapve_cdesc_t structure are populated based on:
173+ * - the corresponding field values of the AvCodecConetxt structure,
174+ * - the apv encoder specific option values,
175+ *
176+ * The order of processing input data and populating the apve_cdsc structure
177+ * 1) first, the fields of the AVCodecContext structure corresponding to the provided input options are processed,
178+ * (i.e -pix_fmt yuv422p -s:v 1920x1080 -r 30 -profile:v 0)
179+ * 2) then apve-specific options added as AVOption to the apv AVCodec implementation
180+ * (i.e -preset 0)
181+ *
182+ * Keep in mind that, there are options that can be set in different ways.
183+ * In this case, please follow the above-mentioned order of processing.
184+ * The most recent assignments overwrite the previous values.
185+ *
186+ * @param[in] avctx codec context (AVCodecContext)
187+ * @param[out] cdsc contains all APV encoder encoder parameters that should be initialized before the encoder is use
188+ *
189+ * @return 0 on success, negative error code on failure
190+ */
191+static int get_conf(AVCodecContext *avctx, oapve_cdesc_t *cdsc)
192+{
193+ ApvEncContext *apv = avctx->priv_data;
194+
195+ /* initialize apv_param struct with default values */
196+ int ret = oapve_param_default(&cdsc->param[FRM_IDX]);
197+ if (OAPV_FAILED(ret)) {
198+ av_log(avctx, AV_LOG_ERROR, "Cannot set default parameter\n");
199+ return AVERROR_EXTERNAL;
200+ }
201+
202+ /* read options from AVCodecContext */
203+ if (avctx->width > 0)
204+ cdsc->param[FRM_IDX].w = avctx->width;
205+
206+ if (avctx->height > 0)
207+ cdsc->param[FRM_IDX].h = avctx->height;
208+
209+ if (avctx->framerate.num > 0) {
210+ cdsc->param[FRM_IDX].fps_num = avctx->framerate.num;
211+ cdsc->param[FRM_IDX].fps_den = avctx->framerate.den;
212+ } else if (avctx->time_base.num > 0) {
213+ cdsc->param[FRM_IDX].fps_num = avctx->time_base.den;
214+ cdsc->param[FRM_IDX].fps_den = avctx->time_base.num;
215+ }
216+
217+ cdsc->param[FRM_IDX].preset = apv->preset_id;
218+ cdsc->param[FRM_IDX].qp = apv->qp;
219+ if (avctx->bit_rate / 1000 > INT_MAX || avctx->rc_max_rate / 1000 > INT_MAX) {
220+ av_log(avctx, AV_LOG_ERROR, "bit_rate and rc_max_rate > %d000 is not supported\n", INT_MAX);
221+ return AVERROR(EINVAL);
222+ }
223+ cdsc->param[FRM_IDX].bitrate = (int)(avctx->bit_rate / 1000);
224+ if (cdsc->param[FRM_IDX].bitrate) {
225+ if (cdsc->param[FRM_IDX].qp) {
226+ av_log(avctx, AV_LOG_WARNING, "You cannot set both the bitrate and the QP parameter at the same time.\n"
227+ "If the bitrate is set, the rate control type is set to ABR, which means that the QP value is ignored.\n");
228+ }
229+ cdsc->param[FRM_IDX].rc_type = OAPV_RC_ABR;
230+ }
231+
232+ cdsc->threads = avctx->thread_count;
233+
234+ if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED) {
235+ cdsc->param[FRM_IDX].color_primaries = avctx->color_primaries;
236+ cdsc->param[FRM_IDX].color_description_present_flag = 1;
237+ }
238+
239+ if (avctx->color_trc != AVCOL_TRC_UNSPECIFIED) {
240+ cdsc->param[FRM_IDX].transfer_characteristics = avctx->color_trc;
241+ cdsc->param[FRM_IDX].color_description_present_flag = 1;
242+ }
243+
244+ if (avctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
245+ cdsc->param[FRM_IDX].matrix_coefficients = avctx->colorspace;
246+ cdsc->param[FRM_IDX].color_description_present_flag = 1;
247+ }
248+
249+ if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED) {
250+ cdsc->param[FRM_IDX].full_range_flag = (avctx->color_range == AVCOL_RANGE_JPEG);
251+ cdsc->param[FRM_IDX].color_description_present_flag = 1;
252+ }
253+
254+ cdsc->max_bs_buf_size = MAX_BS_BUF; /* maximum bitstream buffer size */
255+ cdsc->max_num_frms = MAX_NUM_FRMS;
256+
257+ const AVDictionaryEntry *en = NULL;
258+ while (en = av_dict_iterate(apv->oapv_params, en)) {
259+ ret = oapve_param_parse(&cdsc->param[FRM_IDX], en->key, en->value);
260+ if (ret < 0)
261+ av_log(avctx, AV_LOG_WARNING, "Error parsing option '%s = %s'.\n", en->key, en->value);
262+ }
263+
264+ return 0;
265+}
266+
267+/**
268+ * @brief Initialize APV codec
269+ * Create an encoder instance and allocate all the needed resources
270+ *
271+ * @param avctx codec context
272+ * @return 0 on success, negative error code on failure
273+ */
274+static av_cold int liboapve_init(AVCodecContext *avctx)
275+{
276+ ApvEncContext *apv = avctx->priv_data;
277+ oapve_cdesc_t *cdsc = &apv->cdsc;
278+ unsigned char *bs_buf;
279+ int ret;
280+
281+ /* allocate bitstream buffer */
282+ bs_buf = (unsigned char *)av_malloc(MAX_BS_BUF);
283+ if (bs_buf == NULL) {
284+ av_log(avctx, AV_LOG_ERROR, "Cannot allocate bitstream buffer, size=%d\n", MAX_BS_BUF);
285+ return AVERROR(ENOMEM);
286+ }
287+ apv->bitb.addr = bs_buf;
288+ apv->bitb.bsize = MAX_BS_BUF;
289+
290+ /* read configurations and set values for created descriptor (APV_CDSC) */
291+ ret = get_conf(avctx, cdsc);
292+ if (ret < 0) {
293+ av_log(avctx, AV_LOG_ERROR, "Cannot get OAPV configuration\n");
294+ return ret;
295+ }
296+
297+ /* create encoder */
298+ apv->id = oapve_create(cdsc, &ret);
299+ if (apv->id == NULL) {
300+ av_log(avctx, AV_LOG_ERROR, "Cannot create OAPV encoder\n");
301+ if (ret == OAPV_ERR_INVALID_LEVEL)
302+ av_log(avctx, AV_LOG_ERROR, "Invalid level idc: %d\n", cdsc->param[0].level_idc);
303+ return AVERROR_EXTERNAL;
304+ }
305+
306+ /* create metadata handler */
307+ apv->mid = oapvm_create(&ret);
308+ if (apv->mid == NULL || OAPV_FAILED(ret)) {
309+ av_log(avctx, AV_LOG_ERROR, "cannot create OAPV metadata handler\n");
310+ return AVERROR_EXTERNAL;
311+ }
312+
313+ apv->ifrms.frm[FRM_IDX].imgb = apv_imgb_create(avctx);
314+ if (apv->ifrms.frm[FRM_IDX].imgb == NULL)
315+ return AVERROR(ENOMEM);
316+ apv->ifrms.num_frms++;
317+
318+ /* color description values */
319+ if (cdsc->param[FRM_IDX].color_description_present_flag) {
320+ avctx->color_primaries = cdsc->param[FRM_IDX].color_primaries;
321+ avctx->color_trc = cdsc->param[FRM_IDX].transfer_characteristics;
322+ avctx->colorspace = cdsc->param[FRM_IDX].matrix_coefficients;
323+ avctx->color_range = (cdsc->param[FRM_IDX].full_range_flag) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
324+ }
325+
326+ return 0;
327+}
328+
329+/**
330+ * Encode raw data frame into APV packet
331+ *
332+ * @param[in] avctx codec context
333+ * @param[out] avpkt output AVPacket containing encoded data
334+ * @param[in] frame AVFrame containing the raw data to be encoded
335+ * @param[out] got_packet encoder sets to 0 or 1 to indicate that a
336+ * non-empty packet was returned in pkt
337+ *
338+ * @return 0 on success, negative error code on failure
339+ */
340+static int liboapve_encode(AVCodecContext *avctx, AVPacket *avpkt,
341+ const AVFrame *frame, int *got_packet)
342+{
343+ ApvEncContext *apv = avctx->priv_data;
344+ const oapve_cdesc_t *cdsc = &apv->cdsc;
345+ oapv_frm_t *frm = &apv->ifrms.frm[FRM_IDX];
346+ oapv_imgb_t *imgb = frm->imgb;
347+ int ret;
348+
349+ if (avctx->width != frame->width || avctx->height != frame->height || avctx->pix_fmt != frame->format) {
350+ av_log(avctx, AV_LOG_ERROR, "Dimension changes are not supported\n");
351+ return AVERROR(EINVAL);
352+ }
353+
354+ av_image_copy((uint8_t **)imgb->a, imgb->s, (const uint8_t **)frame->data, frame->linesize,
355+ frame->format, frame->width, frame->height);
356+
357+ imgb->ts[0] = frame->pts;
358+
359+ frm->group_id = 1; // @todo FIX-ME : need to set properly in case of multi-frame
360+ frm->pbu_type = OAPV_PBU_TYPE_PRIMARY_FRAME;
361+
362+ ret = oapve_encode(apv->id, &apv->ifrms, apv->mid, &apv->bitb, &apv->stat, NULL);
363+ if (OAPV_FAILED(ret)) {
364+ av_log(avctx, AV_LOG_ERROR, "oapve_encode() failed\n");
365+ return AVERROR_EXTERNAL;
366+ }
367+
368+ /* store bitstream */
369+ if (OAPV_SUCCEEDED(ret) && apv->stat.write > 0) {
370+ uint8_t *data = apv->bitb.addr;
371+ int size = apv->stat.write;
372+
373+ // The encoder may return a "Raw bitstream" formated AU, including au_size.
374+ // Discard it as we only need the access_unit() structure.
375+ if (size > 4 && AV_RB32(data) != APV_SIGNATURE) {
376+ data += 4;
377+ size -= 4;
378+ }
379+
380+ ret = ff_get_encode_buffer(avctx, avpkt, size, 0);
381+ if (ret < 0)
382+ return ret;
383+
384+ memcpy(avpkt->data, data, size);
385+ avpkt->pts = avpkt->dts = frame->pts;
386+ avpkt->flags |= AV_PKT_FLAG_KEY;
387+
388+ if (cdsc->param[FRM_IDX].qp)
389+ ff_side_data_set_encoder_stats(avpkt, cdsc->param[FRM_IDX].qp * FF_QP2LAMBDA, NULL, 0, AV_PICTURE_TYPE_I);
390+
391+ *got_packet = 1;
392+ }
393+
394+ return 0;
395+}
396+
397+/**
398+ * Destroy the encoder and release all the allocated resources
399+ *
400+ * @param avctx codec context
401+ * @return 0 on success, negative error code on failure
402+ */
403+static av_cold int liboapve_close(AVCodecContext *avctx)
404+{
405+ ApvEncContext *apv = avctx->priv_data;
406+
407+ for (int i = 0; i < apv->num_frames; i++) {
408+ if (apv->ifrms.frm[i].imgb != NULL)
409+ apv->ifrms.frm[i].imgb->release(apv->ifrms.frm[i].imgb);
410+ apv->ifrms.frm[i].imgb = NULL;
411+ }
412+
413+ if (apv->mid) {
414+ oapvm_rem_all(apv->mid);
415+ }
416+
417+ if (apv->id) {
418+ oapve_delete(apv->id);
419+ apv->id = NULL;
420+ }
421+
422+ if (apv->mid) {
423+ oapvm_delete(apv->mid);
424+ apv->mid = NULL;
425+ }
426+
427+ av_freep(&apv->bitb.addr); /* release bitstream buffer */
428+
429+ return 0;
430+}
431+
432+#define OFFSET(x) offsetof(ApvEncContext, x)
433+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
434+
435+static const enum AVPixelFormat supported_pixel_formats[] = {
436+ AV_PIX_FMT_YUV422P10,
437+ AV_PIX_FMT_YUV444P10,
438+ AV_PIX_FMT_NONE
439+};
440+
441+static const AVOption liboapv_options[] = {
442+ { "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" },
443+ { "fastest", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_FASTEST }, INT_MIN, INT_MAX, VE, .unit = "preset" },
444+ { "fast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_FAST }, INT_MIN, INT_MAX, VE, .unit = "preset" },
445+ { "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_MEDIUM }, INT_MIN, INT_MAX, VE, .unit = "preset" },
446+ { "slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_SLOW }, INT_MIN, INT_MAX, VE, .unit = "preset" },
447+ { "placebo", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_PLACEBO }, INT_MIN, INT_MAX, VE, .unit = "preset" },
448+ { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OAPV_PRESET_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "preset" },
449+
450+ { "qp", "Quantization parameter value for CQP rate control mode", OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 63, VE },
451+ { "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 },
452+ { NULL }
453+};
454+
455+static const AVClass liboapve_class = {
456+ .class_name = "liboapv",
457+ .item_name = av_default_item_name,
458+ .option = liboapv_options,
459+ .version = LIBAVUTIL_VERSION_INT,
460+};
461+
462+static const FFCodecDefault liboapve_defaults[] = {
463+ { "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)
464+ { NULL },
465+};
466+
467+const FFCodec ff_liboapv_encoder = {
468+ .p.name = "liboapv",
469+ .p.long_name = NULL_IF_CONFIG_SMALL("liboapv APV"),
470+ .p.type = AVMEDIA_TYPE_VIDEO,
471+ .p.id = AV_CODEC_ID_APV,
472+ .init = liboapve_init,
473+ FF_CODEC_ENCODE_CB(liboapve_encode),
474+ .close = liboapve_close,
475+ .priv_data_size = sizeof(ApvEncContext),
476+ .p.priv_class = &liboapve_class,
477+ .defaults = liboapve_defaults,
478+ .p.capabilities = AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1,
479+ .p.wrapper_name = "liboapv",
480+ .p.pix_fmts = supported_pixel_formats,
481+ .p.profiles = NULL_IF_CONFIG_SMALL(ff_apv_profiles),
482+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_NOT_INIT_THREADSAFE,
483+};
libavcodec/profiles.c+11−0
@@ -203,4 +203,15 @@ const AVProfile ff_evc_profiles[] = { · 202 unmodified lines
203203 { AV_PROFILE_UNKNOWN },
204204 };
205205
206+const AVProfile ff_apv_profiles[] = {
207+ { AV_PROFILE_APV_422_10, "422-10" },
208+ { AV_PROFILE_APV_422_12, "422-12" },
209+ { AV_PROFILE_APV_444_10, "444-10" },
210+ { AV_PROFILE_APV_444_12, "444-12" },
211+ { AV_PROFILE_APV_4444_10, "4444-10" },
212+ { AV_PROFILE_APV_4444_12, "4444-12" },
213+ { AV_PROFILE_APV_400_10, "400-10" },
214+ { AV_PROFILE_UNKNOWN },
215+};
216+
206217 #endif /* !CONFIG_SMALL */
libavcodec/profiles.h+1−0
@@ -77,5 +77,6 @@ extern const AVProfile ff_prores_profiles[]; · 76 unmodified lines
7777 extern const AVProfile ff_mjpeg_profiles[];
7878 extern const AVProfile ff_arib_caption_profiles[];
7979 extern const AVProfile ff_evc_profiles[];
80+extern const AVProfile ff_apv_profiles[];
8081
8182 #endif /* AVCODEC_PROFILES_H */
libavcodec/version.h+1−1
@@ -29,7 +29,7 @@ · 28 unmodified lines
2929
3030 #include "version_major.h"
3131
32−#define LIBAVCODEC_VERSION_MINOR 2
32+#define LIBAVCODEC_VERSION_MINOR 3
3333 #define LIBAVCODEC_VERSION_MICRO 100
3434
3535 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t