単純計算することで、ラインは、ビデオのIフレームに分割します。完全なコードを参照してくださいhttps://andy-zhangtao.github.io/ffmpeg-examples/
用語集
私たちは、最初に以下の用語および概念を定義する必要があります。
- I / P / Bフレーム(特定の違いを参照https://www.jianshu.com/p/18af03556431の)
Iフレーム:イントラ符号化フレーム(キーフレーム)
Pフレーム:順方向予測フレーム(に従って計算Iフレーム差分値)
フレームB:双方向予測フレーム(I及びPフレームとの差から計算されます) - PTS:タイムスケール枠表示(時間を指し、この表示枠)
- DTS(この時点で時間内にフレームをデコード)フレームの復号時間スケール
- タイムスタンプ:ビデオのフレーム内のタイムスタンプ
- Time_base:ビデオは、「スケール」の時刻を示しています
プロセスフロー
ビデオ内には絶対時間、相対時間のみ(ビデオ開始位置に対して)が存在しません。プレーヤーのタイムラインでは、例えば、「午後12時00分05秒」を参照して復号し、相対的な開始時点をレンダリング(00:00:00)現在のフレームを見ていることを示します。
そして、「午後12時00分05秒」だけで、ユーザーが簡単に理解することができるようにすると、タイムスタンプと一緒に保存された映像内の展開タイムスタンプ「午後12時00分05秒は、」(比較的「5000000μs」になりそうではありません)丸め考えます。
そして、タイムスタンプは、それが計算方法ですか?この場合、PTSとTime_baseによって算出一致させる必要があります。
まずTime_baseを見て。定規のようなTime_baseは、(1,60)としてフルスケールを、マークされた時間スケールは、単位時間当たりの1/60である1/60秒で表します。(1,1000)そうである場合には、単位時間当たりの示す1マイクロ秒です。
上記のPTSを言えば、多くの時間スケールを取っている時間スケール表示、です。time_baseは、各スケールが長いことを意味している国立成功大学方言PTS変換は、スケールの数によって占有されています。
しかし、これはそれが何であるかを使用しているのですか?Time_base最も重要な役割は、の「タイム・リズム」を統一することです。time_base 1/1000ビデオ符号化を使用する場合、例えば、フレームは、PTS 465,000として保存されます。9000分の1 time_base交換ビデオデコードが、その場合、時間スケールが矛盾している場合、正しい復号を保証するように、PTS * encode_time_baseを復号する際に、我々は、タイムスタンプに変換する必要があります。
コーディング
コードは、ビューの次の点によって、およびタイムスタンプの時間に換算する方法上記の理論を説明します。
したがって、PTSだけに、各フレームを表示する必要性、time_base、時間とは限り入力を初期化するためとして、出力を初期化する必要はありません。
初期入力ソース
前にいくつかのアイデアの導入を初期化するためによると、唯一に従う必要があります打开文件
- > 判断视频流
- > 初始化解码器
その上、このようなステップ。
+------------------------+ +-------------------------+
| avformat_open_input | ------------>|avformat_find_stream_info|
+------------------------+ +-------------------------+
|
|
|
\|/
+-----------------------------+ +-------------------------+
|avcodec_parameters_to_context| <---------| avcodec_find_decoder |
+-----------------------------+ +-------------------------+
avcodec_parameters_to_context
特に懸念では、この機能は、入力ソースの符号化情報に基づいて、符号化コンテキストを初期化するために、ユーザによって指定されます。符号化された情報は、不可解な復号エラーと一致していないか、正しく設定されている場合。一般的にこの関数を呼び出した後、デコードエラーのほとんどが消えることができます。
時間の計算
time_baseは構造体であります
typedef struct AVRational{
int num; ///< Numerator
int den; ///< Denominator
} AVRational;
numが分子、デン分母を表しています。numのtime_baseが1であるため、毎秒十分位数は、コピーの数を表しデン。上記pts*time_base
そうすることによって、どのように多くの代表各特定のタイムスケールを算出する必要があるので、それは、タイムスタンプに描画することができav_q2d
、各スケールのためのドロー特定の値。
デコードされたフレームデータのサイクル時間の後、直接することができるiframe->pts
現在のフレームのPTS値を読み取り、次いで引き出すことができる現在のタイムスタンプのスケール値を掛けましたiframe->pts * av_q2d(_time_base)
。
擬似コードは次のよう:
while av_read_frame {
avcodec_send_packet
...
while avcodec_receive_frame {
...
iframe->pts * av_q2d(_time_base)
...
}
}