Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2717953
  • 博文数量: 416
  • 博客积分: 10220
  • 博客等级: 上将
  • 技术积分: 4193
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-15 09:47
文章分类

全部博文(416)

文章存档

2022年(1)

2021年(1)

2020年(1)

2019年(5)

2018年(7)

2017年(6)

2016年(7)

2015年(11)

2014年(1)

2012年(5)

2011年(7)

2010年(35)

2009年(64)

2008年(48)

2007年(177)

2006年(40)

我的朋友

分类: WINDOWS

2007-02-02 14:40:30

1显示VFW驱动的视频设备对话框
如果视频捕捉设备采用的仍然是VFW方式的驱动程序,则必须支持下面三个对话框,用来设置视频设备。
1 Video Source
用来选择视频输入设备并且调整设备的设置,比如亮度和对比度。
2Video Format
用来设置桢的大小和位
3Video Display
用来设置视频的显示参数
为了显示上面的三个对话框,你可以do the following
1停止graph。
2向捕捉filter请求IAMVfwCaptureDialogs接口,如果成功,表明设备支持VFW驱动。
3调用IAMVfwCaptureDialogs::HasDialog来检查驱动程序是否支持你请求的对话框,如果支持,返回S_OK,否则返回S_FALSE。注意不要用SUCCEDED宏。
4如果驱动支持该对话框,调用IAMVfwCaptureDialogs::ShowDialog显示该对话框。
5 重新运行graph
代码如下
 pControl->Stop(); // Stop the graph.
 // Query the capture filter for the IAMVfwCaptureDialogs interface.  IAMVfwCaptureDialogs *pVfw = 0;
 hr = pCap->QueryInterface(IID_IAMVfwCaptureDialogs, (void**)&pVfw);  if (SUCCEEDED(hr))
 {
  // Check if the device supports this dialog box.
  if (S_OK == pVfw->HasDialog(VfwCaptureDialog_Source))
  {
  // Show the dialog box.
  hr = pVfw->ShowDialog(VfwCaptureDialog_Source, hwndParent);
  }
  }
  pControl->Run();
2 调整视频的质量
WDM驱动的设备支持一些属性可以用来调整视频的质量,比如亮度,对比度,饱和度,等要向调整视频的质量,do the following
1 从捕捉filter上请求IAMVideoProcAmp接口
2 对于你想调整的任何一个属性,调用IAMVideoProcAmp::GetRange可以返回这个属性赋值的范围,缺省值,最小的增量值。IAMVideoProcAmp::Get返回当前正在使用的值。VideoProcAmpProperty枚举每个属性定义的标志。
3调用IAMVideoProcAmp::Set来设置这个属性值。设置属性的时候,不用停止graph。
看看下面的代码是如何调整视频的质量的
HWND hTrackbar; // Handle to the trackbar control.
// Initialize hTrackbar (not shown).
// Query the capture filter for the IAMVideoProcAmp interface.
  IAMVideoProcAmp *pProcAmp = 0;
  hr = pCap->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
  if (FAILED(hr))
  {
  // The device does not support IAMVideoProcAmp, so disable the control.
  EnableWindow(hTrackbar, FALSE);
  }
  Else
  {
  long Min, Max, Step, Default, Flags, Val;
  // Get the range and default value.
  hr = m_pProcAmp->GetRange(VideoProcAmp_Brightness, &Min, &Max, &Step,
  &Default, &Flags);
  if (SUCCEEDED(hr))
  {
  // Get the current value.
  hr = m_pProcAmp->Get(VideoProcAmp_Brightness, &Val, &Flags);
  }
  if (SUCCEEDED(hr))
  {
  // Set the trackbar range and position.
  SendMessage(hTrackbar, TBM_SETRANGE, TRUE, MAKELONG(Min, Max));
  SendMessage(hTrackbar, TBM_SETPOS, TRUE, Val);
  EnableWindow(hTrackbar, TRUE);
  }
  Else
  {
  // This property is not supported, so disable the control.
  EnableWindow(hTrackbar, FALSE);
  }
  }
