avcodec/evc_encoder: Provided support for EVC encoder
- Added EVC encoder wrapper - Changes in project configuration file and libavcodec Makefile - Added documentation for xeve wrapper Signed-off-by: Dawid Kozinski <d.kozinski@samsung.com> Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
		
							parent
							
								
									e56d91f8a8
								
							
						
					
					
						commit
						c59a96fd08
					
				
							
								
								
									
										4
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								configure
									
									
									
									
										vendored
									
									
								
							| @ -289,6 +289,7 @@ External library support: | |||||||
|   --enable-libwebp         enable WebP encoding via libwebp [no] |   --enable-libwebp         enable WebP encoding via libwebp [no] | ||||||
|   --enable-libx264         enable H.264 encoding via x264 [no] |   --enable-libx264         enable H.264 encoding via x264 [no] | ||||||
|   --enable-libx265         enable HEVC encoding via x265 [no] |   --enable-libx265         enable HEVC encoding via x265 [no] | ||||||
|  |   --enable-libxeve         enable EVC encoding via libxeve [no] | ||||||
|   --enable-libxavs         enable AVS encoding via xavs [no] |   --enable-libxavs         enable AVS encoding via xavs [no] | ||||||
|   --enable-libxavs2        enable AVS2 encoding via xavs2 [no] |   --enable-libxavs2        enable AVS2 encoding via xavs2 [no] | ||||||
|   --enable-libxcb          enable X11 grabbing using XCB [autodetect] |   --enable-libxcb          enable X11 grabbing using XCB [autodetect] | ||||||
| @ -1901,6 +1902,7 @@ EXTERNAL_LIBRARY_LIST=" | |||||||
|     libvorbis |     libvorbis | ||||||
|     libvpx |     libvpx | ||||||
|     libwebp |     libwebp | ||||||
|  |     libxeve | ||||||
|     libxml2 |     libxml2 | ||||||
|     libzimg |     libzimg | ||||||
|     libzmq |     libzmq | ||||||
| @ -3458,6 +3460,7 @@ libx265_encoder_deps="libx265" | |||||||
| libx265_encoder_select="atsc_a53" | libx265_encoder_select="atsc_a53" | ||||||
| libxavs_encoder_deps="libxavs" | libxavs_encoder_deps="libxavs" | ||||||
| libxavs2_encoder_deps="libxavs2" | libxavs2_encoder_deps="libxavs2" | ||||||
|  | libxeve_encoder_deps="libxeve" | ||||||
| libxvid_encoder_deps="libxvid" | libxvid_encoder_deps="libxvid" | ||||||
| libzvbi_teletext_decoder_deps="libzvbi" | libzvbi_teletext_decoder_deps="libzvbi" | ||||||
| vapoursynth_demuxer_deps="vapoursynth" | vapoursynth_demuxer_deps="vapoursynth" | ||||||
| @ -6872,6 +6875,7 @@ enabled libx265           && require_pkg_config libx265 x265 x265.h x265_api_get | |||||||
|                              require_cpp_condition libx265 x265.h "X265_BUILD >= 89" |                              require_cpp_condition libx265 x265.h "X265_BUILD >= 89" | ||||||
| enabled libxavs           && require libxavs "stdint.h xavs.h" xavs_encoder_encode "-lxavs $pthreads_extralibs $libm_extralibs" | enabled libxavs           && require libxavs "stdint.h xavs.h" xavs_encoder_encode "-lxavs $pthreads_extralibs $libm_extralibs" | ||||||
| enabled libxavs2          && require_pkg_config libxavs2 "xavs2 >= 1.3.0" "stdint.h xavs2.h" xavs2_api_get | enabled libxavs2          && require_pkg_config libxavs2 "xavs2 >= 1.3.0" "stdint.h xavs2.h" xavs2_api_get | ||||||
|  | enabled libxeve           && require_pkg_config libxeve "xeve >= 0.4.3" "xeve.h" xeve_encode | ||||||
| enabled libxvid           && require libxvid xvid.h xvid_global -lxvidcore | enabled libxvid           && require libxvid xvid.h xvid_global -lxvidcore | ||||||
| enabled libzimg           && require_pkg_config libzimg "zimg >= 2.7.0" zimg.h zimg_get_api_version | enabled libzimg           && require_pkg_config libzimg "zimg >= 2.7.0" zimg.h zimg_get_api_version | ||||||
| enabled libzmq            && require_pkg_config libzmq "libzmq >= 4.2.1" zmq.h zmq_ctx_new | enabled libzmq            && require_pkg_config libzmq "libzmq >= 4.2.1" zmq.h zmq_ctx_new | ||||||
|  | |||||||
| @ -2911,6 +2911,75 @@ ffmpeg -i input -c:v libxavs2 -xavs2-params RdoqLevel=0 output.avs2 | |||||||
| @end example | @end example | ||||||
| @end table | @end table | ||||||
| 
 | 
 | ||||||
|  | @section libxeve | ||||||
|  | 
 | ||||||
|  | eXtra-fast Essential Video Encoder (XEVE) MPEG-5 EVC encoder wrapper. | ||||||
|  | The xeve-equivalent options or values are listed in parentheses for easy migration. | ||||||
|  | 
 | ||||||
|  | This encoder requires the presence of the libxeve headers and library | ||||||
|  | during configuration. You need to explicitly configure the build with | ||||||
|  | @option{--enable-libxeve}. | ||||||
|  | 
 | ||||||
