Merge pull request #461 from nyanmisaka/rkmppdec-nokey
Some checks failed
🏗️ Build jellyfin-ffmpeg / build_debian (push) Failing after 29s
🏗️ Build jellyfin-ffmpeg / build_ubuntu (push) Failing after 1s
🏗️ Build jellyfin-ffmpeg / build_portable_windows (push) Failing after 29s
🏗️ Build jellyfin-ffmpeg / build_portable_windows_clang (push) Failing after 29s
🏗️ Build jellyfin-ffmpeg / build_portable_linux (push) Failing after 0s
🏗️ Build jellyfin-ffmpeg / build_portable_mac (push) Failing after 29s

Add key-frame only decoding for RKMPP
This commit is contained in:
Nyanmisaka 2024-09-20 05:01:10 +08:00 committed by GitHub
commit 3d25b929cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 23 deletions

1
debian/changelog vendored
View File

@ -4,6 +4,7 @@ jellyfin-ffmpeg (7.0.2-2) unstable; urgency=medium
* Fix the default pkt thread queue size on certain platform * Fix the default pkt thread queue size on certain platform
* Add 12bit videotoolbox decoding support for HEVC * Add 12bit videotoolbox decoding support for HEVC
* Fix the sub2video perf regressions * Fix the sub2video perf regressions
* Add key-frame only decoding for RKMPP
* Update dependencies * Update dependencies
-- nyanmisaka <nst799610810@gmail.com> Wed, 18 Sep 2024 20:37:24 +0800 -- nyanmisaka <nst799610810@gmail.com> Wed, 18 Sep 2024 20:37:24 +0800

View File

