ffmpeg研究ノート(3)

1. FFmpegデコードAPI分析

  1. avformat_open_input分析
    関数avformat_open_inputは、提供されたファイルパスに従ってファイル形式を決定します。実際、このステップを通じて、使用するデマクサーを決定します。

例:flvの場合、Demuxerは対応するff_flv_demuxerを使用するため、対応するキーライフサイクルメソッドread_header、read_packet、read_seek、およびread_closeはすべて、flvのDemuxerの関数ポインターで指定された関数を使用します。read_headerは、AVStream構造を構築して、後続の手順でAVStreamを入力パラメーターとして引き続き使用できるようにします。

  1. avformat_find_stream_info分析
    このメソッドの機能は、ストリームのすべてのメタデータ情報を入力することです。この方法では、まず適切なデコーダーを見つけてから、対応するデコーダーを開き、デマルチプレクサーでread_packet関数を使用して、デコードするデータを読み取ります。もちろん、デコードするデータが多いほど、分析されるストリーム情報の精度が高くなります。ローカルリソースであれば、すぐに正確な情報が得られます。ただし、ネットワークリソースの場合は遅くなるため、この関数には読み取りデータの長さを制御するいくつかのパラメーターがあり、1つはプローブサイズ、もう1つはmax_analyze_duration、もう1つはfps_probe_sizeです。これらの3つのパラメーターは一緒にデコードされたデータを制御します構成されたパラメーターの値が小さい場合、この関数の実行時間は速くなりますが、AVStream構造内の情報(ビデオの幅、高さ、fps、エンコーディングタイプ)は不正確になります。

  2. av_read_frameは
    、このメソッドによって読み取られたデータがAVPacketであることを分析します。FFmpegの初期バージョンで開発者向けに開発された関数は実際にはav_read_packetですが、開発者はAVPacketのデータをデコーダーで処理できない状況に対処する必要があります。未処理の圧縮データをキャッシュする問題。したがって、FFmpegの新しいバージョンでは、この関数はこの状況を処理するために提供されています。この関数の実装は、まずDemuxerのread_packetメソッドに委任されます。もちろん、read_packetは、サービングレイヤーとプロトコルレイヤーの処理後にここにデータを返し、この関数でデータバッファリングが実行されます。

オーディオストリームの場合、1つのAVPacketに複数のAVFrameが含まれる場合がありますが、1つのビデオストリームの場合、1つのAVPacketに含まれるAVFrameは1つだけであり、この関数は最終的に1つのAVPacket構造のみを返します。

  1. avcodec_decode分析
    このメソッドには2つの部分があります。1つはビデオをデコードすることで、もう1つはオーディオをデコードすることです。上記の関数分析では、デコードは対応するデコーダーに実装を委託することがわかっています。デコーダーをオンにすると、対応するデコーダーの実装が見つかります。たとえば、H264のデコードでは、ff_h264_decoderが見つかります。その中に、対応するライフサイクル関数の実装があります。最も重要なものはinit、decode、およびcloseメソッドです。これらは、デコーダーを開く、デコーダーを閉じる、およびデコーダーを閉じる操作に対応し、デコードプロセスは、decodeメソッドを呼び出すことです。

  2. avformat_close_input分析
    この関数は、対応するリソースの解放を担当します。最初に、対応するDemuxerでライフサイクルのread_closeメソッドを呼び出し、次にAVFormatContextを解放して、最後にファイルまたはリモートネットワークリンクを閉じます。

2. FFmpegエンコードAPI分析

  1. avformat_alloc_output_context2分析
    この関数は、avformat_alloc_contextメソッドを呼び出して、AVFormatContext構造体を割り当てる必要があります。もちろん、最も重要なことは、前の手順で登録されたMuxerおよびDemuxerパーツ(つまり、パッケージフォーマットパーツ)に従って対応するフォーマットを見つけることです。それはflv形式、MP4形式、mov形式、またはMP3形式などである可能性があります。対応する形式が見つからない場合(構成オプションでこの形式のスイッチがオンになっていないためである必要があります)、正しい検索に戻りますフォーマットエラープロンプト。APIを呼び出すときに、av_err2strを使用して、返された整数エラーコードを人間が読める文字列に変換できます。これは、デバッグに非常に役立つツール関数です。この関数は最後に、見つかったフォーマットをAVFormatContextタイプのoformatに割り当てます。

  2. avio_open2分析は
    最初に関数ffurl_openを呼び出して、URLProtocolを含むURLContext構造を構築します(最初のステップregister_protocolに登録されているプロトコルリンクリストに移動する必要があります)。次に、avio_alloc_contexメソッドを呼び出してAVIOContext構造を割り当てます。 、そして前の手順で作成したURLProtocolを渡し、前の手順で割り当てたAVIOContext構造体をAVFormatContextプロパティに割り当てます。

以下は、上記の説明で要約した構造間のフレームワーク図です。詳細については、この図を参照してください。

ここに画像の説明を挿入

avio_open2のプロセスも、上記のavformat_open_inputプロセスの分析の逆のプロセスです。エンコードプロセスとデコードプロセスは論理的には逆のプロセスであるため、FFmpegの実装プロセスでは、これらは互いに逆のプロセスでもあります。

  1. その他のAPI(ステップ)分析
    のエンコードエンコードの他のステップもデコードの逆プロセスです。デコードプロセスのavformat_find_stream_infoは、エンコードavformat_new_streamおよびavformat_write_headerに対応します。

avformat_new_stream関数は、オーディオストリームまたはビデオストリームの情報を入力し、AVStream構造体を割り当て、オーディオストリーム内のチャネル、サンプリングレート、表現形式、エンコーダーおよびその他の情報を配布し、幅、高さ、フレームレートを配布します。フォーマットやエンコーダーなどの情報を表します。
デコードプロセスのavformat_write_header関数とread_headerは逆のプロセスであるため、ここでは詳しく説明しません。
次のステップはコーディング段階です。

  1. 手動でカプセル化されたAVFrame構造体をavcodec_encodec_videoメソッドの入力として受け取り、それをAVPacketにエンコードしてから、av_write_frameメソッドを呼び出してメディアファイルに出力します。

  2. av_write_frameメソッドは、エンコードされたAVPacket構造をMuxerのwrite_packetライフサイクルメソッドの入力として使用します。write_packetは、独自のカプセル化形式のヘッダー情報を追加し、プロトコルレイヤーを呼び出して、ローカルファイルまたはネットワークサーバーに書き込みます。

  3. 最後のステップはav_write_trailerです(この関数には非常に大きな穴があります。write_header操作が実行されない場合、write_trailer操作は直接実行され、プログラムは直接Carshオフになるため、これらの2つの関数はペアで表示される必要があります)、av_write_trailerは出力のないAVPacketを配置しますすべてが出力のためにプロトコルレイヤーにスローされ、次にMuxerのwrite_trailerライフサイクルメソッドが呼び出されます(形式が異なり、書き込まれた末尾が異なります)。

おすすめ

転載: blog.csdn.net/qq_43716137/article/details/108658204