|  | @float NOTE | ||||||
|  | Many libxeve encoder options are mapped to FFmpeg global codec options, | ||||||
|  | while unique encoder options are provided through private options. | ||||||
|  | Additionally the xeve-params private options allows one to pass a list | ||||||
|  | of key=value tuples as accepted by the libxeve @code{parse_xeve_params} function. | ||||||
|  | @end float | ||||||
|  | 
 | ||||||
|  | The xeve project website is at @url{https://github.com/mpeg5/xeve}. | ||||||
|  | 
 | ||||||
|  | @subsection Options | ||||||
|  | 
 | ||||||
|  | The following options are supported by the libxeve wrapper. | ||||||
|  | The xeve-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 libxeve options, | ||||||
|  | invoke the command  @code{xeve_app --help} or consult the libxeve 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 xeve's bitrate is in kilobits/s. | ||||||
|  | 
 | ||||||
|  | @item bf (@emph{bframes}) | ||||||
|  | Set the maximum number of B frames (1,3,7,15). | ||||||
|  | 
 | ||||||
|  | @item g (@emph{keyint}) | ||||||
|  | Set the GOP size (I-picture period). | ||||||
|  | 
 | ||||||
|  | @item preset (@emph{preset}) | ||||||
|  | Set the xeve preset. | ||||||
|  | Set the encoder preset value to determine encoding speed [fast, medium, slow, placebo] | ||||||
|  | 
 | ||||||
|  | @item tune (@emph{tune}) | ||||||
|  | Set the encoder tune parameter [psnr, zerolatency] | ||||||
|  | 
 | ||||||
|  | @item profile (@emph{profile}) | ||||||
|  | Set the encoder profile [0: baselie; 1: main] | ||||||
|  | 
 | ||||||
|  | @item crf (@emph{crf}) | ||||||
|  | Set the quality for constant quality mode. | ||||||
|  | Constant rate factor <10..49> [default: 32] | ||||||
|  | 
 | ||||||
|  | @item qp (@emph{qp}) | ||||||
|  | Set constant quantization rate control method parameter. | ||||||
|  | Quantization parameter qp <0..51> [default: 32] | ||||||
|  | 
 | ||||||
|  | @item threads (@emph{threads}) | ||||||
|  | Force to use a specific number of threads | ||||||
|  | 
 | ||||||
|  | @end table | ||||||
|  | 
 | ||||||
| @section libxvid | @section libxvid | ||||||
| 
 | 
 | ||||||
| Xvid MPEG-4 Part 2 encoder wrapper. | Xvid MPEG-4 Part 2 encoder wrapper. | ||||||
|  | |||||||
| @ -343,6 +343,14 @@ libxavs2 is under the GNU Public License Version 2 or later | |||||||
| details), you must upgrade FFmpeg's license to GPL in order to use it. | details), you must upgrade FFmpeg's license to GPL in order to use it. | ||||||
| @end float | @end float | ||||||
| 
 | 
 | ||||||
|  | @section eXtra-fast Essential Video Encoder (XEVE) | ||||||
|  | 
 | ||||||
|  | FFmpeg can make use of the XEVE library for EVC video encoding. | ||||||
|  | 
 | ||||||
|  | Go to @url{https://github.com/mpeg5/xeve} and follow the instructions for | ||||||
|  | installing the XEVE library. Then pass @code{--enable-libxeve} to configure to | ||||||
|  | enable it. | ||||||
|  | 
 | ||||||
| @section ZVBI | @section ZVBI | ||||||
| 
 | 
 | ||||||
| ZVBI is a VBI decoding library which can be used by FFmpeg to decode DVB | ZVBI is a VBI decoding library which can be used by FFmpeg to decode DVB | ||||||
| @ -598,6 +606,7 @@ library: | |||||||
| @item raw DTS                   @tab X @tab X | @item raw DTS                   @tab X @tab X | ||||||
| @item raw DTS-HD                @tab   @tab X | @item raw DTS-HD                @tab   @tab X | ||||||
| @item raw E-AC-3                @tab X @tab X | @item raw E-AC-3                @tab X @tab X | ||||||
|  | @item raw EVC                   @tab X @tab | ||||||
| @item raw FLAC                  @tab X @tab X | @item raw FLAC                  @tab X @tab X | ||||||
| @item raw GSM                   @tab   @tab X | @item raw GSM                   @tab   @tab X | ||||||
| @item raw H.261                 @tab X @tab X | @item raw H.261                 @tab X @tab X | ||||||
| @ -944,6 +953,8 @@ following image formats are supported: | |||||||
| @item Electronic Arts TQI video  @tab     @tab  X | @item Electronic Arts TQI video  @tab     @tab  X | ||||||
| @item Escape 124             @tab     @tab  X | @item Escape 124             @tab     @tab  X | ||||||
| @item Escape 130             @tab     @tab  X | @item Escape 130             @tab     @tab  X | ||||||
|  | @item EVC / MPEG-5 Part 1    @tab  E  @tab | ||||||
|  |     @tab encoding supported through external library libxeve | ||||||
| @item FFmpeg video codec #1  @tab  X  @tab  X | @item FFmpeg video codec #1  @tab  X  @tab  X | ||||||
|     @tab lossless codec (fourcc: FFV1) |     @tab lossless codec (fourcc: FFV1) | ||||||
| @item Flash Screen Video v1  @tab  X  @tab  X | @item Flash Screen Video v1  @tab  X  @tab  X | ||||||
|  | |||||||
| @ -1149,6 +1149,7 @@ OBJS-$(CONFIG_LIBX264_ENCODER)            += libx264.o | |||||||
| OBJS-$(CONFIG_LIBX265_ENCODER)            += libx265.o | OBJS-$(CONFIG_LIBX265_ENCODER)            += libx265.o | ||||||
| OBJS-$(CONFIG_LIBXAVS_ENCODER)            += libxavs.o | OBJS-$(CONFIG_LIBXAVS_ENCODER)            += libxavs.o | ||||||
| OBJS-$(CONFIG_LIBXAVS2_ENCODER)           += libxavs2.o | OBJS-$(CONFIG_LIBXAVS2_ENCODER)           += libxavs2.o | ||||||
|  | OBJS-$(CONFIG_LIBXEVE_ENCODER)            += libxeve.o | ||||||
| OBJS-$(CONFIG_LIBXVID_ENCODER)            += libxvid.o | OBJS-$(CONFIG_LIBXVID_ENCODER)            += libxvid.o | ||||||
| OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER)   += libzvbi-teletextdec.o ass.o | OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER)   += libzvbi-teletextdec.o ass.o | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -821,6 +821,7 @@ extern LIBX264_CONST FFCodec ff_libx264_encoder; | |||||||
| #endif | #endif | ||||||
| extern const FFCodec ff_libx264rgb_encoder; | extern const FFCodec ff_libx264rgb_encoder; | ||||||
| extern FFCodec ff_libx265_encoder; | extern FFCodec ff_libx265_encoder; | ||||||
|  | extern const FFCodec ff_libxeve_encoder; | ||||||
| extern const FFCodec ff_libxavs_encoder; | extern const FFCodec ff_libxavs_encoder; | ||||||
| extern const FFCodec ff_libxavs2_encoder; | extern const FFCodec ff_libxavs2_encoder; | ||||||
| extern const FFCodec ff_libxvid_encoder; | extern const FFCodec ff_libxvid_encoder; | ||||||
|  | |||||||
							
								
								
									
										616
									
								
								libavcodec/libxeve.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										616
									
								
								libavcodec/libxeve.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,616 @@ | |||||||
