summaryrefslogtreecommitdiffstats
path: root/thirdparties/win32/include/directshow/vtrans.h
blob: a787dbc6b1884c6eb120a19db2b27757bb07d82b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//------------------------------------------------------------------------------
// File: VTrans.h
//
// Desc: DirectShow base classes - defines a video transform class.
//
// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------


// This class is derived from CTransformFilter, but is specialised to handle
// the requirements of video quality control by frame dropping.
// This is a non-in-place transform, (i.e. it copies the data) such as a decoder.

class CVideoTransformFilter : public CTransformFilter
{
public:

    CVideoTransformFilter(__in_opt LPCTSTR, __inout_opt LPUNKNOWN, REFCLSID clsid);
    ~CVideoTransformFilter();
    HRESULT EndFlush();

    // =================================================================
    // ----- override these bits ---------------------------------------
    // =================================================================
    // The following methods are in CTransformFilter which is inherited.
    // They are mentioned here for completeness
    //
    // These MUST be supplied in a derived class
    //
    // NOTE:
    // virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut);
    // virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE;
    // virtual HRESULT CheckTransform
    //     (const CMediaType* mtIn, const CMediaType* mtOut) PURE;
    // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *);
    // virtual HRESULT DecideBufferSize
    //     (IMemAllocator * pAllocator, ALLOCATOR_PROPERTIES *pprop) PURE;
    // virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) PURE;
    //
    // These MAY also be overridden
    //
    // virtual HRESULT StopStreaming();
    // virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt);
    // virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin);
    // virtual HRESULT BreakConnect(PIN_DIRECTION dir);
    // virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin);
    // virtual HRESULT EndOfStream(void);
    // virtual HRESULT BeginFlush(void);
    // virtual HRESULT EndFlush(void);
    // virtual HRESULT NewSegment
    //     (REFERENCE_TIME tStart,REFERENCE_TIME tStop,double dRate);
#ifdef PERF

    // If you override this - ensure that you register all these ids
    // as well as any of your own,
    virtual void RegisterPerfId() {
        m_idSkip        = MSR_REGISTER(TEXT("Video Transform Skip frame"));
        m_idFrameType   = MSR_REGISTER(TEXT("Video transform frame type"));
        m_idLate        = MSR_REGISTER(TEXT("Video Transform Lateness"));
        m_idTimeTillKey = MSR_REGISTER(TEXT("Video Transform Estd. time to next key"));
        CTransformFilter::RegisterPerfId();
    }
#endif

protected:

    // =========== QUALITY MANAGEMENT IMPLEMENTATION ========================
    // Frames are assumed to come in three types:
    // Type 1: an AVI key frame or an MPEG I frame.
    //        This frame can be decoded with no history.
    //        Dropping this frame means that no further frame can be decoded
    //        until the next type 1 frame.
    //        Type 1 frames are sync points.
    // Type 2: an AVI non-key frame or an MPEG P frame.
    //        This frame cannot be decoded unless the previous type 1 frame was
    //        decoded and all type 2 frames since have been decoded.
    //        Dropping this frame means that no further frame can be decoded
    //        until the next type 1 frame.
    // Type 3: An MPEG B frame.
    //        This frame cannot be decoded unless the previous type 1 or 2 frame
    //        has been decoded AND the subsequent type 1 or 2 frame has also
    //        been decoded.  (This requires decoding the frames out of sequence).
    //        Dropping this frame affects no other frames.  This implementation
    //        does not allow for these.  All non-sync-point frames are treated
    //        as being type 2.
    //
    // The spacing of frames of type 1 in a file is not guaranteed.  There MUST
    // be a type 1 frame at (well, near) the start of the file in order to start
    // decoding at all.  After that there could be one every half second or so,
    // there could be one at the start of each scene (aka "cut", "shot") or
    // there could be no more at all.
    // If there is only a single type 1 frame then NO FRAMES CAN BE DROPPED
    // without losing all the rest of the movie.  There is no way to tell whether
    // this is the case, so we find that we are in the gambling business.
    // To try to improve the odds, we record the greatest interval between type 1s
    // that we have seen and we bet on things being no worse than this in the
    // future.

    // You can tell if it's a type 1 frame by calling IsSyncPoint().
    // there is no architected way to test for a type 3, so you should override
    // the quality management here if you have B-frames.

    int m_nKeyFramePeriod; // the largest observed interval between type 1 frames
    // 1 means every frame is type 1, 2 means every other.

    int m_nFramesSinceKeyFrame; // Used to count frames since the last type 1.
    // becomes the new m_nKeyFramePeriod if greater.

    BOOL m_bSkipping;           // we are skipping to the next type 1 frame

#ifdef PERF
    int m_idFrameType;          // MSR id Frame type.  1=Key, 2="non-key"
    int m_idSkip;               // MSR id skipping
    int m_idLate;               // MSR id lateness
    int m_idTimeTillKey;        // MSR id for guessed time till next key frame.
#endif

    virtual HRESULT StartStreaming();

    HRESULT AbortPlayback(HRESULT hr);	// if something bad happens

    HRESULT Receive(IMediaSample *pSample);

    HRESULT AlterQuality(Quality q);

    BOOL ShouldSkipFrame(IMediaSample * pIn);

    int m_itrLate;              // lateness from last Quality message
    // (this overflows at 214 secs late).
    int m_tDecodeStart;         // timeGetTime when decode started.
    int m_itrAvgDecode;         // Average decode time in reference units.

    BOOL m_bNoSkip;             // debug - no skipping.

    // We send an EC_QUALITY_CHANGE notification to the app if we have to degrade.
    // We send one when we start degrading, not one for every frame, this means
    // we track whether we've sent one yet.
    BOOL m_bQualityChanged;

    // When non-zero, don't pass anything to renderer until next keyframe
    // If there are few keys, give up and eventually draw something
    int m_nWaitForKey;
};
OpenPOWER on IntegriCloud