Decoder.cs
1 using Ryujinx.Graphics.Nvdec.FFmpeg.Native; 2 using Ryujinx.Graphics.Video; 3 using System; 4 5 namespace Ryujinx.Graphics.Nvdec.FFmpeg.Vp8 6 { 7 public sealed class Decoder : IDecoder 8 { 9 public bool IsHardwareAccelerated => false; 10 11 private readonly FFmpegContext _context = new(AVCodecID.AV_CODEC_ID_VP8); 12 13 public ISurface CreateSurface(int width, int height) 14 { 15 return new Surface(width, height); 16 } 17 18 public bool Decode(ref Vp8PictureInfo pictureInfo, ISurface output, ReadOnlySpan<byte> bitstream) 19 { 20 Surface outSurf = (Surface)output; 21 22 int uncompHeaderSize = pictureInfo.KeyFrame ? 10 : 3; 23 24 byte[] frame = new byte[bitstream.Length + uncompHeaderSize]; 25 26 uint firstPartSizeShifted = pictureInfo.FirstPartSize << 5; 27 28 frame[0] = (byte)(pictureInfo.KeyFrame ? 0 : 1); 29 frame[0] |= (byte)((pictureInfo.Version & 7) << 1); 30 frame[0] |= 1 << 4; 31 frame[0] |= (byte)firstPartSizeShifted; 32 frame[1] |= (byte)(firstPartSizeShifted >> 8); 33 frame[2] |= (byte)(firstPartSizeShifted >> 16); 34 35 if (pictureInfo.KeyFrame) 36 { 37 frame[3] = 0x9d; 38 frame[4] = 0x01; 39 frame[5] = 0x2a; 40 frame[6] = (byte)pictureInfo.FrameWidth; 41 frame[7] = (byte)((pictureInfo.FrameWidth >> 8) & 0x3F); 42 frame[8] = (byte)pictureInfo.FrameHeight; 43 frame[9] = (byte)((pictureInfo.FrameHeight >> 8) & 0x3F); 44 } 45 46 bitstream.CopyTo(new Span<byte>(frame)[uncompHeaderSize..]); 47 48 return _context.DecodeFrame(outSurf, frame) == 0; 49 } 50 51 public void Dispose() => _context.Dispose(); 52 } 53 }