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

问题描述 投票:2回答:1

我需要使用ffmpeg C ++ API对mpegts视频进行编码。输出视频应具有两个流:第一个流的类型应为AVMEDIA_TYPE_VIDEO;第二个应为AVMEDIA_TYPE_DATA类型,并应包含一组KLV数据。

我已经编写了自己的KLV库来管理KLV格式。

但是我无法通过结合两个流来“从头开始”创建新视频。按照FFMPEG C api h.264 encoding / MPEG2 ts streaming problems中的实现,我可以使用单个视频流成功编码mpegts视频。

但是我无法使用新的AVMEDIA_TYPE_DATA流添加到输出视频,因为一旦我使用avformat_new_stream(...)之类的方法添加了新的数据流,输出视频就为空:既没有数据流,也没有产生了一个视频,并且输出文件为空。

有人可以建议我如何以mpegts格式向我的输出视频正确添加数据流的教程页面或示例吗?

非常感谢!

c++ ffmpeg metadata encode
1个回答
0
投票

通过从FFmpeg源附带的“ muxing.c”示例开始,并进行如下修改,我能够将KLV流添加到多路复用输出中。

首先,我如下创建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; 

然后,在编码/混合循环中:

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);

((GetKlv()函数返回一个malloc()的二进制数据数组,该数组将被您用来获取编码KLV的任何内容所取代。它将pkt.size设置为数据长度。]

通过此修改,并指定“ .ts”目标文件,我得到了一个三流文件,在VLC中可以正常播放。 KLV流的stream_type为0x15,表示同步KLV。

请注意AV_CODEC_ID_TIMED_ID3的codec_id值。根据libavformat源文件“ mpegtsenc.c”,对于异步KLV(无随附的PTS或DTS),AV_CODEC_ID_OPUS的值应导致stream_type 6。这实际上对我的应用程序很重要,但是我无法使其正常工作-调用avformat_write_header()会导致除以零错误。如果知道了,我将在此处添加更新。

© www.soinside.com 2019 - 2024. All rights reserved.