diff options
-rw-r--r-- | .SRCINFO | 14 | ||||
-rw-r--r-- | 015-ffmpeg-cuda11-fix.patch | 2 | ||||
-rw-r--r-- | 020-ffmpeg-add-svt-hevc.patch | 637 | ||||
-rw-r--r-- | 040-ffmpeg-add-svt-vp9.patch | 919 | ||||
-rw-r--r-- | PKGBUILD | 28 |
5 files changed, 658 insertions, 942 deletions
@@ -1,6 +1,6 @@ pkgbase = ffmpeg-full-git pkgdesc = Complete solution to record, convert and stream audio and video (all possible features including libfdk-aac; git version) - pkgver = 4.5.r101969.g6c65e49990 + pkgver = 4.5.r102179.gab38a48c48 pkgrel = 1 url = https://www.ffmpeg.org/ arch = x86_64 @@ -65,7 +65,6 @@ pkgbase = ffmpeg-full-git depends = svt-hevc depends = svt-av1 depends = svt-vp9 - depends = tensorflow depends = tesseract depends = libtheora depends = twolame @@ -125,7 +124,6 @@ pkgbase = ffmpeg-full-git provides = libavformat.so provides = libavutil.so provides = libpostproc.so - provides = libavresample.so provides = libswscale.so provides = libswresample.so provides = ffmpeg @@ -135,16 +133,16 @@ pkgbase = ffmpeg-full-git source = git+https://git.ffmpeg.org/ffmpeg.git source = 010-ffmpeg-fix-vmaf-model-path.patch source = 015-ffmpeg-cuda11-fix.patch - source = 020-ffmpeg-add-svt-hevc-g33ca9aa.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/33ca9aa8a2a2d28022d3fc03704e99ce01828376/ffmpeg_plugin/0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch + source = 020-ffmpeg-add-svt-hevc.patch source = 030-ffmpeg-add-svt-hevc-docs-g33ca9aa.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/33ca9aa8a2a2d28022d3fc03704e99ce01828376/ffmpeg_plugin/0002-doc-Add-libsvt_hevc-encoder-docs.patch - source = 040-ffmpeg-add-svt-vp9.patch + source = 040-ffmpeg-add-svt-vp9-g34c8398.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-VP9/34c8398e097cb775477b7576e9338f3cf51a5c63/ffmpeg_plugin/master-0001-Add-ability-for-ffmpeg-to-run-svt-vp9.patch source = LICENSE sha256sums = SKIP sha256sums = 52778c70d9fe6e3a10941b99b96ac7749cec325dc1b9ee11ab75332b5ff68e50 - sha256sums = e096996903d4e19348fabe9c61923678cbadf57299cd03809c9e06065d6ffbe2 - sha256sums = 740dc9838aa47daa9f9b107178e53e384344f4c6f90865bd7e3af189257da544 + sha256sums = de0eeda63c2b0adf185e8c96e15872940cb8cfae5dd7590d593f56ef2c7db09d + sha256sums = e65cef16604e699e56041b1c76cca13ed6719525badd62d8f001b782d75f1917 sha256sums = 1499e419dda72b1604dc5e3959668f3843292ff56bfba78734e31510ba576de0 - sha256sums = ab62715392cb1aee475a95bbe4d4205552fe23e5dd50b85ca7be72a8fcd9fbfe + sha256sums = 5096f89ad10041a2013cfbf1224af3b7303d4c3295f1b225f7f3d0184027a635 sha256sums = 04a7176400907fd7db0d69116b99de49e582a6e176b3bfb36a03e50a4cb26a36 pkgname = ffmpeg-full-git diff --git a/015-ffmpeg-cuda11-fix.patch b/015-ffmpeg-cuda11-fix.patch index b1b7ebab499a..23ec5c0c4126 100644 --- a/015-ffmpeg-cuda11-fix.patch +++ b/015-ffmpeg-cuda11-fix.patch @@ -1,6 +1,6 @@ --- a/configure +++ b/configure -@@ -4351,10 +4351,10 @@ fi +@@ -4344,10 +4344,10 @@ fi if enabled cuda_nvcc; then nvcc_default="nvcc" diff --git a/020-ffmpeg-add-svt-hevc.patch b/020-ffmpeg-add-svt-hevc.patch new file mode 100644 index 000000000000..17699073b3ee --- /dev/null +++ b/020-ffmpeg-add-svt-hevc.patch @@ -0,0 +1,637 @@ +--- a/configure ++++ b/configure +@@ -288,6 +288,7 @@ External library support: + --enable-libwebp enable WebP encoding via libwebp [no] + --enable-libx264 enable H.264 encoding via x264 [no] + --enable-libx265 enable HEVC encoding via x265 [no] ++ --enable-libsvthevc enable HEVC encoding via svt [no] + --enable-libxavs enable AVS encoding via xavs [no] + --enable-libxavs2 enable AVS2 encoding via xavs2 [no] + --enable-libxcb enable X11 grabbing using XCB [autodetect] +@@ -1763,6 +1764,7 @@ EXTERNAL_LIBRARY_LIST=" + gnutls + jni + ladspa ++ libsvthevc + libaom + libass + libbluray +@@ -3286,6 +3288,7 @@ libx264_encoder_select="atsc_a53" + libx264rgb_encoder_deps="libx264 x264_csp_bgr" + libx264rgb_encoder_select="libx264_encoder" + libx265_encoder_deps="libx265" ++libsvt_hevc_encoder_deps="libsvthevc" + libxavs_encoder_deps="libxavs" + libxavs2_encoder_deps="libxavs2" + libxvid_encoder_deps="libxvid" +@@ -6491,6 +6494,7 @@ enabled mmal && { check_lib mmal interface/mmal/mmal.h mmal_port_co + check_lib mmal interface/mmal/mmal.h mmal_port_connect -lmmal_core -lmmal_util -lmmal_vc_client -lbcm_host; } || + die "ERROR: mmal not found" && + check_func_headers interface/mmal/mmal.h "MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS"; } ++enabled libsvthevc && require_pkg_config libsvthevc SvtHevcEnc EbApi.h EbInitHandle + enabled openal && { { for al_extralibs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do + check_lib openal 'AL/al.h' alGetError "${al_extralibs}" && break; done } || + die "ERROR: openal not found"; } && +--- a/libavcodec/Makefile ++++ b/libavcodec/Makefile +@@ -1063,6 +1063,7 @@ OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_anim + OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o + OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o + OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o ++OBJS-$(CONFIG_LIBSVT_HEVC_ENCODER) += libsvt_hevc.o + OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o + OBJS-$(CONFIG_LIBXAVS2_ENCODER) += libxavs2.o + OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o +--- a/libavcodec/allcodecs.c ++++ b/libavcodec/allcodecs.c +@@ -772,6 +772,7 @@ extern const AVCodec ff_libx264_encoder; + #endif + extern const AVCodec ff_libx264rgb_encoder; + extern AVCodec ff_libx265_encoder; ++extern AVCodec ff_libsvt_hevc_encoder; + extern const AVCodec ff_libxavs_encoder; + extern const AVCodec ff_libxavs2_encoder; + extern const AVCodec ff_libxvid_encoder; +new file mode 100644 +index 0000000000..95d6c35c88 +--- /dev/null ++++ b/libavcodec/libsvt_hevc.c +@@ -0,0 +1,578 @@ ++/* ++* 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; ++ int pred_struct; ++ int vid_info; ++} 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; ++ } ++ ++ if(svt_enc->pred_struct >= 0 && svt_enc->pred_struct <= 2) { ++ param->predStructure = svt_enc->pred_struct; ++ } else { ++ av_log(avctx, AV_LOG_ERROR, "Pred Structure should between 0-2\n"); ++ return EB_ErrorBadParameter; ++ } ++ ++ if(svt_enc->vid_info == 0 || svt_enc->vid_info == 1) { ++ param->videoUsabilityInfo = svt_enc->vid_info; ++ } else { ++ av_log(avctx, AV_LOG_ERROR, "Video Usability Info 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 }, ++ { "pred_struct", "The prediction structure", OFFSET(pred_struct), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 2, VE }, ++ { "vid_info", "Enables or disables sending a vui structure in the HEVC Elementary bitstream.", OFFSET(vid_info), ++ 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", ++}; diff --git a/040-ffmpeg-add-svt-vp9.patch b/040-ffmpeg-add-svt-vp9.patch deleted file mode 100644 index 9937f75b5bfa..000000000000 --- a/040-ffmpeg-add-svt-vp9.patch +++ /dev/null @@ -1,919 +0,0 @@ ---- a/configure -+++ b/configure -@@ -286,6 +286,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-libwebp enable WebP encoding via libwebp [no] - --enable-libx264 enable H.264 encoding via x264 [no] - --enable-libx265 enable HEVC encoding via x265 [no] -@@ -1803,6 +1804,7 @@ EXTERNAL_LIBRARY_LIST=" - librtmp - libshine - libsmbclient -+ libsvtvp9 - libsnappy - libsoxr - libspeex -@@ -3283,6 +3285,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" - libwebp_encoder_deps="libwebp" - libwebp_anim_encoder_deps="libwebp" - libx262_encoder_deps="libx262" -@@ -6468,6 +6471,7 @@ enabled libvpx && { - fi - } - -+enabled libsvtvp9 && require_pkg_config libsvtvp9 SvtVp9Enc EbSvtVp9Enc.h eb_vp9_svt_init_handle - enabled libwebp && { - enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion - enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; } ---- a/libavcodec/Makefile -+++ b/libavcodec/Makefile -@@ -1065,6 +1065,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_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o - OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o - OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o ---- a/libavcodec/allcodecs.c -+++ b/libavcodec/allcodecs.c -@@ -758,6 +758,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; - /* preferred over libwebp */ - extern AVCodec ff_libwebp_anim_encoder; - extern AVCodec ff_libwebp_encoder; ---- 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. -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 <stdint.h> -+#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", -+}; ---- a/libavformat/dashenc.c -+++ b/libavformat/dashenc.c -@@ -2271,6 +2271,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; -@@ -2318,6 +2360,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; -@@ -2405,7 +2452,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, ---- 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->last_pkt_duration = pkt->duration; ---- 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; - -@@ -2108,7 +2111,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) -@@ -2301,7 +2310,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; -@@ -2312,6 +2321,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"); -@@ -2329,6 +2340,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) -@@ -2347,7 +2363,67 @@ static int mkv_write_packet_internal(AVFormatContext *s, const AVPacket *pkt) - - if (par->codec_type != AVMEDIA_TYPE_SUBTITLE || - (par->codec_id != AV_CODEC_ID_WEBVTT && duration <= 0)) { -- 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) && -@@ -2415,8 +2491,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); -@@ -2440,7 +2522,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; - } -@@ -2780,6 +2868,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); ---- a/libavformat/movenc.c -+++ b/libavformat/movenc.c -@@ -5978,7 +5978,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, -@@ -7165,6 +7201,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); @@ -1,7 +1,7 @@ # Maintainer: Daniel Bermond <dbermond@archlinux.org> pkgname=ffmpeg-full-git -pkgver=4.5.r101969.g6c65e49990 +pkgver=4.5.r102179.gab38a48c48 pkgrel=1 pkgdesc='Complete solution to record, convert and stream audio and video (all possible features including libfdk-aac; git version)' arch=('x86_64') @@ -16,7 +16,7 @@ depends=( 'libiec61883' 'libilbc' 'jack' 'kvazaar' 'libmodplug' 'lame' 'opencore-amr' 'openjpeg2' 'opus' 'libpulse' 'librabbitmq-c' 'rav1e' 'librsvg' 'rubberband' 'rtmpdump' 'smbclient' 'snappy' 'libsoxr' 'speex' 'srt' 'libssh' - 'svt-hevc' 'svt-av1' 'svt-vp9' 'tensorflow' 'tesseract' 'libtheora' 'twolame' + 'svt-hevc' 'svt-av1' 'svt-vp9' 'tesseract' 'libtheora' 'twolame' 'v4l-utils' 'vid.stab' 'vmaf' 'libvorbis' 'libvpx' 'libwebp' 'x264' 'x265' 'libxcb' 'xvidcore' 'libxml2' 'zimg' 'zeromq' 'zvbi' 'lv2' 'lilv' 'xz' 'libmysofa' 'openal' 'ocl-icd' 'libgl' 'sndio' 'sdl2' 'vapoursynth' @@ -35,23 +35,24 @@ makedepends=( 'decklink-sdk' ) provides=('libavcodec.so' 'libavdevice.so' 'libavfilter.so' 'libavformat.so' - 'libavutil.so' 'libpostproc.so' 'libavresample.so' 'libswscale.so' - 'libswresample.so' 'ffmpeg' 'ffmpeg-full' 'ffmpeg-git') + 'libavutil.so' 'libpostproc.so' 'libswscale.so' 'libswresample.so' + 'ffmpeg' 'ffmpeg-full' 'ffmpeg-git') conflicts=('ffmpeg') _svt_hevc_ver='33ca9aa8a2a2d28022d3fc03704e99ce01828376' +_svt_vp9_ver='34c8398e097cb775477b7576e9338f3cf51a5c63' source=('git+https://git.ffmpeg.org/ffmpeg.git' '010-ffmpeg-fix-vmaf-model-path.patch' '015-ffmpeg-cuda11-fix.patch' - "020-ffmpeg-add-svt-hevc-g${_svt_hevc_ver:0:7}.patch"::"https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/${_svt_hevc_ver}/ffmpeg_plugin/0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch" + '020-ffmpeg-add-svt-hevc.patch' "030-ffmpeg-add-svt-hevc-docs-g${_svt_hevc_ver:0:7}.patch"::"https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/${_svt_hevc_ver}/ffmpeg_plugin/0002-doc-Add-libsvt_hevc-encoder-docs.patch" - '040-ffmpeg-add-svt-vp9.patch' + "040-ffmpeg-add-svt-vp9-g${_svt_vp9_ver:0:7}.patch"::"https://raw.githubusercontent.com/OpenVisualCloud/SVT-VP9/${_svt_vp9_ver}/ffmpeg_plugin/master-0001-Add-ability-for-ffmpeg-to-run-svt-vp9.patch" 'LICENSE') sha256sums=('SKIP' '52778c70d9fe6e3a10941b99b96ac7749cec325dc1b9ee11ab75332b5ff68e50' - 'e096996903d4e19348fabe9c61923678cbadf57299cd03809c9e06065d6ffbe2' - '740dc9838aa47daa9f9b107178e53e384344f4c6f90865bd7e3af189257da544' + 'de0eeda63c2b0adf185e8c96e15872940cb8cfae5dd7590d593f56ef2c7db09d' + 'e65cef16604e699e56041b1c76cca13ed6719525badd62d8f001b782d75f1917' '1499e419dda72b1604dc5e3959668f3843292ff56bfba78734e31510ba576de0' - 'ab62715392cb1aee475a95bbe4d4205552fe23e5dd50b85ca7be72a8fcd9fbfe' + '5096f89ad10041a2013cfbf1224af3b7303d4c3295f1b225f7f3d0184027a635' '04a7176400907fd7db0d69116b99de49e582a6e176b3bfb36a03e50a4cb26a36') prepare() { @@ -59,9 +60,9 @@ prepare() { sed -i 's/general.texi/general_contents.texi/g' "030-ffmpeg-add-svt-hevc-docs-g${_svt_hevc_ver:0:7}.patch" patch -d ffmpeg -Np1 -i "${srcdir}/010-ffmpeg-fix-vmaf-model-path.patch" patch -d ffmpeg -Np1 -i "${srcdir}/015-ffmpeg-cuda11-fix.patch" - patch -d ffmpeg -Np1 -i "${srcdir}/020-ffmpeg-add-svt-hevc-g${_svt_hevc_ver:0:7}.patch" + patch -d ffmpeg -Np1 -i "${srcdir}/020-ffmpeg-add-svt-hevc.patch" patch -d ffmpeg -Np1 -i "${srcdir}/030-ffmpeg-add-svt-hevc-docs-g${_svt_hevc_ver:0:7}.patch" - patch -d ffmpeg -Np1 -i "${srcdir}/040-ffmpeg-add-svt-vp9.patch" + patch -d ffmpeg -Np1 -i "${srcdir}/040-ffmpeg-add-svt-vp9-g${_svt_vp9_ver:0:7}.patch" } pkgver() { @@ -76,7 +77,7 @@ build() { ./configure \ --prefix='/usr' \ - --extra-cflags='-I/opt/cuda/include -I/usr/include/tensorflow' \ + --extra-cflags='-I/opt/cuda/include' \ --extra-ldflags='-L/opt/cuda/lib64' \ --enable-lto \ \ @@ -88,7 +89,6 @@ build() { --disable-static \ --disable-stripping \ --enable-gray \ - --enable-avresample \ \ --enable-alsa \ --enable-avisynth \ @@ -152,7 +152,7 @@ build() { --enable-libssh \ --enable-libsvthevc \ --enable-libsvtav1 \ - --enable-libtensorflow \ + --disable-libtensorflow \ --enable-libtesseract \ --enable-libtheora \ --disable-libtls \ |