gpt4 book ai didi

c++ - 如何通过WebRTC发送ffmpeg AVPacket(使用libdatachannel)

转载 作者:行者123 更新时间:2023-12-04 22:47:40 34 4
gpt4 key购买 nike

我正在使用 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 的指针 vector :

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 是否有或缺少一些 header 信息?
  • 如果我只是 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::LengthH264RtpPacketizer::Separator::LongStartSequence ,非常感谢 libdatachannel paullouisageneau 的作者(见下面的答案)
    我遇到了与 libx264 的设置相关的问题编码器,但可以愉快地使用 h264_nvenc 进行编码和 h264_mf

    最佳答案

    streamer example 的输入文件对于 libdatachannel使用 32 位长度作为 NAL 单元分隔符。因此,H264RtpPacketizer使用 H264RtpPacketizer::Separator::Length 创建实例.
    如果我没记错的话,ffmpeg 输出将有 4 字节的起始序列作为 NAL 单元前缀(这实际上更常见),所以如果您将打包程序设置更改为 H264RtpPacketizer::Separator::LongStartSequence它应该接受您的 sample 。

    关于c++ - 如何通过WebRTC发送ffmpeg AVPacket(使用libdatachannel),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71660975/

    34 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com