Merge media decoding into one FFmpeg bridge (#706)

* [media] merge bink into shared ffmpeg bridge

* [avplayer] decode in process and fix stream info size

* [font] add glyph and teardown exports

* [build] bump ffmpeg runtime to 3b502d4

* [font] add glyph and teardown exports

* [build] bump ffmpeg runtime to 3b502d4

* [avplayer] decode in process

* [font] add glyph and teardown exports

* [build] bump ffmpeg runtime to 3b502d4
This commit is contained in:
Berk
2026-07-31 01:31:14 +03:00
committed by GitHub
parent 753ddf93be
commit 5864328e35
15 changed files with 920 additions and 654 deletions
@@ -75,49 +75,6 @@ public sealed class AvPlayerPathTests : IDisposable
AssertPathIsInsideApp0(resolved);
}
[Theory]
[InlineData(false, "ffmpeg", "ffprobe")]
[InlineData(true, "ffmpeg.exe", "ffprobe.exe")]
public void MediaToolLookupUsesPlatformNames(
bool isWindows,
string ffmpegName,
string ffprobeName)
{
var toolDirectory = Path.Combine(_tempRoot, "Media Tools");
Directory.CreateDirectory(toolDirectory);
var ffmpeg = Path.Combine(toolDirectory, ffmpegName);
File.WriteAllBytes(ffmpeg, []);
var resolved = AvPlayerExports.FindFfmpeg(
configured: null,
searchPath: $"\"{toolDirectory}\"",
isWindows);
Assert.Equal(ffmpeg, resolved);
Assert.Equal(
Path.Combine(toolDirectory, ffprobeName),
AvPlayerExports.GetFfprobePath(ffmpeg, isWindows));
}
[Theory]
[InlineData(false, "ffmpeg")]
[InlineData(true, "ffmpeg.exe")]
public void MediaToolLookupFindsPackagedBinary(bool isWindows, string executable)
{
var publishDirectory = Path.Combine(_tempRoot, "publish");
Directory.CreateDirectory(Path.Combine(publishDirectory, "ffmpeg"));
var ffmpeg = Path.Combine(publishDirectory, "ffmpeg", executable);
File.WriteAllBytes(ffmpeg, []);
Assert.Equal(
ffmpeg,
AvPlayerExports.FindFfmpeg(
configured: null,
searchPath: null,
isWindows,
publishDirectory));
}
[Fact]
public void RelativeFileUriCannotEscapeApp0()
{
@@ -2,18 +2,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
using System.Buffers.Binary;
using SharpEmu.Libs.Bink;
using SharpEmu.Libs.Media;
using Xunit;
namespace SharpEmu.Libs.Tests.Bink;
namespace SharpEmu.Libs.Tests.Media;
public sealed class Bink2MovieBridgeTests : IDisposable
public sealed class HostMovieBridgeTests : IDisposable
{
private readonly string _tempDirectory = Path.Combine(
Path.GetTempPath(),
$"sharpemu-bink-{Guid.NewGuid():N}");
public Bink2MovieBridgeTests()
public HostMovieBridgeTests()
{
Directory.CreateDirectory(_tempDirectory);
}
@@ -23,7 +23,7 @@ public sealed class Bink2MovieBridgeTests : IDisposable
{
var path = WriteHeader("KB2j"u8, 3840, 2160, 30_000, 1_001);
Assert.True(Bink2MovieBridge.TryReadBinkInfo(path, out var info));
Assert.True(HostMovieBridge.TryReadBinkInfo(path, out var info));
Assert.Equal(3840u, info.Width);
Assert.Equal(2160u, info.Height);
Assert.Equal(30_000u, info.FramesPerSecondNumerator);
@@ -43,7 +43,7 @@ public sealed class Bink2MovieBridgeTests : IDisposable
60,
1);
Assert.True(Bink2MovieBridge.TryReadBinkInfo(path, out _));
Assert.True(HostMovieBridge.TryReadBinkInfo(path, out _));
}
[Fact]
@@ -51,7 +51,7 @@ public sealed class Bink2MovieBridgeTests : IDisposable
{
var path = WriteHeader("KB2j"u8, 1920, 1080, 60, 0);
Assert.False(Bink2MovieBridge.TryReadBinkInfo(path, out _));
Assert.False(HostMovieBridge.TryReadBinkInfo(path, out _));
}
private string WriteHeader(
@@ -1,17 +1,17 @@
// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using SharpEmu.Libs.Bink;
using SharpEmu.Libs.Media;
using Xunit;
namespace SharpEmu.Libs.Tests.Bink;
namespace SharpEmu.Libs.Tests.Media;
public sealed class BinkFramePlaybackTests
public sealed class MediaFramePlaybackTests
{
[Fact]
public void FramesAdvanceAccordingToMovieClock()
{
using var playback = new BinkFramePlayback(new SequenceDecoder(1, 2, 3));
using var playback = new MediaFramePlayback(new SequenceDecoder(1, 2, 3));
Assert.Equal(1, WaitForAdvancedFrame(playback)[0]);
Assert.True(playback.TryGetFrame(true, out var heldFrame, out var advanced));
@@ -22,7 +22,7 @@ public sealed class BinkFramePlaybackTests
Assert.Equal(3, WaitForAdvancedFrame(playback)[0]);
}
private static byte[] WaitForAdvancedFrame(BinkFramePlayback playback)
private static byte[] WaitForAdvancedFrame(MediaFramePlayback playback)
{
var deadline = DateTime.UtcNow + TimeSpan.FromSeconds(2);
while (DateTime.UtcNow < deadline)
@@ -41,7 +41,7 @@ public sealed class BinkFramePlaybackTests
[Fact]
public void FirstFrameWaitsUntilPresentationStarts()
{
using var playback = new BinkFramePlayback(new SequenceDecoder(1, 2));
using var playback = new MediaFramePlayback(new SequenceDecoder(1, 2));
var first = WaitForFrame(playback, advanceClock: false);
Assert.Equal(1, first[0]);
@@ -58,7 +58,7 @@ public sealed class BinkFramePlaybackTests
}
private static byte[] WaitForFrame(
BinkFramePlayback playback,
MediaFramePlayback playback,
bool advanceClock)
{
var deadline = DateTime.UtcNow + TimeSpan.FromSeconds(2);
@@ -75,7 +75,7 @@ public sealed class BinkFramePlaybackTests
throw new TimeoutException("The decoder did not produce a frame.");
}
private sealed class SequenceDecoder(params byte[] values) : IBinkFrameDecoder
private sealed class SequenceDecoder(params byte[] values) : IMediaFrameDecoder
{
private int _index;