En condiciones de uso de Windows CE6.0 de interfaz IAMStreamConfig cambia la resolución de la imagen capturada

        Mi entorno de desarrollo: Feiling 6410 placa de desarrollo, el sistema operativo WinCE6.0, OV9650 cámara, la programación de DirectShow, Feiling cámara programa de pruebas Camera_App

         Después de Feiling OK6410 placa de desarrollo viene con el programa de pruebas de cámara que ser modificado, cuando las imágenes tomadas de depuración encontraron poca resolución de 320 * 240, creo que la posibilidad de cambiar este valor. Internet para encontrar un montón, tenía un mensaje ( http://www.devdiv.com/thread-8755-1-1.html ) Hay tantas palabras:

         En general, el filtro de captura de vídeo proporcionará pin de captura, el pasador de vista previa, todavía fijar un pin de salida, etc., se puede seleccionar un pin de salida para capturar imágenes, pero la mayoría optar por pin pin de captura o embargo (dependiendo de sus soportes de dispositivos) .

        Este pin de salida puede enumerar el apoyo de IAMStreamConfig :: GetNumberOfCapabilities, tapas método IAMStreamConfig :: GetStreamCaps (estructura: VIDEO_STREAM_CONFIG_CAPS).

        Esta declaración me dio ilustra un poco de inspiración, considero en primer lugar escribir el código para ver qué dispositivos son compatibles con las tapas, y luego determinar cómo modificar.

      métodos de interfaz A, IAMStreamConfig:

      IAMStreamConfig Hay cuatro maneras, se puede comprobar específica de MSDN bajo, aunque es capaz de leer, pero todavía no sé cómo traducir. Sólo puedo hablar de mi comprensión.

      ① GetStreamCaps función para recuperar la capacidad de formato de índice especificado, los tres parámetros:

      El primer parámetro es el índice especificado iIndex, que van en tamaño desde elGetNumberOfCapabilities primer argumento de iCuenta get.

      El segundo parámetro es AM_MEDIA_TYPE ** tipo pmt, AM_MEDIA_TYPE una estructura. En el PMT el parámetro Recibe Un rellenado Estructura AM_MEDIA_TYPE, que uno Apoyado describe el formato de salida. Es de destacar que AM_MEDIA_TYPE sí no es nuevo para pasar, y hay una función especial: CreateMediaType, que se llama dentro de GetStreamCaps, por lo tanto, la liberación de memoria correspondiente no es una simple llamada a eliminar, pero DeleteMediaType llamada .

      El tercer parámetro es el BYTE * Tipo de PSCC, de la PSCC Estructura de parámetros A recibe el formato que la contiene información adicional.

Para el vídeo, PSCC recibe un VIDEO_STREAM_CONFIG_CAPSestructura. Para el audio, que recibe una estructura AUDIO_STREAM_CONFIG_CAPS.

PSCC una nueva memoria asignada, que tiene un tamaño de GetNumberOfCapabilities una función del segundo parámetro iSize adquirió.

      En MSDN tiene esto que decir vale la pena destacar:

      El método asigna la memoria para la Estructura AM_MEDIA_TYPE que se devuelve en la pmt parámetro. La persona que llama debe liberar la memoria, incluyendo el formato de bloque. Se puede utilizar elDeleteMediaType función auxiliar en la biblioteca de clases base. La persona que llama debe asignar la memoria para la PSCC parámetro.

      ② SetFormat utilizado para establecer el formato adecuado, los parámetros para la AM_MEDIA_TYPE * PMT, tiene esto que decir en MSDN, y por lo tanto debe tratar de llamar a los ajustes de función SetFormat antes RenderStream .

      Este método especifica el formato para el pin de salida. Si el pasador no está conectado, se utilizará este formato para su próxima conexión. Si el pasador ya está conectado, intentará volver a conectar con este formato.

      ③ algunos ejemplos de MSDN, creo que puede explicar un montón de preguntas que pueden ayudar a entender.

int iCount, iSize;
BYTE *pSCC = NULL;
AM_MEDIA_TYPE *pmt;

hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);

pSCC = new BYTE[iSize];
if (pSCC == NULL)
{
    // TODO: Out of memory error.
}

