Does anyone have a simple solution to parse Exp-Golomb code using C ++?

An attempt to decode SDP sprop parameters sets values ​​for the H.264 video stream and found that some of the values ​​will be accessed by parsing data encoded by Exp-Golomb, and my method contains a base64-decoded sprop-parameter - sets the data in an array of bytes which I now walk a bit, but went to the first part of the data encoded in Exp-Golomb, and looked for a suitable code excerpt for analyzing these values.

+3
source share
4 answers

Exp.-Golomb codes of what order? If you need to analyze the H.264 bitstream (I mean the transport layer), you can write simple functions to access scecified bits in an infinite bitstream. Bits indexing from left to right.

inline u_dword get_bit(const u_byte * const base, u_dword offset)
{
    return ((*(base + (offset >> 0x3))) >> (0x7 - (offset & 0x7))) & 0x1;
}

This function implements decoding of zero-range exp-Golomb codes (used in 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 means an unsigned integer of 4 bytes. u_byte means unsigned 1 byte integer.

Note that the first byte of each NAL block is a specified structure with a forbidden bit, a NAL reference, and a NAL type.

+5
source

++ jpeg-ls, golomb. , Exp-Golomb . http://charls.codeplex.com. golomb <= 8 . , .

+2

. .

" 9.1 Exp-Golomb" spec 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);
}
+1

N ; H.264 NALs

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);
}
0

Source: https://habr.com/ru/post/1735042/


All Articles