NvdecDevice.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.Graphics.Device;
  3. using Ryujinx.Graphics.Gpu.Memory;
  4. using Ryujinx.Graphics.Nvdec.Image;
  5. using System;
  6. using System.Collections.Generic;
  7. namespace Ryujinx.Graphics.Nvdec
  8. {
  9. public class NvdecDevice : IDeviceState
  10. {
  11. private readonly ResourceManager _rm;
  12. private readonly DeviceState<NvdecRegisters> _state;
  13. public event Action<FrameDecodedEventArgs> FrameDecoded;
  14. public NvdecDevice(MemoryManager gmm)
  15. {
  16. _rm = new ResourceManager(gmm, new SurfaceCache(gmm));
  17. _state = new DeviceState<NvdecRegisters>(new Dictionary<string, RwCallback>
  18. {
  19. { nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) }
  20. });
  21. }
  22. public int Read(int offset) => _state.Read(offset);
  23. public void Write(int offset, int data) => _state.Write(offset, data);
  24. private void Execute(int data)
  25. {
  26. Decode((CodecId)_state.State.SetCodecID);
  27. }
  28. private void Decode(CodecId codecId)
  29. {
  30. switch (codecId)
  31. {
  32. case CodecId.H264:
  33. H264Decoder.Decode(this, _rm, ref _state.State);
  34. break;
  35. case CodecId.Vp9:
  36. Vp9Decoder.Decode(this, _rm, ref _state.State);
  37. break;
  38. default:
  39. Logger.Error?.Print(LogClass.Nvdec, $"Unsupported codec \"{codecId}\".");
  40. break;
  41. }
  42. }
  43. internal void OnFrameDecoded(CodecId codecId, uint lumaOffset, uint chromaOffset)
  44. {
  45. FrameDecoded?.Invoke(new FrameDecodedEventArgs(codecId, lumaOffset, chromaOffset));
  46. }
  47. }
  48. }