?? upushsource.pas
字號:
//------------------------------------------------------------------------------
// File: UPushSource.pas
// Original file(s): Setup.cpp, PushSource.h,
// PushSourceBitmap.cpp, PushSourceBitmapSet.cpp,
// PushSourceDesktop.cpp, PushSource.h,
// DibHelper.cpp, DibHelper.h, PushGuids.h
// Converted to Delphi by Nevhasymyy Andriy (E-Mail: a.n@email.com)
// Thanks to Henri Gourvest (hgourvest@progdigy.com)
//
// Desc: DirectShow sample code - In-memory push mode source filter
//
// Portions created by Microsoft are
// Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
{
@abstract(In-memory push mode source filter Delphi conversion)
@author(Andriy Nevhasymyy: a.n@email.com)
@created(Jun 28, 2003)
@lastmod(Aug 04, 2003)
}
unit UPushSource;
interface
uses
BaseClass, DirectShow9, DSUtil,
Windows, ActiveX, SysUtils;
const
//
// GUID definitions for PushSource filter set
//
CLSID_PushSourceBitmap: TGUID = '{E446D455-7C13-492A-9C96-38F948687E8A}';
CLSID_PushSourceBitmapSet: TGUID = '{D5070569-3C5F-4988-A77C-4DF44E850C43}';
CLSID_PushSourceDesktop: TGUID = '{570757C1-D2D8-42D1-BA0C-24E1BED3F62F}';
// Setup information
sudPinTypes: TRegPinTypes =
(
// video stream connection
clsMajorType: @MEDIATYPE_Video;
// all available
clsMinorType: @MEDIASUBTYPE_NULL
);
// pins info
sudOutputPinBitmap: array[0..0] of TRegFilterPins =
(
(
strName: 'Output'; // Pins string name
bRendered: FALSE; // Is it rendered
bOutput: TRUE; // Is it an output
bZero: FALSE; // Are we allowed none
bMany: FALSE; // And allowed many
oFilter: nil; // Connects to filter
strConnectsToPin: nil; // Connects to pin
nMediaTypes: 1; // Number of types
lpMediaType: @sudPinTypes // Pin information
)
);
sudOutputPinBitmapSet: array[0..0] of TRegFilterPins =
(
(
strName: 'Output'; // Pins string name
bRendered: FALSE; // Is it rendered
bOutput: TRUE; // Is it an output
bZero: FALSE; // Are we allowed none
bMany: FALSE; // And allowed many
oFilter: nil; // Connects to filter
strConnectsToPin: nil; // Connects to pin
nMediaTypes: 1; // Number of types
lpMediaType: @sudPinTypes // Pin information
)
);
sudOutputPinDesktop: array[0..0] of TRegFilterPins =
(
(
strName: 'Output'; // Pins string name
bRendered: FALSE; // Is it rendered
bOutput: TRUE; // Is it an output
bZero: FALSE; // Are we allowed none
bMany: FALSE; // And allowed many
oFilter: nil; // Connects to filter
strConnectsToPin: nil; // Connects to pin
nMediaTypes: 1; // Number of types
lpMediaType: @sudPinTypes // Pin information
)
);
UNITS = 10000000;
FPS_30 = UNITS div 30;
FPS_20 = UNITS div 20;
FPS_10 = UNITS div 10;
FPS_5 = UNITS div 5;
FPS_4 = UNITS div 4;
FPS_3 = UNITS div 3;
FPS_2 = UNITS div 2;
FPS_1 = UNITS div 1;
DefaultFrameLength: TReferenceTime = FPS_10;
// Filter name strings
PushBitmapName: WideString = '_ PushSource Bitmap Filter';
PushBitmapSetName: WideString = '_ PushSource BitmapSet Filter';
PushDesktopName: WideString = '_ PushSource Desktop Filter';
// default bitmap file name
BITMAP_NAME: string = 'sample.bmp';
// Number of bitmap files to load in the CPushPinBitmapSet class
Num_Files = 5;
type
(**********************************************
*
* Class declarations
*
**********************************************)
TBCPushPinBitmap = class(TBCSourceStream)
protected
// To track where we are in the file
FFramesWritten: Integer;
// Do we need to clear the buffer?
FZeroMemory: Boolean;
// The time stamp for each sample
FSampleTime: TRefTime;
// Pointer to the bitmap header
FBmi: PBitmapInfo;
// Size of the bitmap header
FBitmapInfo: DWord;
// File opening variables
// Handle returned from CreateFile
FFileHandle: THandle;
// Points to beginning of file buffer
FFileBuffer: PByte;
// Points to pixel bits
FImage: PByte;
// How many frames have been displayed
FFrameNumber: Integer;
// Duration of one frame
FFrameLength: TReferenceTime;
// Protects our internal state
FSharedState: TBCCritSec;
public
constructor Create(out hr: HResult; Filter: TBCSource);
destructor Destroy; override;
// Override the version that offers exactly one media type
function GetMediaType(MediaType: PAMMediaType): HResult; override;
function DecideBufferSize(Allocator: IMemAllocator;
Properties: PAllocatorProperties): HRESULT; override;
function FillBuffer(Sample: IMediaSample): HResult; override;
// Quality control
// Not implemented because we aren't going in real time.
// If the file-writing filter slows the graph down, we just do nothing, which means
// wait until we're unblocked. No frames are ever dropped.
// Quality control notifications sent to us
function Notify(Filter: IBaseFilter; q: TQuality): HRESULT; override;
stdcall;
end;
TBCPushPinBitmapSet = class(TBCSourceStream)
protected
// To track where we are in the file
FFramesWritten: Integer;
// Do we need to clear the buffer?
FZeroMemory: Boolean;
// The time stamp for each sample
FSampleTime: TRefTime;
// Array of bitmap headers pointers
FBmi: array[0..Num_Files - 1] of PBitmapInfo;
// Sizes of the bitmap headers
FBitmapInfo: array[0..Num_Files - 1] of DWord;
// File opening variables
// Handles returned from CreateFile
FFileHandle: array[0..Num_Files - 1] of THandle;
// Points to beginning of files buffer
FFileBuffer: array[0..Num_Files - 1] of PByte;
// Points to pixel bits
FImage: array[0..Num_Files - 1] of PByte;
// number of files loaded
FFilesLoaded: Boolean;
// Which bitmap is being displayed
FCurrentBitmap,
// How many frames have been displayed
FFrameNumber: Integer;
// Duration of one frame
FFrameLength: TReferenceTime;
// Protects our internal state
FSharedState: TBCCritSec;
public
constructor Create(out hr: HResult; Filter: TBCSource);
destructor Destroy; override;
// Override the version that offers exactly one media type
function GetMediaType(MediaType: PAMMediaType): HResult; override;
function DecideBufferSize(Allocator: IMemAllocator;
Properties: PAllocatorProperties): HRESULT; override;
function FillBuffer(Sample: IMediaSample): HResult; override;
// Quality control
// Not implemented because we aren't going in real time.
// If the file-writing filter slows the graph down, we just do nothing, which means
// wait until we're unblocked. No frames are ever dropped.
// Quality control notifications sent to us
function Notify(Filter: IBaseFilter; q: TQuality): HRESULT; override;
stdcall;
end;
TBCPushPinDesktop = class(TBCSourceStream)
protected
// To track where we are in the file
FFramesWritten: Integer;
// Do we need to clear the buffer?
FZeroMemory: Boolean;
// The time stamp for each sample
FSampleTime: TRefTime;
// How many frames have been displayed
FFrameNumber: Integer;
// Duration of one frame
FFrameLength: TReferenceTime;
// Rect containing entire screen coordinates
FScreenRect: TRect;
// The current image height
FImageHeight,
// And current image width
FImageWidth,
// Time in msec between frames
FRepeatTime,
// Screen bit depth
FCurrentBitDepth: Integer;
FMediaType: TAMMediaType;
// Protects our internal state
FSharedState: TBCCritSec;
public
constructor Create(out hr: HResult; Filter: TBCSource);
destructor Destroy; override;
// Override the version that offers exactly one media type
function GetMediaType(iPosition: Integer;
out MediaType: PAMMediaType): HResult; override;
// We will accept 8, 16, 24 or 32 bit video formats, in any
// image size that gives room to bounce.
// Returns E_INVALIDARG if the mediatype is not acceptable
function CheckMediaType(MediaType: PAMMediaType): HResult; override;
function DecideBufferSize(Allocator: IMemAllocator;
Properties: PAllocatorProperties): HRESULT; override;
function SetMediaType(MediaType: PAMMediaType): HRESULT; override;
function FillBuffer(Sample: IMediaSample): HResult; override;
// Quality control
// Not implemented because we aren't going in real time.
// If the file-writing filter slows the graph down, we just do nothing, which means
// wait until we're unblocked. No frames are ever dropped.
// Quality control notifications sent to us
function Notify(Filter: IBaseFilter; q: TQuality): HRESULT; override;
stdcall;
end;
// In-memory push mode source filter
// Provides a static bitmap as the video output stream.
TBCPushSourceBitmap = class(TBCSource)
private
FPin: TBCPushPinBitmap;
public
constructor Create(ObjName: string; Unk: IUnKnown; out hr: HRESULT);
constructor CreateFromFactory(Factory: TBCClassFactory;
const Controller: IUnknown); override;
destructor Destroy; override;
end;
// In-memory push mode source filter
// Provides a rotating set of bitmaps as the video output stream.
TBCPushSourceBitmapset = class(TBCSource)
private
FPin: TBCPushPinBitmapSet;
public
constructor Create(ObjName: string; Unk: IUnKnown; out hr: HRESULT);
constructor CreateFromFactory(Factory: TBCClassFactory;
const Controller: IUnknown); override;
destructor Destroy; override;
end;
// In-memory push mode source filter
// Provides an image of the user's desktop as a continuously updating stream.
TBCPushSourceDesktop = class(TBCSource)
private
FPin: TBCPushPinDesktop;
public
constructor Create(ObjName: string; Unk: IUnKnown; out hr: HRESULT);
constructor CreateFromFactory(Factory: TBCClassFactory;
const Controller: IUnknown); override;
destructor Destroy; override;
end;
implementation
// --- TBCPushPinBitmap ---------------
constructor TBCPushPinBitmap.Create(out hr: HResult; Filter: TBCSource);
var
CurrentDir: array[0..MAX_PATH - 1] of Char;
CurrentFileName, MediaFileName: AnsiString;
MsgText: AnsiString;
FileSize, BytesRead: DWord;
FileHeaderSize: Integer;
BmpFileHeader: PBITMAPFILEHEADER;
pb: PByte;
begin
inherited Create('_ Push Source Bitmap', hr, Filter, 'Out');
FFramesWritten := 0;
FZeroMemory := False;
FBmi := nil;
FBitmapInfo := 0;
FFileHandle := INVALID_HANDLE_VALUE;
FFileBuffer := nil;
FImage := nil;
FFrameNumber := 0;
// Display 5 bitmap frames per second
FFrameLength := FPS_5;
FSharedState := TBCCritSec.Create;
// The main point of this sample is to demonstrate how to take a DIB
// in host memory and insert it into a video stream.
// To keep this sample as simple as possible, we just read a single 24 bpp bitmap
// from a file and copy it into every frame that we send downstream.
// In the filter graph, we connect this filter to the AVI Mux, which creates
// the AVI file with the video frames we pass to it. In this case,
// the end result is a still image rendered as a video stream.
// Your filter will hopefully do something more interesting here.
// The main point is to set up a buffer containing the DIB pixel bits.
// This must be done before you start running.
// First look for the bitmap in the current directory
GetCurrentDirectory(MAX_PATH - 1, CurrentDir);
CurrentFileName := Format('%s\%s', [CurrentDir, Bitmap_Name]);
FFileHandle := CreateFile(PChar(CurrentFileName), GENERIC_READ, 0, nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (FFileHandle = INVALID_HANDLE_VALUE) then
begin
// File was not in the application's current directory,
// so look in the DirectX SDK media path instead.
MediaFileName := Format('%s\%s'#0, [GetDXSDKMediaPath, Bitmap_Name]);
FFileHandle := CreateFile(PChar(MediaFileName), GENERIC_READ, 0, nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (FFileHandle = INVALID_HANDLE_VALUE) then
begin
MsgText := Format('Could not open bitmap source file ' +
'in the application directory:'#13#10 + '%s'#13#10 +
'or in the DirectX SDK Media folder:'#13#10 + '%s'#13#10 +
'Please copy this file either to the application''s folder'#13#10 +
'or to the DirectX SDK Media folder, then recreate this filter'#13#10 +
'Otherwise, you will not be able to render the output pin',
[CurrentFileName, MediaFileName]);
OutputDebugString(PChar(MsgText));
MessageBox(0, PChar(MsgText), 'PushSource filter error',
MB_ICONERROR or MB_OK);
hr := HRESULTFROMWIN32(GetLastError);
Exit;
end;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -