⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vidinput_directx.cxx

📁 opal的ptlib c++源程序 可以从官方网站上下载
💻 CXX
📖 第 1 页 / 共 3 页
字号:
 *
 * Set brightness, contrast, hue, saturation
 *
 *
 */
PBoolean PVideoInputDevice_DirectShow::SetControlCommon(long control, int newValue)
{
    IAMVideoProcAmp *pVideoProcAmp;
    long Min, Max, Stepping, Def, CapsFlags;
    HRESULT hr;

    PTRACE(1, "PVidDirectShow\tSetControl() = " << newValue);

    hr = pSrcFilter->QueryInterface(IID_IAMVideoProcAmp, (void **)&pVideoProcAmp);
    if (FAILED(hr))
    {
	PTRACE(4, "PVidDirectShow\tFailed to find VideoProcAmp interface: " << ErrorMessage(hr));
	return PFalse;
    }

    hr = pVideoProcAmp->GetRange(control, &Min, &Max, &Stepping, &Def, &CapsFlags);
    if (FAILED(hr))
    {
	PTRACE(4, "PVidDirectShow\tFailed to getRange interface on " << control << " : " << ErrorMessage(hr));
	pVideoProcAmp->Release();
	return PFalse;
    }

    if (newValue == -1)
	hr = pVideoProcAmp->Set(control, 0, VideoProcAmp_Flags_Auto);
    else
    {
	long ValScaled = Min + ((Max-Min) * newValue) / 65536;
	hr = pVideoProcAmp->Set(control, ValScaled, VideoProcAmp_Flags_Manual);
    }
    PTRACE_IF(4, FAILED(hr), "PVidDirectShow\tFailed to setRange interface on " << control << " : " << ErrorMessage(hr));

    pVideoProcAmp->Release();
    return PTrue;
}

PBoolean PVideoInputDevice_DirectShow::SetBrightness(unsigned newBrightness)
{
    if (!SetControlCommon(VideoProcAmp_Brightness, newBrightness))
	return PFalse;

    frameBrightness = newBrightness;

    return PTrue;
}

PBoolean PVideoInputDevice_DirectShow::SetColour(unsigned newColour)
{
    if (!SetControlCommon(VideoProcAmp_Saturation, newColour))
	return PFalse;

    frameColour = newColour;

    return PTrue;
}

PBoolean PVideoInputDevice_DirectShow::SetContrast(unsigned newContrast)
{
    if (!SetControlCommon(VideoProcAmp_Contrast, newContrast))
	return PFalse;

    frameContrast = newContrast;

    return PTrue;
}

PBoolean PVideoInputDevice_DirectShow::SetHue(unsigned newHue)
{
    if (!SetControlCommon(VideoProcAmp_Hue, newHue))
	return PFalse;

    frameHue = newHue;

    return PTrue;
}

PBoolean PVideoInputDevice_DirectShow::SetWhiteness(unsigned newWhiteness)
{
    if (!SetControlCommon(VideoProcAmp_Gamma, newWhiteness))
	return PFalse;

    frameWhiteness = newWhiteness;

    return PTrue;
}


PBoolean PVideoInputDevice_DirectShow::GetDeviceCapabilities(const PString & /*deviceName*/, Capabilities * /*caps*/)  
{ 
    // To do!
    return FALSE; 
}

/*
 *
 *
 */
