Author: lythm some are trying to prepare the game their friends may encounter such a problem: To play the game cinematic trailer, but how the whole
Play animation? Use media player controls? This is the easiest way, but a lot of functions can not be used, and it is inevitable.
waste. And multimedia libraries such as VFW are too troublesome. How to do it?
In fact, Microsoft not only provides SDK, which provides DirectX's easy-to-game development, but also provides DirectX Media on it.
SDK. This set of SDK can help you simplify multimedia development, and make full use of DirectX's high performance. It is very simple to use,
It is also very powerful, it can identify the format of the stream, even MPEG2 will not let go!
Below I will explain how to call DirectShow to play the video:
First, you need to include the following files in the project:
#include "ddraw.h"
#include "mmstream.h"
#include "amstream.h"
#include "ddstream.h"
These headers provide the necessary data structure and method declarations.
Second, we can divide the entire process of the program into 3 steps:
1. Establish a DirectDraw surface (SURFACE).
2. Extract the video stream from the file (there may be audio).
3. Play the video stream on the surface on the DirectDraw.
The necessary variables:
DDSURFACEDESC DDSD;
IDirectdraw * pdd;
Idirectdrawsurface * pprimarysurface;
IMultimediastream * pmmstream;
The ImultIMediaStream interface is the highest level of interface object in DirectShow, which can contain one or more multimedia objects.
These multimedia objects can be different types, such as audio, video, and more. Let's take it below.
Add the following code in the initialization method:
HRESULT INIT ()
{
......
PDD = NULL;
PprimarySurface = NULL;
PMMStream = NULL;
ZeromeMMory (DDSD, SIZEOF (DDSD));
HRESULT R;
// Initialization COM
Coinitialize (NULL);
// Initialize DirectDraw
r = initddraw ();
Return R;
}
Since DirectShow is based on CoM, use Coinitialize to initialize COM, this method is simple, there is only one parameter and must
It must be NULL.
The implementation of initddraw () will be given later.
The following code is added to the secting method:
void uninit ()
{
......
IF (pmmstream! = null)
PMMSTream-> Release ();
IF (PprimarySurface! = null)
PprimarySurface-> Release ();
IF (PDD! = NULL)
PDD-> Release ();
Couninitialize ();
}
Initialize DirectDraw and establish a DirectDraw surface: (Since DirectDraw is not the focus of this article, please refer to the relevant
Document, only code is given)
It is might as well build a method to include these works, including:
HRESULT initddraw ()
{
HRESULT R;
IF (Failed (R = DirectDrawCreate (Null, & PDD, NULL))))
Return R;
IF (failed (r = pdd-> setcooperativeelevel (hwnd,
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))))))
Return R;
IF (failed (r = pdd-> setDisplaymode (640, 480, 16)) // resolution setting
Return R;
Ddsd.dwsize = sizeof (ddsd);
DDSD.DWFLAGS = DDSD_CAPS;
DDSD.DDSCAPS.DWCAPS = DDSCAPS_PRIMARYSURFACE;
IF (Failed (PDD-> CreateSurface (& DDSD, & PPRIMARYSURFACE, NULL))
Return R;
Return S_OK;
}
The next step will extract the video stream from the file.
A method will also establish a method to encapsulate work.
HRESULT LOADFROMFILE (Const Char * SZFileName, iMultimediaStream ** PPMMSTREAM,
IDirectDraw * PDD)
{
HRESULT R;
IammultiMultiStream * Pamstream;
IF (Failed (r = cocreateInstance) (CLSID_AMMULTIMEDISTREAM, NULL,
CLSCTX_INPROC_SERVER,
IID_iammultiMediaStream, (void **) & pamstream)))))))
Return R;
Wchar wpath [MAX_PATH];
MultibyToWideChar (CP_ACP, 0, SZFileName, -1, WPath,
SIZEOF (WPATH) / SIZEOF (WPath [0]));
IF (Failed (R = Pamstream-> Initialize (streamtype_read, ammsf_nographthread,
NULL))))))
Return R;
IF (Failed (R = Pamstream-> AddMediaStream (PDD, & MSPID_PRIMARYVIDEO, 0, NULL)))
Return R;
IF (Failed (r = pamstream-> addmediastream (null, & mspid_primaryaudio,
Ammsf_adddefaultrenderer, NULL))))))
Return R;
IF (Failed (r = pamstream-> openfile (wpath, 0))))
Return R;
* ppmmstream = pamstream;
Return S_OK;
}
The method code is as above.
The LoadFromFile () method has 3 parameters:
Const Char * SZFileName, ImultimediaStream ** PPMMSTREAM and IDIRECTDRAW * PDD
The first parameter is the file name to extract. String constance. The second parameter is a pointer to the pointer of the multimedia flow interface.
Manipulate multimedia flow. The third parameter is the DirectDraw interface, and it is played through its surface.
First, declare a pointer to an IammultiMultiaStream interface, which is very powerful, here only uses it.
Minute:
Establish a video and audio stream, and then extract from the file.
The CocreateInstance method is then called to create an instance of IAMMULTIMEDIASTREAM. The first parameter of this method is specified
Global Sign (GUID, the same), the fourth parameter indicates the sign of the interface to be created, the fifth parameters are created to return
Remove the Pamstream variable.
The next two lines of code are converted to Unicode to Unicode, and don't have to say. Then initialize IAMMULTIMEDISTREAM to create a video audio stream.
Finally, it is also the most important step: call the OpenFile () method to extract the stream from the file. The first parameter is the file name, the second
A parameter is open mode (please refer to MSDN for details).
This completes the extraction of the stream.
Let's start playing.
This is also the most complex work (relative).
Similarly, build a method package code.
HRESULT Play (iDirectdrawsurface * psurface, iMultiMediStream * pmmstream)
{
IMediaStream * pprimaryvidstream;
IDirectdrawmediastream * pddstream;
IDirectdrawstreamsample * psample;
RECT;
DDSURFACEDESC DDSD;
PMMStream-> getMediaStream (Mspid_PrimaryVideo, & PprimaryvidStream);
PprimaryvidStream-> queryinterface (iid_idirectdrawmediastream, (void **)
& pddStream);
Ddsd.dwsize = sizeof (ddsd);
PDDSTREAM-> GetFormat (& DDSD, NULL, NULL, NULL);
RECT.TOP = 100;
Rect.Left = 150;
Rect.bottom = DDSD.DWHEIGHT 100;
Rect.right = ddsd.dwwidth 150;
PDDSTREAM-> Createsample (Psurface, & Rect, 0, & psample);
Pmmstream-> setState (streamstate_run);
While (psample-> Update (0, null, null, null) == s_ok)
;
PMMStream-> setState (streamstate_stop);
Psample-> release ();
PDDSTREAM-> Release ();
PprimaryvidStream-> release ();
}
The Play () method has two parameters, one is used to play the DirectDraw surface of the video, one is the data stream
MultiMediaStream object.
Variable declarations are as follows:
IMediaStream * pprimaryvidstream;
IDirectdrawmediastream * pddstream;
IDirectdrawstreamsample * psample;
RECT;
DDSURFACEDESC DDSD;
They are ImediAstream interfaces, used to query the IDirectdrawmediStream interface; DirectDrawMediaStream
Interface, used to get details of stream data, such as long, width, etc.; IDirectDrawStreamSample interface, this is a data sample
This is used to refresh the DirectDraw surface, which is played.
The next two are: a RECT data structure, used to specify the play area; a surface description, here is used
The format of this data.
Then the implementation part:
First call the getMediStream () method of iMultiStream to get a video object stream of IMEDISTREAM, which is specified by the parameter mspid_primaryvideo.
Then IMEDIASTREAM is queried to get the iDirectdrawmediastream interface (please refer to COM document, here
No longer accumulated).
Then get the data format by the IDirectDrawmediStream interface, establish a sample and associate to the DirectDraw table
surface. IMEDISTREAM interface
SetState (streamstate_run) method to play media streams, played data by IDirectDrawstreamsample sample
New to the surface of the DirectDRAW.
If the refresh is successful, the idirectdrawstreamsample :: update () method returns S_OK. After you finish it, call it.
IMediaStream :: setState (streamState_stop) Stop media streams.
In this way, DirectShow collaborates with each other to complete the playback of the video stream.
Because the space limit lists only the core code, if you are interested, you can download a DEMO (paypower).
The URL is as follows: http://www.sunistudio.com
This person is scattered, if you have any mistakes, you will also look at the expert guidance! ^ o ^
My email: lythm@citiz.net (Don't bomb me).
......
April 27, 2000