Ryujinx-uplift/Ryujinx.Graphics/VDec/H264BitStreamWriter.cs
gdkchan c86aacde76
NVDEC implementation using FFmpeg (#443)
* 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
2018-12-03 00:38:47 -02:00

79 lines
1.7 KiB
C#

using System.IO;
namespace Ryujinx.Graphics.VDec
{
class H264BitStreamWriter : BitStreamWriter
{
public H264BitStreamWriter(Stream BaseStream) : base(BaseStream) { }
public void WriteU(int Value, int ValueSize)
{
WriteBits(Value, ValueSize);
}
public void WriteSe(int Value)
{
WriteExpGolombCodedInt(Value);
}
public void WriteUe(int Value)
{
WriteExpGolombCodedUInt((uint)Value);
}
public void End()
{
WriteBit(true);
Flush();
}
private void WriteExpGolombCodedInt(int Value)
{
int Sign = Value <= 0 ? 0 : 1;
if (Value < 0)
{
Value = -Value;
}
Value = (Value << 1) - Sign;
WriteExpGolombCodedUInt((uint)Value);
}
private void WriteExpGolombCodedUInt(uint Value)
{
int Size = 32 - CountLeadingZeros((int)Value + 1);
WriteBits(1, Size);
Value -= (1u << (Size - 1)) - 1;
WriteBits((int)Value, Size - 1);
}
private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
private static int CountLeadingZeros(int Value)
{
if (Value == 0)
{
return 32;
}
int NibbleIdx = 32;
int PreCount, Count = 0;
do
{
NibbleIdx -= 4;
PreCount = ClzNibbleTbl[(Value >> NibbleIdx) & 0b1111];
Count += PreCount;
}
while (PreCount == 4);
return Count;
}
}
}