From: Thomas Siedel <thomas.ff@spin-digital.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH v2 08/10] avcodec: add external encoder libvvenc for H266/VVC Date: Thu, 3 Nov 2022 13:51:38 +0100 Message-ID: <CAD25kL61VBAfqWC6skanVT4Yymp+m9qhyPb_uCLuW1jkK7fZKA@mail.gmail.com> (raw) In-Reply-To: <6329329f-75ac-acfe-c517-9c9be10920dc@gmail.com> On Mon, 24 Oct 2022 at 16:38, quietvoid <tcchlisop0@gmail.com> wrote: > On 24/10/2022 10.06, Thomas Siedel wrote: > > > Add external encoder VVenC for H266/VVC encoding. > > Register new encoder libvvencc > > Add libvvenc to wrap the vvenc interface into ffmpeg > > libvvenc implements encoder option: > > preset,qp,period,subjopt,vvenc-params,levelidc,tier > > Enable encoder by adding --enable-libvvenc in configure step > > > > Signed-off-by: Thomas Siedel<thomas.ff@spin-digital.com> > > --- > > configure | 5 + > > libavcodec/Makefile | 1 + > > libavcodec/allcodecs.c | 1 + > > libavcodec/libvvenc.c | 442 +++++++++++++++++++++++++++++++++++++++++ > > 4 files changed, 449 insertions(+) > > create mode 100644 libavcodec/libvvenc.c > > > > diff --git a/configure b/configure > > index 978f15f772..f8f7965371 100755 > > --- a/configure > > +++ b/configure > > @@ -289,6 +289,7 @@ External library support: > > native implementation exists [no] > > --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no] > > --enable-libvvdec enable VVC decoding via vvdec [no] > > + --enable-libvvenc enable VVC encoding via vvenc [no] > > --enable-libwebp enable WebP encoding via libwebp [no] > > --enable-libx264 enable H.264 encoding via x264 [no] > > --enable-libx265 enable HEVC encoding via x265 [no] > > @@ -1877,6 +1878,7 @@ EXTERNAL_LIBRARY_LIST=" > > libvorbis > > libvpx > > libvvdec > > + libvvenc > > libwebp > > libxml2 > > libzimg > > @@ -3409,6 +3411,8 @@ libvpx_vp9_decoder_deps="libvpx" > > libvpx_vp9_encoder_deps="libvpx" > > libvvdec_decoder_deps="libvvdec" > > libvvdec_decoder_select="vvc_mp4toannexb_bsf" > > +libvvenc_encoder_deps="libvvenc" > > +libvvenc_encoder_select="atsc_a53" > > libwebp_encoder_deps="libwebp" > > libwebp_anim_encoder_deps="libwebp" > > libx262_encoder_deps="libx262" > > @@ -6740,6 +6744,7 @@ enabled libvpx && { > > fi > > } > > enabled libvvdec && require_pkg_config libvvdec "libvvdec >= 1.6.0" > > "vvdec/vvdec.h" vvdec_get_version > > +enabled libvvenc && require_pkg_config libvvenc "libvvenc >= 1.6.1" > > "vvenc/vvenc.h" vvenc_get_version > > enabled libwebp && { > > enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= > > 0.2.0" webp/encode.h WebPGetEncoderVersion > > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > > index f4cdbc9be1..badd266e66 100644 > > --- a/libavcodec/Makefile > > +++ b/libavcodec/Makefile > > @@ -1105,6 +1105,7 @@ OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o > > OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o > > OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o > > OBJS-$(CONFIG_LIBVVDEC_DECODER) += libvvdec.o vvc_parse_extradata.o > > vvc_paramset.o > > +OBJS-$(CONFIG_LIBVVENC_ENCODER) += libvvenc.o > > OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o > > OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o > > libwebpenc_animencoder.o > > OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o > > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > > index 9813b291f4..73c36f3134 100644 > > --- a/libavcodec/allcodecs.c > > +++ b/libavcodec/allcodecs.c > > @@ -794,6 +794,7 @@ extern const FFCodec ff_libvpx_vp8_decoder; > > extern FFCodec ff_libvpx_vp9_encoder; > > extern FFCodec ff_libvpx_vp9_decoder; > > extern const FFCodec ff_libvvdec_decoder; > > +extern const FFCodec ff_libvvenc_encoder; > > /* preferred over libwebp */ > > extern const FFCodec ff_libwebp_anim_encoder; > > extern const FFCodec ff_libwebp_encoder; > > diff --git a/libavcodec/libvvenc.c b/libavcodec/libvvenc.c > > new file mode 100644 > > index 0000000000..508fe6ceff > > --- /dev/null > > +++ b/libavcodec/libvvenc.c > > @@ -0,0 +1,442 @@ > > +/* > > + * H.266 encoding using the VVenC library > > + * > > + * Copyright (C) 2022, Thomas Siedel > > + * > > + * 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 "config_components.h" > > + > > +#include <vvenc/vvenc.h> > > +#include <vvenc/vvencCfg.h> > > + > > +#include "avcodec.h" > > +#include "codec_internal.h" > > +#include "encode.h" > > +#include "internal.h" > > +#include "packet_internal.h" > > +#include "profiles.h" > > + > > +#include "libavutil/avutil.h" > > +#include "libavutil/pixdesc.h" > > +#include "libavutil/opt.h" > > +#include "libavutil/common.h" > > +#include "libavutil/imgutils.h" > > +#include "libavutil/frame.h" > > +#include "libavutil/log.h" > > + > > +typedef struct VVenCOptions { > > + int preset; // preset 0: faster 4: slower > > + int qp; // quantization parameter 0-63 > > + int subjectiveOptimization; // perceptually motivated QP adaptation, > > XPSNR based > > + int intraRefreshSec; // intra period/refresh in seconds > > + int levelIdc; // vvc level_idc > > + int tier; // vvc tier > > + AVDictionary *vvenc_opts; > > +} VVenCOptions; > > + > > +typedef struct VVenCContext { > > + AVClass *av_class; > > + VVenCOptions options; // encoder options > > + vvencEncoder *vvencEnc; > > + vvencAccessUnit *pAU; > > + bool encodeDone; > > +}VVenCContext; > > + > > + > > +static av_cold void ff_vvenc_log_callback(void *avctx, int level, > > const char *fmt, va_list args ) > > +{ > > + vfprintf( level == 1 ? stderr : stdout, fmt, args ); > > +} > > + > > +static void ff_vvenc_internalLog( void* ctx, int level, const char* > > fmt, ... ) > > +{ > > + va_list args; > > + va_start( args, fmt ); > > + ff_vvenc_log_callback( ctx, level, fmt, args ); > > + va_end( args ); > > +} > > + > > +static av_cold int ff_vvenc_encode_init(AVCodecContext *avctx) > > +{ > > + int ret; > > + int framerate, qp, parse_ret; > > + VVenCContext *s; > > + vvenc_config params; > > + vvencPresetMode preset; > > + AVDictionaryEntry *en; > > + char statsfile[1024]="vvenc-rcstats.json"; > > + > > + s = (VVenCContext*)avctx->priv_data; > > + qp = (vvencPresetMode)s->options.qp; > > + preset = (vvencPresetMode)s->options.preset; > > + > > + if( avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT ) { > > + av_log(avctx, AV_LOG_ERROR, "ff_vvenc_encode_init::init() interlaced > > encoding not supported yet\n"); > > + return AVERROR_INVALIDDATA; > > + } > > + > > + vvenc_config_default( ¶ms ); > > + > > + // set desired encoding options > > + framerate = avctx->time_base.den / avctx->time_base.num; > > + vvenc_init_default ( ¶ms, avctx->width, avctx->height, > > framerate, avctx->bit_rate, qp, preset ); > > + params.m_FrameRate = avctx->time_base.den; > > + params.m_FrameScale = avctx->time_base.num; > > + > > + params.m_verbosity = VVENC_VERBOSE; > > + if ( av_log_get_level() >= AV_LOG_DEBUG ) > > + params.m_verbosity = VVENC_DETAILS; > > + else if( av_log_get_level() >= AV_LOG_VERBOSE ) > > + params.m_verbosity = VVENC_NOTICE; // output per picture info > > + else if( av_log_get_level() >= AV_LOG_INFO ) > > + params.m_verbosity = VVENC_WARNING; // ffmpeg default ffmpeg loglevel > > + else > > + params.m_verbosity = VVENC_SILENT; > > + > > + if( avctx->ticks_per_frame == 1 ) { > > + params.m_TicksPerSecond = -1; // auto mode for ticks per frame = 1 > > + } > > + else{ > > + params.m_TicksPerSecond = > > > ceil((avctx->time_base.den/(double)avctx->time_base.num)*(double)avctx->ticks_per_frame); > > + } > > + > > + if( avctx->thread_count > 0 ) > > + params.m_numThreads = avctx->thread_count; > > + > > + // GOP settings (IDR/CRA) > > + if( avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ) > > + params.m_DecodingRefreshType = VVENC_DRT_IDR; > > + > > + if( avctx->gop_size == 1 ) { > > + params.m_GOPSize = 1; > > + params.m_IntraPeriod = 1; > > + } > > + else { > > + params.m_IntraPeriodSec = s->options.intraRefreshSec; > > + } > > + > > + params.m_usePerceptQPA = s->options.subjectiveOptimization; > > + params.m_level = (vvencLevel)s->options.levelIdc; > > + params.m_levelTier = (vvencTier)s->options.tier; > > + > > + params.m_AccessUnitDelimiter = true; > > + > > + params.m_internChromaFormat = VVENC_CHROMA_420; > > + switch( avctx->pix_fmt ) { > > + case AV_PIX_FMT_YUV420P : > > + params.m_inputBitDepth[0] = 8; > > + break; > > + case AV_PIX_FMT_YUV420P10LE: > > + params.m_inputBitDepth[0] = 10; > > + break; > > + default: { > > + av_log(avctx, AV_LOG_ERROR, "unsupported pixel format %s, choose > > yuv420p or yuv420p10le\n", av_get_pix_fmt_name(avctx->pix_fmt)); > > + return AVERROR(EINVAL); > > + break; > > + } > > + }; > > + > > + if( avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ) > > + params.m_colourPrimaries = (int)avctx->color_primaries; > > + if( avctx->colorspace != AVCOL_SPC_UNSPECIFIED ) > > + params.m_matrixCoefficients = (int)avctx->colorspace; > > + if( avctx->color_trc != AVCOL_TRC_UNSPECIFIED ) { > > + params.m_transferCharacteristics = (int)avctx->color_trc; > > + > > + if ( params.m_transferCharacteristics == 16 ) > > + params.m_HdrMode = (params.m_colourPrimaries == 9) ? > VVENC_HDR_PQ_BT2020 > > + : VVENC_HDR_PQ; > > + else if ( params.m_transferCharacteristics == 14 && > > params.m_colourPrimaries == 9 ) > > + params.m_HdrMode = VVENC_HDR_HLG_BT2020; > > > Should probably still be using the AVColor enum in the conditions > instead of the values. > Thanks for pointing this out, I now changed it to use the AVColor enums in the new patch set version 3. > > > + else if ( params.m_transferCharacteristics == 1 && > > params.m_colourPrimaries == 1 && > > + params.m_matrixCoefficients == 1 ) > > + params.m_HdrMode = VVENC_HDR_HLG; > > > Is this not supposed to be VVENC_HDR_OFF? > HLG should be matching TRC 14, not 1. > HDR HLG mode was set for color formats/colorspaces that are used for SDR signaling. That code was taken from the vvenc implementation, where bt709 formats are used for HLG 8bit. Now I changed it. In the new version, HLG is only set if the transfer function is HLG (AVCOL_TRC_BT2020_10) or AVCOL_TRC_ARIB_STD_B67. HLG 2020 is used if the input color primaries or color space is also bt2020. SDR signalization has been added. So if any color primaries/colorspace/transfer characteristics are set and it is not an HDR mode, libbvvenc enables VUI signalization in vvenc. This is needed as vvenc currently only enables VUI signalization if any HDR mode is set. This is an issue in vvenc. _______________________________________________ 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".
next prev parent reply other threads:[~2022-11-03 12:52 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-10-24 14:06 [FFmpeg-devel] [PATCH v2 00/10] Add support " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 01/10] avcodec: add enum types " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 02/10] avcodec: add cbs " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 03/10] avcodec: add bitstream parser " Thomas Siedel 2022-10-24 14:38 ` James Almer 2022-10-31 10:16 ` Thomas Siedel 2022-10-31 20:02 ` James Almer 2022-11-03 12:37 ` Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 04/10] avcodec: add MP4 to annexb support " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 05/10] avformat: add demuxer and probe " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 06/10] avformat: add muxer " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 07/10] avcodec: add external decoder libvvdec " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 08/10] avcodec: add external encoder libvvenc " Thomas Siedel 2022-10-24 14:37 ` quietvoid 2022-11-03 12:51 ` Thomas Siedel [this message] 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 09/10] avformat: add ts stream types " Thomas Siedel 2022-10-24 14:06 ` [FFmpeg-devel] [PATCH v2 10/10] avcodec: increase minor version " Thomas Siedel
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=CAD25kL61VBAfqWC6skanVT4Yymp+m9qhyPb_uCLuW1jkK7fZKA@mail.gmail.com \ --to=thomas.ff@spin-digital.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git