Кто мне может помочь с ffmpeg?

Модератор: Модераторы разделов

mops
Сообщения: 172
ОС: Ubuntu Feisty

Кто мне может помочь с ffmpeg?

Сообщение mops »

Здравствуйте.
Уже устал лазить по рассылкам и искать по крупицам ответы на свои вопросы. Хочется найти человека или подробную документацию, которые помогли бы мне разобраться с несколькими проблемами.
Основная проблема состоит в следующем. Я использую av_seek_frame для перехода к произвольному месту видео файла. Но мне не удаётся попасть точно в то место, куда я хотел, всегда выходит на пару секунд раньше. Вот как я это делаю:

Код: Выделить всё

int minute = 5; // вот на эту временную отметку (timestamp) я хочу попасть
int64_t target_frame = pFormatCtx->start_time + minute * 60 * AV_TIME_BASE;
av_seek_frame(pFormatCtx, -1, target_frame, AVSEEK_FLAG_BACKWARD);

Есть ли способ добиться точного попадания?

Есть ещё пару вопросов, но пока подожду принца на белом коне :)
Спасибо сказали:
Аватара пользователя
k01
Сообщения: 104
ОС: Archlinux

Re: Кто мне может помочь с ffmpeg?

Сообщение k01 »

фишка в том, что эта функция переходит на так называемый "ключевой кадр". Так сделали потому что тока начиная с такого кадра можно корректно декодировать видео.
Что бы перематывать с точностью до кадра можно использовать формат видео, где все кадры ключевые, например mjpeg
Рациональное программирование — наш ответ MicroSoft!
Спасибо сказали:
mops
Сообщения: 172
ОС: Ubuntu Feisty

Re: Кто мне может помочь с ffmpeg?

Сообщение mops »

фишка в том, что эта функция переходит на так называемый \"ключевой кадр\". Так сделали потому что тока начиная с такого кадра можно корректно декодировать видео.
Что бы перематывать с точностью до кадра можно использовать формат видео, где все кадры ключевые, например mjpeg

Эээ, ну тут проблема в том, что формат выбираю не я, а юзер :) Это может быть хоть матроска, хоть vmw. Я сейчас для этих целей использую lib-xine, так вот она корректно переходит с точностью до секунды. Значит я так понял, что это в принципе сделать невозможно?
Спасибо сказали:
Аватара пользователя
k01
Сообщения: 104
ОС: Archlinux

Re: Кто мне может помочь с ffmpeg?

Сообщение k01 »

Можно ещё так: перейти на ключевой кадр и "в холостую" считать/декодоровать несколько кадров , расположенных до нужного :)
Непосредственно декодировать произвольный кадр невозможно т.к. для этого нужна информация из соседних(обычно предидущих) кадров.
Рациональное программирование — наш ответ MicroSoft!
Спасибо сказали:
mops
Сообщения: 172
ОС: Ubuntu Feisty

Re: Кто мне может помочь с ffmpeg?

Сообщение mops »

Можно ещё так: перейти на ключевой кадр и \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"в холостую\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" считать/декодоровать несколько кадров , расположенных до нужного :)
Непосредственно декодировать произвольный кадр невозможно т.к. для этого нужна информация из соседних(обычно предидущих) кадров.

Спасибо. Не ожидал, что найду квалифицированную помощь так быстро :)
У меня есть ещё один вопрос. Допустим я хочу захватить сразу несколько кадров. Например, с интервалом в минуту. Первый кадр получаю нормально, но второй кадр идёт не через минуту, а почему-то практически сразу (скорее всего это следующий за первым). Все остальные кадры сдвинуты на минуту назад, но с нормальным интервалом в минуту. В чём тут может быть косяк? Вот кусок кода:

Код: Выделить всё

int minute = 5; // это с какой минуты начинаем
int64_t target_frame; // это тот кадр, куда прыгаем
int count = 4; // это количество кадров, которые нужно захватить

for (int j = 0; j < count; j++)
    {
        target_frame = pFormatCtx->start_time + minute * 60 * AV_TIME_BASE; // вычисляем нужный кадр

        //seeking
        av_seek_frame(pFormatCtx, -1, target_frame, AVSEEK_FLAG_BACKWARD); // прыгаем

        while(av_read_frame(pFormatCtx, &packet) >= 0)
        {
            // Is this a packet from the video stream?
            if(packet.stream_index == videoStream)
            {
                // Decode video frame
                avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
                        packet.data, packet.size);

                // Did we get a video frame?
                if(frameFinished)
                {
                    // Convert the image from its native format to RGB
                    img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,
                        (AVPicture*)pFrame, pCodecCtx->pix_fmt,
                        pCodecCtx->width, pCodecCtx->height);

                    // Save the frame to disk
                    SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, minute);
                    break; // после сохранения выходим на первый цикл
                }
            }
        }
        minute++;
    }
Спасибо сказали:
Аватара пользователя
k01
Сообщения: 104
ОС: Archlinux

Re: Кто мне может помочь с ffmpeg?

Сообщение k01 »

Попробуй после av_seek_frame() вызвать ф-ю avcodec_flush_buffers(AVCodecContext*) .
Если поменять точку старта, кол-во кадров, взять файл другого формата - тот же результат?
Рациональное программирование — наш ответ MicroSoft!
Спасибо сказали:
mops
Сообщения: 172
ОС: Ubuntu Feisty

Re: Кто мне может помочь с ffmpeg?

Сообщение mops »

k01 писал(а):
23.06.2007 22:49
Попробуй после av_seek_frame() вызвать ф-ю avcodec_flush_buffers(AVCodecContext*) .
Если поменять точку старта, кол-во кадров, взять файл другого формата - тот же результат?

Заработало! Я даже не знаю, как выразить тебе мою признательность :) Со вчера возился с этим кодом, а тут просто камень с плеч. Ещё раз благодарю, мир не без добрых людей :)
Спасибо сказали:
mops
Сообщения: 172
ОС: Ubuntu Feisty

Re: Кто мне может помочь с ffmpeg?

Сообщение mops »

Это снова я :) Как раз дошли руки до этого дела, хотелось бы закончить. В моей программе изображение должно быть приведено к RGB32 (unsigned char *).
У меня есть AVFrame *pFrameRGB;, который загоняется в функцию img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB32, (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);. Я так думаю, с этого должно получится то, что мне надо. Но как этот pFrameRGB потом правильно преобразовать в unsigned char?
Буду благодарен любой помощи.
Спасибо сказали: