📄 baseclass.pas
字号:
Fmt : TAMMediaType; // Media type of connection
FStart : TReferenceTime; // time from NewSegment call
FStop : TReferenceTime; // time from NewSegment
FRate : double; // rate from NewSegment
FRef : LongInt;
function GetCurrentMediaType: TBCMediaType;
function GetAMMediaType: PAMMediaType;
protected
procedure DisplayPinInfo(ReceivePin: IPin);
procedure DisplayTypeInfo(Pin: IPin; pmt: PAMMediaType);
// used to agree a media type for a pin connection
// given a specific media type, attempt a connection (includes
// checking that the type is acceptable to this pin)
function AttemptConnection(
ReceivePin: IPin; // connect to this pin
pmt : PAMMediaType // using this type
): HRESULT;
// try all the media types in this enumerator - for each that
// we accept, try to connect using ReceiveConnection.
function TryMediaTypes(
ReceivePin: IPin; // connect to this pin
pmt : PAMMediaType; // proposed type from Connect
Enum : IEnumMediaTypes // try this enumerator
): HRESULT;
// establish a connection with a suitable mediatype. Needs to
// propose a media type if the pmt pointer is null or partially
// specified - use TryMediaTypes on both our and then the other pin's
// enumerator until we find one that works.
function AgreeMediaType(
ReceivePin: IPin; // connect to this pin
pmt : PAMMediaType // proposed type from Connect
): HRESULT;
function DisconnectInternal: HRESULT; stdcall;
public
function NonDelegatingAddRef: Integer; override; stdcall;
function NonDelegatingRelease: Integer; override; stdcall;
constructor Create(
ObjectName: string; // Object description
Filter : TBCBaseFilter; // Owning filter who knows about pins
Lock : TBCCritSec; // Object who implements the lock
out hr : HRESULT; // General OLE return code
Name : WideString; // Pin name for us
dir : TPinDirection); // Either PINDIR_INPUT or PINDIR_OUTPUT
destructor destroy; override;
// --- IPin methods ---
// take lead role in establishing a connection. Media type pointer
// may be null, or may point to partially-specified mediatype
// (subtype or format type may be GUID_NULL).
function Connect(pReceivePin: IPin; const pmt: PAMMediaType): HRESULT; virtual; stdcall;
// (passive) accept a connection from another pin
function ReceiveConnection(pConnector: IPin; const pmt: TAMMediaType): HRESULT; virtual; stdcall;
function Disconnect: HRESULT; virtual; stdcall;
function ConnectedTo(out pPin: IPin): HRESULT; virtual; stdcall;
function ConnectionMediaType(out pmt: TAMMediaType): HRESULT; virtual; stdcall;
function QueryPinInfo(out pInfo: TPinInfo): HRESULT; virtual; stdcall;
function QueryDirection(out pPinDir: TPinDirection): HRESULT; stdcall;
function QueryId(out Id: PWideChar): HRESULT; virtual; stdcall;
// does the pin support this media type
function QueryAccept(const pmt: TAMMediaType): HRESULT; virtual; stdcall;
// return an enumerator for this pins preferred media types
function EnumMediaTypes(out ppEnum: IEnumMediaTypes): HRESULT; virtual; stdcall;
// return an array of IPin* - the pins that this pin internally connects to
// All pins put in the array must be AddReffed (but no others)
// Errors: "Can't say" - FAIL, not enough slots - return S_FALSE
// Default: return E_NOTIMPL
// The filter graph will interpret NOT_IMPL as any input pin connects to
// all visible output pins and vice versa.
// apPin can be NULL if nPin==0 (not otherwise).
function QueryInternalConnections(out apPin: IPin; var nPin: ULONG): HRESULT; virtual; stdcall;
// Called when no more data will be sent
function EndOfStream: HRESULT; virtual; stdcall;
function BeginFlush: HRESULT; virtual; stdcall; abstract;
function EndFlush: HRESULT; virtual; stdcall; abstract;
// Begin/EndFlush still PURE
// NewSegment notifies of the start/stop/rate applying to the data
// about to be received. Default implementation records data and
// returns S_OK.
// Override this to pass downstream.
function NewSegment(tStart, tStop: TReferenceTime; dRate: double): HRESULT; virtual; stdcall;
// --- IQualityControl methods ---
function Notify(pSelf: IBaseFilter; q: TQuality): HRESULT; virtual; stdcall;
function SetSink(piqc: IQualityControl): HRESULT; virtual; stdcall;
// --- helper methods ---
// Returns True if the pin is connected. false otherwise.
function IsConnected: boolean;
// Return the pin this is connected to (if any)
property GetConnected: IPin read FConnected;
// Check if our filter is currently stopped
function IsStopped: boolean;
// find out the current type version (used by enumerators)
function GetMediaTypeVersion: longint; virtual;
procedure IncrementTypeVersion;
// switch the pin to active (paused or running) mode
// not an error to call this if already active
function Active: HRESULT; virtual;
// switch the pin to inactive state - may already be inactive
function Inactive: HRESULT; virtual;
// Notify of Run() from filter
function Run(Start: TReferenceTime): HRESULT; virtual;
// check if the pin can support this specific proposed type and format
function CheckMediaType(mt: PAMMediaType): HRESULT; virtual; abstract;
// set the connection to use this format (previously agreed)
function SetMediaType(mt: PAMMediaType): HRESULT; virtual;
// check that the connection is ok before verifying it
// can be overridden eg to check what interfaces will be supported.
function CheckConnect(Pin: IPin): HRESULT; virtual;
// Set and release resources required for a connection
function BreakConnect: HRESULT; virtual;
function CompleteConnect(ReceivePin: IPin): HRESULT; virtual;
// returns the preferred formats for a pin
function GetMediaType(Position: integer; out MediaType: PAMMediaType): HRESULT; virtual;
// access to NewSegment values
property CurrentStopTime: TReferenceTime read FStop;
property CurrentStartTime: TReferenceTime read FStart;
property CurrentRate: double read FRate;
// Access name
property Name: WideString read FPinName;
property CanReconnectWhenActive: boolean read FCanReconnectWhenActive write FCanReconnectWhenActive;
// Media type
property CurrentMediaType: TBCMediaType read GetCurrentMediaType;
property AMMediaType: PAMMediaType read GetAMMediaType;
end;
TBCEnumPins = class(TInterfacedObject, IEnumPins)
private
FPosition: integer; // Current ordinal position
FPinCount: integer; // Number of pins available
FFilter: TBCBaseFilter; // The filter who owns us
FVersion: LongInt; // Pin version information
// These pointers have not been AddRef'ed and
// so they should not be dereferenced. They are
// merely kept to ID which pins have been enumerated.
FPinCache: TList;
{ If while we are retrieving a pin for example from the filter an error
occurs we assume that our internal state is stale with respect to the
filter (someone may have deleted all the pins). We can check before
starting whether or not the operation is likely to fail by asking the
filter what it's current version number is. If the filter has not
overriden the GetPinVersion method then this will always match }
function AreWeOutOfSync: boolean;
(* This method performs the same operations as Reset, except is does not clear
the cache of pins already enumerated. *)
function Refresh: HRESULT; stdcall;
public
constructor Create(Filter: TBCBaseFilter; EnumPins: TBCEnumPins);
destructor Destroy; override;
function Next(cPins: ULONG; // place this many pins...
out ppPins: IPin; // ...in this array of IPin*
pcFetched: PULONG // actual count passed returned here
): HRESULT; stdcall;
function Skip(cPins: ULONG): HRESULT; stdcall;
function Reset: HRESULT; stdcall;
function Clone(out ppEnum: IEnumPins): HRESULT; stdcall;
end;
TBCEnumMediaTypes = class(TInterfacedObject, IEnumMediaTypes)
private
FPosition: Cardinal; // Current ordinal position
FPin : TBCBasePin; // The pin who owns us
FVersion : LongInt; // Media type version value
function AreWeOutOfSync: boolean;
public
constructor Create(Pin: TBCBasePin; EnumMediaTypes: TBCEnumMediaTypes);
destructor Destroy; override;
function Next(cMediaTypes: ULONG; out ppMediaTypes: PAMMediaType;
pcFetched: PULONG): HRESULT; stdcall;
function Skip(cMediaTypes: ULONG): HRESULT; stdcall;
function Reset: HRESULT; stdcall;
function Clone(out ppEnum: IEnumMediaTypes): HRESULT; stdcall;
end;
TBCBaseOutputPin = class(TBCBasePin)
protected
FAllocator: IMemAllocator;
// interface on the downstreaminput pin, set up in CheckConnect when we connect.
FInputPin : IMemInputPin;
public
constructor Create(ObjectName: string; Filter: TBCBaseFilter; Lock: TBCCritSec;
out hr: HRESULT; const Name: WideString);
// override CompleteConnect() so we can negotiate an allocator
function CompleteConnect(ReceivePin: IPin): HRESULT; override;
// negotiate the allocator and its buffer size/count and other properties
// Calls DecideBufferSize to set properties
function DecideAllocator(Pin: IMemInputPin; out Alloc: IMemAllocator): HRESULT; virtual;
// override this to set the buffer size and count. Return an error
// if the size/count is not to your liking.
// The allocator properties passed in are those requested by the
// input pin - use eg the alignment and prefix members if you have
// no preference on these.
function DecideBufferSize(Alloc: IMemAllocator; propInputRequest: PAllocatorProperties): HRESULT; virtual;
// returns an empty sample buffer from the allocator
function GetDeliveryBuffer(out Sample: IMediaSample; StartTime: PReferenceTime;
EndTime: PReferenceTime; Flags: Longword): HRESULT; virtual;
// deliver a filled-in sample to the connected input pin
// note - you need to release it after calling this. The receiving
// pin will addref the sample if it needs to hold it beyond the
// call.
function Deliver(Sample: IMediaSample): HRESULT; virtual;
// override this to control the connection
function InitAllocator(out Alloc: IMemAllocator): HRESULT; virtual;
function CheckConnect(Pin: IPin): HRESULT; override;
function BreakConnect: HRESULT; override;
// override to call Commit and Decommit
function Active: HRESULT; override;
function Inactive: HRESULT; override;
// we have a default handling of EndOfStream which is to return
// an error, since this should be called on input pins only
function EndOfStream: HRESULT; override; stdcall;
// called from elsewhere in our filter to pass EOS downstream to
// our connected input pin
function DeliverEndOfStream: HRESULT; virtual;
// same for Begin/EndFlush - we handle Begin/EndFlush since it
// is an error on an output pin, and we have Deliver methods to
// call the methods on the connected pin
function BeginFlush: HRESULT; override; stdcall;
function EndFlush: HRESULT; override; stdcall;
function DeliverBeginFlush: HRESULT; virtual;
function DeliverEndFlush: HRESULT; virtual;
// deliver NewSegment to connected pin - you will need to
// override this if you queue any data in your output pin.
function DeliverNewSegment(Start, Stop: TReferenceTime; Rate: double): HRESULT; virtual;
end;
TBCBaseInputPin = class(TBCBasePin, IMemInputPin)
protected
FAllocator: IMemAllocator; // Default memory allocator
// allocator is read-only, so received samples
// cannot be modified (probably only relevant to in-place
// transforms
FReadOnly: boolean;
//private: this should really be private... only the MPEG code
// currently looks at it directly and it should use IsFlushing().
// in flushing state (between BeginFlush and EndFlush)
// if True, all Receives are returned with S_FALSE
FFlushing: boolean;
// Sample properties - initalized in Receive
FSampleProps: TAMSample2Properties;
public
constructor Create(ObjectName: string; Filter: TBCBaseFilter;
Lock: TBCCritSec; out hr: HRESULT; Name: WideString);
destructor Destroy; override;
// ----------IMemInputPin--------------
// return the allocator interface that this input pin
// would like the output pin to use
function GetAllocator(out ppAllocator: IMemAllocator): HRESULT; stdcall;
// tell the input pin which allocator the output pin is actually
// going to use.
function NotifyAllocator(pAllocator: IMemAllocator; bReadOnly: BOOL): HRESULT; stdcall;
// this method is optional (can return E_NOTIMPL).
// default implementation returns E_NOTIMPL. Override if you have
// specific alignment or prefix needs, but could use an upstream
// allocator
function GetAllocatorRequirements(out pProps: TAllocatorProperties): HRESULT; stdcall;
// do something with this media sample
function Receive(pSample: IMediaSample): HRESULT; virtual; stdcall;
// do something with these media samples
function ReceiveMultiple(var pSamples: IMediaSample; nSamples: Longint;
out nSamplesProcessed: Longint): HRESULT; stdcall;
// See if Receive() blocks
function ReceiveCanBlock: HRESULT; stdcall;
//-----------Helper-------------
// Default handling for BeginFlush - call at the beginning
// of your implementation (makes sure that all Receive calls
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -