| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- 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;
- }
- }
- }
|