Слишком медленное декодирование FFMPEG (avcodec_send_packet() / avcodec_receive_frame())

Я использую библиотеки ffmpeg для декодирования, масштабирования и перекодирования видео в транспортном потоке MPEG. Я только что перекомпилировал исходный код до версии 3.3.2 и перешел со старого API avcodec_decode_video2() на новый API отправки/получения.

И старый, и новый API декодируют видео очень медленно.

Видео 25 кадров в секунду = 1 кадр каждые 40 мс. Тем не менее, я вижу от 70 до 120 мс на кадр для декодирования. Это переводчик файлов, поэтому он должен работать быстрее, чем в режиме реального времени.

Схема кода ниже. У кого-нибудь есть идеи, как улучшить скорость декодирования? Есть и другие сообщения о том, что устаревший avcodec_decode_video2() работает медленно; ни один из них не был решен. Новый API не работает быстрее...

gettimeofday(&tv1, NULL);
int rc = av_read_frame(pFormatContext, pESPacket);
gettimeofday(&tv2, NULL);

int ret = avcodec_send_packet(pDecoderContext, pESPacket);
if (ret < 0)
    continue;

ret = avcodec_receive_frame(pDecoderContext, pFrameDec);
if (ret != 0)
{
    printf("avcodec_receive_frame error: %d\n", ret);
    continue;
}
gettimeofday(&tv3, 0);

u_long twoMinusOne   = (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec;
u_long threeMinusTwo = (tv3.tv_sec - tv2.tv_sec) * 1000000 + tv3.tv_usec - tv2.tv_usec;

size_t pktSize = mPacketQueue.getTsPktListSize();
printf("  DECODE ReadFrame %lu usec, DecodeVideo %lu usec. mTsPacketList %u items\n", twoMinusOne, threeMinusTwo, pktSize);

transcodeFrame(pFrameDec);

// Scale and re-encode //
-- call avscale to downsample
-- call avcodec_encode_video2() to encode

Некоторые результаты

DECODE ReadFrame 6 usec, DecodeVideo 154273 usec.
Dump mpFrameEnc with DateTime: 
  AVFrame Info frame 720 X 406. PTS = 305700353  PKT_PTS = 305700353 Linesize[0]=720. Linesize[1]=360. Linesize[2]=360.   
Time taken to ENCODE video frame = 3685 usec. Scaling time 4 usec

DECODE ReadFrame 8 usec, DecodeVideo 128203 usec.
Time taken to ENCODE video frame = 3724 usec. Scaling time 3 usec

DECODE ReadFrame 8 usec, DecodeVideo 69321 usec.
Time taken to ENCODE video frame = 3577 usec. Scaling time 3 usec

Версия FFMPEG

Тесты выполняются на core2 duo 3,2 ГГц, 32-разрядной версии Centos 6.

bin/ffmpeg
ffmpeg version 3.3.2 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-11)
  configuration: --prefix=/mnt/swdevel/DVStor/source_build/ext/ffmpeg-build --libdir=/mnt/swdevel/DVStor/source_build/ext/ffmpeg-build/lib3p_build --shlibdir=/mnt/swdevel/DVStor/source_build/ext/ffmpeg-build/lib3p_build --disable-static --enable-shared --disable-cuda --disable-cuvid --disable-nvenc --enable-libx264 --enable-gpl --extra-cflags=-I/usr/local/include/libx264
  libavutil      55. 58.100 / 55. 58.100
  libavcodec     57. 89.100 / 57. 89.100
  libavformat    57. 71.100 / 57. 71.100
  libavdevice    57.  6.100 / 57.  6.100
  libavfilter     6. 82.100 /  6. 82.100
  libswscale      4.  6.100 /  4.  6.100
  libswresample   2.  7.100 /  2.  7.100
  libpostproc    54.  5.100 / 54.  5.100
Hyper fast Audio and Video encoder

person Danny    schedule 28.07.2017    source источник
comment
Вы захватываете пакеты, декодируете кадры, масштабируете и кодируете все в одном потоке?   -  person WLGfx    schedule 28.07.2017
comment
Один поток заполняет очередь TS-пакетами, которые не показаны в коде. Второй поток, используя AVIO для подачи read_frame, считывает кадры, декодирует, а затем кодирует. Но реальная проблема в том, что при подаче кадра декодер занимает очень много времени.   -  person Danny    schedule 28.07.2017
comment
Привет Дэнни! Прямо сейчас я столкнулся с той же проблемой, связанной с медлительностью декодирования ffmpeg. Мне интересно, вы нашли решение этой проблемы? Если это так, пожалуйста, дайте мне знать. Спасибо   -  person Eugene Alexeev    schedule 08.10.2017


Ответы (1)


В случае, если вы все еще ищете помощи.

В зависимости от формата пикселей видео VLC может использовать графический процессор для его декодирования. Чтобы убедиться, что вы используете GPU-Z (работает только в Windows, есть аналогичные инструменты для Linux) для измерения модуля загрузки видео. Если это так, вам может потребоваться проверить, поддерживают ли ваши библиотеки кодирование/декодирование графического процессора.

person Kxp    schedule 09.01.2018