Проблема: поиск FFMPEG с использованием av_seek_frame с использованием позиций байтов
Я пытаюсь заставить функцию av_seek_frame() перейти к заданной позиции байта. Я реализую механизм поиска кадров для моего приложения и способ, которым я его вижу, сканирую весь видеофайл и сохраняю позиции байтов для каждого ключевого кадра в структуре. Я узнал, где получить текущую позицию байта: AVPacket.pos. Теперь я тестирую эту позицию с помощью av_seek_frame
следующим образом:
av_seek_frame( pFormatCtx, videoStream, 110285594, AVSEEK_FLAG_BYTE);
Однако, похоже, что это не так, когда я вызываю av_read_frame
, он начинается с кадра 23. Если я не ищу, он начинается с кадра 1.
Ответы
Ответ 1
Для тех, кто заинтересован, я нашел решение. После нескольких часов работы в Интернете и некоторой упрощенной формы обратной инженерии я нашел, как получить и установить местоположение байта открытого видео.
Чтобы получить позицию файла:
AVFormatContext.pb.pos
например:
int64_t byteposition = pFormatCtx->pb->pos;
Чтобы установить положение файла:
url_seek (AVFormatContext.pb, Position, SEEK_SET);
например:
url_seek(pFormatCtx->pb, 27909056, SEEK_SET);
Не забудьте очистить буферы, если вы измените местоположение во время игры. Если вы сделаете это до того, как вы впервые сделаете av_read_frame, промывка не требуется.
С уважением,
Ник Верлинден
Ответ 2
В последних версиях libav, url_seek была сделана внутренняя функция. Теперь следует использовать следующую функцию:
/**
* fseek() equivalent for AVIOContext.
* @return new position or AVERROR.
*/
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence);