熟悉DShow接口的朋友请进
请熟悉DShow接口的朋友帮我看看下面的代码,其问题是图像有马赛克,而且在窗口关闭时出读地址错。
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DSUtil, StdCtrls, DSPack, DirectShow9, Menus, ExtCtrls, ComCtrls,
ExtDlgs, ActiveX;
type
TVideoForm = class(TForm)
MainMenu1: TMainMenu;
Devices: TMenuItem;
SavePictureDialog1: TSavePictureDialog;
Bitmap1: TMenuItem;
Setup1: TMenuItem;
Bitmap2: TMenuItem;
Callback1: TMenuItem;
VideoSize1: TMenuItem;
N320X2401: TMenuItem;
N640X4801: TMenuItem;
N720X5761: TMenuItem;
Debug1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure N720X5761Click(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
public
end;
var
VideoForm: TVideoForm;
//DirectShow 接口定义
GraphBuilder : IGraphBuilder;
CaptureGraphBuilder : ICaptureGraphBuilder2;
MediaControl : IMediaControl;
MediaSeeking : IMediaSeeking;
MediaPosition : IMediaPosition;
MediaEventEx : IMediaEventEx;
BasicAudio : IBasicAudio;
BasicVideo : IBasicVideo;
VideoWindow : IVideoWindow;
SampleGrabber : ISampleGrabber;
VideoFrameStep : IVideoFrameStep;
CreateDevEnum : ICreateDevEnum;
EnumMoniker : IEnumMoniker;
implementation
{$R *.dfm}
procedure TVideoForm.FormCreate(Sender: TObject);
var
HR : HResult;
DebugMsg : string;
Moniker : IMoniker;
cFetched : PLongInt;
BaseFilter : IBaseFilter;
begin
Self.Width := 640;
Self.Height := 480;
Self.Left := (Screen.Width - Self.Width) div 2;
Self.Top := (Screen.Height - Self.Height) div 2;
//初始化接口...
try
HR := CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, GraphBuilder);
if not Succeeded(HR) then Exit;
DebugMsg := 'GraphBuilder Created!';
HR := CoCreateInstance(CLSID_CaptureGraphBuilder2, nil, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, CaptureGraphBuilder);
if not Succeeded(HR) then Exit;
DebugMsg := 'CaptureGraphBuilder Created!';
GraphBuilder.QueryInterface(IID_IMediaControl, MediaControl);
GraphBuilder.QueryInterface(IID_IMediaEventEx, MediaEventEx);
GraphBuilder.QueryInterface(IID_IVideoWindow, VideoWindow);
MediaEventEx.SetNotifyWindow(Self.Handle, WM_GRAPHNOTIFY, 0);
CaptureGraphBuilder.SetFiltergraph(GraphBuilder);
//设备枚举
HR := CoCreateInstance (CLSID_SystemDeviceEnum, nil, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, CreateDevEnum);
if not Succeeded(HR) then Exit;
CreateDevEnum.CreateClassEnumerator(CLSID_VideoInputDeviceCategory, EnumMoniker, 0);
if EnumMoniker = nil then Exit;
if EnumMoniker.Next(1, Moniker, cFetched) = S_OK then
begin
Moniker.BindToObject(nil, nil, IID_IBaseFilter, BaseFilter);
Moniker := nil;
end
else Exit;
//将设备添加到graph
HR := GraphBuilder.AddFilter(BaseFilter, 'Video Capture');
if not Succeeded(HR) then Exit;
//连接源...
HR := CaptureGraphBuilder.RenderStream(nil, nil, BaseFilter, nil, nil);
if not Succeeded(HR) then Exit;
//视频窗口...
HR := VideoWindow.put_Owner(Self.Handle);
if not Succeeded(HR) then Exit;
HR := VideoWindow.put_WindowStyle(WS_CHILD and WS_CLIPCHILDREN);
if not Succeeded(HR) then Exit;
VideoWindow.SetWindowPosition(0, 0, 640, 480);
VideoWindow.put_Visible(True);
//
MediaControl.Run;
finally
Self.Caption := DebugMsg;
end;
end;
procedure TVideoForm.FormDestroy(Sender: TObject);
begin
CaptureGraphBuilder := nil;
GraphBuilder := nil;
MediaControl := nil;
MediaEventEx := nil;
VideoWindow := nil;
CreateDevEnum := nil;
EnumMoniker := nil;
end;
end.