set resolution with direct show


void VC::SetResolution(IBaseFilter* pSrcFilter, int Width, int Height) {
	IAMStreamConfig *pConfig = NULL;
	g_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,
		&MEDIATYPE_Video, pSrcFilter, IID_IAMStreamConfig, (void**)&pConfig);

	int resolutions, size;
	VIDEO_STREAM_CONFIG_CAPS caps;
	pConfig->GetNumberOfCapabilities(&resolutions, &size);

	for (int i = 0; i < resolutions; i++)
	{
		AM_MEDIA_TYPE *mediaType;
		if (pConfig->GetStreamCaps(i, &mediaType, reinterpret_cast(&caps)) == S_OK)
		{
			int maxWidth = caps.MaxOutputSize.cx;
			int maxHeigth = caps.MaxOutputSize.cy;

			if (maxWidth == Width && maxHeigth == Height)
			{
				VIDEOINFOHEADER *info = reinterpret_cast(mediaType->pbFormat);

				info->bmiHeader.biWidth = maxWidth;
				info->bmiHeader.biHeight = maxHeigth;
				info->bmiHeader.biSizeImage = DIBSIZE(info->bmiHeader);
				HRESULT hr = pConfig->SetFormat(mediaType);
				MyDeleteMediaType(mediaType);
				break;
			}

			MyDeleteMediaType(mediaType);
		}
	}
	SAFE_RELEASE(pConfig);
}

void VC::MyDeleteMediaType(AM_MEDIA_TYPE *pmt)
{
	if (pmt != NULL)
	{
		// See FreeMediaType for the implementation.
		MyFreeMediaType(*pmt);
        CoTaskMemFree(pmt);
    }
}

void VC::MyFreeMediaType(AM_MEDIA_TYPE& mt)
{
	if (mt.cbFormat != 0)
    {
        CoTaskMemFree((PVOID)mt.pbFormat);
        mt.cbFormat = 0;
        mt.pbFormat = NULL;
    }

    if (mt.pUnk != NULL)
    {

        // Unecessary because pUnk should not be used, but safest.
        mt.pUnk->Release();
        mt.pUnk = NULL;
    }
}

To implement it -

int VC::Begin(HWND hWnd, HWND prvWindow, IBaseFilter* pSrcFilter)
{
	HRESULT hr;

	// Get DirectShow interfaces
    hr = GetInterfaces(hWnd);
    if (FAILED(hr)) {
		return -1;
    }

	// Attach the filter graph to the capture graph
    hr = g_pCapture->SetFiltergraph(g_pGraph);
    if (FAILED(hr)) {
		return -2;
    }

	/*

	hr = FindCaptureDevice(&pSrcFilter);
    if (FAILED(hr)) {
		// Don't display a message because FindCaptureDevice will handle it
		return hr;
    }
	*/

	SetResolution(pSrcFilter, 1280, 720);

	// Add Capture filter to our graph.
    hr = g_pGraph->AddFilter(pSrcFilter, L"Video Capture");
    if(FAILED(hr)) {
		pSrcFilter->Release();
        return -4;
    }

	SetResolution(pSrcFilter, 1280, 720);

	hr = sgAddSampleGrabber(g_pGraph);
    if (FAILED(hr)) {
		return -5;
    }

	hr = sgSetSampleGrabberMediaType();
    /*
	AM_MEDIA_TYPE mt;
		IAMStreamConfig *pSC=NULL; 
		//HRESULT hr;
        ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
		
		hr = g_pCapture->FindInterface(&PIN_CATEGORY_PREVIEW, 0 , 
			pSrcFilter, IID_IAMStreamConfig,(void **)&pSC); 

		if(FAILED(hr)) {
			AfxMessageBox(L"FAIL");
			return hr;
		}

        mt.majortype = MEDIATYPE_Video;
        mt.subtype = MEDIASUBTYPE_RGB24;
		//VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER *)mt.pbFormat;
        //gChannels = pVih->bmiHeader.biBitCount / 8;
        pVih->bmiHeader.biWidth = 1280;
        pVih->bmiHeader.biHeight = 720;

         mt.pbFormat = (unsigned char *) pVih;
		 pSC->SetFormat(&mt); 

        hr = pGrabber->SetMediaType(&mt);
        if (FAILED(hr)) {
                return hr;
        }
        hr = pGrabber->SetOneShot(FALSE);
        hr = pGrabber->SetBufferSamples(TRUE);
	*/
	//
	if (FAILED(hr)) {
		return -6;
    }

	//IBaseFilter* pGrabber2 = sgGetSampleGrabber();

	// Render the preview pin on the video capture filter
    // Use this instead of g_pGraph->RenderFile
	hr = g_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pSrcFilter, pGrabberFilter/*NULL*/, NULL);
	if (FAILED(hr)) {
		pSrcFilter->Release();
        return -7;
    }

	hr = sgGetSampleGrabberMediaType();

	// Now that the filter has been added to the graph and we have
    // rendered its stream, we can release this reference to the filter.
    pSrcFilter->Release();

	// Set video window style and position
    hr = SetupVideoWindow(prvWindow);
    if (FAILED(hr)) {
             
		return -8;
    }

	return 0;
}




你可能感兴趣的:(set resolution with direct show)