USB摄像头拍照按钮会产生什么样的消息事件,通过DirectShow如何捕获?

eagleywy 2013-07-17 05:05:21
摄像头为普通免驱动USB摄像头,上面有个拍照按钮。

想请教大家 按下这个按钮时在windows里面产生了什么样的消息?如何用DirectShow或其他方式捕获这个消息?
...全文
335 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
范特西 2013-08-23
  • 打赏
  • 举报
回复
hr = m_pCapGraphBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,m_pBaseFilter,NULL, NULL); 之后要 //将m_pBaseFilter、pSG_Filter、pNull关联 hr = m_pCapGraphBuilder2->RenderStream(&PIN_CATEGORY_STILL,&MEDIATYPE_Video,m_pBaseFilter,m_pTSG_Filter,m_pNull); if(FAILED(hr)) hr = m_pCapGraphBuilder2->RenderStream(&PIN_CATEGORY_STILL,&MEDIATYPE_Video,m_pBaseFilter,m_pTSG_Filter,m_pNull); if(FAILED(hr)) { errorMsg = __LMSG(L"Error! Could not render capture video stream!"); goto errorEnd; }
范特西 2013-08-23
  • 打赏
  • 举报
回复
hr = m_pMediaControl->Run();//开始视频捕捉 if(FAILED(hr)) { errorMsg = __LMSG(L"Error! Failed to run the graph!"); goto errorEnd; } //必须在Run之后 hr = m_pBaseFilter->QueryInterface(IID_IAMVideoControl, (void**)&m_pAMVideoControl); if (SUCCEEDED(hr)) { IPin *pPin = NULL; hr = m_pCapGraphBuilder2->FindPin(m_pBaseFilter,PINDIR_OUTPUT,&PIN_CATEGORY_STILL,0,false,0,&pPin); if (SUCCEEDED(hr)) { hr = m_pAMVideoControl->SetMode(pPin,VideoControlFlag_Trigger); pPin->Release(); pPin = NULL; } else { errorMsg = __LMSG(L"Error! Failed to find pin of still!"); goto errorEnd; } } else { errorMsg = __LMSG(L"Error! Failed to get video control interfaces!"); goto errorEnd; } m_pTSG->SetOneShot(TRUE); m_pTSG->SetBufferSamples(TRUE); m_pTSG->SetCallback(FStillCB,1);//0->SampleCB; 1->BufferCB m_pTSG->GetConnectedMediaType(&g_StillMediaType);
范特西 2013-08-23
  • 打赏
  • 举报
回复
楼主问题解决没?我实现你楼上的方式,不过有点问题,我的摄像头有两个快门,只有一个有效。此外,发现这种方式不通用,我之前拿国外的一个摄像头就不行,不知道为什么。这应该是标准的USB接口才对,AMCap和MyCam都能很好的兼容大多数这种摄像头。不知道他们怎么实现的,楼主有解决么,有消息的话烦请发个消息给我,万分感激。最近看Windows SDK看的要吐了,WIA有什么snapshot,还有Take_Picture之类的回调消息,没找到系统的怎么调用的例子,好晕哦!
eagleywy 2013-08-15
  • 打赏
  • 举报