3调整视频输出格式
我们知道视频流可以有多种输出格式,一个设备可以支持16-bit RGB, 32-bit RGB, and YUYV,在每一种格式下,设备还可以调整视频桢的大小。
在WDM驱动设备上,IAMStreamConfig 接口用来报告设备输出视频的格式的,VFW设备,可以采用对话框的方式来设置,参见前面的内容。
捕捉Filter的捕捉pin和预览pin都支持IAMStreamConfig 接口,可以通过ICaptureGraphBuilder2::FindInterface获得IAMStreamConfig接口。
 IAMStreamConfig *pConfig = NULL;
  hr = pBuild->FindInterface(
  &PIN_CATEGORY_PREVIEW, // Preview pin.
  0, // Any media type.
  pCap, // Pointer to the capture filter.
  IID_IAMStreamConfig, (void**)&pConfig);
设备还支持一系列的媒体类型,对于每一个媒体类型,设备都要支持一系列的属性,比如,桢的大小,图像如何缩放,桢率的范围等。
通过IAMStreamConfig::GetNumberOfCapabilities获得设备所支持的媒体类型的数量。这个方法返回两个值,一个是媒体类型的数量,二是属性所需结构的大小。
这个结构的大小很重要,因为这个方法是用于视频和音频的,视频采用的是VIDEO_STREAM_CONFIG_CAPS结构,音频用AUDIO_STREAM_CONFIG_CAPS结构。
通过函数IAMStreamConfig::GetStreamCaps来枚举媒体类型,要给这个函数传递一个序号作为参数,这个函数返回媒体类型和相应的属性结构体。看代码把
 int iCount = 0, iSize = 0;
 hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// Check the size to make sure we pass in the correct structure.
  if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)
  {
  // Use the video capabilities structure.
  for (int iFormat = 0; iFormat < iCount; iFormat++)
  {
  VIDEO_STREAM_CONFIG_CAPS scc;
  AM_MEDIA_TYPE *pmtConfig;
  hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
  if (SUCCEEDED(hr))
  {
  /* Examine the format, and possibly use it. */
  // Delete the media type when you are done.
  hr = pConfig->SetFormat(pmtConfig);//重新设置视频格式
  DeleteMediaType(pmtConfig);
  }
  }
你可以调用IAMStreamConfig::SetFormat设置新的媒体类型
hr = pConfig->SetFormat(pmtConfig);
如果pin没有连接,当连接的时候就试图用新的格式,如果pin已经在连接了,它就会用的新的媒体格式重新连接。在任何一种情况下,下游的filter都有可能拒绝新的媒体格式。
在SetFormat前你可以修改VIDEO_STREAM_CONFIG_CAPS结构来重新设置媒体类型。
例如:
如果GetStreamCaps返回的是24-bit RGB format,桢的大小是320 x 240 像素,你可以通过检查媒体类型的major type,subtpye,和format等值
 if ((pmtConfig.majortype == MEDIATYPE_Video) &&
  (pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
  (pmtConfig.formattype == FORMAT_VideoInfo) &&
  (pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
  (pmtConfig.pbFormat != NULL))
  {
  VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
  // pVih contains the detailed format information.
  LONG lWidth = pVih->bmiHeader.biWidth;
  LONG lHeight = pVih->bmiHeader.biHeight;
  }
VIDEO_STREAM_CONFIG_CAPS结构里包含了该媒体类型的视频长度和宽度的最大值和最小值,还有递增的幅度值,就是每次调整视频size的幅度,例如,设备可能返回如下的值
MinOutputSize: 160 x 120
MaxOutputSize: 320 x 240
OutputGranularityX: 8 pixels (horizontal step size)
OutputGranularityY: 8 pixels (vertical step size)
这样你可以在(160, 168, 176, ... 304, 312, 320) 范围内设置宽度,在 (120, 128, 136, ... 104, 112, 120).设置高度值,

图6
如果想设置新的值,直接修改在GetStreamCaps函数中返回的值即可,
 pVih->bmiHeader.biWidth = 160;
  pVih->bmiHeader.biHeight = 120;
  pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
然后将媒体类型传递给SetFormat函数,就可修改视频格式了。
 
阅读(3766) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~