This tutorial describes how to play video data on graphics surfaces using the Video Client APIs.
The purpose of this tutorial is to show you how to open, configure and play video clips on graphics surfaces.
Required Background
The Video Client Overview introduces the video client utilities.
Introduction
The video player utility 2 enables you to open and play video data on graphics surfaces. For more information about graphics surfaces, see Graphics Surfaces.
You can also render video to graphics surfaces without associating them with a target window. This allows you to use graphics surfaces provided by the Multimedia Framework (MMF), as well as other graphics surfaces where no window can be provided.
This functionality is exposed by the CVideoPlayerUtility2 class. CVideoPlayerUtility2 is derived from CVideoPlayerUtility. For more information about CVideoPlayerUtility, see the video player utility tutorials starting with Creating and Preparing a Video Player Tutorial.
Note: CVideoPlayerUtility2 can only be used with controllers that support graphics surfaces.
The following tasks are covered in this tutorial:
The high level step to construct a utility object is shown here:
To create a new instance of CVideoPlayerUtility2, use the NewL() function:
NewL(MVideoPlayerUtilityObserver& aObserver, TInt aPriority, TMdaPriorityPreference aPref);
Creating an instance of CVideoPlayerUtility2 is similar to creating an instance of CVideoPlayerUtility, however, unlike the CVideoPlayerUtility::NewL(), the CVideoPlayerUtility2::NewL() method doesn’t take a window destination.
Once created, the CVideoPlayerUtility2 needs to know what data it should be playing.
Note: To open a video source with CVideoPlayerUtility2, the controller must support graphics surfaces, otherwise it will fail with KErrNotSupported.
Video clips must be opened using one of the following open functions:
From a file
OpenFileL(const TDesC& aFileName, TUid aControllerUid=KNullUid);
This method opens the video clip from a file. It uses an optionally specified plug-in in the argument to load a controller. If no controller plug-in is specified, it searches through the list of available plug-ins and attempts to use each one until successful or the end of the list is reached.
Note: There is also another method to open a video clip from a file. It is strongly recommended to use this method.
OpenFileL(const TMMSource& aSource, TUid aControllerUid);
Where aSource is a filename or an open handle to a file containing the video clip and aControllerUid is an optionally specified plug-in. If specified, it will force the video player to use the controller with the given UID. If no controller plug-in is specified, this function searches through a list of all available plug-ins and attempts to use each one until successful or the end of the list is reached.
From a descriptor
OpenDesL(const TDesC8& aDescriptor, TUid aControllerUid=KNullUid);
This method opens the video clip from a descriptor. It opens the video clip contained as binary data in a descriptor using an optionally specified plug-in in the argument to load a controller. If no controller is specified, it searches through the list of available plug-ins and attempts to use each one until successful or the end of the list is reached.
From an URL
OpenUrlL(const TDesC& aUrl, TInt aIapId = KUseDefaultIap, const TDesC8& aMimeType=KNullDesC8, TUid aControllerUid=KNullUid);
This method opens the video clip from the specified URL and identified by the MIME type. In addition a plug-in can be specified if necessary. If no controller plug-in is specified, this function searches through a list of all available plug-ins and attempts to use each one until successful or the end of the list is reached.
Once the opening of the video clip is complete, successfully or otherwise, the callback function MVideoPlayerUtilityObserver::MvpuoOpenComplete() is called. This notifies the client whether the video clip was successfully opened or not.
Note: Opening a video source must be done before providing any window destination. This is because the controller needs to be able to support graphics surfaces and this is only known at load time.
To play video on graphics surfaces without an associated target window you need to add a display. The high level steps to add a specified display are shown here:
Call the CVideoPlayerUtility2::AddDisplayL() method. This method takes a window server session, which is used to register the graphics surface, the display ID of the display that the surface is to be placed on, and a reference to a surface event handler.
IMPORT_C void AddDisplayL(RWsSession& aWs, TInt aDisplay, MMMFSurfaceEventHandler& aEventHandler);
Note: To use windowless graphics surfaces, you must provide an implementation of the MMMFSurfaceEventHandler interface. The MMMFSurfaceEventHandler interface handles surface-related events from the MMF.
The high level steps to prepare to play video are shown here:
Once the video data is ready, call the CVideoPlayerUtility2::Prepare() function.
When the client receives the MVideoPlayerUtilityObserver::MvpuoPrepareComplete() callback, the video player utility will be in configured state.
Making Configuration Adjustments
Once the video clip is open and ready to play, configuration adjustments can be made using the following functions:
CVideoPlayerUtility2::AddDisplayWindowL: This function adds a new window for displaying the video picture. Client applications must use this method instead of SetDisplayWindowL() when using CVideoPlayerUtility2. This method has two overloads:
The first takes window clipping and video extent as parameters:
AddDisplayWindowL(RWsSession& aWs, CWsScreenDevice& aScreenDevice, RWindowBase& aWindow, const TRect& aVideoExtent, const TRect& aWindowClipRect);
The second is a simplified version which doesn't take window clipping and video extent as parameters:
AddDisplayWindowL(RWsSession& aWs, CWsScreenDevice& aScreenDevice, RWindowBase& aWindow);
Note: When using this version, the video extent and window clipping rectangle default to the whole window.
CVideoPlayerUtility2::SetVideoExtentL: This function sets the video extent on the screen, relative to the window. The extent specifies the area of screen in which the video picture is placed and may be partially or completely outside of the video window. Video picture position within the extent depends on the picture size and content alignment or offset.
SetVideoExtentL(const TRect& aVideoExtent);
Note: Video extent can be set before a successful call to AddDisplayWindowL has been made.
CVideoPlayerUtility2::SetWindowClipRectL: This function sets the window clipping rectangle, relative to the window. The clipping rectangle specifies the part of the window used to display the video picture and must be fully contained within the window. Any video content falling outside of this area is not displayed.
SetWindowClipRectL(const TRect& aWindowClipRect);
The high level step to play video data is shown here:
After configuring the properties, the CVideoPlayerUtility2::Play() function is called for the video clip to be played.
If CMMFVideoPlayerUtility2 receives a ReplaceSurface event, then the graphics surface needs to be replaced. The high level steps to replace a surface are shown here:
Call CVideoPlayerUtility2::RemoveDisplay() and set aDisplay to be the ID of the display to remove.
IMPORT_C void RemoveDisplay(TInt aDisplay);
Call CVideoPlayerUtility2::AddDisplayL(). This method takes a window server session, which is used to register the graphics surface, the display ID of the display that the surface is to be placed on, and a reference to a surface event handler.
IMPORT_C void AddDisplayL(RWsSession& aWs, TInt aDisplay, MMMFSurfaceEventHandler& aEventHandler);
The high level steps to stop video playback are shown here:
Call the CVideoPlayerUtility2::Stop() function.
IMPORT_C TInt Stop();
Video playback is stopped as soon as possible, and the MVideoPlayerUtilityObserver::MvpuoPlayComplete() callback function is called.
To remove a display from the list of surface rendering targets, call CVideoPlayerUtility2::RemoveDisplay() and set aDisplay to be the ID of the display to remove:
IMPORT_C void RemoveDisplay(TInt aDisplay);
Calling RemoveDisplay() destroys any graphics surface associated with the display. You must make sure the graphics surface can be safely destroyed before making this call.
Note: If you have added windows to the display using CVideoPlayerUtility2::AddDisplayWindowL(), then the graphics surface can only be destroyed when you have removed all of the windows as well. That is, when no windows or event handlers are using the display. To remove a window, use the CVideoPlayerUtility2::RemoveDisplayWindowL() function.