首页
学习
活动
专区
圈层
工具
发布

RTP脱碳
EN

Stack Overflow用户
提问于 2014-08-18 11:27:34
回答 1查看 3.1K关注 0票数 2

我正试图解析RTP视频流,以便为H264解码器做准备。

这是Wireshark捕获的数据包流--首先我试图找到IDR片、SPS和PPS参数,所以这就是https://dl.dropboxusercontent.com/u/76817805/frame.pcapng

接下来我要做的是:

1)查找PPS数据并将它们复制到NAL单元中,使用0x000x000x01启动序列,将它们复制到去depacketization缓冲区中。

0001\ SPS

2)用于以0x7C 0x85启动的数据包--我正在重建第一个NAL (在我的情况下为0x65),并将0x7C0x85的数据折叠到带有开始序列的去case缓冲区中。

00 0001 65视频数据.

3)以0x7C0x05启动的数据包的--除了两个头字节之外,我要将数据复制到去加密缓冲区中。

.....视频数据.

4)用于以0x7C 0x45启动的数据包,我正在将数据复制(除了两个第一个字节外)到去into缓冲区。.....视频数据(最后字节)

5)对于不分段的数据包,我只是使用开始序列将数据复制到脱噪缓冲区中。

0001\x{e76f} NALu

所以在解析示例视频流之后,我得到了这个二进制文件 https://dl.dropboxusercontent.com/u/76817805/raw.264,但是不能正确解码。

有人能帮我找到我算法中的错误吗?我做错了什么?非常感谢大家。

代码语言:javascript
复制
UInt32 parseRTP( Uint8 * buf, int inputDataLen, Uint32 curAdr)
{
int result_len = 0;

// filter zero bytes at the end of packet

for (i = inputDataLen-1; i>0; i--)
{
    if (buf[i] == 0x00) inputDataLen--;
    else break;
}

// get NAL type
nal = buf[0];
type = (nal & 0x1f);

if ((buf[0] == 0x7C) && (buf[1] == 0x85)) IFrameisOK = 1; // Start of I frame

if (type == 6)
    return 0;

if (type == 7) // new SPS
{
    memcpy((void*)sps, start_sequence, sizeof(start_sequence));
    memcpy((void*)(sps + sizeof(start_sequence)), buf, inputDataLen);
    sps_len = inputDataLen + sizeof(start_sequence);
    SPSisOK = 1;
    return 0;
}

if (type == 8) // new PPS
{
    memcpy((void*)pps, start_sequence, sizeof(start_sequence));
    memcpy((void*)(pps + sizeof(start_sequence)), buf, inputDataLen);
    pps_len = inputDataLen + sizeof(start_sequence);
    PPSisOK = 1;
    return 0;
}



if (SPSisOK == 1 && PPSisOK == 1)
{
    if (IFrameisOK == 0) return 0; // wait I-frame

    /*  Simplify the case.
        These are all the nal types used internally by the h264 codec
     */
    if (type >= 1 && type <= 23) type = 1;
    switch (type)
        {
            case 0: // undefined;
                break;

            case 1:
                // copy start sequence

                memcpy((void*)curAdr, start_sequence, sizeof(start_sequence));
                curAdr += sizeof(start_sequence);

                // copy data
                memcpy((void*)curAdr, buf, inputDataLen);
                curAdr += inputDataLen;

                result_len = sizeof(start_sequence) +  inputDataLen;
                break;

            case 24: // STAP-A (one packet, multiple nals)  not used in this project
                break;
            case 25: // STAP-B
            case 26: // MTAP-16
            case 27: // MTAP-24
            case 29: // FU-B
                //not used in this project
                break;
            case 28: // FU-A (fragmented nal)

                inputDataLen -= 2; // delete 2 first bytes for fragmented units
                //skip the fu_indicator
                buf++;

                Uint8 fu_indicator = nal;
                Uint8 fu_header = *buf; // read the fu_header.
                Uint8 start_bit = fu_header >> 7;
                Uint8 reconstructed_nal;
                Uint8 nal_type = (fu_header & 0x1f);


                /* reconstruct this packet's true nal; only the
                data follows..*/
                reconstructed_nal = fu_indicator & (0xe0);

                /*the original nal forbidden bit and NRI are stored in this
                packet's nal*/
                reconstructed_nal |= nal_type;

                // skip the fu_header...
                buf++;

                if(start_bit)
                {
                    if (NEED_CONFIGS)
                    {
                        // copy SPS and PPS first
                        memcpy((void*)curAdr, sps, sps_len);
                        curAdr += sps_len;

                        memcpy((void*)curAdr, pps, pps_len);
                        curAdr += pps_len;

                    }

                    // copy in the start sequence
                    memcpy((void*)curAdr, start_sequence, sizeof(start_sequence));
                    curAdr += sizeof(start_sequence);


                    // copy reconstructed nal
                    memcpy((void*)curAdr,&reconstructed_nal, sizeof(reconstructed_nal));
                    curAdr += sizeof(reconstructed_nal);


                    // copy payload
                    memcpy((void*)curAdr,buf, inputDataLen);
                    curAdr += inputDataLen;

                    if (NEED_CONFIGS)
                    {
                        result_len = (sps_len + pps_len + sizeof(start_sequence) + sizeof(reconstructed_nal) + inputDataLen);
                        NEED_CONFIGS = 0;
                    }
                    else
                    {
                        result_len += (sizeof(start_sequence) + sizeof(reconstructed_nal) + inputDataLen);
                    }

                }
                else
                {

                    memcpy((void*)curAdr,buf, inputDataLen);
                    curAdr += inputDataLen;

                    result_len = inputDataLen;
                }


                break;
            default:
                break;
        }
    return result_len;
}
else
{
    return 0;
}

}

EN

回答 1

Stack Overflow用户

发布于 2014-08-18 11:38:40

Depacketization规则是用用于H.264视频的RFC 6184 - RTP有效负载格式描述的,您应该遵循它们,而不是尝试发明自己的规则。

您的假设是,在片段前面加上00 00 01 65是在重构NAL单元,这是不正确的。

其想法是,这个NAL单元太大,无法容纳单个数据包,然后它被分割成几个部分。您将接收多个RTP片段,然后将它们合并成单个NAL单元,以完整和原始状态重构它。见第5.8条。零碎单位(FUs)的细节。

而不是按照上面提到的,您只是简单地将00 00 01 65添加到NAL单元的每个部分--这预期不会产生可解码的输出。

另请参阅:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25362239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档