|
IBaseFilter* SampleGrabber;
HRESULT hr;
SampleGrabber = new CSampleGrabber(Null, &hr, FALSE);
m_pFilterGraph->AddFilter(SampleGrabber, L"Grabber Filter");
this method i did before. but my callback function wasn't called
,so i couldn't get data and save it to disk.
|
|
|
|
|
SampleGrabber = new CSampleGrabber(Null, &hr, FALSE);
m_pFilterGraph->AddFilter(SampleGrabber, L"Grabber Filter");
SampleGrabber->QueryInterface( IID_ISampleGrabber, (void**)&m_pISampleGrabber );
I'm not sure why your callback function didn't work. Apparently, I used the above method and it seemed to work. Did you forget to register Callback with:
m_pISampleGrabber->RegisterCallback( m_ManagedCallback );
Also remember to pass in a valid callback function inside m_ManagedCallback.
|
|
|
|
|
the code about samplegrabber filter is
IBaseFilter *pGrabberF;
ISampleGrabber *pGrabber;
pGrabberF = new CSampleGrabber(NULL, &hr, FALSE);
hr = pGrabberF->QueryInterface(IID_IGrabberSample,
(void **)&pGrabber);
hr = pGrabber->SetCallback(&callback);
i know callback functon is called by transform method. the question is
method transofrm isn't called, so it results callback function isn't executed. it's too weird to understand.
|
|
|
|
|
hi, angle
i wrote a program as following your example.
but there are errors like
error LNK2001: unresolved external symbol CLSID_SampleGrabber
error LNK2019: unresolved external symbol "public: __cdecl CTransInPlaceFilter::CTransInPlaceFilter(wchar_t *,struct IUnknown *,struct _GUID const &,long *)" (??0CTransInPlaceFilter@@QAA@PA_WPAUIUnknown@@ABU_GUID@@PAJ@Z) referenced in function "public: __cdecl MYSampleGrabber::MYSampleGrabber(struct IUnknown *,long *,int)
error LNK2001: unresolved external symbol "public: virtual unsigned long __cdecl CBaseFilter::NonDelegatingRelease(void)
my development environment is:
vs 2008
winmobile 6 sdk
could your tell me reasons. thanks in advance.
best regards,
sword
|
|
|
|
|
for error LNK2001, possible causes are:
1. initguid.h is defined twice. The compiler most likely doesn't understand which GUID to use.
2. If you are registering the samplegrabber as a DLL, then you might have forgotten to set it to be a DLL. Go to Project Properties->Configuration Properties->Deployment->Register Output to Yes.
for error LNK2019: It is caused by error LNK2001. The external symbol refers to the CLSID_SampleGrabber. If you solve error LNK2001, error 2019 won't occur.
For error LNK2001, possible solutions are:
1. Go to Project Properties->C/C++, set wchar_t as Built-in Type to "No"
2. If you are running in debug mode, make sure that in your Project Properties->Linker->Additional Dependencies, you have added strmbase.lib and not strmbasd.lib.
3. In your SampleGrabber.cpp, include this few lines of code:
#ifdef _DEBUG
#define DEBUG_OUTPUT(debugstring) \
OutputDebugString(debugstring)
#else
#define DEBUG_OUTPUT(debugstring)
#endif
or
ULONG CBaseFilter::NonDelegatingRelease(void)
{
return 1;
}
modified on Wednesday, April 28, 2010 10:41 PM
|
|
|
|
|
your adivce is really much appreciated.
errors disappaered.
now i have encounted another problem. this is partial code as:
IGraphBuilder *pGraph;
IBaseFilter *pGrabberF;
ISampleGrabber *pGrabber;
// create the Sample Grabber filter.
1) hr = CoCreateInstance( CLSID_GrabberSample, NULL, CLSCTX_INPROC,
IID_IBaseFilter, (void**)&pGrabberF);
if(FAILED(hr))
goto done;
2) hr = pGraph->AddFilter(pGrabberF, L"Sample Grabber");
if(FAILED(hr))
goto done;
//get a point to the interface
hr = pGrabberF->QueryInterface(IID_IGrabberSample, (void **)&pGrabber);
if(FAILED(hr))
goto done;
i just want to instantiate pGrabberF. the fact is that it always fails in
step 1 in debug modle.could help me kill the problem.
thanks a lot!
|
|
|
|
|
Hi Angel,
First of all, thank you very much for the article & code.
Well...I just want to set HWND to main window, that video gets rendered on complete window.
I am trying to use (1) your code to render the video and (2) OpenGL to render a 3D cube into it(overlay on the video). 3D cube is getting rendered on the main window and I passed my window hwnd through Init() and also verified that it is going till graphManager. But video is still getting rendered on your defined window.
I am going crazy...am I missing anything on this?
Thanks again.
-Big D
|
|
|
|
|
Hi,
no you are not going crazy There are actually 2 separate windows where the video is rendered on. One is the picturebox on the main window, and the second is a preview window started from DirectShow. You would want to shut this off.
Regards,
Angel
|
|
|
|
|
Thanks. Really appreciate your support, its long time since you wrote the code.
2 new discusssions..
#1 The video on the picturebox seems like a part of main video, and it looks like that part is actually zoomed. Are we not getting the complete buffer, along with height & width?
#2 In my HTC Kaiser the video is coming when I compiled in DEBUG mode, but not when DLL is compiled in release mode!
Any idea?
|
|
|
|
|
Hi Big D,
#1 - yes, you are getting the complete buffer, with height and width. It might seem a bit distorted due to the size of the picturebox.
#2 - this is something I struggled a lot with and hadn't been able to fix.
Regards,
Angel
|
|
|
|
|
Angel Kafazov wrote: Hi,
no you are not going crazy Smile There are actually 2 separate windows where the video is rendered on. One is the picturebox on the main window, and the second is a preview window started from DirectShow. You would want to shut this off.
Regards,
Angel
Hello,
first of all I would like to thank you for the great code. It's very helpful for me. Could you tell me how can I disable preview window started from DirectShow? I would like to see and use only picturebox. I googled and tried different code samples but preview window is still here. Please help.
Thank you very much!
Regards,
Marko
|
|
|
|
|
If you want to make the preview invisible, change the following code inside CGraphManager::StartCaptureFramesInternal()
CHK (pVideoWindow->put_Visible(OATRUE));
To
CHK(pVideoWindow->put_Visible(OAFALSE));
However, the processing power will not be reduced in such cases. It would be best to create your own null renderer and attach it in the following line in CGraphManager::CreateCaptureGraphInternal():
Change:
CHK(m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_VIDEO, m_pVideoCaptureFilter, pH263Transform, NULL) ;
To
CHK(m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_VIDEO, m_pVideoCaptureFilter, pH263Transform, /*YOUR NULL RENDERER HERE */) ;
after which, you can comment all the lines with regards to pVideoWindow in the CGraphManager::StartCaptureFramesInternal() since the default video renderer will not be used.
modified on Wednesday, April 28, 2010 11:12 PM
|
|
|
|
|
I have find the problem on my HTC HD2. The preview picture is rotated by 90 degrees. Has anyone met with this problem and is there any solution?
|
|
|
|
|
2 solutions to the problem:
1. If you are using your program in landscape mode, you can create a custom transInPlace filter that unsets the BI_SRCPREROTATE flag in your GetMediaType method. This will let the camera know that the phone is in the same orientation as the camera.
2. If you are using your program in potrait mode, you have to create a transform filter. In your transform method, you need to transpose your image inside there. From my experience, there is no easy solution for rotating preview if u are using potrait mode.
modified on Wednesday, April 28, 2010 11:11 PM
|
|
|
|
|
Hi Angel,
First of all, thank you for this DS filter code that you have given us. It is much appreciated!
I have read the faq forum, and have seen some questions about running this program under WM5.
However, I haven't seen anyone yet posting that de SampleGrabber worked under WM5.
I am now trying to get it to work under WM5, but I ran into an error I can't seem to resolve.
It happens inside the CreateBitmap method.
The moment CopyBitmap(ptrDst, ptrSrc, dstStride, srcStride, m_Height) is executed, I receive the error:
Error: ExceptionCode: 0x0000005
ExceptionAddress: 0x03fb2928
Reading: 0x0028d000
Everything else seems to run just fine (the preview works)
Have you got any idea what this error could be?
tnx,
Andre
|
|
|
|
|
It looks like CopyBitmap read from an invalid location. Check the datatype of the stream you are getting, what is the format of the frames? You can read more about copying video frames in the Windows Mobile SDK Documentation.
|
|
|
|
|
Figured out what the problem was:
In the application i clicked the start button before clicking the callback button.
This prevented the callback to the OnMediaTypeSet function to occur, which prevented the correct settings of the height, width, size and stride values.
I had noticed before that these values were missing, so I used 150 as default...and that is why the memory exception occured
But now with the correct values, the entire application is working just fine under WM5!
Thank you again for your contribution!
|
|
|
|
|
I am happy to hear that. Good luck!
|
|
|
|
|
Hi,
I am facing problem to compile source-7.67KB in VS2005.
Debug mode compilation succeed but Release compilation failed with the following linker errors:
SampleGrabberFilter.def : error LNK2001: unresolved external symbol DllCanUnloadNow
1>SampleGrabberFilter.def : error LNK2001: unresolved external symbol DllGetClassObject
1>Windows Mobile 6 Standard SDK (ARMV4I)\Release/SampleGrabberFilter.lib : fatal error LNK1120: 2 unresolved externals
Can someone please help me with this problem?
Regards,
Efi
|
|
|
|
|
Hi all, I am trying to have a filter graph which is based on the original sample codes. Camera Filter-> Encoder -> SampleGrabber -> Null Filter. However when i try to preview the video, with this 2 additions, the video doesnt show up.
Code as follows:
CHK(CoCreateInstance(CLSID_DMOWrapperFilter, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVideoEncoder));
CHK(pVideoEncoder->QueryInterface(&pWrapperFilter ));
CHK(pWrapperFilter->Init( CLSID_CWMV9EncMediaObject, DMOCATEGORY_VIDEO_ENCODER ));
CHK(m_pFilterGraph->AddFilter( pVideoEncoder, L"WMV9DMO Encoder"));
CHK( CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pH263Transform ) );
CHK( m_pFilterGraph->AddFilter( pH263Transform, FILTERNAME ) );
CHK( pH263Transform->QueryInterface( IID_ISampleGrabber, (void**)&m_pISampleGrabber ) );
CHK( CoCreateInstance( CLSID_NullRenderer, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&pNullRenderer ) );
CHK( m_pFilterGraph->AddFilter( pNullRenderer, L"NullRenderer" ) );
CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pVideoCaptureFilter, pVideoEncoder, pH263Transform ) );
CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, pH263Transform, NULL, pNullRenderer ) );
CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, m_pVideoCaptureFilter, pH263Transform, NULL ) );
Please advise me, thanks all!
|
|
|
|
|
maybe u might have already found the solution. But for others, these is the actual problem.
HK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pVideoCaptureFilter, pVideoEncoder, pH263Transform ) );
CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, pH263Transform, NULL, pNullRenderer ) );
// preview stream
CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, m_pVideoCaptureFilter, pH263Transform, NULL ) );
In your 1st m_pCaptureGraphBuilder->RenderStream , RenderStream only accepts 1 source, 1 intermediate and 1 renderer filter.
You cannot join a video encoder to a samplegrabber using renderstream. You need to connect the pins manually in cases where there are 2 or more intermediate filters.
In your 2nd m_pCaptureGraphBuilder->RenderStream, ph263 is not a source filter, hence it cannot be added in that parameter.
modified on Wednesday, April 28, 2010 11:12 PM
|
|
|
|
|
Hello Angel Kafazov
great article on creating a custom sample grabber filter which help me a lot!! I have developed an application that gets the camera frames
and processes them in order to do some object recognition. The resolution of the frames is 176*144 pixels.
What I need to do is, depending on my needs to be able to use a higher resolution frame e.g. 640*480 that will be obtained only when I press a button (I do not want a callback function that will return higher resolution frames all the time).
Is this doable?? I mean, can I get a higher resolution frame when I press a button while graph keeps running?
I suspect that the graph must stop getting the low resolution frames to return a higher resolution one. Also perhaps I should use the PIN_CATEGORY_CAPTURE or PIN_CATEGORY_STILL pins??
Regards
Demetrio
|
|
|
|
|
Hi Demetrio,
yes this can be done. The PINs in the graph have nothing to do with the resolution. I suppose that you will have to restart the graph and accept the higher resolutions which the camera offers. It all depends on the device and how much is DirectShow supported on it.
Regards,
Angel
|
|
|
|
|
Hello Angel,
thanks for the reply. I will try your suggestion and see how it goes. I was also thinking if I can add to the my program functionality for storing images when i need to (like the cameracapture in the microsoft sdk samples). Storing the image might solve my problem since when I tried the cameracapture sample (on the same phone I am using now) it would only store images of 640*480 resolution.
Regards
Demetrio
|
|
|
|
|
Hi Demetrio,
I have the same problem.
Could you find a way to get higher resolution?
thanks...
alper
|
|
|
|
|