mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2024-12-23 12:25:44 +00:00
c86aacde76
* Initial nvdec implementation using FFmpeg * Fix swapped channels on the video decoder and the G8R8 texture format * Fix texture samplers not being set properly (regression) * Rebased * Remove unused code introduced on the rebase * Add support for RGBA8 output format on the video image composer * Correct spacing * Some fixes for rebase and other tweaks * Allow size mismatch on frame copy * Get rid of GetHostAddress calls on VDec
134 lines
No EOL
3.6 KiB
C#
134 lines
No EOL
3.6 KiB
C#
using System.IO;
|
|
|
|
namespace Ryujinx.Graphics.VDec
|
|
{
|
|
class VpxRangeEncoder
|
|
{
|
|
private const int HalfProbability = 128;
|
|
|
|
private static readonly int[] NormLut = new int[]
|
|
{
|
|
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
private Stream BaseStream;
|
|
|
|
private uint LowValue;
|
|
private uint Range;
|
|
private int Count;
|
|
|
|
public VpxRangeEncoder(Stream BaseStream)
|
|
{
|
|
this.BaseStream = BaseStream;
|
|
|
|
Range = 0xff;
|
|
Count = -24;
|
|
|
|
Write(false);
|
|
}
|
|
|
|
public void WriteByte(byte Value)
|
|
{
|
|
Write(Value, 8);
|
|
}
|
|
|
|
public void Write(int Value, int ValueSize)
|
|
{
|
|
for (int Bit = ValueSize - 1; Bit >= 0; Bit--)
|
|
{
|
|
Write(((Value >> Bit) & 1) != 0);
|
|
}
|
|
}
|
|
|
|
public void Write(bool Bit)
|
|
{
|
|
Write(Bit, HalfProbability);
|
|
}
|
|
|
|
public void Write(bool Bit, int Probability)
|
|
{
|
|
uint Range = this.Range;
|
|
|
|
uint Split = 1 + (((Range - 1) * (uint)Probability) >> 8);
|
|
|
|
Range = Split;
|
|
|
|
if (Bit)
|
|
{
|
|
LowValue += Split;
|
|
Range = this.Range - Split;
|
|
}
|
|
|
|
int Shift = NormLut[Range];
|
|
|
|
Range <<= Shift;
|
|
Count += Shift;
|
|
|
|
if (Count >= 0)
|
|
{
|
|
int Offset = Shift - Count;
|
|
|
|
if (((LowValue << (Offset - 1)) >> 31) != 0)
|
|
{
|
|
long CurrentPos = BaseStream.Position;
|
|
|
|
BaseStream.Seek(-1, SeekOrigin.Current);
|
|
|
|
while (BaseStream.Position >= 0 && PeekByte() == 0xff)
|
|
{
|
|
BaseStream.WriteByte(0);
|
|
|
|
BaseStream.Seek(-2, SeekOrigin.Current);
|
|
}
|
|
|
|
BaseStream.WriteByte((byte)(PeekByte() + 1));
|
|
|
|
BaseStream.Seek(CurrentPos, SeekOrigin.Begin);
|
|
}
|
|
|
|
BaseStream.WriteByte((byte)(LowValue >> (24 - Offset)));
|
|
|
|
LowValue <<= Offset;
|
|
Shift = Count;
|
|
LowValue &= 0xffffff;
|
|
Count -= 8;
|
|
}
|
|
|
|
LowValue <<= Shift;
|
|
|
|
this.Range = Range;
|
|
}
|
|
|
|
private byte PeekByte()
|
|
{
|
|
byte Value = (byte)BaseStream.ReadByte();
|
|
|
|
BaseStream.Seek(-1, SeekOrigin.Current);
|
|
|
|
return Value;
|
|
}
|
|
|
|
public void End()
|
|
{
|
|
for (int Index = 0; Index < 32; Index++)
|
|
{
|
|
Write(false);
|
|
}
|
|
}
|
|
}
|
|
} |