Problems capturing with Media Foundation & Windows 8 in C++ - c++

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.

Related

DirectShow fails with black frames and 0x80070005 on Win7/Win10

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.

DirectX11 Desktop duplication not working with NVIDIA

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.

Realtime video buffer access webcam, Windows Phone 8.1 C++

I need to do some basic video processing from the Webcam in Windows Phone 8.1.
I cannot find any examples of how to access the webcam preview buffer. The Microsoft examples (very few) all have a video preview frame activate, I can find none that show how to subscribe to a 'new frame ready' event, or where the buffer is.
The MediaCapture, and CaptureDevice appear to be the main ways of reaching the camera in this api.
Can anyone point to a specific example? For instance, a QR code reader, or maybe a program that adds video effects, like greyscale, would need to attach an event to every frame.
Thanks.
It sounds like you need to access the buffer from the preview stream of the phone cameras. If you absolutely need to target 8 and 8.1, then you should look into GetPreviewBufferArgb(out int[] pixels). See here: https://msdn.microsoft.com/en-us/library/windows.phone.media.capture.cameracaptureframe.getpreviewbufferargb.aspx
But if you can instead target Windows 10, you get the benefit of fully universal APIs, and you don't take a dependency on the likely soon to be deprecated (if not already) Windows.Phone.Media.Capture namespace. I would strongly recommend doing this instead, as the APIs will be easier to work with, and any 8.1 device can upgrade to 10 for free.
Here is a fully working Windows 10 sample: http://aka.ms/2015buildgetpreviewframesample, which was shown off at the last Build conference (video here: http://channel9.msdn.com/Events/Build/2015/2-730).

Mic/Speakers Audio Feedback in VLC API

I'm building a Webcam recording application with Qt 5.3 using vlc-qt, the problem is while previewing Audio/Video high feedback/noise and echo starts and gets higher, I've been googling and found it's the effect called Larsen's effect and how it's happening.
Notes:
I know using a headphone is a solution
I'm on a Windows 7 Ultimate Notebook
The Microphone Boost on zero dB is less noise but echo is persistent
My Questions:
How other webcam recording applications suppress the noise and the echo?
Specifically, how it can be fixed in VLC, your answer can be commandline arguments, notes or instructions to do in VLC software, it doesn't have to be code
Thanks!
I found http://www.dspcottage.com/en/algorithms/AEC a C++/MFC echo cancellation application based on Speex, but I needed to use it in Qt so I scrapped all MFC related code and here is the final solution https://github.com/Marware/Cpp_AEC

Program shuts down silently

There is a multithreaded program that operates simultaneously with a device via COM port based communication and remote (IP) video stream. The program also uses OpenCV library to process the data.
The trouble is that it shuts down without any signals (neither run-time, nor any other errors are caught; log file has no anything useful as well). The most top level application error event handler is set and still there are no any signs of the program crash. It just closes after awhile.
The biggest difficulty is that it works fine on all our PCs for days non-stop. But fails on customers PCs so that testing process is very slow. Customer is in a different country (Asian localization, whilst ours is European), but the program is built with Unicode support.
So far we have got some assumptions about localization issues and antivirus activity... but it gives nothing in result.
The program is written with MinGW 4.4.x C++ and wxWidgets 2.9.3
Any suggestions of the probable origin would be appreciate.
Solved.
The problem was inside OpenCV build 2.3.1, that we use. The function cv::imdecode(...) uses stdio.h`s tempnam() function to generate temporary file during decoding. Under x86 Windows systems this function fails after 32767 new names for temporary file. Under x64 Windows systems it returns some nonsense string, but it still works.
So the solution I came with was to change the way of receiving-decoding images from our device.
Thanks everybody for comments.