// Get the first format.
hr = pConfig->GetStreamCaps(0, &pmt, pSCC));
if (hr == S_OK)
{
    // TODO: Examine the format. If it's not suitable for some
    // reason, call GetStreamCaps with the next index value (up
    // to iCount). Otherwise, set the format:
    hr = pConfig->SetFormat(pmt);
    if (FAILED(hr))
    {
        // TODO: Error handling.
    }
    DeleteMediaType(pmt);
}
delete [] pSCC;

      En segundo lugar, cómo llegar IAMStreamConfig Interfaz

      ¿Cómo conseguir el filtro en las interfaces IAMStreamConfig (es decir, las rutinas anteriores pConfig) es un problema desconcertante, búsqueda en Internet, algunos puestos, a mucha gente porque no pueden obtener la interfaz correcta y cambie la resolución de la cámara no se pueden alcanzar. Aquí para hablar de mi entendimiento y realización.

      Tiene esto que decir en MSDN:

    Para utilizar la interfaz, enumerar los pasadores y la consulta del filtro para IAMStreamConfig. O, si está utilizando el gráfico de captura constructor de objetos para construir el gráfico de filtro, se puede llamar al método ICaptureGraphBuilder2 :: FindInterface.

      Yo estaba usando ICaptureGraphBuilder2 :: FindInterface obtener la interfaz IAMStreamConfig, esta función tiene cinco parámetros:

      El primer parámetro es el GUID * pCategory, ya que es la adquisición de una imagen a través de la patilla de salida, esto debería ser PIN_CATEGORY_PREVIEW o PIN_CATEGORY_CAPTURE o PIN_CATEGORY_STILL .

      El segundo parámetro GUID * pType. Puntero a un GUID que especifica los principales medios de tipo de un pin de salida, o NULL. puesto en línea usando MEDIATYPE_Interleaved, pero no tener éxito con esto, a continuación, utilizar MEDIATYPE_Video llamada fue exitosa .

     El tercer parámetro puntero a la interfaz IBaseFilter del filtro . El método comienza a buscar a partir de este filtro. Nota: este parámetro para utilizar el filtro de captura de vídeo IBaseFilter la interfaz para obtener , directamente a Internet se definió como una IBaseFilter * PBASE el argumento, al parecer, no se puede llamar éxito. Que se utiliza aquí es la variables miembro m_pVideoCaptureFilter Feiling Camera_App programa de prueba, es decir, captura de vídeo del filtro .

     El cuarto parámetro es IID_IAMStreamConfig.

     El quinto parámetro es la interfaz puntero IAMStreamConfig.

     En tercer lugar, la función DeleteMediaType

     Cuando el programa directamente la función DeleteMediaType, produce el siguiente error en el acoplamiento:

 LNK2019 de error: símbolo externo sin resolver "DeleteMediaType vacío __cdecl (struct _AMMediaType *)" (DeleteMediaType @@ YAXPAU_AMMediaType @@@ Z?) Se hace referencia en la función "pública: int __cdecl ccamera :: EnumCaps (clase ATL :: CStringT <wchar_t, clase StrTraitMFC <wchar_t, clase ATL :: ChTraitsOS <wchar_t>>> y)"(? EnumCaps @ ccamera @@ QAAHAAV? CStringT $ @ _WV? StrTraitMFC $ @ _WV? ChTraitsOS $ @ _W @ ATL ATL @@@@@ @@@ Z)

     La biblioteca principal no está llamando a la función correcta, dado un código alternativo en MSDN, la aplicación puede reemplazar DeleteMediaType, la función de uso _DeleteMediaType se define a continuación.

// Delete a media type structure that was allocated on the heap.
void _DeleteMediaType(AM_MEDIA_TYPE *pmt)
{
    if (pmt != NULL)
    {
        _FreeMediaType(*pmt); 
        CoTaskMemFree(pmt);
    }
}

// Release the format block for a media type.

