65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 DirectShow 进行同步预览和视频捕获

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.35/5 (28投票s)

2004年4月16日

CPOL

3分钟阅读

viewsIcon

688578

downloadIcon

20129

一种使用 DirectShow 从网络摄像头同时进行预览和帧捕获的方法。

引言

本文介绍了一种使用 DirectShow 从网络摄像头同时执行预览和抓取的方法。除了使用传统的 ISampleGrabber 接口外,此应用程序还使用 DirectShow VMR 过滤器和 IPin 接口。

背景

有很多用于捕获和预览的解决方案,但很少有将两者结合起来的。我尝试使用 ISampleGrabberIVideoWindow 接口创建一个实现此目的的应用程序。它在 Windows 2000 上运行良好,但在 XP 上表现不佳。

DirectShow "无窗口示例"(视频混合渲染器中的无窗口模式)为在预览时捕获帧提供了线索。

使用代码

我创建了一个名为 CVMR_Capture 的类。要使用此类

  • VMR_Capture.hVMR_Capture.cpp 文件插入到您的项目中。
  • 在 VC++ 项目设置中链接 strmiids.libquartz.lib
  • 在您的对话框资源中添加一个静态控件。
  • 为该静态控件添加一个成员变量。
  • 声明 CVMR_Capture 的成员变量。

提供的公共接口是

int EnumDevices(HWND hList);
HRESULT Init(int iDeviceID,HWND hWnd,int iWidth,int iHeight);
DWORD GetFrame(BYTE ** pFrame);
BOOL StopVMR();
BOOL Pause();
DWORD ImageCapture(LPCTSTR szFile);
DWORD GrabFrame();
  • int EnumDevices(HWND hList);(可选)

    枚举连接到计算机的可用设备。 HWND 是显示连接设备的组合框的句柄。

  • HRESULT Init(int iDeviceID,HWND hWnd,int iWidth,int iHeight);

    初始化。 iDeviceID 是选定的设备索引(来自组合框),hWnd 是显示窗口的句柄,iWidthiHeight 是预期的分辨率(例如:320/240)。显示将自身调整为窗口的大小。

  • DWORD GrabFrame();

  • DWORD GetFrame(BYTE ** pFrame);

    调用这些函数以获取捕获的缓冲区。 GrabFrame(); 将抓取图像。将其存储在缓冲区中,返回值是缓冲区的大小。用户可以通过调用 GetFrame(BYTE ** pFrame) 来获取缓冲区指针,该指针返回缓冲区的大小。

    不要删除 "pFrame" 缓冲区值,它将由类析构函数删除。使用指针(pFrame)用于处理或将内存复制到用户分配的缓冲区。

  • BOOL StopVMR();

    停止预览。

  • BOOL Pause();

    暂停捕获。再次调用此方法以重新开始捕获。

  • DWORD ImageCapture(LPCTSTR szFile);

    捕获并将原始图像字节 (RGB) 写入提供的文件。

特殊函数和说明

bool BindFilter(int deviceId, IBaseFilter **pFilter);
HRESULT InitializeWindowlessVMR(HWND hWnd);
HRESULT InitVideoWindow(HWND hWnd,int width, int height);
void StopCapture();
void CloseInterfaces(void);
void DeleteMediaType(AM_MEDIA_TYPE *pmt);
bool Convert24Image(BYTE *p32Img,BYTE *p24Img,DWORD dwSize32);
  • bool BindFilter(int deviceId, IBaseFilter **pFilter);

    将过滤器绑定到给定的设备 ID。

  • HRESULT InitializeWindowlessVMR(HWND hWnd);

    将 VMR 初始化为提供的 HWND

  • HRESULT InitVideoWindow(HWND hWnd,int width, int height);

    根据显示窗口的大小调整显示视频大小。

  • void StopCapture();

    停止捕获。

  • void CloseInterfaces(void);

    释放并删除接口/分配的内存。

  • void DeleteMediaType(AM_MEDIA_TYPE *pmt);

    删除媒体类型对象。

  • bool Convert24Image(BYTE *p32Img,BYTE *p24Img,DWORD dwSize32);

    使用 VMR 捕获的图像是 32 位 RGB。此函数将 32 位 RGB 转换为 24 位 RGB。

关注点

此类在 Windows 2000 和 Windows XP 上使用 DirectX9.0 进行了测试。支持 VMR7 和 VMR9。我没有在此示例中包含 DirectShow 事件处理部分。使用时请附加所需的异常/错误处理机制。

请给我发送电子邮件,告诉我任何错误或改进该类的建议。您的建议和指导将最有价值。

© . All rights reserved.