【问题标题】:WebRTC: What is RTPFragmentationHeader in encoder implementation?WebRTC:编码器实现中的 RTPFragmentationHeader 是什么?
【发布时间】:2018-01-19 19:23:31
【问题描述】:

我已修改 h264_encoder_impl 以使用基于 nvidia 网格的硬件编码器。这是通过用 Nvidia API 调用替换 OpenH264 特定调用来完成的。编码流可以写入文件成功,但写入encoded_image__buffer_size还不够,还需要填写RTPFragmentationHeader

// RtpFragmentize(EncodedImage* encoded_image,
//                       std::unique_ptr<uint8_t[]>* encoded_image_buffer,
//                       const VideoFrameBuffer& frame_buffer,
//                       SFrameBSInfo* info,
//                      RTPFragmentationHeader* frag_header)

// encode
openh264_->Encode(input, &info /*out*/);

// fragmentize ?
RtpFragmentize(&encoded_image_ /*out*/, &encoded_image_buffer_, *frame_buffer, 
               &info, &frag_header /*out*/); 

// ...

// send 
encoded_image_callback_->OnEncodedImage(encoded_image_, &codec_specific, &frag_header);

当前基于 Openh264 的实现将 frag_header 填充到 RTPFragmentize() 中,而 VP8 以不同方式填充它。我可以看到 NAL untis 和层也计算 encoded_image-&gt;_length 但我不知道如何。

我在任何地方都找不到任何文档。 VP8 和 OpenH264 实现就是我所拥有的。

那么RTPFragmentationHeader 是什么?它有什么作用? encoded_image-&gt;_length 是什么?使用自定义H264编码器时如何正确填充?我可以找到起始码,但接下来呢?如何填写其所有成员?

【问题讨论】:

    标签: video video-streaming webrtc h.264 openh264


    【解决方案1】:

    h264_encoder_impl 中经过RTPFragmentize() 之后,我想通了。

    在一个编码帧中有多个 NALU。有不同的 NALU,包括 AUD、SPS (67)、PPS (68) 和 IDR。每个 NALU 由 4 字节的起始码分隔,即00 00 00 01

    对于 OpenH264,第一帧的标题看起来像这样

    [00 00 00 01 67 42 c0 20 8c 8d 40 20 03 09 00 f0 88 46 a0 00 00 00 01 68 ce 3c 80]00 00 00 01 ..

    您可以看到粗体的起始代码。只有方括号之间的字节属于头部,最后一个起始码是帧数据。

    RTPFragmentationHeader 以上:

    frag_header->fragmentationVectorSize = 3     // 2 fragments for header
                                                 // 3rd fragment for frame buffer
    
    frag_header->fragmentationOffset[0]  = 4     
    frag_header->fragmentationLength[0]  = 15
    
    frag_header->fragmentationOffset[1]  = 23    // 4 + 15 + sizeof(startcode)
    frag_header->fragmentationLength[1]  = 4    
    
    frag_header->fragmentationOffset[2]  = 31   
    frag_header->fragmentationLength[2]  = 43218 // last fragment is frame buffer
    

    下一帧总是只有一个片段,看起来像下面

    00 00 00 01 67 b8 .. .. ..
    

    encoded_image-&gt;_length 是实际编码帧缓冲区的大小,
    encoded_image-&gt;_size 是编码帧缓冲区的最大大小。

    OpenH264 API 给出了编码帧中的 NALU 数量,用于计算片段,而我使用的 API 仅提供了标头及其大小,无论标头是否实际添加了帧。仅针对标头大小搜索帧字节允许正确计算分段。

    这样做最终发送了编码数据,并在客户端浏览器上正确解码。

    更新:本质上,我不得不完全跳过RTPFragmentize(),因为它是专门为OpenH264制作的,并根据上述观察自己计算frag_header

    【讨论】:

      猜你喜欢
      • 2021-05-19
      • 2020-01-12
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      相关资源
      最近更新 更多