Page 1 of 1

How add Data Stream into MXF(using mpeg2video) file with FFmpeg

Posted: Mon Mar 25, 2019 3:04 pm
by helmuthschmitz
Hi friends. I'm a little bit stuck here trying create a MXF file
with data stream on it. I have several MXF video files that contain
this standard

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



This data stream, contain personal data inside video file. I can
open this stream and data is really there. Is all ok. But, when i try
to create a file exactly like this, everytime i call "avformat_write_header"
it returns an error.

If i do comment the creation of this data streams the video file is succeffully
created.

If i change to "mpegts" with this data stream, the video file is also succeffully
created.

But, i can't use mpets and i need this data stream.

I know that is possible MXF with data stream cause i have this originals files
that have this combination.

So, i know that i missing something in my code.

This is the way i create this Data Stream:

Code: Select all

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

the file openning is this:

Code: Select all

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 format\n");
		return;
	}

	//encontra o codec...
	codec = avcodec_find_encoder(outputFormat->video_codec);
	if (!codec)
	{
		qDebug( "Codec not found\n");
		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);
		}		
	}

	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);
	}
	
	addDataStream(&datastream, formatContext, &video_codec, outputFormat->video_codec);	

	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)
[b][/b]		{
			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();
}
The code always fails at "avformat_write_header" call.

But if i remove "datastream" or change it to mpegts everything runs fine.

Any ideia of what am i doing wrong here?

Thanks for reading this.

Helmuth