Как настроить AVStream для записи файлов 29.97FPS с использованием FFmpeg - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь записать файл 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?

1 Ответ

0 голосов
/ 14 мая 2018

Установка значения avg_frame_rate устраняет проблему ...

videoStream->avg_frame_rate = _videoCodecContext->framerate;
...