首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过AVPacket (使用libdatachannel)发送ffmpeg AVPacket

如何通过AVPacket (使用libdatachannel)发送ffmpeg AVPacket
EN

Stack Overflow用户
提问于 2022-03-29 11:12:22
回答 2查看 527关注 0票数 2

我用ffmpeg库编码一个视频帧,用压缩数据生成一个AVPacket

由于最近在S/O方面的一些建议,我试图使用WebRTClibdatachannel通过网络发送该帧,特别是通过修改这里的示例:

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向量中:

代码语言:javascript
运行
复制
sample.resize(pkt->size);
memcpy(sample.data(), pkt->data, pkt->size * sizeof(std::byte));    

但是,当试图从这些数据中获取长度值时,包装器就会掉下来。具体来说,在下面的代码中,第一次迭代的长度为1,而第二次,查找索引5,则为1119887324。这对我的数据来说太大了,数据只有3526字节(整个帧是一个很可能很小的颜色,一旦编码):

代码语言:javascript
运行
复制
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;
}

这是一个垃圾场

代码语言:javascript
运行
复制
uint32_t length = ntohl(*lengthPtr);

对于消息的前几个元素(括号中的*lengthPtr):

代码语言:javascript
运行
复制
[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读取编解码器信息。
代码语言:javascript
运行
复制
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_nvench264_mf进行编码。

EN

Stack Overflow用户

发布于 2022-11-14 11:06:11

如果您使用ffmpeg进行h264编码,有时ffmpeg将使用00 00 01作为开始序列,而H264RtpPacketizer::Separator::LongStartSequence只接受00 00 00 01,使用H264RtpPacketizer::Separator::StartSequence可以解决这个问题。

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71660975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档