У кого-нибудь есть простое решение для разбора кодов Exp-Golomb с использованием С++?

Попытка декодировать значения наборов параметров sprop-параметров SDP для видеопотока H.264 и обнаружение доступа к некоторым значениям потребует синтаксического анализа данных, закодированных Exp-Golomb, и мой метод содержит декодированные в base64 данные наборов параметров sprop в массив байтов, который я сейчас немного прогуливаюсь, но подошел к первой части данных, закодированных Exp-Golomb, и искал подходящий фрагмент кода для анализа этих значений.


person Jonathan Websdale    schedule 02.03.2010    source источник
comment
Откуда вы узнали, что содержится в sprop-parameter-sets?! Я ищу в Интернете безрезультатно... =| Можно ссылку на документацию?! Меня интересует расшифровка размера видео... спасибо   -  person Cipi    schedule 04.03.2010
comment
Эй, я нашел это: vcodex.com/files/h264_vlc.pdf   -  person Cipi    schedule 04.03.2010
comment
За содержимым наборов параметров sprop мне пришлось обратиться к следующему документу ISO/IEC 14496-10:2005, за который, боюсь, вам придется заплатить. Раздел 7.3.2.1.   -  person Jonathan Websdale    schedule 08.03.2010
comment
Требуемую спецификацию можно бесплатно загрузить с веб-сайта МСЭ здесь: - itu.int/rec/T-REC-H.264-200903-I/en Выберите бесплатно загружаемый файл PDF, и вы найдете формат, подробно описанный в разделе 7.3.2.1.1. Извините, я не был тупым с моим предыдущим ответом, просто не знал, что информация доступна в открытом доступе.   -  person Jonathan Websdale    schedule 12.03.2010


Ответы (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.

person t0k3n1z3r    schedule 12.08.2012
comment
Это называется порядок, а не диапазон - person anatolyg; 12.08.2012
comment
Может быть, это было несколько лет назад. Прости! - person t0k3n1z3r; 13.08.2012
comment
Я понимаю, что этот пост устарел, но я просто хочу сказать, что это самая элегантная реализация декодирования ExpGolomb, которую я когда-либо видел! Я приветствую вас t0k3n1z3r !!! - person Andres Gonzalez; 04.02.2014
comment
рада, что пригодилось) - person t0k3n1z3r; 04.02.2014
comment
Баг: убрать голый (*offset)++ после информации u_dword.... В противном случае он съедает слишком много бит и сбрасывает все последующие декодирования. - person jesup; 01.05.2014

Я написал библиотеку сжатия jpeg-ls на С++, которая использует коды голомба. Я не знаю, совпадают ли коды Exp-Golomb. Библиотеку с открытым исходным кодом можно найти по адресу http://charls.codeplex.com. Я использую таблицу поиска для декодирования кодов голомба длиной ‹= 8 бит. Дайте мне знать, если у вас возникнут проблемы с поиском пути.

person Community    schedule 03.03.2010

Принятый ответ не является правильной реализацией. Это дает неправильный вывод. Правильная реализация согласно псевдокоду из

«Разд. 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);
}
person Alam    schedule 03.10.2016

Переработано с функцией получения 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);
}
person jesup    schedule 30.04.2014