объяснение временной единицы ffmpeg и метод AV seek frame


Что означает time_base в ffmpeg? документ (здесь ) говорит, что это "кадры в секунду". и я вижу в реальном примере, что:

AVFormatContext->streams[video_index]->time_base == 1 / 30000

Но видео AVCodecContext->time_base == 1001 / 60000

Это приводит меня в полное замешательство, и я их не понимаю.

Второй вопрос касается методаav_seek_frame . Если искать через отметку времени (последний параметр-AVSEEK_FLAG_BACKWARD или 0), поиск начинается с текущей позиции, считываемой av_seek_frame ? или с самого начала файла? или из начальной позиции декодирования после последнего вызова av_seek_frame ?

3 4

3 ответа:

Но AVCodecContext видео- > time_base == 1001 / 60000

Это приводит меня в полное замешательство, и я их не понимаю.
Time_base имеет тип AVRational, который является рациональным числом, состоящим из числителя и знаменателя, в отличие от использования десятичной точки. Я предполагаю, что причина, по которой они не просто используют double, заключается в том, что таким образом вы не теряете точность.

AVRational определяется в источниках как:

typedef struct AVRational{
    int num; ///< numerator
    int den; ///< denominator
} AVRational;

Time_base также взаимно кадров в секунду, не равный ему. Таким образом, если у вас есть 30 кадров в секунду, это означает, что база времени составляет 1/30, а не 30.

Я проверил все поля из ссылки комментария satuon с несколькими видеофайлами, и похоже, что правильная частота кадров может быть вычислена таким образом:

double framerate = av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate);

... где pFormatCtx - Ваш AVFormatContext и videoStream - индекс вашего видеопотока, найденный с помощью этого кода:

int videoStream = -1;
for (uint i=0; i < pFormatCtx->nb_streams; i++) {
    if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && videoStream < 0) {
        videoStream = i;
    }
}

Использование ffmpeg 1.1.

Не используйте r_frame_rate, так как это libavformats угадать, не точно. (см. http://ffmpeg.org/pipermail/ffmpeg-devel/2005-May/003079.html )

AVCodecContext.time_base дает точный fps. Если значение ticks_per_frame равно 2, уменьшите time_base на 1/2. Например, если AVCodecContext.time_base (1, 60) и ticks_per_frame-1, fps-60. Если значение ticks_per_frame равно 2, то fps равно 30.

Если AVCodecContext- > time_base равен (1001, 60000), fps равен 60.

База времени для AVCodecContext связан с fps.

Time_base для AVStream используется только для единицы времени в методах AVStream, таких как получение времени одного кадра или .начальная переменная.

Существует еще одна база времени для AVPacket. Но из состава ffmpeg-Devel, который они предпочитают делать AVPacket.time_base то же самое, что и для AVStream.