2011-07-18 27 views
2

私はFfmpegを使ってビデオファイルをデコードして再生しています。私は現在、ビデオの再生とオーディオの再生を、CPUがデコードして表示できる速度で実行しています。問題は、システムクロックを使用してビデオとオーディオを同期して再生したいということです。Ffmpegを使ってデコードされたビデオを同期する

ドレンジャーのtutorial 05以外は何も見つかりませんでしたが、自分のプログラムが彼と同じ方法で書かれていないため、彼が何をしているのか分かりません。

私はmjpegファイルを使用していますので、フレームがデコードされるたびにptsが取得されているようですが、drangerが秒単位で値を取得するためにtime_baseでptsを掛けましたが、ビデオが25フレーム/秒で動作するので、値「25」を25回、「7」を25回取得します。

もっと正確な値はありませんか?より正確な値を取得する方法もあれば、この値に同期するにはどうしたらいいですか?私は値を表示するためにSDLを使用していますので、私は取得した値のSDL_Delay()を使用できますか?適切なtime_base上)(av_q2d使用し、浮動小数点秒にPTSやDTSを変換するにはお時間を

おかげで、

Infinitifizz

+0

正しいタイプを使用していることを確認するには、floatではなくintとして 'pts * time_base'の計算を行っているかもしれません。 –

+0

PTSの値がint64tに浮かんでいないか、または倍数になっているようです。 –

+0

drangerのチュートリアルでは、基本的にフレームのptsとしてフレームを構成する最初のパケットのptsを使用します。存在しない場合は、パケットのdts値を使用します。この値はビデオtime_base(double)として乗算されますが、それでもuint64_tなので、出力は次のようになります:0,0,0,0,0,0,1,1,1,1,1,1 、2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4などであり、ミリ秒単位のものではなく、秒より正確なものである。 –

答えて

2

// You got the context from open_input: 
AVFormatContext *pFormatCtx; 
avformat_open_input(&pFormatCtx, inputfilename, NULL, &format_opts); 

// Get a stream from the context 
AVStream pStream= pFormatCtx->streams[i]; 

// Convert packet time (here, dts) to seconds with: 
double seconds= (dts - pStream->start_time) * av_q2d(pStream->time_base); 

// Or convert frame number to seconds with the codec context 
AVCodecContext *pCodecCtx= pStream->pVideoStream->codec; 
double seconds= framenumber * av_q2d(pCodecCtx->time_base); 

これは時間-from-を返します。ビデオが開始されると、秒単位で開始されます。

+0

「フレーム」とは何か、どこから「dts」を取得していますか? –

+1

おそらく問題は解決しましたが、将来のサーチャーのために: 'framenumber'は' pCodecCtx'から得られ、 'dts'はデコード関数を呼び出した後に得られる' AVPacket'から来ます。 – Sam

関連する問題