Ffmpeg av_seek_frame
Я пытаюсь искать в фильме, используя метод ffmpeg av_seek_frame, однако у меня больше всего проблем с определением того, как создавать метку времени, к которой нужно стремиться. Предполагая, что я хочу искать количество кадров в формате "вперед" или "назад", и я знаю, в какой кадре находится фильм, как бы я это сделал?
Ответы
Ответ 1
Вот как я это сделал:
// Duration of one frame in AV_TIME_BASE units
int64_t timeBase;
void open(const char* fpath){
...
timeBase = (int64_t(pCodecCtx->time_base.num) * AV_TIME_BASE) / int64_t(pCodecCtx->time_base.den);
...
}
bool seek(int frameIndex){
if(!pFormatCtx)
return false;
int64_t seekTarget = int64_t(frameIndex) * timeBase;
if(av_seek_frame(pFormatCtx, -1, seekTarget, AVSEEK_FLAG_ANY) < 0)
mexErrMsgTxt("av_seek_frame failed.");
}
AVSEEK_FLAG_ANY позволяет искать каждый кадр, а не только ключевые кадры.
Ответ 2
Простой ответ: у вас должен быть объект AVFormatContext. Свойство duration
сообщает вам, как долго ваш файл находится в терминах метки времени, умноженной на 1000, которая может использоваться в av_seek_frame, поэтому относитесь к ней как к 100%. Затем вы можете рассчитать, как далеко в видео вы хотите искать.
если вы хотите перейти на один кадр, просто вызовите av_read_frame и avcodec_decode_video, пока он не заполнит got_picture_ptr ненулевым значением. Перед вызовом avcodec_decode_video убедитесь, что пакет из av_read_frame из видеопотока. avcodec_decode_video затем заполнит структуру AVFrame, которую вы можете использовать для чего-либо.