FFmpeg/libav 将 AVPacket 数据存储在文件中并在不同的流中再次对其进行解码 - 如何在解码器中准备和发送自定义数据包?

FFmpeg/libav Storing AVPacket data in a file and decoding them again in a different stream - How to prepare and send custom packets in the decoder?

我希望能够打开带有视频文件的流,并在解码器中发送我自己的数据包,其中包含我之前使用相同编解码器从不同流存储的数据。所以喜欢在解码器中伪造我自己的数据包。

我的方法是使用 H.265 将帧编码为数据包并将数据存储在这样的文件中:

AVPacket *packet;
std::vector<uint8_t> data;
...encoding...
data->insert(data->end(), &packet->data[0], &packet->data[packet->size]);
...storing the buffer in a file...

我也有一个mkv视频,H.265码流参数相同。现在我想获取文件中存储的包数据,新建一个包,送入mkv文件的解码过程。为了方便起见,我只是将 mkv 流中第一个数据包的参数复制到一个新数据包中,我在其中插入数据并将其发送到解码器。这是正确的做法吗?

...open decoder with mkv file...
auto packet = av_packet_alloc();
av_read_frame(formatContext, packet);
//here is the packet I will use later with my data
av_packet_copy_props(decodingPacket, packet);
decodingPacket->flags = 0;
//sending the packet from the mkv
avcodec_send_packet(codecContext, packet);
//the data contains the previously stored data
av_packet_from_data(decodingPacket, data.data(), data.size());
avcodec_send_packet(codecContext, decodingPacket);
...retrieving the frame...

但是,当我尝试发送遗忘数据包时出现此错误:

Assertion buf_size >= 0 failed at libavcodec/bytestream.h:141

我曾尝试手动更改 decodingPacket->buf->size 但这可能不是问题所在。我相信我需要在伪造的数据包中设置一些其他参数,但具体是什么?也许我还可以以某种方式不仅存储数据包数据而且存储整个结构?请让我知道,如果有更好的方法来存储和重新加载数据包并将其强制进入具有相同参数的不相关解码器。 谢谢!

编辑:似乎 buf_size 问题与我错误检索的数据有关。我可以确认这现在有效,但我收到一个新错误:

[hevc @ 0x559b931606c0] Invalid NAL unit size (0 > 414).
[hevc @ 0x559b931606c0] Error splitting the input into NAL units.

所以我上面描述的过程似乎是正确且可行的!我的问题是数据包不一致。编码器和解码器需要完全相同(某些编解码器参数显然可以产生不同类型的数据包)。实现这一目标的最简单方法是创建一个用于初始化解码器的最小参考文件。 NAL 的问题可能是由 h.265 的不同流格式引起的。 This great answer 帮助我识别了它!输出格式影响数据包数据,例如,当有原始数据和使用附件 B 时,有必要插入起始代码,如:

data.insert(data.begin(), {0,0,0,1});