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, которую вы можете использовать для чего-либо.