<!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&#8482; 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 &lt;OMXAL/OpenMAXAL.h&gt;
#include &lt;OMXAL/OpenMAXAL_Android.h&gt;
</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 &lt;android/native_window_jni.h&gt;

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 "&amp;" 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>