回复
Capturing an Image From a Still Image Pin Some cameras can produce a still image separate from the capture stream, and often the still image is of higher quality than the images produced by the capture stream. The camera may have a button that acts as a hardware trigger, or it may support software triggering. A camera that supports still images will expose a still image pin, which is pin category PIN_CATEGORY_STILL. The recommended way to get still images from the device is to use the Windows Image Acquisition (WIA) APIs. For more information, see "Windows Image Acquisition" in the Platform SDK documentation. However, you can also use DirectShow to capture an image. To trigger the still pin, use the IAMVideoControl::SetMode method when the graph is running, as follows: pControl->Run(); // Run the graph. IAMVideoControl *pAMVidControl = NULL; hr = pCap->QueryInterface(IID_IAMVideoControl, (void**)&pAMVidControl); if (SUCCEEDED(hr)) { // Find the still pin. IPin *pPin = 0; hr = pBuild->FindPin(pCap, PINDIR_OUTPUT, &PIN_CATEGORY_STILL, 0, FALSE, 0, &pPin); if (SUCCEEDED(hr)) { hr = pAMVidControl->SetMode(pPin, VideoControlFlag_Trigger); pPin->Release(); } pAMVidControl->Release(); } Query the capture filter for IAMVideoControl. If the interface is supported, get a pointer to the still pin's IPin interface by calling the ICaptureGraphBuilder2::FindPin method, as shown in the previous example. Then call put_Mode with the IPin pointer and the VideoControlFlag_Trigger flag. Note Depending on the camera, you might need to render the capture pin (PIN_CATEGORY_CAPTURE) before the still pin will connect. Example: Using the Sample Grabber Filter One way to capture the image is with the Sample Grabber filter. The Sample Grabber uses an application-defined callback function to process the image. For more information about the Sample Grabber filter, see Using the Sample Grabber. The following example assumes that the still pin delivers an uncompressed RGB image. First, define a class that will implement the Sample Grabber's callback interface, ISampleGrabberCB: // Class to hold the callback function for the Sample Grabber filter. class SampleGrabberCallback : public ISampleGrabberCB { // Implementation is described later. } // Global instance of the class. SampleGrabberCallback g_StillCapCB; The implementation of the class is described shortly. Next, connect the still pin to the Sample Grabber, and connect the Sample Grabber to the Null Renderer filter. The Null Renderer simply discards media samples that it receives; the actual work will be done within the callback. (The only reason for the Null Renderer is to connect the Sample Grabber's output pin to something.) Call CoCreateInstance to create the Sample Grabber and Null Renderer filters, and call AddFilter to add both filters to the graph: // Add the Sample Grabber filter to the graph. IBaseFilter *pSG_Filter; hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSG_Filter); hr = pGraph->AddFilter(pSG_Filter, L"SampleGrab"); // Add the Null Renderer filter to the graph. IBaseFilter *pNull; hr = CoCreateInstance(CLSID_NullRendere, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNull); hr = pGraph->AddFilter(pSG_Filter, L"NullRender"); You can use the RenderStream method to connect all three filters in one method call, going from the still pin to the Sample Grabber, and from the Sample Grabber to the Null Renderer: hr = pBuild->RenderStream( &PIN_CATEGORY_STILL, // Connect this pin ... &MEDIATYPE_Video, // with this media type ... pCap, // on this filter ... pSG_Filter, // to the Sample Grabber ... pNull); // ... and finally to the Null Renderer. Now use the ISampleGrabber interface to configure the Sample Grabber so that it buffers samples: // Configure the Sample Grabber. ISampleGrabber *pSG; hr = pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG); pSG->SetOneShot(FALSE); pSG->SetBufferSamples(TRUE); Set the callback interface with a pointer to your callback object: pSG->SetCallback(&g_StillCapCB, 0); // 0 = Use the SampleCB callback method. Get the media type that the still pin used to connect with the Sample Grabber: // Store the media type for later use. AM_MEDIA_TYPE g_StillMediaType; hr = pSG->GetConnectedMediaType(&g_StillMediaType); pSG->Release(); This media type will contain the BITMAPINFOHEADER structure that defines the format of the still image. Free the media type before the application exits: // On exit, remember to release the media type. FreeMediaType(g_StillMediaType); What follows is an example of the callback class. Note that the class implements IUnknown, which it inherits through the ISampleGrabber interface, but it does not keep a reference count. This is safe because the application creates the object on the stack, and the object remains in scope throughout the lifetime of the filter graph. All of the work happens in the BufferCB method, which is called by the Sample Grabber whenever it gets a new sample. In the following example, the method writes the bitmap to a file: class SampleGrabberCallback : public ISampleGrabberCB { public: // Fake referance counting. STDMETHODIMP_(ULONG) AddRef() { return 1; } STDMETHODIMP_(ULONG) Release() { return 2; } STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) { if (NULL == ppvObject) return E_POINTER; if (riid == __uuidof(IUnknown)) { *ppvObject = static_cast<IUnknown*>(this); return S_OK; } if (riid == __uuidof(ISampleGrabberCB)) { *ppvObject = static_cast<ISampleGrabberCB*>(this); return S_OK; } return E_NOTIMPL; } STDMETHODIMP SampleCB(double Time, IMediaSample *pSample) { return E_NOTIMPL; } STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen) { if ((g_StillMediaType.majortype != MEDIATYPE_Video) || (g_StillMediaType.formattype != FORMAT_VideoInfo) || (g_StillMediaType.cbFormat < sizeof(VIDEOINFOHEADER)) || (g_StillMediaType.pbFormat == NULL)) { return VFW_E_INVALIDMEDIATYPE; } HANDLE hf = CreateFile("C:\\Example.bmp", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); if (hf == INVALID_HANDLE_VALUE) { return E_FAIL; } long cbBitmapInfoSize = g_StillMediaType.cbFormat - SIZE_PREHEADER; VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)g_StillMediaType.pbFormat; BITMAPFILEHEADER bfh; ZeroMemory(&bfh, sizeof(bfh)); bfh.bfType = 'MB'; // Little-endian for "MB". bfh.bfSize = sizeof( bfh ) + BufferLen + cbBitmapInfoSize; bfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + cbBitmapInfoSize; // Write the file header. DWORD dwWritten = 0; WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL ); WriteFile(hf, HEADER(pVideoHeader), cbBitmapInfoSize, &dwWritten, NULL); WriteFile( hf, pBuffer, BufferLen, &dwWritten, NULL ); CloseHandle( hf ); return S_OK; } }; 注意: Depending on the camera, you might need to render the capture pin (PIN_CATEGORY_CAPTURE) before the still pin will connect. 本人之前因为一直没有 按 PIN_CATEGORY_CAPTURE 把链表中的滤波器链接起来,所以一直失败
eagleywy 2013-07-18
  • 打赏
  • 举报
回复
用DirectShow显示视频没问题。 不知你是否注意到,一些 USB 摄像头上有一个拍摄按钮。在XP系统下,用系统自带的工具打开浏览视频后,当你按下 USB 摄像头上的拍摄按钮 就会采集一张图像。想知道DirectShow是怎样捕捉这个按钮消息的。
rightorwrong 2013-07-17
  • 打赏
  • 举报
回复
就是创建directshow对象,连接filter,显示图像 捕获这个消息是什么意思

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