I'm developing a small video capture library on top of videoInput (a thin wrapper around DirectShow) and lately I encountered a tricky issue.
The library captures and saves video frames to its internal format, using code to the effect of this:
if (VI->setupDevice(m_deviceIndex, width, height)) {
//... checks for frame size etc
//...
auto pixels = VI->getPixels(m_deviceIndex, true, true);
}
This code was built in VS 2017 using vc140/sdk8.1 and it worked fine on a range of different machines running Windows 7, 8.1 and 10, which included typical office desktops and laptops, several development machines, a highly restrictive production desktop and VirtualBox guests.
Then we discovered that on one Windows 7 computer videoInput yields black frames (null pixels), even though the camera itself works properly with other applications. We tested several different camera models to the same effect.
I built DirectShow examples from official Microsoft repository and discovered that on startup the samples fail with hr=0x80070005 error (access denied), regardless of running in elevated mode. Here's where the error occurs (amcap.cpp, line 787).
Since official samples supposedly should work out of the box, I suspected that there might be a compatibility bug in later versions of SDK/MSVC and tried compiling with VS 2010, but that didn't help. I also tried different capture back-ends, using Windows Media Foundation example from the same repository, as well as OpenCV with ffmpeg - all to the same effect.
Then we discovered another machine, running Windows 10, which had exactly the same problem, indicating that this is not an issue of backwards compatibility. Meanwhile, the same builds were working fine on my test machines, and third-party applications like Webcamoid were working fine on the problematic PCs.
My best guess is that there's some kind of compatibility flag or permission which has to be granted, since the camera works just fine with third-party software, but I have no idea where to look for them, and Windows 7 doesn't have camera permission settings to begin with, if I'm not mistaken.
Now, does anyone have any idea what on Earth might be wrong? I would greatly appreciate any advice.
Thank's.
Problem solved.
The problem turned out to be due to Kaspersky Endpoint Security, which has an option to restrict video streaming for unknown applications. This is why camera apps from the Store worked fine (they were trusted by default), and our application didn't.
Caveat emptor.
Related
I have an application developed with Qt3D (which uses OpenGL) by Qt 5.11.3 and Xcode 9.4.1 build tools. App runs fine on Linux and Windows, but on macOS Retina display (10.14, Mojave), I observe:
There are two workarounds for the above observation:
Set Retina display to full native resolution (microscopically small) then open app which seems to look and function correctly. Then lower the resolution to something usable and app continues to work properly
Get info of the app and check the open in low resolution checkbox like this image from a website:
I have studied similar questions but the posted solutions look more like a hack. And my app is a complex one, I cannot just simply multiply everything by a ratio. Is there any other solution for this? How can I force my app to open in low resolution on macOS, already asked here? Thanks.
I'm trying too use DirectX desktop duplication API.
I tried running exmaples from
http://www.codeproject.com/Tips/1116253/Desktop-Screen-Capture-on-Windows-via-Windows-Desk
And from
https://code.msdn.microsoft.com/windowsdesktop/Desktop-Duplication-Sample-da4c696a
Both of these are examples of screen capture using DXGI.
I have NVIDIA GeForce GTX 1060 with Windows 10 Pro on the machine. It has Intelâ„¢ Core i7-6700HQ processor.
These examples work perfectly fine when NVIDIA Control Panel > 3D Settings is selected to Auto select processor.
However if I set the setting manually to NVIDIA Graphics Card the samples stop working.
Error occurs at the following line.
//IDXGIOutput1* DxgiOutput1
hr = DxgiOutput1->DuplicateOutput(m_Device, &m_DeskDupl);
Error in hr(HRESULT) is DXGI_ERROR_UNSUPPORTED 0x887A0004
I'm new to DirectX and I don't know the issue here, is DirectX desktop duplication not supported on NVIDIA ?
If that's the case then is there a way to select a particular processor at the start of program so that program can run with any settings ?
#Edit
After looking around I asked the developer (Evgeny Pereguda) of the second sample project on codeproject.com
Here's a link to the discussion
https://www.codeproject.com/Tips/1116253/Desktop-Screen-Capture-on-Windows-via-Windows-Desk?msg=5319978#xx5319978xx
Posting the screenshot of the discussion on codeproject.com in case original link goes down
I also found an answer on stackoverflow which unequivocally suggested that it could not be done with the desktop duplication API referring to support ticket at microsoft's support site https://support.microsoft.com/en-us/help/3019314/error-generated-when-desktop-duplication-api-capable-application-is-ru
Quote from the ticket
This issue occurs because the DDA does not support being run against
the discrete GPU on a Microsoft Hybrid system. By design, the call
fails together with error code DXGI_ERROR_UNSUPPORTED in such a
scenario.
However there are some applications which are efficiently duplicating desktop on windows in both modes (integrated graphics and discrete) on my machine. (https://www.youtube.com/watch?v=bjE6qXd6Itw)
I have looked into the installation folder of the Virtual Desktop on my machine and can see following DLLs of interest
SharpDX.D3DCompiler.dll
SharpDX.Direct2D1.dll
SharpDX.Direct3D10.dll
SharpDX.Direct3D11.dll
SharpDX.Direct3D9.dll
SharpDX.dll
SharpDX.DXGI.dll
SharpDX.Mathematics.dll
Its probably an indication that this application is using DXGI to duplicate desktop, or may be the application is capable of selecting a specific processor before it starts.
Anyway the question remains, is there any other efficient method of duplicating desktop in both modes?
The likely cause is certain internal limitation for Desktop Duplication API, described in Error generated when Desktop Duplication API-capable application is run against discrete GPU:
... when the application tries to duplicate the desktop image against the discrete GPU on a Microsoft Hybrid system, the application may not run correctly, or it may generate one of the following errors:
Failed to create windows swapchain with 0x80070005
CDesktopCaptureDWM: IDXGIOutput1::DuplicateOutput failed: 0x887a0004
The article does not suggest any other workaround except use of a different GPU (without more specific detail as for whether it is at all achievable programmatically):
To work around this issue, run the application on the integrated GPU instead of on the discrete GPU on a Microsoft Hybrid system.
Microsoft introduced a registry value that can be set programmatically to control which GPU an application runs on. Full answer here.
This is going to be my first question in StackOverflow after several days looking for an explanation. Please, be gentle with me for asking because I know my problem is a bit bizarre to be a general problem.
I made a MF capture video application, based in the Microsoft example 'CaptureToFile'. It did work on Windows 7 x64. I upgraded to Visual Studio 2013 without problems. Problems arose when I try to put all the development on a Windows 8.1 x64 machine.
The app compiles and executes without error, but it's UNABLE to capture samples by using m_pReader->ReadSample() in asynchronous mode; only the first two samples arrive to OnReadSample method; and there must be 'control' samples, because the IMFSample is null in all of them. After that, the app gets 'hanged' waiting for data.
I've tried the original MFCaptureToFile sample with the same sad results.
Of course, I think hardware and software are similar (the same capture card with the same driver version, both are desktop PC...)
Do you know any possible reason for this behaviour? in Win7 everything is working flawless! Or at least, if you could light me a bit about new paths for finding what's happening
Thanks in advance
UPDATE: There is another 'player' in the game. Looking into the threads, I see that a worker thread is in 'RTWorkQ.dll', the real-time work queue container, specific only for Windows 8. I will go on investigating. In the meantime, if you have any idea, something to share, I'll be glad to hear you.
UPDATE 2: I've modified the sample MFCaptureToFile to get the video samples synchronously, because I thought the problem could be due to the asynchronous behaviour; related with the queues. I've to say that the problem persist even with this change. The second time it tries to read a sample, the application gets 'hanged' waiting for a reading that doesn't never arrives.
UPDATE 3: I've tried with the CaptureEngine sample application that uses another MF way to capture video (MFCaptureEngine). It builds and runs flawlessly but doesn't show any images when starting the 'preview' and doesn't record any useful, only non-playable files.
UPDATE 4: I've installed Visual Studio 2010 Ultimate in Windows 8 PRO. The sample MFCaptureToFile fails again in the sample. It's unable to read a 2nd sample from the frame grabber. I'm starting to think that can be an incompatibility between the capture card (Datapath VisionRGB-E1S) and Windows 8 PRO despite the driver assures it works fine in this platform and the test program shows images. Tomorrow I'm going to try the test with an external USB webcam.
Finally, I have figured out the reason of this problem.
With Windows 8.1 release Microsoft has introduced New AVStream Interfaces for Windows 8.1
There is a small but very important change in KS_FRAME_INFO structure - the new FrameCompletionNumber member.
An identifying sequence number for the frame in the completed queue.
This number is used to verify proper frame order. When this value is
0, the frame was cancelled. This member is available starting with
Windows 8.1.
DirectShow doesn't care about this number. And MediaFoundation cares.
So, you cannot just fix that on your user-mode side. The manufacture developers must release an update. Btw, I have two webcams - Logitech C270 and Creative Live Socialize HD. Logitech supports Metro while Creative does not.
I have successfully updated my driver with only a few lines of code (to set up FrameCompletionNumber properly).
UPD. similar thread http://www.osronline.com/showthread.cfm?link=255004
It must be a problem of the frame grabber Datapath VisionRGB-E1S. I've tried with the brand-new USB webcam LifeCam Studio, and everything worked fine.
I will left for other future thread why this unpaired behaviour between Windows 8 and Windows 7, but it could be something related to the User-mode access...
I had the same kind of issue:
IMFSourceReader was obtained successfully
reader->SetCurrentMediaType() reported no error.
reader->ReadSample() was successful.
then OnReadSample() was called only once and the hrStatus argument 0x80070491
For me, the issue was that I modified the video subtype IMFMediaType, then applied to the reader as current media type.
I've been trying to research why certain compatibility features differ based on operating system so I can program a patch. I'm using the compatibility settings in the registry for Windows 95 to run a game (that of which the game was produced on) in each system. In Windows XP, the game runs perfectly. None of the scenes lag, and the sound works just as well as the scenes. I'm unsure of how it runs in Windows Vista, but in Windows 7 & 8 the compatibility feature breaks the game. I used a VM to run XP, but that doesn't effect the game's playability; real XP users have tested it. Whenever I play the game using the Win95 setting for compatibility in 7 & 8, everything lags. The music doesn't slow down during gameplay, but the graphics do. During cutscenes, they literally break. Everything pixelates, white noise and static increases volume, and the video lags every two seconds.
I therein tested it in Ubuntu Linux via WINE, and it runs better than it does in XP. I just had to use the alsa sound driver. What changed? If so, is it programmatically fixable? I'm using an amalgamation of C++, Batch and Java.
If it is necessary, the video game is entitled "The Neverhood."
Thanks.
The compatibility feature available in the shell is just scratching the surface of the "Application Compatibility" subject in Windows.
There is a tool called "Microsoft Application Compatibility Toolkit (ACT)" (that exist since Windows XP exist I believe) that has much more to offer, so maybe that can help.
For example here are some compatibility settings for Graphics Control Issues
I currently play "The Neverhood" on Win7 x64 without any visual problem, you are right when I played on Win7 for first time (4 years ago) was a headache and a little tricky to do the correct compatibility flags for each win version but finally I wrote this reg code for Win7 and worked for me while 4 years, sure it will work for you too:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Folder\\nhc.exe"="# WIN95 256COLOR 640X480 DISABLEDWM"
Where "C:\\Folder\\nhc.exe" of course is the path to your Neverhood. (Notice the double backslashes)
that flags means: Change Display color to 256 colors, change display resolution to 640x480, disable Themes service (DWM Service).
I hope this help you.
This may not answer the question directly, but if you want to improve performance of The Neverhood, change the compatibility to run in Windows 95 - then switch all other options ON, except the bottom three. This helps to make the game as fast and smooth as possible.
I have just recently installed Windows 8, and I tried to compile and build a simple c++ game project in VS 2010, but when I did, it was running at 5 fps. On windows 7, it runs at a solid 60 fps. Nothing has been changed in the code, but there is just horrible slow down.
I have updated my video drivers, but there is still horrible lag. I thought the problem was to do with compatibility issues with windows 8 and OpenGL, but I can't find anything to confirm this. I was wondering if anyone else has had this problem, and if you have solved it.
I would recommend you test your graphics card / drivers first. All sorts of driver issues could arise when you upgrade operating systems. One of the best tests would be to download Cinebench and see how it performs. Cinebench will evaluate your OpenGL performance. If you get poor results, then you know it's a hardware / driver issue and not an issue with your application.
If the Cinebench results are good, then you can move on to the recommendations made by #Robert Rouhani (comments).
http://www.maxon.net/products/cinebench/overview.html
What sort of video card do you have in the Win8 machine?
If it's a laptop you might be battling against nVidia Optimus (or an equivalent technology?). Basically programs have to tell the OS in advance that they want to use the video card or they get defaulted to using the low power GPU embedded in the CPU (note: over-simplification).
If this is the case, there's some options in the nVidia control panel to let you create a profile telling the OS to run your app with the discrete GPU, rather than the embedded one.