Implement positioned movie playback opcode

This commit is contained in:
gamer147
2026-07-29 15:41:01 -04:00
parent 92d7fb295e
commit cfd8809339
18 changed files with 523 additions and 46 deletions

View File

@@ -21,6 +21,11 @@ internal sealed record FfmpegAudioChunk(float[] InterleavedStereo, int FrameCoun
internal interface IFfmpegFrameSource : IDisposable
{
FfmpegMovieInfo Info { get; }
void Seek(long positionMs)
{
if (positionMs != 0)
throw new NotSupportedException("movie source does not support positioned playback");
}
bool TryDecodeNextVideoFrame(out FfmpegVideoFrame frame);
bool TryDecodeNextAudioChunk(out FfmpegAudioChunk chunk)
{
@@ -39,7 +44,7 @@ internal sealed class FfmpegMovieSession : IFfmpegFrameSource
public FfmpegMovieSession(MoviePayload movie)
{
ArgumentNullException.ThrowIfNull(movie);
if (FfmpegMovieNative.AbiVersion() != 2)
if (FfmpegMovieNative.AbiVersion() != 3)
throw new InvalidOperationException("unsupported age_movie_ffmpeg ABI version");
byte[] error = new byte[1024];
@@ -70,6 +75,20 @@ internal sealed class FfmpegMovieSession : IFfmpegFrameSource
}
}
public void Seek(long positionMs)
{
ObjectDisposedException.ThrowIf(_handle.IsClosed, this);
int result;
string? error = null;
lock (_decodeLock)
{
result = FfmpegMovieNative.Seek(_handle, Math.Max(0, positionMs));
if (result != 0) error = FfmpegMovieNative.LastError(_handle);
}
if (result != 0)
throw new InvalidDataException($"FFmpeg movie seek failed: {error}");
}
public bool TryDecodeNextVideoFrame(out FfmpegVideoFrame frame)
{
ObjectDisposedException.ThrowIf(_handle.IsClosed, this);
@@ -240,6 +259,11 @@ internal static class FfmpegMovieNative
nuint rgbaSize,
out long presentationTimeMs);
[DllImport(LibraryName, EntryPoint = "age_movie_seek", CallingConvention = CallingConvention.Cdecl)]
internal static extern int Seek(
FfmpegMovieHandle movie,
long positionMs);
[DllImport(LibraryName, EntryPoint = "age_movie_decode_audio", CallingConvention = CallingConvention.Cdecl)]
internal static extern int DecodeAudio(
FfmpegMovieHandle movie,