объяснение временной единицы 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 ответа:
Time_base имеет тип AVRational, который является рациональным числом, состоящим из числителя и знаменателя, в отличие от использования десятичной точки. Я предполагаю, что причина, по которой они не просто используют double, заключается в том, что таким образом вы не теряете точность.Но AVCodecContext видео- > time_base == 1001 / 60000
Это приводит меня в полное замешательство, и я их не понимаю.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.