aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Nvdec/NvdecDevice.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-09-28 19:43:40 -0300
committerGitHub <noreply@github.com>2021-09-29 00:43:40 +0200
commitf4f496cb48a59aae36e3252baa90396e1bfadd2e (patch)
tree5594d76b3f1b552f1fecdeda37bd2f6667781a56 /Ryujinx.Graphics.Nvdec/NvdecDevice.cs
parent0d23504e30395ba20d1704da464b41f3fe539062 (diff)
NVDEC (H264): Use separate contexts per channel and decode frames in DTS order (#2671)
* Use separate NVDEC contexts per channel (for FFMPEG) * Remove NVDEC -> VIC frame override hack * Add missing bottom_field_pic_order_in_frame_present_flag * Make FFMPEG logging static * nit: Remove empty lines * New FFMPEG decoding approach -- call h264_decode_frame directly, trim surface cache to reduce memory usage * Fix case * Silence warnings * PR feedback * Per-decoder rather than per-codec ownership of surfaces on the cache
Diffstat (limited to 'Ryujinx.Graphics.Nvdec/NvdecDevice.cs')
-rw-r--r--Ryujinx.Graphics.Nvdec/NvdecDevice.cs45
1 files changed, 35 insertions, 10 deletions
diff --git a/Ryujinx.Graphics.Nvdec/NvdecDevice.cs b/Ryujinx.Graphics.Nvdec/NvdecDevice.cs
index 08f802a1..5319429b 100644
--- a/Ryujinx.Graphics.Nvdec/NvdecDevice.cs
+++ b/Ryujinx.Graphics.Nvdec/NvdecDevice.cs
@@ -2,17 +2,20 @@
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Nvdec.Image;
-using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Threading;
namespace Ryujinx.Graphics.Nvdec
{
- public class NvdecDevice : IDeviceState
+ public class NvdecDevice : IDeviceStateWithContext
{
private readonly ResourceManager _rm;
private readonly DeviceState<NvdecRegisters> _state;
- public event Action<FrameDecodedEventArgs> FrameDecoded;
+ private long _currentId;
+ private ConcurrentDictionary<long, NvdecDecoderContext> _contexts;
+ private NvdecDecoderContext _currentContext;
public NvdecDevice(MemoryManager gmm)
{
@@ -21,6 +24,33 @@ namespace Ryujinx.Graphics.Nvdec
{
{ nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) }
});
+ _contexts = new ConcurrentDictionary<long, NvdecDecoderContext>();
+ }
+
+ public long CreateContext()
+ {
+ long id = Interlocked.Increment(ref _currentId);
+ _contexts.TryAdd(id, new NvdecDecoderContext());
+
+ return id;
+ }
+
+ public void DestroyContext(long id)
+ {
+ if (_contexts.TryRemove(id, out var context))
+ {
+ context.Dispose();
+ }
+
+ _rm.Cache.Trim();
+ }
+
+ public void BindContext(long id)
+ {
+ if (_contexts.TryGetValue(id, out var context))
+ {
+ _currentContext = context;
+ }
}
public int Read(int offset) => _state.Read(offset);
@@ -36,20 +66,15 @@ namespace Ryujinx.Graphics.Nvdec
switch (codecId)
{
case CodecId.H264:
- H264Decoder.Decode(this, _rm, ref _state.State);
+ H264Decoder.Decode(_currentContext, _rm, ref _state.State);
break;
case CodecId.Vp9:
- Vp9Decoder.Decode(this, _rm, ref _state.State);
+ Vp9Decoder.Decode(_rm, ref _state.State);
break;
default:
Logger.Error?.Print(LogClass.Nvdec, $"Unsupported codec \"{codecId}\".");
break;
}
}
-
- internal void OnFrameDecoded(CodecId codecId, uint lumaOffset, uint chromaOffset)
- {
- FrameDecoded?.Invoke(new FrameDecodedEventArgs(codecId, lumaOffset, chromaOffset));
- }
}
}