| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | 
 | "http://www.w3.org/TR/html4/loose.dtd"> | 
 | <html> | 
 |  | 
 | <head> | 
 | <title>OpenMAX AL for Android</title> | 
 | </head> | 
 |  | 
 | <body> | 
 |  | 
 | <h1>OpenMAX AL for Android</h1> | 
 |  | 
 | This article describes the Android native multimedia APIs based on the | 
 | Khronos Group OpenMAX AL™ 1.0.1 standard, as of Android API level 14 (Android | 
 | platform version 4.0) and higher. | 
 | <p> | 
 | OpenMAX AL is a companion API to OpenSL ES, but for multimedia (video | 
 | and audio) rather than audio only. | 
 | <p> | 
 | Android 4.0 provides a direct, efficient path for low-level streaming multimedia. The new path is | 
 | ideal for applications that need to maintain complete control over media data before passing it to | 
 | the platform for presentation. For example, media applications can now retrieve data from any | 
 | source, apply proprietary encryption/decryption, and then send the data to the platform for display. | 
 | <p> | 
 | Applications can now send processed data to the platform as a multiplexed stream of audio/video | 
 | content in MPEG-2 transport stream format. The platform de-muxes, decodes, and renders the content. | 
 | The audio track is rendered to the active audio device, while the video track is rendered to either | 
 | a Surface or a SurfaceTexture. When rendering to a SurfaceTexture, the application can apply | 
 | subsequent graphics effects to each frame using OpenGL. | 
 | <p> | 
 | OpenMAX AL provides a C language interface that is also callable from C++, and | 
 | exposes features similar to these Android APIs | 
 | callable from Java programming language code: | 
 | <ul> | 
 | <li><a href="http://developer.android.com/reference/android/media/MediaPlayer.html"> | 
 | android.media.MediaPlayer</a> | 
 | </ul> | 
 |  | 
 | As with all of the Android Native Development Kit (NDK), the primary | 
 | purpose of OpenMAX AL for Android is to facilitate the implementation | 
 | of shared libraries to be called from Java programming language code via Java Native | 
 | Interface (JNI).  NDK is not intended for writing pure C/C++ | 
 | applications. | 
 |  | 
 | <p> | 
 | Note: though based on OpenMAX AL, the Android native multimedia API | 
 | is <i>not</i> a conforming implementation of either OpenMAX AL 1.0.1 | 
 | profile (media player or media player / recorder). This is because Android does not | 
 | implement all of the features required by either of the profiles. | 
 | Any known cases where Android behaves differently than the specification | 
 | are described in section "Android extensions" below. | 
 |  | 
 | The Android OpenMAX AL implementation has limited features, and is | 
 | intended primarily for certain performance-sensitive native streaming | 
 | multimedia applications such as video players. | 
 | <p> | 
 | The major feature is the ability to play an MPEG-2 transport stream | 
 | containing a single program stream made up of one H.264 video elementary | 
 | stream and one AAC audio elementary stream. The application provides | 
 | the stream via an Android buffer queue data source, which is based on | 
 | the OpenSL ES buffer queue concept and Android-specific extensions. | 
 | <p> | 
 | The video sink is an <code>ANativeWindow *</code> abstract handle, | 
 | derived from an <code>android.view.Surface</code> ("surface"). | 
 | A Surface from <code>SurfaceHolder.getSurface()</code> should be used when displaying | 
 | an unaltered video within a fixed SurfaceView frame. A Surface from | 
 | <code>new Surface(SurfaceTexture)</code> allows streaming the decoded | 
 | video frames to an OpenGL ES 2.0 texture, where the frames can be used | 
 | as input to a shader algorithm in the Graphics Processing Unit (GPU). | 
 | Be sure to <code>release()</code> the Surface as soon as possible after | 
 | calling <code>setSurface</code> or ANativeWindow_fromSurface. | 
 | <p> | 
 | The audio sink is always an output mix, a device-independent mixer object | 
 | similar to that of OpenSL ES. | 
 |  | 
 | <h2>Getting started</h2> | 
 |  | 
 | <h3>Example code</h3> | 
 |  | 
 | <h4>Recommended</h4> | 
 |  | 
 | Supported and tested example code, usable as a model | 
 | for your own code, is located in NDK folder | 
 | <code>platforms/android-14/samples/native-media/</code>. | 
 |  | 
 | <h4>Not recommended</h4> | 
 |  | 
 | The OpenMAX AL 1.0.1 specification contains example code in the | 
 | appendices (see section "References" below for the link to this | 
 | specification).  However, the examples in Appendix D: Sample Code | 
 | use features | 
 | not supported by Android. Some examples also contain | 
 | typographical errors, or use APIs that are likely to change. | 
 | Proceed with caution in referring to these; | 
 | though the code may be helpful in understanding the full OpenMAX AL | 
 | standard, it should not be used as is with Android. | 
 |  | 
 | <h3>Adding OpenMAX AL to your application source code</h3> | 
 |  | 
 | OpenMAX AL is a C API, but is callable from both C and C++ code. | 
 | <p> | 
 | Add the following lines to your code: | 
 | <pre> | 
 | #include <OMXAL/OpenMAXAL.h> | 
 | #include <OMXAL/OpenMAXAL_Android.h> | 
 | </pre> | 
 |  | 
 | <h3>Makefile</h3> | 
 |  | 
 | Modify your Android.mk as follows: | 
 | <pre> | 
 | LOCAL_LDLIBS += libOpenMAXAL | 
 | </pre> | 
 |  | 
 | <h3>Multimedia content</h3> | 
 |  | 
 | The only supported way to supply multimedia content is via an MPEG-2 | 
 | transport stream. | 
 | <p> | 
 | Finding or creating useful multimedia content for your application is | 
 | beyond the scope of this article. | 
 | <p> | 
 | Note that it is your responsibility to ensure that you are legally | 
 | permitted to play the content. | 
 |  | 
 | <h3>Debugging</h3> | 
 |  | 
 | For robustness, we recommend that you examine the <code>XAresult</code> | 
 | value which is returned by most APIs. Use of <code>assert</code> | 
 | vs. more advanced error handling logic is a matter of coding style | 
 | and the particular API; see the Wikipedia article on | 
 | <a href="http://en.wikipedia.org/wiki/Assertion_(computing)">assert</a> | 
 | for more information. In the supplied example, we have used <code>assert</code> | 
 | for "impossible" conditions which would indicate a coding error, and | 
 | explicit error handling for others which are more likely to occur | 
 | in production. | 
 | <p> | 
 | Many API errors result in a log entry, in addition to the non-zero | 
 | result code. These log entries provide additional detail which can | 
 | be especially useful for the more complex APIs such as | 
 | <code>Engine::CreateMediaPlayer</code>. | 
 | <p> | 
 | Use <a href="http://developer.android.com/guide/developing/tools/adb.html"> | 
 | adb logcat</a>, the | 
 | <a href="http://developer.android.com/guide/developing/eclipse-adt.html"> | 
 | Eclipse ADT plugin</a> LogCat pane, or | 
 | <a href="http://developer.android.com/guide/developing/tools/ddms.html#logcat"> | 
 | ddms logcat</a> to see the log. | 
 |  | 
 | <h2>Supported features from OpenMAX AL 1.0.1</h2> | 
 |  | 
 | This section summarizes available features. In some | 
 | cases, there are limitations which are described in the next | 
 | sub-section. | 
 |  | 
 | <h3>Global entry points</h3> | 
 |  | 
 | Supported global entry points: | 
 | <ul> | 
 | <li><code>xaCreateEngine</code> | 
 | <li><code>xaQueryNumSupportedEngineInterfaces</code> | 
 | <li><code>xaQuerySupportedEngineInterfaces</code> | 
 | </ul> | 
 |  | 
 | <h3>Objects and interfaces</h3> | 
 |  | 
 | The following figure indicates objects and interfaces supported by | 
 | Android's OpenMAX AL implementation.  A green cell means the feature | 
 | is supported. | 
 |  | 
 | <p> | 
 | <img src="chart3.png" alt="Supported objects and interfaces"> | 
 |  | 
 | <h3>Limitations</h3> | 
 |  | 
 | This section details limitations with respect to the supported | 
 | objects and interfaces from the previous section. | 
 |  | 
 | <h4>Audio</h4> | 
 |  | 
 | The audio stream type cannot be configured; it is always <code>AudioManager.STREAM_MUSIC</code>. | 
 | <p> | 
 | Effects are not supported. | 
 |  | 
 | <h4>Dynamic interface management</h4> | 
 |  | 
 | <code>RemoveInterface</code> and <code>ResumeInterface</code> are not supported. | 
 |  | 
 | <h4>Engine</h4> | 
 |  | 
 | Supported: | 
 | <ul> | 
 | <li><code>CreateMediaPlayer</code> | 
 | </ul> | 
 |  | 
 | Not supported: | 
 | <ul> | 
 | <li><code>CreateCameraDevice</code> | 
 | <li><code>CreateRadioDevice</code> | 
 | <li><code>CreateLEDDevice</code> | 
 | <li><code>CreateVibraDevice</code> | 
 | <li><code>CreateMetadataExtractor</code> | 
 | <li><code>CreateExtensionObject</code> | 
 | <li><code>GetImplementationInfo</code> | 
 | </ul> | 
 |  | 
 | For <code>CreateMediaPlayer</code>, these restrictions apply: | 
 | <ul> | 
 | <li>audio sink is an output mix data locator | 
 | <li>video sink is a native display data locator | 
 | <li>soundbank, LED array, and vibra sinks must be <code>NULL</code> | 
 | </ul> | 
 |  | 
 | <h4>MIME data format</h4> | 
 |  | 
 | In the current Android implementation of OpenMAX AL, a media player | 
 | receives its source data as an MPEG-2 transport stream via a | 
 | buffer queue. | 
 | <p> | 
 | The source data locator must be <code>XA_DATALOCATOR_ANDROIDBUFFERQUEUE</code> | 
 | (see "Android extensions" below). | 
 | <p> | 
 | The source data format must be <code>XADataFormat_MIME</code>. | 
 | Initialize <code>mimeType</code> to <code>XA_ANDROID_MIME_MP2TS</code>, | 
 | and <code>containerType</code> to <code>XA_CONTAINERTYPE_MPEG_TS</code>. | 
 | <p> | 
 | The contained transport stream must have a single program with one H.264 | 
 | video elementary stream and one AAC audio elementary stream. | 
 |  | 
 | <h4>Object</h4> | 
 |  | 
 | <code>Resume</code>, <code>RegisterCallback</code>, | 
 | <code>AbortAsyncOperation</code>, <code>SetPriority</code>, | 
 | <code>GetPriority</code>, and <code>SetLossOfControlInterfaces</code> | 
 | are not supported. | 
 |  | 
 | <h4>StreamInformation</h4> | 
 |  | 
 | Use the StreamInformation interface on a media player object to discover | 
 | when the video metrics (height/width or aspect ratio) are available or | 
 | changed, and to then get the sizes. | 
 | <p> | 
 |  | 
 | Supported: | 
 | <ul> | 
 | <li><code>RegisterStreamChangeCallback</code> | 
 | <li><code>QueryMediaContainerInformation</code> | 
 | <li><code>QueryStreamInformation</code> | 
 | <li><code>QueryStreamType</code> | 
 | </ul> | 
 |  | 
 | Not supported: | 
 | <ul> | 
 | <li><code>QueryActiveStreams</code> | 
 | <li><code>QueryStreamName</code> | 
 | <li><code>SetActiveStream</code> | 
 | </ul> | 
 |  | 
 | <h4>VideoDecoderCapabilities</h4> | 
 |  | 
 | This interface on the engine object reports video decoder capabilities | 
 | without interpretation, exactly as claimed by the underlying OpenMAX IL | 
 | implementation. | 
 | <p> | 
 | These fields in <code>XAVideoCodecDescriptor</code> are filled: | 
 | <ul> | 
 | <li><code>codecId</code> | 
 | <li><code>profileSetting</code> | 
 | <li><code>levelSetting</code> | 
 | </ul> | 
 | The other fields are not filled and should be ignored. | 
 | <p> | 
 | Applications should rely on the capabilities documented at | 
 | <a href="http://developer.android.com/guide/appendix/media-formats.html">Android Supported Media Formats</a>, | 
 | not the information reported by this interface. | 
 |  | 
 | <h3>Data structures</h3> | 
 |  | 
 | Android API level 14 supports these OpenMAX AL 1.0.1 data structures: | 
 | <ul> | 
 | <li>XADataFormat_MIME | 
 | <li>XADataLocator_NativeDisplay | 
 | <li>XADataLocator_OutputMix | 
 | <li>XADataSink | 
 | <li>XADataSource | 
 | <li>XAEngineOption | 
 | <li>XAInterfaceID | 
 | <li>XAMediaContainerInformation | 
 | <li>XANativeHandle | 
 | <li>XA*StreamInformation | 
 | <li>XAVideoCodecDescriptor | 
 | </ul> | 
 |  | 
 | <h4>XADataLocator_NativeDisplay</h4> | 
 |  | 
 | The native display data locator is used to specify the video sink: | 
 | <pre> | 
 | typedef struct XADataLocator_NativeDisplay_ { | 
 |     XAuint32 locatorType;      // XA_DATALOCATOR_NATIVEDISPLAY | 
 |     XANativeHandle hWindow;    // ANativeWindow * | 
 |     XANativeHandle hDisplay;   // NULL | 
 | } XADataLocator_NativeDisplay; | 
 | </pre> | 
 |  | 
 | Set the <code>hWindow</code> field to an | 
 | <code>ANativeWindow *</code> and set <code>hDisplay</code> to <code>NULL</code>. | 
 | You can get a <code>ANativeWindow *</code> handle from an <code>android.view.Surface</code>, | 
 | using this NDK function: | 
 | <pre> | 
 | #include <android/native_window_jni.h> | 
 |  | 
 | ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface); | 
 | </pre> | 
 | Don't forget to free this handle in your shutdown code with <code>ANativeWindow_release</code>. | 
 |  | 
 | <h3>Platform configuration</h3> | 
 |  | 
 | OpenMAX AL for Android is designed for multi-threaded applications, | 
 | and is thread-safe. | 
 | <p> | 
 | OpenMAX AL for Android supports a single engine per application, and | 
 | up to 32 objects. Available device memory and CPU may further | 
 | restrict the usable number of objects. | 
 | <p> | 
 | <code>xaCreateEngine</code> recognizes, but ignores, these engine options: | 
 | <ul> | 
 | <li><code>XA_ENGINEOPTION_THREADSAFE</code> | 
 | <li><code>XA_ENGINEOPTION_LOSSOFCONTROL</code> | 
 | </ul> | 
 |  | 
 | OpenMAX AL and OpenSL ES may be used together in the same application. | 
 | In this case, there is internally a single shared engine object, | 
 | and the 32 object limit is shared between OpenMAX AL and OpenSL ES. | 
 | The application should first create both engines, then use both engines, | 
 | and finally destroy both engines.  The implementation maintains a | 
 | reference count on the shared engine, so that it is correctly destroyed | 
 | at the second destroy. | 
 |  | 
 | <h2>Planning for future versions of OpenMAX AL</h2> | 
 |  | 
 | The Android native multimedia APIs at level 14 are based on Khronos | 
 | Group OpenMAX AL 1.0.1 (see section "References" below). | 
 | As of the time of this writing, Khronos has recently released | 
 | a revised version 1.1 of the standard. The revised version | 
 | includes new features, clarifications, correction of | 
 | typographical errors, and some incompatibilities. Most of the | 
 | incompatibilities are relatively minor, or are in areas of OpenMAX AL | 
 | not supported by Android. However, even a small change | 
 | can be significant for an application developer, so it is important | 
 | to prepare for this. | 
 | <p> | 
 | The Android team is committed to preserving future API binary | 
 | compatibility for developers to the extent feasible. It is our | 
 | intention to continue to support future binary compatibility of the | 
 | 1.0.1-based API, even as we add support for later versions of the | 
 | standard. An application developed with this version should | 
 | work on future versions of the Android platform, provided that | 
 | you follow the guidelines listed in section "Planning for | 
 | binary compatibility" below. | 
 | <p> | 
 | Note that future source compatibility will <i>not</i> be a goal. That is, | 
 | if you upgrade to a newer version of the NDK, you may need to modify | 
 | your application source code to conform to the new API. We expect | 
 | that most such changes will be minor; see details below. | 
 |  | 
 | <h3>Planning for binary compatibility</h3> | 
 |  | 
 | We recommend that your application follow these guidelines, | 
 | to improve future binary compatibility: | 
 | <ul> | 
 | <li> | 
 | Use only the documented subset of Android-supported features from | 
 | OpenMAX AL 1.0.1. | 
 | <li> | 
 | Do not depend on a particular result code for an unsuccessful | 
 | operation; be prepared to deal with a different result code. | 
 | <li> | 
 | Application callback handlers generally run in a restricted context, | 
 | and should be written to perform their work quickly and then return | 
 | as soon as possible. Do not do complex operations within a callback | 
 | handler. For example, within a buffer queue completion callback, | 
 | you can enqueue another buffer, but do not create a media player. | 
 | <li> | 
 | Callback handlers should be prepared to be called more or less | 
 | frequently, to receive additional event types, and should ignore | 
 | event types that they do not recognize. Callbacks that are configured | 
 | with an event mask of enabled event types should be prepared to be | 
 | called with multiple event type bits set simultaneously. | 
 | Use "&" to test for each event bit rather than a switch case. | 
 | <li> | 
 | Use prefetch status and callbacks as a general indication of progress, but do | 
 | not depend on specific hard-coded fill levels or callback sequence. | 
 | The meaning of the prefetch status fill level, and the behavior for | 
 | errors that are detected during prefetch, may change. | 
 | </ul> | 
 |  | 
 | <h3>Planning for source compatibility</h3> | 
 |  | 
 | As mentioned, source code incompatibilities are expected in the next | 
 | version of OpenMAX AL from Khronos Group. Likely areas of change include: | 
 |  | 
 | <ul> | 
 | <li>Addition of <code>const</code> to input parameters passed by reference, | 
 | and to <code>XAchar *</code> struct fields used as input values. | 
 | This should not require any changes to your code. | 
 | <li>Substitution of unsigned types for some parameters that are | 
 | currently signed.  You may need to change a parameter type from | 
 | <code>XAint32</code> to <code>XAuint32</code> or similar, or add a cast. | 
 | <li>Additional fields in struct types. For output parameters, these | 
 | new fields can be ignored, but for input parameters the new fields | 
 | will need to be initialized. Fortunately, these are expected to all | 
 | be in areas not supported by Android. | 
 | <li>Interface | 
 | <a href="http://en.wikipedia.org/wiki/Globally_unique_identifier"> | 
 | GUIDs</a> will change. Refer to interfaces by symbolic name rather than GUID | 
 | to avoid a dependency. | 
 | <li><code>XAchar</code> will change from <code>unsigned char</code> | 
 | to <code>char</code>. This primarily affects the MIME data format. | 
 | <li><code>XADataFormat_MIME.mimeType</code> will be renamed to <code>pMimeType</code>. | 
 | We recommend that you initialize the <code>XADataFormat_MIME</code> | 
 | data structure using a brace-enclosed comma-separated list of values, | 
 | rather than by field name, to isolate your code from this change. | 
 | In the example code we have used this technique. | 
 | </ul> | 
 |  | 
 | <h2>Android extensions</h2> | 
 |  | 
 | The API for Android extensions is defined in <code>OMXAL/OpenMAXAL_Android.h</code> | 
 | . | 
 | Consult that file for details on these extensions. Unless otherwise | 
 | noted, all interfaces are "explicit". | 
 | <p> | 
 | Note that use these extensions will limit your application's | 
 | portability to other OpenMAX AL implementations. If this is a concern, | 
 | we advise that you avoid using them, or isolate your use of these | 
 | with <code>#ifdef</code> etc. | 
 | <p> | 
 | The following figure shows which Android-specific interfaces and | 
 | data locators are available for each object type. | 
 |  | 
 | <p> | 
 | <img src="chart4.png" alt="Android extensions"> | 
 |  | 
 | <h3>Android buffer queue data locator and interface</h3> | 
 |  | 
 | <h4>Comparison with OpenSL ES buffer queue</h4> | 
 |  | 
 | The Android buffer queue data locator and interface are based on | 
 | similar concepts from OpenSL ES 1.0.1, with these differences: | 
 | <ul> | 
 | <li>Though currently usable with only a media player and MPEG-2 transport | 
 | stream data, the Android buffer queue API is designed for flexibility | 
 | so that the API can also apply to other use cases in the future. | 
 | <li>Commands may be | 
 | optionally specified by the application at time of <code>Enqueue</code>. | 
 | Each command consists of an item key and optional item value. | 
 | Command key/value pairs are carried alongside the corresponding buffer in the queue, | 
 | and thus are processed in synchrony with the buffer. | 
 | <li>To enqueue command(s) without associated data, specify | 
 | a buffer address of NULL and buffer size of zero, along | 
 | with at least one command. | 
 | <li>Status may be | 
 | provided by the implementation during a completion callback. | 
 | Each status consists of an item key and optional item value. | 
 | Status key/value pairs are carried alongside | 
 | the corresponding buffer in the queue, and thus are received by the | 
 | application in synchrony with the completion callback. | 
 | <li>The completion callback receives additional parameters: | 
 | buffer address, buffer maximum data size, buffer actual size consumed (or filled by a future | 
 | recorder object), and a <code>void *</code> for application. | 
 | <li>The callback returns a value, which must be <code>XA_RESULT_SUCCESS</code>. | 
 | </ul> | 
 |  | 
 | The data locator type code is <code>XA_DATALOCATOR_ANDROIDBUFFERQUEUE</code> and | 
 | the associated structure is <code>XADataLocator_AndroidBufferQueue</code>. | 
 | <p> | 
 | The interface ID is <code>XA_IID_ANDROIDBUFFERQUEUESOURCE</code>. | 
 |  | 
 | <h4>Usage</h4> | 
 |  | 
 | A typical buffer queue configuration is 8 buffers of 1880 bytes each. | 
 | <p> | 
 | The application enqueues filled buffers of data in MPEG-2 transport | 
 | stream format.  The buffer size must be a multiple of 188 bytes, | 
 | the size of an MPEG-2 transport stream packet. The buffer data must | 
 | be properly aligned on a packet boundary, and formatted per the MPEG-2 | 
 | Part 1 specification. | 
 | <p> | 
 | An application may supply zero or one of these item codes | 
 | (command key/value pairs) at <code>Enqueue</code>: | 
 | <dl> | 
 | <dt>XA_ANDROID_ITEMKEY_EOS</dt> | 
 | <dd>End of stream. Informs the decode and rendering components that playback is complete. | 
 | The application must not call <code>Enqueue</code> again. | 
 | There is no associated value, so <code>itemSize</code> must be zero. | 
 | There must be no data buffer alongside the EOS command. | 
 | </dd> | 
 | <dt>XA_ANDROID_ITEMKEY_DISCONTINUITY</dt> | 
 | <dd>Discontinuity. This and following buffers have a new presentation time. | 
 | The new presentation time may be optionally specified as a parameter, | 
 | expressed in <code>itemData</code> as a 64-bit unsigned integer in units of 90 kHz clock ticks. | 
 | The <code>itemSize</code> should be either zero or 8. | 
 | The discontinuity command is intended for seeking to a new point in | 
 | the stream.  The application should flush its internal data, then send | 
 | the discontinuity command prior to, or alongside of, the first buffer | 
 | corresponding to the new stream position. | 
 | The initial packets in the video elementary stream | 
 | should describe an IDR (Instantaneous Decoding Refresh) frame. | 
 | Note that the discontinuity | 
 | command is not intended for stream configuration / format changes; | 
 | for these use <code>XA_ANDROID_ITEMKEY_FORMAT_CHANGE</code>. | 
 | </dd> | 
 | <dt>XA_ANDROID_ITEMKEY_FORMAT_CHANGE</dt> | 
 | <dd>Format change. This and following buffers have a new format, | 
 | for example for MBR (Multiple Bit Rate) or resolution switching. | 
 | </dd> | 
 | </dl> | 
 | <p> | 
 | Upon notification of completion via a registered callback, the now | 
 | consumed buffer is available for the application to re-fill. | 
 | <p> | 
 | The implementation may supply zero or more of these item codes | 
 | (status key/value pairs) to the callback handler: | 
 | <dl> | 
 | <dt>XA_ANDROID_ITEMKEY_BUFFERQUEUEEVENT</dt> | 
 | <dd>Buffer queue event mask. The <code>itemSize</code> is 4, and <code>itemData</code> contains | 
 | the bit-wise "or" of zero or more of the <code>XA_ANDROIDBUFFERQUEUEEVENT_*</code> | 
 | symbols. This event mask explains the reason(s) why the callback handler | 
 | was called.</dd> | 
 | </dl> | 
 |  | 
 | <h3>Reporting of extensions</h3> | 
 |  | 
 | <code>Engine::QueryNumSupportedExtensions</code>, | 
 | <code>Engine::QuerySupportedExtension</code>, | 
 | <code>Engine::IsExtensionSupported</code> report these extensions: | 
 | <ul> | 
 | <li><code>ANDROID_SDK_LEVEL_#</code> | 
 | where # is the platform API level, 14 or higher | 
 | </ul> | 
 |  | 
 | <h2>Programming notes</h2> | 
 |  | 
 | These notes supplement the OpenMAX AL 1.0.1 specification, | 
 | available in the "References" section below. | 
 |  | 
 | <h3>Objects and interface initialization</h3> | 
 |  | 
 | Two aspects of the OpenMAX AL programming model that may be unfamiliar | 
 | to new developers are the distinction between objects and interfaces, | 
 | and the initialization sequence. | 
 | <p> | 
 | Briefly, an OpenMAX AL object is similar to the object concept | 
 | in programming languages such as Java and C++, except an OpenMAX AL | 
 | object is <i>only</i> visible via its associated interfaces. This | 
 | includes the initial interface for all objects, called | 
 | <code>XAObjectItf</code>.  There is no handle for an object itself, | 
 | only a handle to the <code>XAObjectItf</code> interface of the object. | 
 | <p> | 
 | An OpenMAX AL object is first "created", which returns an | 
 | <code>XAObjectItf</code>, then "realized". This is similar to the | 
 | common programming pattern of first constructing an object (which | 
 | should never fail other than for lack of memory or invalid parameters), | 
 | and then completing initialization (which may fail due to lack of | 
 | resources).  The realize step gives the implementation a | 
 | logical place to allocate additional resources if needed. | 
 | <p> | 
 | As part of the API to create an object, an application specifies | 
 | an array of desired interfaces that it plans to acquire later. Note | 
 | that this array does <i>not</i> automatically acquire the interfaces; | 
 | it merely indicates a future intention to acquire them.  Interfaces | 
 | are distinguished as "implicit" or "explicit".  An explicit interface | 
 | <i>must</i> be listed in the array if it will be acquired later. | 
 | An implicit interface need not be listed in the object create array, | 
 | but there is no harm in listing it there.  OpenMAX AL has one more | 
 | kind of interface called "dynamic", which does not need to be | 
 | specified in the object create array, and can be added later after | 
 | the object is created.  The Android implementation provides a | 
 | convenience feature to avoid this complexity; see section "Dynamic | 
 | interfaces at object creation" above. | 
 | <p> | 
 | After the object is created and realized, the application should | 
 | acquire interfaces for each feature it needs, using | 
 | <code>GetInterface</code> on the initial <code>XAObjectItf</code>. | 
 | <p> | 
 | Finally, the object is available for use via its interfaces, though | 
 | note that some objects require further setup. | 
 | Some use cases needs a bit more preparation in | 
 | order to detect connection errors. See the next section | 
 | "Media player prefetch" for details. | 
 | <p> | 
 | After your application is done with the object, you should explicitly | 
 | destroy it; see section "Destroy" below. | 
 |  | 
 | <h3>Media player prefetch</h3> | 
 |  | 
 | For a media player, <code>Object::Realize</code> allocates resources | 
 | but does not connect to the data source (i.e. "prepare") or begin | 
 | pre-fetching data. These occur once the player state is set to | 
 | either <code>XA_PLAYSTATE_PAUSED</code> or <code>XA_PLAYSTATE_PLAYING</code>. | 
 | <p> | 
 | The prefetch status interface is useful for detecting errors. | 
 | Register a callback and enable at least the | 
 | <code>XA_PREFETCHEVENT_FILLLEVELCHANGE</code> and | 
 | <code>XA_PREFETCHEVENT_STATUSCHANGE</code> events. If both of these | 
 | events are delivered simultaneously, and | 
 | <code>PrefetchStatus::GetFillLevel</code> reports a zero level, and | 
 | <code>PrefetchStatus::GetPrefetchStatus</code> reports | 
 | <code>XA_PREFETCHSTATUS_UNDERFLOW</code>, then this indicates a | 
 | non-recoverable error in the data source or in rendering to the video sink. | 
 | <p> | 
 | The next version of OpenMAX AL is expected to add more explicit | 
 | support for handling errors in the data source. However, for future | 
 | binary compatibility, we intend to continue to support the current | 
 | method for reporting a non-recoverable error. | 
 | <p> | 
 | In summary, a recommended code sequence is: | 
 | <ul> | 
 | <li>Engine::CreateMediaPlayer | 
 | <li>Object:Realize | 
 | <li>Object::GetInterface for XA_IID_PREFETCHSTATUS | 
 | <li>PrefetchStatus::SetCallbackEventsMask | 
 | <li>PrefetchStatus::RegisterCallback | 
 | <li>Object::GetInterface for XA_IID_PLAY | 
 | <li>Play::SetPlayState to XA_PLAYSTATE_PAUSED or XA_PLAYSTATE_PLAYING | 
 | <li>preparation and prefetching occur here; during this time your | 
 | callback will be called with periodic status updates and | 
 | error notifications | 
 | </ul> | 
 |  | 
 | <h3>Destroy</h3> | 
 |  | 
 | Be sure to destroy all objects on exit from your application.  Objects | 
 | should be destroyed in reverse order of their creation, as it is | 
 | not safe to destroy an object that has any dependent objects. | 
 | For example, destroy in this order: audio players and recorders, | 
 | output mix, then finally the engine. | 
 | <p> | 
 | OpenMAX AL does not support automatic garbage collection or | 
 | <a href="http://en.wikipedia.org/wiki/Reference_counting">reference counting</a> | 
 | of interfaces. After you call <code>Object::Destroy</code>, all extant | 
 | interfaces derived from the associated object become <i>undefined</i>. | 
 | <p> | 
 | The Android OpenMAX AL implementation does not detect the incorrect | 
 | use of such interfaces. | 
 | Continuing to use such interfaces after the object is destroyed will | 
 | cause your application to crash or behave in unpredictable ways. | 
 | <p> | 
 | We recommend that you explicitly set both the primary object interface | 
 | and all associated interfaces to NULL as part of your object | 
 | destruction sequence, to prevent the accidental misuse of a stale | 
 | interface handle. | 
 |  | 
 | <h3>Callbacks and threads</h3> | 
 |  | 
 | Callback handlers are generally called <i>synchronously</i> with | 
 | respect to the event, that is, at the moment and location where the | 
 | event is detected by the implementation. But this point is | 
 | <i>asynchronous</i> with respect to the application. Thus you should | 
 | use a mutex or other synchronization mechanism to control access | 
 | to any variables shared between the application and the callback | 
 | handler. In the example code, such as for buffer queues, we have | 
 | omitted this synchronization in the interest of simplicity. However, | 
 | proper mutual exclusion would be critical for any production code. | 
 | <p> | 
 | Callback handlers are called from internal | 
 | non-application thread(s) which are not attached to the Dalvik virtual machine and thus | 
 | are ineligible to use JNI. Because these internal threads are | 
 | critical to the integrity of the OpenMAX AL implementation, a callback | 
 | handler should also not block or perform excessive work. Therefore, | 
 | if your callback handler needs to use JNI or do anything significant | 
 | (e.g. beyond an <code>Enqueue</code> or something else simple such as the "Get" | 
 | family), the handler should instead post an event for another thread | 
 | to process. | 
 | <p> | 
 | Note that the converse is safe: a Dalvik application thread which has | 
 | entered JNI is allowed to directly call OpenMAX AL APIs, including | 
 | those which block. However, blocking calls are not recommended from | 
 | the main thread, as they may result in the dreaded "Application Not | 
 | Responding" (ANR). | 
 |  | 
 | <h3>Performance</h3> | 
 |  | 
 | As OpenMAX AL is a native C API, non-Dalvik application threads which | 
 | call OpenMAX AL have no Dalvik-related overhead such as garbage | 
 | collection pauses. However, there is no additional performance | 
 | benefit to the use of OpenMAX AL other than this. In particular, use | 
 | of OpenMAX AL does not result in lower audio or video latency, higher scheduling | 
 | priority, etc. than what the platform generally provides. | 
 | On the other hand, as the Android platform and specific device | 
 | implementations continue to evolve, an OpenMAX AL application can | 
 | expect to benefit from any future system performance improvements. | 
 |  | 
 | <h3>Security and permissions</h3> | 
 |  | 
 | As far as who can do what, security in Android is done at the | 
 | process level. Java programming language code can't do anything more than native code, nor | 
 | can native code do anything more than Java programming language code. The only differences | 
 | between them are what APIs are available that provide functionality | 
 | that the platform promises to support in the future and across | 
 | different devices. | 
 | <p> | 
 | Applications using OpenMAX AL must request whatever permissions they | 
 | would need for similar non-native APIs. | 
 | Applications that play | 
 | network resources need <code>android.permission.NETWORK</code>. | 
 | Note that the current Android implementation does not directly access the network, | 
 | but many applications that play multimedia receive their data via the network. | 
 |  | 
 | <h2>Platform issues</h2> | 
 |  | 
 | This section describes known issues in the initial platform | 
 | release which supports these APIs. | 
 |  | 
 | <h3>Dynamic interface management</h3> | 
 |  | 
 | <code>DynamicInterfaceManagement::AddInterface</code> does not work. | 
 | Instead, specify the interface in the array passed to Create. | 
 |  | 
 | <h2>References and resources</h2> | 
 |  | 
 | Android: | 
 | <ul> | 
 | <li><a href="http://developer.android.com/resources/index.html"> | 
 | Android developer resources</a> | 
 | <li><a href="http://groups.google.com/group/android-developers"> | 
 | Android developers discussion group</a> | 
 | <li><a href="http://developer.android.com/sdk/ndk/index.html">Android NDK</a> | 
 | <li><a href="http://groups.google.com/group/android-ndk"> | 
 | Android NDK discussion group</a> (for developers of native code, including OpenMAX AL) | 
 | <li><a href="http://code.google.com/p/android/issues/"> | 
 | Android open source bug database</a> | 
 | </ul> | 
 |  | 
 | Khronos Group: | 
 | <ul> | 
 | <li><a href="http://www.khronos.org/openmax/al/"> | 
 | Khronos Group OpenMAX AL Overview</a> | 
 | <li><a href="http://www.khronos.org/registry/omxal/"> | 
 | Khronos Group OpenMAX AL 1.0.1 specification</a> | 
 | <li><a href="http://www.khronos.org/message_boards/viewforum.php?f=30"> | 
 | Khronos Group public message board for OpenMAX AL</a> | 
 | (please limit to non-Android questions) | 
 | </ul> | 
 | For convenience, we have included a copy of the OpenMAX AL 1.0.1 | 
 | specification with the NDK in | 
 | <code>docs/openmaxal/OpenMAX_AL_1_0_1_Specification.pdf</code>. | 
 |  | 
 | <p> | 
 | Miscellaneous: | 
 | <ul> | 
 | <li><a href="http://en.wikipedia.org/wiki/Java_Native_Interface">JNI</a> | 
 | <li><a href="http://en.wikipedia.org/wiki/MPEG-2">MPEG-2</a> | 
 | <li><a href="http://en.wikipedia.org/wiki/MPEG_transport_stream">MPEG-2 transport stream</a> | 
 | <li><a href="http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC">H.264</a> | 
 | <li><a href="http://en.wikipedia.org/wiki/Advanced_Audio_Coding">AAC</a> | 
 | </ul> | 
 |  | 
 | </body> | 
 | </html> |