ISampleGrabberCB sampleCB() не вызывается при использовании DirectShowC++

Программы на C++. Форум разработчиков
Anonymous
ISampleGrabberCB sampleCB() не вызывается при использовании DirectShow

Сообщение Anonymous »

Я пытаюсь захватить видеокадры с USB-видеоустройства (UVC) с помощью DirectShow. На самом деле сравниваю Media Foundation с DirectShow, потому что при использовании Media Foundation я вижу буферизацию около 11 миллисекунд, поэтому не получаю фактическую частоту кадров. Хочу изолировать буферизацию 11 мс от Media Foundation или низкоуровневого драйвера usbVideo.sys, поэтому использую Directshow, чтобы проверить, возникнет ли у меня такая же проблема с буферизацией 11 мс.
Чтобы измерить частоту кадров, у меня есть зарегистрировал CB с помощью ISampleGrabberCB. Но по какой-то причине ЦБ не вызывают. Я проверил наличие ошибок.
Это правильный способ получить доступ к кадровому буферу?

Код: Выделить всё

#include 
#include 
#include 
#include "qedit.h"

#pragma comment(lib, "strmiids.lib")

void EnumerateVideoDevices() {
// Initialize COM
CoInitialize(NULL);

// Create System Device Enumerator
ICreateDevEnum* pCreateDevEnum = nullptr;
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);

// Create EnumMoniker
IEnumMoniker* pEnumMoniker = nullptr;
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);

// Check if there are devices
if (pEnumMoniker != nullptr) {
IMoniker* pMoniker = nullptr;

// Display available devices
int index = 1;
while (pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK) {
IPropertyBag* pPropBag;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);

// Retrieve device name
VARIANT var;
VariantInit(&var);
pPropBag->Read(L"FriendlyName", &var, 0);
std::wcout Release();
CoUninitialize();
}

IBaseFilter* ChooseVideoDevice() {
// Prompt the user to choose a video device
std::cout > selectedIndex;

// Initialize COM
CoInitialize(NULL);

// Create System Device Enumerator
ICreateDevEnum* pCreateDevEnum = nullptr;
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);

// Create EnumMoniker
IEnumMoniker* pEnumMoniker = nullptr;
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);

// Check if there are devices
if (pEnumMoniker != nullptr) {
IMoniker* pMoniker = nullptr;

// Find the selected device
int index = 1;
while (pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK) {
if (index == selectedIndex) {
// Bind to the selected device
IBaseFilter* pVideoCaptureFilter = nullptr;
pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pVideoCaptureFilter);

// Release enumerator
pEnumMoniker->Release();
pCreateDevEnum->Release();
CoUninitialize();

return pVideoCaptureFilter;
}

pMoniker->Release();
index++;
}

// Release enumerator
pEnumMoniker->Release();
}

// Release COM objects
pCreateDevEnum->Release();
CoUninitialize();

return nullptr;
}

IPin* GetOutPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir) {
IEnumPins* pEnum;
IPin* pPin = NULL;

if (SUCCEEDED(pFilter->EnumPins(&pEnum))) {
ULONG fetched;
while (pEnum->Next(1, &pPin, &fetched) == S_OK) {
PIN_DIRECTION ThisPinDir;
if (SUCCEEDED(pPin->QueryDirection(&ThisPinDir)) && (ThisPinDir == PinDir)) {
break;
}
pPin->Release();
}
pEnum->Release();
}

return pPin;
}

IPin* GetInPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir) {
IEnumPins* pEnum;
IPin* pPin = NULL;

if (SUCCEEDED(pFilter->EnumPins(&pEnum))) {
ULONG fetched;
while (pEnum->Next(1, &pPin, &fetched) == S_OK) {
PIN_DIRECTION ThisPinDir;
if (SUCCEEDED(pPin->QueryDirection(&ThisPinDir)) && (ThisPinDir == PinDir)) {
break;
}
pPin->Release();
}
pEnum->Release();
}

return pPin;
}

class CallbackObject : public ISampleGrabberCB {
public:

CallbackObject() {};

STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
if (NULL == ppv) return E_POINTER;
if (riid == __uuidof(IUnknown)) {
*ppv = static_cast(this);
return S_OK;
}
if (riid == IID_ISampleGrabberCB) {
*ppv = static_cast(this);
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) AddRef() { return S_OK; }
STDMETHODIMP_(ULONG) Release() { return S_OK; }

//ISampleGrabberCB
STDMETHODIMP SampleCB(double SampleTime, IMediaSample* pSample);
STDMETHODIMP BufferCB(double SampleTime, BYTE* pBuffer, long BufferLen) { return S_OK; }
};

STDMETHODIMP CallbackObject::SampleCB(double SampleTime, IMediaSample* pSample)
{
if (!pSample)
return E_POINTER;
long sz = pSample->GetActualDataLength();
BYTE* pBuf = NULL;
pSample->GetPointer(&pBuf);
if (sz Release();
return S_OK;
}

int main() {
// Enumerate video devices
std::cout Release();
pGraph->Release();
pVideoCaptureFilter->Release();
pSampleGrabber->Release();
pSampleGrabberFilter->Release();
delete pCallback; // Release the callback object

// Uninitialize COM
CoUninitialize();

return 0;
}

Видео со встроенной веб-камеры ноутбука, похоже, захватывается и обрабатывается, но функция SampleCB(), похоже, не вызывается. Есть подсказки, что я делаю не так?
Спасибо,
Винай

Подробнее здесь: https://stackoverflow.com/questions/778 ... directshow

Вернуться в «C++»