WebRTC:编码器实现中的RTPFragmentationHeader是什么?

问题描述 投票:2回答:1

我修改了h264_encoder_impl以使用基于nvidia网格的硬件编码器。这是通过用Nvidia API调用替换OpenH264特定调用来完成的。编码流可以成功写入文件,但写_buffer_size encoded_image_是不够的,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->_length,但我不知道如何。

我无法在任何地方找到任何文档。我只有VP8和OpenH264实现。

那么什么是RTPFragmentationHeader?它有什么作用?什么是encoded_image->_length?使用自定义H264编码器时如何正确填充?我可以找到启动码,但下一步是什么?如何填补所有会员?

video video-streaming webrtc h.264 openh264
1个回答
3
投票

经过RTPFragmentize()h264_encoder_impl之后,我发现了它。

在编码帧中有多个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->_length是实际编码帧缓冲区的大小 encoded_image->_size是编码帧缓冲区的最大大小。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.