有谁有一个简单的解决方案来使用 C++ 解析 Exp-Golomb 代码?

发布于 2024-08-23 15:39:21 字数 180 浏览 7 评论 0原文

尝试解码 H.264 视频流的 SDP sprop-parameter-sets 值,并发现访问某些值将涉及解析 Exp-Golomb 编码数据,我的方法包含 base64 解码的 sprop-parameter-sets 数据一个字节数组,我现在有点步行,但已经到达 Exp-Golomb 编码数据的第一部分,并寻找合适的代码提取来解析这些值。

Trying to decode the SDP sprop-parameter-sets values for an H.264 video stream and have found to access some of the values will involve parsing of Exp-Golomb encoded data and my method contains the base64 decoded sprop-parameter-sets data in a byte array which I now bit walking but have come up to the first part of Exp-Golomb encoded data and looking for a suitable code extract to parse these values.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

十年不长 2024-08-30 15:39:21

Exp.-Golomb 代码的顺序是什么?
如果您需要解析 H.264 位流(我的意思是传输层),您可以编写一个简单的函数来访问无限位流中的指定位。位索引从左到右。

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

该函数实现零范围指数哥伦布码(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 类型的指定结构。

Exp.-Golomb codes of what order ??
If it you need to parse H.264 bit stream (I mean transport layer) you can write a simple functions to make an access to scecified bits in the endless bit stream. 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 implement decoding of exp-Golomb codes of zero range (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 unsigned 4 bytes integer.
u_byte means unsigned 1 byte integer.

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

喵星人汪星人 2024-08-30 15:39:21

接受的答案不是正确的实现。它给出了错误的输出。根据伪代码正确实现

“Exp-Golomb 代码的第 9.1 节解析过程”规范 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);
}

Accepted answer is not a correct implementation. It is giving wrong output. Correct implementation as per pseudo code from

"Sec 9.1 Parsing process for Exp-Golomb codes" 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);
}
喜爱皱眉﹌ 2024-08-30 15:39:21

我编写了一个使用 golomb 代码的 c++ jpeg-ls 压缩库。我不知道Exp-Golomb码是否完全相同。该库是开源的,可以在 http://charls.codeplex.com 找到。我使用查找表来解码长度 <= 8 位的哥伦布码。如果您在寻找出路时遇到问题,请告诉我。

I wrote a c++ jpeg-ls compression library that uses golomb codes. I don't know if Exp-Golomb codes is exactly the same. The library is open source can be found at http://charls.codeplex.com. I use a lookup table to decode golomb codes <= 8 bits in length. Let me know if you have problems finding your way around.

孤千羽 2024-08-30 15:39:21

修改为从流中获取 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);
}

Revised with a function to get N bits from the stream; works parsing 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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文