Проблема с функцией ffmpeg avformat_seek_file () - PullRequest
1 голос
/ 18 июня 2011

Я пытаюсь найти данный кадр в видео с помощью библиотеки ffmpeg. Я знал, что есть функция av_seek_frame(), но было рекомендовано использовать avformat_seek_file(). Нечто подобное упомянуто здесь .

Я знаю, что avformat_seek_file() не всегда может привести вас к тому, что вы хотите, но это нормально для меня. Я просто хочу перейти на ближайший ключевой кадр. Итак, я открываю видео, нахожу видеопоток и называю его так:

avformat_seek_file( formatContext, streamId, 0, frameNumber, frameNumber, AVSEEK_FLAG_FRAME )

Всегда возвращает 0, так что я понимаю это как правильное завершение. Тем не менее, это не работает, как следует. Я проверяю позицию байта как здесь до и после вызова avformat_seek_file(). На самом деле это меняется, но меняется всегда одинаково, когда я пытаюсь поставить разные номера целевых кадров! Я имею в виду, что байтовое положение после этого вызова всегда одинаково даже с разными значениями frameNumber. Очевидно, я делаю что-то не так, но не знаю, что именно. Я не знаю, имеет ли это значение, но я использую файлы .h264 для этого. Я пробовал разные флаги, разные файлы, используя временные метки вместо кадров, очищал буферы до и после и так далее, но у меня это не работает. Буду очень признателен, если кто-нибудь покажет мне, что с ним не так.

Ответы [ 2 ]

5 голосов
/ 15 августа 2011

У меня была такая же проблема, см. Код ниже (у меня работает):

    ...
    checkPosition(input_files[file_index].ctx);
    ...

    void checkPosition(AVFormatContext *is) {
        int stream_index = av_find_default_stream_index(is);
        //Convert ts to frame
        tm = av_rescale(tm, is->streams[stream_index]->time_base.den, is-                >streams[stream_index]->time_base.num);
        tm /= 1000;

        //SEEK
        if (avformat_seek_file(is, stream_index, INT64_MIN, tm, INT64_MAX, 0) < 0) {
            av_log(NULL, AV_LOG_ERROR, "ERROR av_seek_frame: %u\n", tm);
        } else {
            av_log(NULL, AV_LOG_ERROR, "SUCCEEDED av_seek_frame: %u newPos:%d\n", tm, is->pb->pos);
            avcodec_flush_buffers(is->streams[stream_index]->codec);
        }
    }
0 голосов
/ 19 апреля 2013

Ваша проблема может быть связана с тем, что ваш ввод является необработанным .h264.попробуйте использовать, например, mp4box, чтобы преобразовать его в файл .mp4, затем загрузите файл mp4 с помощью ffmpeg и попробуйте снова найти ключевой кадр.например:

mp4box -new -add my_file.h264 my_file.mp4
...