简体   繁体   English

ffmpeg c++ API 用 KLV 数据流编码 mpegts

[英]ffmpeg c++ API encode mpegts with KLV data stream

I need to encode an mpegts video using the ffmpeg C++ API.我需要使用 ffmpeg C++ API 对 mpegts 视频进行编码。 The output video shall have two streams: the first one shall be of type AVMEDIA_TYPE_VIDEO;输出视频应有两个流:第一个应为 AVMEDIA_TYPE_VIDEO 类型; the second one shall be of type AVMEDIA_TYPE_DATA and shall contain a set of KLV data.第二个应该是 AVMEDIA_TYPE_DATA 类型并且应该包含一组 KLV 数据。

I have written my own KLV library to manage the KLV format.我编写了自己的 KLV 库来管理 KLV 格式。

However I'm not able to create "from scratch" a new video by combining the two streams.但是,我无法通过组合两个流来“从头开始”创建新视频。 Following the implementation as in FFMPEG C api h.264 encoding / MPEG2 ts streaming problems I can successfully encode a mpegts video with a single video stream.按照FFMPEG C api h.264 编码/MPEG2 ts 流问题中的实现,我可以使用单个视频流成功编码 mpegts 视频。

However I'm not able to add a new AVMEDIA_TYPE_DATA stream to the output video since, as soon as I add a new data stream using methods like avformat_new_stream(...) the output video is empty: neither the data stream nor the video one are produced and the output file is empty.但是,我无法向输出视频添加新的 AVMEDIA_TYPE_DATA 流,因为一旦我使用 avformat_new_stream(...) 等方法添加新的数据流,输出视频就为空:数据流和视频都不是生成并且输出文件为空。

Can anyone suggest me a tutorial page or a sample on how to properly add a data stream to my output video in mpegts format?任何人都可以向我建议有关如何以 mpegts 格式将数据流正确添加到我的输出视频的教程页面或示例吗?

Thanks a lot!非常感谢!

I was able to get a KLV stream added to a muxed output by starting with the "muxing.c" example that comes with the FFmpeg source, and modifying it as follows.通过从 FFmpeg 源附带的“muxing.c”示例开始,并按如下方式修改它,我能够将 KLV 流添加到混合输出中。

First, I created the AVStream as follows, where "oc" is the AVFormatContext (muxer) variable:首先,我按如下方式创建了 AVStream,其中“oc”是 AVFormatContext (muxer) 变量:

AVStream *klv_stream = klv_stream = avformat_new_stream(oc, NULL);
klv_stream->codec->codec_type = AVMEDIA_TYPE_DATA;  
klv_stream->codec->codec_id = AV_CODEC_ID_TIMED_ID3;
klv_stream->time_base = AVRational{ 1, 30 };
klv_stream->id = oc->nb_streams - 1; 

Then, during the encoding/muxing loop:然后,在编码/混合循环期间:

AVPacket pkt;
av_init_packet(&pkt);
pkt.data = (uint8_t*)GetKlv(pkt.size);
auto res = write_frame(oc, &video_st.st->time_base, klv_stream, &pkt);
free(pkt.data);

(The GetKlv() function returns a malloc()'ed array of binary data that would be replaced by whatever you're using to get your encoded KLV. It sets pkt.size to the length of the data.) (GetKlv() 函数返回一个由 malloc() 处理的二进制数据数组,该数组将被您用来获取编码 KLV 的任何内容替换。它将 pkt.size 设置为数据的长度。)

With this modification, and specifying a ".ts" target file, I get a three-stream file that plays just fine in VLC.通过这个修改,并指定一个“.ts”目标文件,我得到了一个在 VLC 中播放得很好的三流文件。 The KLV stream has a stream_type of 0x15, indicating synchronous KLV. KLV流的stream_type为0x15,表示同步KLV。

Note the codec_id value of AV_CODEC_ID_TIMED_ID3.请注意 AV_CODEC_ID_TIMED_ID3 的 codec_id 值。 According to the libavformat source file "mpegtsenc.c", a value of AV_CODEC_ID_OPUS should result in stream_type 6, for asynchronous KLV (no accompanying PTS or DTS).根据 libavformat 源文件“mpegtsenc.c”,对于异步 KLV(没有伴随的 PTS 或 DTS),AV_CODEC_ID_OPUS 的值应该导致 stream_type 6。 This is actually important for my application, but I'm unable to get it to work -- the call to avformat_write_header() throws a division by zero error.这实际上对我的应用程序很重要,但我无法让它工作 - 对 avformat_write_header() 的调用引发了除以零错误。 If I get that figured out, I'll add an update here.如果我弄明白了,我会在这里添加更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM