1. 程式人生 > >ffdshow 原始碼分析 9: 編解碼器有關類的總結

ffdshow 原始碼分析 9: 編解碼器有關類的總結

=====================================================

ffdshow原始碼分析系列文章列表:

=====================================================

前幾篇文章已經完成了ffdshow解碼器封裝的大部分程式碼的分析:

本文再做最後一點的分析。在ffdshow中有如下繼承關係:


前文已經分析過TvideoCodecLibavcodec,TvideoCodecDec,在這裡我們看一下他們的父類:TvideoCodec,TcodecDec,以及前兩個類的父類Tcodec。

其實本文介紹的這3個類充當了介面的作用,TvideoCodecDec繼承TvideoCodec,TcodecDec,以及這兩個類繼承Tcodec,都使用了virtual的方式。

先來看看TvideoCodec。注意這個類強調的是【視訊】:

//編解碼器的父類
class TvideoCodec : virtual public Tcodec
{
public:
    TvideoCodec(IffdshowBase *Ideci);
    virtual ~TvideoCodec();
    bool ok;
    int connectedSplitter;
    bool isInterlacedRawVideo;
    Rational containerSar;

    struct CAPS {
        enum {
            NONE = 0,
            VIS_MV = 1,
            VIS_QUANTS = 2
        };
    };

    virtual void end(void) {}
};

可以看出TvideoCodec定義非常的簡單,只包含了視訊編解碼器會用到的一些變數。注意,是編解碼器,不僅僅是解碼器。

再來看看TcodecDec。注意這個類強調的是【解碼】:

//實現瞭解碼器的祖父類
class TcodecDec : virtual public Tcodec
{
private:
    IdecSink *sink;
protected:
    comptrQ<IffdshowDec> deciD;
    TcodecDec(IffdshowBase *Ideci, IdecSink *Isink);
    virtual ~TcodecDec();
    virtual HRESULT flushDec(void) {
        return S_OK;
    }
public:
    virtual HRESULT flush(void);
};

可以看出TcodecDec定義非常簡單,只包含了解碼器需要的一些變數,注意不限於視訊解碼器,還包含音訊解碼器。有兩個變數比較重要:

IdecSink *sink;
comptrQ<IffdshowDec> deciD;

最後來看一下Tcodec。這個類不再繼承任何類:

//編解碼器的祖父類,都是虛擬函式
class Tcodec
{
protected:
    const Tconfig *config;
    comptr<IffdshowBase> deci;
    Tcodec(IffdshowBase *Ideci);
    virtual ~Tcodec();
public:
    AVCodecID codecId;
    virtual int getType(void) const = 0;
    virtual const char_t* getName(void) const {
        return getMovieSourceName(getType());
    }
    virtual void getEncoderInfo(char_t *buf, size_t buflen) const {
        ff_strncpy(buf, _l("unknown"), buflen);
        buf[buflen - 1] = '\0';
    }
    static const char_t* getMovieSourceName(int source);

    virtual HRESULT flush() {
        return S_OK;
    }
    virtual HRESULT BeginFlush() {
        return S_OK;
    }
    virtual HRESULT EndFlush() {
        return S_OK;
    }
    virtual bool onSeek(REFERENCE_TIME segmentStart) {
        return false;
    }
};

可以看出,該類定義了一些編解碼器會用到的公共函式。有幾個變數還是比較重要的:

const Tconfig *config;
comptr<IffdshowBase> deci;
Tcodec(IffdshowBase *Ideci);
AVCodecID codecId

自此,我們可以總結出ffdshow編解碼器這部分繼承關係如下(圖太大了,截成兩張):

從TcodecDec繼承下來的如下圖所示。包含視訊解碼器以及音訊解碼器。


從TvideoCodec繼承下來的如下圖所示。包含了解碼器類和編碼器類。


總算大體上完成了,關於ffdshow解碼器封裝的內容就先告一段落吧。