PBoolean PVideoInputDevice_DirectShow::ListSupportedFormats()
{
    HRESULT hr;
    IAMStreamConfig *pStreamConfig;
    AM_MEDIA_TYPE *pMediaFormat;
    int iCount, iSize;
    VIDEO_STREAM_CONFIG_CAPS scc;
    int i;

    PTRACE(1, "PVidDirectShow\tListSupportedFormats()");

    hr = pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
	    			 pSrcFilter, IID_IAMStreamConfig, (void **)&pStreamConfig);
    if (FAILED(hr))
    {
	PTRACE(4, "PVidDirectShow\tFailed to find StreamConfig Video interface: " << ErrorMessage(hr));
	return PFalse;
    }

    hr = pStreamConfig->GetNumberOfCapabilities(&iCount, &iSize);
    if (FAILED(hr))
    {
	PTRACE(1, "PVidDirectShow\tFailed to GetNumberOfCapabilities: " << ErrorMessage(hr));
	pStreamConfig->Release();
	return PFalse;
    }

    /* Sanity check: just to be sure that the Streamcaps is a VIDEOSTREAM and not AUDIOSTREAM */
    if (sizeof(scc) != iSize)
    {
	PTRACE(1, "PVidDirectShow\tBad Capapabilities (not a  VIDEO_STREAM_CONFIG_CAPS)");
	pStreamConfig->Release();
	return PFalse;
    }

    for (i=0; i<iCount; i++)
    {
	pMediaFormat = NULL;
	hr = pStreamConfig->GetStreamCaps(i, &pMediaFormat, (BYTE *)&scc);
	if (FAILED(hr))
	{
	    PTRACE(1, "PVidDirectShow\tFailed to GetStreamCaps(" << i <<"): " << ErrorMessage(hr));
	    continue;
	}

#if PTRACING
	if ((pMediaFormat->formattype == FORMAT_VideoInfo)     &&
            (pMediaFormat->cbFormat >= sizeof(VIDEOINFOHEADER)) &&
	    (pMediaFormat->pbFormat != NULL))
	{
	    VIDEOINFOHEADER *VideoInfo = (VIDEOINFOHEADER *)pMediaFormat->pbFormat;
	    BITMAPINFOHEADER *BitmapInfo = &(VideoInfo->bmiHeader);

	    PTRACE(1,"PVidDirectShow\tFmt["<< i << "] = ("
		    << media_format_to_pwlib_format(pMediaFormat->subtype) << ", "
		    << BitmapInfo->biWidth << "x" << BitmapInfo->biHeight << ", "
		    << (10000000.0/VideoInfo->AvgTimePerFrame) << "fps)");
	}
#endif

	MyDeleteMediaType(pMediaFormat);
    }

    pStreamConfig->Release();

    return PTrue;
}

/*
 *
 *
 */
PBoolean PVideoInputDevice_DirectShow::GetDefaultFormat()
{
    HRESULT hr;
    IAMStreamConfig *pStreamConfig;
    AM_MEDIA_TYPE *pMediaFormat;

    PTRACE(4, "PVidDirectShow\tGetDefaultFormat()");

    hr = pCapture->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
	    			 pSrcFilter, IID_IAMStreamConfig, (void **)&pStreamConfig);

    if (FAILED(hr))
    {
	PTRACE(4, "PVidDirectShow\tFailed to find StreamConfig Video interface: " << ErrorMessage(hr));
	return PFalse;
    }

    hr = pStreamConfig->GetFormat(&pMediaFormat);
    if (FAILED(hr))
    {
	PTRACE(1, "PVidDirectShow\tFailed to getFormat: " << ErrorMessage(hr));
	pStreamConfig->Release();
	return PFalse;
    }

    if ((pMediaFormat->formattype == FORMAT_VideoInfo)     &&
        (pMediaFormat->cbFormat >= sizeof(VIDEOINFOHEADER)) &&
	(pMediaFormat->pbFormat != NULL))
    {
	VIDEOINFOHEADER *VideoInfo = (VIDEOINFOHEADER *)pMediaFormat->pbFormat;
	BITMAPINFOHEADER *BitmapInfo = &(VideoInfo->bmiHeader);
	PString format = media_format_to_pwlib_format(pMediaFormat->subtype);
	int fps = (int)(10000000.0/VideoInfo->AvgTimePerFrame);

	PTRACE(1,"PVidDirectShow\tDefault format is: "
		<< format << ", "
		<< BitmapInfo->biWidth << "x" << BitmapInfo->biHeight << ", "
		<< fps << "fps)");

	colourFormat = format;
	frameWidth = BitmapInfo->biWidth;
	frameHeight = BitmapInfo->biHeight;
	frameRate = fps;

    }

    MyDeleteMediaType(pMediaFormat);
    pStreamConfig->Release();

	return TRUE;
}


#ifndef _WIN32_WCE
/*
 *
 *
 *
 */
