forked from Ryubing/Ryujinx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
16 changed files
with
220 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...raphics.Nvdec.H264/H264BitStreamWriter.cs → ....Nvdec.FFmpeg/H264/H264BitStreamWriter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 3 additions & 2 deletions
5
...c.H264/Ryujinx.Graphics.Nvdec.H264.csproj → ...mpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<byte> 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<byte>(frame).Slice(uncompHeaderSize)); | ||
|
||
return _context.DecodeFrame(outSurf, frame) == 0; | ||
} | ||
|
||
public void Dispose() => _context.Dispose(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<uint> 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<uint> 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<int> OutputTop; // in units of 256 | ||
public Array2<int> 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<sbyte> OutputMemoryLayout; // output NV12/NV24 setting. item 0:golden - 1: altref - 2: last | ||
public byte SegmentationFeatureDataUpdate; | ||
public Array3<byte> Reserved3; | ||
public uint ResultValue; // ucode return result | ||
public Array8<uint> PartitionOffset; | ||
public Array3<uint> Reserved4; | ||
#pragma warning restore CS0649 | ||
|
||
public Vp8PictureInfo Convert() | ||
{ | ||
return new Vp8PictureInfo() | ||
{ | ||
KeyFrame = KeyFrame != 0, | ||
FirstPartSize = FirstPartSize, | ||
Version = Version, | ||
FrameWidth = FrameWidth, | ||
FrameHeight = FrameHeight | ||
}; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<PictureInfo>(state.SetPictureInfoOffset); | ||
ReadOnlySpan<byte> 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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
Oops, something went wrong.