dshow,Sample Grabber 从摄像头采集

char* CCameraDS::QueryFrame()

{

	long evCode, size = 0;

	





#if CALLBACKMODE

	static double lastSampleTime=0;

	if( lastSampleTime == cbInfo.dblSampleTime)

		return NULL;

	if(cbInfo.lBufferSize == 0)

		return NULL;

	if ( m_nBufferSize != cbInfo.lBufferSize)

	{

		if (m_pFrame)

		{

			free(m_pFrame);

		}

		m_nBufferSize = cbInfo.lBufferSize;

		m_pFrame = (char*)malloc(m_nBufferSize);//cvCreateImage(cvSize(m_nWidth, m_nHeight), IPL_DEPTH_8U, 3);

	}

	lastSampleTime = cbInfo.dblSampleTime;

	m_pFrame2 = (char*)cbInfo.pBuffer;

#else

	m_pMediaControl->Run();

	m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);

	m_pSampleGrabber->GetCurrentBuffer(&size, NULL);

	if(size == 0)

		return NULL;

	//if the buffer size changed

	if (size != m_nBufferSize)

	{

		if (m_pFrame)

		{

			free(m_pFrame);

		}

		if (m_pFrame2)

		{

			free(m_pFrame2);

		}

		m_nBufferSize = size;

		m_pFrame = (char*)malloc(m_nWidth*m_nHeight*3);//cvCreateImage(cvSize(m_nWidth, m_nHeight), IPL_DEPTH_8U, 3);

		m_pFrame2 = (char*)malloc(m_nWidth*m_nHeight*3);

	}

	

	m_pSampleGrabber->GetCurrentBuffer(&m_nBufferSize, (long*)m_pFrame2);

	//cvFlip(m_pFrame);

#endif

	for(int i=0;i<m_nHeight;i++)

		memcpy(m_pFrame+m_nWidth*3*i,m_pFrame2+m_nWidth*3*(m_nHeight-1-i),m_nWidth*3);



	return m_pFrame;

}

1.缓冲区模式

 

#if !CALLBACKMODE
m_pSampleGrabber->SetBufferSamples(TRUE);
m_pSampleGrabber->SetOneShot(TRUE);
#endif

只能设置SetOneShot为TRUE, 因为使用SetPositions 函数始终返回 E_NOTIMPL:Method is not supported.如果为false,

WaitForCompletion(INFINITE, &evCode)函数会一直等待下去。

2.回调模式

回调模式每采到一直就会进入回调函数,可以在回调函数里面处理采到的数据。

#if CALLBACKMODE
m_pSampleGrabber->SetBufferSamples(FALSE);
m_pSampleGrabber->SetOneShot(FALSE);
// Set the callback, so we can grab the one sample
//
CB.Width = m_nWidth;
CB.Height = m_nHeight;
hr = m_pSampleGrabber->SetCallback( &CB, 1 );
m_pMediaControl->Run();
#endif

只用Run()一次即可。如果SetOneShot(TRUE)的话,也可以每请求一帧Run()一次,然后WaitForCompletion,再从回调函数的buffer中取出数据,这种其实和缓冲区模式一样,只不过缓冲区变成了在回调函数中。

如果摄像头采集帧率为30,SetOneShot(FALSE)回调模式,就一秒进去回调函数30次。而OneShot模式会取到重复的帧。

 

你可能感兴趣的:(sample)