Meu ambiente de desenvolvimento: Feiling 6410 desenvolvimento bordo, sistema operacional WINCE6.0, OV9650 câmera, programação DirectShow, Feiling câmera programa de teste Camera_App
Depois Feiling de OK6410 placa de desenvolvimento vem com o programa de teste de câmera a ser modificada, quando as imagens tiradas de depuração encontrou pouca resolução de 320 x 240, considero a possibilidade de alterar este valor. A Internet para encontrar um monte, tinha uma mensagem ( http://www.devdiv.com/thread-8755-1-1.html ) Há tantas palavras:
Em geral, filtro de captura de vídeo irá fornecer pino captura, visualização pin, Still fixar um pino de saída, etc., você pode selecionar um pino de saída para capturar imagens, mas a maioria optar por pino captura ou ainda pin (dependendo de seus suportes do dispositivo) .
Este pino de saída pode enumerar suportado por IAMStreamConfig :: GetNumberOfCapabilities, tampões método IAMStreamConfig :: GetStreamCaps (estrutura: VIDEO_STREAM_CONFIG_CAPS).
Esta declaração ilustra me deu alguma inspiração, considero em primeiro lugar escrever o código para ver o que os dispositivos suportam as tampas, e então determinar como modificar.
métodos de interface Um, IAMStreamConfig:
IAMStreamConfig Há quatro maneiras, você pode verificar específica MSDN sob, embora capaz de ler, mas eu ainda não sei como traduzir. Eu só posso falar sobre o meu entendimento.
① GetStreamCaps função para recuperar a capacidade formato de índice especificado, os três parâmetros:
O primeiro parâmetro é o índice especificado iIndex, que varia em tamanho a partir daGetNumberOfCapabilities primeiro argumento de iCount GET.
O segundo parâmetro é AM_MEDIA_TYPE ** tipo PMT, AM_MEDIA_TYPE uma estrutura. At The pmt o parâmetro recebe uma Cheio-in Estrutura AM_MEDIA_TYPE, Qual suportados Descreve o formato de saída. Vale ressaltar que AM_MEDIA_TYPE em si não é novo para passar, e há uma função especial: CreateMediaType, que é chamado dentro GetStreamCaps, portanto, a liberação de memória correspondente não é uma simples chamada para apagar, mas DeleteMediaType chamada .
O terceiro parâmetro é o BYTE PSCC * Tipo, de O CAPS estrutura de parâmetro A Recebe o formato que o contém informação adicional.
Para vídeo, CAPS recebe um VIDEO_STREAM_CONFIG_CAPSestrutura. Para o áudio, ele recebe uma estrutura AUDIO_STREAM_CONFIG_CAPS.
CAPS uma nova memória alocada, que tem um tamanho GetNumberOfCapabilities uma função do segundo parâmetro iSize adquirido.
Em MSDN tem a dizer dignos de nota:
O método aloca a memória para o AM_MEDIA_TYPE estrutura que é devolvido na PMT parâmetro. O chamador deve liberar a memória, incluindo o bloco formato. Você pode usar oFunção auxiliar DeleteMediaType na biblioteca de classes base. O chamador deve alocar a memória para o CAPS parâmetro.
② SetFormat usado para definir o formato adequado, os parâmetros para a AM_MEDIA_TYPE * PMT, tem a dizer sobre MSDN e, portanto, deve tentar chamar definições da função SetFormat antes RenderStream .
Este método especifica o formato para o pino de saída. Se o pino não estiver conectado, ele vai usar esse formato para a sua próxima conexão. Se o pino já estiver conectado, ele tentará se reconectar com este formato.
③ alguns exemplos da MSDN, eu acredito que pode explicar um monte de perguntas que podem ajudar 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;
Em segundo lugar, como obter IAMStreamConfig interface
Como obter o filtro em interfaces de IAMStreamConfig (ou seja, as rotinas acima pConfig) é um intrigante problema, busca na Internet, alguns posts, um monte de gente, porque eles não podem obter a interface correto e altere a resolução da câmera não pode ser alcançado. Aqui para falar sobre a minha compreensão e realização.
Tem a dizer sobre MSDN:
Para usar a interface, enumerar pinos e consulta do filtro para IAMStreamConfig. Ou, se você estiver usando o Captura Graph Builder objeto para construir o gráfico de filtro, você pode chamar o método ICaptureGraphBuilder2 :: FindInterface.
Eu estava usando ICaptureGraphBuilder2 :: FindInterface para obter interface de IAMStreamConfig, esta função tem cinco parâmetros:
O primeiro parâmetro é o GUID * pCategory, uma vez que é a aquisição de uma imagem através do pino de saída, esta deve ser PIN_CATEGORY_PREVIEW ou PIN_CATEGORY_CAPTURE ou PIN_CATEGORY_STILL .
O segundo parâmetro GUID * pType. Ponteiro para uma GUID que especifica os principais meios de tipo de um pino de saída, ou NULL. pós online usando MEDIATYPE_Interleaved, mas não teve sucesso com este, em seguida, usar MEDIATYPE_Video chamada foi bem sucedida .
O terceiro Pointer parâmetro para a interface IBaseFilter do filtro . O método começa a procurar a partir deste filtro. Nota: este parâmetro para usar o filtro de captura de vídeo IBaseFilter a interface para obter , diretamente à Internet foi definido como um IBaseFilter * PBASE o argumento, aparentemente, não pode ser chamado de sucesso. Eu usei aqui é o membro variáveis m_pVideoCaptureFilter Feiling Camera_App programa de teste, ou seja, captura de vídeo do Filtro .
O quarto parâmetro é IID_IAMStreamConfig.
O quinto parâmetro é a interface ponteiro IAMStreamConfig.
Em terceiro lugar, a função DeleteMediaType
Quando o programa diretamente a função DeleteMediaType, ocorre o seguinte erro no link:
erro LNK2019: Símbolo externo não resolvido "DeleteMediaType __cdecl void (struct _AMMediaType *)" (DeleteMediaType @@ YAXPAU_AMMediaType @@@ Z?) referenciado na função "public: int __cdecl CCamera :: EnumCaps (classe ATL :: CStringT <wchar_t, classe StrTraitMFC <wchar_t, classe ATL :: ChTraitsOS <wchar_t>>> &)"(? EnumCaps @ CCamera @@ QAAHAAV? $ CStringT @ _WV? $ StrTraitMFC @ _WV? $ ChTraitsOS @ _W @ ATL @@@@@ ATL @@@ Z)
A biblioteca principal não está chamando a função correta, dado um código alternativo no MSDN, o aplicativo pode substituir DeleteMediaType, use a função _DeleteMediaType definido abaixo.
// 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;
}
}
Em quarto lugar, a rotina
Aqui está parte do meu código de teste.
① enumerar os suportes de dispositivos Caps. código de função HrCheck é um I valor definido função incorporada para determinar se o retorno FALHOU, lançando assim uma excepção, pode não controlo, o atraso não é compreendido.
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;
}
Meus resultados dos testes são os seguintes:
② meu código de configuração de resolução. Ao entrar no índice, selecione a tecla Caps pode suportar enumeração fora. Claro, você também pode definir a largura e altura para continuar a sua própria, desde que o dispositivo suporta a linha.
//设置图像分辨率
//输入参数: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;
}