📄 vidinput_directx.cxx
字号:
*
* 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 + -