From d1604aa762a3f669a3fecff0a30b7360399954bc Mon Sep 17 00:00:00 2001 From: Ac_K Date: Tue, 12 Oct 2021 22:55:57 +0200 Subject: [PATCH] nvdec: Adding Vp8 codec support (#2707) * first try * second try * working update * Final impl * Fixes nits * Fix everything * remove leftover * Update FFmpegContext.cs * Update Surface.cs * Addresses gdkchan feedback * bool not byte * Addresses gdkchan feedback --- .../FFmpegContext.cs | 16 ++-- .../H264}/Decoder.cs | 9 ++- .../H264}/H264BitStreamWriter.cs | 2 +- .../H264}/SpsAndPpsReconstruction.cs | 2 +- .../Ryujinx.Graphics.Nvdec.FFmpeg.csproj | 5 +- .../Surface.cs | 2 +- Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs | 53 +++++++++++++ Ryujinx.Graphics.Nvdec/H264Decoder.cs | 6 +- Ryujinx.Graphics.Nvdec/NvdecDecoderContext.cs | 20 +++-- Ryujinx.Graphics.Nvdec/NvdecDevice.cs | 3 + .../Ryujinx.Graphics.Nvdec.csproj | 2 +- .../Types/Vp8/PictureInfo.cs | 75 +++++++++++++++++++ Ryujinx.Graphics.Nvdec/Vp8Decoder.cs | 33 ++++++++ Ryujinx.Graphics.Video/Vp8PictureInfo.cs | 11 +++ Ryujinx.sln | 14 ++-- Ryujinx/Ryujinx.csproj | 2 +- 16 files changed, 220 insertions(+), 35 deletions(-) rename {Ryujinx.Graphics.Nvdec.H264 => Ryujinx.Graphics.Nvdec.FFmpeg}/FFmpegContext.cs (90%) rename {Ryujinx.Graphics.Nvdec.H264 => Ryujinx.Graphics.Nvdec.FFmpeg/H264}/Decoder.cs (84%) rename {Ryujinx.Graphics.Nvdec.H264 => Ryujinx.Graphics.Nvdec.FFmpeg/H264}/H264BitStreamWriter.cs (98%) rename {Ryujinx.Graphics.Nvdec.H264 => Ryujinx.Graphics.Nvdec.FFmpeg/H264}/SpsAndPpsReconstruction.cs (99%) rename Ryujinx.Graphics.Nvdec.H264/Ryujinx.Graphics.Nvdec.H264.csproj => Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj (63%) rename {Ryujinx.Graphics.Nvdec.H264 => Ryujinx.Graphics.Nvdec.FFmpeg}/Surface.cs (96%) create mode 100644 Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs create mode 100644 Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs create mode 100644 Ryujinx.Graphics.Nvdec/Vp8Decoder.cs create mode 100644 Ryujinx.Graphics.Video/Vp8PictureInfo.cs diff --git a/Ryujinx.Graphics.Nvdec.H264/FFmpegContext.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs similarity index 90% rename from Ryujinx.Graphics.Nvdec.H264/FFmpegContext.cs rename to Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs index 66b1e6c1a..1e3b88bbf 100644 --- a/Ryujinx.Graphics.Nvdec.H264/FFmpegContext.cs +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/FFmpegContext.cs @@ -5,27 +5,26 @@ using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -namespace Ryujinx.Graphics.Nvdec.H264 +namespace Ryujinx.Graphics.Nvdec.FFmpeg { unsafe class FFmpegContext : IDisposable { - private readonly AVCodec_decode _h264Decode; + private readonly AVCodec_decode _decodeFrame; private static readonly av_log_set_callback_callback _logFunc; private readonly AVCodec* _codec; private AVPacket* _packet; private AVCodecContext* _context; - public FFmpegContext() + public FFmpegContext(AVCodecID codecId) { - _codec = ffmpeg.avcodec_find_decoder(AVCodecID.AV_CODEC_ID_H264); + _codec = ffmpeg.avcodec_find_decoder(codecId); _context = ffmpeg.avcodec_alloc_context3(_codec); - _context->debug |= ffmpeg.FF_DEBUG_MMCO; ffmpeg.avcodec_open2(_context, _codec, null); _packet = ffmpeg.av_packet_alloc(); - _h264Decode = Marshal.GetDelegateForFunctionPointer(_codec->decode.Pointer); + _decodeFrame = Marshal.GetDelegateForFunctionPointer(_codec->decode.Pointer); } static FFmpegContext() @@ -115,7 +114,7 @@ namespace Ryujinx.Graphics.Nvdec.H264 { _packet->data = ptr; _packet->size = bitstream.Length; - result = _h264Decode(_context, output.Frame, &gotFrame, _packet); + result = _decodeFrame(_context, output.Frame, &gotFrame, _packet); } if (gotFrame == 0) @@ -126,7 +125,7 @@ namespace Ryujinx.Graphics.Nvdec.H264 // Get the next delayed frame by passing a 0 length packet. _packet->data = null; _packet->size = 0; - result = _h264Decode(_context, output.Frame, &gotFrame, _packet); + result = _decodeFrame(_context, output.Frame, &gotFrame, _packet); // We need to set B frames to 0 as we already consumed all delayed frames. // This prevents the decoder from trying to return a delayed frame next time. @@ -138,6 +137,7 @@ namespace Ryujinx.Graphics.Nvdec.H264 if (gotFrame == 0) { ffmpeg.av_frame_unref(output.Frame); + return -1; } diff --git a/Ryujinx.Graphics.Nvdec.H264/Decoder.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/H264/Decoder.cs similarity index 84% rename from Ryujinx.Graphics.Nvdec.H264/Decoder.cs rename to Ryujinx.Graphics.Nvdec.FFmpeg/H264/Decoder.cs index fed64af4f..8deda42a5 100644 --- a/Ryujinx.Graphics.Nvdec.H264/Decoder.cs +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/H264/Decoder.cs @@ -1,7 +1,8 @@ -using Ryujinx.Graphics.Video; +using FFmpeg.AutoGen; +using Ryujinx.Graphics.Video; using System; -namespace Ryujinx.Graphics.Nvdec.H264 +namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264 { public sealed class Decoder : IH264Decoder { @@ -11,7 +12,7 @@ namespace Ryujinx.Graphics.Nvdec.H264 private readonly byte[] _workBuffer = new byte[WorkBufferSize]; - private FFmpegContext _context = new FFmpegContext(); + private FFmpegContext _context = new FFmpegContext(AVCodecID.AV_CODEC_ID_H264); private int _oldOutputWidth; private int _oldOutputHeight; @@ -29,7 +30,7 @@ namespace Ryujinx.Graphics.Nvdec.H264 outSurf.RequestedHeight != _oldOutputHeight) { _context.Dispose(); - _context = new FFmpegContext(); + _context = new FFmpegContext(AVCodecID.AV_CODEC_ID_H264); _oldOutputWidth = outSurf.RequestedWidth; _oldOutputHeight = outSurf.RequestedHeight; diff --git a/Ryujinx.Graphics.Nvdec.H264/H264BitStreamWriter.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs similarity index 98% rename from Ryujinx.Graphics.Nvdec.H264/H264BitStreamWriter.cs rename to Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs index c0e2357de..3d3b32933 100644 --- a/Ryujinx.Graphics.Nvdec.H264/H264BitStreamWriter.cs +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs @@ -1,7 +1,7 @@ using System; using System.Numerics; -namespace Ryujinx.Graphics.Nvdec.H264 +namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264 { struct H264BitStreamWriter { diff --git a/Ryujinx.Graphics.Nvdec.H264/SpsAndPpsReconstruction.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/H264/SpsAndPpsReconstruction.cs similarity index 99% rename from Ryujinx.Graphics.Nvdec.H264/SpsAndPpsReconstruction.cs rename to Ryujinx.Graphics.Nvdec.FFmpeg/H264/SpsAndPpsReconstruction.cs index 6fd1ce79f..5c16ef3df 100644 --- a/Ryujinx.Graphics.Nvdec.H264/SpsAndPpsReconstruction.cs +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/H264/SpsAndPpsReconstruction.cs @@ -2,7 +2,7 @@ using Ryujinx.Graphics.Video; using System; -namespace Ryujinx.Graphics.Nvdec.H264 +namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264 { static class SpsAndPpsReconstruction { diff --git a/Ryujinx.Graphics.Nvdec.H264/Ryujinx.Graphics.Nvdec.H264.csproj b/Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj similarity index 63% rename from Ryujinx.Graphics.Nvdec.H264/Ryujinx.Graphics.Nvdec.H264.csproj rename to Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj index fdcdae06d..b437f36e6 100644 --- a/Ryujinx.Graphics.Nvdec.H264/Ryujinx.Graphics.Nvdec.H264.csproj +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -6,10 +6,11 @@ - + + diff --git a/Ryujinx.Graphics.Nvdec.H264/Surface.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs similarity index 96% rename from Ryujinx.Graphics.Nvdec.H264/Surface.cs rename to Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs index 3dbc980e3..20cee4a18 100644 --- a/Ryujinx.Graphics.Nvdec.H264/Surface.cs +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs @@ -2,7 +2,7 @@ using Ryujinx.Graphics.Video; using System; -namespace Ryujinx.Graphics.Nvdec.H264 +namespace Ryujinx.Graphics.Nvdec.FFmpeg { unsafe class Surface : ISurface { diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs new file mode 100644 index 000000000..f12de2875 --- /dev/null +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Vp8/Decoder.cs @@ -0,0 +1,53 @@ +using FFmpeg.AutoGen; +using Ryujinx.Graphics.Video; +using System; + +namespace Ryujinx.Graphics.Nvdec.FFmpeg.Vp8 +{ + public sealed class Decoder : IDecoder + { + public bool IsHardwareAccelerated => false; + + private readonly FFmpegContext _context = new FFmpegContext(AVCodecID.AV_CODEC_ID_VP8); + + public ISurface CreateSurface(int width, int height) + { + return new Surface(width, height); + } + + public bool Decode(ref Vp8PictureInfo pictureInfo, ISurface output, ReadOnlySpan bitstream) + { + Surface outSurf = (Surface)output; + + int uncompHeaderSize = pictureInfo.KeyFrame ? 10 : 3; + + byte[] frame = new byte[bitstream.Length + uncompHeaderSize]; + + uint firstPartSizeShifted = pictureInfo.FirstPartSize << 5; + + frame[0] = (byte)(pictureInfo.KeyFrame ? 0 : 1); + frame[0] |= (byte)((pictureInfo.Version & 7) << 1); + frame[0] |= 1 << 4; + frame[0] |= (byte)firstPartSizeShifted; + frame[1] |= (byte)(firstPartSizeShifted >> 8); + frame[2] |= (byte)(firstPartSizeShifted >> 16); + + if (pictureInfo.KeyFrame) + { + frame[3] = 0x9d; + frame[4] = 0x01; + frame[5] = 0x2a; + frame[6] = (byte)pictureInfo.FrameWidth; + frame[7] = (byte)((pictureInfo.FrameWidth >> 8) & 0x3F); + frame[8] = (byte)pictureInfo.FrameHeight; + frame[9] = (byte)((pictureInfo.FrameHeight >> 8) & 0x3F); + } + + bitstream.CopyTo(new Span(frame).Slice(uncompHeaderSize)); + + return _context.DecodeFrame(outSurf, frame) == 0; + } + + public void Dispose() => _context.Dispose(); + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Nvdec/H264Decoder.cs b/Ryujinx.Graphics.Nvdec/H264Decoder.cs index 1ee3997b5..69eeb4949 100644 --- a/Ryujinx.Graphics.Nvdec/H264Decoder.cs +++ b/Ryujinx.Graphics.Nvdec/H264Decoder.cs @@ -1,4 +1,4 @@ -using Ryujinx.Graphics.Nvdec.H264; +using Ryujinx.Graphics.Nvdec.FFmpeg.H264; using Ryujinx.Graphics.Nvdec.Image; using Ryujinx.Graphics.Nvdec.Types.H264; using Ryujinx.Graphics.Video; @@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Nvdec { private const int MbSizeInPixels = 16; - public unsafe static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state) + public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state) { PictureInfo pictureInfo = rm.Gmm.DeviceRead(state.SetPictureInfoOffset); H264PictureInfo info = pictureInfo.Convert(); @@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Nvdec uint lumaOffset = state.SetSurfaceLumaOffset[surfaceIndex]; uint chromaOffset = state.SetSurfaceChromaOffset[surfaceIndex]; - Decoder decoder = context.GetDecoder(); + Decoder decoder = context.GetH264Decoder(); ISurface outputSurface = rm.Cache.Get(decoder, 0, 0, width, height); diff --git a/Ryujinx.Graphics.Nvdec/NvdecDecoderContext.cs b/Ryujinx.Graphics.Nvdec/NvdecDecoderContext.cs index 90da0bee7..54934bc5a 100644 --- a/Ryujinx.Graphics.Nvdec/NvdecDecoderContext.cs +++ b/Ryujinx.Graphics.Nvdec/NvdecDecoderContext.cs @@ -1,21 +1,29 @@ -using Ryujinx.Graphics.Nvdec.H264; using System; namespace Ryujinx.Graphics.Nvdec { class NvdecDecoderContext : IDisposable { - private Decoder _decoder; + private FFmpeg.H264.Decoder _h264Decoder; + private FFmpeg.Vp8.Decoder _vp8Decoder; - public Decoder GetDecoder() + public FFmpeg.H264.Decoder GetH264Decoder() { - return _decoder ??= new Decoder(); + return _h264Decoder ??= new FFmpeg.H264.Decoder(); + } + + public FFmpeg.Vp8.Decoder GetVp8Decoder() + { + return _vp8Decoder ??= new FFmpeg.Vp8.Decoder(); } public void Dispose() { - _decoder?.Dispose(); - _decoder = null; + _h264Decoder?.Dispose(); + _h264Decoder = null; + + _vp8Decoder?.Dispose(); + _vp8Decoder = null; } } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Nvdec/NvdecDevice.cs b/Ryujinx.Graphics.Nvdec/NvdecDevice.cs index 5319429bb..18c2fc130 100644 --- a/Ryujinx.Graphics.Nvdec/NvdecDevice.cs +++ b/Ryujinx.Graphics.Nvdec/NvdecDevice.cs @@ -68,6 +68,9 @@ namespace Ryujinx.Graphics.Nvdec case CodecId.H264: H264Decoder.Decode(_currentContext, _rm, ref _state.State); break; + case CodecId.Vp8: + Vp8Decoder.Decode(_currentContext, _rm, ref _state.State); + break; case CodecId.Vp9: Vp9Decoder.Decode(_rm, ref _state.State); break; diff --git a/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj b/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj index 4c20979dd..095e0e599 100644 --- a/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj +++ b/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj @@ -9,7 +9,7 @@ - + diff --git a/Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs b/Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs new file mode 100644 index 000000000..844f21030 --- /dev/null +++ b/Ryujinx.Graphics.Nvdec/Types/Vp8/PictureInfo.cs @@ -0,0 +1,75 @@ +using Ryujinx.Common.Memory; +using Ryujinx.Graphics.Video; + +namespace Ryujinx.Graphics.Nvdec.Types.Vp8 +{ + struct PictureInfo + { +#pragma warning disable CS0649 + public Array13 Unknown0; + public uint GpTimerTimeoutValue; + public ushort FrameWidth; + public ushort FrameHeight; + public byte KeyFrame; // 1: key frame - 0: not + public byte Version; + public byte Flags0; + // TileFormat : 2 // 0: TBL; 1: KBL; + // GobHeight : 3 // Set GOB height, 0: GOB_2, 1: GOB_4, 2: GOB_8, 3: GOB_16, 4: GOB_32 (NVDEC3 onwards) + // ReserverdSurfaceFormat : 3 + public byte ErrorConcealOn; // 1: error conceal on - 0: off + public uint FirstPartSize; // the size of first partition (frame header and mb header partition) + public uint HistBufferSize; // in units of 256 + public uint VLDBufferSize; // in units of 1 + public Array2 FrameStride; // [y_c] + public uint LumaTopOffset; // offset of luma top field in units of 256 + public uint LumaBotOffset; // offset of luma bottom field in units of 256 + public uint LumaFrameOffset; // offset of luma frame in units of 256 + public uint ChromaTopOffset; // offset of chroma top field in units of 256 + public uint ChromaBotOffset; // offset of chroma bottom field in units of 256 + public uint ChromaFrameOffset; // offset of chroma frame in units of 256 + public uint Flags1; + // EnableTFOutput : 1; // =1, enable dbfdma to output the display surface; if disable, then the following configure on tf is useless. + // Remap for VC1 + // VC1MapYFlag : 1 + // MapYValue : 3 + // VC1MapUVFlag : 1 + // MapUVValue : 3 + // TF + // OutStride : 8 + // TilingFormat : 3; + // OutputStructure : 1 // 0:frame, 1:field + // Reserved0 : 11 + public Array2 OutputTop; // in units of 256 + public Array2 OutputBottom; // in units of 256 + // Histogram + public uint Flags2; + // EnableHistogram : 1 // enable histogram info collection + // HistogramStartX : 12 // start X of Histogram window + // HistogramStartY : 12 // start Y of Histogram window + // Reserved1 : 7 + // HistogramEndX : 12 // end X of Histogram window + // HistogramEndY : 12 // end y of Histogram window + // Reserved2 : 8 + // Decode picture buffer related + public sbyte CurrentOutputMemoryLayout; + public Array3 OutputMemoryLayout; // output NV12/NV24 setting. item 0:golden - 1: altref - 2: last + public byte SegmentationFeatureDataUpdate; + public Array3 Reserved3; + public uint ResultValue; // ucode return result + public Array8 PartitionOffset; + public Array3 Reserved4; +#pragma warning restore CS0649 + + public Vp8PictureInfo Convert() + { + return new Vp8PictureInfo() + { + KeyFrame = KeyFrame != 0, + FirstPartSize = FirstPartSize, + Version = Version, + FrameWidth = FrameWidth, + FrameHeight = FrameHeight + }; + } + } +} diff --git a/Ryujinx.Graphics.Nvdec/Vp8Decoder.cs b/Ryujinx.Graphics.Nvdec/Vp8Decoder.cs new file mode 100644 index 000000000..8a369984e --- /dev/null +++ b/Ryujinx.Graphics.Nvdec/Vp8Decoder.cs @@ -0,0 +1,33 @@ +using Ryujinx.Graphics.Nvdec.FFmpeg.Vp8; +using Ryujinx.Graphics.Nvdec.Image; +using Ryujinx.Graphics.Nvdec.Types.Vp8; +using Ryujinx.Graphics.Video; +using System; + +namespace Ryujinx.Graphics.Nvdec +{ + static class Vp8Decoder + { + public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state) + { + PictureInfo pictureInfo = rm.Gmm.DeviceRead(state.SetPictureInfoOffset); + ReadOnlySpan bitstream = rm.Gmm.DeviceGetSpan(state.SetBitstreamOffset, (int)pictureInfo.VLDBufferSize); + + Decoder decoder = context.GetVp8Decoder(); + + ISurface outputSurface = rm.Cache.Get(decoder, 0, 0, pictureInfo.FrameWidth, pictureInfo.FrameHeight); + + Vp8PictureInfo info = pictureInfo.Convert(); + + uint lumaOffset = state.SetSurfaceLumaOffset[3]; + uint chromaOffset = state.SetSurfaceChromaOffset[3]; + + if (decoder.Decode(ref info, outputSurface, bitstream)) + { + SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset); + } + + rm.Cache.Put(outputSurface); + } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics.Video/Vp8PictureInfo.cs b/Ryujinx.Graphics.Video/Vp8PictureInfo.cs new file mode 100644 index 000000000..878674b8e --- /dev/null +++ b/Ryujinx.Graphics.Video/Vp8PictureInfo.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.Graphics.Video +{ + public ref struct Vp8PictureInfo + { + public bool KeyFrame; + public uint FirstPartSize; + public uint Version; + public ushort FrameWidth; + public ushort FrameHeight; + } +} \ No newline at end of file diff --git a/Ryujinx.sln b/Ryujinx.sln index 9504bbc2d..e0d35bdb5 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -51,8 +51,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.Vp9" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vic", "Ryujinx.Graphics.Vic\Ryujinx.Graphics.Vic.csproj", "{81BB2C11-9408-4EA3-822E-42987AF54429}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.H264", "Ryujinx.Graphics.Nvdec.H264\Ryujinx.Graphics.Nvdec.H264.csproj", "{990F9601-343E-46CB-8529-B498FA761A92}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Video", "Ryujinx.Graphics.Video\Ryujinx.Graphics.Video.csproj", "{FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.OpenAL", "Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj", "{0BE11899-DF2D-4BDE-B9EE-2489E8D35E7D}" @@ -67,7 +65,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "Ryuj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Headless.SDL2", "Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -159,10 +159,6 @@ Global {81BB2C11-9408-4EA3-822E-42987AF54429}.Debug|Any CPU.Build.0 = Debug|Any CPU {81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.ActiveCfg = Release|Any CPU {81BB2C11-9408-4EA3-822E-42987AF54429}.Release|Any CPU.Build.0 = Release|Any CPU - {990F9601-343E-46CB-8529-B498FA761A92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {990F9601-343E-46CB-8529-B498FA761A92}.Debug|Any CPU.Build.0 = Debug|Any CPU - {990F9601-343E-46CB-8529-B498FA761A92}.Release|Any CPU.ActiveCfg = Release|Any CPU - {990F9601-343E-46CB-8529-B498FA761A92}.Release|Any CPU.Build.0 = Release|Any CPU {FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU {FD4A2C14-8E3D-4957-ABBE-3C38897B3E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -195,6 +191,10 @@ Global {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU {390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU + {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Ryujinx/Ryujinx.csproj b/Ryujinx/Ryujinx.csproj index 86afe71e2..aba9b53c5 100644 --- a/Ryujinx/Ryujinx.csproj +++ b/Ryujinx/Ryujinx.csproj @@ -20,7 +20,7 @@ - +