I developed a video capture application in C++ with Qt on Windows 7, using the videoInput library (which uses DirectShow). My application works fine with all the devices I previously tried (some inboard capture devices, webcams, a Pinnacle Dazzle DVC 100, a Pinnacle Studio Movie Box, and even a troubled PixelView PlayTV USB Hybrid), but now I bought an AVerMedia DarkCrystal HD Capture Station (in order to support HD capturing) and it simply won't work.
According to the AVerMedia website, it is totally DirectShow-compatible and I don't even need to use its SDK. I followed the manufacturer's installation instructions and I'm able to capture video using its own bundled software (TotalMedia Studio MV), so I suppose it's working properly.
I tried to run my videoInput-based application and also AmCap (DirectShow sample from Microsoft) and both of them behave the same way. They are able to find the device, retrieve its friendly name, but nothing else. AmCap says Error 80004002: Cannot find VCapture:IAMStreamConfig.
I was debugging AmCap and found out the ICaptureGraphBuilder2::FindInterface method always returns E_NOINTERFACE, i.e. no such interface supported, in lines like this:
hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, gcap.pVCap,
IID_IAMStreamConfig, (void **)&gcap.pVSC);
Here, gcap.pBuilder is a pointer to ICaptureGraphBuilder2, gcap.pVCap is a pointer to IBaseFilter, and gcap.pVSC is a pointer to IAMStreamConfig and should receive the return value.
I suppose there's some workaround that could help me to capture from this device, since I could sucessfully retrieve the device name (using the ICreateDevEnum::CreateClassEnumerator method, based on the CLSID_VideoInputDeviceCategory class identifier).
A video capture device which does not implement IAMStreamConfig is a possible scenario, though it's not something expected. Actually it more looks like a bug on video device or underlying driver, however you might want to update your app to use default media type in case of missing IAMStreamConfig (you can still use GraphEdit to check if the device is operational).
Related
I can not seem to find any tutorial on the internet for my question.
All the simple guide is not suitable for UWP.
For Example,
To use WASAPI there are these steps
enumerate devices
capture audio
play (render) audio back
But the enumerating step, The client must call CoCreateInstance. But from my understanding this function is not support in UWP. Also I failed at Line 30 when following this code.
So, I try to understand This, C++ UWP using WASAPI, But I can't find any Enumerate part and this project is very complicate for me.
It include a lot of other files (DeviceState.h, common.h)
And I failed to extract the code to create my own application.
My question is how can I capture audio on c++ UWP app with WASAPI?
If this question is too board, I will change my question to How to enumerate audio device in c++ UWP application?.
And the reason why I use WASAPI is because I want to access the data stored in the Buffer.
Edit:
For enumerating.
https://github.com/Microsoft/Windows-universal-samples/blob/7c7832e1f144e4fc836603fd70e1352024a5fe1a/Samples/WindowsAudioSession/cpp/Scenario1.xaml.cpp#L85
Yes, you can use WASAPI to do audio capturing in UWP and this is what is done in the sample you have referenced (https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/WindowsAudioSession).
For the enumeration, the main function is DeviceInformation::FindAllAsync with this selector MediaDevice::GetAudioCaptureSelector it will allow you to list the capture devices.
For the stream capturing, the main function you need is
ActivateAudioInterfaceAsync, it will allow you to create an IAudioClient from a device id (specific device) or a device class (render or capture) if you just need to use the default device.
Once you have this IAudioClient you can use it to get an IAudioClientCapture, basically the things that you have seen in the sample.
The question is complete in itself. Adding a few more details to include the things which I have already tried:
I have searched across stackexchange platform, but was unable to get my query solved.
Through some clues which I gathered along the way, I could only count the number of connected devices.
VideoCapture class has been mentioned in some posts, but that was only so much useful.
I am working on Windows platform with C++.
I created this C++ class that allows you to enumerate the devices (including ID) that you can use in order to get the list of devices to use in OpenCV. It is hosted on GitHub
https://github.com/studiosi/OpenCVDeviceEnumerator
The idea is to use DirectShow to get all the devices that have the category with GUID CLSID_VideoInputDeviceCategory, and then, through an enumerator, you get in which order they appear on the system, which is the ID you need to open them on OpenCV by creating a VideoCapture object (by using the constructor that receives the ID, which would be the index of the device on the enumeration). Obviously, this approach only works on Windows.
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).
I am trying to write a program which captures your speech applies my effect on the captured audio and play it back immediately. I am writing this app to the windows store in c++. After suffering with MediaCapture I decided to use WASAPI to do that. I am using an example from the msdn to set up WASAPI. As I expected I ran into a problem very soon. So the problem is with the following two lines:
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
The visual studio says that:
Error: operand of __uuidof must have a class or enum type for which __declspec(uuid('..')) has been specified.
I haven't got any idea what it means. I would appreciate some help here.
To be able to use __uuidof() a uuid must have been declared for the target. When compiling for Windows 8 Store Apps it seems that MMDeviceEnumerator and IMMDeviceEnumerator don't have any uuid declaration and you should instead use the Windows::Devices::Enumeration namespace to enumerate the devices and then use IActivateAudioInterfaceAsyncOperation to initialize and activate the audio device.
Here is a link to a fully working example that captures pcm data and writes it to a wav-file. It uses the systems' default audio capture device but enumerating the available devices and using any of them instead is a piece of cake. :)
WASAPI sample for Windows 8
I'm trying to stream a video from a camera ( Sony HVR-Z1E ) over FireWire to my Computer. The incoming pictures/stream shall be processed further by some functions which expect the CVMat format ( from openCV ).
Well my problem is now that I have no idea how to grab the stream. Okay openCV 2.1 offers me some methods ( cvCapturefromCam ) , but no matter which parameter I give him, it always gets the stream from the webcam of the laptop and not from the firewire. I heard I need to switch the primary cam in the DirectShow API ( with the Windows SDK ). But I actually don't know how to do that either.
So any suggestions how to do this?
See my related answer here. OpenCV cannot capture video from Firewire cameras natively. You will either need to use the CMU1394 driver, or the Sony driver (if an SDK is available for it) to capture video from that camera, and then pass it to OpenCV.
Years ago, I've made something like this using DirectShow. The main limitation was fact, that image acquired via DShow was in standard PAL resolution. HD Image grabbing was not possible (it was one of the first pro-consumer HD camcorders from Sony, don't remember exact model now). Good thing was - this method didn't need anything except bare DirectShow - no additional drivers and so on. And it was VERY fast.
In general, method was something like this:
building media render graph (of course, You have to enumerate video devices in that stage)
inserting into it custom class which inherited from ISampleGrabberCB.
How it worked:
it used BufferCB() virtual method from ISampleGrabberCB - which you have to write in your inherited class.
in mentioned method, you have to leave data in global struct, and from main thread - take care of them.
I know, that's a bit fuzzy description, but I hope You'll find Your info (googling for "ISampleGrabberCB" should be a good starting point, there should be a lot of sample code).