1
votes

I'm trying to write mkv file using ffmpeg to encode in FFV1 and FLAC in NTSC format, but the frame rate shown in VLC and media info are not correct.

Here is how I create and configure the output format context:

AVOutputFormat  *outputFormat = av_guess_format("matroska", NULL, NULL);

//Allocate an AVFormatContext for an output format.
int err = avformat_alloc_output_context2(&_formatContext, outputFormat, NULL, filename);

//Specify the codec of the outputFormat
_formatContext->oformat->video_codec = _videoCodecContext->codec_id;

//Create AVStream 
AVStream *videoStream = avformat_new_stream(_formatContext, NULL);  

//FrameDuration.value : 1001, FrameDuration.timescale : 30000
videoStream->time_base = (AVRational){ (int)_frameDuration.value, (int)_frameDuration.timescale };  //1001 30000

//Copy video stream parameters to the muxer
err = avcodec_parameters_from_context(videoStream->codecpar, _videoCodecContext);

//Open file for writing
err = avio_open(&_formatContext->pb, filename, AVIO_FLAG_WRITE);            

if (err >= 0) {
    //Write header
    err = avformat_write_header(_formatContext, &options);
}

Before writing the packet, I use this to convert PTS to the stream time_base

// Rescale output packet timestamp values from codec to stream timebase
av_packet_rescale_ts(inAVPacket, *inTimeStamp, [outputStream stream]->time_base);

The thing is that the avformat_write_header method is changing the stream time_base from 30000/1001 to 1/1000, so PTS loose precision. In VLC inspector, the frame rate shown is 1000 fps and in MediaInfo 30.033 fps.

The file is playing correctly and the video/audio sync is OK.

Is there something to do to specify the file frame rate somewhere else ? Or a work around to avoid changing the time_base when calling avformat_write_header ?

1

1 Answers

1
votes

Setting the avg_frame_rate fixes the issue...

videoStream->avg_frame_rate = _videoCodecContext->framerate;