This chapter describes the process of playing audio and/or video using the Media Engine.
For more information on the Media Session APIs, see the Media Session API reference documentation. To play PCM audio using only the Audio Manager, see Chapter 3, "Audio Subsystem."
Playing Audio and/or Video
The following steps walk through the basic process of playing back a media file, such as an MP3 or MPEG-4 file. Note that in order for playback to occur any necessary codec(s) must be installed.
- First, create a "media session": a context in which the media file is processed. You create a session for a specific "action," either playback or record. Create a playback session as follows:
ALPMMSessionID hSession; status = alp_media_session_create(ALP_MM_SESSION_CLASS_PLAYBACK, &hSession);
- Specify the source containing the media to be played back. Currently, the Media Engine supports two types of sources: a local file, or memory. Specify a source file as follows:
alp_media_session_add_source(hSession, ALP_MM_TYPE_FILE, Â Â Â Â filename, &hSource);
The
filenameparameter is a C string containing the path to the file. - Add one or more destinations to the session. The Media Engine currently only supports three type of destinations, which are defined in
media_session.h:
- LCDDEV
- the screen.
- DSPDEV
- the DSP device (for audio playback).
- FILENAME
- A file into which the media stream is to be saved. (This destination only applies to recording sessions.)
If the media file contains a video stream, you must add the LCDDEV destination. If it contains an audio stream, add the DSPDEV destination. Do this with one or both of the following (add both to play both audio and video):
alp_media_session_add_dest(hSession, DSPDEV, &hDsp); alp_media_session_add_dest(hSession, LCDDEV, &hLcd);
Note that if you have already specified the source, you can use the alp_media_property_get() function to determine whether the source contains audio and/or video, like this:
// send the video stream to the LCD display, if the source has video alp_media_property_get(gSession_id, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_FILE_HAS_VIDEO, ALP_MM_PROPERTY_CODE_BOOL, &bHasVideo, NULL); if(bHasVideo) status = alp_media_session_add_dest(gSession_id, LCDDEV, &lcd_dest_id); // send the audio stream to the DSP chip, if the source has an audio track alp_media_property_get(gSession_id, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_FILE_HAS_AUDIO, ALP_MM_PROPERTY_CODE_BOOL, &bHasAudio, NULL); if(bHasAudio) status = alp_media_session_add_dest(gSession_id, DSPDEV, &dsp_dest_id);
- Either now or after you have successfully finalized your media session, get and set any needed media session properties. Use
alp_media_property_get()to obtain a property, andalp_media_property_set()to set one.See "Media Session Properties - Playback" for the complete set of properties you can get and/or set during a playback session.
- If you wish to be notified when errors and warnings arise, or when the session state changes (from playback to stopped, for instance), or on a periodic basis during playback (useful for updating a progress indicator), write an event handler and register it as a media session callback function. See "Registering a Callback" for details.
- After you have added both the source and one or more destinations, before you can play, you must finalize the session and verify that it is ready:
status = alp_media_session_finalize(hSession); if(status == ALP_STATUS_OK){ // OK to play }
alp_media_session_finalize()will verify that:- You specified a source.
- The source exists.
- The source can be read.
- The source has a supported format.
- The destinations are valid for the specified source format. For instance, if you are playing an MP3 file but the destination is LCDDEV, an error is returned. If the source has both audio and video, LCDDEV is a valid destination.
- Play the media file with:
alp_media_session_control(hSession, ALP_MM_SESSION_CTL_RUN);
In general, you control the session using the values defined in the AlpMMSessionControlOpcode enum. When playing back a media file, in addition to playing you can also pause and stop playback as follows:
alp_media_session_control(hSession, Â Â Â Â ALP_MM_SESSION_CTL_PAUSE); alp_media_session_control(hSession, ALP_MM_SESSION_CTL_STOP);
- When you are done with the session, call
alp_media_session_destroy()to dispose of the session and free up its resources. Note that if you call this function while playback is ongoing, playback will immediately be halted and the session will be destroyed.
Putting it all Together
The following code is part of a simple GTK+ application that can play both audio and video1. The CreatePlaybackSession() takes an absolute path to a file containing the media to be played in a format that can be handled by one of the codecs—an MP3 or MPEG-4 file, for instance—and creates a new playback session. For simplicity, the session ID is stored in a global variable named gSession_id.
The session creation function registers a callback function that is invoked when certain events occur. This particular implementation of the callback function (MySessionCallback()) keeps the user informed of the playback progress by responding to the ALP_MM_SESSION_EVENT_CURRENT_TIME event code. For a playback session, the Media Session invokes the callback at regular intervals with this event code and passes a structure containing both the current position within the playback (a 64-bit value expressed in nanoseconds, relative to the beginning of the stream) and the total length of the stream (again, in nanoseconds). The callback also watches for an ALP_MM_SESSION_EVENT_CAUSE_END_OF_STREAM "event cause". Note that there is a difference between an "event code" and an "event cause". When the event code is zero, check the event cause to determine why the callback was called.
The purpose of the PlayButtonClicked(), StopButtonClicked(), and PauseButtonClicked() functions should be pretty obvious. These are designed to be "wired up" to GTK+ buttons.
The "play" function is the most complex of the three. First, it creates a session if one doesn't already exist. It then issues an ALP_MM_SESSION_CTL_RUN command (after first checking to see if the session isn't already playing). The "stop" function is simpler; it simply issues an ALP_MM_SESSION_CTL_STOP command and then destroys the session (actually, you could simply destroy the session; that immediately stops the playback).
Listing 4.1 Playing audio and video
#include <alp/media_defs.h> #include <alp/media_sound_mgr.h> #include <alp/media_session.h> AlpMMSessionID gSession_id = 0; Â Â Â // we're using a global for the session ID void MySessionCallback(AlpMMSessionEvent *event, void *userData){ switch(event->event_code){ case ALP_MM_SESSION_EVENT_CURRENT_TIME: // update time display { int32_t position = event->position/1000000000LL; int32_t duration = event->duration/1000000000LL; // now that we have converted the time values from nanoseconds to // seconds, we could display them here } break; default: if(event->event_cause == ALP_MM_SESSION_EVENT_CAUSE_END_OF_STREAM){ // Indicate to the user that playback has finished } break; } } alp_status_t CreatePlaybackSession(char *filePath){ AlpMMSourceID source_id = 0; AlpMMDestID dsp_dest_id = 0; AlpMMDestID lcd_dest_id = 0; alp_status_t status; gboolean bHasVideo, bHasAudio; // create a session status = alp_media_session_create(ALP_MM_SESSION_CLASS_PLAYBACK, &gSession_id); // add a source - a file, in this particular case if(status == ALP_MM_STATUS_OK){ status = alp_media_session_register_callback(gSession_id, (AlpMMSessionCallbackFn)MySessionCallback, NULL); if(status == ALP_MM_STATUS_OK){ status = alp_media_session_add_source(gSession_id, ALP_MM_TYPE_FILE, filePath, &source_id); if(status == ALP_MM_STATUS_OK){ // send the video stream to the LCD display, if the source has video alp_media_property_get(gSession_id, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_FILE_HAS_VIDEO, ALP_MM_PROPERTY_CODE_BOOL, &bHasVideo, NULL); if(bHasVideo) status = alp_media_session_add_dest(gSession_id, LCDDEV, &lcd_dest_id); // send the audio stream to the DSP chip, if the source has audio alp_media_property_get(gSession_id, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_FILE_HAS_AUDIO, ALP_MM_PROPERTY_CODE_BOOL, &bHasAudio, NULL); if(bHasAudio) status = alp_media_session_add_dest(gSession_id, DSPDEV, &dsp_dest_id); if(status == ALP_MM_STATUS_OK){ status = alp_media_session_finalize(gSession_id); } } } if(status != ALP_MM_STATUS_OK){ // something failed along the way, but after we created a session alp_media_session_destroy(gSession_id); gSession_id = 0; } } return status; } void PlayButtonClicked(GtkWidget *button, gpointer data){ alp_status_t status = ALP_MM_STATUS_OK; if(!gSession_id) status = CreatePlaybackSession(gFilepath); if(status == ALP_MM_STATUS_OK){ AlpMMSessionState current_state; alp_media_session_get_state(gSession_id, ¤t_state); if(current_state != ALP_MM_SESSION_RUNNING){ // here, you might update the display to show the user what is playing status = alp_media_session_control(gSession_id, ALP_MM_SESSION_CTL_RUN); } } else { // deal with the fact that the session could not be created } } void StopButtonClicked(GtkWidget *button, gpointer data){ alp_status_t status; if(gSession_id){ status = alp_media_session_control(gSession_id, ALP_MM_SESSION_CTL_STOP); alp_media_session_destroy(gSession_id); gSession_id = 0; } } void PauseButtonClicked(GtkWidget *button, gpointer data){ alp_status_t status; if(gSession_id){ status = alp_media_session_control(gSession_id, ALP_MM_SESSION_CTL_PAUSE); } }
Media Session Properties - Playback
As part of a media playback session you can get or set, as noted, the properties listed in the following sections.
IMPORTANT: Always check the status value returned from the
alp_media_property_get() or alp_media_property_set() call; if it is not ALP_MM_STATUS_OK, the property get/set operation did not succeed.
Depending upon the property, you need to specify the appropriate object ID. There are three different object ID types used when getting and setting playback properties:
- AlpMMSessionID
- The ID of a media session. This ID is returned when you create the session with
alp_media_session_create(). - AlpMMSourceID
- The ID of a media source. This ID is returned when you successfully add a media source with
alp_media_session_add_source(). - AlpMMDestID
- The ID of a destination. For playback, this is typically the ID representing the screen (LCD) or the audio output (DSP). A destination ID is returned from each successful call to
alp_media_session_add_dest().
ALP_MM_SESSION_AUDIO_ENABLE
Purpose
Specifies whether an audio track is enabled or disabled.
Get/Set
Object ID Type
Data Type
gboolean (ALP_MM_PROPERTY_CODE_BOOL)
Comments
If the media source contains both audio and video streams, disabling audio will cause only the video stream to be played.
Example
The following code determines whether or not the audio stream is enabled:
gboolean bEnable; status = alp_media_property_get(sessionID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SESSION_AUDIO_ENABLE, ALP_MM_PROPERTY_CODE_BOOL, &bEnable, NULL); /* If successful, bEnable will be set to TRUE if the audio    stream is enabled for playing. */
The following code shows how to enable or disable the audio stream:
gboolean bEnable= FALSE;    // disables the audio stream status = alp_media_property_set(sessionID, ALP_MM_SESSION_AUDIO_ENABLE, ALP_MM_PROPERTY_CODE_BOOL, &bEnable, NULL); /* If successful, the Media Engine will disable the audio    stream. */
ALP_MM_SESSION_AUDIO_VOLUME
Purpose
Gets or set the volume level of the destination device.
Get/Set
Object ID Type
ALPMMDestID (usually, of the DSP chip)
Data Type
int (ALP_MM_PROPERTY_CODE_INT32)
Comments
Pass the ID of the destination device as the first parameter, rather than the usual session ID. The value of the volume parameter can range from 0 to 100.
Example
The following code obtains the volume setting for the DSP chip:
int volume; status = alp_media_property_get(dsp_dest_id, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SESSION_AUDIO_VOLUME, ALP_MM_PROPERTY_CODE_INT32, &volume, NULL); /* If successful, volume will be set to the DSP chip's volume    level setting */
ALP_MM_SESSION_DEST_RECT
Purpose
The destination rectangle to use for a video frame. The rectangle specifies both the position and the size. The image will be scaled to fit the specified rectangle.
Get/Set
Object ID Type
AlpMMDestID for the LCD device
Data Type
AlpMMRectangle (ALP_MM_PROPERTY_CODE_RAW)
Example
AlpMMRectangle rect; int length = sizeof(rect); status = alp_media_property_get(gLCDDestID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SESSION_DEST_RECT, ALP_MM_PROPERTY_CODE_RAW, &rect, &length); /* If successful, rect.width will have the video width and    rect.height will have the video height. rect.x and rect.y    indicate the rectangle's position on the screen */
ALP_MM_SESSION_REPEAT_ENABLE
Purpose
Indicates whether or not playback should repeat when the end of the track is reached.
Get/Set
Object ID Type
Data Type
gboolean (ALP_MM_PROPERTY_CODE_BOOL)
Example
To determine whether or not repeat playback is enabled:
gboolean bRepeat; status = alp_media_property_get(sessionID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SESSION_REPEAT_ENABLE, ALP_MM_PROPERTY_CODE_BOOL, &bRepeat, NULL); /* If successful, bRepeat will be set to TRUE if the track    will play repeatedly, or FALSE if it will only play once. */
To control whether or not the media stream is played once, or repeatedly:
gboolean bRepeat = TRUE; status = alp_media_property_set(sessionID, ALP_MM_SESSION_REPEAT_ENABLE, ALP_MM_PROPERTY_CODE_BOOL, &bRepeat, NULL); /* If successful, the Media Engine will cause the media    stream to play repeatedly. */
ALP_MM_SESSION_VIDEO_ENABLE
Purpose
Specifies whether a video track should be enabled.
Get/Set
Object ID Type
Data Type
gboolean (ALP_MM_PROPERTY_CODE_BOOL)
Comments
If the media source contains both audio and video streams, disabling video will cause only the audio stream to be played.
Example
The following code shows how to determine whether or not the video stream is enabled:
gboolean bEnable; status = alp_media_property_get(sessionID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SESSION_VIDEO_ENABLE, ALP_MM_PROPERTY_CODE_BOOL, &bEnable, NULL); /* If successful, bEnable will be set to TRUE if the video    stream is enabled. */
To control whether or not the video stream is enabled, do this:
gboolean bEnable= FALSE;    // disable video playback status = alp_media_property_set(sessionID, ALP_MM_SESSION_VIDEO_ENABLE, ALP_MM_PROPERTY_CODE_BOOL, &bEnable, NULL); /* If successful, the Media Engine will disable the video    stream. */
ALP_MM_SOURCE_FILE_FORMAT
Purpose
Specifies the format of a media file.
Get/Set
Get. This property cannot be set for a playback session.
Object ID Type
Data Type
AlpMediaFileFormatType (ALP_MM_PROPERTY_CODE_INT32)
Example
AlpMediaFileFormatType file_type; int32_t size = sizeof(file_type); status = alp_media_property_get(sourceID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_FILE_FORMAT, ALP_MM_PROPERTY_CODE_INT32, &file_type, &size); /* If successful, file_type will have one of the    AlpMediaFileFormatType enum values */
ALP_MM_SOURCE_FILE_HAS_AUDIO
Purpose
Specifies whether or not the media source file has an audio track.
Get/Set
Get. This property cannot be set for a playback session.
Object ID Type
Data Type
gboolean (ALP_MM_PROPERTY_CODE_BOOL)
Example
gboolean bHasAudio; status = alp_media_property_get(sessionID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_FILE_HAS_AUDIO, ALP_MM_PROPERTY_CODE_BOOL, &bHasAudio, NULL); /* If successful, bHasVideo will be set to TRUE if the media    source has an audio stream, or FALSE if it does not. */
ALP_MM_SOURCE_FILE_HAS_VIDEO
Purpose
Specifies whether or not the media source file has a video track.
Get/Set
Get. This property cannot be set for a playback session.
Object ID Type
Data Type
gboolean (ALP_MM_PROPERTY_CODE_BOOL)
Example
gboolean bHasVideo; status = alp_media_property_get(sessionID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_FILE_HAS_VIDEO, ALP_MM_PROPERTY_CODE_BOOL, &bHasVideo, NULL); /* If successful, bHasVideo will be set to TRUE if the media    source has a video stream, or FALSE if it does not. */
ALP_MM_SOURCE_URL
Purpose
The URL used to identify a source object.
Get/Set
Get. This property cannot be set for a playback session. Use alp_media_session_add_source() to specify the media source.
Object ID Type
Data Type
char * (ALP_MM_PROPERTY_CODE_STRING)
Comments
You must allocate the space into which the URL will be written, and supply both a pointer to your buffer and a pointer to the length of the allocated buffer.
Example
gchar urlBuffer[128]; int length = sizeof(urlBuffer)/sizeof(gchar); status = alp_media_property_get(sourceID, ALP_MM_PROPERTY_TYPE_DEFAULT, ALP_MM_SOURCE_URL, ALP_MM_PROPERTY_CODE_STRING, urlBuffer, &length); /* If successful, urlBuffer will contain the URL. */
1. See the ACCESS Linux Platform Application Programming book for a complete media playback application.



