Method for realizing graphics during DSHOW playback
1: Join the Simple Grabber Filter,
a): From IsampleGrabbercb, you have a class, then implement its virtual function, see the sample program in SDK (DXSDK Root / Samples / C / DirectShow / Editing / GrabbitMaps)
b): When adding Filter, because this may slow down efficiency, the following method can be employed:
The method needs to pass the time, and is not added to the FILTER when playing is played and then screenshots, but also open the original file.
State the following interface:
Igraphbuilder * pgraph = null;
IMediaControl * pControl = null;
IMediaseEKing * pseeking = null;
IMediaeventex * pevent = null;
Ibasefilter * pnullfilter = null;
Initialize these interfaces:
JIF (CocreateInstance (CLSID_FILTERGRAPH, NULL, CLSCTX_INPROC,
IID_IGRAPHBUILDER, (void **) & pgraph));
JIF (CocreateInstance (CLSID_NULLRENDERER, NULL, CLSCTX_INPROC,
IID_IBASEFILTER, (void **) & pnullfilter);
JIF (PGRAPH-> QueryInterface (IID_IMEDIACONTROL, (Void **) & PControl);
JIF (PGRAPH-> Queryinterface (IID_IMEDIASEEKING, (VOID **) & PSEEKING));
JIF (pgraph-> queryinterface (iid_imediaevent, (void **) & pevent);
Create Sample Grabber
// CREATE The Sample Grabber.
Ibasefilter * pgrabberf = null;
JIF (CoCreateInstance (CLSID_SAMPLEGRABBER, NULL, CLSCTX_INPROC_SERVER,
IID_IBASEFILTER, (Void **) & pgrabberf);
JIF (PGRAPH-> AddFilter (Pgrabberf, L "Sample Grabber");
JIF (PGRAPH-> AddFilter (PNULLFILTER, L "NULL RENDER Filter");
Isamplegrabber * pgrabber;
JIF (PGRabberf-> Queryinterface (IID_ID_ISAMPLEGRABBBBER);
Set the media format of Grabber:
Call SetMediaType, which accepts an am_media_type structure, mainly setting Majortype, and Subtype fields in this structure.
Add Source Filter:
Ibasefilter * psrc;
JIF (pgraph-> addsourcefilter (t2W (m_szfile), l "source", & psrc);
Two filters connected to Grabber and Nullrender
Ipin * poutpin;
HR = getpin (pgrabberf, pindir_output, & poutpin; ipin * pinpin;
HR = getpin (pnullfilter, pindir_input, & pinpin);
PGRAPH-> Connect (poutpin, pinpin);
The GRF chart after the connection is as follows:
A false figure, source code
Get the type of the currently connected media
AM_MEDIA_TYPE MT;
HR = pgrabber-> getConnectedMediaType (& MT);
// Examine The Format Block.
VideoInfoHeader * PVIH;
IF ((mt.formattype == format_videoinfo) &&&
(mt.cbformat> = sizeof (videofoheader) &&
(mt.pbformat! = null))
{
PVIH = (VideoInfoHeader *) mt.pbformat;
}
Else
{
// Wrong format. Free the format block and return an error.
FreeMediaType (MT);
Return VFW_E_INVALIDMEDITYPE;
}
// DO Buffer the Samples As The Pass Through
//
HR = pgrabber-> setBuffersamples (true);
// Only Grab One At a Time, Stop StreamAfter
// Grabbing One Sample
//
HR = pgrabber-> setOnShot (TRUE);
Seeking files that make it reach the time frame to be screenshot
Pseeping-> setPositions (pcurrentpos, am_seeking_absolutePositioning,
NULL, AM_SEEKING_NOPOSITIONING;
PCONTROL-> Run ();
Long Evcode = 0;
HR = pevent-> WaitForCompletion (Infinite, & Evcode);
Get the current buffer data
// Find The Required Buffer Size.
Long cbbuffer = 0;
HR = pgrabber-> getCurrentBuffer (& CBBuffer, NULL);
Longlong CurrentPos;
Pseeping-> getCurrentPosition; & CurrentPos;
BYTE * PBUFFER = New byte [CBBuffer];
IF (! pbuffer)
{
// out of memory. Return An Error Code.
MSG ("Out of Memory";
}
HR = PGRABBER-> GetCurrentBuffer (& CBBuffer, (long *) pBuffer;
Release resource
PCONTROL-> STOP ();
SAFE_RELEASE (PCONTROL);
SAFE_RELEASE (PSEEKING);
SAFE_RELEASE (PEVENT);
SAFE_RELEASE (PSRC);
SAFE_RELEASE (PNULLFILTER);
SAFE_RELEASE (PGRABBER);
SAFE_RELEASE (PGRABBBERF);
SAFE_RELEASE (PGRAPH);
Write file
// Create a file to hold the bitmap
Handle HF = Createfile (SzFileName, Generic_Write, File_Share_read,
NULL, CREATE_ALWAYS, NULL, NULL;
IF (HF == Invalid_Handle_Value)
{
// Failed to create file
Return 0;
}
// write out the file header
//
BitmapfileHeader Bfh;
MEMSET (& BFH, 0, SIZEOF (BFH));
Bfh.bfType = 'MB';
BFH.BFSIZE = SizeOf (BFH) CBBuffer Sizeof (BitmapInfoHead);
Bfh.bfoffbits = sizeof (BitmapInfoHeader) Sizeof (BitmapfileHeader);
DWORD WRITTEN = 0;
Writefile (HF, & BFH, SIZEOF (BFH), & Written, NULL
// Write the bitmap Format
//
BitmapInfoheader Bih;
MEMSET (& BiH, 0, Sizeof (BIH));
Bih.bisize = sizeof (bih);
Bih.biwidth = pvih-> bmiheader.biwidth;
Bih.biheight = pvih-> bmiheader.biheight;
BIH.BIPLANES = PVIH-> bmiheader.biplanes;
BIH.BIBITCOUNT = PVIH-> bmiheader.biBitcount;
Written = 0;
Writefile (HF, & BIH, SIZEOF (BIH), & Written, NULL;
// Write the bitmap bits
//
Written = 0;
Writefile (HF, PBUFFER, CBBUFFER, & Written, NULL);
FreeMediaType (MT);
CloseHandle (HF);
In fact, we can do without NullRender, but use the iVideoWindow interface.
If so, first stated iVideoWindow * pvideo = NULL;
Add PVIDEO to Filter GRAPH
JIF (PGRAPH-> QueryInterface (IID_IVideoWindow, (void **) & pvideo));
HR = pgraph-> render (poutpin);
IF (PVideo)
{
HR = pvideo-> PUT_AUTOSHOW (OAFALSE);
}
The method of obtaining data and writing files is the same.
Its established GRF is: GRF diagram established by PVIDEO, its source code
3: Call ibasicVideo :: getCurrentImage, source files via the ibasicvideo interface
4: Call iMedIAdet :: EnterbitmapGrabMode, iMedett :: get_currentstream, iMedett :: getBitmapbits or iMedett :: WriteBitmapbits or iMedett :: WriteBitmapbits, Source Codes 5: Using DDRAW technology, use Surface's copy.