|  | /*
 | ||||||
|  |  * libxeve encoder | ||||||
|  |  * EVC (MPEG-5 Essential Video Coding) encoding using XEVE MPEG-5 EVC encoder library | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2021 Dawid Kozinski <d.kozinski@samsung.com> | ||||||
|  |  * | ||||||
|  |  * 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 <float.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | 
 | ||||||
|  | #include <xeve.h> | ||||||
|  | 
 | ||||||
|  | #include "libavutil/internal.h" | ||||||
|  | #include "libavutil/common.h" | ||||||
|  | #include "libavutil/opt.h" | ||||||
|  | #include "libavutil/pixdesc.h" | ||||||
|  | #include "libavutil/pixfmt.h" | ||||||
|  | #include "libavutil/time.h" | ||||||
|  | #include "libavutil/cpu.h" | ||||||
|  | #include "libavutil/avstring.h" | ||||||
|  | 
 | ||||||
|  | #include "avcodec.h" | ||||||
|  | #include "internal.h" | ||||||
|  | #include "packet_internal.h" | ||||||
|  | #include "codec_internal.h" | ||||||
|  | #include "profiles.h" | ||||||
|  | #include "encode.h" | ||||||
|  | 
 | ||||||
|  | #define MAX_BS_BUF (16*1024*1024) | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Error codes | ||||||
|  |  */ | ||||||
|  | #define XEVE_PARAM_BAD_NAME -100 | ||||||
|  | #define XEVE_PARAM_BAD_VALUE -200 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Encoder states | ||||||
|  |  * | ||||||
|  |  * STATE_ENCODING - the encoder receives and processes input frames | ||||||
|  |  * STATE_BUMPING  - there are no more input frames, however the encoder still processes previously received data | ||||||
|  |  */ | ||||||
|  | typedef enum State { | ||||||
|  |     STATE_ENCODING, | ||||||
|  |     STATE_BUMPING, | ||||||
|  | } State; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * The structure stores all the states associated with the instance of Xeve MPEG-5 EVC encoder | ||||||
|  |  */ | ||||||
|  | typedef struct XeveContext { | ||||||
|  |     const AVClass *class; | ||||||
|  | 
 | ||||||
|  |     XEVE id;            // XEVE instance identifier
 | ||||||
|  |     XEVE_CDSC cdsc;     // coding parameters i.e profile, width & height of input frame, num of therads, frame rate ...
 | ||||||
|  |     XEVE_BITB bitb;     // bitstream buffer (output)
 | ||||||
|  |     XEVE_STAT stat;     // encoding status (output)
 | ||||||
|  |     XEVE_IMGB imgb;     // image buffer (input)
 | ||||||
|  | 
 | ||||||
|  |     State state;        // encoder state (skipping, encoding, bumping)
 | ||||||
|  | 
 | ||||||
|  |     int profile_id;     // encoder profile (main, baseline)
 | ||||||
|  |     int preset_id;      // preset of xeve ( fast, medium, slow, placebo)
 | ||||||
|  |     int tune_id;        // tune of xeve (psnr, zerolatency)
 | ||||||
|  | 
 | ||||||
|  |     // variables for rate control modes
 | ||||||
|  |     int rc_mode;        // Rate control mode [ 0(CQP) / 1(ABR) / 2(CRF) ]
 | ||||||
|  |     int qp;             // quantization parameter (QP) [0,51]
 | ||||||
|  |     int crf;            // constant rate factor (CRF) [10,49]
 | ||||||
|  | 
 | ||||||
|  |     int hash;           // embed picture signature (HASH) for conformance checking in decoding
 | ||||||
|  |     int sei_info;       // embed Supplemental enhancement information while encoding
 | ||||||
|  | 
 | ||||||
|  |     int color_format;   // input data color format: currently only XEVE_CF_YCBCR420 is supported
 | ||||||
|  | 
 | ||||||
|  |     AVDictionary *xeve_params; | ||||||
|  | } XeveContext; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Convert FFmpeg pixel format (AVPixelFormat) to XEVE pre-defined color format | ||||||
|  |  * | ||||||
|  |  * @param[in]  av_pix_fmt pixel format (@see https://ffmpeg.org/doxygen/trunk/pixfmt_8h.html#a9a8e335cf3be472042bc9f0cf80cd4c5)
 | ||||||
|  |  * @param[out] xeve_col_fmt XEVE pre-defined color format (@see xeve.h) | ||||||
|  |  * | ||||||
|  |  * @return 0 on success, negative value on failure | ||||||
|  |  */ | ||||||
|  | static int libxeve_color_fmt(enum AVPixelFormat av_pix_fmt, int *xeve_col_fmt) | ||||||
|  | { | ||||||
|  |     switch (av_pix_fmt) { | ||||||
|  |     case AV_PIX_FMT_YUV420P: | ||||||
|  |         *xeve_col_fmt = XEVE_CF_YCBCR420; | ||||||
|  |         break; | ||||||
|  |     case AV_PIX_FMT_YUV420P10: | ||||||
|  |         *xeve_col_fmt = XEVE_CF_YCBCR420; | ||||||
|  |         break; | ||||||
|  |     default: | ||||||
|  |         *xeve_col_fmt = XEVE_CF_UNKNOWN; | ||||||
|  |         return AVERROR_INVALIDDATA; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Convert FFmpeg pixel format (AVPixelFormat) into XEVE pre-defined color space | ||||||
|  |  * | ||||||
|  |  * @param[in] px_fmt pixel format (@see https://ffmpeg.org/doxygen/trunk/pixfmt_8h.html#a9a8e335cf3be472042bc9f0cf80cd4c5)
 | ||||||
|  |  * | ||||||
|  |  * @return XEVE pre-defined color space (@see xeve.h) on success, XEVE_CF_UNKNOWN on failure | ||||||
|  |  */ | ||||||
|  | static int libxeve_color_space(enum AVPixelFormat av_pix_fmt) | ||||||
|  | { | ||||||
|  |     /* color space of input image */ | ||||||
|  |     int cs = XEVE_CF_UNKNOWN; | ||||||
|  | 
 | ||||||
|  |     switch (av_pix_fmt) { | ||||||
|  |     case AV_PIX_FMT_YUV420P: | ||||||
|  |         cs = XEVE_CS_YCBCR420; | ||||||
|  |         break; | ||||||
|  |     case AV_PIX_FMT_YUV420P10: | ||||||
|  | #if AV_HAVE_BIGENDIAN | ||||||
|  |         cs = XEVE_CS_SET(XEVE_CF_YCBCR420, 10, 1); | ||||||
|  | #else | ||||||
|  |         cs = XEVE_CS_YCBCR420_10LE; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |         break; | ||||||
|  |     default: | ||||||
|  |         cs = XEVE_CF_UNKNOWN; | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return cs; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * The function returns a pointer to the object of the XEVE_CDSC type. | ||||||
|  |  * XEVE_CDSC contains all encoder parameters that should be initialized before the encoder is used. | ||||||
|  |  * | ||||||
|  |  * The field values of the XEVE_CDSC structure are populated based on: | ||||||
|  |  * - the corresponding field values of the AvCodecConetxt structure, | ||||||
|  |  * - the xeve encoder specific option values, | ||||||
|  |  *   (the full list of options available for xeve encoder is displayed after executing the command ./ffmpeg --help encoder = libxeve) | ||||||
|  |  * | ||||||
|  |  * The order of processing input data and populating the XEVE_CDSC structure | ||||||
|  |  * 1) first, the fields of the AVCodecContext structure corresponding to the provided input options are processed, | ||||||
|  |  *    (i.e -pix_fmt yuv420p -s:v 1920x1080 -r 30 -profile:v 0) | ||||||
|  |  * 2) then xeve-specific options added as AVOption to the xeve 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 Xeve MPEG-5 EVC 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, XEVE_CDSC *cdsc) | ||||||
|  | { | ||||||
|  |     XeveContext *xectx = NULL; | ||||||
|  |     int ret; | ||||||
|  | 
 | ||||||
|  |     xectx = avctx->priv_data; | ||||||
|  | 
 | ||||||
|  |     /* initialize xeve_param struct with default values */ | ||||||
|  |     ret = xeve_param_default(&cdsc->param); | ||||||
|  |     if (XEVE_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.w = avctx->width; | ||||||
|  | 
 | ||||||
|  |     if (avctx->height > 0) | ||||||
|  |         cdsc->param.h = avctx->height; | ||||||
|  | 
 | ||||||
|  |     if (avctx->framerate.num > 0) { | ||||||
|  |         // fps can be float number, but xeve API doesn't support it
 | ||||||
|  |         cdsc->param.fps = lrintf(av_q2d(avctx->framerate)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // GOP size (key-frame interval, I-picture period)
 | ||||||
|  |     cdsc->param.keyint = avctx->gop_size; // 0: only one I-frame at the first time; 1: every frame is coded in I-frame
 | ||||||
|  | 
 | ||||||
|  |     if (avctx->max_b_frames == 0 || avctx->max_b_frames == 1 || avctx->max_b_frames == 3 || | ||||||
|  |         avctx->max_b_frames == 7 || avctx->max_b_frames == 15)   // number of b-frames
 | ||||||
|  |         cdsc->param.bframes = avctx->max_b_frames; | ||||||
|  |     else { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Incorrect value for maximum number of B frames: (%d) \n" | ||||||
|  |                "Acceptable values for bf option (maximum number of B frames) are 0,1,3,7 or 15\n", avctx->max_b_frames); | ||||||
|  |         return AVERROR_INVALIDDATA; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     cdsc->param.level_idc = avctx->level; | ||||||
|  | 
 | ||||||
|  |     if (avctx->rc_buffer_size)   // VBV buf size
 | ||||||
|  |         cdsc->param.vbv_bufsize = (int)(avctx->rc_buffer_size / 1000); | ||||||
|  | 
 | ||||||
|  |     cdsc->param.rc_type = xectx->rc_mode; | ||||||
|  | 
 | ||||||
|  |     if (xectx->rc_mode == XEVE_RC_CQP) | ||||||
|  |         cdsc->param.qp = xectx->qp; | ||||||
|  |     else if (xectx->rc_mode == XEVE_RC_ABR) { | ||||||
|  |         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_INVALIDDATA; | ||||||
|  |         } | ||||||
|  |         cdsc->param.bitrate = (int)(avctx->bit_rate / 1000); | ||||||
|  |     } else if (xectx->rc_mode == XEVE_RC_CRF) | ||||||
|  |         cdsc->param.crf = xectx->crf; | ||||||
|  |     else { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Not supported rate control type: %d\n", xectx->rc_mode); | ||||||
|  |         return AVERROR_INVALIDDATA; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (avctx->thread_count <= 0) { | ||||||
|  |         int cpu_count = av_cpu_count(); | ||||||
|  |         cdsc->param.threads = (cpu_count < XEVE_MAX_THREADS) ? cpu_count : XEVE_MAX_THREADS; | ||||||
|  |     } else if (avctx->thread_count > XEVE_MAX_THREADS) | ||||||
|  |         cdsc->param.threads = XEVE_MAX_THREADS; | ||||||
|  |     else | ||||||
|  |         cdsc->param.threads = avctx->thread_count; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     libxeve_color_fmt(avctx->pix_fmt, &xectx->color_format); | ||||||
|  | 
 | ||||||
|  |     cdsc->param.cs = XEVE_CS_SET(xectx->color_format, cdsc->param.codec_bit_depth, AV_HAVE_BIGENDIAN); | ||||||
|  | 
 | ||||||
|  |     cdsc->max_bs_buf_size = MAX_BS_BUF; | ||||||
|  | 
 | ||||||
|  |     ret = xeve_param_ppt(&cdsc->param, xectx->profile_id, xectx->preset_id, xectx->tune_id); | ||||||
|  |     if (XEVE_FAILED(ret)) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Cannot set profile(%d), preset(%d), tune(%d)\n", xectx->profile_id, xectx->preset_id, xectx->tune_id); | ||||||
|  |         return AVERROR_EXTERNAL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Set XEVE_CFG_SET_USE_PIC_SIGNATURE for encoder | ||||||
|  |  * | ||||||
|  |  * @param[in] logger context | ||||||
|  |  * @param[in] id XEVE encodec instance identifier | ||||||
|  |  * @param[in] ctx the structure stores all the states associated with the instance of Xeve MPEG-5 EVC encoder | ||||||
|  |  * | ||||||
|  |  * @return 0 on success, negative error code on failure | ||||||
|  |  */ | ||||||
|  | static int set_extra_config(AVCodecContext *avctx, XEVE id, XeveContext *ctx) | ||||||
|  | { | ||||||
|  |     int ret, size; | ||||||
|  |     size = 4; | ||||||
|  | 
 | ||||||
|  |     // embed SEI messages identifying encoder parameters and command line arguments
 | ||||||
|  |     // - 0: off\n"
 | ||||||
|  |     // - 1: emit sei info"
 | ||||||
|  |     //
 | ||||||
|  |     // SEI - Supplemental enhancement information contains information
 | ||||||
|  |     // that is not necessary to decode the samples of coded pictures from VCL NAL units.
 | ||||||
|  |     // Some SEI message information is required to check bitstream conformance
 | ||||||
|  |     // and for output timing decoder conformance.
 | ||||||
|  |     // @see ISO_IEC_23094-1_2020 7.4.3.5
 | ||||||
|  |     // @see ISO_IEC_23094-1_2020 Annex D
 | ||||||
|  |     ret = xeve_config(id, XEVE_CFG_SET_SEI_CMD, &ctx->sei_info, &size); // sei_cmd_info
 | ||||||
|  |     if (XEVE_FAILED(ret)) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Failed to set config for sei command info messages\n"); | ||||||
|  |         return AVERROR_EXTERNAL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = xeve_config(id, XEVE_CFG_SET_USE_PIC_SIGNATURE, &ctx->hash, &size); | ||||||
|  |     if (XEVE_FAILED(ret)) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Failed to set config for picture signature\n"); | ||||||
|  |         return AVERROR_EXTERNAL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Switch encoder to bumping mode | ||||||
|  |  * | ||||||
|  |  * @param id XEVE encodec instance identifier | ||||||
|  |  * @return 0 on success, negative error code on failure | ||||||
|  |  */ | ||||||
|  | static int setup_bumping(XEVE id) | ||||||
|  | { | ||||||
|  |     int val = 1; | ||||||
|  |     int size = sizeof(int); | ||||||
|  |     if (XEVE_FAILED(xeve_config(id, XEVE_CFG_SET_FORCE_OUT, (void *)(&val), &size))) | ||||||
|  |         return AVERROR_EXTERNAL; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Initialize eXtra-fast Essential Video Encoder 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 libxeve_init(AVCodecContext *avctx) | ||||||
|  | { | ||||||
|  |     XeveContext *xectx = avctx->priv_data; | ||||||
|  |     unsigned char *bs_buf = NULL; | ||||||
|  |     int i; | ||||||
|  |     int shift_h = 0; | ||||||
|  |     int shift_v = 0; | ||||||
|  |     int width_chroma = 0; | ||||||
|  |     int height_chroma = 0; | ||||||
|  |     XEVE_IMGB *imgb = NULL; | ||||||
|  |     int ret = 0; | ||||||
|  | 
 | ||||||
|  |     XEVE_CDSC *cdsc = &(xectx->cdsc); | ||||||
|  | 
 | ||||||
|  |     /* allocate bitstream buffer */ | ||||||
|  |     bs_buf = av_malloc(MAX_BS_BUF); | ||||||
|  |     if (bs_buf == NULL) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Cannot allocate bitstream buffer\n"); | ||||||
|  |         return AVERROR(ENOMEM); | ||||||
|  |     } | ||||||
|  |     xectx->bitb.addr = bs_buf; | ||||||
|  |     xectx->bitb.bsize = MAX_BS_BUF; | ||||||
|  | 
 | ||||||
|  |     /* read configurations and set values for created descriptor (XEVE_CDSC) */ | ||||||
|  |     if ((ret = get_conf(avctx, cdsc)) != 0) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Cannot get configuration\n"); | ||||||
|  |         return AVERROR(EINVAL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((ret = xeve_param_check(&cdsc->param)) != 0) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Invalid configuration\n"); | ||||||
|  |         return AVERROR(EINVAL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     { | ||||||
|  |         AVDictionaryEntry *en = NULL; | ||||||
|  |         while (en = av_dict_get(xectx->xeve_params, "", en, AV_DICT_IGNORE_SUFFIX)) { | ||||||
|  |             if ((ret = xeve_param_parse(&cdsc->param, en->key, en->value)) < 0) { | ||||||
|  |                 av_log(avctx, AV_LOG_WARNING, | ||||||
|  |                        "Error parsing option '%s = %s'.\n", | ||||||
|  |                        en->key, en->value); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* create encoder */ | ||||||
|  |     xectx->id = xeve_create(cdsc, NULL); | ||||||
|  |     if (xectx->id == NULL) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Cannot create XEVE encoder\n"); | ||||||
|  |         return AVERROR_EXTERNAL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((ret = set_extra_config(avctx, xectx->id, xectx)) != 0) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Cannot set extra configuration\n"); | ||||||
|  |         return AVERROR(EINVAL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v)) != 0) { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Failed to get  chroma shift\n"); | ||||||
|  |         return AVERROR(EINVAL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Chroma subsampling
 | ||||||
|  |     //
 | ||||||
|  |     // YUV format explanation
 | ||||||
|  |     // shift_h == 1 && shift_v == 1 : YUV420
 | ||||||
|  |     // shift_h == 1 && shift_v == 0 : YUV422
 | ||||||
|  |     // shift_h == 0 && shift_v == 0 : YUV444
 | ||||||
|  |     //
 | ||||||
|  |     width_chroma = AV_CEIL_RSHIFT(avctx->width, shift_h); | ||||||
|  |     height_chroma = AV_CEIL_RSHIFT(avctx->height, shift_v); | ||||||
|  | 
 | ||||||
|  |     /* set default values for input image buffer */ | ||||||
|  |     imgb = &xectx->imgb; | ||||||
|  |     imgb->cs = libxeve_color_space(avctx->pix_fmt); | ||||||
|  |     imgb->np = 3; /* only for yuv420p, yuv420ple */ | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < imgb->np; i++) | ||||||
|  |         imgb->x[i] = imgb->y[i] = 0; | ||||||
|  | 
 | ||||||
|  |     imgb->w[0] = imgb->aw[0] = avctx->width; // width luma
 | ||||||
|  |     imgb->w[1] = imgb->w[2] = imgb->aw[1] = imgb->aw[2] = width_chroma; | ||||||
|  |     imgb->h[0] = imgb->ah[0] = avctx->height; // height luma
 | ||||||
|  |     imgb->h[1] = imgb->h[2] = imgb->ah[1] = imgb->ah[2] = height_chroma; | ||||||
|  | 
 | ||||||
|  |     xectx->state = STATE_ENCODING; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |   * Encode raw data frame into EVC 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 libxeve_encode(AVCodecContext *avctx, AVPacket *avpkt, | ||||||
|  |                           const AVFrame *frame, int *got_packet) | ||||||
|  | { | ||||||
|  |     XeveContext *xectx =  avctx->priv_data; | ||||||
|  |     int  ret = -1; | ||||||
|  | 
 | ||||||
|  |     // No more input frames are available but encoder still can have some data in its internal buffer to process
 | ||||||
|  |     // and some frames to dump.
 | ||||||
|  |     if (xectx->state == STATE_ENCODING && frame == NULL) { | ||||||
|  |         if (setup_bumping(xectx->id) == 0) | ||||||
|  |             xectx->state = STATE_BUMPING;  // Entering bumping process
 | ||||||
|  |         else { | ||||||
|  |             av_log(avctx, AV_LOG_ERROR, "Failed to setup bumping\n"); | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (xectx->state == STATE_ENCODING) { | ||||||
|  |         int i; | ||||||
|  |         XEVE_IMGB *imgb = NULL; | ||||||
|  | 
 | ||||||
|  |         imgb = &xectx->imgb; | ||||||
|  | 
 | ||||||
|  |         for (i = 0; i < imgb->np; i++) { | ||||||
|  |             imgb->a[i] = frame->data[i]; | ||||||
|  |             imgb->s[i] = frame->linesize[i]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         imgb->ts[XEVE_TS_PTS] = frame->pts; | ||||||
|  | 
 | ||||||
|  |         /* push image to encoder */ | ||||||
|  |         ret = xeve_push(xectx->id, imgb); | ||||||
|  |         if (XEVE_FAILED(ret)) { | ||||||
|  |             av_log(avctx, AV_LOG_ERROR, "xeve_push() failed\n"); | ||||||
|  |             return AVERROR_EXTERNAL; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     if (xectx->state == STATE_ENCODING || xectx->state == STATE_BUMPING) { | ||||||
|  |         /* encoding */ | ||||||
|  |         ret = xeve_encode(xectx->id, &(xectx->bitb), &(xectx->stat)); | ||||||
|  |         if (XEVE_FAILED(ret)) { | ||||||
|  |             av_log(avctx, AV_LOG_ERROR, "xeve_encode() failed\n"); | ||||||
|  |             return AVERROR_EXTERNAL; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /* store bitstream */ | ||||||
|  |         if (ret == XEVE_OK_OUT_NOT_AVAILABLE) { // Return OK but picture is not available yet
 | ||||||
|  |             *got_packet = 0; | ||||||
|  |             return 0; | ||||||
|  |         } else if (ret == XEVE_OK) { | ||||||
|  |             int av_pic_type; | ||||||
|  | 
 | ||||||
|  |             if (xectx->stat.write > 0) { | ||||||
|  | 
 | ||||||
|  |                 ret = ff_get_encode_buffer(avctx, avpkt, xectx->stat.write, 0); | ||||||
|  |                 if (ret < 0) | ||||||
|  |                     return ret; | ||||||
|  | 
 | ||||||
|  |                 memcpy(avpkt->data, xectx->bitb.addr, xectx->stat.write); | ||||||
|  | 
 | ||||||
|  |                 avpkt->time_base.num = 1; | ||||||
|  |                 avpkt->time_base.den = xectx->cdsc.param.fps; | ||||||
|  | 
 | ||||||
|  |                 avpkt->pts = xectx->bitb.ts[XEVE_TS_PTS]; | ||||||
|  |                 avpkt->dts = xectx->bitb.ts[XEVE_TS_DTS]; | ||||||
|  | 
 | ||||||
|  |                 switch(xectx->stat.stype) { | ||||||
|  |                 case XEVE_ST_I: | ||||||
|  |                     av_pic_type = AV_PICTURE_TYPE_I; | ||||||
|  |                     avpkt->flags |= AV_PKT_FLAG_KEY; | ||||||
|  |                     break; | ||||||
|  |                 case XEVE_ST_P: | ||||||
|  |                     av_pic_type = AV_PICTURE_TYPE_P; | ||||||
|  |                     break; | ||||||
|  |                 case XEVE_ST_B: | ||||||
|  |                     av_pic_type = AV_PICTURE_TYPE_B; | ||||||
|  |                     break; | ||||||
|  |                 case XEVE_ST_UNKNOWN: | ||||||
|  |                     av_log(avctx, AV_LOG_ERROR, "Unknown slice type\n"); | ||||||
|  |                     return AVERROR_INVALIDDATA; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 ff_side_data_set_encoder_stats(avpkt, xectx->stat.qp * FF_QP2LAMBDA, NULL, 0, av_pic_type); | ||||||
|  | 
 | ||||||
|  |                 *got_packet = 1; | ||||||
|  |             } | ||||||
|  |         } else if (ret == XEVE_OK_NO_MORE_FRM) { | ||||||
|  |             // Return OK but no more frames
 | ||||||
|  |             return 0; | ||||||
|  |         } else { | ||||||
|  |             av_log(avctx, AV_LOG_ERROR, "Invalid return value: %d\n", ret); | ||||||
|  |             return AVERROR_EXTERNAL; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         av_log(avctx, AV_LOG_ERROR, "Udefined encoder state\n"); | ||||||
|  |         return AVERROR_INVALIDDATA; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     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 libxeve_close(AVCodecContext *avctx) | ||||||
|  | { | ||||||
|  |     XeveContext *xectx = avctx->priv_data; | ||||||
|  | 
 | ||||||
|  |     if (xectx->id) { | ||||||
|  |         xeve_delete(xectx->id); | ||||||
|  |         xectx->id = NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     av_free(xectx->bitb.addr); /* release bitstream buffer */ | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define OFFSET(x) offsetof(XeveContext, x) | ||||||
|  | #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | ||||||
|  | 
 | ||||||
|  | static const enum AVPixelFormat supported_pixel_formats[] = { | ||||||
|  |     AV_PIX_FMT_YUV420P, | ||||||
|  |     AV_PIX_FMT_YUV420P10, | ||||||
|  |     AV_PIX_FMT_NONE | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Consider using following options (./ffmpeg --help encoder=libxeve)
 | ||||||
|  | //
 | ||||||
|  | static const AVOption libxeve_options[] = { | ||||||
|  |     { "preset", "Encoding preset for setting encoding speed", OFFSET(preset_id), AV_OPT_TYPE_INT, { .i64 = XEVE_PRESET_MEDIUM }, XEVE_PRESET_DEFAULT,  XEVE_PRESET_PLACEBO, VE, "preset" }, | ||||||
|  |     { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_DEFAULT }, INT_MIN, INT_MAX, VE, "preset" }, | ||||||
|  |     { "fast",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_FAST },    INT_MIN, INT_MAX, VE, "preset" }, | ||||||
|  |     { "medium",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_MEDIUM },  INT_MIN, INT_MAX, VE, "preset" }, | ||||||
|  |     { "slow",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_SLOW },    INT_MIN, INT_MAX, VE, "preset" }, | ||||||
|  |     { "placebo", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PRESET_PLACEBO }, INT_MIN, INT_MAX, VE, "preset" }, | ||||||
|  |     { "tune", "Tuning parameter for special purpose operation", OFFSET(tune_id), AV_OPT_TYPE_INT, { .i64 = XEVE_TUNE_NONE }, XEVE_TUNE_NONE, XEVE_TUNE_PSNR, VE, "tune"}, | ||||||
|  |     { "none",        NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_TUNE_NONE },        INT_MIN, INT_MAX, VE, "tune" }, | ||||||
|  |     { "zerolatency", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_TUNE_ZEROLATENCY }, INT_MIN, INT_MAX, VE, "tune" }, | ||||||
|  |     { "psnr",        NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_TUNE_PSNR },        INT_MIN, INT_MAX, VE, "tune" }, | ||||||
|  |     { "profile", "Encoding profile", OFFSET(profile_id), AV_OPT_TYPE_INT, { .i64 = XEVE_PROFILE_BASELINE }, XEVE_PROFILE_BASELINE,  XEVE_PROFILE_MAIN, VE, "profile" }, | ||||||
|  |     { "baseline", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PROFILE_BASELINE }, INT_MIN, INT_MAX, VE, "profile" }, | ||||||
|  |     { "main",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_PROFILE_MAIN },     INT_MIN, INT_MAX, VE, "profile" }, | ||||||
|  |     { "rc_mode", "Rate control mode", OFFSET(rc_mode), AV_OPT_TYPE_INT, { .i64 = XEVE_RC_CQP }, XEVE_RC_CQP,  XEVE_RC_CRF, VE, "rc_mode" }, | ||||||
|  |     { "CQP", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_RC_CQP }, INT_MIN, INT_MAX, VE, "rc_mode" }, | ||||||
|  |     { "ABR", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_RC_ABR }, INT_MIN, INT_MAX, VE, "rc_mode" }, | ||||||
|  |     { "CRF", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = XEVE_RC_CRF }, INT_MIN, INT_MAX, VE, "rc_mode" }, | ||||||
|  |     { "qp", "Quantization parameter value for CQP rate control mode", OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 51, VE }, | ||||||
|  |     { "crf", "Constant rate factor value for CRF rate control mode", OFFSET(crf), AV_OPT_TYPE_INT, { .i64 = 32 }, 10, 49, VE }, | ||||||
|  |     { "hash", "Embed picture signature (HASH) for conformance checking in decoding", OFFSET(hash), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, | ||||||
|  |     { "sei_info", "Embed SEI messages identifying encoder parameters and command line arguments", OFFSET(sei_info), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, | ||||||
|  |     { "xeve-params",  "Override the xeve configuration using a :-separated list of key=value parameters", OFFSET(xeve_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, | ||||||
|  |     { NULL } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const AVClass libxeve_class = { | ||||||
|  |     .class_name = "libxeve", | ||||||
|  |     .item_name  = av_default_item_name, | ||||||
|  |     .option     = libxeve_options, | ||||||
|  |     .version    = LIBAVUTIL_VERSION_INT, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  libavcodec generic global options, which can be set on all the encoders and decoders | ||||||
|  |  *  @see https://www.ffmpeg.org/ffmpeg-codecs.html#Codec-Options
 | ||||||
|  |  */ | ||||||
|  | static const FFCodecDefault libxeve_defaults[] = { | ||||||
|  |     { "b", "0" },       // bitrate in terms of kilo-bits per second
 | ||||||
|  |     { "g", "0" },       // gop_size (key-frame interval 0: only one I-frame at the first time; 1: every frame is coded in I-frame)
 | ||||||
|  |     { "bf", "15"},      // maximum number of B frames (0: no B-frames, 1,3,7,15)
 | ||||||
|  |     { "threads", "0"},  // number of threads to be used (0: automatically select the number of threads to set)
 | ||||||
|  |     { NULL }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const FFCodec ff_libxeve_encoder = { | ||||||
|  |     .p.name             = "libxeve", | ||||||
|  |     .p.long_name        = NULL_IF_CONFIG_SMALL("libxeve MPEG-5 EVC"), | ||||||
|  |     .p.type             = AVMEDIA_TYPE_VIDEO, | ||||||
|  |     .p.id               = AV_CODEC_ID_EVC, | ||||||
|  |     .init               = libxeve_init, | ||||||
|  |     FF_CODEC_ENCODE_CB(libxeve_encode), | ||||||
|  |     .close              = libxeve_close, | ||||||
|  |     .priv_data_size     = sizeof(XeveContext), | ||||||
|  |     .p.priv_class       = &libxeve_class, | ||||||
|  |     .defaults           = libxeve_defaults, | ||||||
|  |     .p.capabilities     = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_DR1, | ||||||
|  |     .p.profiles         = NULL_IF_CONFIG_SMALL(ff_evc_profiles), | ||||||
|  |     .p.wrapper_name     = "libxeve", | ||||||
|  |     .p.pix_fmts         = supported_pixel_formats, | ||||||
|  |     .caps_internal      = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_NOT_INIT_THREADSAFE, | ||||||
|  | }; | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user