オーディオおよびビデオ プロジェクト - FFmpeg および SDL に基づくオーディオおよびビデオ プレーヤーの分析 (11)

導入

このシリーズでは、gitee プロジェクトのオーディオおよびビデオ プレーヤーの説明に多くの時間を費やす予定です。このプロジェクトでは、オーディオとビデオのカプセル化解除、デコード、および SDL レンダリング関連の知識を学ぶことができます。ソース コードに興味がある場合は、FFmpeg および SDL に基づくオーディオおよびビデオ プレーヤーをチェックしてください。

この記事が理解できない場合は、以前の記事「オーディオおよびビデオ プロジェクト - FFmpeg および SDL に基づくオーディオおよびビデオ プレーヤーの分析 (10)」を参照してください。

解析する

私たちの記事では AVFrameQueue について説明しています。まず .h ファイルのコードを見てください。

#ifndef AVFRAMEQUEUE_H_
#define AVFRAMEQUEUE_H_

#include"queue.h"

#ifdef __cplusplus

extern "C" {
#include"libavutil/avutil.h"
#include"libavformat/avformat.h"
#include"libavcodec/avcodec.h"
}

#endif

class AVFrameQueue{
public:
    AVFrameQueue();
    ~AVFrameQueue();
    void Abort();
    int Push(AVFrame* val);
    AVFrame* Pop(const int timeout);
    AVFrame* Front();
    int Size();
private:
    void release();
    Queue<AVFrame*> queue_t;
};

#endif

AVPacketQueue の機能は全体としては Abort、Push、Pop、Front、Size、release に違いはありませんが、唯一の違いは格納されるデータが異なります。 other にはフレーム (Frame) が格納されます。

関数の実装を見てみましょう

アボート:
void AVFrameQueue::Abort(){
    release();
    queue_t.Abort();
}

この関数はプログラムを中断する役割を果たし、最初に release 関数を呼び出してキュー内のデータを解放し、次に Queue 親クラスの Abort メソッドを呼び出してプログラムを終了します。

押す:
int AVFrameQueue::Push(AVFrame* val){
    return queue_t.Push(val);
}

この関数は、キューにデータを追加する役割を果たします。Queue 親クラスの Push メソッドを直接呼び出すため、理解しやすいです。

ポップ:
AVFrame* AVFrameQueue::Pop(const int timeout){
    AVFrame* av_frame = nullptr;
    int ret = queue_t.Pop(av_frame, timeout);
    if(ret < 0){
        perror("AVFrameQueue:: Pop failed");
    }
    return av_frame;
}

この関数は、キューからデータをポップする役割を果たします。この Queue 親クラスのメソッドはポップアップ データをパラメータに割り当てる必要があるため、関数ヘッダーに AVFrame 変数を追加して関数に渡す必要があります。

フロント:
AVFrame* AVFrameQueue::Front(){
    AVFrame* av_frame = nullptr;
    int ret = queue_t.Front(av_frame);
    if(ret < 0){
        perror("AVFrameQueue:: Front failed");
    }
    return av_frame;
}

この関数は、キューの最初のデータを返す役割を果たします。これも分かりやすく、Queue親クラスのFront関数を直接呼び出します。

サイズ:
int AVFrameQueue::Size(){
    return queue_t.Size();
}

この関数はキューの長さを返す役割を果たします。Queue の Size メソッドを直接呼び出すだけです。

リリース:
void AVFrameQueue::release(){
    while(true){
        AVFrame* av_frame = nullptr;
        int ret = queue_t.Pop(av_frame, 1);
        if(ret < 0){
            break;
        }else {
            av_frame_free(&av_frame);
        }
    }
}

この関数は、キューのすべての要素を解放する役割を果たします。この関数には while の無限ループがあり、データがなくなるまで継続的にデータをキューにポップし、その後ループから抜け出します。

これで、Queue、AVPacketQueue、AVFrameQueue はすべて完了しました。次回の記事では、音声とビデオの同期の仕組みとその実装方法について説明します。

次に何が起こったのか知りたい場合は、次回の内訳を聞いてください。

おすすめ

転載: blog.csdn.net/weixin_60701731/article/details/134474591