Capturing Video From Web-Camera On Windows 7 and 8 by Using Media Foundation - CodeProject
Capturing Video From Web-Camera On Windows 7 and 8 by Using Media Foundation - CodeProject
1 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
Sign in
G m ailfor W ork
Search for articles, questions, tips
home
articles
quick answers
discussions
features
community
help
CPOL
Rate this:
After starting to use the Win8-Desktop, I found that some old technologies do not work well, especially DirectShow. For instance,
capturing of live video from web-camera by DirectShow works perfect on WinXP, Vista, Win7, and allows to get the specific resolution.
For example, from Microsoft Life Studio Web-Camera, I can get video with 1080p. However, on Win8-Desktop, I can get only a 640x480
video. The fact is that the function in the line code, which on Win7 returns HRESULT - S_OK returns FAILED on Win8-Desktop. After
reading information on MSDN, I have got an idea that Microsoft has made purpose to stop support of DirectShow and expand another
technology - Media Foundation. I found some information about supporting of capturing of video from a web-camera by Media
Foundation with the needed parameters, but this information is very dispersed on MSDN. I think, it would be useful to have only one C++
class which includes all procedures of initialization, but hides all of them and has a simple interface. I made it and present it in this tip.
I lead the project of Augment Reality and I need simple support for capturing video from web-camera. I used the simple library
videoInputfrom the website http://muonics.net/school/spring05/videoInput/ which uses DirectShow for this purpose. However, it
was not working well on a Win8-Desktop. I found that there is a problem with setting the resolution for capturing of the video. I found
the solution to this problem by using Media Foundation, but my project used videoInput and I thought that it would be useful to
create a new library with the same interface as videoInput, but which uses Media Foundation. So I got the needed purpose, and I
think that my new library would be useful for other people who have faced the same problem in the process of development of the
program of image recognition.
The library videoInput was written in Visual Studio 2012 - videoInputVS2012.zip (staticlibrary videoInput-staticlibVS2012x86.zip) and includes nine classes:
videoInput - class-interface. For using this library, it is enough to include videoInput.h and videoInput .lib in your project. This
class is made as a singleton which makes managing of resources easy.
Media_Foundation - is a class singleton which manages the allocation and realizing of resources of Media Foundation.
videoDevices - is a class singleton which manages allocation and realizing of video devices and access to the separate video
device.
videoDevice - is the class for manipulation of capturing of video device, getting raw data, checking a new frame, getting
supported resolutions, setting the needed resolution, closing the video device.
ImageGrabberThread - is the class for manipulation of thread of the grabbing of the image.
ImageGrabber- is the class for initialization and grabbing images from the video device. It controls the process of grabbing
and finishes it.
RawImage - is the temp class which contains for writing and reading one frame.
10/27/2015 2:51 PM
2 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
FormatReading - is class for reading information about supported resolution into customer's MediaType.
DebugPrintOut - is the class for printing text into console.
It is enough to use the file videoInput.h as the interface of the library. Listing of it is presented below:
Hide Shrink
Copy Code
#pragmaonce
#include <guiddef.h>
structIMFMediaSource;
//Structureforcollectinginfoabouttypesofvideo,
//whicharesupportedbycurrentvideodevice
structMediaType
{
unsigned intMF_MT_FRAME_SIZE;
unsigned intheight;
unsigned intwidth;
unsigned intMF_MT_YUV_MATRIX;
unsigned intMF_MT_VIDEO_LIGHTING;
unsigned intMF_MT_DEFAULT_STRIDE;
unsigned intMF_MT_VIDEO_CHROMA_SITING;
GUIDMF_MT_AM_FORMAT_TYPE;
wchar_t*pMF_MT_AM_FORMAT_TYPEName;
unsigned intMF_MT_FIXED_SIZE_SAMPLES;
unsigned intMF_MT_VIDEO_NOMINAL_RANGE;
unsigned intMF_MT_FRAME_RATE;
unsigned intMF_MT_FRAME_RATE_low;
unsigned intMF_MT_PIXEL_ASPECT_RATIO;
unsigned intMF_MT_PIXEL_ASPECT_RATIO_low;
unsigned intMF_MT_ALL_SAMPLES_INDEPENDENT;
unsigned intMF_MT_FRAME_RATE_RANGE_MIN;
unsigned intMF_MT_FRAME_RATE_RANGE_MIN_low;
unsigned intMF_MT_SAMPLE_SIZE;
unsigned intMF_MT_VIDEO_PRIMARIES;
unsigned intMF_MT_INTERLACE_MODE;
unsigned intMF_MT_FRAME_RATE_RANGE_MAX;
unsigned intMF_MT_FRAME_RATE_RANGE_MAX_low;
GUIDMF_MT_MAJOR_TYPE;
wchar_t*pMF_MT_MAJOR_TYPEName;
GUIDMF_MT_SUBTYPE;
wchar_t*pMF_MT_SUBTYPEName;
MediaType();
~MediaType();
voidClear();
};
//Structureforcollectinginfoaboutoneparameterofcurrentvideodevice
structParametr
{
longCurrentValue;
longMin;
longMax;
longStep;
longDefault;
longFlag;
Parametr();
};
//Structureforcollectinginfoabout17parametersofcurrentvideodevice
structCamParametrs
{
ParametrBrightness;
ParametrContrast;
ParametrHue;
ParametrSaturation;
ParametrSharpness;
ParametrGamma;
ParametrColorEnable;
ParametrWhiteBalance;
ParametrBacklightCompensation;
ParametrGain;
ParametrPan;
ParametrTilt;
10/27/2015 2:51 PM
3 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
ParametrRoll;
ParametrZoom;
ParametrExposure;
ParametrIris;
ParametrFocus;
};
///Theonlyvisibleclassforcontrollingofvideodevicesinformatsingleton
classvideoInput
{
public:
virtual~videoInput(void);
//GettingofstaticinstanceofvideoInputclass
staticvideoInput&getInstance();
//ClosingvideodevicewithdeviceID
voidcloseDevice(unsigned intdeviceID);
//Settingcallbackfunctionforemergencyevents
//(forexample:removingvideodevicewithdeviceID)withuserData
voidsetEmergencyStopEvent(unsigned intdeviceID,void*userData,void(*func)(int,void*));
//Closingalldevices
voidcloseAllDevices();
//GettingofparametrsofvideodevicewithdeviceID
CamParametrsgetParametrs(unsigned intdeviceID);
//SettingofparametrsofvideodevicewithdeviceID
voidsetParametrs(unsigned intdeviceID,CamParametrsparametrs);
//Gettingnumbersofexistencevideodeviceswithlistinginconsole
unsigned intlistDevices(boolsilent=false);
//Gettingnumbersofformats,whicharesupportedbyvideodevicewithdeviceID
unsigned intgetCountFormats(unsigned intdeviceID);
//Gettingwidthofimage,whichisgettingfromvideodevicewithdeviceID
unsigned intgetWidth(unsigned intdeviceID);
//Gettingheightofimage,whichisgettingfromvideodevicewithdeviceID
unsigned intgetHeight(unsigned intdeviceID);
//GettingnameofvideodevicewithdeviceID
wchar_t*getNameVideoDevice(unsigned intdeviceID);
//GettinginterfaceMediaSourceforMediaFoundationfromvideodevicewithdeviceID
IMFMediaSource*getMediaSource(unsigned intdeviceID);
//Gettingformatwithid,whichissupportedbyvideodevicewithdeviceID
MediaTypegetFormat(unsigned intdeviceID,int unsignedid);
//Checkingofexistenceofthesuitablevideodevices
boolisDevicesAcceable();
//CheckingofusingthevideodevicewithdeviceID
boolisDeviceSetup(unsigned intdeviceID);
//CheckingofusingMediaSourcefromvideodevicewithdeviceID
boolisDeviceMediaSource(unsigned intdeviceID);
//CheckingofusingRawDataofpixelsfromvideodevicewithdeviceID
boolisDeviceRawDataSource(unsigned intdeviceID);
//Settingofthestateofoutprintinginfoinconsol
voidsetVerbose(boolstate);
//InitializationofvideodevicewithdeviceIDbymediatypewithid
boolsetupDevice(unsigned intdeviceID,unsigned intid=0);
//InitializationofvideodevicewithdeviceIDbywidthw,heighthandfpsidealFramerate
boolsetupDevice(unsigned intdeviceID,unsigned intw,
unsigned inth,unsigned intidealFramerate=30);
//CheckingofrecivigofnewframefromvideodevicewithdeviceID
boolisFrameNew(unsigned intdeviceID);
//WritingofRawDatapixelsfromvideodevicewithdeviceIDwithcorrection
//ofRedAndBlueflippingflipRedAndBlueandverticalflippingflipImage
boolgetPixels(unsigned intdeviceID,unsigned char*pixels,
boolflipRedAndBlue=false,boolflipImage=false);
private:
boolaccessToDevices;
videoInput(void);
10/27/2015 2:51 PM
4 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
Copy Code
//TestvideoInput.cpp:.
//
#include "stdafx.h"
#include "videoInput.h"
#include "highgui.h"
#pragmacomment(lib,"lib\\opencv\\Release\\opencv_highgui242.lib")
#pragmacomment(lib,"lib\\opencv\\Release\\opencv_core242.lib")
#pragmacomment(lib,"videoInput.lib")
voidStopEvent(intdeviceID,void*userData)
{
videoInput*VI=&videoInput::getInstance();
VI>closeDevice(deviceID);
}
int_tmain(intargc,_TCHAR*argv[])
{
videoInput*VI=&videoInput::getInstance();
inti=VI>listDevices();
if(i>0)
{
if(VI>setupDevice(i1,640,480,60))
{
VI>setEmergencyStopEvent(i1,NULL,StopEvent);
if(VI>isFrameNew(i1))
{
intcountLeftFrames=0;
cvNamedWindow("VideoTest",CV_WINDOW_AUTOSIZE);
CvSizesize=cvSize(VI>getWidth(i1),VI>getHeight(i1));
IplImage*frame;
frame=cvCreateImage(size,8,3);
while(1)
{
if(VI>isFrameNew(i1))
{
VI>getPixels(i1,(unsigned char*)frame>imageData);
cvShowImage("VideoTest",frame);
countLeftFrames=0;
}
else
countLeftFrames++;
charc=cvWaitKey(33);
if(c==27)
break;
if(c==49)
{
CamParametrsCP=VI>getParametrs(i1);
CP.Brightness.CurrentValue=128;
10/27/2015 2:51 PM
5 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
CP.Brightness.Flag=1;
VI>setParametrs(i1,CP);
}
if(!VI>isDeviceSetup(i1))
{
break;
}
if(countLeftFrames>60)
break;
}
VI>closeDevice(i1);
cvDestroyWindow("VideoTest");
}
}
}
if(VI>setupDevice(i1,1920,1080,60))
{
if(VI>isFrameNew(i1))
{
intcountLeftFrames=0;
cvNamedWindow("VideoTest1",CV_WINDOW_AUTOSIZE);
CvSizesize=cvSize(VI>getWidth(i1),VI>getHeight(i1));
IplImage*frame;
frame=cvCreateImage(size,8,3);
while(1)
{
if(VI>isFrameNew(i1))
{
VI>getPixels(i1,(unsigned char*)frame>imageData,false);
cvShowImage("VideoTest1",frame);
countLeftFrames=0;
}
else
countLeftFrames++;
charc=cvWaitKey(33);
if(c==27)
break;
if(!VI>isDeviceSetup(i1))
{
break;
}
if(countLeftFrames>60)
break;
}
VI>closeDevice(i1);
cvDestroyWindow("VideoTest1");
}
}
return 0;
}
In this code, the pointer on class videoInput can be got by calling the method videoInput::getInstance(). Before using
camera, it needs to get the list of suitable devices using the function VI>listDevices(). The device is initialized by calling the
method VI>setupDevice(i1,640,480,60). There are two overloaded methods setupDevice - setting the desired
resolution and frames per second, and setting the number of needed type output. The first method finds the existent MediaTypewith
the needed parameters, or uses the default type with number 0. Grabbing images from MediaSourcestarts by first calling
VI>isFrameNew(i1). After calling this method, the raw data can be gotten by the method VI>getPixels(i1,
(unsignedchar*)frame>imageData,false). Parameters of the video camera can be got by calling the method
VI>getParametrs(i1). The new parameters can be set by the method VI>setParametrs(i1,CP). The method of
closing of the device VI>closeDevice(i1) stops the thread of grabbing and releases the context of the video device. The
example shows fast using, stopping, and reusing of the same video device. The global function StopEvent(intdeviceID,void
*userData) is used as a callback function in the method VI>setEmergencyStopEvent(i1,NULL,StopEvent).
This function is called in the case of unexpected stopping - e.g., removing web-camera from the USB socket.
10/27/2015 2:51 PM
6 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
The second example is based on the SimpleCaptureexample from the Windows SDK (this code - SimpleCaptureVS2012.zip,
application - SimpleCapture-exe.zip). This example is too big for listing, but I can describe several differences from the original one. Firstly,
I removed all the original linking for the web-camera and set the videoInputlibrary.
Secondly, I included the the second dialog for choosing a suitable resolution from the list of supported Media Types. It is important to
mention that the interface IMFMediaSource ought not be stopped manually. It is released by calling the function
closeDevice(unsignedintdeviceID).
10/27/2015 2:51 PM
7 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
I have spent much time on searching for suitable information on the Microsoft website for developers and I have not gotten help from
experts in that site. And I was not alone in searching for a solution for this problem. I was surprised that the problem of using a
web-camera with Media Foundation was not presented, and I hope that my tip will become a useful contribution on this site.
This article, along with any associated source code and files, is licensed under
The Code Project Open License (CPOL)
Evgeny Pereguda
Software Developer
Australia
No Biography provided
10/27/2015 2:51 PM
8 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
Spacing
Compact
Go
Per page 50
Update
nbugalia
6-Apr-15 8:38
Hello Evgeny,
First of all, thanks a lot for this wonderful code.
This code works well on vs2012 x86 but does not compile under x64 settings due to assembly instructions used in
videoinput.cpp file.
Can you suggest modifications to make it usable on x64 platform ?
Nishant
Evgeny Pereguda
8-Apr-15 21:51
Hi,
I could advice you to see the new version of this project on link: Capturing Live-video from Web-camera on Windows 7 and
Windows 8. In the comments you will find the solution for your problem with compiling on x64.
With best,
Evgeny
tttk
16-Feb-15 20:00
Thanks for your code, I can run my webcam in tablet PC, win8.
However, just like android and ios, users can pinch and zoom the camera output, we hope it can be done with Media Foundation.
I found a Parameter named Zoom, and an API of setParameter. But, it seems not work when I set the zoom's currentValue.
I really want to know how to do. Thanks any way.
To do, to best.
Evgeny Pereguda
17-Feb-15 4:58
Hi,
Firstly, I would like to recommend you an new article: Capturing Live-video from Web-camera on Windows 7 and Windows 8.
The new vesion of code is more stable and has partition on C# - WPF.
Secondly, zooming can have only expensive cameras - I recommend to check the documentation of you tablet PC.
Thirdly, You can check the accessebility of the parameter by checking the Parametr variable Flag after execution
command getParametrs - it has value 0x0001 for auto, 0x0002 for manual, and 0x0000 for non-accessebile
parameter.
With best.
Sign In View Thread Permalink
johnbMA
24-Nov-14 17:45
10/27/2015 2:51 PM
9 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
Evgeny Pereguda
25-Nov-14 12:22
Hi John,
I can give some perks
I would like to advise you to use my new article about capturing video from web-cam: Capturing Live-video from
Web-camera on Windows 7 and Windows 8.
There are some reasons, why it would be better to use the new article:
1. The current article was published about a one and half year ago - the new one was published a half year ago.
2. I have read a book which you mentioned in your mail, and it has inspired me to rewrite all old code - some patterns from
the book you can find in the code.
3. The new code is written with using of Test Driven Development pattern - any important section of code which connects
with Media Foundation (MF) is tested. It contains about 50 tests.
4. The new code returns the result of working with MF in form of enum constant - it contains about 50 constants, which cover
almost all exception with MF.
5. The new code executes only grabbing of frames - there is not any connection with IMFPMediaPlayer interface.
6. The new code can work in synchronize and asynchronize modes: in the first mode of the controlling thread is stopped until
the frame is gotten from the web-cam or the time out is reached, in the second mode if the frame is not gotten the
controlling thread is just leave the calling method.
7. The new code allows to set one of three output color formats
Hide Copy Code
enumVideoFormat
{
RGB24=0,
RGB32=1,
AYUV=2
};
10/27/2015 2:51 PM
10 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
johnbMA
25-Nov-14 20:02
Hi Evgeny:
Thank you so much for your prompt response.
I've been trying to immerse myself in the world of sinks, nodes, and topologies.
I'm eagerly awaiting the book so I can a basic understanding of the framework.
I will start looking at your suggestions tomorrow.
Happy Thanksgiving wishes to you.
I'll let you know how I make out.
Thanks,
JB
Sign In View Thread Permalink
ambikaksm
13-Oct-14 2:03
Hi,
I have seen your SampleCapture application.You are using MFMediaPlayer concept to switch different resolution.I am beginner to
Media Foundation.
I am using topology to show USB camera device streaming.I have been done to get supported video and still resolutions.Now i
want to change video resolution of the particular camera.Before change resolution,i stopped the preview and disconnect the
topology node.After select the resolution,rebuild the topology with modified media type.Media session MFMediaEvent is
throwing MFError.More over i am not able to switch to high resolution like HD,3MP.
Please help me out from this issue.Give me a sample application to change the video resolution.
Thanks in advance.
Regards,
Ambika
Sign In View Thread Permalink
Evgeny Pereguda
14-Oct-14 1:31
You can see how it work in the SampleCapture code. I cannot understand all list of actions which you execute in the code.
It looks like you try to set the values of resolution which are not defined for your device.
With best regards,
Evgeny
Sign In View Thread Permalink
ambikaksm
11-Nov-14 2:32
Hi,
Thanks for your reply.Both YUY2 and MJPG format supported in my device.
Using IMFMediaTypeHandler::SetCurrentMediaType,i changed resolution and format.After change media type,I could not
see any changes occur on my preview window.Default media type only streaming.
What should i do to affect changes in my application? Please give me a sample application for reference.
Thanks in advance.
With best regards,
Ambika
10/27/2015 2:51 PM
11 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
12-Nov-14 18:07
Evgeny Pereguda
Hi Ambika,
Sorry for a late answer. I cannot understand which resolution you try to set. Is it supported by your device? Look at the
next code how it is done in my code:
Hide Expand
Copy Code
hr after hr=pHandler>SetCurrentMediaType(pType);
ambikaksm
17-Jun-15 4:17
Hi Evgeny,
Sorry for late reply.
I have solved the problem.I'm able to switch all resolutions supported in my usb device.
I'm facing one more problem(i.e)I couldn't capture an image from image stream(still pin).
My video input device contains 2 streams.One is for preview and another one is for still.
Below steps, i have tried to build the topology.
1)Created Presentation descriptor interface.
2)Deselected the preview stream and selected the image stream.
3)Retrieves a stream descriptor for a selected stream in the presentation.
4)Created source node and added it to the topology.
5)Created SampleGrabber sink node and added it to the topology.
6)Connect source and sink node.(Eg: pSourceNode->ConnectOutput(0, pGrabberNode, 0);)
6)Set the topology.
7)After receive TOPOLOGY_STATUS_READY event,i started the session.
8)IMFMediaEvent gives E_INVALIDARG(0x80070057) error.This error is not related to media session.
Can you please tell me,why am i getting this error?Am i missing anything to build the topology?
10/27/2015 2:51 PM
12 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
I have searched many sites regarding this issue,but no luck.Most of them,capturing an image from preview pin,not
from image stream.
Please help me to solve this problem.Sample code is more helpful to solve this.
Thanks in advance.
Regards,
Ambika
Sign In View Thread Permalink
Evgeny Pereguda
18-Jun-15 4:46
Hi,
I understand your problem, and I also faced with it.
However, I could not give you the correct solution.
The fact is that after receiving of TOPOLOGY_STATUS_READY event the topology resolved
correctly, but receiving E_INVALIDARG error means that the instance of MFSession sends sample request
to the MFSource in incorrect way.
Some time ago I wrote two MFSource for project - one for Screen Capturing and another for capturing MJPEG
network broadcasting and spent much time on research of implementation IMFSource, IMFStreamDescriptor,
and other interfaces.
I know that Session sends request and information about time - time stamp, duration, position and others.
In my view the problem is that stream, which is associated with still capture has wrong MajorType MFMediaType_Video.
The fact is that Media Foundation has another MajorType which more suitable for still image MFMediaType_Image.
The different MajorTypes have different schemes of working with MFSource. For example, MFMediaType_Image
type does not have duration and position, and sending such arguments must be considered as error.
So, As I said previously, I do not have the solution, but I can advise to try special software for tracing the Media
Foundation request - mftrack.exe. It can log all requests in the local session of Media Foundation in you
application.
However, In my view there is only way for resolving such problem - write own version of the MFSession - yes it
is very difficult task, but it is the only way to take control over sending request to the MFSource and correct it
for the cases of live video and still image. I do not have other ideas about it, because the error is emitted in the
moment of starting of MFSource.
With best,
Evgeny
RobCC
17-May-14 2:16
Well yes, you make some interesting points, but, for example, Intel did extend x8086 to x80186, to 286,386,4...5... and on,
because code is just code, a code for "add" doesnt need to evolve, but the hardware that runs it can be improved... while
maintaining compatibility!!
DirectShow isnt old, its still very new, it uses COM, it is object-oriented, extendable, and the filters are still be added, the ffdshow
and the new project.
Microsoft could do what Intel did, extend it, improve it, without breaking applications!
But, as you say, exactly as you say, Microsoft dont want users to have direct and powerful control of the hardware for media
apps!
This is horrible news for developers, Microsoft will enslave us to the whims of their marketing hacks for ever!
So support DShow, it works great on Windows 7 and 8, and will work on Windows 9 and 10 even if we have to add the dlls!
Dont let Microsoft walk all over us, thats what I say!
Sign In View Thread Permalink
10/27/2015 2:51 PM
13 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
RobCC
16-May-14 22:20
DirectShow is still supported by Windows 8, problems may occur because of not having the correct codecs installed.
Officially, Microsoft have stated that they are "gradually implementing Media Foundation" with the aim of replacing DirectShow
at some future point, but as of May 2014 Media Foundation is far from ready to replace DirectShow.
Media Foundation will have extensive media rights management support, so that the big content producers can make sure their
movies cannot be copied; this looks like the driving force behind Media Foundation.
The real problem with this sample is that it is very slow, requiring multiple transfers of large frames of video to reach a display
surface.
Under DirectShow, the IAMMultiMediaStream interface support direct capture to an IDirectDrawSurface and supports full frame
rate video capture direct to a surface with very little CPU overhead.
This is meant to be possible with MediaFoundation but I havent been able to compile the MFCapture sample even on Visual
Studio 2012 because of errors that list up.
To Microsoft "If it aint broken, dont fix it!"
Please pressurise Microsoft to support our DirectShow applications indefinitely.
There is no such thing as "old code", look at our DNA, it has the best code in it, perfect code, and its millions of years old. We
dont want to re-invent the wheel just because Microsoft marketing hacks have some "plan" to make more money!
Sign In View Thread Permalink
Evgeny Pereguda
16-May-14 23:39
Hi,
Your ideas are not bad. However, you are missed the last trend of the Microsoft
- creating environment of the Windows Windows Store and Windows RT. It includes protection of media content, protection of access for the devices and others. If
you worked with progamming language Java or C# than you know that "sandbox" is fundament of the them. Powerful
DirestShow with deep access to devices blow up this trend for protection of system. I read the blog of the "Itseez" company
which spent much time on porting OpenCV on ARM Windows RT and find that Media Foundation - is only API for working
on this platform.
"Please pressurise Microsoft to support our DirectShow applications indefinitely." - It is like ask Intel to continue produce
x8086 proc.
Sign In View Thread Permalink
problem
chengweige517
8-May-14 21:59
Hello Evgeny,
when i set up a device, close it, and then set up the same devcie, close it...
Hide Copy Code
for(inti=0;i<100;i++)
{
if(VI>setupDevice(0,640,480,60))
{
VI>closeDevice(0);
Sleep(500);
}
}
i found that the memory has been increased about 40kb every time...
is there any memory block has not been released in closeDevice?
Sign In View Thread Permalink
Re: problem
Evgeny Pereguda
11-May-14 22:04
Hi,
I spent some time on the review of the code and debugging it, but I didn't find any marks of the memory leak. However, you
are right - calling function _CrtDumpMemoryLeaks(); shows memory leak. I think that it a memory leak at the libraries of
VS2012.
10/27/2015 2:51 PM
14 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
int_tmain(intargc,_TCHAR*argv[])
{
_CrtDumpMemoryLeaks();
while(true)
{
charc=cvWaitKey(33);
if(c==27)
break;
}
return 0;
}
Detectedmemoryleaks!
Dumpingobjects>
{310}normalblockat0x0069D890,47byteslong.
Data:<JPEG2000CodeS>4A5045472D3230303020436F64652053
{309}normalblockat0x0069D850,4byteslong.
Data:<jpc>6A706300
{308}normalblockat0x0069D810,4byteslong.
Data:<jpc>6A706300
{307}normalblockat0x0069D7A0,51byteslong.
Data:<JPEG2000JP2Fi>4A5045472D32303030204A5032204669
{306}normalblockat0x0069D760,4byteslong.
Data:<jp2>6A703200
{305}normalblockat0x0069D720,4byteslong.
Data:<jp2>6A703200
{304}normalblockat0x0069D670,56byteslong.
Data:<hyX>689779580000000000000000CDCDCDCD
{303}normalblockat0x0069D2A8,908byteslong.
Data:<>00000000000000000000000080020000
{302}normalblockat0x0069D1F8,56byteslong.
Data:<hyX>689779580000000000000000CDCDCDCD
{301}normalblockat0x0069CE30,908byteslong.
The code does not call any method of the videoInput and Dump pointed on the code which is bound with JPEG-2000 Code.
This dump is showed after loading C:\Windows\SysWOW64\msctf.dll
.
However, if you have another idea or you use another technique for detecting of the memory leak, I would be glad to have
some advised.
P.S.
I just want say that today I have found the great news about my project "videoInput" - it has been included into the open
source project OpenCV - the most power project of the computer vision. They have taken almost 95% of the code and added
some interesting improvements. You can find it on the next link: OpenCV.
For me it is a great Honour.
Evgeny
Re: problem
chengweige517
13-May-14 1:05
Hi
i used the task manager in Win 7, and i found the memory has been increased about 40kb every time
Hide Copy Code
VIDEODEVICE0:Deviceissetuped
VIDEODEVICE0:Deviceisstopped
VIDEODEVICE0:Deviceissetuped
VIDEODEVICE0:Deviceisstopped
10/27/2015 2:51 PM
15 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
VIDEODEVICE0:Deviceissetuped
VIDEODEVICE0:Deviceisstopped
VIDEODEVICE0:Deviceissetuped
VIDEODEVICE0:Deviceisstopped
VIDEODEVICE0:Deviceissetuped
VIDEODEVICE0:Deviceisstopped
...
Memory leaks
chengweige517
16-Apr-14 17:36
Hello Evgeny,
I have some plrblems running the TestvideoInput under Windows 7 OS, i am using the integrated camera, When
countLeftFrames is greater than 60, then it should switch to the next section, that is reusing of the same video device,
but it comes out a message
'Unhandled exception at 0x3183fdac in videoInputTest.exe: 0xC0000005: Access violation reading location 0xfeeefef6'
Then I use the source code for deubug, i find that the code
Hide Copy Code
hr=checkDevice(pAttributes,&vd_pActivate);
has a problem.
I think my problem is the same as sanjeev.567, for function
Hide Copy Code
template<classT>voidSafeRelease(T**ppT)
{
if(*ppT)
{
ULONGe=(*ppT)>Release();
*ppT=NULL;
}
}
the variable e is 4.
The link TestvideoInput[^] is out of date, so would you please help me how to solve the problem, thanks!
Sign In View Thread Permalink
Evgeny Pereguda
22-Apr-14 22:36
Hi,
I am sorry for late with answer.
Thank you for the message with info about memory leak in code. I have corrected the code and the article. You can find new
code by the next link:
videoInputVS2012.zip.
Sign In View Thread Permalink
chengweige517
24-Apr-14 19:30
#if0
if(met==MEVideoCaptureDeviceRemoved)
{
DPO>printOut(L"IMAGEGRABBERVIDEODEVICE%i:MEVideoCaptureDeviceRemoved\n",
ig_DeviceID);
10/27/2015 2:51 PM
16 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
break;
}
#endif
hr=ig_pSession>GetEvent(0,&pEvent);
i don't know if it is the block commented that cause the error, and then
if i use vs2010 and win7 OS, how to solve the macro definition problem? thanks!
Sign In View Thread Permalink
Evgeny Pereguda
24-Apr-14 20:37
Hi,
It is not easy to give you a correct answer because I use vs2012 and Win7 for development projects. However I can
give you some advices:
1. Do you use Windows SDK for you project? I use Windows Kit 8. Almost all headers of Media foundation are part of
Windows SDK (Kit). Try to download the suitable Windows SDK from Microsoft site.
2. MEVideoCaptureDeviceRemoved - is not macro. It is enum in mfobjects.h. You can copy this enum which is given
below in Common.h or just use numerical integral = 800 . This numerical code is generated when video device is
unplugged.
Hide Expand
Copy Code
enum__MIDL___MIDL_itf_mfobjects_0000_0012_0001
{
MEUnknown
=0,
MEError =1,
MEExtendedType =2,
MENonFatalError =3,
MEGenericV1Anchor
=MENonFatalError,
MESessionUnknown
=100,
MESessionTopologySet
=101,
MESessionTopologiesCleared =102,
MESessionStarted
=103,
MESessionPaused =104,
MESessionStopped
=105,
MESessionClosed =106,
MESessionEnded =107,
MESessionRateChanged
=108,
MESessionScrubSampleComplete
=109,
MESessionCapabilitiesChanged
=110,
10/27/2015 2:51 PM
17 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
MESessionTopologyStatus =111,
MESessionNotifyPresentationTime =112,
MENewPresentation
=113,
MELicenseAcquisitionStart
=114,
MELicenseAcquisitionCompleted
=115,
MEIndividualizationStart
=116,
MEIndividualizationCompleted
=117,
MEEnablerProgress
=118,
MEEnablerCompleted =119,
IMAGEGRABBERVIDEODEVICE0:StartGrabbingoftheimages
IMAGEGRABBERVIDEODEVICE0:Stoppingofofgrabbingofimages
IMAGEGRABBERTHREADVIDEODEVICE0:DestroingImageGrabberThread
anerroroccuredat
hr=ig_pSession>GetEvent(0,&pEvent);
After "Stopping of of grabbing of images" the code must generate "MESessionStopped". The code for this
Hide Copy Code
voidImageGrabber::stopGrabbing()
{
if(ig_pSession)
ig_pSession>Stop();
DebugPrintOut*DPO=&DebugPrintOut::getInstance();
DPO>printOut(L"IMAGEGRABBERVIDEODEVICE%i:Stoppingofofgrabbingofimages\n",
ig_DeviceID);
}
where ig_pSession - is current IMESession pointer. Check the value of it by debugging ImageGrabber.cpp.
After calling method
Hide Copy Code
ig_pSession>Stop();
the main thread is slept for 0.5 sec
Hide Copy Code
voidvideoDevice::closeDevice()
{
if(vd_IsSetuped)
{
vd_IsSetuped=false;
vd_pSource>Stop();
if(vd_LockOut==RawDataLock)
{
vd_pImGrTh>stop();
Sleep(500);
vd_pImGrTh.reset(0);
SafeReleaseAllCount(&vd_pSource);
}
SafeRelease(&vd_pSource);
vd_LockOut=OpenLock;
DebugPrintOut*DPO=&DebugPrintOut::getInstance();
DPO>printOut(L"VIDEODEVICE%i:Deviceisstopped\n",vd_CurrentNumber);
}
}
For 0.5 second the code
Hide Copy Code
hr=ig_pSession>GetEvent(0,&pEvent);
10/27/2015 2:51 PM
18 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
if(met==MESessionStopped)
{
DPO>printOut(L"IMAGEGRABBERVIDEODEVICE%i:MESessionStopped\n",ig_DeviceID);
break;
}
and break out from the while loop, and the pointer vd_pSource is released fully Hide Copy Code
SafeReleaseAllCount(&vd_pSource);
. But in your case the while loop is not break out and after the vd_pSource is released fully, the code
Hide Copy Code
hr=ig_pSession>GetEvent(0,&pEvent);
uses the pointer ig_pSession which is released already.
I cannot give you the solving of this problem, but I can advice to you to do a debugging of processing of the pointer
ig_pSession - you compiler generate code, which has invalid process of this pointer.
Evgeny
chengweige517
24-Apr-14 21:23
In debug mode, i checked the code step by step, vd_pSource is NULL after
Hide Copy Code
SafeReleaseAllCount(&vd_pSource);
and then everything is OK, but without debug, the error appeared all the same
I replace the thread sleep time for 1.5 sec, that is
Hide Copy Code
Sleep(1500);
then everything is ok whether it is under debug mode or release mode,
i was wondering is it the sleep time that cause the problem?
Sign In View Thread Permalink
Evgeny Pereguda
24-Apr-14 21:47
Hi,
This problem is not bound with Sleep() function on direct way. The fact is that in the program there is two
threads: thread of the main program, where methods of videoInput are called and thread of grabbing, where
there is code
Hide Copy Code
hr=ig_pSession>GetEvent(0,&pEvent);
. function Sleep(500) is used for synchronization of threads - the grabbing thread must catch the event of
stopping session - MESessionStopped for 0.5 second. I thought that half second is enough for stopping the
session of capturing of device. However. in you case it takes more than 0.5 second. Of course, it would be better
to use mutix or semafor for synchronization of two threads, but I did not have much time on it. And I thought
that these elements of synchronization can make dead block in case of there is not existence of event MESessionStopped. I thought that it would be better to have exception which can be processed by try - catch
than have dead lock of threads. However, I have idea to include these type synchronization.
Evgeny
10/27/2015 2:51 PM
19 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
Evgeny Pereguda
25-Apr-14 0:20
Hi,
I just want say that after some thinking I have made decision that it is not professional to use Sleep() function
for the purpose of synchronization of the threads. I have corrected code and include in it mutex and wait
function. It works OK on my comp. If you want - you can get modificated version on updated page.
Hide Copy Code
if(vd_LockOut==RawDataLock)
{
vd_pImGrTh>stop();
WaitForSingleObject(vd_pImGrTh>getMutexHandle(),5000);
vd_pImGrTh.reset(0);
SafeReleaseAllCount(&vd_pSource);
}
chengweige517
25-Apr-14 3:03
Member 10728526
7-Apr-14 6:48
Evgeny Pereguda
9-Apr-14 3:09
Hi,
I developed the code only for Windows 8 Desktop and I did not work on tablet version.
However, I can say one thing - I am sure on 100% that old code on DirectShow will not work on tablet. The COMPANY invests
much force in Media Foundation framework.
I advise you to debug the code in Visual Studio and direct info on consol.
Sign In View Thread Permalink
jakosek
9-Apr-14 3:49
This is Windows 8 x86 tablet. I'm not interested in metro, only desktop app. DirectShow gives me resolutionn of
448x252px. Before i've tried OpenCV - 640x480 max.
There is no camera in device manager/imaging devices, only Intel ISP 2300. OV2720/OV8830 can be found in system
devices.
Buil-in metro camera app works but i want control it from my program.
Sign In View Thread Permalink
Evgeny Pereguda
9-Apr-14 4:16
You can try to get the list of supported capture format by calling functions:
Hide Copy Code
10/27/2015 2:51 PM
20 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
//Gettingnumbersofformats,whicharesupportedbyvideodevicewithdeviceID
unsigned intgetCountFormats(unsigned intdeviceID);
//Gettingformatwithid,whichissupportedbyvideodevicewithdeviceID
MediaTypegetFormat(unsigned intdeviceID,int unsignedid);
You will get the amount of the supported formats and the inform about of format in structure MediaType.
Sign In View Thread Permalink
Heinrich Lwe
27-Jan-14 6:41
Thank you so much for this library, it works pretty well and saves so much time.
I found one little quirk so far which caused some confuison to me: While changing camera/video parameters i noticed, that the
getParametrs method always sets the current values to the default value. Is this behaviour intended?
Cheers,
Heinrich.
Sign In View Thread Permalink
Evgeny Pereguda
27-Jan-14 12:21
Hi,
Thank you for your message. About camera/video parameters - yes, it is little error. I found it in my projects and resolve.
You can do it in file videoDevice in method CamParametrs videoDevice::getParametrs() - you can change
pProcAmp->GetRange( on pProcAmp->Get(
With best regard,
Evgeny
Sign In View Thread Permalink
5.00/5 (1 vote)
Member 10541568
23-Jan-14 12:28
1.00/5 (1 vote)
Evgeny Pereguda
24-Jan-14 21:32
Hi,
In my projects I worked with many webcams and It was ok. I had the similar problems, when attached USB TVtuner. I can
advice to you to debug the code of the methods HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID
VideoFormat) and HRESULT ImageGrabber::startGrabbing(void) of ImageGrabber class. If it is ok, then in console you must
get "IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images". If it is not, then the grabbing is not launched.
Sign In View Thread Permalink
Member 10541568
25-Jan-14 0:44
Hi Evheny,
Thank you for you fast answer !
In the debugger I see, that there are 2 attempts to start capturing - with 2 resolutions: 640x480 & 1920x1080, and both
fails.
10/27/2015 2:51 PM
21 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
I've changed slightly the running code, and I know, that "HD Pro Webcam C920" (index 0) is used for capturing attempt.
The following are console output I see:
Member 10381522
2-Dec-13 4:02
I notice that after a short time (~3500 tries), the isFrameNew functions always returns true.
Not sure why that is.
Also, if you are looking for suggestions, I would add the ability to report the Symbolic Link.
10/27/2015 2:51 PM
22 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
That is a unique ID for each camera which will allow you to tie cameras to calibration when there is more than one camera.
Sign In View Thread Permalink
Member 10381522
6-Nov-13 19:45
Thanks very much for this as I had been using videoInput and having strange problems related to Windows 8.
Your link to code with modifications directed to memory leaks does not work an longer.
Could you provide a new link to the updated code that works?
Thanks again
Sign In View Thread Permalink
Capture to File
Member 9960263
2-May-13 11:07
Hello Evgeny,
This software also runs in Windows 7. Very nice and useful software. Well done!
I was wondering how difficult it would be to save the capture to .avi file on the hard disk. Would this be easy to do? I don't have
much experience with Windows programming. Do you have any suggestions?
Thanks!
Sign In View Thread Permalink
Evgeny Pereguda
2-May-13 18:22
Hi,
If you want only to save video from camera into video file, you can take example from Microsoft developer site. The
name of this example is 'MFCaptureToFile'. This example capture live video into video file with of two coders: mp4 or wmv. I
compiled this example, and you can try it by this link
MFCaptureToFile.exe
This link on source of this example
MFCaptureToFile.zip
If you want to use avi coder than you need additional code from any open source developer.
With best regard,
Evgeny
Sign In View Thread Permalink
sanjeev.567
15-Apr-13 14:38
Hello,
Thanks a lot of this fine example of code.
I'm using it to grab frames using VI->getPixels and showing them using a CBitmap. Its works fine but the while loop freezes up
the window. So I use OnTimer to get the frames. This also works, except there are some memory leaks.
I found and fixed the leaks due to not deleting the RawImage *ig_RIFirst; *ig_RISecond; *ig_RIOut; on close, but there is still a leak
of 12 Bytes after close. (And it keeps taking memory while running). I guess there is something in Imagegrabber instance which is
leaking, but I couldn't find it.
Can you please help, where is the problem ? Thanks...
Sign In View Thread Permalink
Evgeny Pereguda
16-Apr-13 1:41
Hi sanjeev.567
,
I does not tested this code on leaking of memory. I have used singleton in the code for correct work with COM system
of Media Foundation. I would like to thank you for marking of this kind of problem. I will try to find the source of the
problem, but I can advice you to use std::auto_ptr for correct working with classes, which are created in the heap.
10/27/2015 2:51 PM
23 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
Member 9649062
24-Apr-13 4:26
It seems that the problem is with the setupDevice or closeDevice methods. My application leaks memory everytime
setupDevice and closeDevice are called. Thanks for the lib Evgeny, if you ever find the source of the leak, please let us
know.
With best regards from Brazil
Sign In View Thread Permalink
Evgeny Pereguda
26-Apr-13 1:08
Hi. I am glad that you pointed my attention on the fact of memory leak. I do not have any experience of resolving
such problems and I would like to get some advices about it. However, I can give you some my ideas about the
reasons of this memory leak. Firstly, the code can have the problems with objects which are created in the heap. As a
result, I have wrapped such objects into smart pointers std::auto_ptr - I think it will solve the problem. Secondly, I think
that working with COM objects of Media Foundation through can be the reason of memory leak. The fact is that when
the method closeDevice() of videoDevice is called COM interface IMFMediaSource *vd_pSource is not released, and
variable e is not zero (I found it 4).
Hide Copy Code
ULONGe=vd_pSource>Release();
It means that this interface is not deleted from heap. And the problem is that in the code many interfaces are created
from vd_pSource, and it is not easy to understand when it is copy of the original interface or transforming to the
parent interface or creating of new objects in the heap. As a result, it makes real hell. For resolving this problem I
include in code global function SafeReleaseAllCount, which enumerate counter of the interface. When counter reach 0
object of the pointer is released.
Hide Copy Code
template<classT>voidSafeReleaseAllCount(T**ppT)
{
if(*ppT)
{
ULONGe=(*ppT)>Release();
while(e)
{
e=(*ppT)>Release();
}
*ppT=NULL;
}
}
I rewrote the code of videoInput and posted it there TestvideoInput.
I hope it will help you.
With best regards.
From Russia with love
Evgeny Pereguda
5.00/5 (1 vote)
Oldtimer88
15-Apr-13 6:55
hi Mr. Pereguda,
I am a neophyte in terms of coding, etc.
I found the title very interesting,,,,, but at the end, how could I use everything you said and put it to work in my Windows 8 PC, as
a practical new application or usage?
Or perhaps this is a theoretical exercise for your equals to appreciate and expand further?
10/27/2015 2:51 PM
24 of 24
http://www.codeproject.com/Tips/559437/Capturing-Video-from-Web-c...
Please advice.
Sign In View Thread Permalink
16-Apr-13 1:18
Evgeny Pereguda
Hi, Oldtimer88
I wrote my article about capturing of video after development my project of Augment Reality. The code in the article is
used in my project, and everyone can use this code when he/she needs, but I CANNOT give you the code of my project. If
you are interested of using of processing of live video then I can advise to read book about OpenCV - Open source
framework for Computer Vision (the project of Intel). It includes code for recognition images and code for artificial intellect
(neuron networks, fuzzy sets, i.e). You can find this book on this link Learning_OpenCV. You can use the code of this article for
development of glass likes Google Glass, or open alternative of Skype-Microsoft. You can find many examples of code of the
recognition of face, which is based on OpenCV, on the Internet. However, for all these you will need code for capturing of
video, and the fact is that old code for video capturing which use DirectShow is not works well on Windows 8. New OS uses
new technology (Media Foundation).
Sign In View Thread Permalink
31-Mar-13 21:22
mightypanda
Hello Evgeny,
thank you very much, MediaFoundation samples are so rare, and this library is really handy!
I have a question: do you think it would be simple enough to create a general-purpose grabber of any video stream?
Similarly to the SampleGrabber in DirectShow, so the mediafile playing at its speed with sound etc, and a callback to grab every
individual frame in uncompressed format.
I guess MediaFoundation uses sinks for that but, also in this case, working examples are rare.
Thank you
Stefano
Sign In View Thread Permalink
5.00/5 (1 vote)
1-Apr-13 23:30
Evgeny Pereguda
Hello Stefano,
I think that it is possible create the one grabber for all media sources, but it would take too much time (my project of
Augment Reality keeps me very busy). I am glad that rated this article so high.
With best regards,
Evgeny
Sign In View Thread Permalink
News
Question
Refresh
Bug
Answer
Select Language
Joke
Layout: fixed |
fluid
Praise
Rant
Admin
Article Copyright 2013 by Evgeny Pereguda
Everything else Copyright CodeProject, 1999-2015
10/27/2015 2:51 PM