Call DirectShow in VC to play video in full screen

Source: Internet
Author: User
Some friends who are trying to compile their own games may encounter the following problem: the game wants to play titles, but how to play full-screen animations? Media Player control? This is the simplest method, but it is a waste of resources because many functions cannot be used. VFW and other multi-media libraries are too troublesome. What should we do?

In fact, Microsoft not only provides Games Development sdks such as DirectX, but also provides DirectX Media sdks based on them. This SDK can help you simplify multimedia development and make full use of DirectX's high performance. It is easy to use and has powerful functions. It can identify the stream format by itself, and even MPEG2 won't let go!

The following example shows how to call DirectShow to play a video in full screen mode:

First, you must include the following header files in the project:

# Include "ddraw. h"
# Include "mmstream. h"
# Include "amstream. h"
# Include "ddstream. h"

These header files provide necessary data structures and method declarations.

Secondly, we can divide the entire process of the program into three steps:

1. Build a DirectDraw surface ).

2. Extract video streams from files (possibly audio ).

3. Play video streams on the DirectDraw surface.

Necessary variables:

Ddsurfacedesc ddsd;
Idirectdraw * PDD;
Idirectdrawsurface * pprimarysurface;
Imultimediastream * pmmstream;

The imultimediastream interface is the highest-level interface object in DirectShow. It can contain one or more multimedia objects.

These multimedia objects can be of different types, such as audio and video. We will see it below.

Add the following code to the initialization method:

Hresult Init ()
{
......
PDD = NULL;
Pprimarysurface = NULL;
Pmmstream = NULL;
Zeromemmory (ddsd, sizeof (ddsd ));
 
Hresult R;
// Initialize com
Coinitialize (null );
// Initialize DirectDraw
R = initddraw ();

Return r;
}

Because DirectShow is based on COM, coinitialize is used to initialize com. This method is very simple. There is only one parameter and must be null.

The implementation of initddraw () is provided later.

Add the following code to the Destructor:

Void uninit ()
{
......
If (pmmstream! = NULL)
Pmmstream-> release ();
If (pprimarysurface! = NULL)
Pprimarysurface-> release ();
If (PDD! = NULL)
PDD-> release ();
Couninitialize ();
}

Initialize DirectDraw and build the DirectDraw surface: (because DirectDraw is not the focus of this article, please refer to the relevant literature for the principle. Now only the code is provided)

You may wish to establish a method to include all of these tasks:

Hresult initddraw ()
{
HRESULT r;
If (FAILED (r = DirectDrawCreate (NULL, & pDD, NULL )))
Return r;
If (FAILED (r = pDD-> SetCooperativeLevel (hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN )))
Return r;
If (FAILED (r = pDD-> SetDisplayMode (640,480, 16) // resolution settings
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 is to extract the video stream from the file.

You may also create a method to encapsulate your work.

HRESULT LoadFromFile (const char * szFileName, IMultiMediaStream ** ppMMStream, IDirectDraw * pDD)
{
HRESULT r;
IAMMultiMediaStream * pAMStream;

If (FAILED (r = CoCreateInstance (CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, (void **) & pAMStream )))
Return r;

WCHAR wPath [MAX_PATH];
MultiByteToWideChar (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 follows.

The LoadFromFile () method has three parameters:

Const char * szFileName, IMultiMediaStream ** ppMMStream and IDirectDraw * pDD

The first parameter is the name of the file to be extracted. String constant. The second parameter is the pointer of the multimedia stream interface, which is used to manipulate the multimedia stream. The third parameter is the DirectDraw interface, which will be used in future playback.

First, declare a pointer to an IAMMultiMediaStream interface. This interface is very powerful and only uses part of it:

Create a video or audio stream and extract it from the file.

Call the CoCreateInstance method to create an IAMMultiMediaStream instance. The first parameter of this method specifies the global flag (guid, the same below), the fourth parameter specifies the flag of the interface to be created, and the fifth parameter indicates that the created instance is returned to the pAMStream variable.

The following two lines of code convert a char string to unicode.

Then initialize IAMMultiMediaStream to create a video and audio stream.

Finally, it is also the most important step: Call the OpenFile () method to extract streams from files. The first parameter is the file name, and the second parameter is the open mode (For details, refer to msdn ).

In this way, the stream extraction is completed.

Start playing.

This is also the most complex task (relative ).

Similarly, create a method to encapsulate the code.

HRESULT Play (IDirectDrawSurface * pSurface, IMultiMediaStream * pMMStream)
{
IMediaStream * pPrimaryVidStream;
IDirectDrawMediaStream * pDDStream;
IDirectDrawStreamSample * pSample;
RECT rect;
DDSURFACEDESC ddsd;

PMMStream-> GetMediaStream (MSPID_PrimaryVideo, & pPrimaryVidStream );
PPrimaryVidStream-> QueryInterface (IID_IDirectDrawMediaStream, (void **) & pDDStream );
Ddsd. dwSize = sizeof (ddsd );
PDDStream-> GetFormat (& ddsd, NULL, NULL );
 
Rect. top = 100;
Rect. left = 150;
Rect. bottom = ddsd. dwHeight + 100;
Rect. right = ddsd. dwWidth plus 150;
 
PDDStream-> CreateSample (pSurface, & rect, 0, & pSample );
PMMStream-> SetState (STREAMSTATE_RUN );

While (pSample-> Update (0, NULL) = S_ OK );

PMMStream-> SetState (STREAMSTATE_STOP );
PSample-> Release ();
PDDStream-> Release ();
PPrimaryVidStream-> Release ();
}

The Play () method has two parameters: one is the DirectDraw surface used to Play the video, and the other is the MultiMediaStream object containing the data stream.

The variable declaration is as follows:

IMediaStream * pPrimaryVidStream;
IDirectDrawMediaStream * pDDStream;
IDirectDrawStreamSample * pSample;
RECT rect;
DDSURFACEDESC ddsd;

They are IMediaStream interfaces used to query IDirectDrawMediaStream interfaces; DirectDrawMediaStream interfaces used to obtain details of stream data, such as length and width; IDirectDrawStreamSample interface, which is a data sample used to refresh the DirectDraw surface, that is, playing the video.

The following two items are: A rect data structure, used to specify the playing area; a surface description, used to obtain the sample data format.

The implementation section is as follows:

Call the GetMediaStream () method of IMultiMediaStream to obtain an IMediaStream video object stream. The type is specified by the parameter MSPID_PrimaryVideo.
Then, the IDirectDrawMediaStream interface is obtained through IMediaStream query (for details about the mechanism, refer to the COM documentation. I will not describe it here ).

Then, the IDirectDrawMediaStream interface obtains the data format, establishes a sample, and associates it with the DirectDraw surface. IMediaStream Interface
SetState (STREAMSTATE_RUN) method to play a media stream. The data to be played is refreshed from the IDirectDrawStreamSample to the DirectDraw surface.

If the refresh is successful, the IDirectDrawStreamSample: Update () method returns S_ OK. Call IMediaStream: SetState (STREAMSTATE_STOP) to stop the media stream.

In this way, DirectShow completes video stream playback through these interfaces.
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.