Re: Grab a frame from cpature device
From: Andreas Pfeuti (andreas.pfeuti_at_switzerland.org)
Date: 03/19/04
- Next message: Alessandro Angeli [MVP::DigitalMedia]: "Re: VMR9 consumes much more CPU horse power than the default Video Renderer. Why?"
- Previous message: VideoDev: "PSI Parser"
- In reply to: The March Hare \(MVP\): "Re: Grab a frame from cpature device"
- Messages sorted by: [ date ] [ thread ]
Date: 18 Mar 2004 23:32:47 -0800
"The March Hare \(MVP\)" <phil@ndsm.maps> wrote in message news:<#HMA9$2CEHA.2308@tk2msftngp13.phx.gbl>...
> > Are there filters which can store a frame in a bmp-file? Or how could
> > I solve my requirement?
>
> Look at the Grabber sample and the ISampleGrabber interface in the docs.
Thanks for the hint.
I post here my code-snipets. It shows how to grabb a frame triggered
by the application and save the the frame into a bmp file.
May somebody can use it.
//first, add the Sample-Grabber-Filter to the graph
//remark m_pGrabber is a member variable containing the
ISampleGrabber-Interface
// create a sample grabber
//
hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
CLSCTX_INPROC,IID_IBaseFilter, (void **)&pSampleGrabberFilter);
if( FAILED(hr) )
{
Msg( TEXT("Could not create SampleGrabber (is qedit.dll
registered?)"));
return hr;
}
pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber,
(void**)&m_pGrabber);
if( FAILED(hr) )
{
Msg( TEXT("Could not get ISampleGrabber - Interface"));
return hr;
}
// force it to connect to video, 24 bit
//
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = m_pGrabber->SetMediaType(&mt);
if( FAILED( hr ) )
{
Msg( TEXT("Could not set media type"));
return hr;
}
// add the grabber to the graph
//
hr = m_pGraph->AddFilter( pSampleGrabberFilter, L"Grabber" );
if( FAILED( hr ) )
{
Msg( TEXT("Could not put sample grabber in graph"));
return hr;
}
//set buffering mode
hr = m_pGrabber->SetBufferSamples(TRUE);
-------------------------------------------------------------------------
//the GetStillImage - method is called by the application
//this method uses the ISampleGrabber-Interface to grabb a frame an
converts
//the frame into a MFC CBitmap - object
CBitmap* TVideoCapture::GetStillImage()
{
// The video header contains the bitmap information.
// Copy it into a BITMAPINFO structure.
BITMAPINFO bitmapInfo;
ZeroMemory(&bitmapInfo, sizeof(bitmapInfo));
VIDEOINFOHEADER* pVih = NULL;
pVih = this->GetVideoInfoHeader();
if (!pVih)
{
return NULL;
}
CopyMemory(&bitmapInfo.bmiHeader, &(pVih->bmiHeader),
sizeof(BITMAPINFOHEADER));
// Create a DIB from the bitmap header, and get a pointer to the
buffer.
char *buffer = NULL;
HBITMAP hBitmap = ::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS,
(void**)&buffer,
NULL, 0);
// Copy the image into the buffer.
long size = 0;
//determine the required size of the buffer
HRESULT hr = m_pGrabber->GetCurrentBuffer(&size, NULL);
//grab the frame
hr = m_pGrabber->GetCurrentBuffer(&size,(long *)buffer);
if (FAILED(hr))
{
Msg(TEXT(TLanguageInterface::instance()->getString(EXTRACT_STILL_IMAGE_FAILED)));
return NULL;
}
//make a CBitmap object and return it
CBitmap* image = CBitmap::FromHandle(hBitmap);
return image;
}
VIDEOINFOHEADER* TVideoCapture::GetVideoInfoHeader()
{
AM_MEDIA_TYPE mt;
HRESULT hr = m_pGrabber->GetConnectedMediaType(&mt);
if (FAILED(hr))
{
// Return error code.
}
// Examine the format block.
VIDEOINFOHEADER *pVih = NULL;
if ((mt.formattype == FORMAT_VideoInfo) &&
(mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
(mt.pbFormat != NULL) )
{
pVih = (VIDEOINFOHEADER*)mt.pbFormat;
}
else
{
// Wrong format. Free the format block and return an error.
MyFreeMediaType(mt);
Msg(TEXT(TLanguageInterface::instance()->getString(VIDEOINFOHEADER_WRONG_FORMAT)));
}
return pVih;
}
void TVideoCapture::MyFreeMediaType(AM_MEDIA_TYPE& mt)
{
if (mt.cbFormat != 0)
{
CoTaskMemFree((PVOID)mt.pbFormat);
mt.cbFormat = 0;
mt.pbFormat = NULL;
}
if (mt.pUnk != NULL)
{
// Unecessary because pUnk should not be used, but safest.
mt.pUnk->Release();
mt.pUnk = NULL;
}
}
----------------------------------------------------------------------------
//save the received CBitmap into a file
//note: m_pImage is a pointer to the CBitmap-object received by
GetStillImage()
BOOL TStillImageDialog::saveImage()
{
BOOL success;
CString fileName = "MyStillImage.bmp";
HANDLE hf = CreateFile(
fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
CREATE_ALWAYS, NULL, NULL );
if( hf == INVALID_HANDLE_VALUE )
return FALSE;
// write out the file header
//
BITMAP bitmap;
m_pImage->GetBitmap(&bitmap);
long imageSize = bitmap.bmWidthBytes * bitmap.bmHeight;
BITMAPFILEHEADER bfh;
memset( &bfh, 0, sizeof( bfh ) );
bfh.bfType = 'MB';
bfh.bfSize = sizeof( bfh ) + imageSize + sizeof( BITMAPINFOHEADER );
bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof(
BITMAPFILEHEADER );
DWORD dwWritten = 0;
success = WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );
if (!success)
{
CloseHandle( hf );
return success;
}
// and the bitmap format
//
BITMAPINFOHEADER bih;
memset( &bih, 0, sizeof( bih ) );
bih.biSize = sizeof( bih );
bih.biWidth = bitmap.bmWidth;
bih.biHeight = bitmap.bmHeight;
bih.biPlanes = bitmap.bmPlanes;
bih.biSizeImage = imageSize;
bih.biBitCount = bitmap.bmBitsPixel;
dwWritten = 0;
success = WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );
if (!success)
{
CloseHandle( hf );
return success;
}
// and the bits themselves
//
dwWritten = 0;
success = WriteFile( hf, bitmap.bmBits, imageSize, &dwWritten, NULL
);
if (!success)
{
CloseHandle( hf );
return success;
}
success = CloseHandle( hf );
return success;
}
---- E N D -----------------------------------------------------------------
- Next message: Alessandro Angeli [MVP::DigitalMedia]: "Re: VMR9 consumes much more CPU horse power than the default Video Renderer. Why?"
- Previous message: VideoDev: "PSI Parser"
- In reply to: The March Hare \(MVP\): "Re: Grab a frame from cpature device"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|