diff --git a/ffmpeg/custom/017-ffmpeg-glslang-11.0-fix.patch b/ffmpeg/custom/017-ffmpeg-glslang-11.0-fix.patch deleted file mode 100644 index 4d7e340c..00000000 --- a/ffmpeg/custom/017-ffmpeg-glslang-11.0-fix.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4dab04622a6cf2a31da26a51dedb60ec44ac89a4 Mon Sep 17 00:00:00 2001 -From: Ben Clayton -Date: Fri, 10 Jul 2020 16:53:12 +0100 -Subject: [PATCH] libavfilter/glslang: Remove unused header - -The include was not used, and revision.h has -been removed from glslang master. -See: https://github.com/KhronosGroup/glslang/pull/2277 ---- - libavfilter/glslang.cpp | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/libavfilter/glslang.cpp b/libavfilter/glslang.cpp -index 497df6e..125eb5c 100644 ---- a/libavfilter/glslang.cpp -+++ b/libavfilter/glslang.cpp -@@ -24,7 +24,6 @@ extern "C" { - } - - #include --#include - #include - #include - --- -2.7.4 - diff --git a/ffmpeg/custom/020-ffmpeg-add-svt-hevc-1.5.0.patch b/ffmpeg/custom/020-ffmpeg-add-svt-hevc-1.5.0.patch deleted file mode 100644 index f72977f5..00000000 --- a/ffmpeg/custom/020-ffmpeg-add-svt-hevc-1.5.0.patch +++ /dev/null @@ -1,647 +0,0 @@ -From 297c9a0309c8ba06f9f746d7685dceaef7c0b690 Mon Sep 17 00:00:00 2001 -From: Jing Sun -Date: Wed, 21 Nov 2018 11:33:04 +0800 -Subject: [PATCH] lavc/svt_hevc: add libsvt hevc encoder wrapper - -Signed-off-by: Zhengxu Huang -Signed-off-by: Hassene Tmar -Signed-off-by: Jun Zhao -Signed-off-by: Jing Sun -Signed-off-by: Austin Hu -Signed-off-by: Guo Jiansheng ---- - configure | 4 + - libavcodec/Makefile | 1 + - libavcodec/allcodecs.c | 1 + - libavcodec/libsvt_hevc.c | 559 +++++++++++++++++++++++++++++++++++++++ - 4 files changed, 565 insertions(+) - create mode 100644 libavcodec/libsvt_hevc.c - -diff --git a/configure b/configure -index 09bda9b408..454cf65a90 100755 ---- a/configure -+++ b/configure -@@ -267,6 +267,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] -@@ -1801,6 +1802,7 @@ EXTERNAL_LIBRARY_LIST=" - libspeex - libsrt - libssh -+ libsvthevc - libtensorflow - libtesseract - libtheora -@@ -3229,6 +3231,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" -@@ -6344,6 +6347,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 c1c9a44f2b..dd9b930b9b 100644 ---- a/libavcodec/Makefile -+++ b/libavcodec/Makefile -@@ -1008,6 +1008,7 @@ OBJS-$(CONFIG_LIBRAV1E_ENCODER) += librav1e.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 b3184af954..41994e31b3 100644 ---- a/libavcodec/allcodecs.c -+++ b/libavcodec/allcodecs.c -@@ -720,6 +720,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..fce27a06ea ---- /dev/null -+++ b/libavcodec/libsvt_hevc.c -@@ -0,0 +1,559 @@ -+/* -+* 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 "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; -+ uint8_t *in_data; -+ 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; -+ int thread_count; -+ int high_dynamic_range; -+ int unrestricted_motion_vector; -+ int tile_row_count; -+ int tile_col_count; -+ int tile_slice_mode; -+} 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) -+{ -+ if (svt_enc && svt_enc->in_data) { -+ av_freep(&svt_enc->in_data); -+ svt_enc->in_data = NULL; -+ } -+} -+ -+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) { -+ svt_enc->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; -+ param->vbvMaxrate = avctx->rc_max_rate; -+ param->vbvBufsize = avctx->rc_buffer_size; -+ -+ 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; -+ } -+ -+ 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; -+ param->highDynamicRangeInput = svt_enc->high_dynamic_range; -+ if (param->rateControlMode) { -+ param->maxQpAllowed = avctx->qmax; -+ param->minQpAllowed = avctx->qmin; -+ } -+ -+ if (svt_enc->la_depth != -1) -+ param->lookAheadDistance = svt_enc->la_depth; -+ -+ if ((svt_enc->thread_count > 0) && -+ (svt_enc->thread_count < (EB_THREAD_COUNT_MIN_CORE * EB_THREAD_COUNT_FACTOR))) { -+ param->threadCount = EB_THREAD_COUNT_MIN_CORE * EB_THREAD_COUNT_FACTOR; -+ av_log(avctx, AV_LOG_WARNING, "Thread count is set too small, forced to %"PRId32"\n", -+ param->threadCount); -+ } else if (svt_enc->thread_count % EB_THREAD_COUNT_MIN_CORE) { -+ param->threadCount = (svt_enc->thread_count + EB_THREAD_COUNT_MIN_CORE - 1) -+ / EB_THREAD_COUNT_MIN_CORE * EB_THREAD_COUNT_MIN_CORE; -+ av_log(avctx, AV_LOG_DEBUG, "Thread count is rounded to %"PRId32"\n", -+ param->threadCount); -+ } else { -+ param->threadCount = svt_enc->thread_count; -+ } -+ -+ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) -+ param->codeVpsSpsPps = 0; -+ else -+ param->codeVpsSpsPps = 1; -+ -+ param->codeEosNal = 1; -+ -+ if (svt_enc->unrestricted_motion_vector == 0 || svt_enc->unrestricted_motion_vector == 1) { -+ param->unrestrictedMotionVector = svt_enc->unrestricted_motion_vector; -+ } else { -+ av_log(avctx, AV_LOG_ERROR, "Unrestricted Motion Vector should be set 0 or 1\n"); -+ return EB_ErrorBadParameter; -+ } -+ -+ if(svt_enc->tile_row_count >= 1 && svt_enc->tile_row_count <= 16) { -+ param->tileRowCount = svt_enc->tile_row_count; -+ } else { -+ av_log(avctx, AV_LOG_ERROR, "Tile Row Count should between 1-16\n"); -+ return EB_ErrorBadParameter; -+ } -+ -+ if(svt_enc->tile_col_count >= 1 && svt_enc->tile_col_count <= 16) { -+ param->tileColumnCount = svt_enc->tile_col_count; -+ } else { -+ av_log(avctx, AV_LOG_ERROR, "Tile Column Count should between 1-16\n"); -+ return EB_ErrorBadParameter; -+ } -+ -+ if(svt_enc->tile_slice_mode == 0 || svt_enc->tile_slice_mode == 1) { -+ param->tileSliceMode = svt_enc->tile_slice_mode; -+ } else { -+ av_log(avctx, AV_LOG_ERROR, "Tile Slice Mode should be set 0 or 1\n"); -+ return EB_ErrorBadParameter; -+ } -+ 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(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->nFlags = EB_BUFFERFLAG_EOS; -+ header_ptr->pBuffer = NULL; -+ -+ 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; -+ } else if (svt_ret == EB_ErrorMax) { -+ *got_packet = 0; -+ av_log(avctx, AV_LOG_ERROR, "Received NULL packet with error code 0x%X\n", header_ptr->nFlags); -+ return AVERROR_INVALIDDATA; -+ } -+ -+ 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; -+ } -+ } -+ -+ 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_INT, { .i64 = -1 }, -1, INT_MAX, 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 = 7 }, 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 }, -+ -+ { "thread_count", "Number of threads [0: Auto, 96: Min]", OFFSET(thread_count), -+ AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, 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" }, -+ { "hdr", "High dynamic range input (HDR10)", OFFSET(high_dynamic_range), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 1, VE, "hdr" }, -+ { "umv", "Enables or disables unrestricted motion vectors", OFFSET(unrestricted_motion_vector), -+ AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, -+ { "tile_row_cnt", "tile count in the row", OFFSET(tile_row_count), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 16, VE }, -+ { "tile_col_cnt", "tile count in the column", OFFSET(tile_col_count), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 16, VE }, -+ { "tile_slice_mode", "per slice per tile, only valid for multi-tile", OFFSET(tile_slice_mode), -+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, -+ {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" }, -+ { "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, -+ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, -+ AV_PIX_FMT_YUV420P10, -+ AV_PIX_FMT_YUV422P, -+ AV_PIX_FMT_YUV422P10, -+ 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.17.1 - diff --git a/ffmpeg/custom/030-ffmpeg-add-svt-hevc-docs-1.5.0.patch b/ffmpeg/custom/030-ffmpeg-add-svt-hevc-docs-1.5.0.patch deleted file mode 100644 index b1e14880..00000000 --- a/ffmpeg/custom/030-ffmpeg-add-svt-hevc-docs-1.5.0.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 6b0a4fd63454e3c2185efe741e50e80df5c9a4a4 Mon Sep 17 00:00:00 2001 -From: Jing Sun -Date: Tue, 5 Mar 2019 15:04:58 +0800 -Subject: [PATCH 2/2] doc: Add libsvt_hevc encoder docs - -Add docs for libsvt_hevc encoder in encoders.texi and general.texi - -Signed-off-by: Jun Zhao -Signed-off-by: Zhengxu Huang -Signed-off-by: Hassene Tmar -Signed-off-by: Jing Sun ---- - doc/encoders.texi | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - doc/general.texi | 8 +++ - 2 files changed, 157 insertions(+) - -diff --git a/doc/encoders.texi b/doc/encoders.texi -index eefd124..81debda 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 >=0 (the value sets headers insertion interval). Default is -1 (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. -diff --git a/doc/general.texi b/doc/general.texi -index 3c0c803..fa9cd31 100644 ---- a/doc/general.texi -+++ b/doc/general.texi -@@ -243,6 +243,14 @@ FFmpeg can use the OpenJPEG libraries for decoding/encoding J2K videos. Go to - instructions. To enable using OpenJPEG in FFmpeg, pass @code{--enable-libopenjpeg} to - @file{./configure}. - -+@section Scalable Video Technology for HEVC -+ -+FFmpeg can make use of the SVT-HEVC library for HEVC encoding. -+ -+Go to @url{https://github.com/intel/SVT-HEVC.git} and follow the instructions -+for installing the library. Pass @code{--enable-libsvthevc} to configure to -+enable it. -+ - @section TwoLAME - - FFmpeg can make use of the TwoLAME library for MP2 encoding. --- -1.8.3.1 - diff --git a/ffmpeg/custom/040-ffmpeg-add-svt-av1-0.8.4.patch b/ffmpeg/custom/040-ffmpeg-add-svt-av1-0.8.4.patch deleted file mode 100644 index 01d8050e..00000000 --- a/ffmpeg/custom/040-ffmpeg-add-svt-av1-0.8.4.patch +++ /dev/null @@ -1,671 +0,0 @@ -From 726a9def395d40aa0d8a4b8fe5ebc1af13015dbb Mon Sep 17 00:00:00 2001 -From: Daryl Seah -Date: Fri, 18 Jan 2019 02:11:38 +0000 -Subject: [PATCH] Add ability for ffmpeg to run svt-av1 - -Change-Id: I37ee5414fdd99e0b3f112a6e5ede166f3e48d819 -Signed-off-by: Daryl Seah -Signed-off-by: Jing SUN -Signed-off-by: ZhiZhen Tang -Signed-off-by: Zhong Li -Signed-off-by: Xu Guangxin ---- - configure | 4 + - libavcodec/Makefile | 1 + - libavcodec/allcodecs.c | 1 + - libavcodec/libsvt_av1.c | 583 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 589 insertions(+) - create mode 100644 libavcodec/libsvt_av1.c - -diff --git a/configure b/configure -index 7495f35faa..e0a466b968 100755 ---- a/configure -+++ b/configure -@@ -249,6 +249,7 @@ External library support: - --enable-libmp3lame enable MP3 encoding via libmp3lame [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-libsvtav1 enable AV1 encoding via svt [no] - --enable-libopencv enable video filtering via libopencv [no] - --enable-libopenh264 enable H.264 encoding via OpenH264 [no] - --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no] -@@ -1786,6 +1787,7 @@ EXTERNAL_LIBRARY_LIST=" - libmodplug - libmp3lame - libmysofa -+ libsvtav1 - libopencv - libopenh264 - libopenjpeg -@@ -3223,6 +3225,7 @@ libopencore_amrnb_decoder_deps="libopencore_amrnb" - libopencore_amrnb_encoder_deps="libopencore_amrnb" - libopencore_amrnb_encoder_select="audio_frame_queue" - libopencore_amrwb_decoder_deps="libopencore_amrwb" -+libsvt_av1_encoder_deps="libsvtav1" - libopenh264_decoder_deps="libopenh264" - libopenh264_decoder_select="h264_mp4toannexb_bsf" - libopenh264_encoder_deps="libopenh264" -@@ -6342,6 +6345,7 @@ enabled libnpp && { check_lib libnpp npp.h nppGetLibVersion -lnppig - - die "ERROR: libnpp not found"; } - enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb - enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb -+enabled libsvtav1 && require_pkg_config libsvtav1 SvtAv1Enc EbSvtAv1Enc.h svt_av1_enc_init_handle - enabled libopencv && { check_headers opencv2/core/core_c.h && - { check_pkg_config libopencv opencv opencv2/core/core_c.h cvCreateImageHeader || - require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } || -diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 5a6ea59715..b4dbca54d5 100644 ---- a/libavcodec/Makefile -+++ b/libavcodec/Makefile -@@ -971,6 +971,7 @@ OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o - OBJS-$(CONFIG_ELBG_FILTER) += elbg.o - - # external codec libraries -+OBJS-$(CONFIG_LIBSVT_AV1_ENCODER) += libsvt_av1.o - OBJS-$(CONFIG_AAC_AT_DECODER) += audiotoolboxdec.o - OBJS-$(CONFIG_AC3_AT_DECODER) += audiotoolboxdec.o - OBJS-$(CONFIG_ADPCM_IMA_QT_AT_DECODER) += audiotoolboxdec.o -diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c -index fa0c08d42e..ec1e0d48ba 100644 ---- a/libavcodec/allcodecs.c -+++ b/libavcodec/allcodecs.c -@@ -716,6 +716,7 @@ extern AVCodec ff_libmp3lame_encoder; - extern AVCodec ff_libopencore_amrnb_encoder; - extern AVCodec ff_libopencore_amrnb_decoder; - extern AVCodec ff_libopencore_amrwb_decoder; -+extern AVCodec ff_libsvt_av1_encoder; - extern AVCodec ff_libopenjpeg_encoder; - extern AVCodec ff_libopenjpeg_decoder; - extern AVCodec ff_libopus_encoder; -diff --git a/libavcodec/libsvt_av1.c b/libavcodec/libsvt_av1.c -new file mode 100644 -index 0000000000..541ba228fa ---- /dev/null -+++ b/libavcodec/libsvt_av1.c -@@ -0,0 +1,583 @@ -+ -+/* -+* Scalable Video Technology for AV1 encoder library plugin -+* -+* Copyright (c) 2018 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 -+#include "EbSvtAv1ErrorCodes.h" -+#include "EbSvtAv1Enc.h" -+ -+#include "libavutil/common.h" -+#include "libavutil/frame.h" -+#include "libavutil/opt.h" -+#include "libavutil/pixdesc.h" -+#include "libavutil/avassert.h" -+ -+#include "internal.h" -+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 93, 100) -+#include "encode.h" -+#endif -+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 90, 100) -+#include "packet_internal.h" -+#endif -+#include "avcodec.h" -+ -+typedef enum eos_status { -+ EOS_NOT_REACHED = 0, -+ EOS_SENT, -+ EOS_RECEIVED -+}EOS_STATUS; -+ -+typedef struct SvtContext { -+ AVClass *class; -+ -+ EbSvtAv1EncConfiguration enc_params; -+ EbComponentType *svt_handle; -+ -+ EbBufferHeaderType *in_buf; -+ int raw_size; -+ int max_tu_size; -+ -+ AVFrame *frame; -+ -+ AVBufferPool* pool; -+ -+ EOS_STATUS eos_flag; -+ -+ // User options. -+ int hierarchical_level; -+ int la_depth; -+ int enc_mode; -+ int rc_mode; -+ int scd; -+ int qp; -+ -+ int forced_idr; -+ -+ int tier; -+ int level; -+ int profile; -+ -+ int tile_columns; -+ int tile_rows; -+} SvtContext; -+ -+static const struct { -+ EbErrorType eb_err; -+ int av_err; -+ const char *desc; -+} svt_errors[] = { -+ { EB_ErrorNone, 0, "success" }, -+ { EB_ErrorInsufficientResources, AVERROR(ENOMEM), "insufficient resources" }, -+ { EB_ErrorUndefined, AVERROR(EINVAL), "undefined error" }, -+ { EB_ErrorInvalidComponent, AVERROR(EINVAL), "invalid component" }, -+ { EB_ErrorBadParameter, AVERROR(EINVAL), "bad parameter" }, -+ { EB_ErrorDestroyThreadFailed, AVERROR_EXTERNAL, "failed to destory thread" }, -+ { EB_ErrorSemaphoreUnresponsive, AVERROR_EXTERNAL, "semaphore unresponsive" }, -+ { EB_ErrorDestroySemaphoreFailed, AVERROR_EXTERNAL, "semaphore unresponsive" }, -+ { EB_ErrorCreateMutexFailed, AVERROR_EXTERNAL, "failed to creat mutex" }, -+ { EB_ErrorMutexUnresponsive, AVERROR_EXTERNAL, "mutex unresponsive" }, -+ { EB_ErrorDestroyMutexFailed, AVERROR_EXTERNAL, "failed to destory muxtex" }, -+ { EB_NoErrorEmptyQueue, AVERROR(EAGAIN), "empty queue" }, -+}; -+ -+static int svt_map_error(EbErrorType eb_err, const char **desc) -+{ -+ int i; -+ -+ av_assert0(desc); -+ for (i = 0; i < FF_ARRAY_ELEMS(svt_errors); i++) { -+ if (svt_errors[i].eb_err == eb_err) { -+ *desc = svt_errors[i].desc; -+ return svt_errors[i].av_err; -+ } -+ } -+ *desc = "unknown error"; -+ return AVERROR_UNKNOWN; -+} -+ -+static int svt_print_error(void *log_ctx, EbErrorType err, -+ const char *error_string) -+{ -+ const char *desc; -+ int ret; -+ ret = svt_map_error(err, &desc); -+ av_log(log_ctx, AV_LOG_ERROR, "%s: %s (0x%x)\n", error_string, desc, err); -+ return ret; -+} -+ -+static void free_buffer(SvtContext *svt_enc) -+{ -+ if (svt_enc->in_buf) { -+ EbSvtIOFormat *in_data = (EbSvtIOFormat *)svt_enc->in_buf->p_buffer; -+ av_freep(&in_data); -+ av_freep(&svt_enc->in_buf); -+ } -+ av_buffer_pool_uninit(&svt_enc->pool); -+} -+ -+static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc) -+{ -+ const int pack_mode_10bit = -+ (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0; -+ const size_t luma_size_8bit = -+ config->source_width * config->source_height * (1 << pack_mode_10bit); -+ const size_t luma_size_10bit = -+ (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit : 0; -+ -+ EbSvtIOFormat *in_data; -+ -+ svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2; -+ -+ // allocate buffer for in and out -+ svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf)); -+ if (!svt_enc->in_buf) -+ return AVERROR(ENOMEM); -+ -+ svt_enc->in_buf->p_buffer = (unsigned char *)av_mallocz(sizeof(*in_data)); -+ if (!svt_enc->in_buf->p_buffer) -+ return AVERROR(ENOMEM); -+ -+ svt_enc->in_buf->size = sizeof(*svt_enc->in_buf); -+ svt_enc->in_buf->p_app_private = NULL; -+ -+ return 0; -+ -+} -+ -+static int config_enc_params(EbSvtAv1EncConfiguration *param, -+ AVCodecContext *avctx) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ const AVPixFmtDescriptor *desc; -+ -+ param->source_width = avctx->width; -+ param->source_height = avctx->height; -+ -+ desc = av_pix_fmt_desc_get(avctx->pix_fmt); -+ param->encoder_bit_depth = desc->comp[0].depth; -+ av_log(avctx, AV_LOG_DEBUG , "Encoder %d bits depth input\n", param->encoder_bit_depth); -+ -+ if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 1) -+ param->encoder_color_format = EB_YUV420; -+ else if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 0) -+ param->encoder_color_format = EB_YUV422; -+ else if (!desc->log2_chroma_w && !desc->log2_chroma_h) -+ param->encoder_color_format = EB_YUV444; -+ else { -+ av_log(avctx, AV_LOG_ERROR , "Unsupported pixel format\n"); -+ return AVERROR(EINVAL); -+ } -+ av_log(avctx, AV_LOG_DEBUG , "Encoder color format is %d \n", param->encoder_color_format); -+ -+ param->profile = svt_enc->profile; -+ -+ if ((param->encoder_color_format == EB_YUV422 || param->encoder_bit_depth > 10) -+ && param->profile != PROFESSIONAL_PROFILE ) { -+ av_log(avctx, AV_LOG_WARNING, "Force to be professional profile \n"); -+ param->profile = PROFESSIONAL_PROFILE; -+ } else if (param->encoder_color_format == EB_YUV444 && param->profile != HIGH_PROFILE) { -+ av_log(avctx, AV_LOG_WARNING, "Force to be high profile \n"); -+ param->profile = HIGH_PROFILE; -+ } -+ -+ // Update param from options -+ param->hierarchical_levels = svt_enc->hierarchical_level; -+ param->enc_mode = svt_enc->enc_mode; -+ param->tier = svt_enc->tier; -+ param->level = svt_enc->level; -+ param->rate_control_mode = svt_enc->rc_mode; -+ param->scene_change_detection = svt_enc->scd; -+ -+ param->qp = svt_enc->qp; -+ -+ -+ param->target_bit_rate = avctx->bit_rate; -+ if (avctx->gop_size > 0) -+ param->intra_period_length = avctx->gop_size - 1; -+ -+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { -+ param->frame_rate_numerator = avctx->framerate.num; -+ param->frame_rate_denominator = avctx->framerate.den * avctx->ticks_per_frame; -+ } else { -+ param->frame_rate_numerator = avctx->time_base.den; -+ param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame; -+ } -+ -+ if (param->rate_control_mode) { -+ param->max_qp_allowed = avctx->qmax; -+ param->min_qp_allowed = avctx->qmin; -+ } -+ -+ param->intra_refresh_type = svt_enc->forced_idr + 1; -+ -+ if (svt_enc->la_depth != -1) -+ param->look_ahead_distance = svt_enc->la_depth; -+ -+ param->tile_columns = svt_enc->tile_columns; -+ param->tile_rows = svt_enc->tile_rows; -+ -+ return 0; -+} -+ -+static void read_in_data(const AVFrame *frame, -+ EbBufferHeaderType *header_ptr) -+{ -+ EbSvtIOFormat *in_data = (EbSvtIOFormat *)header_ptr->p_buffer; -+ const AVPixFmtDescriptor *desc; -+ int i, bytes_shift, plane_h; -+ -+ desc = av_pix_fmt_desc_get(frame->format); -+ bytes_shift = desc->comp[0].depth > 8 ? 1 : 0; -+ -+ in_data->luma = frame->data[0]; -+ in_data->cb = frame->data[1]; -+ in_data->cr = frame->data[2]; -+ -+ in_data->y_stride = AV_CEIL_RSHIFT(frame->linesize[0], bytes_shift); -+ in_data->cb_stride = AV_CEIL_RSHIFT(frame->linesize[1], bytes_shift); -+ in_data->cr_stride = AV_CEIL_RSHIFT(frame->linesize[2], bytes_shift); -+ -+ for (i = 0; i < desc->nb_components; i++) { -+ plane_h = frame->height; -+ if (i > 0) -+ plane_h = AV_CEIL_RSHIFT(plane_h, desc->log2_chroma_h); -+ header_ptr->n_filled_len += frame->linesize[i] * plane_h; -+ } -+} -+ -+static av_cold int eb_enc_init(AVCodecContext *avctx) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ EbErrorType svt_ret; -+ int ret; -+ -+ svt_enc->eos_flag = EOS_NOT_REACHED; -+ -+ svt_ret = svt_av1_enc_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params); -+ if (svt_ret != EB_ErrorNone) { -+ return svt_print_error(avctx, svt_ret, "Error init encoder handle"); -+ } -+ -+ ret = config_enc_params(&svt_enc->enc_params, avctx); -+ if (ret < 0) { -+ av_log(avctx, AV_LOG_ERROR, "Error configure encoder parameters\n"); -+ return ret; -+ } -+ -+ svt_ret = svt_av1_enc_set_parameter(svt_enc->svt_handle, &svt_enc->enc_params); -+ if (svt_ret != EB_ErrorNone) { -+ return svt_print_error(avctx, svt_ret, "Error setting encoder parameters"); -+ } -+ -+ svt_ret = svt_av1_enc_init(svt_enc->svt_handle); -+ if (svt_ret != EB_ErrorNone) { -+ svt_av1_enc_deinit_handle(svt_enc->svt_handle); -+ svt_enc->svt_handle = NULL; -+ return svt_print_error(avctx, svt_ret, "Error init encoder"); -+ } -+ -+ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { -+ EbBufferHeaderType *headerPtr = NULL; -+ -+ svt_ret = svt_av1_enc_stream_header(svt_enc->svt_handle, &headerPtr); -+ if (svt_ret != EB_ErrorNone) { -+ return svt_print_error(avctx, svt_ret, "Error when build stream header"); -+ } -+ -+ avctx->extradata_size = headerPtr->n_filled_len; -+ avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); -+ if (!avctx->extradata) { -+ av_log(avctx, AV_LOG_ERROR, -+ "Cannot allocate AV1 header of size %d.\n", avctx->extradata_size); -+ return AVERROR(ENOMEM); -+ } -+ -+ memcpy(avctx->extradata, headerPtr->p_buffer, avctx->extradata_size); -+ -+ svt_ret = svt_av1_enc_stream_header_release(headerPtr); -+ if (svt_ret != EB_ErrorNone) { -+ return svt_print_error(avctx, svt_ret, "Error when destroy stream header"); -+ } -+ } -+ -+ svt_enc->frame = av_frame_alloc(); -+ if (!svt_enc->frame) -+ return AVERROR(ENOMEM); -+ -+ ret = alloc_buffer(&svt_enc->enc_params, svt_enc); -+ if (ret < 0) -+ return ret; -+ return 0; -+ -+} -+ -+static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ EbBufferHeaderType *headerPtr = svt_enc->in_buf; -+ -+ if (!frame) { -+ EbBufferHeaderType headerPtrLast; -+ -+ if (svt_enc->eos_flag == EOS_SENT) -+ return 0; -+ -+ headerPtrLast.n_alloc_len = 0; -+ headerPtrLast.n_filled_len = 0; -+ headerPtrLast.n_tick_count = 0; -+ headerPtrLast.p_app_private = NULL; -+ headerPtrLast.p_buffer = NULL; -+ headerPtrLast.flags = EB_BUFFERFLAG_EOS; -+ -+ svt_av1_enc_send_picture(svt_enc->svt_handle, &headerPtrLast); -+ svt_enc->eos_flag = EOS_SENT; -+ av_log(avctx, AV_LOG_DEBUG, "Finish sending frames!!!\n"); -+ return 0; -+ } -+ -+ read_in_data(frame, headerPtr); -+ -+ headerPtr->flags = 0; -+ headerPtr->p_app_private = NULL; -+ headerPtr->pts = frame->pts; -+ -+ svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr); -+ -+ return 0; -+} -+ -+static AVBufferRef* get_output_ref(AVCodecContext *avctx, SvtContext *svt_enc, int filled_len) -+{ -+ if (filled_len > svt_enc->max_tu_size) { -+ const int MAX_FRAMES = 8; -+ int max_tu_size; -+ if (filled_len > svt_enc->raw_size * MAX_FRAMES) { -+ av_log(avctx, AV_LOG_ERROR, "something wrong in libsvtav1, the tu size > %d raw frame size.\n", MAX_FRAMES); -+ return NULL; -+ } -+ max_tu_size = 1 << av_ceil_log2(filled_len); -+ av_buffer_pool_uninit(&svt_enc->pool); -+ svt_enc->pool = av_buffer_pool_init(max_tu_size, NULL); -+ if (!svt_enc->pool) { -+ return NULL; -+ } -+ svt_enc->max_tu_size = max_tu_size; -+ } -+ if (!svt_enc->pool) { -+ av_log(avctx, AV_LOG_ERROR, "bug, no buffer pool.\n"); -+ return NULL; -+ } -+ return av_buffer_pool_get(svt_enc->pool); -+} -+ -+static int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ EbBufferHeaderType *headerPtr; -+ AVFrame *frame = svt_enc->frame; -+ EbErrorType svt_ret; -+ int ret = 0, pict_type; -+ AVBufferRef* ref; -+ -+ if (svt_enc->eos_flag == EOS_RECEIVED) -+ return AVERROR_EOF; -+ -+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 93, 100) -+ ret = ff_encode_get_frame(avctx, frame); -+ if (ret < 0 && ret != AVERROR_EOF) -+ return ret; -+ if (ret == AVERROR_EOF) -+ frame = NULL; -+ -+ eb_send_frame(avctx, frame); -+ av_frame_unref(svt_enc->frame); -+#endif -+ -+ svt_ret = svt_av1_enc_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag); -+ if (svt_ret == EB_NoErrorEmptyQueue) -+ return AVERROR(EAGAIN); -+ -+ ref = get_output_ref(avctx, svt_enc, headerPtr->n_filled_len); -+ if (!ref) { -+ av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n"); -+ svt_av1_enc_release_out_buffer(&headerPtr); -+ return AVERROR(ENOMEM); -+ } -+ pkt->buf = ref; -+ pkt->data = ref->data; -+ -+ memcpy(pkt->data, headerPtr->p_buffer, headerPtr->n_filled_len); -+ pkt->size = headerPtr->n_filled_len; -+ pkt->pts = headerPtr->pts; -+ pkt->dts = headerPtr->dts; -+ if (headerPtr->pic_type == EB_AV1_KEY_PICTURE) { -+ pkt->flags |= AV_PKT_FLAG_KEY; -+ pict_type = AV_PICTURE_TYPE_I; -+ } else if (headerPtr->pic_type == EB_AV1_INTRA_ONLY_PICTURE) { -+ pict_type = AV_PICTURE_TYPE_I; -+ } else if (headerPtr->pic_type == EB_AV1_INVALID_PICTURE) { -+ pict_type = AV_PICTURE_TYPE_NONE; -+ } else -+ pict_type = AV_PICTURE_TYPE_P; -+ -+ if (headerPtr->pic_type == EB_AV1_NON_REF_PICTURE) -+ pkt->flags |= AV_PKT_FLAG_DISPOSABLE; -+ -+ if (headerPtr->flags & EB_BUFFERFLAG_EOS) -+ svt_enc->eos_flag = EOS_RECEIVED; -+ -+ ff_side_data_set_encoder_stats(pkt, headerPtr->qp * FF_QP2LAMBDA, NULL, 0, pict_type); -+ -+ svt_av1_enc_release_out_buffer(&headerPtr); -+ -+ return 0; -+} -+ -+static av_cold int eb_enc_close(AVCodecContext *avctx) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ -+ if (svt_enc) { -+ if (svt_enc->svt_handle) { -+ svt_av1_enc_deinit(svt_enc->svt_handle); -+ svt_av1_enc_deinit_handle(svt_enc->svt_handle); -+ } -+ -+ av_frame_free(&svt_enc->frame); -+ -+ free_buffer(svt_enc); -+ 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[] = { -+ { "hielevel", "Hierarchical prediction levels setting", OFFSET(hierarchical_level), -+ AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE , "hielevel"}, -+ { "3level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" }, -+ { "4level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, INT_MIN, INT_MAX, VE, "hielevel" }, -+ -+ { "la_depth", "Look ahead distance [0, 120]", OFFSET(la_depth), -+ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE }, -+ -+ { "preset", "Encoding preset [0, 8]", -+ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = MAX_ENC_PRESET }, 0, MAX_ENC_PRESET, VE }, -+ -+ { "profile", "Set profile restrictions", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = MAIN_PROFILE}, MAIN_PROFILE, PROFESSIONAL_PROFILE, VE, "profile" }, -+ { "main" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MAIN_PROFILE}, INT_MIN, INT_MAX, VE, "profile" }, -+ { "high" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = HIGH_PROFILE}, INT_MIN, INT_MAX, VE, "profile" }, -+ { "professional", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PROFESSIONAL_PROFILE }, INT_MIN, INT_MAX, VE, "profile" }, -+ -+ { "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" }, -+ -+ { "level", "Set level (level_idc)", OFFSET(level), -+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0x1f, VE, "level" }, -+ -+#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ -+ { .i64 = value }, 0, 0, VE, "level" -+ { LEVEL("2.0", 20) }, -+ { LEVEL("2.1", 21) }, -+ { LEVEL("2.2", 22) }, -+ { LEVEL("2.3", 23) }, -+ { LEVEL("3.0", 30) }, -+ { LEVEL("3.1", 31) }, -+ { LEVEL("3.2", 32) }, -+ { LEVEL("3.3", 33) }, -+ { LEVEL("4.0", 40) }, -+ { LEVEL("4.1", 41) }, -+ { LEVEL("4.2", 42) }, -+ { LEVEL("4.3", 43) }, -+ { LEVEL("5.0", 50) }, -+ { LEVEL("5.1", 51) }, -+ { LEVEL("5.2", 52) }, -+ { LEVEL("5.3", 53) }, -+ { LEVEL("6.0", 60) }, -+ { LEVEL("6.1", 61) }, -+ { LEVEL("6.2", 62) }, -+ { LEVEL("6.3", 63) }, -+ { LEVEL("7.0", 70) }, -+ { LEVEL("7.1", 71) }, -+ { LEVEL("7.2", 72) }, -+ { LEVEL("7.3", 73) }, -+#undef LEVEL -+ -+ { "rc", "Bit rate control mode", OFFSET(rc_mode), -+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, VE , "rc"}, -+ { "cqp", "Const Quantization Parameter", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" }, -+ { "vbr", "Variable Bit Rate, use a target bitrate for the entire stream", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" }, -+ { "cvbr", "Constrained Variable Bit Rate, use a target bitrate for each GOP", 0, AV_OPT_TYPE_CONST,{ .i64 = 2 }, INT_MIN, INT_MAX, VE, "rc" }, -+ -+ { "qp", "QP value for intra frames", OFFSET(qp), -+ AV_OPT_TYPE_INT, { .i64 = 50 }, 0, 63, VE }, -+ -+ { "sc_detection", "Scene change detection", OFFSET(scd), -+ 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 = 1 }, 0, 1, VE }, -+ { "tile-columns", "Log2 of number of tile columns to use", OFFSET(tile_columns), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, VE}, -+ { "tile-rows", "Log2 of number of tile rows to use", OFFSET(tile_rows), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 6, VE}, -+ -+ {NULL}, -+}; -+ -+static const AVClass class = { -+ .class_name = "libsvt_av1", -+ .item_name = av_default_item_name, -+ .option = options, -+ .version = LIBAVUTIL_VERSION_INT, -+}; -+ -+static const AVCodecDefault eb_enc_defaults[] = { -+ { "b", "7M" }, -+ { "g", "-2" }, -+ { "qmin", "0" }, -+ { "qmax", "63" }, -+ { NULL }, -+}; -+ -+AVCodec ff_libsvt_av1_encoder = { -+ .name = "libsvt_av1", -+ .long_name = NULL_IF_CONFIG_SMALL("SVT-AV1(Scalable Video Technology for AV1) encoder"), -+ .priv_data_size = sizeof(SvtContext), -+ .type = AVMEDIA_TYPE_VIDEO, -+ .id = AV_CODEC_ID_AV1, -+ .init = eb_enc_init, -+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 93, 100) -+ .send_frame = eb_send_frame, -+#endif -+ .receive_packet = eb_receive_packet, -+ .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_NONE }, -+ .priv_class = &class, -+ .defaults = eb_enc_defaults, -+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, -+ .wrapper_name = "libsvt_av1", -+}; --- -2.17.1 - diff --git a/ffmpeg/custom/050-ffmpeg-add-svt-vp9-0.3.0.patch b/ffmpeg/custom/050-ffmpeg-add-svt-vp9-0.3.0.patch deleted file mode 100644 index 1fb38fc2..00000000 --- a/ffmpeg/custom/050-ffmpeg-add-svt-vp9-0.3.0.patch +++ /dev/null @@ -1,961 +0,0 @@ -From 213cabc3d23724beae998e473660702fe30aaad1 Mon Sep 17 00:00:00 2001 -From: hassene -Date: Fri, 15 Feb 2019 17:43:54 -0800 -Subject: [PATCH] Add ability for ffmpeg to run svt vp9 - -Signed-off-by: hassene -Signed-off-by: Jing Sun -Signed-off-by: Austin Hu -Signed-off-by: Guo Jiansheng ---- - configure | 4 + - libavcodec/Makefile | 1 + - libavcodec/allcodecs.c | 1 + - libavcodec/avcodec.h | 4 + - libavcodec/libsvt_vp9.c | 509 ++++++++++++++++++++++++++++++++++++++ - libavformat/dashenc.c | 49 +++- - libavformat/ivfenc.c | 30 ++- - libavformat/matroskaenc.c | 104 +++++++- - libavformat/movenc.c | 42 +++- - 9 files changed, 733 insertions(+), 11 deletions(-) - create mode 100644 libavcodec/libsvt_vp9.c - -diff --git a/configure b/configure -index bdfd731602..fbe6f838df 100755 ---- a/configure -+++ b/configure -@@ -283,6 +283,7 @@ External library support: - --enable-libvorbis enable Vorbis en/decoding via libvorbis, - native implementation exists [no] - --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no] -+ --enable-libsvtvp9 enable VP9 encoding via svt [no] - --enable-libwavpack enable wavpack encoding via libwavpack [no] - --enable-libwebp enable WebP encoding via libwebp [no] - --enable-libx264 enable H.264 encoding via x264 [no] -@@ -1800,6 +1801,7 @@ EXTERNAL_LIBRARY_LIST=" - librtmp - libshine - libsmbclient -+ libsvtvp9 - libsnappy - libsoxr - libspeex -@@ -3253,6 +3255,7 @@ libvpx_vp8_decoder_deps="libvpx" - libvpx_vp8_encoder_deps="libvpx" - libvpx_vp9_decoder_deps="libvpx" - libvpx_vp9_encoder_deps="libvpx" -+libsvt_vp9_encoder_deps="libsvtvp9" - libwavpack_encoder_deps="libwavpack" - libwavpack_encoder_select="audio_frame_queue" - libwebp_encoder_deps="libwebp" -@@ -6412,6 +6415,7 @@ enabled libvpx && { - fi - } - -+enabled libsvtvp9 && require_pkg_config libsvtvp9 SvtVp9Enc EbSvtVp9Enc.h eb_vp9_svt_init_handle - enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack - 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 18353da549..230660ea27 100644 ---- a/libavcodec/Makefile -+++ b/libavcodec/Makefile -@@ -1035,6 +1035,7 @@ OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o - 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_LIBSVT_VP9_ENCODER) += libsvt_vp9.o - OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o - OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o - OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o -diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c -index a5048290f7..c34ef96fb9 100644 ---- a/libavcodec/allcodecs.c -+++ b/libavcodec/allcodecs.c -@@ -735,6 +735,7 @@ extern AVCodec ff_libvpx_vp8_encoder; - extern AVCodec ff_libvpx_vp8_decoder; - extern AVCodec ff_libvpx_vp9_encoder; - extern AVCodec ff_libvpx_vp9_decoder; -+extern AVCodec ff_libsvt_vp9_encoder; - extern AVCodec ff_libwavpack_encoder; - /* preferred over libwebp */ - extern AVCodec ff_libwebp_anim_encoder; -diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h -index c91b2fd169..10cdb7b0d9 100644 ---- a/libavcodec/avcodec.h -+++ b/libavcodec/avcodec.h -@@ -405,6 +405,10 @@ typedef struct RcOverride{ - * Export encoder Producer Reference Time through packet side data - */ - #define AV_CODEC_EXPORT_DATA_PRFT (1 << 1) -+ -+#define AV_PKT_FLAG_SVT_VP9_EXT_ON 0x10000 // Indicating SVT VP9 frame header ext on -+#define AV_PKT_FLAG_SVT_VP9_EXT_OFF 0x20000 // Indicating SVT VP9 frame header ext off -+ - /** - * Decoding only. - * Export the AVVideoEncParams structure through frame side data. -diff --git a/libavcodec/libsvt_vp9.c b/libavcodec/libsvt_vp9.c -new file mode 100644 -index 0000000000..a557019c9b ---- /dev/null -+++ b/libavcodec/libsvt_vp9.c -@@ -0,0 +1,509 @@ -+/* -+* Scalable Video Technology for VP9 encoder library plugin -+* -+* Copyright (c) 2018 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 -+#include "EbSvtVp9ErrorCodes.h" -+#include "EbSvtVp9Enc.h" -+ -+#include "libavutil/common.h" -+#include "libavutil/frame.h" -+#include "libavutil/opt.h" -+ -+#include "internal.h" -+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 93, 100) -+#include "encode.h" -+#endif -+#include "avcodec.h" -+ -+typedef enum eos_status { -+ EOS_NOT_REACHED = 0, -+ EOS_REACHED, -+ EOS_TOTRIGGER -+}EOS_STATUS; -+ -+typedef struct SvtContext { -+ AVClass *class; -+ -+ EbSvtVp9EncConfiguration enc_params; -+ EbComponentType *svt_handle; -+ -+ EbBufferHeaderType *in_buf; -+ int raw_size; -+ -+ AVFrame *frame; -+ -+ AVBufferPool* pool; -+ -+ EOS_STATUS eos_flag; -+ -+ // User options. -+ int enc_mode; -+ int rc_mode; -+ int tune; -+ int qp; -+ -+ int forced_idr; -+ -+ int level; -+ -+ int base_layer_switch_mode; -+} SvtContext; -+ -+static int error_mapping(EbErrorType svt_ret) -+{ -+ int err; -+ -+ switch (svt_ret) { -+ case EB_ErrorInsufficientResources: -+ err = AVERROR(ENOMEM); -+ break; -+ -+ case EB_ErrorUndefined: -+ case EB_ErrorInvalidComponent: -+ case EB_ErrorBadParameter: -+ err = AVERROR(EINVAL); -+ break; -+ -+ case EB_ErrorDestroyThreadFailed: -+ case EB_ErrorSemaphoreUnresponsive: -+ case EB_ErrorDestroySemaphoreFailed: -+ case EB_ErrorCreateMutexFailed: -+ case EB_ErrorMutexUnresponsive: -+ case EB_ErrorDestroyMutexFailed: -+ err = AVERROR_EXTERNAL; -+ break; -+ -+ case EB_NoErrorEmptyQueue: -+ err = AVERROR(EAGAIN); -+ -+ case EB_ErrorNone: -+ err = 0; -+ break; -+ -+ default: -+ err = AVERROR_UNKNOWN; -+ } -+ -+ return err; -+} -+ -+static void free_buffer(SvtContext *svt_enc) -+{ -+ if (svt_enc->in_buf) { -+ EbSvtEncInput *in_data = (EbSvtEncInput *)svt_enc->in_buf->p_buffer; -+ av_freep(&in_data); -+ av_freep(&svt_enc->in_buf); -+ } -+ av_buffer_pool_uninit(&svt_enc->pool); -+} -+ -+static int alloc_buffer(EbSvtVp9EncConfiguration *config, SvtContext *svt_enc) -+{ -+ const size_t luma_size_8bit = -+ config->source_width * config->source_height; -+ const size_t luma_size_10bit = -+ (config->encoder_bit_depth > 8) ? luma_size_8bit : 0; -+ -+ EbSvtEncInput *in_data; -+ -+ svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2; -+ -+ // allocate buffer for in and out -+ svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf)); -+ if (!svt_enc->in_buf) -+ goto failed; -+ -+ -+ svt_enc->in_buf->p_buffer = (unsigned char *)av_mallocz(sizeof(*in_data)); -+ if (!svt_enc->in_buf->p_buffer) -+ goto failed; -+ -+ svt_enc->in_buf->size = sizeof(*svt_enc->in_buf); -+ svt_enc->in_buf->p_app_private = NULL; -+ -+ svt_enc->pool = av_buffer_pool_init(svt_enc->raw_size, NULL); -+ if (!svt_enc->pool) -+ goto failed; -+ -+ return 0; -+ -+failed: -+ free_buffer(svt_enc); -+ return AVERROR(ENOMEM); -+} -+ -+static int config_enc_params(EbSvtVp9EncConfiguration *param, -+ AVCodecContext *avctx) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ int ret; -+ int ten_bits = 0; -+ -+ param->source_width = avctx->width; -+ param->source_height = avctx->height; -+ -+ if (avctx->pix_fmt == AV_PIX_FMT_YUV420P10LE) { -+ av_log(avctx, AV_LOG_DEBUG , "Encoder 10 bits depth input\n"); -+ // Disable Compressed 10-bit format default -+ ten_bits = 1; -+ } -+ -+ // Update param from options -+ param->enc_mode = svt_enc->enc_mode; -+ param->level = svt_enc->level; -+ param->rate_control_mode = svt_enc->rc_mode; -+ param->tune = svt_enc->tune; -+ param->base_layer_switch_mode = svt_enc->base_layer_switch_mode; -+ param->qp = svt_enc->qp; -+ -+ param->target_bit_rate = avctx->bit_rate; -+ if (avctx->gop_size > 0) -+ param->intra_period = avctx->gop_size - 1; -+ -+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { -+ param->frame_rate_numerator = avctx->framerate.num; -+ param->frame_rate_denominator = avctx->framerate.den * avctx->ticks_per_frame; -+ } else { -+ param->frame_rate_numerator = avctx->time_base.den; -+ param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame; -+ } -+ -+ if (param->rate_control_mode) { -+ param->max_qp_allowed = avctx->qmax; -+ param->min_qp_allowed = avctx->qmin; -+ } -+ -+ if (ten_bits) { -+ param->encoder_bit_depth = 10; -+ } -+ -+ ret = alloc_buffer(param, svt_enc); -+ -+ return ret; -+} -+ -+static void read_in_data(EbSvtVp9EncConfiguration *config, -+ const AVFrame *frame, -+ EbBufferHeaderType *headerPtr) -+{ -+ uint8_t is16bit = config->encoder_bit_depth > 8; -+ uint64_t luma_size = -+ (uint64_t)config->source_width * config->source_height<< is16bit; -+ EbSvtEncInput *in_data = (EbSvtEncInput *)headerPtr->p_buffer; -+ -+ // support yuv420p and yuv420p010 -+ in_data->luma = frame->data[0]; -+ in_data->cb = frame->data[1]; -+ in_data->cr = frame->data[2]; -+ -+ // stride info -+ in_data->y_stride = frame->linesize[0] >> is16bit; -+ in_data->cb_stride = frame->linesize[1] >> is16bit; -+ in_data->cr_stride = frame->linesize[2] >> is16bit; -+ -+ headerPtr->n_filled_len += luma_size * 3/2u; -+} -+ -+static av_cold int eb_enc_init(AVCodecContext *avctx) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ EbErrorType svt_ret; -+ -+ svt_enc->eos_flag = EOS_NOT_REACHED; -+ -+ svt_ret = eb_vp9_svt_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params); -+ if (svt_ret != EB_ErrorNone) { -+ av_log(avctx, AV_LOG_ERROR, "Error init encoder handle\n"); -+ goto failed; -+ } -+ -+ svt_ret = config_enc_params(&svt_enc->enc_params, avctx); -+ if (svt_ret != EB_ErrorNone) { -+ av_log(avctx, AV_LOG_ERROR, "Error configure encoder parameters\n"); -+ goto failed_init_handle; -+ } -+ -+ svt_ret = eb_vp9_svt_enc_set_parameter(svt_enc->svt_handle, &svt_enc->enc_params); -+ if (svt_ret != EB_ErrorNone) { -+ av_log(avctx, AV_LOG_ERROR, "Error setting encoder parameters\n"); -+ goto failed_init_handle; -+ } -+ -+ svt_ret = eb_vp9_init_encoder(svt_enc->svt_handle); -+ if (svt_ret != EB_ErrorNone) { -+ av_log(avctx, AV_LOG_ERROR, "Error init encoder\n"); -+ goto failed_init_handle; -+ } -+ -+ svt_enc->frame = av_frame_alloc(); -+ if (!svt_enc->frame) -+ return AVERROR(ENOMEM); -+ -+ // if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { -+ // EbBufferHeaderType* headerPtr; -+ // headerPtr->size = sizeof(headerPtr); -+ // headerPtr->n_filled_len = 0; /* in/out */ -+ // headerPtr->p_buffer = av_malloc(10 * 1024 * 1024); -+ // headerPtr->n_alloc_len = (10 * 1024 * 1024); -+ // -+ // if (!headerPtr->p_buffer) { -+ // av_log(avctx, AV_LOG_ERROR, -+ // "Cannot allocate buffer size %d.\n", headerPtr->n_alloc_len); -+ // svt_ret = EB_ErrorInsufficientResources; -+ // goto failed_init_enc; -+ // } -+ // -+ // svt_ret = eb_svt_enc_stream_header(svt_enc->svt_handle, &headerPtr); -+ // if (svt_ret != EB_ErrorNone) { -+ // av_log(avctx, AV_LOG_ERROR, "Error when build stream header.\n"); -+ // av_freep(&headerPtr->p_buffer); -+ // goto failed_init_enc; -+ // } -+ // -+ // avctx->extradata_size = headerPtr->n_filled_len; -+ // avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); -+ // if (!avctx->extradata) { -+ // av_log(avctx, AV_LOG_ERROR, -+ // "Cannot allocate VP9 header of size %d.\n", avctx->extradata_size); -+ // av_freep(&headerPtr->p_buffer); -+ // svt_ret = EB_ErrorInsufficientResources; -+ // goto failed_init_enc; -+ // } -+ // memcpy(avctx->extradata, headerPtr->p_buffer, avctx->extradata_size); -+ // -+ // av_freep(&headerPtr->p_buffer); -+ // } -+ return 0; -+ -+//failed_init_enc: -+// eb_deinit_encoder(svt_enc->svt_handle); -+failed_init_handle: -+ eb_vp9_deinit_handle(svt_enc->svt_handle); -+failed: -+ free_buffer(svt_enc); -+ return error_mapping(svt_ret); -+} -+ -+static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ EbBufferHeaderType *headerPtr = svt_enc->in_buf; -+ -+ if (!frame) { -+ if (svt_enc->eos_flag == EOS_REACHED) -+ return 0; -+ -+ EbBufferHeaderType headerPtrLast; -+ headerPtrLast.n_alloc_len = 0; -+ headerPtrLast.n_filled_len = 0; -+ headerPtrLast.n_tick_count = 0; -+ headerPtrLast.p_app_private = NULL; -+ headerPtrLast.p_buffer = NULL; -+ headerPtrLast.flags = EB_BUFFERFLAG_EOS; -+ -+ eb_vp9_svt_enc_send_picture(svt_enc->svt_handle, &headerPtrLast); -+ svt_enc->eos_flag = EOS_REACHED; -+ av_log(avctx, AV_LOG_DEBUG, "Finish sending frames!!!\n"); -+ return 0; -+ } -+ -+ read_in_data(&svt_enc->enc_params, frame, headerPtr); -+ -+ headerPtr->flags = 0; -+ headerPtr->p_app_private = NULL; -+ headerPtr->pts = frame->pts; -+ switch (frame->pict_type) { -+ case AV_PICTURE_TYPE_I: -+ headerPtr->pic_type = svt_enc->forced_idr > 0 ? EB_IDR_PICTURE : EB_I_PICTURE; -+ break; -+ case AV_PICTURE_TYPE_P: -+ headerPtr->pic_type = EB_P_PICTURE; -+ break; -+ case AV_PICTURE_TYPE_B: -+ headerPtr->pic_type = EB_B_PICTURE; -+ break; -+ default: -+ headerPtr->pic_type = EB_INVALID_PICTURE; -+ break; -+ } -+ eb_vp9_svt_enc_send_picture(svt_enc->svt_handle, headerPtr); -+ -+ return 0; -+} -+ -+static int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ EbBufferHeaderType *headerPtr; -+ EbErrorType svt_ret; -+ AVBufferRef *ref; -+ -+ if (EOS_TOTRIGGER == svt_enc->eos_flag) { -+ pkt = NULL; -+ return AVERROR_EOF; -+ } -+ -+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 93, 100) -+ AVFrame *frame = svt_enc->frame; -+ int ret = ff_encode_get_frame(avctx, frame); -+ if (ret < 0 && ret != AVERROR_EOF) -+ return ret; -+ if (ret == AVERROR_EOF) -+ frame = NULL; -+ -+ eb_send_frame(avctx, frame); -+ av_frame_unref(svt_enc->frame); -+#endif -+ -+ svt_ret = eb_vp9_svt_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag); -+ if (svt_ret == EB_NoErrorEmptyQueue) -+ return AVERROR(EAGAIN); -+ -+ ref = av_buffer_pool_get(svt_enc->pool); -+ if (!ref) { -+ av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n"); -+ eb_vp9_svt_release_out_buffer(&headerPtr); -+ return AVERROR(ENOMEM); -+ } -+ pkt->buf = ref; -+ pkt->data = ref->data; -+ -+ memcpy(pkt->data, headerPtr->p_buffer, headerPtr->n_filled_len); -+ pkt->size = headerPtr->n_filled_len; -+ pkt->pts = headerPtr->pts; -+ pkt->dts = headerPtr->dts; -+ if (headerPtr->pic_type == EB_IDR_PICTURE) -+ pkt->flags |= AV_PKT_FLAG_KEY; -+ if (headerPtr->pic_type == EB_NON_REF_PICTURE) -+ pkt->flags |= AV_PKT_FLAG_DISPOSABLE; -+ -+ if (headerPtr->flags & EB_BUFFERFLAG_SHOW_EXT) -+ pkt->flags |= AV_PKT_FLAG_SVT_VP9_EXT_ON; -+ else -+ pkt->flags |= AV_PKT_FLAG_SVT_VP9_EXT_OFF; -+ -+ if (EB_BUFFERFLAG_EOS & headerPtr->flags) -+ svt_enc->eos_flag = EOS_TOTRIGGER; -+ -+ eb_vp9_svt_release_out_buffer(&headerPtr); -+ return 0; -+} -+ -+static av_cold int eb_enc_close(AVCodecContext *avctx) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ -+ eb_vp9_deinit_encoder(svt_enc->svt_handle); -+ eb_vp9_deinit_handle(svt_enc->svt_handle); -+ -+ av_frame_free(&svt_enc->frame); -+ -+ free_buffer(svt_enc); -+ -+ return 0; -+} -+ -+#define OFFSET(x) offsetof(SvtContext, x) -+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM -+static const AVOption options[] = { -+ { "preset", "Encoding preset [1, 1]", -+ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = 9 }, 0, 9, VE }, -+ -+ { "level", "Set level (level_idc)", OFFSET(level), -+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xff, VE, "level" }, -+ -+#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ -+ { .i64 = value }, 0, 0, VE, "level" -+ { LEVEL("1", 10) }, -+ { LEVEL("2", 20) }, -+ { LEVEL("2.1", 21) }, -+ { LEVEL("3", 30) }, -+ { LEVEL("3.1", 31) }, -+ { LEVEL("4", 40) }, -+ { LEVEL("4.1", 41) }, -+ { LEVEL("5", 50) }, -+ { LEVEL("5.1", 51) }, -+ { LEVEL("5.2", 52) }, -+ { LEVEL("6", 60) }, -+ { LEVEL("6.1", 61) }, -+ { LEVEL("6.2", 62) }, -+#undef LEVEL -+ -+ { "tune", "Tune mode", OFFSET(tune), -+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE , "tune"}, -+ { "vq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "tune" }, -+ { "ssim", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "tune" }, -+ { "vmaf", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "tune" }, -+ -+ { "rc", "Bit rate control mode", OFFSET(rc_mode), -+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, 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" }, -+ { "cbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "rc" }, -+ -+ { "qp", "QP value for intra frames", OFFSET(qp), -+ AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 51, 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 }, -1, 1, VE }, -+ -+ {NULL}, -+}; -+ -+static const AVClass class = { -+ .class_name = "libsvt_vp9", -+ .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" }, -+ { NULL }, -+}; -+ -+AVCodec ff_libsvt_vp9_encoder = { -+ .name = "libsvt_vp9", -+ .long_name = NULL_IF_CONFIG_SMALL("SVT-VP9(Scalable Video Technology for VP9) encoder"), -+ .priv_data_size = sizeof(SvtContext), -+ .type = AVMEDIA_TYPE_VIDEO, -+ .id = AV_CODEC_ID_VP9, -+ .init = eb_enc_init, -+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 93, 100) -+ .send_frame = eb_send_frame, -+#endif -+ .receive_packet = eb_receive_packet, -+ .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_NONE }, -+ .priv_class = &class, -+ .defaults = eb_enc_defaults, -+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, -+ .wrapper_name = "libsvt_vp9", -+}; -diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c -index dc3306a56a..13c8a92268 100644 ---- a/libavformat/dashenc.c -+++ b/libavformat/dashenc.c -@@ -2270,6 +2270,48 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) - return ret; - } - -+static int dash_write_packet_vp9(AVFormatContext *s, AVPacket *pkt) -+{ -+ int ret; -+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { -+ uint8_t *saved_data = pkt->data; -+ int saved_size = pkt->size; -+ int64_t saved_pts = pkt->pts; -+ -+ // Main frame -+ pkt->data = saved_data; -+ pkt->size = saved_size - 4; -+ pkt->pts = saved_pts; -+ ret = dash_write_packet(s, pkt); -+ -+ // Latter 4 one-byte repeated frames -+ pkt->data = saved_data + saved_size - 4; -+ pkt->size = 1; -+ pkt->pts = saved_pts - 2; -+ ret = dash_write_packet(s, pkt); -+ -+ pkt->data = saved_data + saved_size - 3; -+ pkt->size = 1; -+ pkt->pts = saved_pts - 1; -+ ret = dash_write_packet(s, pkt); -+ -+ pkt->data = saved_data + saved_size - 2; -+ pkt->size = 1; -+ pkt->pts = saved_pts; -+ ret = dash_write_packet(s, pkt); -+ -+ pkt->data = saved_data + saved_size - 1; -+ pkt->size = 1; -+ pkt->pts = saved_pts + 1; -+ ret = dash_write_packet(s, pkt); -+ } -+ else{ -+ ret = dash_write_packet(s, pkt); -+ } -+ -+ return ret; -+} -+ - static int dash_write_trailer(AVFormatContext *s) - { - DASHContext *c = s->priv_data; -@@ -2317,6 +2359,11 @@ static int dash_check_bitstream(struct AVFormatContext *s, const AVPacket *avpkt - DASHContext *c = s->priv_data; - OutputStream *os = &c->streams[avpkt->stream_index]; - AVFormatContext *oc = os->ctx; -+ -+ if ((avpkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || -+ (avpkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) -+ return 0; -+ - if (oc->oformat->check_bitstream) { - int ret; - AVPacket pkt = *avpkt; -@@ -2404,7 +2451,7 @@ AVOutputFormat ff_dash_muxer = { - .flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE | AVFMT_TS_NEGATIVE, - .init = dash_init, - .write_header = dash_write_header, -- .write_packet = dash_write_packet, -+ .write_packet = dash_write_packet_vp9, - .write_trailer = dash_write_trailer, - .deinit = dash_free, - .check_bitstream = dash_check_bitstream, -diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c -index 0951f56c92..3a49097e9a 100644 ---- a/libavformat/ivfenc.c -+++ b/libavformat/ivfenc.c -@@ -81,9 +81,33 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) - AVIOContext *pb = s->pb; - IVFEncContext *ctx = s->priv_data; - -- avio_wl32(pb, pkt->size); -- avio_wl64(pb, pkt->pts); -- avio_write(pb, pkt->data, pkt->size); -+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { -+ avio_wl32(pb, pkt->size - 4); -+ avio_wl64(pb, pkt->pts); -+ avio_write(pb, pkt->data, pkt->size - 4); -+ -+ avio_wl32(pb, 1); -+ avio_wl64(pb, pkt->pts - 2); -+ avio_write(pb, pkt->data + pkt->size - 4, 1); -+ -+ avio_wl32(pb, 1); -+ avio_wl64(pb, pkt->pts - 1); -+ avio_write(pb, pkt->data + pkt->size - 3, 1); -+ -+ avio_wl32(pb, 1); -+ avio_wl64(pb, pkt->pts); -+ avio_write(pb, pkt->data + pkt->size - 2, 1); -+ -+ avio_wl32(pb, 1); -+ avio_wl64(pb, pkt->pts + 1); -+ avio_write(pb, pkt->data + pkt->size - 1, 1); -+ } -+ else { -+ avio_wl32(pb, pkt->size); -+ avio_wl64(pb, pkt->pts); -+ avio_write(pb, pkt->data, pkt->size); -+ } -+ - if (ctx->frame_cnt) - ctx->sum_delta_pts += pkt->pts - ctx->last_pts; - ctx->frame_cnt++; -diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c -index 233c472b8f..00e6ccc8b5 100644 ---- a/libavformat/matroskaenc.c -+++ b/libavformat/matroskaenc.c -@@ -142,6 +142,9 @@ typedef struct MatroskaMuxContext { - unsigned nb_attachments; - int have_video; - -+ int simple_block_timecode; -+ int accumulated_cluster_timecode; -+ - int wrote_chapters; - int wrote_tags; - -@@ -2084,7 +2087,13 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb, - put_ebml_id(pb, blockid); - put_ebml_length(pb, size + track->track_num_size + 3, 0); - put_ebml_num(pb, track_number, track->track_num_size); -- avio_wb16(pb, ts - mkv->cluster_pts); -+ -+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || -+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) -+ avio_wb16(pb, mkv->simple_block_timecode); -+ else -+ avio_wb16(pb, ts - mkv->cluster_pts); -+ - avio_w8(pb, (blockid == MATROSKA_ID_SIMPLEBLOCK && keyframe) ? (1 << 7) : 0); - avio_write(pb, data + offset, size); - if (data != pkt->data) -@@ -2268,7 +2277,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) - return 0; - } - --static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt) -+static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) - { - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb; -@@ -2279,6 +2288,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt) - int ret; - int64_t ts = track->write_dts ? pkt->dts : pkt->pts; - int64_t relative_packet_pos; -+ double fps = 0; -+ int pts_interval = 0; - - if (ts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n"); -@@ -2296,6 +2307,11 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt) - } - } - -+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) { -+ fps = av_q2d(s->streams[pkt->stream_index]->avg_frame_rate); -+ pts_interval = 1000 / fps; -+ } -+ - if (mkv->cluster_pos == -1) { - ret = start_ebml_master_crc32(&mkv->cluster_bc, mkv); - if (ret < 0) -@@ -2313,7 +2329,67 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt) - relative_packet_pos = avio_tell(pb); - - if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) { -- ret = mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { -+ uint8_t *saved_data = pkt->data; -+ int saved_size = pkt->size; -+ int64_t saved_pts = pkt->pts; -+ // Main frame -+ pkt->data = saved_data; -+ pkt->size = saved_size - 4; -+ pkt->pts = saved_pts; -+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -+ -+ // Latter 4 one-byte repeated frames -+ pkt->data = saved_data + saved_size - 4; -+ pkt->size = 1; -+ pkt->pts = saved_pts - 2; -+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -+ mkv->simple_block_timecode += pts_interval; -+ -+ pkt->data = saved_data + saved_size - 3; -+ pkt->size = 1; -+ pkt->pts = saved_pts - 1; -+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -+ mkv->simple_block_timecode += pts_interval; -+ -+ pkt->data = saved_data + saved_size - 2; -+ pkt->size = 1; -+ pkt->pts = saved_pts; -+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -+ mkv->simple_block_timecode += pts_interval; -+ -+ pkt->data = saved_data + saved_size - 1; -+ pkt->size = 1; -+ pkt->pts = saved_pts + 1; -+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -+ mkv->simple_block_timecode += pts_interval; -+ } else { -+ ret = mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); -+ if (ret < 0) return ret; -+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF) { -+ GetBitContext gb; -+ int invisible, profile; -+ -+ if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0) -+ return ret; -+ -+ get_bits(&gb, 2); // frame marker -+ profile = get_bits1(&gb); -+ profile |= get_bits1(&gb) << 1; -+ if (profile == 3) profile += get_bits1(&gb); -+ -+ if (get_bits1(&gb)) { -+ invisible = 0; -+ } else { -+ get_bits1(&gb); // keyframe -+ invisible = !get_bits1(&gb); -+ } -+ -+ if (!invisible) -+ mkv->simple_block_timecode += pts_interval; -+ } -+ } -+ - if (ret < 0) - return ret; - if (keyframe && IS_SEEKABLE(s->pb, mkv) && -@@ -2377,8 +2453,14 @@ static int mkv_write_packet(AVFormatContext *s, const AVPacket *pkt) - if (mkv->cluster_pos != -1) { - if (mkv->tracks[pkt->stream_index].write_dts) - cluster_time = pkt->dts - mkv->cluster_pts; -- else -- cluster_time = pkt->pts - mkv->cluster_pts; -+ else { -+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || -+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) -+ cluster_time = mkv->accumulated_cluster_timecode - mkv->cluster_pts; -+ else -+ cluster_time = pkt->pts - mkv->cluster_pts; -+ } -+ - cluster_time += mkv->tracks[pkt->stream_index].ts_offset; - - cluster_size = avio_tell(mkv->cluster_bc); -@@ -2402,7 +2484,13 @@ static int mkv_write_packet(AVFormatContext *s, const AVPacket *pkt) - start_new_cluster = 0; - - if (start_new_cluster) { -- ret = mkv_end_cluster(s); -+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || -+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) { -+ // Reset Timecode for new cluster. -+ mkv->accumulated_cluster_timecode += mkv->simple_block_timecode; -+ mkv->simple_block_timecode = 0; -+ } -+ ret = mkv_end_cluster(s); - if (ret < 0) - return ret; - } -@@ -2739,6 +2827,10 @@ static int mkv_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) - int ret = 1; - AVStream *st = s->streams[pkt->stream_index]; - -+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || -+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) -+ return 0; -+ - if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { - if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) - ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL); -diff --git a/libavformat/movenc.c b/libavformat/movenc.c -index 7db2e28840..a1f0b3a943 100644 ---- a/libavformat/movenc.c -+++ b/libavformat/movenc.c -@@ -5853,7 +5853,43 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) - } - } - -- return ff_mov_write_packet(s, pkt); -+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { -+ uint8_t *saved_data = pkt->data; -+ int saved_size = pkt->size; -+ int64_t saved_pts = pkt->pts; -+ -+ // Main frame -+ pkt->data = saved_data; -+ pkt->size = saved_size - 4; -+ pkt->pts = saved_pts; -+ ret = ff_mov_write_packet(s, pkt); -+ -+ // Latter 4 one-byte repeated frames -+ pkt->data = saved_data + saved_size - 4; -+ pkt->size = 1; -+ pkt->pts = saved_pts - 2; -+ ret = ff_mov_write_packet(s, pkt); -+ -+ pkt->data = saved_data + saved_size - 3; -+ pkt->size = 1; -+ pkt->pts = saved_pts - 1; -+ ret = ff_mov_write_packet(s, pkt); -+ -+ pkt->data = saved_data + saved_size - 2; -+ pkt->size = 1; -+ pkt->pts = saved_pts; -+ ret = ff_mov_write_packet(s, pkt); -+ -+ pkt->data = saved_data + saved_size - 1; -+ pkt->size = 1; -+ pkt->pts = saved_pts + 1; -+ ret = ff_mov_write_packet(s, pkt); -+ } -+ else{ -+ ret = ff_mov_write_packet(s, pkt); -+ } -+ -+ return ret; - } - - static int mov_write_subtitle_end_packet(AVFormatContext *s, -@@ -7013,6 +7049,10 @@ static int mov_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) - int ret = 1; - AVStream *st = s->streams[pkt->stream_index]; - -+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || -+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) -+ return 0; -+ - if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { - if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) - ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL); --- -2.17.1 - diff --git a/ffmpeg/custom/PKGBUILD b/ffmpeg/custom/PKGBUILD index 8faa27a7..2fa981be 100644 --- a/ffmpeg/custom/PKGBUILD +++ b/ffmpeg/custom/PKGBUILD @@ -9,8 +9,8 @@ _name=ffmpeg pkgname=ffmpeg-custom -pkgver=4.4 -pkgrel=2 +pkgver=4.4.1 +pkgrel=1 epoch=1 pkgdesc='Complete solution to record, convert and stream audio and video (with more features enabled than regular ffmpeg)' arch=('x86_64') @@ -111,13 +111,15 @@ provides=( ) conflicts=("$_name") -_tag=dc91b913b6260e85e1304c74ff7bb3c22a8c9fb1 +_tag=7e0d640edf6c3eee1816b105c2f7498c4f948e74 source=( git+https://git.ffmpeg.org/ffmpeg.git#tag=${_tag} 'vmaf-model-path.patch' ) -sha256sums=('SKIP' - '8dff51f84a5f7460f8893f0514812f5d2bd668c3276ef7ab7713c99b71d7bd8d') +sha256sums=( + 'SKIP' + '8dff51f84a5f7460f8893f0514812f5d2bd668c3276ef7ab7713c99b71d7bd8d' +) #pkgver() { # cd ffmpeg