zoukankan      html  css  js  c++  java
  • 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模式会取到重复的帧。

  • 相关阅读:
    Linux学习之路:shell变量(二)环境变量
    LVS配置与安装
    Linux学习之路:shell变量(一)
    SQL Server用存储过程新建视图
    【转】SQL Server 2012 配置AlwaysOn(三)
    【转】SQL 语句:Alter table
    Linux学习之路:认识shell和bash
    【转】Centos配置yum源
    【Azure 应用服务】App Service 无法连接到Azure MySQL服务,报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
    【Azure API 管理】在APIM 中添加 logtoeventhub 策略,把 Request Body 信息全部记录在Event Hub中
  • 原文地址:https://www.cnblogs.com/mlj318/p/3782534.html
Copyright © 2011-2022 走看看