static char *BSTR_to_ANSI(BSTR pSrc)
{
    unsigned int cb, cwch;
    char *szOut = NULL;

    if(!pSrc)
	return NULL;

    cwch = SysStringLen(pSrc);

    /* Count the number of character needed to allocate */
    cb = WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, NULL, 0, 0, 0);
    if (cb == 0)
	return NULL;

    szOut = (char *)calloc(cb+1, 1);
    if (szOut == NULL)
	return NULL;

    cb = WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, szOut, cb, 0, 0);
    if (cb == 0)
    {
	free(szOut);
	return NULL;
    }

    return szOut;
}
#endif


static HRESULT SetDevice(const PString & devName, IBaseFilter ** ppSrcFilter)
{
#ifndef _WIN32_WCE

	HRESULT hr;
    IBaseFilter *pSrc = NULL;
    IMoniker *pMoniker = NULL;
    ICreateDevEnum *pDevEnum = NULL;
    IEnumMoniker *pClassEnum = NULL;
    ULONG cFetched;

    PTRACE(4,"PVidDirectShow\tSetDevice(" << devName << ")");

    // Create the system device enumerator

    hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           IID_ICreateDevEnum, (void **) &pDevEnum);
    if (FAILED(hr))
    {
        PTRACE(1, "PVidDirectShow\tCouldn't create system enumerator: " << ErrorMessage(hr));
        return hr;
    }

    // Create an enumerator for the video capture devices

    hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
    if (FAILED(hr))
    {
        PTRACE(1, "PVidDirectShow\tCouldn't create class enumerator: " << ErrorMessage(hr));
        return hr;
    }

    if (pClassEnum == NULL)
    {
        PTRACE(1, "PVidDirectShow\tSetDevice() No video capture device was detected");
        return hr;
    }

    pClassEnum->Reset();

    *ppSrcFilter = NULL;
    while (*ppSrcFilter == NULL)
    {
	// Get the next device
	hr = pClassEnum->Next(1, &pMoniker, &cFetched);
	if (hr != S_OK)
	{
	    PTRACE(4, "PVidDirectShow\tSetDevice() No more video capture device");
	    hr = ERROR_DEVICE_NOT_CONNECTED;
	    break;
	}

	// Get the property bag
	IPropertyBag *pPropBag;

	hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
	if (FAILED(hr))
	{
	    pMoniker->Release();
	    continue;
	}

	// Find the description or friendly name.
	VARIANT DeviceName;
	DeviceName.vt = VT_BSTR;

	hr = pPropBag->Read(L"Description", &DeviceName, 0);
	if (FAILED(hr))
	    hr = pPropBag->Read(L"FriendlyName", &DeviceName, 0);
	if (SUCCEEDED(hr))
	{
	    char *pDeviceName = BSTR_to_ANSI(DeviceName.bstrVal);
	    PTRACE(4, "PVidDirectShow\tSetDevice() current capture device '"<< pDeviceName << "'");

	    if (pDeviceName && PString(pDeviceName) == devName)
	    {
		// Bind Moniker to a filter object
		hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc);
		if (FAILED(hr))
		{
		    PTRACE(1, "PVidDirectShow\tSetDevice() Couldn't bind moniker to filter object: " << ErrorMessage(hr));
		    break;
		}
		PTRACE(4, "PVidDirectShow\tSetDevice() This one is kept '"<< pDeviceName << "'");
		*ppSrcFilter = pSrc;
	    }
	    if (pDeviceName)
		free(pDeviceName);
	}

	pPropBag->Release();
	pMoniker->Release();
	// Next Device
    }
    /* If no device was found ppSrcFilter is NULL */

    SAFE_RELEASE(pDevEnum);
    SAFE_RELEASE(pClassEnum);

    return hr;
#else
	return S_OK;
#endif // !_WIN32_WCE
}


static struct {
    const char * pwlib_format;
    GUID         media_format;
} const formats[] =
{
    { "Grey",    MEDIASUBTYPE_RGB8   },
    { "BGR32",   MEDIASUBTYPE_RGB32  }, /* Microsoft assumes that we are in little endian */
    { "BGR24",   MEDIASUBTYPE_RGB24  },
    { "RGB565",  MEDIASUBTYPE_RGB565 },
    { "RGB555",  MEDIASUBTYPE_RGB555 },
#ifndef _WIN32_WCE
	{ "YUV420P", MEDIASUBTYPE_IYUV   },  
    { "YUV422P", MEDIASUBTYPE_YUYV   },
#endif
    { "YUV411",  MEDIASUBTYPE_Y411   },
    { "YUV411P", MEDIASUBTYPE_Y41P   },
    { "YUV410P", MEDIASUBTYPE_YVU9   },
    { "YUY2",    MEDIASUBTYPE_YUY2   },
    { "MJPEG",   MEDIASUBTYPE_MJPG   },
    { "UYVY422", MEDIASUBTYPE_UYVY   },
};

