2017-07-28 9 views
3

私はMPEGトランスポートストリーム内でビデオをデコード、スケーリング、再エンコードするためにffmpegライブラリを使用しています。私はソースからv3.3.2に再コンパイルし、古いavcodec_decode_video2()APIから新しいsend/receive APIに変更しました。FFMPEGのデコードが遅すぎる(avcodec_send_packet()/ avcodec_receive_frame())

古いAPIと新しいAPIの両方が、ビデオを非常にゆっくりとデコードします。

25fpsビデオ= 40msごとに1フレーム。しかし、私はデコードする1フレームあたり70から120ミリ秒を参照してください。これはファイル変換プログラムですので、をより速く実行する必要があります。はリアルタイムです。

コードの概要は以下のとおりです。誰でも復号化のスピードを向上させる方法について考えている人はいますか?非推奨の他の投稿はavcodec_decode_video2()です。それらのどれも解決されなかった。新しいAPIは、いくつかの出力

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バージョンコア2デュオで実行されている

テスト3.2 GHzの、32ビットのCentOSにも速く...

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 

を実行しません。 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 
+0

パケットを捕捉し、フレームをデコードし、同じスレッド上でスケーリングしてエンコードしていますか? – WLGfx

+0

1つのスレッドは、コードに表示されていないTSパケットをキューに取り込みます。 2番目のスレッドは、AVIOを使用してread_frameをフィードし、フレームを読み取り、デコードしてからエンコードします。しかし実際の問題は、フレームを供給すると、デコーダに非常に時間がかかることです。 – Danny

+0

こんにちはダニー!今、私はffmpegの遅さを解読するのと同じ問題に直面しています。私はその問題の解決策を見つけたのですか?もしそうなら、私に知らせてください。おかげで –

答えて

-1

私が今までに見つけたベストソリューションはavcodec_decode_video2()に戻り、より良いハードウェアを購入していました...

+0

ありがとう、それは理にかなっていません。 CPUは十分速く、VLC(ffmpegデコーダを使用しています)を使ってフルフレームレートでビデオを再生できます。だから、*どのように*私は構成しているか、またはデコーダを使用して*いくつかの問題です... – Danny

0

あなたはまだヘルプを探しています。

ビデオのピクセル形式によっては、VLCがGPUを使用してデコードすることができます。 GPU-Z(ウィンドウでのみ動作しますが、Linux用の同様のツールがあります)を使用して、ビデオ負荷エンジンを測定するようにしてください。 その場合、libsがGPUのエンコード/デコードをサポートしているかどうかを確認する必要があります。