DirectShow Programming Guide
We finally started our real journey! Let's go!
Because DirectX and VC are closely related, all code is written in C .
One. Play the film
Demonstrate how to play a movie through a simple C program. This section includes:
1. Play a media file - play back the basic code of the media file.
2. Adding a Media SEEK Function - Provides a code for how SEEK in a media file. (SeeK is ... you used CFile :: seek? Um ... it is him).
Because it is just a lot of demonstrations. E.g:
Tchar * szfilename = "c: //dxmedia/Movie/Movie.avi";
Of course, you can use a variety of ways to get the file information you use.
In addition, you define your own response message and a release macro:
#define WM_GraphNotify WM_USER 13
#define helper_release (x) {if (x) x-> release (); x = NULL;
Needed header:
#include
#include
#include
Declared variables:
HWND GHAPP;
Hinstance ghinst;
HRESULT HR;
Long Evcode;
Long Evparam1;
Long evparam2;
Where ghapp is a response window handle of an event generated by a graph. Ghinst is the window of Hinstance. Evcode will save event code, EVPARAM1, and EVPARAM2 to save the parameters of the event.
State and initialize the interface. Since the index value of the interface is automatic plus 1, you don't call the iUnknown :: AddRef method (if you feel strange, you can refer to the "First, DirectX and Parts Object Model COM" of the review).
IGRAPHBUILDER * PIGB = NULL;
IMediaControl * pimc = null;
IMediaEventex * Pimex = NULL;
IvideoWindow * pivw = NULL;
Define a function: SZFile parameter is the media file name played
Void Playfile (LPSTR SZFILE)
{
HRESULT HR;
Build a Unicode (Wide Character) string.
Wchar wfile [MAX_PATH];
MultibyToWideChar (CP_ACP, 0, SZFILE, -1, WFILE, MAX_PATH);
Instantiate a FILTER GRAPH Manager.
HR = CocreateInstance (CLSID_FILTERGRAPH,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGRAPHBUILDER,
(void **) & pigb);
Query the iMediaControl interface (providing Run, Pause and Stop Methods), iMediaEventEx interface (you can receive event response), iVideoWindow interface.
Pigb-> queryinterface (IID_IMEDIACONTROL, (Void **) & PIMC);
Pigb-> queryinterface (IID_IMEDIAEVENTEX, (Void **) & pimex);
Pigb-> queryinterface (IID_IVideoWindow, (void **) & pivw); Let Filter Graph Manager build FILTER GRAPH to render input files. There is no playing file yet (when you play with the RUN function, the Filter Graph automatically renders the media type of the input file, you don't have to specify the rendering filter).
HR = Pigb-> Renderfile (WFILE, NULL);
Use a window to capture the Waraph's notification event. You can improve performance, but allow your application to run in another thread.
Pimex-> SetNotifyWindow (OAHWND) GHAPP, WM_GRAPHNOTIFY, 0);
In response to all events from Graphs in GHAPP processing messages. If the event happens, DirectShow will post a WM_GRAPHNOTIFY message to GHAPP.
Start playing files.
HR = PIMC-> Run ();
Similarly, you can have
HR = PIMC-> pause ();
HR = PIMC-> STOP ();
Of course, you can use a dialog button to respond to Pause and STOP. This achieves simple playback.
Remember, in your code, to release the interface you use, you can use the helper_release macro.
Example: Helper_Release (PIGB);
Add the SEEK function now.
In your media file, you can use the iMediaPosition or iMediaseEKing interface Seek to a specific location. IMEDIAPOSTION :: PUT_CURRENTPSITION method can specify start time, for example, you can use the code below to replay:
IMediaPosition * PIMP;
HR = pigb-> queryinterface (& iID_IMEDIAPOSITION, (Void **) & PIMP);
HR = PIMP-> PUT_CURRENTPSITION (0);
The unit of time is 100 seconds, the following code seek to the file:
HR = PIMP-> PUT_CURRENTPSITION (10000000);
You can also use the iMediaPosition :: Put_stoptime method to set the file's playback stop time.
However, using iMediaPosition can only use seek time if you use iMediaseEKing interface, you can use multiple format seek, use 100 秒 单, frame), bytes, Media Samples, or Interlaced Video Fields. You can use iMediaseEKing :: SetTimeFormat to set the format you need. Note that it is sure that you are not playing the media file, when you set the format.
The format is as follows:
Time_format_media_time unit is 100
Time_format_byte unit is byte
Time_format_field unit is Interlaced Video Field (I don't know this format, all in English)
Time_format_frame unit is a frame
Time_format_sample unit is Sample (I don't know this format, all in English)
For example, the code setting format below is frame.
IMediaseEKing * PIMS;
HR = Pigb-> queryinterface (IID_IMEDIASEEKING, (VOID **) & PIMS);
HR = PIMS-> SetTimeFormat; the application can use a variety of SEEK modes without considering the time / rate conversion. Sometimes it is very useful.
The following example starts and ends with the format of the frame. If the 15 frame is open is played movies. You can insert the code anywhere in the PlayFile function, pay attention to, be sure to be behind the renderfile function (Remember HR = Pigb-> Renderfile (WFILE, NULL); this code?).
IMediaseEKing * PIMS;
HR = Pigb-> queryinterface (IID_IMEDIASEEKING, (VOID **) & PIMS);
Set the time format.
HR = PIMS-> SetTimeFormat;
State and initialize the start and end variables:
Longlong start = 5L;
Longlong Stop = 15L;
Set the start and end time through the iMediaseeking :: SetPositions method, the am_seeking_absolutepositioning flag means this is an absolute position (not relative to the current location of the media file). In this example, the media file begins at the 5th frame, ending at 15 frames, and the duration is 10 frames. The specific time length depends on the playback rate of the video frame.
PIMS-> setPositions (& Start, am_seeking_absolutepositioning, & stop,
Am_seeking_absolutepositioning;
The final release interface.
PIMS-> Release ();
Of course, you can also set other formats, and information that is ending. For example, 5 seconds to 7 seconds.
HR = PIMS-> SetTimeFormat;
Longlong start = 50000000L;
Longlong Stop = 70000000L;
Others will look at yourself ... (I don't have any rights interference)