From 30cc44df15fe9ee6c08ac228f0bf371c5df87532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 14 Jun 2024 16:46:06 +0200 Subject: [PATCH] Ignore editlist when decoding mp4/mov videos Closes https://github.com/ppy/osu/issues/13696. The editlist would cause storyboard videos to not play back the same way stable (and most other video players) plays them back. --- osu.Framework/Graphics/Video/FFmpegFuncs.cs | 6 ++++++ osu.Framework/Graphics/Video/VideoDecoder.cs | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Framework/Graphics/Video/FFmpegFuncs.cs b/osu.Framework/Graphics/Video/FFmpegFuncs.cs index 91821e44bb..e95cdfa7b9 100644 --- a/osu.Framework/Graphics/Video/FFmpegFuncs.cs +++ b/osu.Framework/Graphics/Video/FFmpegFuncs.cs @@ -15,6 +15,10 @@ public unsafe class FFmpegFuncs { #region Delegates + public delegate int AvDictSetDelegate(AVDictionary** pm, [MarshalAs(UnmanagedType.LPUTF8Str)] string key, [MarshalAs(UnmanagedType.LPUTF8Str)] string value, int flags); + + public delegate void AvDictFreeDelegate(AVDictionary** m); + public delegate AVFrame* AvFrameAllocDelegate(); public delegate void AvFrameFreeDelegate(AVFrame** frame); @@ -89,6 +93,8 @@ public unsafe class FFmpegFuncs #endregion + public AvDictSetDelegate av_dict_set; + public AvDictFreeDelegate av_dict_free; public AvFrameAllocDelegate av_frame_alloc; public AvFrameFreeDelegate av_frame_free; public AvFrameUnrefDelegate av_frame_unref; diff --git a/osu.Framework/Graphics/Video/VideoDecoder.cs b/osu.Framework/Graphics/Video/VideoDecoder.cs index 60fd958fb8..780ac08c41 100644 --- a/osu.Framework/Graphics/Video/VideoDecoder.cs +++ b/osu.Framework/Graphics/Video/VideoDecoder.cs @@ -349,7 +349,12 @@ private void prepareDecoding() formatContext->pb = ioContext; formatContext->flags |= FFmpegFuncs.AVFMT_FLAG_GENPTS; // required for most HW decoders as they only read `pts` - int openInputResult = ffmpeg.avformat_open_input(&fcPtr, "pipe:", null, null); + AVDictionary* options = null; + // see https://github.com/ppy/osu/issues/13696 for reasoning + ffmpeg.av_dict_set(&options, "ignore_editlist", "1", 0); + int openInputResult = ffmpeg.avformat_open_input(&fcPtr, "pipe:", null, &options); + ffmpeg.av_dict_free(&options); + inputOpened = openInputResult >= 0; if (!inputOpened) throw new InvalidOperationException($"Error opening file or stream: {getErrorMessage(openInputResult)}"); @@ -842,6 +847,8 @@ protected virtual FFmpegFuncs CreateFuncs() return new FFmpegFuncs { + av_dict_set = FFmpeg.AutoGen.ffmpeg.av_dict_set, + av_dict_free = FFmpeg.AutoGen.ffmpeg.av_dict_free, av_frame_alloc = FFmpeg.AutoGen.ffmpeg.av_frame_alloc, av_frame_free = FFmpeg.AutoGen.ffmpeg.av_frame_free, av_frame_unref = FFmpeg.AutoGen.ffmpeg.av_frame_unref,