@ -295,7 +295,7 @@ Index: FFmpeg/libavcodec/rkmppdec.c
* *
* This file is part of FFmpeg. * This file is part of FFmpeg.
* *
@@ -19,569 +20,937 @@ @@ -19,569 +20,952 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
@ -486,6 +486,7 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ r->draining = 0; + r->draining = 0;
+ r->info_change = 0; + r->info_change = 0;
+ r->errinfo_cnt = 0; + r->errinfo_cnt = 0;
+ r->got_frame = 0;
- if (decoder->frame_group) { - if (decoder->frame_group) {
- mpp_buffer_group_put(decoder->frame_group); - mpp_buffer_group_put(decoder->frame_group);
@ -625,6 +626,9 @@ Index: FFmpeg/libavcodec/rkmppdec.c
- if (ret != MPP_OK) { - if (ret != MPP_OK) {
- av_log(avctx, AV_LOG_ERROR, "Failed to initialize MPP context (code = %d).\n", ret); - av_log(avctx, AV_LOG_ERROR, "Failed to initialize MPP context (code = %d).\n", ret);
- ret = AVERROR_UNKNOWN; - ret = AVERROR_UNKNOWN;
+ if (avctx->skip_frame == AVDISCARD_NONKEY)
+ r->deint = 0;
+
+ if ((ret = r->mapi->control(r->mctx, MPP_DEC_SET_ENABLE_DEINTERLACE, &r->deint)) != MPP_OK) { + if ((ret = r->mapi->control(r->mctx, MPP_DEC_SET_ENABLE_DEINTERLACE, &r->deint)) != MPP_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to set enable deinterlace: %d\n", ret); + av_log(avctx, AV_LOG_ERROR, "Failed to set enable deinterlace: %d\n", ret);
+ ret = AVERROR_EXTERNAL; + ret = AVERROR_EXTERNAL;
@ -945,19 +949,25 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ light = av_content_light_metadata_create_side_data(frame); + light = av_content_light_metadata_create_side_data(frame);
+ if (!light) + if (!light)
+ return AVERROR(ENOMEM); + return AVERROR(ENOMEM);
+
+ light->MaxCLL = mpp_light.MaxCLL;
+ light->MaxFALL = mpp_light.MaxFALL;
- mpp_frame_deinit(&framecontext->frame); - mpp_frame_deinit(&framecontext->frame);
- av_buffer_unref(&framecontext->decoder_ref); - av_buffer_unref(&framecontext->decoder_ref);
- av_buffer_unref(&framecontextref); - av_buffer_unref(&framecontextref);
+ light->MaxCLL = mpp_light.MaxCLL; + return 0;
+ light->MaxFALL = mpp_light.MaxFALL; +}
- av_free(desc); - av_free(desc);
+ return 0; +static void rkmpp_free_mpp_frame(void *opaque, uint8_t *data)
+{
+ MppFrame mpp_frame = (MppFrame)opaque;
+ mpp_frame_deinit(&mpp_frame);
} }
-static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame) -static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
+static void rkmpp_free_mpp_frame(void *opaque, uint8_t *data) +static void rkmpp_free_drm_desc(void *opaque, uint8_t *data)
{ {
- RKMPPDecodeContext *rk_context = avctx->priv_data; - RKMPPDecodeContext *rk_context = avctx->priv_data;
- RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data; - RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
@ -967,12 +977,6 @@ Index: FFmpeg/libavcodec/rkmppdec.c
- MppFrame mppframe = NULL; - MppFrame mppframe = NULL;
- MppBuffer buffer = NULL; - MppBuffer buffer = NULL;
- AVDRMFrameDescriptor *desc = NULL; - AVDRMFrameDescriptor *desc = NULL;
+ MppFrame mpp_frame = (MppFrame)opaque;
+ mpp_frame_deinit(&mpp_frame);
+}
+
+static void rkmpp_free_drm_desc(void *opaque, uint8_t *data)
+{
+ AVRKMPPDRMFrameDescriptor *drm_desc = (AVRKMPPDRMFrameDescriptor *)opaque; + AVRKMPPDRMFrameDescriptor *drm_desc = (AVRKMPPDRMFrameDescriptor *)opaque;
+ av_free(drm_desc); + av_free(drm_desc);
+} +}
@ -1380,6 +1384,7 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ } else { + } else {
+ av_log(avctx, AV_LOG_DEBUG, "Received a frame\n"); + av_log(avctx, AV_LOG_DEBUG, "Received a frame\n");
+ r->errinfo_cnt = 0; + r->errinfo_cnt = 0;
+ r->got_frame = 1;
+ +
+ switch (avctx->pix_fmt) { + switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_DRM_PRIME: + case AV_PIX_FMT_DRM_PRIME:
@ -1467,11 +1472,16 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ return AVERROR_EXTERNAL; + return AVERROR_EXTERNAL;
+ } + }
+ mpp_packet_set_eos(mpp_pkt); + mpp_packet_set_eos(mpp_pkt);
+
- ret = rkmpp_send_packet(avctx, &pkt);
- av_packet_unref(&pkt);
+ do { + do {
+ ret = r->mapi->decode_put_packet(r->mctx, mpp_pkt); + ret = r->mapi->decode_put_packet(r->mctx, mpp_pkt);
+ } while (ret != MPP_OK); + } while (ret != MPP_OK);
+
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Failed to send packet to decoder (code = %d)\n", ret);
- return ret;
+ r->draining = 1; + r->draining = 1;
+ +
+ mpp_packet_deinit(&mpp_pkt); + mpp_packet_deinit(&mpp_pkt);
@ -1489,6 +1499,15 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ if (r->draining) + if (r->draining)
+ return AVERROR(EOF); + return AVERROR(EOF);
+ +
+ /* do not skip non-key pkt until got any frame */
+ if (r->got_frame &&
+ avctx->skip_frame == AVDISCARD_NONKEY &&
+ !(pkt->flags & AV_PKT_FLAG_KEY)) {
+ av_log(avctx, AV_LOG_TRACE, "Skip packet without key flag "
+ "at pts %"PRId64"\n", pkt->pts);
+ return 0;
+ }
+
+ if ((ret = mpp_packet_init(&mpp_pkt, pkt->data, pkt->size)) != MPP_OK) { + if ((ret = mpp_packet_init(&mpp_pkt, pkt->data, pkt->size)) != MPP_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to init packet: %d\n", ret); + av_log(avctx, AV_LOG_ERROR, "Failed to init packet: %d\n", ret);
+ return AVERROR_EXTERNAL; + return AVERROR_EXTERNAL;
@ -1501,9 +1520,7 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ return AVERROR(EAGAIN); + return AVERROR(EAGAIN);
+ } + }
+ av_log(avctx, AV_LOG_DEBUG, "Wrote %d bytes to decoder\n", pkt->size); + av_log(avctx, AV_LOG_DEBUG, "Wrote %d bytes to decoder\n", pkt->size);
+
- ret = rkmpp_send_packet(avctx, &pkt);
- av_packet_unref(&pkt);
+ mpp_packet_deinit(&mpp_pkt); + mpp_packet_deinit(&mpp_pkt);
+ return 0; + return 0;
+} +}
@ -1520,10 +1537,7 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ /* no more frames after EOS */ + /* no more frames after EOS */
+ if (r->eof) + if (r->eof)
+ return AVERROR_EOF; + return AVERROR_EOF;
+
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Failed to send packet to decoder (code = %d)\n", ret);
- return ret;
+ /* drain remain frames */ + /* drain remain frames */
+ if (r->draining) { + if (r->draining) {
+ ret = rkmpp_get_frame(avctx, frame, MPP_TIMEOUT_BLOCK); + ret = rkmpp_get_frame(avctx, frame, MPP_TIMEOUT_BLOCK);
@ -1594,6 +1608,7 @@ Index: FFmpeg/libavcodec/rkmppdec.c
+ r->draining = 0; + r->draining = 0;
+ r->info_change = 0; + r->info_change = 0;
+ r->errinfo_cnt = 0; + r->errinfo_cnt = 0;
+ r->got_frame = 0;
- ret = decoder->mpi->reset(decoder->ctx); - ret = decoder->mpi->reset(decoder->ctx);
- if (ret == MPP_OK) { - if (ret == MPP_OK) {
@ -1670,7 +1685,7 @@ Index: FFmpeg/libavcodec/rkmppdec.h
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ FFmpeg/libavcodec/rkmppdec.h +++ FFmpeg/libavcodec/rkmppdec.h
@@ -0,0 +1,143 @@ @@ -0,0 +1,144 @@
+/* +/*
+ * Copyright (c) 2017 Lionel CHAZALLON + * Copyright (c) 2017 Lionel CHAZALLON
+ * Copyright (c) 2023 Huseyin BIYIK + * Copyright (c) 2023 Huseyin BIYIK
@ -1730,6 +1745,7 @@ Index: FFmpeg/libavcodec/rkmppdec.h
+ int draining; + int draining;
+ int info_change; + int info_change;
+ int errinfo_cnt; + int errinfo_cnt;
+ int got_frame;
+ +
+ int deint; + int deint;
+ int afbc; + int afbc;

View File

@ -439,7 +439,7 @@ prepare_extra_amd64() {
# VPL-GPU-RT (RT only) # VPL-GPU-RT (RT only)
# Provides VPL runtime (libmfx-gen.so.1.2) for 11th Gen Tiger Lake and newer # Provides VPL runtime (libmfx-gen.so.1.2) for 11th Gen Tiger Lake and newer
pushd ${SOURCE_DIR} pushd ${SOURCE_DIR}
git clone -b intel-onevpl-24.3.3 --depth=1 https://github.com/intel/vpl-gpu-rt.git git clone -b intel-onevpl-24.3.4 --depth=1 https://github.com/intel/vpl-gpu-rt.git
pushd vpl-gpu-rt pushd vpl-gpu-rt
mkdir build && pushd build mkdir build && pushd build
cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \ cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \
@ -459,7 +459,7 @@ prepare_extra_amd64() {
# Full Feature Build: ENABLE_KERNELS=ON(Default) ENABLE_NONFREE_KERNELS=ON(Default) # Full Feature Build: ENABLE_KERNELS=ON(Default) ENABLE_NONFREE_KERNELS=ON(Default)
# Free Kernel Build: ENABLE_KERNELS=ON ENABLE_NONFREE_KERNELS=OFF # Free Kernel Build: ENABLE_KERNELS=ON ENABLE_NONFREE_KERNELS=OFF
pushd ${SOURCE_DIR} pushd ${SOURCE_DIR}
git clone -b intel-media-24.3.3 --depth=1 https://github.com/intel/media-driver.git git clone -b intel-media-24.3.4 --depth=1 https://github.com/intel/media-driver.git
pushd media-driver pushd media-driver
mkdir build && pushd build mkdir build && pushd build
cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \ cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \