媒体基础 - 如何从交叉栏中选择输入
Media Foundation - How to select input from crossbar?
晚上好
我正在尝试使用Media Foundation将一个小的视频捕获DLL放在一起,该DLL在很大程度上改编自SimpleCapture和CaptureEngine SDK示例。当我的捕获源是我的内置网络摄像头时,整个事情都很好用。
问题是当我尝试使用具有多个输入(s-video,复合和立体声音频)的外部USB图像采集卡时,没有预览流。我有一个使用 DShow 接口的功能,它似乎可以成功更改横杆上的选定输入(通过运行函数后查看 AMCAP 中的选项进行验证)但是我根本无法预览设备。
是否有从交叉栏选择输入的媒体基础方法?或者如果没有,您能否建议下面的交叉条输入选择代码可能存在什么问题:
HRESULT CaptureManager::doSelectInputUsingCrossbar(std::wstring deviceName, long input)
{
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter* pSrc = NULL;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pClassEnum = NULL;
IMoniker *pMoniker = NULL;
bool bCameraFound = false;
IPropertyBag *pPropBag = NULL;
bool crossbarSet = false;
HRESULT hr = S_OK;
if (!(input == PhysConn_Video_Composite || input == PhysConn_Video_SVideo))
{
return S_FALSE;
}
// Create the Filter Graph Manager.
hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
if (SUCCEEDED(hr))
{
// Create the Capture Graph Builder.
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void **)&pBuilder);
if (SUCCEEDED(hr))
{
pBuilder->SetFiltergraph(pGraph);
}
else return hr;
}
else return hr;
//////////////////////////
// chooses the default camera filter
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **)&pDevEnum);
if (FAILED(hr))
{
return E_FAIL;
}
// Create an enumerator for video capture devices.
if (FAILED(pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0)))
{
return E_FAIL;
}
if (pClassEnum == NULL)
{
CheckHR(hr, "Class enumerator is null - no input devices detected?");
pDevEnum->Release();
return E_FAIL;
}
while (!bCameraFound && (pClassEnum->Next(1, &pMoniker, NULL) == S_OK))
{
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
if (FAILED(hr))
{
pMoniker->Release();
continue; // Skip this one, maybe the next one will work.
}
// Find the description or friendly name.
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"Description", &varName, 0);
if (FAILED(hr))
{
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
}
if (SUCCEEDED(hr))
{
if (0 == wcscmp(varName.bstrVal, deviceName.c_str()))
{
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc);
bCameraFound = true;
break;
}//if
VariantClear(&varName);
}
pPropBag->Release();
pMoniker->Release();
}//while
pClassEnum->Release();
pDevEnum->Release();
if (!bCameraFound)//else
{
CheckHR(hr, "Error: Get device Moniker, No device found");
goto done;
}
hr = pGraph->AddFilter(pSrc, L"video capture adapter");
if (FAILED(hr))
{
CheckHR(hr, "Can't add capture device to graph");
goto done;
}
///////////////
IAMCrossbar *pxBar = NULL;
hr = pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, pSrc, IID_IAMCrossbar, (void **)&pxBar);
if (FAILED(hr))
{
hr = pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSrc, IID_IAMCrossbar, (void **)&pxBar);
if (FAILED(hr))
{
CheckHR(hr, "Failed to get crossbar filter");
goto done;
}
}//if
else
{
CheckHR(hr, "Failed to get crossbar (capture)");
goto done;
}
LONG lInpin, lOutpin;
hr = pxBar->get_PinCounts(&lOutpin, &lInpin);
BOOL IPin = TRUE; LONG pIndex = 0, pRIndex = 0, pType = 0;
while (pIndex < lInpin)
{
hr = pxBar->get_CrossbarPinInfo(IPin, pIndex, &pRIndex, &pType);
if (pType == input)
{
break;
}
pIndex++;
}
BOOL OPin = FALSE; LONG pOIndex = 0, pORIndex = 0, pOType = 0;
while (pOIndex < lOutpin)
{
hr = pxBar->get_CrossbarPinInfo(OPin, pOIndex, &pORIndex, &pOType);
if (pOType == PhysConn_Video_VideoDecoder)
{
break;
}
pIndex++;
}
hr = pxBar->Route(pOIndex, pIndex);
done:
SafeRelease(&pPropBag);
SafeRelease(&pMoniker);
SafeRelease(&pxBar);
SafeRelease(&pGraph);
SafeRelease(&pBuilder);
SafeRelease(&pSrc);
return hr;
}
Microsoft媒体基金会不支持USB图像采集卡。Microsoft媒体基金会支持通过USB视频类设备驱动程序进行实时源。现代网络摄像头支持此类驱动程序,但USB图像采集卡不支持。DirectShow 过滤器的 USB 图像采集卡支持 DirectShow 过滤器 - 源将媒体样本发送到媒体图中,而媒体基础使用 PULL 模型处理管道Microsoft接收器发送新媒体样本的请求,源"侦听"此类请求。
用最好的。
相关文章:
- 如何选择waveIn/waveOut函数C++使用的输入/输出设备
- 根据C++中的外部输入选择类
- 如何允许用户在进行错误选择时再次输入
- 菜单选择器不接受有效输入
- 从类中查看 rand() 并将用户输入与计算机选择进行比较.石头,纸,剪刀游戏
- 根据输入类型选择正确的结构方法
- 有什么方法可以让用户选择要输入哪个变量
- PRNG程序故障.无法输入随机数量的选择,并且将始终从PRNG中回答2
- C ,基于价值输入从2D数组中选择
- 基于用户输入(选择向上,向下,左或右)中的3x3数组中的元素
- 如何仅从输入文件中"20071406"的数字中选择"2007"的数字并将其存储在变量中?
- 输入验证用于选择用字符的项目,通过CIN.FAIL遇到错误
- 在 C++ 中,我无法选择用于用户输入的特定变量
- 有没有选择排序优于冒泡排序的输入
- C++具有无限可选参数和不同输入变量选择的函数
- 媒体基础 - 如何从交叉栏中选择输入
- 如何强制用户在从菜单中选择之前输入一些数字
- 如何提示用户输入数字,直到他们选择奇数?C++
- 使用 V4L2 API 选择输入通道
- 如果发现两个数字相等,人们会如何选择输入的第一个数字?