我用ffmpeg
库编码一个视频帧,用压缩数据生成一个AVPacket
。
由于最近在S/O方面的一些建议,我试图使用WebRTC
库libdatachannel
通过网络发送该帧,特别是通过修改这里的示例:
https://github.com/paullouisageneau/libdatachannel/tree/master/examples/streamer
我在h264rtppacketizer.cpp
(库的一部分,而不是示例)中看到了问题,这些问题几乎肯定与我提供示例数据的方式有关。(我不认为这与libdatachannel有任何关系,具体而言,这将与我发送的内容有关)
示例代码从文件中读取每个编码的帧,并通过将文件的内容设置为文件的内容来填充sample
:
sample = *reinterpret_cast<vector<byte> *>(&fileContents);
sample
只是一个std::vector<byte>;
我天真地将AVPacket->data
指针的内容复制到sample
向量中:
sample.resize(pkt->size);
memcpy(sample.data(), pkt->data, pkt->size * sizeof(std::byte));
但是,当试图从这些数据中获取长度值时,包装器就会掉下来。具体来说,在下面的代码中,第一次迭代的长度为1,而第二次,查找索引5,则为1119887324。这对我的数据来说太大了,数据只有3526字节(整个帧是一个很可能很小的颜色,一旦编码):
while (index < message->size()) {
assert(index + 4 < message->size());
auto lengthPtr = (uint32_t *)(message->data() + index);
uint32_t length = ntohl(*lengthPtr);
auto naluStartIndex = index + 4;
auto naluEndIndex = naluStartIndex + length;
assert(naluEndIndex <= message->size());
auto begin = message->begin() + naluStartIndex;
auto end = message->begin() + naluEndIndex;
nalus->push_back(std::make_shared<NalUnit>(begin, end));
index = naluEndIndex;
}
这是一个垃圾场
uint32_t length = ntohl(*lengthPtr);
对于消息的前几个元素(括号中的*lengthPtr
):
[2022-03-29 15:12:01.182] [info] index 0: 1 (16777216)
[2022-03-29 15:12:01.183] [info] index 1: 359 (1728118784)
[2022-03-29 15:12:01.184] [info] index 2: 91970 (1114046720)
[2022-03-29 15:12:01.186] [info] index 3: 23544512 (3225577217)
[2022-03-29 15:12:01.186] [info] index 4: 1732427807 (532693607)
[2022-03-29 15:12:01.187] [info] index 5: 1119887324 (3693068354)
[2022-03-29 15:12:01.188] [info] index 6: 3223313413 (98312128)
[2022-03-29 15:12:01.188] [info] index 7: 534512896 (384031)
[2022-03-29 15:12:01.188] [info] index 8: 3691315291 (1526728156)
[2022-03-29 15:12:01.189] [info] index 9: 83909537 (2707095557)
[2022-03-29 15:12:01.189] [info] index 10: 6004992 (10574592)
[2022-03-29 15:12:01.190] [info] index 11: 1537277952 (41307)
[2022-03-29 15:12:01.190] [info] index 12: 2701131779 (50331809)
[2022-03-29 15:12:01.192] [info] index 13: 768 (196608)
(我知道我应该贴一个完整的样本,我正在做)
AVPacket
side_data
做一些事情,AVPacket是否有或遗漏了一些标题信息?fwrite
pkt->data
,则可以使用ffprobe
读取编解码器信息。Input #0, h264, from 'encodedOut.h264':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 1280x720, 30 tbr, 1200k tbn
更新:这个问题是通过将H264RtpPacketizer
分隔符设置从H264RtpPacketizer::Separator::Length
更改为H264RtpPacketizer::Separator::LongStartSequence
来解决的,这要感谢libdatachannel [医]黄豆的作者(见下面的答案)。
我有与libx264
编码器的设置相关的问题,但可以很高兴地使用h264_nvenc
和h264_mf
进行编码。
发布于 2022-11-14 11:06:11
如果您使用ffmpeg进行h264编码,有时ffmpeg将使用00 00 01
作为开始序列,而H264RtpPacketizer::Separator::LongStartSequence
只接受00 00 00 01
,使用H264RtpPacketizer::Separator::StartSequence
可以解决这个问题。
https://stackoverflow.com/questions/71660975
复制相似问题