проблема с кодированием скорости ffmpeg

#ffmpeg #encoder

#ffmpeg #кодировщик

Вопрос:

В настоящее время я разрабатываю приложение, которое выполняет захват видео с веб-камеры в Linux с использованием инструмента Qt Designer и библиотек V4L2 и ffmpeg под C , для захвата изображения нет проблем с использованием библиотеки V4L2, и поскольку изображение готово, я отправляю его кодировщику, основанному на библиотеках ffmpeg, изначально кодировщик создает видеофайл и получает изображения для кодирования его в этот файл, моя проблема заключается в следующем: кодирование обычно выполняется, но после того, как я начну воспроизводить записанный файл, я получаю изображения, которые кодируются в этом файле. видеофайл, скорость которого, по-видимому, увеличена по сравнению с обычной скоростью! Итак, что ясно, проблема в кодировании видео, мой вопрос в том, существует ли метод или функция, которая управляет скоростью кодирования изображений в ffmpeg????? спасибо за вашу помощь.

Комментарии:

1. Итак, ваш вопрос не имеет ничего общего с C или Qt, пожалуйста, отметьте соответствующим образом.

2. я просто хотел уточнить свою проблему, потому что я использую Qt, программируя на языке c .

3. Но люди, обладающие знаниями только C и Qt, не смогут вам помочь, хотя они могут «отслеживать» эти теги.

Ответ №1:

При создании пользовательского закодированного видео с помощью FFMpeg вам фактически потребуется установить PTS для каждого AVPacket, который записывается в выходной файл. Установка time_base вашего AVCodecContext только подскажет контейнеру, чего ожидать. PTS (отметка времени презентации) сообщает декодеру (при просмотре вашего видео), когда на самом деле отображать этот конкретный кадр.

Например:

У меня есть AVFrame, который я получил из части FFMpeg V4L2. Для начала безопаснее сделать копию этого изображения с помощью av_picture_copy. (Таким образом, кодировщик не просматривает всю дополнительную информацию в структуре AVFrame.)

 av_picture_copy( (AVPicture*) picture, (AVPicture*) pFrame, c->pix_fmt, c->width, c->height );

picture->pts = numFrames;
  

теперь установите pts на основе количества закодированных кадров

 pDestFrame->pts = numFrames;
  

теперь кодируйте

 numEncodedBytes = avcodec_encode_video( AVCodecCtx, buffer, bufferSize, pDestFrame );
  

ТЕПЕРЬ создайте AVPacket и снова установите временную метку после изменения масштаба

 AVPacket pkt;
av_init_packet(amp;pkt);

pkt.pts = av_rescale_q( c->coded_frame->pts, c->time_base, mpVideoStr->time_base );

if ( c->coded_frame->key_frame ) pkt.flags |= AV_PKT_FLAG_KEY;

pkt.stream_index = mpVideoStr->index;
pkt.data = outbuf;
pkt.size = out_size;
  

Наконец, вы можете записать пакет

 av_write_frame( formatCtx, amp;pkt );
  

Я знаю, что это работает для кодирования видео H264, но я не уверен на 100%, что это работает для других типов видео, поскольку меня интересовал только H264, когда я писал это.

Ответ №2:

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

Комментарии:

1. я видел это руководство, но оно предназначено для функции декодирования, мой декодер работает нормально, более того, я просто записал видеопоток без звука, чтобы упростить его, вот почему я твердо уверен, что проблема в декодере, на данный момент я модифицирую pts в кодировщике, особенно в пакете formatcontext…

2. Вы можете увидеть в tut, как выполняется синхронизация. В этом случае, как видео синхронизируется со звуком. В вашем случае я предполагаю, что звука нет. Итак, вам нужно определить, как долго должен отображаться видеокадр. Например, используя частоту кадров или длительность для каждого кадра.

3. извините, я имею в виду, что проблема в «КОДИРОВЩИКЕ», потому что декодер работает нормально, и если я проигрываю записанное видео с помощью проигрывателя (например, vlc), оно, похоже, тоже ускоряется, так что проблема в кодировщике.

4. Хорошо, я думал, что это только в вашем приложении. Но если поток в целом неправильный, то на самом деле речь идет о неправильных временных метках. Вы можете посмотреть на ответ Беккета. Вам нужно установить частоту кадров для контекста и значение pts для каждого AVPicture, которое вы хотите закодировать. Это должно обеспечить достаточное количество информации для воспроизведения

5. я думаю, что это было сделано, взгляните: я использовал это в своей функции createfile pCodecCtx->bit_rate = Bitrate; pCodecCtx->width = getWidth(); pCodecCtx->height = getHeight(); pCodecCtx->time_base.den = 24; pCodecCtx->time_base.num = 1; pCodecCtx->gop_size = Gop; pCodecCtx->pix_fmt = ffmpeg::PIX_FMT_YUV420P; , а это для th packet pts : if (pCodecCtx->coded_frame->pts != ((unsigned)0x8000000000000000LL)) pkt.pts= av_rescale_q(pCodecCtx->coded_frame->pts, pCodecCtx->time_base, pVideoStream->time_base);

Ответ №3:

При создании файла ffmpeg вы должны указать частоту кадров, зависящую от того, какую библиотеку вы используете, но ищите что-то вроде

 pCodecContext->time_base.den = frames_per_second;
pCodecContext->time_base.num = 1;
  

В противном случае, если вы генерируете 10-15 кадров в секунду с веб-камеры, но по умолчанию в файле установлено значение 30 кадров в секунду, воспроизведение будет быстрым.

Смотрите http://code.google.com/p/qtffmpegwrapper для оболочки Qt ffmpeg

Комментарии:

1. спасибо за воспроизведение, в настоящее время я использую некоторые функции из оболочки Qt ffmpeg, например, в encoding, decoding, и я только что изменил значение pCodecContext->time_base.den даже я ввел 1!! но все та же проблема

2. Либо установите его в настройках вашей веб-камеры, либо измерьте его с предыдущего запуска. Или, если вы действительно привередливы, запустите веб-камеру на полной скорости, но выбросьте изображения, чтобы уменьшить его, чтобы оставлять ровно один новый кадр каждые ‘n’ миллисекунд. Лучший вариант — просто предположить, что это 10-15 — пример directshow amcap или приложение для просмотра веб-камеры покажет вам