I am using a source filter of a webcam. When I use the filter in graphstudio it has two output pins. However in code the call to IEnumPins->next always returns S_FALSE.
I also looked for another interface that could create pins but didn't find such a thing.
How do I add pins to the webcam filter? If they're available in graphstudio they should be in code too, right?
Here is my code.. I checked for return values and returned them if they are not ok. But everything seems to work fine except that the webcam filter doesn't return any pins
CoInitialize(NULL);
IGraphBuilder* graphBuilder = NULL;
IMediaControl* mediaControl = NULL;
IMediaEvent* mediaEvent = NULL;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IFilterGraph, (void **)&graphBuilder);
HANDLE fileHandle = CreateFile(L"D:\\TEMP\\debug1.log", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
graphBuilder->SetLogFile((DWORD_PTR)fileHandle);
graphBuilder->QueryInterface(IID_IMediaControl, (void **)&mediaControl);
graphBuilder->QueryInterface(IID_IMediaEvent, (void **)&mediaEvent);
IBaseFilter* source = NULL;
static const GUID CLSID_Webcam =
{ 0x17CCA71B, 0xECD7, 0x11D0, { 0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } };
hr = CoCreateInstance(CLSID_Webcam, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&source);
if (FAILED(hr))
return hr;
hr = graphBuilder->AddFilter(source, L"logitech");
if (FAILED(hr))
return hr;
IPin* camOut = GetPin(source, PINDIR_OUTPUT);
...
The GetPin function uses EnumPins method to find pin:
IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
{
BOOL bFound = FALSE;
IEnumPins *pEnum;
IPin *pPin;
pFilter->EnumPins(&pEnum);
while (pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pPin->QueryDirection(&PinDirThis);
if (bFound = (PinDir == PinDirThis))
break;
pPin->Release();
}
pEnum->Release();
return (bFound ? pPin : 0);
}
Also, I don't think that this is 32/64bit problem. I compile to x64 and I also used the 64bit version of graphstudionext. And i also made sure that the guid of the webcam filter is correct. (At least if you can trust graphstudionext)
This is an indication that your code deals with another filter or has bugs otherwise. You normally don't "create" pins, especially on video device backed source filter. Typical reasons are: (a) you are effectively creating a different filter, (b) direct bug in your code, (c) 32/64-bit issue with different filters in the two environments. There can hardly be anything else. Stepping and inspecting your code thoroughly, adding debug output should take you to the solution.
UPDATE. Video capture devices like this cannot be instantiated using CoCreateInstance. You have to create them using monikers. typically through enumeration, as described on MSDN (with source code snippet): Selecting a Capture Device.
The code below is incorrect, FYI this GUID is declared in SDK as CLSID_Proxy.
static const GUID CLSID_Webcam =
{ 0x17CCA71B, 0xECD7, 0x11D0, { 0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } };
hr = CoCreateInstance(CLSID_Webcam, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&source);
Related
I'm trying to disable Aeroshake minimize mouse gesture only. Asked a question How to disable Aero Shake minimize only on Windows 7 but no answers. So I continued digging and found another solution by updating user Group Policy.
void aeroshake(DWORD action)
{
HRESULT hr;
IGroupPolicyObject* pLGPO;
HKEY machine_key, dsrkey;
LSTATUS sdf, ds, rStatus;
GUID RegistryId = REGISTRY_EXTENSION_GUID;
GUID ThisAdminToolGuid =
/*{ CLSID_PolicySnapinUser/* */
{
0x0F6B957E,
0x509E,
0x11D1,
{ 0xA7, 0xCC, 0x00, 0x00, 0xF8, 0x75, 0x71, 0xE3 }
};
const IID my_IID_IGroupPolicyObject =
{ 0xea502723, 0xa23d, 0x11d1,{ 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
const IID my_CLSID_GroupPolicyObject =
{ 0xea502722, 0xa23d, 0x11d1,{ 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } };
GUID ext_guid = REGISTRY_EXTENSION_GUID;
// This next one can be any GUID you want
GUID snap_guid = { 0x3d271cfc, 0x2bc6, 0x4ac2,{ 0xb6, 0x33, 0x3b, 0xdf, 0xf5, 0xbd, 0xab, 0x2a } };
// Create an instance of the IGroupPolicyObject class
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CoCreateInstance(my_CLSID_GroupPolicyObject, NULL, CLSCTX_INPROC_SERVER,
my_IID_IGroupPolicyObject, (LPVOID*)&pLGPO);
// We need the machine LGPO (if C++, no need to go through the lpVtbl table)
hr = pLGPO->OpenLocalMachineGPO(GPO_OPEN_LOAD_REGISTRY);
if (hr != S_OK) {
goto release;
}
hr = pLGPO->GetRegistryKey(GPO_SECTION_USER, &machine_key);
if (hr != S_OK) {
goto close;
}
// create key for disable Aeroshake minimise
sdf = RegCreateKeyEx(machine_key, TEXT("Software\\Policies\\Microsoft\\Windows\\Desktop\\NoWindowMinimizingShortcuts"),
0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, NULL, &dsrkey, NULL);
// Create the value
ds = RegSetKeyValue(dsrkey, NULL, TEXT("NoWindowMinimizingShortcuts"), REG_DWORD, &action, sizeof(action));
RegCloseKey(dsrkey);
// Apply policy and free resources
pLGPO->Save( TRUE, TRUE, &ext_guid, &snap_guid);
rStatus = RegCloseKey(machine_key);
// Write the GPO back to the directory
hr = pLGPO->Save(
FALSE,
TRUE,
&RegistryId,
&ThisAdminToolGuid);
close:
RegCloseKey(machine_key);
release:
pLGPO->Release();
}
This looks like a proper way but I have problem with OpenLocalMachineGPO it always returns E_ACCESSDENIED. Can that be sorted w/o need to run as Admin. Also when the code run as Admin it still doesn't change the required policy.
E_ACCESSDENIED means no access, of course you need enough permissions to modify the GPO.
In addition, The key value NoWindowMinimizingShortcuts is under the Sub Key Software\\Policies\\Microsoft\\Windows\\Explorer
sdf = RegCreateKeyEx(machine_key, TEXT("Software\\Policies\\Microsoft\\Windows\\Explorer"),
0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, NULL, &dsrkey, NULL);
You'll need to reboot or at least log off, then log in to take effect.(Even you modify in GPO directly)
Then the changes will be updated to HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Explorer:
NoWindowMinimizingShortcuts = 0x00000001
Of course, you can also modify this key directly.(need to create it first if you don't have one)
void aeroshake(DWORD action)
{
// create key for disable Aeroshake minimise
HKEY hKeyRoot, dsrkey;
LSTATUS sdf = RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Policies\\Microsoft\\Windows"), &hKeyRoot);
sdf = RegCreateKey(hKeyRoot, TEXT("Explorer"), &dsrkey);
// Create the value
sdf = RegSetKeyValue(dsrkey, NULL, TEXT("NoWindowMinimizingShortcuts"), REG_DWORD, &action, sizeof(action));
RegCloseKey(dsrkey);
}
I'm trying to get a pointer to the IDirect3DSurface9 and I use the the helper function MFGetService and I pass MR_BUFFER_SERVICE to the second parameter.While linking,I received a "unresolved external symbol _MR_BUFFER_SERVICE" error.
I looked up the definition of MR_BUFFER_SERVICE in evr.h and found a macro describing it:
DEFINE_GUID(MR_BUFFER_SERVICE,
0xa562248c,
0x9ac6,
0x4ffc,
0x9f, 0xba, 0x3a, 0xf8, 0xf8, 0xad, 0x1a, 0x4d
);
And then I decided to make this GUID on my own and passed to the MFGetService, but then I get the error code E_NOINTERFACE while debugging.
//Here are the GUID struct I made:
const GUID FAR MR_BUFFER_SERVICE = { 0xa562248c,0x9ac6,0x4ffc, {0x9f, 0xba, 0x3a, 0xf8, 0xf8, 0xad, 0x1a, 0x4d} };
//The main code of getting a pointer to IDirect3DSurface9:
IDirect3DSurface9 *d3dsurface9;
IMFMediaBuffer* pBuffer = NULL;
hr = MFCreateMemoryBuffer(1024 * 10, &pBuffer);
if (FAILED(hr))
{
MessageBox(NULL, L"fail in creating Media Buffer", NULL, NULL);
}
hr = MFGetService(pBuffer, MR_BUFFER_SERVICE,
IID_PPV_ARGS(&d3dsurface9));
if (FAILED(hr))
{
MessageBox(NULL, L"failed in getting IDirect3DSurface9", NULL, NULL);
}
Linker error is to be resolved by additionally linking strmiids.lib
#pragma comment(lib, "strmiids.lib")
MR_BUFFER_SERVICE is not available from generic system memory backed buffers you create by MFCreateMemoryBuffer. This service is only available from buffers which are wrapping respective D3D9 surface, esp. created with MFCreateDXSurfaceBuffer function.
The details are documented here: DirectX Surface Buffer.
I have bought license from Elecard for their AVC\H264 Decoder
Following that code:
HRESULT DShowPlayer::ActivateFilter(IBaseFilter *filter)
{
static const GUID KEY_GUID = { 0xb9d44b32, 0xd34a, 0x11e8, { 0x88, 0x16, 0x10 , 0x20 ,0xFB ,0x45 ,0x87, 0x53 } };
HRESULT hr = S_OK;
IModuleConfig* IMC;
hr = filter->QueryInterface(&IMC);
if (SUCCEEDED(hr))
{
hr = IMC->SetValue(&KEY_GUID, NULL);
IMC->Release();
}
return hr;
}
I am trying to activate my filter ( The number above was changed of course)
Calling that function i pass the Elecard Decoder filter after it was added to the graph.
I am getting the hr of
hr = IMC->SetValue(&KEY_GUID, NULL);
is Invalid pointer
Does someone activate Elecard Decoder via code.
BTW, Activating the filter via the Module Config Checker works as expected
Thanks!
Sorry , i just enter incorrect GUID
entering incorret GUID gives pointer error
I am trying to send an HTTP request from a C++ program.
The problem is that I get a 5023 (0x139F) error, which is most probably ERROR_INVALID_STATE.
I have no idea why that happens.
It happens when I use the code from:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383989(v=vs.85).aspx
and that happens when I run the line:
hr = pIWinHttpRequest->Open(bstrMethod,
bstrUrl,
varFalse);
The code is copied to here:
//code
#include <windows.h>
#include <stdio.h>
#include <objbase.h>
#include "httprequest.h"
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")
// IID for IWinHttpRequest.
const IID IID_IWinHttpRequest =
{
0x06f29373,
0x5c5a,
0x4b54,
{0xb0, 0x25, 0x6e, 0xf1, 0xbf, 0x8a, 0xbf, 0x0e}
};
int main()
{
// Variable for return value
HRESULT hr;
// Initialize COM
hr = CoInitialize( NULL );
IWinHttpRequest * pIWinHttpRequest = NULL;
BSTR bstrResponse = NULL;
VARIANT varFalse;
VARIANT varEmpty;
CLSID clsid;
VariantInit(&varFalse);
V_VT(&varFalse) = VT_BOOL;
V_BOOL(&varFalse) = VARIANT_FALSE;
VariantInit(&varEmpty);
V_VT(&varEmpty) = VT_ERROR;
hr = CLSIDFromProgID(L"WinHttp.WinHttpRequest.5.1",
&clsid);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(clsid,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWinHttpRequest,
(void **)&pIWinHttpRequest);
}
if (SUCCEEDED(hr))
{
// Open WinHttpRequest.
BSTR bstrMethod = SysAllocString(L"GET");
BSTR bstrUrl = SysAllocString(L"http://microsoft.com");
hr = pIWinHttpRequest->Open(bstrMethod,
bstrUrl,
varFalse);
SysFreeString(bstrMethod);
SysFreeString(bstrUrl);
}
if (SUCCEEDED(hr))
{
// Send Request.
hr = pIWinHttpRequest->Send(varEmpty);
}
if (SUCCEEDED(hr))
{
// Get Response text.
hr = pIWinHttpRequest->get_ResponseText(&bstrResponse);
}
if (SUCCEEDED(hr))
{
// Print the response to a console.
wprintf(L"%.256s",bstrResponse);
}
// Release memory.
if (pIWinHttpRequest)
pIWinHttpRequest->Release();
if (bstrResponse)
SysFreeString(bstrResponse);
CoUninitialize();
return 0;
}
Your help is appreciated.
I use Windows 7 64 bit if this matters in anyway.
On another machine Windows 7 64 bit machine the same code worked for me, so that must be an environment issue.
If anyone knows what to look for, it will be great.
Thanks,
Ronen
In windows XP, it is quite easy to control master volume of a mixer device by setting volume of destination line using mixer api.It can be easily tested by sdk sample application provided by Microsoft.But in case of windows 7 whenever I open a mixer device in my application it shows it as new volume application and I am able to control only volume of my application.Not able to control complete sound of system.Can anyone suggest me how to control complete sound of speaker which will affect sound of all running application.
How can I change speakers volume using my application in windows 7 ?
I believe that the method you're looking for is SetMasterVolumeLevelScalar.
A short example in C (sorry for the lpVtbls):
BOOL AddMasterVolumeLevelScalar(float fMasterVolumeAdd)
{
IMMDeviceEnumerator *deviceEnumerator = NULL;
IMMDevice *defaultDevice = NULL;
IAudioEndpointVolume *endpointVolume = NULL;
HRESULT hr;
float fMasterVolume;
BOOL bSuccess = FALSE;
hr = CoCreateInstance(&XIID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &XIID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator);
if(SUCCEEDED(hr))
{
hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice);
if(SUCCEEDED(hr))
{
hr = defaultDevice->lpVtbl->Activate(defaultDevice, &XIID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
if(SUCCEEDED(hr))
{
if(SUCCEEDED(endpointVolume->lpVtbl->GetMasterVolumeLevelScalar(endpointVolume, &fMasterVolume)))
{
fMasterVolume += fMasterVolumeAdd;
if(fMasterVolume < 0.0)
fMasterVolume = 0.0;
else if(fMasterVolume > 1.0)
fMasterVolume = 1.0;
if(SUCCEEDED(endpointVolume->lpVtbl->SetMasterVolumeLevelScalar(endpointVolume, fMasterVolume, NULL)))
bSuccess = TRUE;
}
endpointVolume->lpVtbl->Release(endpointVolume);
}
defaultDevice->lpVtbl->Release(defaultDevice);
}
deviceEnumerator->lpVtbl->Release(deviceEnumerator);
}
return bSuccess;
}
In case the GUIDs are not defined:
const static GUID XIID_IMMDeviceEnumerator = { 0xA95664D2, 0x9614, 0x4F35, { 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6 } };
const static GUID XIID_MMDeviceEnumerator = { 0xBCDE0395, 0xE52F, 0x467C, { 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E } };
const static GUID XIID_IAudioEndpointVolume = { 0x5CDF2C82, 0x841E, 0x4546, { 0x97, 0x22, 0x0C, 0xF7, 0x40, 0x78, 0x22, 0x9A } };