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
15- pngenc: set default prediction method to PAETH15- pngenc: set default prediction method to PAETH
16- APV decoder and APV raw bitstream muxing and demuxing16- APV decoder and APV raw bitstream muxing and demuxing
17- APV parser17- APV parser
18- APV encoding support through a libopenapv wrapper
18 19
19 20
20version 7.1:21version 7.1:
configure+4−0
@@ -250,6 +250,7 @@ External library support: · 249 unmodified lines
250 --enable-liblensfun enable lensfun lens correction [no]250 --enable-liblensfun enable lensfun lens correction [no]
251 --enable-libmodplug enable ModPlug via libmodplug [no]251 --enable-libmodplug enable ModPlug via libmodplug [no]
252 --enable-libmp3lame enable MP3 encoding via libmp3lame [no]252 --enable-libmp3lame enable MP3 encoding via libmp3lame [no]
253 --enable-liboapv enable APV encoding/decoding via liboapv [no]
253 --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]254 --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
254 --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]255 --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
255 --enable-libopencv enable video filtering via libopencv [no]256 --enable-libopencv enable video filtering via libopencv [no]
@@ -1951,6 +1952,7 @@ EXTERNAL_LIBRARY_LIST=" · 1695 unmodified lines
1951 libmodplug1952 libmodplug
1952 libmp3lame1953 libmp3lame
1953 libmysofa1954 libmysofa
1955 liboapv
1954 libopencv1956 libopencv
1955 libopenh2641957 libopenh264
1956 libopenjpeg1958 libopenjpeg
@@ -3590,6 +3592,7 @@ liblc3_encoder_select="audio_frame_queue" · 1633 unmodified lines
3590libmodplug_demuxer_deps="libmodplug"3592libmodplug_demuxer_deps="libmodplug"
3591libmp3lame_encoder_deps="libmp3lame"3593libmp3lame_encoder_deps="libmp3lame"
3592libmp3lame_encoder_select="audio_frame_queue mpegaudioheader"3594libmp3lame_encoder_select="audio_frame_queue mpegaudioheader"
3595liboapv_encoder_deps="liboapv"
3593libopencore_amrnb_decoder_deps="libopencore_amrnb"3596libopencore_amrnb_decoder_deps="libopencore_amrnb"
3594libopencore_amrnb_encoder_deps="libopencore_amrnb"3597libopencore_amrnb_encoder_deps="libopencore_amrnb"
3595libopencore_amrnb_encoder_select="audio_frame_queue"3598libopencore_amrnb_encoder_select="audio_frame_queue"
@@ -6930,6 +6933,7 @@ enabled jni && { [ $target_os = "android" ] && check_headers jni.h · 3334 unmodified lines
6930enabled ladspa && require_headers "ladspa.h dlfcn.h"6933enabled ladspa && require_headers "ladspa.h dlfcn.h"
6931enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext6934enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext
6932enabled libaom && require_pkg_config libaom "aom >= 2.0.0" aom/aom_codec.h aom_codec_version6935enabled libaom && require_pkg_config libaom "aom >= 2.0.0" aom/aom_codec.h aom_codec_version
6936enabled liboapv && require_pkg_config liboapv "oapv >= 0.1.13" "oapv/oapv.h" oapve_encode
6933enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new ||6937enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new ||
6934 { enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } ||6938 { enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } ||
6935 die "ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl."; }6939 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
1889 1889
1890@end table1890@end table
1891 1891
1892@section liboapv
1893
1894Advanced Professional Video codec encoder wrapper.
1895
1896This encoder requires the presence of the liboapv headers and library
1897during configuration. You need to explicitly configure the build with
1898@option{--enable-liboapv}.
1899
1900@float NOTE
1901Many liboapv encoder options are mapped to FFmpeg global codec options,
1902while unique encoder options are provided through private options.
1903@end float
1904
1905The apv project website is at @url{https://github.com/AcademySoftwareFoundation/openapv}.
1906
1907@subsection Options
1908
1909The following options are supported by the liboapv wrapper.
1910
1911@float NOTE
1912To get a more extensive documentation of the liboapv options, consult the
1913liboapv documentation.
1914@end float
1915
1916@table @option
1917@item preset
1918Set the quality-speed tradeoff [fastest, fast, medium, slow, placebo, default]
1919
1920@item qp
1921Set the quantization parameter value for CQP rate control mode.
1922
1923@item oapv-params (@emph{parse_apv_params})
1924Set liboapvenc options using a list of @var{key}=@var{value} pairs separated
1925by ":". See the liboapv encoder user guide for a list of accepted parameters.
1926@end table
1927
1892@section libsvtav11928@section libsvtav1
1893 1929
1894SVT-AV1 encoder wrapper.1930SVT-AV1 encoder wrapper.
libavcodec/Makefile+1−0
@@ -1151,6 +1151,7 @@ OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o · 1150 unmodified lines
1151OBJS-$(CONFIG_LIBLC3_ENCODER) += liblc3enc.o1151OBJS-$(CONFIG_LIBLC3_ENCODER) += liblc3enc.o
1152OBJS-$(CONFIG_LIBLC3_DECODER) += liblc3dec.o1152OBJS-$(CONFIG_LIBLC3_DECODER) += liblc3dec.o
1153OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o1153OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o
1154OBJS-$(CONFIG_LIBOAPV_ENCODER) += liboapvenc.o
1154OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o1155OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o
1155OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o1156OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o
1156OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o1157OBJS-$(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
787extern const FFCodec ff_liblc3_encoder;787extern const FFCodec ff_liblc3_encoder;
788extern const FFCodec ff_liblc3_decoder;788extern const FFCodec ff_liblc3_decoder;
789extern const FFCodec ff_libmp3lame_encoder;789extern const FFCodec ff_libmp3lame_encoder;
790extern const FFCodec ff_liboapv_encoder;
790extern const FFCodec ff_libopencore_amrnb_encoder;791extern const FFCodec ff_libopencore_amrnb_encoder;
791extern const FFCodec ff_libopencore_amrnb_decoder;792extern const FFCodec ff_libopencore_amrnb_decoder;
792extern const FFCodec ff_libopencore_amrwb_decoder;793extern const FFCodec ff_libopencore_amrwb_decoder;
libavcodec/defs.h+8−0
@@ -194,6 +194,14 @@ · 193 unmodified lines
194#define AV_PROFILE_EVC_BASELINE 0194#define AV_PROFILE_EVC_BASELINE 0
195#define AV_PROFILE_EVC_MAIN 1195#define AV_PROFILE_EVC_MAIN 1
196 196
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
197 205
198#define AV_LEVEL_UNKNOWN -99206#define AV_LEVEL_UNKNOWN -99
199 207
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 */
52typedef 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
72static 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
84static int apv_imgb_addref(oapv_imgb_t * imgb)
85{
86 int refcnt = ++imgb->refcnt;
87 return refcnt;
88}
89
90static 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 */
100static 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
118static 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;
158fail:
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 */
191static 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 */
274static 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 */
340static 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 */
403static 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
435static const enum AVPixelFormat supported_pixel_formats[] = {
436 AV_PIX_FMT_YUV422P10,
437 AV_PIX_FMT_YUV444P10,
438 AV_PIX_FMT_NONE
439};
440
441static 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
455static 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
462static 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
467const 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
203 { AV_PROFILE_UNKNOWN },203 { AV_PROFILE_UNKNOWN },
204};204};
205 205
206const 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
206#endif /* !CONFIG_SMALL */217#endif /* !CONFIG_SMALL */
libavcodec/profiles.h+1−0
@@ -77,5 +77,6 @@ extern const AVProfile ff_prores_profiles[]; · 76 unmodified lines
77extern const AVProfile ff_mjpeg_profiles[];77extern const AVProfile ff_mjpeg_profiles[];
78extern const AVProfile ff_arib_caption_profiles[];78extern const AVProfile ff_arib_caption_profiles[];
79extern const AVProfile ff_evc_profiles[];79extern const AVProfile ff_evc_profiles[];
80extern const AVProfile ff_apv_profiles[];
80 81
81#endif /* AVCODEC_PROFILES_H */82#endif /* AVCODEC_PROFILES_H */
libavcodec/version.h+1−1
@@ -29,7 +29,7 @@ · 28 unmodified lines
29 29
30#include "version_major.h"30#include "version_major.h"
31 31
32#define LIBAVCODEC_VERSION_MINOR 232#define LIBAVCODEC_VERSION_MINOR 3
33#define LIBAVCODEC_VERSION_MICRO 10033#define LIBAVCODEC_VERSION_MICRO 100
34 34
35#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \35#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