diff --git a/.SRCINFO b/.SRCINFO index 2b24bde..d35e5c8 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,7 +1,7 @@ pkgbase = ffmpeg-full pkgdesc = Complete solution to record, convert and stream audio and video (all possible features including libfdk-aac) pkgver = 8.0.1 - pkgrel = 2 + pkgrel = 3 url = https://ffmpeg.org/ arch = x86_64 license = LicenseRef-nonfree-and-unredistributable @@ -154,8 +154,8 @@ pkgbase = ffmpeg-full source = git+https://github.com/lensfun/lensfun.git source = https://github.com/ggml-org/whisper.cpp/archive/v1.8.2/whisper.cpp-1.8.2.tar.gz source = 010-ffmpeg-add-svt-hevc.patch - source = 020-ffmpeg-add-svt-hevc-docs-ged80959.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/ed80959ebb5586aa7763c91a397d44be1798587c/ffmpeg_plugin/0002-doc-Add-libsvt_hevc-encoder-docs.patch - source = 030-ffmpeg-add-svt-vp9.patch + source = 020-ffmpeg-add-svt-hevc-docs-g4181c9e.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/4181c9ee0611baefb40b4c0ed10023cfd837d522/ffmpeg_plugin/0002-doc-Add-libsvt_hevc-encoder-docs.patch + source = 030-ffmpeg-add-svt-vp9-g290fb8c.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-VP9/290fb8c3662ed76a8887b587a9b8201878ba71ed/ffmpeg_plugin/master-0001-Add-ability-for-ffmpeg-to-run-svt-vp9.patch source = 040-ffmpeg-add-av_stream_get_first_dts-for-chromium.patch source = 050-ffmpeg-fix-cuda-nvcc-with-gcc14.patch source = 060-ffmpeg-whisper.cpp-fix-pkgconfig.patch @@ -171,7 +171,7 @@ pkgbase = ffmpeg-full sha256sums = bcee25589bb8052d9e155369f6759a05729a2022d2a8085c1aa4345108523077 sha256sums = ccdc1cab97d1fe5a454cd57fbd2bb865256092d715fd7f380c30cc3f42891b3c sha256sums = a164ebdc4d281352bf7ad1b179aae4aeb33f1191c444bed96cb8ab333c046f81 - sha256sums = 60bfff3c6bf3c2f1ca674b051b4d1b40f5686087555d1bdde82fa37102e5a801 + sha256sums = 1f06dfcb78e43a6c732cbc4f6ae583ae19fb111b56d33c8c860d5b6566c04f99 sha256sums = 5cb2475de410f5696072687af88e91461cdacd1bb636ac14a3b348e3383934f1 sha256sums = 9f3d84b3abe1077b3d6c1a25f36dcddf6419a7fe3217a4edd52aab6f0e4cd838 sha256sums = 98b3d28cbd13bb575c602785f6b8cb0b66ea3128ab5a3a82fc1645822320c136 diff --git a/030-ffmpeg-add-svt-vp9.patch b/030-ffmpeg-add-svt-vp9.patch deleted file mode 100644 index ebcc266..0000000 --- a/030-ffmpeg-add-svt-vp9.patch +++ /dev/null @@ -1,764 +0,0 @@ ---- a/configure -+++ b/configure -@@ -294,6 +294,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-libvvenc enable H.266/VVC encoding via vvenc [no] - --enable-libwebp enable WebP encoding via libwebp [no] - --enable-libx264 enable H.264 encoding via x264 [no] -@@ -1991,6 +1992,7 @@ EXTERNAL_LIBRARY_LIST=" - libvmaf - libvorbis - libvpx -+ libsvtvp9 - libvvenc - libwebp - libxevd -@@ -3660,6 +3662,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" - libvvenc_encoder_deps="libvvenc" - libwebp_encoder_deps="libwebp" - libwebp_anim_encoder_deps="libwebp" -@@ -7199,6 +7202,7 @@ enabled libvpx && { - fi - } - -+enabled libsvtvp9 && require_pkg_config libsvtvp9 SvtVp9Enc EbSvtVp9Enc.h eb_vp9_svt_init_handle - enabled libvvenc && require_pkg_config libvvenc "libvvenc >= 1.6.1" "vvenc/vvenc.h" vvenc_get_version - enabled libwebp && { - enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion ---- a/libavcodec/Makefile -+++ b/libavcodec/Makefile -@@ -1195,6 +1195,7 @@ OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o - OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o - OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o - OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o -+OBJS-$(CONFIG_LIBSVT_VP9_ENCODER) += libsvt_vp9.o - OBJS-$(CONFIG_LIBVVENC_ENCODER) += libvvenc.o - OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o - OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o ---- a/libavcodec/allcodecs.c -+++ b/libavcodec/allcodecs.c -@@ -813,6 +813,7 @@ extern const FFCodec ff_libvpx_vp8_encoder; - extern const FFCodec ff_libvpx_vp8_decoder; - extern FFCodec ff_libvpx_vp9_encoder; - extern const FFCodec ff_libvpx_vp9_decoder; -+extern const FFCodec ff_libsvt_vp9_encoder; - extern const FFCodec ff_libvvenc_encoder; - /* preferred over libwebp */ - extern const FFCodec ff_libwebp_anim_encoder; ---- /dev/null -+++ b/libavcodec/libsvt_vp9.c -@@ -0,0 +1,707 @@ -+/* -+* 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 "libavutil/mem.h" -+#include "libavcodec/get_bits.h" -+#include "libavcodec/version.h" -+ -+#include "codec_internal.h" -+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 93, 100) -+#include "encode.h" -+#endif -+ -+#include "avcodec.h" -+ -+#define SUPERFRAME_INDEX_MAX_SIZE 128 -+ -+#define RECIVED_FRAMES_MAX_SIZE 32 -+#define MAX_VP9_SUPERFRAME_SIZE 8 -+ -+typedef enum eos_status { -+ EOS_NOT_REACHED = 0, -+ EOS_REACHED, -+ EOS_TOTRIGGER -+}EOS_STATUS; -+ -+typedef struct SvtReceivedFrameStruct { -+ // fields for AVPacket -+ AVBufferRef *buf; -+ int64_t pts; -+ int64_t dts; -+ int size; -+ int flags; -+ -+ // svt fields: -+ int ready_flag; // frame or superframe in data is visible -+ int frames_count; -+ int frames_sizes[MAX_VP9_SUPERFRAME_SIZE]; -+} SvtReceivedFrameStruct; -+ -+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 target_socket; -+ -+ int forced_idr; -+ -+ int level; -+ -+ int base_layer_switch_mode; -+ -+ -+ int64_t last_ready_dts; -+ SvtReceivedFrameStruct received_frames[RECIVED_FRAMES_MAX_SIZE]; -+ int received_frames_size; -+} 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) * MAX_VP9_SUPERFRAME_SIZE + SUPERFRAME_INDEX_MAX_SIZE; -+ -+ // 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; -+ -+ svt_enc->received_frames_size = 0; -+ svt_enc->last_ready_dts = -1e9; -+ -+ 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_socket = svt_enc->target_socket; -+ 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; -+ } else { -+ param->frame_rate_numerator = avctx->time_base.den; -+ param->frame_rate_denominator = avctx->time_base.num; -+ } -+ -+ 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 is_frame_visible(uint8_t const* ptr, int size) { -+ GetBitContext gb; -+ int ret, visible, profile; -+ if ((ret = init_get_bits8(&gb, ptr, size)) < 0) { -+ return ret; -+ } -+ -+ // frame marker -+ get_bits(&gb, 2); -+ profile = get_bits1(&gb); -+ profile |= get_bits1(&gb) << 1; -+ -+ // reserved_zero -+ if (profile == 3) profile += get_bits1(&gb); // reserved_zero -+ -+ // read show_existing_frame -+ if (get_bits1(&gb)) { -+ // show_existing_frame == 1 -+ visible = 1; -+ } else { -+ // show_existing_frame == 0 -+ // keyframe (frame_type actually) -+ get_bits1(&gb); -+ // read show_frame -+ visible = get_bits1(&gb) ? 2 : 0; -+ } -+ -+ return visible; -+} -+ -+static int get_received_frame(SvtContext *svt_enc, AVPacket *pkt) { -+ SvtReceivedFrameStruct* rfs = &svt_enc->received_frames[0]; -+ -+ if (svt_enc->received_frames_size == 0 || !rfs->ready_flag) { -+ return AVERROR(EAGAIN); -+ } -+ -+ pkt->buf = rfs->buf; -+ pkt->data = rfs->buf->data; -+ pkt->dts = rfs->dts; -+ pkt->pts = rfs->pts; -+ pkt->flags = rfs->flags; -+ pkt->size = rfs->size; -+ -+ --svt_enc->received_frames_size; -+ for (int i = 0; i < svt_enc->received_frames_size; ++i) { -+ svt_enc->received_frames[i] = svt_enc->received_frames[i + 1]; -+ } -+ -+ return 0; -+} -+ -+static int put_received_frame(AVCodecContext *avctx, uint8_t* data, int size, int keyframe, int64_t dts, int64_t pts) { -+ SvtContext *svt_enc = avctx->priv_data; -+ SvtReceivedFrameStruct* rfs; -+ -+ if (svt_enc->received_frames_size == 0 || svt_enc->received_frames[svt_enc->received_frames_size - 1].ready_flag) { -+ ++svt_enc->received_frames_size; -+ if (svt_enc->received_frames_size > RECIVED_FRAMES_MAX_SIZE) { -+ av_log(avctx, AV_LOG_ERROR, "Fail: svt_enc->received_frames_size > RECIVED_FRAMES_MAX_SIZE \n"); -+ return AVERROR_BUG; -+ } -+ -+ rfs = &svt_enc->received_frames[svt_enc->received_frames_size - 1]; -+ -+ rfs->buf = av_buffer_pool_get(svt_enc->pool); -+ if (!rfs->buf) { -+ av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n"); -+ return AVERROR(ENOMEM); -+ } -+ -+ rfs->size = 0; -+ rfs->flags = 0; -+ rfs->ready_flag = 0; -+ rfs->frames_count = 0; -+ } else { -+ rfs = &svt_enc->received_frames[svt_enc->received_frames_size - 1]; -+ } -+ -+ rfs->pts = pts; -+ rfs->dts = dts; -+ rfs->flags = (keyframe ? AV_PKT_FLAG_KEY : 0); -+ -+ ++rfs->frames_count; -+ if (rfs->frames_count > MAX_VP9_SUPERFRAME_SIZE) { -+ av_log(avctx, AV_LOG_ERROR, "Fail: rfs->frames_count > MAX_VP9_SUPERFRAME_SIZE \n"); -+ return AVERROR_BUG; -+ } -+ -+ rfs->frames_sizes[rfs->frames_count - 1] = size; -+ -+ memcpy(rfs->buf->data + rfs->size, data, size); -+ rfs->size += size; -+ -+ int visible = is_frame_visible(data, size); -+ if (visible < 0) { -+ av_log(avctx, AV_LOG_ERROR, "Fail: is_frame_visible \n"); -+ return visible; -+ } -+ -+ -+ rfs->ready_flag = visible; -+ -+ if (rfs->ready_flag) { -+ if (rfs->dts <= svt_enc->last_ready_dts) { -+ rfs->dts = svt_enc->last_ready_dts + 1; -+ } -+ svt_enc->last_ready_dts = rfs->dts; -+ -+ } -+ -+ // add superframe_index if needed -+ if (rfs->ready_flag && rfs->frames_count > 1) { -+ // superframe_header: -+ // 110 - superframe_marker -+ // 11 = 3 = bytes_per_framesize_minus_1 - use 4-bytes size -+ // xxx = frames_in_superframe_minus_1 -+ uint8_t header = 0b11011000; -+ header |= (rfs->frames_count - 1) & 0b111; -+ -+ uint8_t* ptr = rfs->buf->data + rfs->size; -+ -+ ptr[0] = header; -+ ++ptr; -+ -+ for (int i = 0; i < rfs->frames_count; ++i) { -+ ptr[0] = (rfs->frames_sizes[i] >> 0) & 0xff; -+ ptr[1] = (rfs->frames_sizes[i] >> 8) & 0xff; -+ ptr[2] = (rfs->frames_sizes[i] >> 16) & 0xff; -+ ptr[3] = (rfs->frames_sizes[i] >> 24) & 0xff; -+ -+ ptr += 4; -+ } -+ -+ ptr[0] = header; -+ ++ptr; -+ -+ rfs->size = ptr - rfs->buf->data; -+ } -+ -+ return 0; -+} -+ -+static int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt) -+{ -+ SvtContext *svt_enc = avctx->priv_data; -+ EbBufferHeaderType *headerPtr; -+ EbErrorType svt_ret; -+ AVBufferRef *ref; -+ int ret = 0; -+ -+ if (get_received_frame(svt_enc, pkt) == 0) { -+ return 0; -+ } -+ -+ 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; -+ 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 -+ -+ -+ for (;;) { -+ svt_ret = eb_vp9_svt_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag); -+ if (svt_ret == EB_NoErrorEmptyQueue) { -+ return AVERROR(EAGAIN); -+ } -+ -+ if (EB_BUFFERFLAG_EOS & headerPtr->flags) -+ svt_enc->eos_flag = EOS_TOTRIGGER; -+ -+ ret = 0; -+ -+ // ignore headerPtr->dts on purpose -+ -+ if (headerPtr->flags & EB_BUFFERFLAG_SHOW_EXT) { -+ ret = put_received_frame(avctx, headerPtr->p_buffer, headerPtr->n_filled_len - 4, 0, headerPtr->pts - 3, headerPtr->pts - 3); -+ if (ret != 0) goto end; -+ ret = put_received_frame(avctx, headerPtr->p_buffer + headerPtr->n_filled_len - 4, 1, 0, headerPtr->pts - 2, headerPtr->pts - 2); -+ if (ret != 0) goto end; -+ ret = put_received_frame(avctx, headerPtr->p_buffer + headerPtr->n_filled_len - 3, 1, 0, headerPtr->pts - 1, headerPtr->pts - 1); -+ if (ret != 0) goto end; -+ ret = put_received_frame(avctx, headerPtr->p_buffer + headerPtr->n_filled_len - 2, 1, 0, headerPtr->pts + 0, headerPtr->pts + 0); -+ if (ret != 0) goto end; -+ ret = put_received_frame(avctx, headerPtr->p_buffer + headerPtr->n_filled_len - 1, 1, 0, headerPtr->pts + 1, headerPtr->pts + 1); -+ if (ret != 0) goto end; -+ } else { -+ ret = put_received_frame(avctx, headerPtr->p_buffer, headerPtr->n_filled_len, headerPtr->pic_type == EB_IDR_PICTURE, headerPtr->pts, headerPtr->pts); -+ if (ret != 0) goto end; -+ } -+ -+ ret = get_received_frame(svt_enc, pkt); -+ -+ end: -+ eb_vp9_svt_release_out_buffer(&headerPtr); -+ -+ if (ret == AVERROR(EAGAIN)) { -+ continue; -+ } -+ -+ break; -+ } -+ -+ -+ -+ return ret; -+} -+ -+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 }, -+ -+ { "socket", "Target CPU socket to use. -1 use all available", OFFSET(target_socket), -+ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, -+ -+ { "bl_mode", "Random Access Prediction Structure type setting", OFFSET(base_layer_switch_mode), -+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, -+ -+ { "forced-idr", "If forcing keyframes, force them as IDR frames.", OFFSET(forced_idr), -+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, -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 FFCodecDefault eb_enc_defaults[] = { -+ { "b", "7M" }, -+ { "flags", "-cgop" }, -+ { "qmin", "10" }, -+ { "qmax", "48" }, -+ { NULL }, -+}; -+ -+const FFCodec ff_libsvt_vp9_encoder = { -+ .p.name = "libsvt_vp9", -+ CODEC_LONG_NAME("SVT-VP9(Scalable Video Technology for VP9) encoder"), -+ .priv_data_size = sizeof(SvtContext), -+ .p.type = AVMEDIA_TYPE_VIDEO, -+ .p.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 -+ FF_CODEC_RECEIVE_PACKET_CB(eb_receive_packet), -+ .close = eb_enc_close, -+ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, -+ CODEC_PIXFMTS(AV_PIX_FMT_YUV420P, -+ AV_PIX_FMT_NONE), -+ .p.priv_class = &class, -+ .defaults = eb_enc_defaults, -+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, -+ .p.wrapper_name = "libsvt_vp9", -+}; diff --git a/PKGBUILD b/PKGBUILD index 1bfa3d0..d6690f3 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -3,8 +3,9 @@ pkgname=ffmpeg-full pkgver=8.0.1 -pkgrel=2 -_svt_hevc_ver='ed80959ebb5586aa7763c91a397d44be1798587c' +pkgrel=3 +_svt_hevc_ver='4181c9ee0611baefb40b4c0ed10023cfd837d522' +_svt_vp9_ver='290fb8c3662ed76a8887b587a9b8201878ba71ed' _whispercpp_ver='1.8.2' pkgdesc='Complete solution to record, convert and stream audio and video (all possible features including libfdk-aac)' arch=('x86_64') @@ -163,7 +164,7 @@ source=("https://ffmpeg.org/releases/ffmpeg-${pkgver}.tar.xz"{,.asc} "https://github.com/ggml-org/whisper.cpp/archive/v${_whispercpp_ver}/whisper.cpp-${_whispercpp_ver}.tar.gz" '010-ffmpeg-add-svt-hevc.patch' "020-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" - '030-ffmpeg-add-svt-vp9.patch' + "030-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" '040-ffmpeg-add-av_stream_get_first_dts-for-chromium.patch' '050-ffmpeg-fix-cuda-nvcc-with-gcc14.patch' '060-ffmpeg-whisper.cpp-fix-pkgconfig.patch' @@ -178,7 +179,7 @@ sha256sums=('05ee0b03119b45c0bdb4df654b96802e909e0a752f72e4fe3794f487229e5a41' 'bcee25589bb8052d9e155369f6759a05729a2022d2a8085c1aa4345108523077' 'ccdc1cab97d1fe5a454cd57fbd2bb865256092d715fd7f380c30cc3f42891b3c' 'a164ebdc4d281352bf7ad1b179aae4aeb33f1191c444bed96cb8ab333c046f81' - '60bfff3c6bf3c2f1ca674b051b4d1b40f5686087555d1bdde82fa37102e5a801' + '1f06dfcb78e43a6c732cbc4f6ae583ae19fb111b56d33c8c860d5b6566c04f99' '5cb2475de410f5696072687af88e91461cdacd1bb636ac14a3b348e3383934f1' '9f3d84b3abe1077b3d6c1a25f36dcddf6419a7fe3217a4edd52aab6f0e4cd838' '98b3d28cbd13bb575c602785f6b8cb0b66ea3128ab5a3a82fc1645822320c136' @@ -193,7 +194,7 @@ prepare() { rm -f "ffmpeg-${pkgver}/libavcodec"/libsvt_{hevc,vp9}.c patch -d "ffmpeg-${pkgver}" -Np1 -i "${srcdir}/010-ffmpeg-add-svt-hevc.patch" patch -d "ffmpeg-${pkgver}" -Np1 -i "${srcdir}/020-ffmpeg-add-svt-hevc-docs-g${_svt_hevc_ver:0:7}.patch" - patch -d "ffmpeg-${pkgver}" -Np1 -i "${srcdir}/030-ffmpeg-add-svt-vp9.patch" + patch -d "ffmpeg-${pkgver}" -Np1 -i "${srcdir}/030-ffmpeg-add-svt-vp9-g${_svt_vp9_ver:0:7}.patch" patch -d "ffmpeg-${pkgver}" -Np1 -i "${srcdir}/040-ffmpeg-add-av_stream_get_first_dts-for-chromium.patch" patch -d "ffmpeg-${pkgver}" -Np1 -i "${srcdir}/050-ffmpeg-fix-cuda-nvcc-with-gcc14.patch" patch -d "whisper.cpp-${_whispercpp_ver}" -Np1 -i "${srcdir}/060-ffmpeg-whisper.cpp-fix-pkgconfig.patch"