diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2021-09-28 19:43:40 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-09-29 00:43:40 +0200 |
| commit | f4f496cb48a59aae36e3252baa90396e1bfadd2e (patch) | |
| tree | 5594d76b3f1b552f1fecdeda37bd2f6667781a56 /Ryujinx.Graphics.Nvdec/NvdecDevice.cs | |
| parent | 0d23504e30395ba20d1704da464b41f3fe539062 (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.cs | 45 |
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)); - } } } |