static GUID pwlib_format_to_media_format(const char *format)
{
    unsigned int i;

    for (i=0; i<sizeof(formats)/sizeof(formats[0]); i++)
    {
	if (strcmp(formats[i].pwlib_format, format) == 0)
	    return formats[i].media_format;
    }
    return MEDIATYPE_NULL;
}

static PString media_format_to_pwlib_format(const GUID guid)
{
    unsigned int i;

    for (i=0; i<sizeof(formats)/sizeof(formats[0]); i++)
    {
	if (guid == formats[i].media_format)
	    return formats[i].pwlib_format;
    }

#ifndef _WIN32_WCE
	if (guid == MEDIASUBTYPE_CLPL)
	return "CLPL";
    if (guid == MEDIASUBTYPE_YUYV)
	return "YUYV";
    if (guid == MEDIASUBTYPE_IYUV)
	return "IYUV";
#endif
    if (guid == MEDIASUBTYPE_YVU9)
	return "YVU9";
    if (guid == MEDIASUBTYPE_Y411)
	return "Y411";
    if (guid == MEDIASUBTYPE_Y41P)
	return "Y41P";
    if (guid == MEDIASUBTYPE_YUY2)
	return "YUY2";
    if (guid == MEDIASUBTYPE_YVYU)
	return "YVYU";
    if (guid == MEDIASUBTYPE_UYVY)
	return "UYVY";
    if (guid == MEDIASUBTYPE_Y211)
	return "Y211";
    if (guid == MEDIASUBTYPE_YV12)
	return "YV12";
    if (guid == MEDIASUBTYPE_CLJR)
	return "CLJR";
    if (guid == MEDIASUBTYPE_IF09)
	return "IF09";
    if (guid == MEDIASUBTYPE_CPLA)
	return "CPLA";
    if (guid == MEDIASUBTYPE_MJPG)
	return "MJPG";
    if (guid == MEDIASUBTYPE_TVMJ)
	return "TVMJ";
    if (guid == MEDIASUBTYPE_WAKE)
	return "WAKE";
    if (guid == MEDIASUBTYPE_CFCC)
	return "CFCC";
    if (guid == MEDIASUBTYPE_IJPG)
	return "IJPG";
    if (guid == MEDIASUBTYPE_Plum)
	return "Plum";
    if (guid == MEDIASUBTYPE_DVCS)
	return "DVCS";
    if (guid == MEDIASUBTYPE_DVSD)
	return "DVSD";
    if (guid == MEDIASUBTYPE_MDVF)
	return "MDVF";
    if (guid == MEDIASUBTYPE_RGB1)
	return "RGB1";
    if (guid == MEDIASUBTYPE_RGB4)
	return "RGB4";
    if (guid == MEDIASUBTYPE_RGB8)
	return "RGB8";
    if (guid == MEDIASUBTYPE_RGB565)
	return "RGB565";
    if (guid == MEDIASUBTYPE_RGB555)
	return "RGB555";
    if (guid == MEDIASUBTYPE_RGB24)
	return "BGR24";
    if (guid == MEDIASUBTYPE_RGB32)
	return "BGR32";
#ifndef _WIN32_WCE
    if (guid == MEDIASUBTYPE_IYUV)
	return "I420";
#endif

    wchar_t guid_wchar[256];
    char guid_string[256];
    int guid_wcharlen;

    guid_wcharlen = StringFromGUID2(guid, guid_wchar, sizeof(guid_wchar));
    WideCharToMultiByte(CP_ACP, 0,
	                guid_wchar, guid_wcharlen+1,
			guid_string, sizeof(guid_string),
			0, 0);

    return guid_string;
}

#endif /*P_DIRECTSHOW*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -