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

标签 video video-streaming webrtc h.264 openh264

我修改了 h264_encoder_impl 以使用基于 nvidia 网格的硬件编码器。这是通过将 OpenH264 特定调用替换为 Nvidia API 调用来完成的。编码流可以成功写入文件,但是写入_bufferencoded_image__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 的实现在 RTPFragmentize() 中填充 frag_header,而 VP8 以不同的方式填充它。我可以看到一些 NAL untis 和层也计算 encoded_image->_length 但我不知道如何计算。

我在任何地方都找不到关于它的任何文档。我只有 VP8 和 OpenH264 实现。

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

最佳答案

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 .. 

You can see start code in bold. Only bytes between square brackets belong to header, last start code is for frame data.

RTPFragmentationHeader for above:

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 仅提供 header 及其大小,无论 header 是否实际添加到帧中。仅针对 header 的大小搜索帧字节允许正确计算分段。

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

更新:本质上,我必须完全跳过 RTPFragmentize(),因为它是专门为 OpenH264 制作的,并且我自己计算 frag_header基于以上观察。

关于video - WebRTC:编码器实现中的 RTPFragmentationHeader 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45632432/

相关文章:

android - 如何在 Amazon Fire TV 的 WebView 中播放 YouTube 视频?

javascript - getUserMedia() 的解析约束无法正常工作 (WebRTC)

javascript - Node 应用程序,完全有效的 JSON, "d"怎么没有定义?

go - 使 httputil.ReverseProxy 转发响应流正确

ffmpeg - ffserver 有哪些替代方案?

ffmpeg - 如何检测转换文件中存在的音频或视频或两者

ios - 使用 react-native-webrtc 断开视频通话

iOS 4 : video quality with AVAsset based application

jquery - 如何在父 Bootstrap Collapse 面板折叠时动态暂停视频?

android - 是否使用 libgdx 在 android 中进行屏幕录制