Last active
July 11, 2019 23:56
-
-
Save wiiaboo/9a570057d6bc605a3c72429cfe0cf45b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 9585df20e053dfecb341005cab4808332620236b Mon Sep 17 00:00:00 2001 | |
From: Jing SUN <[email protected]> | |
Date: Fri, 31 May 2019 13:37:54 +0800 | |
Subject: [PATCH 1/2] lavc/svt_hevc: add libsvt hevc encoder wrapper | |
Signed-off-by: Zhengxu Huang <[email protected]> | |
Signed-off-by: Hassene Tmar <[email protected]> | |
Signed-off-by: Jun Zhao <[email protected]> | |
Signed-off-by: Jing Sun <[email protected]> | |
--- | |
configure | 4 + | |
libavcodec/Makefile | 1 + | |
libavcodec/allcodecs.c | 1 + | |
libavcodec/libsvt_hevc.c | 501 +++++++++++++++++++++++++++++++++++++++ | |
4 files changed, 507 insertions(+) | |
create mode 100644 libavcodec/libsvt_hevc.c | |
diff --git a/configure b/configure | |
index 5a4f507246..3a6cab733c 100755 | |
--- a/configure | |
+++ b/configure | |
@@ -264,6 +264,7 @@ External library support: | |
--enable-libspeex enable Speex de/encoding via libspeex [no] | |
--enable-libsrt enable Haivision SRT protocol via libsrt [no] | |
--enable-libssh enable SFTP protocol via libssh [no] | |
+ --enable-libsvthevc enable HEVC encoding via svt [no] | |
--enable-libtensorflow enable TensorFlow as a DNN module backend | |
for DNN based filters like sr [no] | |
--enable-libtesseract enable Tesseract, needed for ocr filter [no] | |
@@ -1788,6 +1789,7 @@ EXTERNAL_LIBRARY_LIST=" | |
libspeex | |
libsrt | |
libssh | |
+ libsvthevc | |
libtensorflow | |
libtesseract | |
libtheora | |
@@ -3183,6 +3185,7 @@ libshine_encoder_select="audio_frame_queue" | |
libspeex_decoder_deps="libspeex" | |
libspeex_encoder_deps="libspeex" | |
libspeex_encoder_select="audio_frame_queue" | |
+libsvt_hevc_encoder_deps="libsvthevc" | |
libtheora_encoder_deps="libtheora" | |
libtwolame_encoder_deps="libtwolame" | |
libvo_amrwbenc_encoder_deps="libvo_amrwbenc" | |
@@ -6230,6 +6233,7 @@ enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr | |
enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp_init | |
enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init | |
enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket | |
+enabled libsvthevc && require_pkg_config libsvthevc SvtHevcEnc EbApi.h EbInitHandle | |
enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow | |
enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate | |
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg | |
diff --git a/libavcodec/Makefile b/libavcodec/Makefile | |
index 3cd73fbcc6..d39f568585 100644 | |
--- a/libavcodec/Makefile | |
+++ b/libavcodec/Makefile | |
@@ -991,6 +991,7 @@ OBJS-$(CONFIG_LIBOPUS_ENCODER) += libopusenc.o libopus.o \ | |
OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o | |
OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o | |
OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o | |
+OBJS-$(CONFIG_LIBSVT_HEVC_ENCODER) += libsvt_hevc.o | |
OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o | |
OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o | |
OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o | |
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c | |
index d2f9a39ce5..d8788a7954 100644 | |
--- a/libavcodec/allcodecs.c | |
+++ b/libavcodec/allcodecs.c | |
@@ -707,6 +707,7 @@ extern AVCodec ff_librsvg_decoder; | |
extern AVCodec ff_libshine_encoder; | |
extern AVCodec ff_libspeex_encoder; | |
extern AVCodec ff_libspeex_decoder; | |
+extern AVCodec ff_libsvt_hevc_encoder; | |
extern AVCodec ff_libtheora_encoder; | |
extern AVCodec ff_libtwolame_encoder; | |
extern AVCodec ff_libvo_amrwbenc_encoder; | |
diff --git a/libavcodec/libsvt_hevc.c b/libavcodec/libsvt_hevc.c | |
new file mode 100644 | |
index 0000000000..d9ac04c19a | |
--- /dev/null | |
+++ b/libavcodec/libsvt_hevc.c | |
@@ -0,0 +1,501 @@ | |
+/* | |
+* Scalable Video Technology for HEVC encoder library plugin | |
+* | |
+* Copyright (c) 2019 Intel Corporation | |
+* | |
+* 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 this program; if not, write to the Free Software | |
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
+*/ | |
+ | |
+#include "EbErrorCodes.h" | |
+#include "EbTime.h" | |
+#include "EbApi.h" | |
+ | |
+#include "libavutil/common.h" | |
+#include "libavutil/frame.h" | |
+#include "libavutil/opt.h" | |
+ | |
+#include "internal.h" | |
+#include "avcodec.h" | |
+ | |
+typedef enum eos_status { | |
+ EOS_NOT_REACHED = 0, | |
+ EOS_SENT, | |
+ EOS_RECEIVED | |
+}EOS_STATUS; | |
+ | |
+typedef struct SvtContext { | |
+ AVClass *class; | |
+ | |
+ EB_H265_ENC_CONFIGURATION enc_params; | |
+ EB_COMPONENTTYPE *svt_handle; | |
+ EB_BUFFERHEADERTYPE in_buf; | |
+ EOS_STATUS eos_flag; | |
+ | |
+ // User options. | |
+ int profile; | |
+ int hierarchical_level; | |
+ int enc_mode; | |
+ int tier; | |
+ int level; | |
+ int rc_mode; | |
+ int scd; | |
+ int tune; | |
+ int base_layer_switch_mode; | |
+ int qp; | |
+ int aud; | |
+ int asm_type; | |
+ int forced_idr; | |
+ int la_depth; | |
+} SvtContext; | |
+ | |
+static int error_mapping(EB_ERRORTYPE svt_ret) | |
+{ | |
+ switch (svt_ret) { | |
+ case EB_ErrorInsufficientResources: | |
+ return AVERROR(ENOMEM); | |
+ | |
+ case EB_ErrorUndefined: | |
+ case EB_ErrorInvalidComponent: | |
+ case EB_ErrorBadParameter: | |
+ return AVERROR(EINVAL); | |
+ | |
+ case EB_ErrorDestroyThreadFailed: | |
+ case EB_ErrorSemaphoreUnresponsive: | |
+ case EB_ErrorDestroySemaphoreFailed: | |
+ case EB_ErrorCreateMutexFailed: | |
+ case EB_ErrorMutexUnresponsive: | |
+ case EB_ErrorDestroyMutexFailed: | |
+ return AVERROR_EXTERNAL; | |
+ | |
+ case EB_NoErrorEmptyQueue: | |
+ return AVERROR(EAGAIN); | |
+ | |
+ case EB_ErrorNone: | |
+ return 0; | |
+ | |
+ default: | |
+ return AVERROR_UNKNOWN; | |
+ } | |
+} | |
+ | |
+static void free_buffer(SvtContext *svt_enc) | |
+{ | |
+ uint8_t *in_data = svt_enc->in_buf.pBuffer; | |
+ | |
+ av_freep(&in_data); | |
+} | |
+ | |
+static EB_ERRORTYPE alloc_buffer(SvtContext *svt_enc) | |
+{ | |
+ EB_BUFFERHEADERTYPE *in_buf = &svt_enc->in_buf; | |
+ EB_H265_ENC_INPUT *in_data = NULL; | |
+ | |
+ memset(in_buf, 0, sizeof(*in_buf)); | |
+ in_buf->nSize = sizeof(*in_buf); | |
+ in_buf->sliceType = EB_INVALID_PICTURE; | |
+ | |
+ in_data = (EB_H265_ENC_INPUT *)av_mallocz(sizeof(*in_data)); | |
+ if (in_data) { | |
+ in_buf->pBuffer = (uint8_t *)in_data; | |
+ return EB_ErrorNone; | |
+ } else { | |
+ return EB_ErrorInsufficientResources; | |
+ } | |
+} | |
+ | |
+static int config_enc_params(EB_H265_ENC_CONFIGURATION *param, | |
+ AVCodecContext *avctx) | |
+{ | |
+ SvtContext *svt_enc = avctx->priv_data; | |
+ | |
+ param->sourceWidth = avctx->width; | |
+ param->sourceHeight = avctx->height; | |
+ | |
+ if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P10) || | |
+ (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) || | |
+ (avctx->pix_fmt == AV_PIX_FMT_YUV444P10)) { | |
+ av_log(avctx, AV_LOG_DEBUG, "Set 10 bits depth input\n"); | |
+ param->encoderBitDepth = 10; | |
+ } else { | |
+ av_log(avctx, AV_LOG_DEBUG, "Set 8 bits depth input\n"); | |
+ param->encoderBitDepth = 8; | |
+ } | |
+ | |
+ if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P) || | |
+ (avctx->pix_fmt == AV_PIX_FMT_YUV420P10)) | |
+ param->encoderColorFormat = EB_YUV420; | |
+ else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P) || | |
+ (avctx->pix_fmt == AV_PIX_FMT_YUV422P10)) | |
+ param->encoderColorFormat = EB_YUV422; | |
+ else | |
+ param->encoderColorFormat = EB_YUV444; | |
+ | |
+ param->profile = svt_enc->profile; | |
+ | |
+ if (FF_PROFILE_HEVC_MAIN_STILL_PICTURE == param->profile) { | |
+ av_log(avctx, AV_LOG_ERROR, "Main Still Picture Profile not supported\n"); | |
+ return EB_ErrorBadParameter; | |
+ } | |
+ | |
+ if ((param->encoderColorFormat >= EB_YUV422) && | |
+ (param->profile != FF_PROFILE_HEVC_REXT)) { | |
+ av_log(avctx, AV_LOG_WARNING, "Rext Profile forced for 422 or 444\n"); | |
+ param->profile = FF_PROFILE_HEVC_REXT; | |
+ } | |
+ | |
+ if ((FF_PROFILE_HEVC_MAIN == param->profile) && | |
+ (param->encoderBitDepth > 8)) { | |
+ av_log(avctx, AV_LOG_WARNING, "Main10 Profile forced for 10 bits\n"); | |
+ param->profile = FF_PROFILE_HEVC_MAIN_10; | |
+ } | |
+ | |
+ param->targetBitRate = avctx->bit_rate; | |
+ | |
+ if (avctx->gop_size > 0) | |
+ param->intraPeriodLength = avctx->gop_size - 1; | |
+ | |
+ if ((avctx->framerate.num > 0) && (avctx->framerate.den > 0)) { | |
+ param->frameRateNumerator = avctx->framerate.num; | |
+ param->frameRateDenominator = | |
+ avctx->framerate.den * avctx->ticks_per_frame; | |
+ } else { | |
+ param->frameRateNumerator = avctx->time_base.den; | |
+ param->frameRateDenominator = | |
+ avctx->time_base.num * avctx->ticks_per_frame; | |
+ } | |
+ | |
+ if (param->rateControlMode) { | |
+ param->maxQpAllowed = avctx->qmax; | |
+ param->minQpAllowed = avctx->qmin; | |
+ } | |
+ | |
+ param->hierarchicalLevels = svt_enc->hierarchical_level; | |
+ param->encMode = svt_enc->enc_mode; | |
+ param->tier = svt_enc->tier; | |
+ param->level = svt_enc->level; | |
+ param->rateControlMode = svt_enc->rc_mode; | |
+ param->sceneChangeDetection = svt_enc->scd; | |
+ param->tune = svt_enc->tune; | |
+ param->baseLayerSwitchMode = svt_enc->base_layer_switch_mode; | |
+ param->qp = svt_enc->qp; | |
+ param->accessUnitDelimiter = svt_enc->aud; | |
+ param->asmType = svt_enc->asm_type; | |
+ | |
+ param->intraRefreshType = svt_enc->forced_idr + 1; | |
+ | |
+ if (svt_enc->la_depth != -1) | |
+ param->lookAheadDistance = svt_enc->la_depth; | |
+ | |
+ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) | |
+ param->codeVpsSpsPps = 0; | |
+ else | |
+ param->codeVpsSpsPps = 1; | |
+ | |
+ param->codeEosNal = 1; | |
+ | |
+ return EB_ErrorNone; | |
+} | |
+ | |
+static void read_in_data(EB_H265_ENC_CONFIGURATION *config, | |
+ const AVFrame *frame, | |
+ EB_BUFFERHEADERTYPE *header_ptr) | |
+{ | |
+ uint8_t is16bit; | |
+ uint64_t frame_size; | |
+ EB_H265_ENC_INPUT *in_data = (EB_H265_ENC_INPUT *)header_ptr->pBuffer; | |
+ | |
+ is16bit = config->encoderBitDepth > 8; | |
+ frame_size = (uint64_t)(config->sourceWidth * config->sourceHeight) << is16bit; | |
+ | |
+ in_data->luma = frame->data[0]; | |
+ in_data->cb = frame->data[1]; | |
+ in_data->cr = frame->data[2]; | |
+ | |
+ in_data->yStride = frame->linesize[0] >> is16bit; | |
+ in_data->cbStride = frame->linesize[1] >> is16bit; | |
+ in_data->crStride = frame->linesize[2] >> is16bit; | |
+ | |
+ if (config->encoderColorFormat == EB_YUV420) | |
+ frame_size *= 3/2u; | |
+ else if (config->encoderColorFormat == EB_YUV422) | |
+ frame_size *= 2u; | |
+ else | |
+ frame_size *= 3u; | |
+ | |
+ header_ptr->nFilledLen += frame_size; | |
+} | |
+ | |
+static av_cold int eb_enc_init(AVCodecContext *avctx) | |
+{ | |
+ SvtContext *svt_enc = avctx->priv_data; | |
+ EB_ERRORTYPE svt_ret; | |
+ | |
+ svt_enc->eos_flag = EOS_NOT_REACHED; | |
+ | |
+ svt_ret = EbInitHandle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params); | |
+ if (svt_ret != EB_ErrorNone) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to init handle\n"); | |
+ return error_mapping(svt_ret); | |
+ } | |
+ | |
+ svt_ret = config_enc_params(&svt_enc->enc_params, avctx); | |
+ if (svt_ret != EB_ErrorNone) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to config parameters\n"); | |
+ goto failed_init_handle; | |
+ } | |
+ | |
+ svt_ret = EbH265EncSetParameter(svt_enc->svt_handle, &svt_enc->enc_params); | |
+ if (svt_ret != EB_ErrorNone) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to set parameters\n"); | |
+ goto failed_init_handle; | |
+ } | |
+ | |
+ svt_ret = EbInitEncoder(svt_enc->svt_handle); | |
+ if (svt_ret != EB_ErrorNone) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to init encoder\n"); | |
+ goto failed_init_handle; | |
+ } | |
+ | |
+ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { | |
+ EB_BUFFERHEADERTYPE *header_ptr = NULL; | |
+ | |
+ svt_ret = EbH265EncStreamHeader(svt_enc->svt_handle, &header_ptr); | |
+ if (svt_ret != EB_ErrorNone) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to build stream header\n"); | |
+ goto failed_init_encoder; | |
+ } | |
+ | |
+ avctx->extradata_size = header_ptr->nFilledLen; | |
+ avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); | |
+ if (!avctx->extradata) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to allocate extradata\n"); | |
+ svt_ret = EB_ErrorInsufficientResources; | |
+ goto failed_init_encoder; | |
+ } | |
+ memcpy(avctx->extradata, header_ptr->pBuffer, avctx->extradata_size); | |
+ memset((void *)(avctx->extradata+avctx->extradata_size), 0, AV_INPUT_BUFFER_PADDING_SIZE); | |
+ } | |
+ | |
+ svt_ret = alloc_buffer(svt_enc); | |
+ if (svt_ret != EB_ErrorNone) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to alloc data buffer\n"); | |
+ goto failed_init_encoder; | |
+ } | |
+ return 0; | |
+ | |
+failed_init_encoder: | |
+ EbDeinitEncoder(svt_enc->svt_handle); | |
+failed_init_handle: | |
+ EbDeinitHandle(svt_enc->svt_handle); | |
+ svt_enc->svt_handle = NULL; | |
+ svt_enc = NULL; | |
+ return error_mapping(svt_ret); | |
+} | |
+ | |
+static int eb_encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |
+ const AVFrame *frame, int *got_packet) | |
+{ | |
+ SvtContext *svt_enc = avctx->priv_data; | |
+ EB_BUFFERHEADERTYPE *header_ptr = &svt_enc->in_buf; | |
+ EB_ERRORTYPE svt_ret; | |
+ int av_ret; | |
+ | |
+ if (EOS_RECEIVED == svt_enc->eos_flag) { | |
+ *got_packet = 0; | |
+ return 0; | |
+ } | |
+ | |
+ if (!frame) { | |
+ if (!svt_enc->eos_flag) { | |
+ svt_enc->eos_flag = EOS_SENT; | |
+ | |
+ header_ptr->nAllocLen = 0; | |
+ header_ptr->nFilledLen = 0; | |
+ header_ptr->nTickCount = 0; | |
+ header_ptr->pBuffer = NULL; | |
+ header_ptr->nFlags = EB_BUFFERFLAG_EOS; | |
+ | |
+ EbH265EncSendPicture(svt_enc->svt_handle, header_ptr); | |
+ | |
+ av_log(avctx, AV_LOG_DEBUG, "Sent EOS\n"); | |
+ } | |
+ } else { | |
+ read_in_data(&svt_enc->enc_params, frame, header_ptr); | |
+ header_ptr->pts = frame->pts; | |
+ | |
+ EbH265EncSendPicture(svt_enc->svt_handle, header_ptr); | |
+ | |
+ av_log(avctx, AV_LOG_DEBUG, "Sent PTS %"PRId64"\n", header_ptr->pts); | |
+ } | |
+ | |
+ header_ptr = NULL; | |
+ svt_ret = EbH265GetPacket(svt_enc->svt_handle, &header_ptr, svt_enc->eos_flag); | |
+ | |
+ if (svt_ret == EB_NoErrorEmptyQueue) { | |
+ *got_packet = 0; | |
+ av_log(avctx, AV_LOG_DEBUG, "Received none\n"); | |
+ return 0; | |
+ } | |
+ | |
+ av_log(avctx, AV_LOG_DEBUG, "Received PTS %"PRId64" packet\n", header_ptr->pts); | |
+ | |
+ av_ret = ff_alloc_packet2(avctx, pkt, header_ptr->nFilledLen, 0); | |
+ if (av_ret) { | |
+ av_log(avctx, AV_LOG_ERROR, "Failed to allocate a packet\n"); | |
+ EbH265ReleaseOutBuffer(&header_ptr); | |
+ return av_ret; | |
+ } | |
+ | |
+ memcpy(pkt->data, header_ptr->pBuffer, header_ptr->nFilledLen); | |
+ pkt->size = header_ptr->nFilledLen; | |
+ pkt->pts = header_ptr->pts; | |
+ pkt->dts = header_ptr->dts; | |
+ | |
+ if ((header_ptr->sliceType == EB_IDR_PICTURE) || | |
+ (header_ptr->sliceType == EB_I_PICTURE)) | |
+ pkt->flags |= AV_PKT_FLAG_KEY; | |
+ if (header_ptr->sliceType == EB_NON_REF_PICTURE) | |
+ pkt->flags |= AV_PKT_FLAG_DISPOSABLE; | |
+ | |
+ EbH265ReleaseOutBuffer(&header_ptr); | |
+ | |
+ *got_packet = 1; | |
+ | |
+ if (EB_BUFFERFLAG_EOS == header_ptr->nFlags) | |
+ svt_enc->eos_flag = EOS_RECEIVED; | |
+ | |
+ return 0; | |
+} | |
+ | |
+static av_cold int eb_enc_close(AVCodecContext *avctx) | |
+{ | |
+ SvtContext *svt_enc = avctx->priv_data; | |
+ | |
+ if (svt_enc) { | |
+ free_buffer(svt_enc); | |
+ | |
+ if (svt_enc->svt_handle) { | |
+ EbDeinitEncoder(svt_enc->svt_handle); | |
+ EbDeinitHandle(svt_enc->svt_handle); | |
+ svt_enc->svt_handle = NULL; | |
+ } | |
+ | |
+ svt_enc = NULL; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
+#define OFFSET(x) offsetof(SvtContext, x) | |
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM | |
+static const AVOption options[] = { | |
+ { "asm_type", "Assembly instruction set type [0: C Only, 1: Auto]", OFFSET(asm_type), | |
+ AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, | |
+ | |
+ { "aud", "Include Access Unit Delimiter", OFFSET(aud), | |
+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, | |
+ | |
+ { "bl_mode", "Random Access Prediction Structure type setting", OFFSET(base_layer_switch_mode), | |
+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, | |
+ | |
+ { "forced-idr", "If forcing keyframes, force them as IDR frames.", OFFSET(forced_idr), | |
+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, | |
+ | |
+ { "hielevel", "Hierarchical prediction levels setting", OFFSET(hierarchical_level), | |
+ AV_OPT_TYPE_INT, { .i64 = 3 }, 0, 3, VE , "hielevel"}, | |
+ { "flat", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "hielevel" }, | |
+ { "1 level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "hielevel" }, | |
+ { "2 level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "hielevel" }, | |
+ { "3 level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" }, | |
+ | |
+ { "la_depth", "Look ahead distance [0, 256]", OFFSET(la_depth), | |
+ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 256, VE }, | |
+ | |
+ { "level", "Set level (level_idc)", OFFSET(level), | |
+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xff, VE, "level" }, | |
+ | |
+ { "preset", "Encoding preset [0, 12]", | |
+ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = 9 }, 0, 12, VE }, | |
+ | |
+ { "profile", "Profile setting, Main Still Picture Profile not supported", OFFSET(profile), | |
+ AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_HEVC_MAIN }, FF_PROFILE_HEVC_MAIN, FF_PROFILE_HEVC_REXT, VE, "profile"}, | |
+ | |
+ { "qp", "QP value for intra frames", OFFSET(qp), | |
+ AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 51, VE }, | |
+ | |
+ { "rc", "Bit rate control mode", OFFSET(rc_mode), | |
+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE , "rc"}, | |
+ { "cqp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" }, | |
+ { "vbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" }, | |
+ | |
+ { "sc_detection", "Scene change detection", OFFSET(scd), | |
+ AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, | |
+ | |
+ { "tier", "Set tier (general_tier_flag)", OFFSET(tier), | |
+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "tier" }, | |
+ { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "tier" }, | |
+ { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "tier" }, | |
+ | |
+ { "tune", "Quality tuning mode", OFFSET(tune), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, VE, "tune" }, | |
+ { "sq", "Visually optimized mode", 0, | |
+ AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "tune" }, | |
+ { "oq", "PSNR / SSIM optimized mode", 0, | |
+ AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "tune" }, | |
+ { "vmaf", "VMAF optimized mode", 0, | |
+ AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "tune" }, | |
+ | |
+ {NULL}, | |
+}; | |
+ | |
+static const AVClass class = { | |
+ .class_name = "libsvt_hevc", | |
+ .item_name = av_default_item_name, | |
+ .option = options, | |
+ .version = LIBAVUTIL_VERSION_INT, | |
+}; | |
+ | |
+static const AVCodecDefault eb_enc_defaults[] = { | |
+ { "b", "7M" }, | |
+ { "flags", "+cgop" }, | |
+ { "qmin", "10" }, | |
+ { "qmax", "48" }, | |
+ { "g", "-2" }, | |
+ { NULL }, | |
+}; | |
+ | |
+AVCodec ff_libsvt_hevc_encoder = { | |
+ .name = "libsvt_hevc", | |
+ .long_name = NULL_IF_CONFIG_SMALL("SVT-HEVC(Scalable Video Technology for HEVC) encoder"), | |
+ .priv_data_size = sizeof(SvtContext), | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_HEVC, | |
+ .init = eb_enc_init, | |
+ .encode2 = eb_encode_frame, | |
+ .close = eb_enc_close, | |
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, | |
+ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, | |
+ AV_PIX_FMT_YUV420P10, | |
+ AV_PIX_FMT_YUV422P, | |
+ AV_PIX_FMT_YUV420P10, | |
+ AV_PIX_FMT_YUV444P, | |
+ AV_PIX_FMT_YUV444P10, | |
+ AV_PIX_FMT_NONE }, | |
+ .priv_class = &class, | |
+ .defaults = eb_enc_defaults, | |
+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | |
+ .wrapper_name = "libsvt_hevc", | |
+}; | |
-- | |
2.22.0 | |
From 87228283897cee47ea4166987cd2242a569ee591 Mon Sep 17 00:00:00 2001 | |
From: Jing SUN <[email protected]> | |
Date: Thu, 30 May 2019 19:35:37 +0800 | |
Subject: [PATCH 2/2] doc: Add libsvt_hevc encoder docs | |
Add docs for libsvt_hevc encoder in encoders.texi and general.texi | |
RiCON: removed general.texi modifications to prevent conflicts | |
Signed-off-by: Jun Zhao <[email protected]> | |
Signed-off-by: Zhengxu Huang <[email protected]> | |
Signed-off-by: Hassene Tmar <[email protected]> | |
Signed-off-by: Jing Sun <[email protected]> | |
--- | |
doc/encoders.texi | 149 ++++++++++++++++++++++++++++++++++++++++++++++ | |
1 file changed, 149 insertions(+) | |
diff --git a/doc/encoders.texi b/doc/encoders.texi | |
index eefd124751..81debda5a8 100644 | |
--- a/doc/encoders.texi | |
+++ b/doc/encoders.texi | |
@@ -1640,6 +1640,155 @@ Set maximum NAL size in bytes. | |
Allow skipping frames to hit the target bitrate if set to 1. | |
@end table | |
+@section libsvt_hevc | |
+ | |
+Scalable Video Technology for HEVC (SVT-HEVC) encoder wrapper. | |
+ | |
+This encoder requires the presence of the headers and | |
+library during configuration. You need to explicitly configure the | |
+build with @code{--enable-libsvthevc}. The library is detected using | |
+@command{pkg-config}. | |
+ | |
+For more information about the library see | |
+@url{https://github.com/intel/SVT-HEVC.git}. | |
+ | |
+@subsection Options | |
+ | |
+The following FFmpeg global options affect the configurations of the | |
+libsvt_hevc encoder: | |
+ | |
+@table @option | |
+@item b (@emph{bitrate}) | |
+Set the bitrate (as a number of bits per second). Default is 7M. | |
+ | |
+@item g / @option{gop_size} | |
+Set the GOP size. Default is -2 (unspecified). | |
+ | |
+@item flags +cgop | |
+Enable closed GOP. | |
+ | |
+@item qmin (@emph{min-q}) | |
+Default is 10 | |
+ | |
+@item qmax (@emph{max-q}) | |
+Default is 48 | |
+ | |
+Set minimum/maximum quantisation values. Valid range is from 0 to 51 | |
+(Only used when bit rate control mode @option{rc} is set to 1(vbr) mode. | |
+It is required that qmax >= qmin). | |
+ | |
+@item profile (@emph{profile}) | |
+Set profile restrictions. Can assume one of the following possible values: | |
+ | |
+@table @samp | |
+@item main | |
+main profile | |
+@item main10 | |
+main10 profile | |
+@item rext | |
+rext profile | |
+@end table | |
+ | |
+Default is 1 (main). | |
+ | |
+@item level (@emph{level}) | |
+ | |
+@option{level} sets the value of @emph{level}. | |
+Set level (level_idc). Default is 0 (to be determined by the encoder). | |
+ | |
+@end table | |
+ | |
+The encoder also has its own specific options: | |
+ | |
+@table @option | |
+@item aud (@emph{aud}) | |
+Enable use of access unit delimiters when set to 1. Default is 0 (Off). | |
+ | |
+@item hielevel | |
+Set hierarchical levels. Can assume one of the following possible values: | |
+ | |
+@table @samp | |
+@item flat | |
+flat more | |
+@item 1 level | |
+Minigop size is 2^1 | |
+@item 2 level | |
+Minigop size is 2^2 | |
+@item 3 level | |
+Minigop size is 2^3 | |
+@end table | |
+ | |
+Default is 3 level. | |
+ | |
+@item la_depth | |
+Set look-ahead depth, depending on @option{rc}: for @var{vbr}, it's recommended | |
+to unset it and use the default value (the intra period); for @var{cqp}, better | |
+specify the look-ahead depth. | |
+ | |
+The range is @var{-1-256}. Default is -1 (unset and the default value to be used). | |
+ | |
+@item preset | |
+Set the quality vs density tradeoff point at which the encoding is to be performed. | |
+Higher perset value, higher density and lower quality. | |
+ | |
+The range is @var{0-12}. Default is 9. | |
+ | |
+@item tier | |
+Set @emph{general_tier_flag}. This may affect the level chosen for the stream | |
+if it is not explicitly specified. Can assume one of the following possible values: | |
+ | |
+@table @samp | |
+@item main | |
+main tier | |
+@item high | |
+high tier | |
+@end table | |
+ | |
+Default is 1 (main). | |
+ | |
+@item rc | |
+Set bit rate control mode. Can assume one of the following possible values: | |
+ | |
+@table @samp | |
+@item cqp | |
+Constant QP (CQP) mode | |
+@item vbr | |
+Variable Bit Rate (VBR) mode | |
+@end table | |
+ | |
+Default is 0 (cqp). | |
+ | |
+@item forced_idr | |
+Force keyframes to be IDR if set to 1. Default is 0 (CRA). | |
+ | |
+@item asm_type | |
+Auto select highest supported asm if set to 1 or C only if 0. Default is 1. | |
+ | |
+@item qp | |
+Initial quantization parameter for the intra pictures used when | |
+@option{rc} is cqp mode. The range is from @var{0-51}. Default is 32. | |
+ | |
+@item sc_detection | |
+Enables or disables the scene change detection algorithm. Default is 0 (disabled). | |
+ | |
+@item tune | |
+Set quality tuning mode. Can assume one of the following possible values: | |
+ | |
+@table @samp | |
+@item sq | |
+Visually optimized mode | |
+@item oq | |
+PSNR / SSIM optimized mode | |
+@item vmaf | |
+VMAF optimized mode | |
+@end table | |
+ | |
+Default is 1 (oq). | |
+ | |
+@item bl_mode | |
+Enables or disables Random Access Prediction. Default is 0 (disabled). | |
+@end table | |
+ | |
@section libtheora | |
libtheora Theora encoder wrapper. | |
-- | |
2.22.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment