#include "idirectshowapi.h"
#include <QDebug>
IDirectShowApi::IDirectShowApi()
{
}
bool IDirectShowApi::dxCameraParameter(const int& index, CameraParameterData ¶meter)
{
HRESULT hr = S_OK;
std::vector<POINT> vecPix;
ICaptureGraphBuilder2* _pCapture = NULL;
IBaseFilter* _pBF;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **)&_pCapture);
if (FAILED(hr)){
qDebug() << "directshow CoCreateInstance error:" << hr;
_pCapture->Release();
return false;
}
if (!BindFilter(index, &_pBF))
{
qDebug() << "directshow BindFilter error";
_pCapture->Release();
return false;
}
//获取参数
IAMVideoProcAmp* _pProcAmp;
hr = _pBF->QueryInterface(IID_IAMVideoProcAmp, (void**)&_pProcAmp);
if(SUCCEEDED(hr))
{
long Min, Max, Step, Default, Flags, Val;
// 亮度
hr = _pProcAmp->GetRange(VideoProcAmp_Brightness, &Min, &Max, &Step, &Default, &Flags);
if(SUCCEEDED(hr))
{
hr = _pProcAmp->Get(VideoProcAmp_Brightness, &Val, &Flags);
if(FAILED(hr))
qDebug() << "Get Brightness Cur value error.";
parameter.brightness.min = (int)Min;
parameter.brightness.max = (int)Max;
parameter.brightness.def = (int)Default;
parameter.brightness.cur = (int)Val;
qDebug() << "Brightness--->" << "Min:" << Min << "Max:" << Max << "Default:"<< Default << "Cur:" << Val;
}else qDebug() << "Get Brightness Parameter Error.";
// 对比度
hr = _pProcAmp->GetRange(VideoProcAmp_Contrast, &Min, &Max, &Step, &Default, &Flags);
if(SUCCEEDED(hr))
{
hr = _pProcAmp->Get(VideoProcAmp_Contrast, &Val, &Flags);
if(FAILED(hr))
qDebug() << "Get Contrast Cur value error.";
parameter.contrast.min = (int)Min;
parameter.contrast.max = (int)Max;
parameter.contrast.def = (int)Default;
parameter.contrast.cur = (int)Val;
qDebug() << "Contrast--->" << "Min:" << Min << "Max:" << Max << "Default:"<< Default << "Cur:" << Val;
}else qDebug() << "Get Contrast Parameter Error.";
// 饱和度
hr = _pProcAmp->GetRange(VideoProcAmp_Saturation, &Min, &Max, &Step, &Default, &Flags);
if(SUCCEEDED(hr))
{
hr = _pProcAmp->Get(VideoProcAmp_Saturation, &Val, &Flags);
if(FAILED(hr))
qDebug() << "Get Saturation Cur value error.";
parameter.saturation.min = (int)Min;
parameter.saturation.max = (int)Max;
parameter.saturation.def = (int)Default;
parameter.saturation.cur = (int)Val;
qDebug() << "Saturation--->" << "Min:" << Min << "Max:" << Max << "Default:"<< Default << "Cur:" << Val;
}else qDebug() << "Get Saturation Parameter Error.";
}
_pProcAmp->Release();
_pCapture->Release();
_pBF->Release();
return true;
}
bool IDirectShowApi::dxCameraSupportResolution(const int &index, QList<QSizeF> &resolutions)
{
HRESULT hr = S_OK;
std::vector<POINT> vecPix;
ICaptureGraphBuilder2* _pCapture = NULL;
IBaseFilter* _pBF;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **)&_pCapture);
if (FAILED(hr)){
qDebug() << "directshow CoCreateInstance error:" << hr;
return false;
}
if (!BindFilter(index, &_pBF))
{
qDebug() << "directshow BindFilter error";
_pCapture->Release();
return false;
}
IEnumPins * pinEnum = NULL;
IPin * pin = NULL;
if (FAILED(_pBF->EnumPins(&pinEnum)))
{
pinEnum->Release();
return false;
}
pinEnum->Reset();
ULONG pinFetched = 0;
while (SUCCEEDED(pinEnum->Next(1, &pin, &pinFetched)) && pinFetched)
{
if (!pin)
{
continue;
}
PIN_INFO pinInfo;
if (FAILED(pin->QueryPinInfo(&pinInfo)))
{
continue;
}
if (pinInfo.dir != PINDIR_OUTPUT)
{
continue;
}
IEnumMediaTypes *mtEnum = NULL;
AM_MEDIA_TYPE *mt = NULL;
if (FAILED(pin->EnumMediaTypes(&mtEnum)))
{
break;
}
mtEnum->Reset();
ULONG mtFetched = 0;
while (SUCCEEDED(mtEnum->Next(1, &mt, &mtFetched)) && mtFetched)
{
BITMAPINFOHEADER* bmi = NULL;
int avgTime;
if (mt->formattype == FORMAT_VideoInfo)
{
if (mt->cbFormat >= sizeof(VIDEOINFOHEADER))
{
VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(mt->pbFormat);
bmi = &(pVih->bmiHeader);
avgTime = pVih->AvgTimePerFrame;
}
}
//else if (mt->formattype == FORMAT_VideoInfo2)
//{
// if (mt->cbFormat >= sizeof(VIDEOINFOHEADER2))
// {
// VIDEOINFOHEADER2* pVih = reinterpret_cast<VIDEOINFOHEADER2*>(mt->pbFormat);
// bmi = &(pVih->bmiHeader);
// avgTime = pVih->AvgTimePerFrame;
// }
//}
if (bmi)
{
int echo = false;
for (int i = 0; i < resolutions.size(); i++)
{
if (resolutions[i].width() == bmi->biWidth && resolutions[i].height() == bmi->biHeight)
{
echo = true;
break;
}
}
if (!echo)
{
resolutions.append(QSizeF(bmi->biWidth,bmi->biHeight));
qDebug() << "Resolution:" << bmi->biWidth << "x" << bmi->biHeight;
}
}
}
pin->Release();
}
_pCapture->Release();
_pBF->Release();
// 拍序
for (int j=0; j < resolutions.count()-1; j++)
{
for (int i=0 ;i < resolutions.count()-j-1; i++){
if ( resolutions.at(i).width() > resolutions.at(i+1).width())
{
QSizeF t = resolutions[i];
resolutions[i] = resolutions[i + 1];
resolutions[i + 1] = t;
}
}
}
return true;
}
bool IDirectShowApi::dxCameraDevices(QStringList &cameras)
{
char sName[256] = { 0 };
QString cameraname = "";
// enumerate all video capture devices
ICreateDevEnum* pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)
{
return false;
}
IEnumMoniker* pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
if (hr != NOERROR)
{
return false;
}
pEm->Reset(); // Go to the start of the enumerated list
ULONG cFetched;
IMoniker *pM;
int index =0;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
IPropertyBag *pBag;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (hr == NOERROR)
{
WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sName, 256, "", NULL);
cameraname = QString::fromLocal8Bit(sName);
cameras.append(cameraname);