WebRTC:编码器实现中的 RTPFragmentationHeader 是什么?
WebRTC: What is RTPFragmentationHeader in encoder implementation?
我已经修改 h264_encoder_impl
以使用基于 nvidia 网格的硬件编码器。这是通过将 OpenH264 特定调用替换为 Nvidia API 调用来完成的。编码流可以成功写入文件,但是写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 的实现在 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 由 00 00 00 01
.
的 4 字节起始码分隔
对于 OpenH264,header 第一帧看起来像这样
[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 ..
您可以看到粗体的开始代码。只有方括号之间的字节属于header,最后一个起始码是帧数据。
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 我只使用提供的 header 及其大小,无论是否 header实际上是否添加了框架。仅搜索 header 大小的帧字节允许正确计算碎片。
这样做最终发送了编码数据,并在客户端浏览器上正确解码。
更新: 本质上,我不得不完全跳过RTPFragmentize()
,因为它是专门为OpenH264制作的,并根据上面自己计算frag_header
观察。
我已经修改 h264_encoder_impl
以使用基于 nvidia 网格的硬件编码器。这是通过将 OpenH264 特定调用替换为 Nvidia API 调用来完成的。编码流可以成功写入文件,但是写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 的实现在 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 由 00 00 00 01
.
对于 OpenH264,header 第一帧看起来像这样
[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 ..
您可以看到粗体的开始代码。只有方括号之间的字节属于header,最后一个起始码是帧数据。
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 我只使用提供的 header 及其大小,无论是否 header实际上是否添加了框架。仅搜索 header 大小的帧字节允许正确计算碎片。
这样做最终发送了编码数据,并在客户端浏览器上正确解码。
更新: 本质上,我不得不完全跳过RTPFragmentize()
,因为它是专门为OpenH264制作的,并根据上面自己计算frag_header
观察。