Скажите libavcodec / ffmpeg удалить кадр - PullRequest
4 голосов
/ 06 июля 2011

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

В настоящее время я пропускаю получение текущего кадра, если я опаздываю.FFMPEG / libavcodec рассматривает каждый кадр, который я передаю ему, как следующий кадр в строке, поэтому, если я пропущу 1 из 2 кадров, видео продолжительностью 20 секунд будет длиться только 10. Больше проблем возникнет, как только я добавлю звук, так как обработка звуканамного быстрее ...

Я хотел бы сказать FFMPEG: «последний кадр должен длиться в два раза дольше, чем первоначально предполагалось», или все, что может позволить мне обрабатывать в режиме реального времени.

Я пытался складывать кадры в определенный момент, но это заканчивалось тем, что убивал всю мою память (я также пытался «складывать» свои кадры на жесткий диск, что, как я и ожидал, было медленным)

Я думаю, мне придется работать с pts вручную, но все мои попытки не увенчались успехом, и чтение кода некоторых других приложений, использующих ffmpeg, таких как VLC, не очень помогло ... так что любой совет будетмногоприветствуется!

Заранее большое спасибо!

Ответы [ 4 ]

1 голос
/ 07 марта 2013

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

для примера того, как это сделать (хотя бы указав свою собственную часть метки времени), см. doc / examples / muxing.c в дистрибутиве ffmpeg(строка 491 в моем текущем git pull):

frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);

здесь автор увеличивает временную метку кадра на 1 в временной базе видеокодека, масштабированной до временной базы видеопотока, но в вашем случае вы можете просто изменить масштабколичество секунд, прошедшее с того момента, как вы начали захватывать кадры из произвольной временной базы в временную базу выходного видеопотока (как в примере выше).например, если ваша произвольная временная база составляет 1/1000, и вы получаете кадр за 0,25 секунды с момента начала захвата, сделайте следующее:

AVRational my_timebase = {1, 1000};
frame->pts = av_rescale_q(250, my_timebase, avstream->time_base);

, затем закодируйте кадр как обычно.

0 голосов
/ 06 июля 2011

Просто идея ... когда вы отстаете от обработки, вы пытались снова передать ему тот же кадр (и сбросить текущий)? Может быть, он может быстро обработать дублированный кадр.

0 голосов
/ 06 июля 2011

Для многоядерной обработки есть переключатель командной строки ffmpeg -threads ..., поэтому вы должны иметь возможность делать что-то подобное с API (хотя я понятия не имею, как). Это может решить вашу проблему.

0 голосов
/ 06 июля 2011

Многие (большинство?) Видео форматы не позволяют оставлять кадры. Вместо этого, попробуйте повторно использовать старые видеокадры, если вы не можете вовремя получить новый.

...