123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- //------------------------------------------------------------------------------
- // 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;
- };
|