如何将数据流添加到具有FFmpeg和C / C++的MXF(使用mpeg2video)文件中

How add Data Stream into MXF(using mpeg2video) file with FFmpeg and C/C++

本文关键字:MXF C++ 使用 mpeg2video 文件 添加 数据流 FFmpeg      更新时间:2023-10-16

我在尝试创建MXF文件时有点卡在这里 上面有数据流。我有几个MXF视频文件,其中包含 本标准

**1 Video Stream:
Stream #0:0: Video: mpeg2video (4:2:2), yuv422p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 50000 kb/s, 29.9
16 audio streams
Audio: pcm_s24le, 48000 Hz, 1 channels, s32 (24 bit), 1152 kb/s
1 Data Stream:
Data: none**

此数据流包含视频文件中的个人数据。我可以 打开这个流,数据真的在那里。都还好。但是,当我尝试时 要创建一个完全像这样的文件,每次我调用"avformat_write_header" 它返回一个错误。

如果我确实评论此数据流的创建,则视频文件是成功的 创建。

如果我使用此数据流更改为"mpegts",则视频文件也成功 创建。

但是,我不能使用 mpet,我需要这个数据流。

我知道有可能使用数据流进行MXF,因为我有这个原始文件 具有此组合。

所以,我知道我的代码中缺少一些东西。

这是我创建此数据流的方式:

void CFFmpegVideoWriter::addDataStream(EOutputStream *ost, AVFormatContext *oc, AVCodec **codec, enum AVCodecID codec_id)
{
AVCodecParameters *par;
ost->stream = avformat_new_stream(oc, NULL);
if (ost->stream == NULL)
{
fprintf(stderr, "OOooohhh man: avformat_new_stream() failed.n");
return;
}
par = ost->stream->codecpar;
ost->stream->index = 17;
par->codec_id = AV_CODEC_ID_NONE;
par->codec_type = AVMEDIA_TYPE_DATA;
ost->stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}

文件打开是这样的:

CFFMpegVideoWriter::CFFMpegVideoWriter(QString outputfilename) : QThread()
{
av_register_all();
avcodec_register_all();
isOpen = false;
shouldClose = false;
frameIndex = 0;
#ifdef __linux__
QByteArray bFilename = outputfilename.toUtf8();
#else
QByteArray bFilename = outputfilename.toLatin1();
#endif
const char* filename = bFilename.data();
codecContext = NULL;
//encontra o formato desejado...
outputFormat = av_guess_format("mp2v", filename, nullptr);
if (!outputFormat)
{
qDebug("Could not find suitable output formatn");
return;
}
//encontra o codec...
codec = avcodec_find_encoder(outputFormat->video_codec);
if (!codec)
{
qDebug( "Codec not foundn");
return;
}
//aloca o contexto do codec...
codecContext = avcodec_alloc_context3(codec);
codecContext->field_order = AV_FIELD_TT;
codecContext->profile = FF_PROFILE_MPEG2_422;
//aloca o contexto do formato...
formatContext = avformat_alloc_context();
formatContext->oformat = outputFormat;
//aloca o contexto da midia de saida...
avformat_alloc_output_context2(&formatContext, NULL, NULL, filename);
if (!formatContext)
{
qDebug("Erro");
return;
}
videoStream.tmp_frame = NULL;
videoStream.swr_ctx = NULL;
//adiciona a stream de video...
if (outputFormat->video_codec != AV_CODEC_ID_NONE)
{
addVideoStream(&videoStream, formatContext, &video_codec, outputFormat->video_codec);       
}
//adiciona as 16 streams de audio...
if (outputFormat->audio_codec != AV_CODEC_ID_NONE)
{
for (int i = 0; i < 16; i++)
{
addAudioStream(&audioStream[i], formatContext, &audio_codec, outputFormat->audio_codec);
}       
}
addDataStream(&datastream, formatContext, &video_codec, outputFormat->video_codec);     
videoStream.sws_ctx = NULL;
for (int i = 0; i < 16; i++)
{
audioStream[i].sws_ctx = NULL;
}   
opt = NULL;

//carreca o codec de video para stream de video...      
initVideoCodec(formatContext, video_codec, &videoStream, opt);

//carrega o codec de audio para stream de audio...s
for (int i = 0; i < 16; i++)
{
initAudioCodec(formatContext, audio_codec, &audioStream[i], opt);
}

av_dump_format(formatContext, 0, filename, 1);
//abrea o arquivo de saida..
if (!(outputFormat->flags & AVFMT_NOFILE))
{
ret = avio_open(&formatContext->pb, filename, AVIO_FLAG_WRITE);
if (ret < 0)
{
qDebug("Could not open'%s", filename);
return;
}
}
//escreve o cabecalho do arquivo...
ret = avformat_write_header(formatContext, &opt);
if (ret < 0)
{
qDebug("Error occurred when opening output file");
return;
}
isOpen = true;
QThread::start();
}

代码在"avformat_write_header"调用时始终失败。

但是,如果我删除"数据流"或将其更改为 mpegts,一切正常。

我在这里做错了什么?

感谢您阅读本文。

赫尔穆特

经过长时间尝试很多解决方案,我发现了问题所在。我必须添加一个指定数据类型的元数据项。

就我而言,数据类型"vbi_vanc_smpte_436M"MXF支持。

所以,我同意:

av_dict_set(&out_stream->metadata, "data_type", "vbi_vanc_smpte_436M",  AV_DICT_IGNORE_SUFFIX);  

然后一切正常。

我希望这可以帮助其他有同样问题的人。