📄 baseclass.pas
字号:
// --- TBCBaseOutputPin ------------
function QueryId(out Id: PWideChar): HRESULT; override; stdcall;
// Grab and release extra interfaces if required
function CheckConnect(Pin: IPin): HRESULT; override;
function BreakConnect: HRESULT; override;
function CompleteConnect(ReceivePin: IPin): HRESULT; override;
// check that we can support this output type
function CheckMediaType(mtOut: PAMMediaType): HRESULT; override;
// set the connection media type
function SetMediaType(pmt: PAMMediaType): HRESULT; override;
// called from CBaseOutputPin during connection to ask for
// the count and size of buffers we need.
function DecideBufferSize(Alloc: IMemAllocator; Prop: PAllocatorProperties): HRESULT; override;
// returns the preferred formats for a pin
function GetMediaType(Position: integer; out MediaType: PAMMediaType): HRESULT; override;
// inherited from IQualityControl via CBasePin
function Notify(Sendr: IBaseFilter; q: TQuality): HRESULT; override; stdcall;
end;
// milenko start (added TBCVideoTransformFilter conversion)
TBCVideoTransformFilter = class(TBCTransformFilter)
public
constructor Create(Name: WideString; Unk: IUnknown; clsid: TGUID);
destructor Destroy; override;
function EndFlush: HRESULT; override;
// =================================================================
// ----- 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,
procedure RegisterPerfId; virtual;
{$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.
FKeyFramePeriod: integer; // the largest observed interval between type 1 frames
// 1 means every frame is type 1, 2 means every other.
FFramesSinceKeyFrame: integer; // Used to count frames since the last type 1.
// becomes the new m_nKeyFramePeriod if greater.
FSkipping: Boolean; // we are skipping to the next type 1 frame
{$IFDEF PERF}
FidFrameType: integer; // MSR id Frame type. 1=Key, 2="non-key"
FidSkip: integer; // MSR id skipping
FidLate: integer; // MSR id lateness
FidTimeTillKey: integer; // MSR id for guessed time till next key frame.
{$ENDIF}
FitrLate: integer; // lateness from last Quality message
// (this overflows at 214 secs late).
FtDecodeStart: integer; // timeGetTime when decode started.
FitrAvgDecode: integer; // Average decode time in reference units.
FNoSkip: Boolean; // 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.
FQualityChanged: Boolean;
// When non-zero, don't pass anything to renderer until next keyframe
// If there are few keys, give up and eventually draw something
FWaitForKey: integer;
function AbortPlayback(hr: HRESULT): HRESULT; // if something bad happens
function ShouldSkipFrame(pIn: IMediaSample): Boolean;
public
function StartStreaming: HRESULT; override;
function Receive(Sample: IMediaSample): HRESULT; override;
function AlterQuality(const q: TQuality): HRESULT; override;
end;
// milenko end
TBCTransInPlaceOutputPin = class;
TBCTransInPlaceInputPin = class;
TBCTransInPlaceFilter = class(TBCTransformFilter)
public
// map getpin/getpincount for base enum of pins to owner
// override this to return more specialised pin objects
function GetPin(n: integer): TBCBasePin; override;
// Set bModifiesData == false if your derived filter does
// not modify the data samples (for instance it's just copying
// them somewhere else or looking at the timestamps).
constructor Create(ObjectName: string; unk: IUnKnown; clsid: TGUID;
out hr: HRESULT; ModifiesData: boolean = True);
constructor CreateFromFactory(Factory: TBCClassFactory; const Controller: IUnknown); override;
// The following are defined to avoid undefined pure virtuals.
// Even if they are never called, they will give linkage warnings/errors
// We override EnumMediaTypes to bypass the transform class enumerator
// which would otherwise call this.
function GetMediaType(Position: integer; out MediaType: PAMMediaType): HRESULT; override;
// This is called when we actually have to provide out own allocator.
function DecideBufferSize(Alloc: IMemAllocator; propInputRequest: PAllocatorProperties): HRESULT; override;
// The functions which call this in CTransform are overridden in this
// class to call CheckInputType with the assumption that the type
// does not change. In Debug builds some calls will be made and
// we just ensure that they do not assert.
function CheckTransform(mtIn, mtOut: PAMMediaType): HRESULT; override;
// =================================================================
// ----- You may want to override this -----------------------------
// =================================================================
function CompleteConnect(dir: TPinDirection; ReceivePin: IPin): HRESULT; override;
// chance to customize the transform process
function Receive(Sample: IMediaSample): HRESULT; override;
// =================================================================
// ----- You MUST override these -----------------------------------
// =================================================================
function Transform(Sample: IMediaSample): HRESULT; reintroduce; virtual; abstract;
// this goes in the factory template table to create new instances
// static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *);
protected
FModifiesData: boolean; // Does this filter change the data?
function Copy(Source: IMediaSample): IMediaSample;
// these hold our input and output pins
function InputPin: TBCTransInPlaceInputPin;
function OutputPin: TBCTransInPlaceOutputPin;
// Helper to see if the input and output types match
function TypesMatch: boolean;
// Are the input and output allocators different?
function UsingDifferentAllocators: boolean;
end;
TBCTransInPlaceInputPin = class(TBCTransformInputPin)
protected
FTIPFilter: TBCTransInPlaceFilter; // our filter
FReadOnly : boolean; // incoming stream is read only
public
constructor Create(ObjectName: string; Filter: TBCTransInPlaceFilter;
out hr: HRESULT; Name: WideString);
// --- IMemInputPin -----
// Provide an enumerator for media types by getting one from downstream
function EnumMediaTypes(out ppEnum: IEnumMediaTypes): HRESULT; override; stdcall;
// Say whether media type is acceptable.
function CheckMediaType(pmt: PAMMediaType): HRESULT; override;
// Return our upstream allocator
function GetAllocator(out Allocator: IMemAllocator): HRESULT; stdcall;
// get told which allocator the upstream output pin is actually
// going to use.
function NotifyAllocator(Allocator: IMemAllocator; ReadOnly: BOOL): HRESULT; stdcall;
// Allow the filter to see what allocator we have
// N.B. This does NOT AddRef
function PeekAllocator: IMemAllocator;
// Pass this on downstream if it ever gets called.
function GetAllocatorRequirements(props: PAllocatorProperties): HRESULT; stdcall;
property ReadOnly: Boolean read FReadOnly;
end;
// ==================================================
// Implements the output pin
// ==================================================
TBCTransInPlaceOutputPin = class(TBCTransformOutputPin)
protected
// m_pFilter points to our CBaseFilter
FTIPFilter: TBCTransInPlaceFilter;
public
constructor Create(ObjectName: string; Filter: TBCTransInPlaceFilter;
out hr: HRESULT; Name: WideString);
// --- CBaseOutputPin ------------
// negotiate the allocator and its buffer size/count
// Insists on using our own allocator. (Actually the one upstream of us).
// We don't override this - instead we just agree the default
// then let the upstream filter decide for itself on reconnect
// virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc);
// Provide a media type enumerator. Get it from upstream.
function EnumMediaTypes(out ppEnum: IEnumMediaTypes): HRESULT; override; stdcall;
// Say whether media type is acceptable.
function CheckMediaType(pmt: PAMMediaType): HRESULT; override;
// This just saves the allocator being used on the output pin
// Also called by input pin's GetAllocator()
procedure SetAllocator(Allocator: IMemAllocator);
function ConnectedIMemInputPin: IMemInputPin;
// Allow the filter to see what allocator we have
// N.B. This does NOT AddRef
function PeekAllocator: IMemAllocator;
end;
TBCBasePropertyPage = class(TBCUnknown, IPropertyPage)
private
FObjectSet: boolean; // SetObject has been called or not.
protected
FPageSite: IPropertyPageSite; // Details for our property site
FDirty: boolean; // Has anything been changed
FForm: TFormPropertyPage;
public
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -