From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 3C6CE4B574 for ; Wed, 30 Apr 2025 14:04:12 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C080D687DEE; Wed, 30 Apr 2025 17:04:07 +0300 (EEST) Received: from mailout1.w1.samsung.com (mailout1.w1.samsung.com [210.118.77.11]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 62523687B5C for ; Wed, 30 Apr 2025 17:04:00 +0300 (EEST) Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20250430140358euoutp01aa565b6fe4ac5d0e5fbe6cfa0c1657fa~7HZx8oeM-1873318733euoutp01o for ; Wed, 30 Apr 2025 14:03:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20250430140358euoutp01aa565b6fe4ac5d0e5fbe6cfa0c1657fa~7HZx8oeM-1873318733euoutp01o DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1746021838; bh=IP7GhTBAAKdkgadtoIMbnT5q7PWPpBhRmzj5SzjBAyI=; h=From:To:In-Reply-To:Subject:Date:References:From; b=AZIWfdvjs9JL6FWRSel/5AfyEd7Gm5zjAaSOpUNMw/ROb1gmfqAGAbrMMDokcT1ws ryvvQZYtrQ6UoJhpsF1hrSGATrC+mRolAgDeXgW4QjhoUIm1u88JBvcYGCMgFay2bX BI5WpXyk22quIUXQlrVAaAJDEzwlOqXdPzl8iuFQ= Received: from eusmtip1.samsung.com (unknown [203.254.199.221]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20250430140358eucas1p2caafb5ea6294fd1d05bef80bc3f69d3e~7HZxzHsaW0615906159eucas1p2d for ; Wed, 30 Apr 2025 14:03:58 +0000 (GMT) Received: from AMDN5164 (unknown [106.210.132.171]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20250430140358eusmtip1cb0fadac279b0f1654648c02620cc23b~7HZxqwB1I2484624846eusmtip1w for ; Wed, 30 Apr 2025 14:03:58 +0000 (GMT) From: "Dawid Kozinski/Multimedia \(PLT\) /SRPOL/Staff Engineer/Samsung Electronics" To: "'FFmpeg development discussions and patches'" In-Reply-To: <20250430004000.11599-1-jamrial@gmail.com> Date: Wed, 30 Apr 2025 16:03:57 +0200 Message-ID: <007b01dbb9d8$b79d85b0$26d89110$@samsung.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AQEAF2dDFEz9TekkXJG8P6IqFkGWZAI0HDGftWHfJQA= Content-Language: pl X-CMS-MailID: 20250430140358eucas1p2caafb5ea6294fd1d05bef80bc3f69d3e X-Msg-Generator: CA X-RootMTR: 20250430004031eucas1p1b66ae7108a5ccfdccf8a3e6a9de4bd66 X-EPHeader: CA X-CMS-RootMailID: 20250430004031eucas1p1b66ae7108a5ccfdccf8a3e6a9de4bd66 References: <20250430004000.11599-1-jamrial@gmail.com> Subject: Re: [FFmpeg-devel] [PATCH] avcodec: add APV encoder using liboapv X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: quoted-printable Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: > -----Original Message----- > From: ffmpeg-devel On Behalf Of James > Almer > Sent: =B6roda, 30 kwietnia 2025 02:40 > To: ffmpeg-devel@ffmpeg.org > Subject: [FFmpeg-devel] [PATCH] avcodec: add APV encoder using liboapv > = > From: Dawid Kozinski > = > Co-authored-by: James Almer > Signed-off-by: James Almer > --- > Touched up Dawid's patch to fix several issues. The most important one being > the image rescaling code that's out of place in an encoder. > liboapv does not seem to properly support 12bit content yet (Which is why the > scaling code was added, to reduce the input to 10bit), so i removed it > altogether. Same with all the references to GRAY, 420P, A444P, and Y210, which > are also not supported. > = Thank you for the review and your changes. We are aware that the encoder is not the best place for data rescaling. However, the oapve_encode() function requires data which size is a multiple of 16. Any suggestions for resolving this problem? A bit off-topic. I am still working on the implementation of the MOV muxer. The patch should be submitted soon. > Also removed the ad-hock atomics. If the library needs the reference counting > to be atomic, it needs to handle it itself. Their own CLI implementation doesn't > even bother with it. > = > configure | 4 + > doc/encoders.texi | 41 ++++ > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 2 + > libavcodec/liboapvenc.c | 490 ++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 538 insertions(+) > create mode 100644 libavcodec/liboapvenc.c > = > diff --git a/configure b/configure > index e285061742..4717836aff 100755 > --- a/configure > +++ b/configure > @@ -250,6 +250,7 @@ External library support: > --enable-liblensfun enable lensfun lens correction [no] > --enable-libmodplug enable ModPlug via libmodplug [no] > --enable-libmp3lame enable MP3 encoding via libmp3lame [no] > + --enable-liboapv enable APV encoding/decoding via liboapv [no] > --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore- > amrnb [no] > --enable-libopencore-amrwb enable AMR-WB decoding via libopencore- > amrwb [no] > --enable-libopencv enable video filtering via libopencv [no] > @@ -1951,6 +1952,7 @@ EXTERNAL_LIBRARY_LIST=3D" > libmodplug > libmp3lame > libmysofa > + liboapv > libopencv > libopenh264 > libopenjpeg > @@ -3590,6 +3592,7 @@ liblc3_encoder_select=3D"audio_frame_queue" > libmodplug_demuxer_deps=3D"libmodplug" > libmp3lame_encoder_deps=3D"libmp3lame" > libmp3lame_encoder_select=3D"audio_frame_queue mpegaudioheader" > +liboapv_encoder_deps=3D"liboapv" > libopencore_amrnb_decoder_deps=3D"libopencore_amrnb" > libopencore_amrnb_encoder_deps=3D"libopencore_amrnb" > libopencore_amrnb_encoder_select=3D"audio_frame_queue" > @@ -6930,6 +6933,7 @@ enabled jni && { [ $target_os =3D "android" ] && > check_headers jni.h > enabled ladspa && require_headers "ladspa.h dlfcn.h" > enabled lcms2 && require_pkg_config lcms2 "lcms2 >=3D 2.13" lcms2.h > cmsCreateContext > enabled libaom && require_pkg_config libaom "aom >=3D 2.0.0" > aom/aom_codec.h aom_codec_version > +enabled liboapv && require_pkg_config liboapv "oapv >=3D 0.1.1= 3" > "oapv/oapv.h" oapve_encode > enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" > "aribb24/aribb24.h" arib_instance_new || > { enabled gpl && require_pkg_config libaribb24 aribb24 > "aribb24/aribb24.h" arib_instance_new; } || > die "ERROR: libaribb24 requires version higher than 1.0.3 or -- > enable-gpl."; } diff --git a/doc/encoders.texi b/doc/encoders.texi index > 128e81a2e7..f5d6d69246 100644 > --- a/doc/encoders.texi > +++ b/doc/encoders.texi > @@ -1889,6 +1889,47 @@ ffmpeg -i input -c:v libaom-av1 -b:v 500K -aom- > params tune=3Dpsnr:enable-tpl-model > = > @end table > = > +@section liboapv > + > +Advanced Professional Video codec encoder wrapper. > + > +This encoder requires the presence of the liboapv headers and library > +during configuration. You need to explicitly configure the build with > +@option{--enable-liboapv}. > + > +@float NOTE > +Many liboapv encoder options are mapped to FFmpeg global codec options, > +while unique encoder options are provided through private options. > +Additionally the apv-params private options allows one to pass a list > +of key=3Dvalue tuples as accepted by the liboapv @code{parse_apv_params} > function. > +@end float > + > +The apv project website is at > @url{https://protect2.fireeye.com/v1/url?k=3D0ac15afb-6bbaf073-0ac0d1b4- > 74fe4860018a-8320254a0f21174c&q=3D1&e=3Db2c8d30c-5c3a-4ef3-af4f- > bd15f74e89f9&u=3Dhttps%3A%2F%2Fgithub.com%2FAcademySoftwareFoundatio > n%2Fopenapv%257D. > + > +@subsection Options > + > +The following options are supported by the liboapv wrapper. > +The apv-equivalent options or values are listed in parentheses for easy > migration. > + > +@float NOTE > +To reduce the duplication of documentation, only the private options > +and some others requiring special attention are documented here. For > +the documentation of the undocumented generic options, see > +@ref{codec-options,,the Codec Options chapter}. > +@end float > + > +@float NOTE > +To get a more accurate and extensive documentation of the liboapv > +options, invoke the command @code{apv_app_enc --help} or consult the > liboapv documentation. > +@end float > + > +@table @option > +@item b (@emph{bitrate}) > +Set target video bitrate in bits/s. > +Note that FFmpeg's b option is expressed in bits/s, while apv's bitrate is in > kilobits/s. > + > +@end table > + > @section libsvtav1 > = > SVT-AV1 encoder wrapper. > diff --git a/libavcodec/Makefile b/libavcodec/Makefile index > cc142bbae2..cae8f3a9f1 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -1151,6 +1151,7 @@ OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) +=3D > libkvazaar.o > OBJS-$(CONFIG_LIBLC3_ENCODER) +=3D liblc3enc.o > OBJS-$(CONFIG_LIBLC3_DECODER) +=3D liblc3dec.o > OBJS-$(CONFIG_LIBMP3LAME_ENCODER) +=3D libmp3lame.o > +OBJS-$(CONFIG_LIBOAPV_ENCODER) +=3D liboapvenc.o > OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) +=3D libopencore-amr.o > OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) +=3D libopencore-amr.o > OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) +=3D libopencore-amr.o diff > --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index > 09f06c71d6..3cb04a2462 100644 > --- a/libavcodec/allcodecs.c > +++ b/libavcodec/allcodecs.c > @@ -764,6 +764,7 @@ extern const FFCodec ff_pcm_mulaw_at_decoder; > extern const FFCodec ff_qdmc_at_decoder; extern const FFCodec > ff_qdm2_at_decoder; extern FFCodec ff_libaom_av1_encoder; > + > /* preferred over libaribb24 */ > extern const FFCodec ff_libaribcaption_decoder; extern const FFCodec > ff_libaribb24_decoder; @@ -787,6 +788,7 @@ extern const FFCodec > ff_libjxl_encoder; extern const FFCodec ff_liblc3_encoder; extern const > FFCodec ff_liblc3_decoder; extern const FFCodec ff_libmp3lame_encoder; > +extern const FFCodec ff_liboapv_encoder; > extern const FFCodec ff_libopencore_amrnb_encoder; extern const FFCodec > ff_libopencore_amrnb_decoder; extern const FFCodec > ff_libopencore_amrwb_decoder; diff --git a/libavcodec/liboapvenc.c > b/libavcodec/liboapvenc.c new file mode 100644 index 0000000000..01fb20ecff > --- /dev/null > +++ b/libavcodec/liboapvenc.c > @@ -0,0 +1,490 @@ > +/* > + * liboapv encoder > + * Advanced Professional Video codec library > + * > + * Copyright (C) 2025 Dawid Kozinski > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > +02110-1301 USA */ > + > +#include > +#include > + > +#include > + > +#include "libavutil/opt.h" > +#include "libavutil/pixdesc.h" > +#include "libavutil/pixfmt.h" > +#include "libavutil/mem.h" > +#include "libavutil/avassert.h" > +#include "libavutil/imgutils.h" > + > +#include "avcodec.h" > +#include "packet_internal.h" > +#include "codec_internal.h" > +#include "encode.h" > + > +#define MAX_BS_BUF (128 * 1024 * 1024) > +#define MAX_NUM_FRMS (1) // supports only 1-frame in an access unit > +#define FRM_IDX (0) // supports only 1-frame in an access unit > +#define MAX_NUM_CC (OAPV_MAX_CC) // Max number of color componets > (upto 4:4:4:4) > + > +/** > + * The structure stores all the states associated with the instance of > +APV encoder */ typedef struct ApvEncContext { > + const AVClass *class; > + > + oapve_t id; // APV instance identifier > + oapvm_t mid; > + oapve_cdesc_t cdsc; // coding parameters i.e profile, width & height of > input frame, num of therads, frame rate ... > + oapv_bitb_t bitb; // bitstream buffer (output) > + oapve_stat_t stat; // encoding status (output) > + > + oapv_frms_t ifrms; // frames for input > + > + int num_frames; // number of frames in an access unit > + > + int preset_id; // preset of apv ( fastest, fast, medium, slow, placebo) > + > + int qp; // quantization parameter (QP) [0,51] > + > + AVDictionary *oapv_params; > +} ApvEncContext; > + > +static int apv_imgb_release(oapv_imgb_t *imgb) { > + int refcnt =3D --imgb->refcnt; > + if (refcnt =3D=3D 0) { > + for (int i =3D 0; i < imgb->np; i++) > + av_freep(&imgb->baddr[i]); > + av_free(imgb); > + } > + > + return refcnt; > +} > + > +static int apv_imgb_addref(oapv_imgb_t * imgb) { > + int refcnt =3D ++imgb->refcnt; > + return refcnt; > +} > + > +static int apv_imgb_getref(oapv_imgb_t * imgb) { > + return imgb->refcnt; > +} > + > +static oapv_imgb_t *apv_imgb_create(int w, int h, int cs, void *logctx) > +{ > + oapv_imgb_t *imgb; > + int i, bd; > + > + imgb =3D av_mallocz(sizeof(oapv_imgb_t)); > + if (!imgb) > + goto fail; > + > + bd =3D OAPV_CS_GET_BYTE_DEPTH(cs); /* byte unit */ > + > + imgb->w[0] =3D w; > + imgb->h[0] =3D h; > + switch(OAPV_CS_GET_FORMAT(cs)) { > + case OAPV_CF_YCBCR422: > + imgb->w[1] =3D imgb->w[2] =3D (w + 1) >> 1; > + imgb->h[1] =3D imgb->h[2] =3D h; > + imgb->np =3D 3; > + break; > + case OAPV_CF_YCBCR444: > + imgb->w[1] =3D imgb->w[2] =3D w; > + imgb->h[1] =3D imgb->h[2] =3D h; > + imgb->np =3D 3; > + break; > + default: > + av_log(logctx, AV_LOG_ERROR, "unsupported color format\n"); > + goto fail; > + } > + > + for (i =3D 0; i < imgb->np; i++) { > + imgb->aw[i] =3D FFALIGN(imgb->w[i], OAPV_MB_W); > + imgb->s[i] =3D imgb->aw[i] * bd; > + imgb->ah[i] =3D FFALIGN(imgb->h[i], OAPV_MB_H); > + imgb->e[i] =3D imgb->ah[i]; > + > + imgb->bsize[i] =3D imgb->s[i] * imgb->e[i]; > + imgb->a[i] =3D imgb->baddr[i] =3D av_mallocz(imgb->bsize[i]); > + if (imgb->a[i] =3D=3D NULL) > + goto fail; > + } > + imgb->cs =3D cs; > + imgb->addref =3D apv_imgb_addref; > + imgb->getref =3D apv_imgb_getref; > + imgb->release =3D apv_imgb_release; > + > + imgb->refcnt =3D 1; > + > + return imgb; > +fail: > + av_log(logctx, AV_LOG_ERROR, "cannot create image buffer\n"); > + if (imgb) { > + for (int i =3D 0; i < imgb->np; i++) > + av_freep(&imgb->a[i]); > + } > + av_freep(&imgb); > + return NULL; > +} > + > +/** > + * Convert FFmpeg pixel format (AVPixelFormat) into APV pre-defined > +color format > + * > + * @return APV pre-defined color format (@see oapv.h) on success, > +OAPV_CF_UNKNOWN on failure */ static inline int get_color_format(enum > +AVPixelFormat pix_fmt) { > + int cf =3D OAPV_CF_UNKNOWN; > + > + switch (pix_fmt) { > + case AV_PIX_FMT_YUV422P10: > + cf =3D OAPV_CF_YCBCR422; > + break; > + case AV_PIX_FMT_YUV444P10: > + cf =3D OAPV_CF_YCBCR444; > + break; > + default: > + break; > + } > + > + return cf; > +} > + > +/** > + * The function returns a pointer to the object of the oapve_cdesc_t type. > + * oapve_cdesc_t contains all encoder parameters that should be initialized > before the encoder is used. > + * > + * The field values of the oapve_cdesc_t structure are populated based on: > + * - the corresponding field values of the AvCodecConetxt structure, > + * - the apv encoder specific option values, > + * > + * The order of processing input data and populating the apve_cdsc > +structure > + * 1) first, the fields of the AVCodecContext structure corresponding to the > provided input options are processed, > + * (i.e -pix_fmt yuv422p -s:v 1920x1080 -r 30 -profile:v 0) > + * 2) then apve-specific options added as AVOption to the apv AVCodec > implementation > + * (i.e -preset 0) > + * > + * Keep in mind that, there are options that can be set in different ways. > + * In this case, please follow the above-mentioned order of processing. > + * The most recent assignments overwrite the previous values. > + * > + * @param[in] avctx codec context (AVCodecContext) > + * @param[out] cdsc contains all APV encoder encoder parameters that > +should be initialized before the encoder is use > + * > + * @return 0 on success, negative error code on failure */ static int > +get_conf(AVCodecContext *avctx, oapve_cdesc_t *cdsc) { > + ApvEncContext *apv =3D avctx->priv_data; > + > + /* initialize apv_param struct with default values */ > + int ret =3D oapve_param_default(&cdsc->param[FRM_IDX]); > + if (OAPV_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "Cannot set default parameter\n"); > + return AVERROR_EXTERNAL; > + } > + > + /* read options from AVCodecContext */ > + if (avctx->width > 0) > + cdsc->param[FRM_IDX].w =3D avctx->width; > + > + if (avctx->height > 0) > + cdsc->param[FRM_IDX].h =3D avctx->height; > + > + if (avctx->framerate.num > 0) { > + cdsc->param[FRM_IDX].fps_num =3D avctx->framerate.num; > + cdsc->param[FRM_IDX].fps_den =3D avctx->framerate.den; > + } else if (avctx->time_base.num > 0) { > + cdsc->param[FRM_IDX].fps_num =3D avctx->time_base.den; > + cdsc->param[FRM_IDX].fps_den =3D avctx->time_base.num; > + } > + > + cdsc->param[FRM_IDX].preset =3D apv->preset_id; > + cdsc->param[FRM_IDX].qp =3D apv->qp; > + if (avctx->bit_rate / 1000 > INT_MAX || avctx->rc_max_rate / 1000 > > INT_MAX) { > + av_log(avctx, AV_LOG_ERROR, "Not supported bitrate bit_rate and > rc_max_rate > %d000\n", INT_MAX); > + return AVERROR(EINVAL); > + } > + cdsc->param[FRM_IDX].bitrate =3D (int)(avctx->bit_rate / 1000); > + if (cdsc->param[FRM_IDX].bitrate) { > + if (cdsc->param[FRM_IDX].qp) { > + av_log(avctx, AV_LOG_WARNING, "You cannot set both the bitrate and > the QP parameter at the same time.\n" > + "If the bitrate is set, the rate control type is set to ABR, > which means that the QP value is ignored.\n"); > + } > + cdsc->param[FRM_IDX].rc_type =3D OAPV_RC_ABR; > + } > + > + cdsc->threads =3D avctx->thread_count; > + > + if (avctx->color_primaries !=3D AVCOL_PRI_UNSPECIFIED) > + cdsc->param[FRM_IDX].color_primaries =3D avctx->color_primaries; > + > + if (avctx->color_trc !=3D AVCOL_TRC_UNSPECIFIED) > + cdsc->param[FRM_IDX].transfer_characteristics =3D > + avctx->color_trc; > + > + if (avctx->colorspace !=3D AVCOL_SPC_UNSPECIFIED) > + cdsc->param[FRM_IDX].matrix_coefficients =3D avctx->colorspace; > + > + if (avctx->color_range !=3D AVCOL_RANGE_UNSPECIFIED) > + cdsc->param[FRM_IDX].full_range_flag =3D (avctx->color_range =3D= =3D > + AVCOL_RANGE_JPEG); > + > + cdsc->max_bs_buf_size =3D MAX_BS_BUF; /* maximum bitstream buffer si= ze > */ > + cdsc->max_num_frms =3D MAX_NUM_FRMS; > + > + return 0; > +} > + > +static int get_bit_depth(enum AVPixelFormat pixel_format) { > + const AVPixFmtDescriptor *desc =3D av_pix_fmt_desc_get(pixel_format= ); > + av_assert0(desc); > + return desc->comp[0].depth; > +} > + > +/** > + * @brief Initialize APV codec > + * Create an encoder instance and allocate all the needed resources > + * > + * @param avctx codec context > + * @return 0 on success, negative error code on failure */ static > +av_cold int liboapve_init(AVCodecContext *avctx) { > + ApvEncContext *apv =3D avctx->priv_data; > + oapve_cdesc_t *cdsc =3D &apv->cdsc; > + unsigned char *bs_buf; > + int input_depth; > + int cfmt; // color format > + int ret; > + > + apv->id =3D NULL; > + apv->mid =3D NULL; > + apv->bitb.addr =3D NULL; > + > + /* allocate bitstream buffer */ > + bs_buf =3D (unsigned char *)av_malloc(MAX_BS_BUF); > + if (bs_buf =3D=3D NULL) { > + av_log(avctx, AV_LOG_ERROR, "Cannot allocate bitstream buffer, > size=3D%d\n", MAX_BS_BUF); > + return AVERROR(ENOMEM); > + } > + apv->bitb.addr =3D bs_buf; > + apv->bitb.bsize =3D MAX_BS_BUF; > + > + /* read configurations and set values for created descriptor (APV_CDSC) */ > + ret =3D get_conf(avctx, cdsc); > + if (ret < 0) { > + av_log(avctx, AV_LOG_ERROR, "Cannot get OAPV configuration\n"); > + return ret; > + } > + > + const AVDictionaryEntry *en =3D NULL; > + while (en =3D av_dict_iterate(apv->oapv_params, en)) { > + ret =3D oapve_param_parse(&cdsc->param[FRM_IDX], en->key, en->value); > + if (ret < 0) > + av_log(avctx, AV_LOG_WARNING, "Error parsing option '%s =3D %s'.\n", > en->key, en->value); > + } > + > + /* create encoder */ > + apv->id =3D oapve_create(cdsc, &ret); > + if (apv->id =3D=3D NULL) { > + av_log(avctx, AV_LOG_ERROR, "Cannot create OAPV encoder\n"); > + if (ret =3D=3D OAPV_ERR_INVALID_LEVEL) > + av_log(avctx, AV_LOG_ERROR, "Invalid level idc: %d\n", cdsc- > >param[0].level_idc); > + return AVERROR_EXTERNAL; > + } > + > + /* create metadata handler */ > + apv->mid =3D oapvm_create(&ret); > + if (apv->mid =3D=3D NULL || OAPV_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "cannot create OAPV metadata > handler\n"); > + return AVERROR_EXTERNAL; > + } > + > + input_depth =3D get_bit_depth(avctx->pix_fmt); > + cfmt =3D get_color_format(avctx->pix_fmt); > + > + apv->ifrms.frm[FRM_IDX].imgb =3D apv_imgb_create(avctx->width, avctx- > >height, > + OAPV_CS_SET(cfmt, input_depth, > AV_HAVE_BIGENDIAN), avctx); > + if (apv->ifrms.frm[FRM_IDX].imgb =3D=3D NULL) > + return AVERROR(ENOMEM); > + apv->ifrms.num_frms++; > + > + /* color description values */ > + if (cdsc->param[FRM_IDX].color_description_present_flag) { > + avctx->color_primaries =3D cdsc->param[FRM_IDX].color_primaries; > + avctx->color_trc =3D cdsc->param[FRM_IDX].transfer_characteristi= cs; > + avctx->colorspace =3D cdsc->param[FRM_IDX].matrix_coefficients; > + avctx->color_range =3D (cdsc->param[FRM_IDX].full_range_flag) ? > AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; > + } > + > + return 0; > +} > + > +/** > + * Encode raw data frame into APV packet > + * > + * @param[in] avctx codec context > + * @param[out] avpkt output AVPacket containing encoded data > + * @param[in] frame AVFrame containing the raw data to be encoded > + * @param[out] got_packet encoder sets to 0 or 1 to indicate that a > + * non-empty packet was returned in pkt > + * > + * @return 0 on success, negative error code on failure > + */ > +static int liboapve_encode(AVCodecContext *avctx, AVPacket *avpkt, > + const AVFrame *frame, int *got_packet) { > + ApvEncContext *apv =3D avctx->priv_data; > + oapv_frm_t *frm =3D &apv->ifrms.frm[FRM_IDX]; > + oapv_imgb_t *imgb =3D frm->imgb; > + int ret; > + > + if (avctx->width !=3D frame->width || avctx->height !=3D frame->heig= ht || avctx- > >pix_fmt !=3D frame->format) { > + av_log(avctx, AV_LOG_ERROR, "Dimension change is not supported\n"); > + return AVERROR(EINVAL); > + } > + > + av_image_copy((uint8_t **)imgb->a, imgb->s, (const uint8_t **)frame- > >data, frame->linesize, > + frame->format, frame->width, frame->height); > + > + imgb->ts[0] =3D frame->pts; > + > + frm->group_id =3D 1; // @todo FIX-ME : need to set properly in case = of multi- > frame > + frm->pbu_type =3D OAPV_PBU_TYPE_PRIMARY_FRAME; > + > + ret =3D oapve_encode(apv->id, &apv->ifrms, apv->mid, &apv->bitb, &ap= v- > >stat, NULL); > + if (OAPV_FAILED(ret)) { > + av_log(avctx, AV_LOG_ERROR, "oapve_encode() failed\n"); > + return AVERROR_EXTERNAL; > + } > + > + /* store bitstream */ > + if (OAPV_SUCCEEDED(ret) && apv->stat.write > 0) { > + ret =3D ff_get_encode_buffer(avctx, avpkt, apv->stat.write - 4, = 0); > + if (ret < 0) > + return ret; > + > + // The encoder returns a "Raw bitstream" formated AU, including au_size. > + // Discard it as we only need the access_unit() structure. > + memcpy(avpkt->data, (uint8_t *)apv->bitb.addr + 4, > + apv->stat.write - 4); > + > + avpkt->time_base.num =3D apv->cdsc.param->fps_num; > + avpkt->time_base.den =3D apv->cdsc.param->fps_den; > + > + avpkt->pts =3D avpkt->dts =3D frame->pts; > + avpkt->flags |=3D AV_PKT_FLAG_KEY; > + > + ff_side_data_set_encoder_stats(avpkt, apv->qp * FF_QP2LAMBDA, > + NULL, 0, AV_PICTURE_TYPE_I); > + > + *got_packet =3D 1; > + } > + > + return 0; > +} > + > +/** > + * Destroy the encoder and release all the allocated resources > + * > + * @param avctx codec context > + * @return 0 on success, negative error code on failure */ static > +av_cold int liboapve_close(AVCodecContext *avctx) { > + ApvEncContext *apv =3D avctx->priv_data; > + > + for (int i =3D 0; i < apv->num_frames; i++) { > + if (apv->ifrms.frm[i].imgb !=3D NULL) > + apv->ifrms.frm[i].imgb->release(apv->ifrms.frm[i].imgb); > + apv->ifrms.frm[i].imgb =3D NULL; > + } > + > + if (apv->mid) { > + oapvm_rem_all(apv->mid); > + } > + > + if (apv->id) { > + oapve_delete(apv->id); > + apv->id =3D NULL; > + } > + > + if (apv->mid) { > + oapvm_delete(apv->mid); > + apv->mid =3D NULL; > + } > + > + av_freep(&apv->bitb.addr); /* release bitstream buffer */ > + > + return 0; > +} > + > +#define OFFSET(x) offsetof(ApvEncContext, x) #define VE > +AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM > + > +static const enum AVPixelFormat supported_pixel_formats[] =3D { > + AV_PIX_FMT_YUV422P10, > + AV_PIX_FMT_YUV444P10, > + AV_PIX_FMT_NONE > +}; > + > +static const AVOption liboapv_options[] =3D { > + { "preset", "Encoding preset for setting encoding speed (optimization level > control)", OFFSET(preset_id), AV_OPT_TYPE_INT, { .i64 =3D > OAPV_PRESET_DEFAULT }, OAPV_PRESET_FASTEST, OAPV_PRESET_PLACEBO, > VE, .unit =3D "preset" }, > + { "fastest", NULL, 0, AV_OPT_TYPE_CONST, { .i64 =3D OAPV_PRESET_FAST= EST > }, INT_MIN, INT_MAX, VE, .unit =3D "preset" }, > + { "fast", NULL, 0, AV_OPT_TYPE_CONST, { .i64 =3D OAPV_PRESET_FAST= }, > INT_MIN, INT_MAX, VE, .unit =3D "preset" }, > + { "medium", NULL, 0, AV_OPT_TYPE_CONST, { .i64 =3D > OAPV_PRESET_MEDIUM }, INT_MIN, INT_MAX, VE, .unit =3D "preset" }, > + { "slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 =3D OAPV_PRESET_SLOW= }, > INT_MIN, INT_MAX, VE, .unit =3D "preset" }, > + { "placebo", NULL, 0, AV_OPT_TYPE_CONST, { .i64 =3D > OAPV_PRESET_PLACEBO }, INT_MIN, INT_MAX, VE, .unit =3D "preset" }, > + { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 =3D > +OAPV_PRESET_DEFAULT }, INT_MIN, INT_MAX, VE, .unit =3D "preset" }, > + > + { "qp", "Quantization parameter value for CQP rate control mode", > OFFSET(qp), AV_OPT_TYPE_INT, { .i64 =3D 32 }, 0, 51, VE }, > + { "oapv-params", "Override the apv configuration using a :-separated list of > key=3Dvalue parameters", OFFSET(oapv_params), AV_OPT_TYPE_DICT, { 0 }, 0,= 0, > VE }, > + { NULL } > +}; > + > +static const AVClass liboapve_class =3D { > + .class_name =3D "liboapv", > + .item_name =3D av_default_item_name, > + .option =3D liboapv_options, > + .version =3D LIBAVUTIL_VERSION_INT, > +}; > + > +static const FFCodecDefault liboapve_defaults[] =3D { > + { "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) > + { NULL }, > +}; > + > +const FFCodec ff_liboapv_encoder =3D { > + .p.name =3D "liboapv", > + .p.long_name =3D NULL_IF_CONFIG_SMALL("liboapv APV"), > + .p.type =3D AVMEDIA_TYPE_VIDEO, > + .p.id =3D AV_CODEC_ID_APV, > + .init =3D liboapve_init, > + FF_CODEC_ENCODE_CB(liboapve_encode), > + .close =3D liboapve_close, > + .priv_data_size =3D sizeof(ApvEncContext), > + .p.priv_class =3D &liboapve_class, > + .defaults =3D liboapve_defaults, > + .p.capabilities =3D AV_CODEC_CAP_OTHER_THREADS | > AV_CODEC_CAP_DR1, > + .p.wrapper_name =3D "liboapv", > + .p.pix_fmts =3D supported_pixel_formats, > + .caps_internal =3D FF_CODEC_CAP_INIT_CLEANUP | > FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_NOT_INIT_THREADSAFE, > +}; > -- > 2.49.0 > = > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://protect2.fireeye.com/v1/url?k=3Dc2a62f8e-a3dd8506-c2a7a4c1- > 74fe4860018a-499384c6081a622b&q=3D1&e=3Db2c8d30c-5c3a-4ef3-af4f- > bd15f74e89f9&u=3Dhttps%3A%2F%2Fffmpeg.org%2Fmailman%2Flistinfo%2Fffmp > eg-devel > = > To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org > with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".