Попытка декодировать значения наборов параметров sprop-параметров SDP для видеопотока H.264 и обнаружение доступа к некоторым значениям потребует синтаксического анализа данных, закодированных Exp-Golomb, и мой метод содержит декодированные в base64 данные наборов параметров sprop в массив байтов, который я сейчас немного прогуливаюсь, но подошел к первой части данных, закодированных Exp-Golomb, и искал подходящий фрагмент кода для анализа этих значений.
У кого-нибудь есть простое решение для разбора кодов Exp-Golomb с использованием С++?
Ответы (4)
Эксп.-коды Голомба какого порядка?? Если вам нужно проанализировать битовый поток H.264 (я имею в виду транспортный уровень), вы можете написать простые функции, чтобы сделать доступ к заданным битам в бесконечном битовом потоке. Биты индексируются слева направо.
inline u_dword get_bit(const u_byte * const base, u_dword offset)
{
return ((*(base + (offset >> 0x3))) >> (0x7 - (offset & 0x7))) & 0x1;
}
Эта функция реализует декодирование кодов exp-Golomb нулевого диапазона (используется в H.264).
u_dword DecodeUGolomb(const u_byte * const base, u_dword * const offset)
{
u_dword zeros = 0;
// calculate zero bits. Will be optimized.
while (0 == get_bit(base, (*offset)++)) zeros++;
// insert first 1 bit
u_dword info = 1 << zeros;
for (s_dword i = zeros - 1; i >= 0; i--)
{
info |= get_bit(base, (*offset)++) << i;
}
return (info - 1);
}
u_dword означает беззнаковое 4-байтовое целое число. u_byte означает беззнаковое 1-байтовое целое.
Обратите внимание, что первый байт каждого блока NAL представляет собой определенную структуру с запрещенным битом, ссылкой NAL и типом NAL.
Я написал библиотеку сжатия jpeg-ls на С++, которая использует коды голомба. Я не знаю, совпадают ли коды Exp-Golomb. Библиотеку с открытым исходным кодом можно найти по адресу http://charls.codeplex.com. Я использую таблицу поиска для декодирования кодов голомба длиной ‹= 8 бит. Дайте мне знать, если у вас возникнут проблемы с поиском пути.
Принятый ответ не является правильной реализацией. Это дает неправильный вывод. Правильная реализация согласно псевдокоду из
«Разд. 9.1 Процесс синтаксического анализа кодов Exp-Golomb», спецификация T-REC-H.264-201304
int32_t getBitByPos(unsigned char *buffer, int32_t pos) {
return (buffer[pos/8] >> (8 - pos%8) & 0x01);
}
uint32_t decodeGolomb(unsigned char *byteStream, uint32_t *index) {
uint32_t leadingZeroBits = -1;
uint32_t codeNum = 0;
uint32_t pos = *index;
if (byteStream == NULL || pos == 0 ) {
printf("Invalid input\n");
return 0;
}
for (int32_t b = 0; !b; leadingZeroBits++)
b = getBitByPos(byteStream, pos++);
for (int32_t b = leadingZeroBits; b > 0; b--)
codeNum = codeNum | (getBitByPos(byteStream, pos++) << (b - 1));
*index = pos;
return ((1 << leadingZeroBits) - 1 + codeNum);
}
Переработано с функцией получения N битов из потока; работает парсинг H.264 NAL
inline uint32_t get_bit(const uint8_t * const base, uint32_t offset)
{
return ((*(base + (offset >> 0x3))) >> (0x7 - (offset & 0x7))) & 0x1;
}
inline uint32_t get_bits(const uint8_t * const base, uint32_t * const offset, uint8_t bits)
{
uint32_t value = 0;
for (int i = 0; i < bits; i++)
{
value = (value << 1) | (get_bit(base, (*offset)++) ? 1 : 0);
}
return value;
}
// This function implement decoding of exp-Golomb codes of zero range (used in H.264).
uint32_t DecodeUGolomb(const uint8_t * const base, uint32_t * const offset)
{
uint32_t zeros = 0;
// calculate zero bits. Will be optimized.
while (0 == get_bit(base, (*offset)++)) zeros++;
// insert first 1 bit
uint32_t info = 1 << zeros;
for (int32_t i = zeros - 1; i >= 0; i--)
{
info |= get_bit(base, (*offset)++) << i;
}
return (info - 1);
}