|
Hello Evgeny,
when i set up a device, close it, and then set up the same devcie, close it...
for (int i = 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?
|
|
|
|
|
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.
I have written the simple code WITHOUT using of videoInput
int _tmain(int argc, _TCHAR* argv[])
{
_CrtDumpMemoryLeaks();
while(true)
{
char c = cvWaitKey(33);
if(c == 27)
break;
}
return 0;
}
And I have got the next output listing
Detected memory leaks!
Dumping objects ->
{310} normal block at 0x0069D890, 47 bytes long.
Data: <JPEG-2000 Code S> 4A 50 45 47 2D 32 30 30 30 20 43 6F 64 65 20 53
{309} normal block at 0x0069D850, 4 bytes long.
Data: <jpc > 6A 70 63 00
{308} normal block at 0x0069D810, 4 bytes long.
Data: <jpc > 6A 70 63 00
{307} normal block at 0x0069D7A0, 51 bytes long.
Data: <JPEG-2000 JP2 Fi> 4A 50 45 47 2D 32 30 30 30 20 4A 50 32 20 46 69
{306} normal block at 0x0069D760, 4 bytes long.
Data: <jp2 > 6A 70 32 00
{305} normal block at 0x0069D720, 4 bytes long.
Data: <jp2 > 6A 70 32 00
{304} normal block at 0x0069D670, 56 bytes long.
Data: <h yX > 68 97 79 58 00 00 00 00 00 00 00 00 CD CD CD CD
{303} normal block at 0x0069D2A8, 908 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 80 02 00 00
{302} normal block at 0x0069D1F8, 56 bytes long.
Data: <h yX > 68 97 79 58 00 00 00 00 00 00 00 00 CD CD CD CD
{301} normal block at 0x0069CE30, 908 bytes long.
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
|
|
|
|
|
Hi
i used the task manager in Win 7, and i found the memory has been increased about 40kb every time
VIDEODEVICE 0: Device is setuped
VIDEODEVICE 0: Device is stopped
VIDEODEVICE 0: Device is setuped
VIDEODEVICE 0: Device is stopped
VIDEODEVICE 0: Device is setuped
VIDEODEVICE 0: Device is stopped
VIDEODEVICE 0: Device is setuped
VIDEODEVICE 0: Device is stopped
VIDEODEVICE 0: Device is setuped
VIDEODEVICE 0: Device is stopped
...
|
|
|
|
|
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
hr = checkDevice(pAttributes, &vd_pActivate);
has a problem.
I think my problem is the same as sanjeev.567, for function
template <class T> void SafeRelease(T **ppT)
{
if (*ppT)
{
ULONG e = (*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!
|
|
|
|
|
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.
|
|
|
|
|
Thanks for your reply.
I download the latest source files from http://www.codeproject.com/KB/audio-video/559437/videoInputVS2012.zip
for Win7 OS and vs2010, there is no definition for macro 'MEVideoCaptureDeviceRemoved', so i just comment the block
#if 0
if (met == MEVideoCaptureDeviceRemoved)
{
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID);
break;
}
#endif
then i run the TestVideoInput project,
***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****
VIDEOINPUT SPY MODE!
SETUP: Looking For Capture Devices
SETUP: 0) Integrated Camera
SETUP: 1 Device(s) found
VIDEODEVICE 0: Device is setuped
IMAGEGRABBER VIDEODEVICE 0: Creating instance of ImageGrabber
IMAGEGRABBERTHREAD VIDEODEVICE 0: Initialization of instance of the ImageGrabber
class
IMAGEGRABBERTHREAD VIDEODEVICE 0: Creating of the instance of ImageGrabberThread
IMAGEGRABBERTHREAD VIDEODEVICE 0: Thread for grabbing images is started
IMAGEGRABBER VIDEODEVICE 0: Start Grabbing of the images
IMAGEGRABBER VIDEODEVICE 0: Stopping of of grabbing of images
IMAGEGRABBERTHREAD VIDEODEVICE 0: Destroing ImageGrabberThread
an error occured at
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!
|
|
|
|
|
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.
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,
MESessionTopologyStatus = 111,
MESessionNotifyPresentationTime = 112,
MENewPresentation = 113,
MELicenseAcquisitionStart = 114,
MELicenseAcquisitionCompleted = 115,
MEIndividualizationStart = 116,
MEIndividualizationCompleted = 117,
MEEnablerProgress = 118,
MEEnablerCompleted = 119,
MEPolicyError = 120,
MEPolicyReport = 121,
MEBufferingStarted = 122,
MEBufferingStopped = 123,
MEConnectStart = 124,
MEConnectEnd = 125,
MEReconnectStart = 126,
MEReconnectEnd = 127,
MERendererEvent = 128,
MESessionStreamSinkFormatChanged = 129,
MESessionV1Anchor = MESessionStreamSinkFormatChanged,
MESourceUnknown = 200,
MESourceStarted = 201,
MEStreamStarted = 202,
MESourceSeeked = 203,
MEStreamSeeked = 204,
MENewStream = 205,
MEUpdatedStream = 206,
MESourceStopped = 207,
MEStreamStopped = 208,
MESourcePaused = 209,
MEStreamPaused = 210,
MEEndOfPresentation = 211,
MEEndOfStream = 212,
MEMediaSample = 213,
MEStreamTick = 214,
MEStreamThinMode = 215,
MEStreamFormatChanged = 216,
MESourceRateChanged = 217,
MEEndOfPresentationSegment = 218,
MESourceCharacteristicsChanged = 219,
MESourceRateChangeRequested = 220,
MESourceMetadataChanged = 221,
MESequencerSourceTopologyUpdated = 222,
MESourceV1Anchor = MESequencerSourceTopologyUpdated,
MESinkUnknown = 300,
MEStreamSinkStarted = 301,
MEStreamSinkStopped = 302,
MEStreamSinkPaused = 303,
MEStreamSinkRateChanged = 304,
MEStreamSinkRequestSample = 305,
MEStreamSinkMarker = 306,
MEStreamSinkPrerolled = 307,
MEStreamSinkScrubSampleComplete = 308,
MEStreamSinkFormatChanged = 309,
MEStreamSinkDeviceChanged = 310,
MEQualityNotify = 311,
MESinkInvalidated = 312,
MEAudioSessionNameChanged = 313,
MEAudioSessionVolumeChanged = 314,
MEAudioSessionDeviceRemoved = 315,
MEAudioSessionServerShutdown = 316,
MEAudioSessionGroupingParamChanged = 317,
MEAudioSessionIconChanged = 318,
MEAudioSessionFormatChanged = 319,
MEAudioSessionDisconnected = 320,
MEAudioSessionExclusiveModeOverride = 321,
MESinkV1Anchor = MEAudioSessionExclusiveModeOverride,
MECaptureAudioSessionVolumeChanged = 322,
MECaptureAudioSessionDeviceRemoved = 323,
MECaptureAudioSessionFormatChanged = 324,
MECaptureAudioSessionDisconnected = 325,
MECaptureAudioSessionExclusiveModeOverride = 326,
MECaptureAudioSessionServerShutdown = 327,
MESinkV2Anchor = MECaptureAudioSessionServerShutdown,
METrustUnknown = 400,
MEPolicyChanged = 401,
MEContentProtectionMessage = 402,
MEPolicySet = 403,
METrustV1Anchor = MEPolicySet,
MEWMDRMLicenseBackupCompleted = 500,
MEWMDRMLicenseBackupProgress = 501,
MEWMDRMLicenseRestoreCompleted = 502,
MEWMDRMLicenseRestoreProgress = 503,
MEWMDRMLicenseAcquisitionCompleted = 506,
MEWMDRMIndividualizationCompleted = 508,
MEWMDRMIndividualizationProgress = 513,
MEWMDRMProximityCompleted = 514,
MEWMDRMLicenseStoreCleaned = 515,
MEWMDRMRevocationDownloadCompleted = 516,
MEWMDRMV1Anchor = MEWMDRMRevocationDownloadCompleted,
METransformUnknown = 600,
METransformNeedInput = ( METransformUnknown + 1 ) ,
METransformHaveOutput = ( METransformNeedInput + 1 ) ,
METransformDrainComplete = ( METransformHaveOutput + 1 ) ,
METransformMarker = ( METransformDrainComplete + 1 ) ,
MEByteStreamCharacteristicsChanged = 700,
MEVideoCaptureDeviceRemoved = 800,
MEVideoCaptureDevicePreempted = 801,
MEReservedMax = 10000
} ;
3. About error when stopping.
IMAGEGRABBER VIDEODEVICE 0: Start Grabbing of the images
IMAGEGRABBER VIDEODEVICE 0: Stopping of of grabbing of images
IMAGEGRABBERTHREAD VIDEODEVICE 0: Destroing ImageGrabberThread
an error occured at
hr = ig_pSession->GetEvent(0, &pEvent);
After "Stopping of of grabbing of images" the code must generate "MESessionStopped". The code for this
void ImageGrabber::stopGrabbing()
{
if(ig_pSession)
ig_pSession->Stop();
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID);
}
where ig_pSession - is current IMESession pointer. Check the value of it by debugging ImageGrabber.cpp.
After calling method
ig_pSession->Stop(); the main thread is slept for 0.5 sec
void videoDevice::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: Device is stopped \n", vd_CurrentNumber);
}
}
For 0.5 second the code
hr = ig_pSession->GetEvent(0, &pEvent);
must generate pEvent with num code
if (met == MESessionStopped)
{
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID);
break;
}
and break out from the while loop, and the pointer vd_pSource is released fully -
SafeReleaseAllCount(&vd_pSource); . But in your case the while loop is not break out and after the vd_pSource is released fully, the 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
|
|
|
|
|
In debug mode, i checked the code step by step, vd_pSource is NULL after
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
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?
|
|
|
|
|
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
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
modified 25-Apr-14 3:55am.
|
|
|
|
|
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.
if(vd_LockOut == RawDataLock)
{
vd_pImGrTh->stop();
WaitForSingleObject(vd_pImGrTh->getMutexHandle(), 5000);
vd_pImGrTh.reset(0);
SafeReleaseAllCount(&vd_pSource);
}
|
|
|
|
|
thanks a lot, i will have a try.
|
|
|
|
|
After more and more reaserch i found that site.
BUT still i can't pass 640x480 resolution. Is it possible to get full resolution with this lib on Windows 8 tablet with Intel ISP?
|
|
|
|
|
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.
|
|
|
|
|
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.
|
|
|
|
|
You can try to get the list of supported capture format by calling functions:
unsigned int getCountFormats(unsigned int deviceID);
MediaType getFormat(unsigned int deviceID, int unsigned id);
You will get the amount of the supported formats and the inform about of format in structure MediaType.
|
|
|
|
|
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.
|
|
|
|
|
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
|
|
|
|
|
I've successfully compiled & linked TestvideoInput & videoInput.
It does successfully find all cameras connected to my laptop (I have built in and 2 others connected via USB ports).
But it fails to grab the frames: the check of VI->isFrameNew() returns false all the time, countLeftFrames is being increased more than 60 and application is being finished.
The camera I tried to use is definitely OK: I can use it by Skype.
My impression is, that in my case your videoInput misses some phase of camera initialization, as when it works with Skype, it has its activity indicator on, but with TestvideoInput it is off.
I see on console report "VIDEODEVICE 0: Device is setuped", so it seems to be OK ...
What could be the reason, what is missed ? What could you recommend to check ?
|
|
|
|
|
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.
|
|
|
|
|
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.
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:
***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****
VIDEODEVICE 2: IMFMediaSource interface cannot be created
VIDEOINPUT SPY MODE!
SETUP: Looking For Capture Devices
SETUP: 0) HD Pro Webcam C920
SETUP: 1) Integrated Camera
SETUP: 2) (null)
SETUP: 3 Device(s) found
VIDEODEVICE 0: Device is setuped
IMAGEGRABBER VIDEODEVICE 0: Creating instance of ImageGrabber
IMAGEGRABBERTHREAD VIDEODEVICE 0: Initialization of instance of the ImageGrabber class
IMAGEGRABBERTHREAD VIDEODEVICE 0: Creating of the instance of ImageGrabberThread
IMAGEGRABBERTHREAD VIDEODEVICE 0: Thread for grabbing images is started
IMAGEGRABBER VIDEODEVICE 0: Start Grabbing of the images
IMAGEGRABBER VIDEODEVICE 0: Stopping of of grabbing of images
IMAGEGRABBER VIDEODEVICE 0: MESessionStopped
IMAGEGRABBER VIDEODEVICE 0: Finish startGrabbing
IMAGEGRABBERTHREAD VIDEODEVICE 0: Finish thread
IMAGEGRABBERTHREAD VIDEODEVICE 0: Destroing ImageGrabberThread
IMAGEGRABBER VIDEODEVICE 0: Destroing instance of the ImageGrabber class
VIDEODEVICE 0: Device is stopped
VIDEODEVICE 0: Device is setuped
IMAGEGRABBER VIDEODEVICE 0: Creating instance of ImageGrabber
IMAGEGRABBERTHREAD VIDEODEVICE 0: Initialization of instance of the ImageGrabber class
IMAGEGRABBERTHREAD VIDEODEVICE 0: Creating of the instance of ImageGrabberThread
IMAGEGRABBERTHREAD VIDEODEVICE 0: Thread for grabbing images is started
IMAGEGRABBER VIDEODEVICE 0: Start Grabbing of the images
IMAGEGRABBER VIDEODEVICE 0: Stopping of of grabbing of images
IMAGEGRABBER VIDEODEVICE 0: MESessionStopped
IMAGEGRABBER VIDEODEVICE 0: Finish startGrabbing
IMAGEGRABBERTHREAD VIDEODEVICE 0: Finish thread
IMAGEGRABBERTHREAD VIDEODEVICE 0: Destroing ImageGrabberThread
IMAGEGRABBER VIDEODEVICE 0: Destroing instance of the ImageGrabber class
VIDEODEVICE 0: Device is stopped
***** CLOSE VIDEOINPUT LIBRARY - 2013 *****
Press any key to continue . . .
=================================
By the way, on Windows 8.1 I can successfully run the very simple sample taken from MS site (it captures and shows on the screan the stream from the camera):
http://code.msdn.microsoft.com/windowsdesktop/Media-Foundation-Capture-78504c83
It has the UI very similar that you provided.
Currently I debug and learn this sample.
|
|
|
|
|
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.
That is a unique ID for each camera which will allow you to tie cameras to calibration when there is more than one camera.
|
|
|
|
|
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
|
|
|
|
|
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!
|
|
|
|
|
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
|
|
|
|
|
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...
|
|
|
|
|