void _FreeMediaType(AM_MEDIA_TYPE& mt)
{
    if (mt.cbFormat != 0)
    {
        CoTaskMemFree((PVOID)mt.pbFormat);
        mt.cbFormat = 0;
        mt.pbFormat = NULL;
    }
    if (mt.pUnk != NULL)
    {
        // pUnk should not be used.
        mt.pUnk->Release();
        mt.pUnk = NULL;
    }
}

   En cuarto lugar, la rutina

     Aquí es parte de mi código de prueba.

    ① enumerar los soportes de dispositivos Caps. código de función HrCheck es un valor definido I función en línea para determinar si el retorno fallado, tirando de ese modo una excepción, puede no control, el retardo no se entiende.

BOOL CCamera::EnumCaps(CString& szOutput)
{
	CComPtr<IAMStreamConfig> pConfig;
	try
	{
		//找到IAMStreamConfig接口
		HrCheck(m_pCaptureGraphBuilder->FindInterface(&PIN_CATEGORY_STILL, &MEDIATYPE_Video,
			m_pVideoCaptureFilter,IID_IAMStreamConfig, (void**)&pConfig));

		//获取number数
		int iCnt, iSize;
		HrCheck(pConfig->GetNumberOfCapabilities(&iCnt, &iSize));

		//获取cps信息
		BYTE *pSCC = NULL;
		AM_MEDIA_TYPE *pmt;
		pSCC = new BYTE [iSize];
		if(pSCC == NULL)
			throw std::runtime_error("Allocate Memory Error");
		//遍历
		for(int i=0; i<iCnt; i++)
		{
			HrCheck(pConfig->GetStreamCaps(i, &pmt, pSCC));	//获取信息
			//形成信息字符串,用于打印显示
			CString str;
			str.Format(L"Cap index: %d \r\nMinOutputSize: %ld*%ld \r\nMaxOutputSize: %ld*%ld \r\nMinCroppingSize: %ld*%ld\r\nMaxCroppingSize: %ld*%ld\r\n",
				i, 
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MinOutputSize.cx, 
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MinOutputSize.cy,
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MaxOutputSize.cx,
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MaxOutputSize.cy,
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MinCroppingSize.cx,
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MinCroppingSize.cy,
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MaxCroppingSize.cx,
				((VIDEO_STREAM_CONFIG_CAPS*)pSCC)->MaxCroppingSize.cy);
			szOutput+=str;
			
			_DeleteMediaType(pmt);	//删除
		}

		delete [] pSCC;
	}
	catch(std::runtime_error err)
	{
		MessageBox(NULL, _T("枚举Cap信息失败!"), CString(err.what()), MB_OK);
		return FALSE;
	}
	
	return TRUE;
}

    Mis resultados de la prueba son los siguientes:

   


      ② mi código de configuración de la resolución. Al participar en el índice, seleccione las tapas pueden apoyar la enumeración a cabo. Por supuesto, también se puede ajustar la anchura y la altura para promover su propia, siempre y cuando el dispositivo es compatible con la línea.

//设置图像分辨率
//输入参数:index-0:表示320*240;1:-表示640*480
BOOL CCamera::SetCaps(int index)
{
	CComPtr<IAMStreamConfig> pConfig;
	try
	{
		//找到IAMStreamConfig接口
		HrCheck(m_pCaptureGraphBuilder->FindInterface(&PIN_CATEGORY_STILL, &MEDIATYPE_Video,
			m_pVideoCaptureFilter,IID_IAMStreamConfig, (void**)&pConfig));

		//获取number数
		int iCnt, iSize;
		HrCheck(pConfig->GetNumberOfCapabilities(&iCnt, &iSize));

		//获取cps信息
		BYTE *pSCC = NULL;
		AM_MEDIA_TYPE *pmt;
		pSCC = new BYTE [iSize];
		if(pSCC == NULL)
			throw std::runtime_error("Allocate Memory Error");

		HrCheck(pConfig->GetStreamCaps(index, &pmt, pSCC));	//获取信息
		HrCheck(pConfig->SetFormat(pmt));		//设置信息

		_DeleteMediaType(pmt);	//删除
		delete [] pSCC;
	}
	catch(std::runtime_error err)
	{
		MessageBox(NULL, _T("设置Cap失败!"), CString(err.what()), MB_OK);
		return FALSE;
	}
	
	return TRUE;
}



Publicado 37 artículos originales · ganado elogios 204 · vistas 440 000 +

Supongo que te gusta

Origin blog.csdn.net/zwgdft/article/details/7279599
Recomendado
Clasificación