Я пытаюсь записать файл mkv, используя ffmpeg для кодирования в FFV1 и FLAC в формате NTSC, но частота кадров, показанная в VLC, и информация о мультимедиа неверны.
Вот как я создаю и настраиваюконтекст выходного формата:
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);
}
Перед записью пакета я использую его для преобразования PTS в поток time_base
// Rescale output packet timestamp values from codec to stream timebase
av_packet_rescale_ts(inAVPacket, *inTimeStamp, [outputStream stream]->time_base);
Дело в том, что метод avformat_write_header изменяет поток time_baseот 30000/1001 до 1/1000, поэтому PTS теряет точность.В инспекторе VLC показанная частота кадров составляет 1000 кадров в секунду, а в MediaInfo 30,033 кадров в секунду.
Файл воспроизводится правильно, а синхронизация видео / аудио в порядке.
Что-то нужно сделать, чтобы указатьчастота кадров файла где-то еще?Или обходной путь, чтобы избежать изменения time_base при вызове avformat_write_header?