1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2"http://www.w3.org/TR/html4/loose.dtd">
3<html>
4
5<head>
6<title>OpenMAX AL for Android</title>
7</head>
8
9<body>
10
11<b>Note:</b>
12<a href="http://developer.android.com/reference/android/media/MediaCodec.html">android.media.MediaCodec</a>
13is recommended for new applications at API level 16 and above.  The NDK
14equivalent (in &lt;media/NdkMedia*.h&gt;) is recommended for new native
15applications at API level 21 and above.
16
17<h1>OpenMAX AL for Android</h1>
18
19This article describes the Android native multimedia APIs based on the
20Khronos Group OpenMAX AL&#8482; 1.0.1 standard, as of Android API level 14 (Android
21platform version 4.0) and higher.
22<p>
23OpenMAX AL is a companion API to OpenSL ES, but for multimedia (video
24and audio) rather than audio only.
25<p>
26Android 4.0 provides a direct, efficient path for low-level streaming multimedia. The path is
27ideal for applications that need to maintain complete control over media data before passing it to
28the platform for presentation. For example, media applications can retrieve data from any
29source, apply proprietary encryption/decryption, and then send the data to the platform for display.
30<p>
31Applications can send processed data to the platform as a multiplexed stream of audio/video
32content in MPEG-2 transport stream format. The platform de-muxes, decodes, and renders the content.
33The audio track is rendered to the active audio device, while the video track is rendered to either
34a Surface or a SurfaceTexture. When rendering to a SurfaceTexture, the application can apply
35subsequent graphics effects to each frame using OpenGL.
36<p>
37OpenMAX AL provides a C language interface that is also callable from C++, and
38exposes features similar to these Android APIs
39callable from Java programming language code:
40<ul>
41<li><a href="http://developer.android.com/reference/android/media/MediaPlayer.html">
42android.media.MediaPlayer</a>
43</ul>
44
45As with all of the Android Native Development Kit (NDK), the primary
46purpose of OpenMAX AL for Android is to facilitate the implementation
47of shared libraries to be called from Java programming language code via Java Native
48Interface (JNI).  NDK is not intended for writing pure C/C++
49applications.
50
51<p>
52Note: though based on OpenMAX AL, the Android native multimedia API
53is <i>not</i> a conforming implementation of either OpenMAX AL 1.0.1
54profile (media player or media player / recorder). This is because Android does not
55implement all of the features required by either of the profiles.
56Any known cases where Android behaves differently than the specification
57are described in section "Android extensions" below.
58
59The Android OpenMAX AL implementation has limited features, and is
60intended primarily for certain performance-sensitive native streaming
61multimedia applications such as video players.
62<p>
63The major feature is the ability to play an MPEG-2 transport stream
64containing a single program stream made up of one H.264 video elementary
65stream and one AAC audio elementary stream. The application provides
66the stream via an Android buffer queue data source, which is based on
67the OpenSL ES buffer queue concept and Android-specific extensions.
68<p>
69The video sink is an <code>ANativeWindow *</code> abstract handle,
70derived from an <code>android.view.Surface</code> ("surface").
71A Surface from <code>SurfaceHolder.getSurface()</code> should be used when displaying
72an unaltered video within a fixed SurfaceView frame. A Surface from
73<code>new Surface(SurfaceTexture)</code> allows streaming the decoded
74video frames to an OpenGL ES 2.0 texture, where the frames can be used
75as input to a shader algorithm in the Graphics Processing Unit (GPU).
76Be sure to <code>release()</code> the Surface as soon as possible after
77calling <code>setSurface</code> or ANativeWindow_fromSurface.
78<p>
79The audio sink is always an output mix, a device-independent mixer object
80similar to that of OpenSL ES.
81
82<h2>Getting started</h2>
83
84<h3>Example code</h3>
85
86<h4>Recommended</h4>
87
88Supported and tested example code, usable as a model
89for your own code, is located in NDK folder
90<code>platforms/android-14/samples/native-media/</code>.
91
92<h4>Not recommended</h4>
93
94The OpenMAX AL 1.0.1 specification contains example code in the
95appendices (see section "References" below for the link to this
96specification).  However, the examples in Appendix D: Sample Code
97use features
98not supported by Android. Some examples also contain
99typographical errors, or use APIs that are likely to change.
100Proceed with caution in referring to these;
101though the code may be helpful in understanding the full OpenMAX AL
102standard, it should not be used as is with Android.
103
104<h3>Adding OpenMAX AL to your application source code</h3>
105
106OpenMAX AL is a C API, but is callable from both C and C++ code.
107<p>
108Add the following lines to your code:
109<pre>
110#include &lt;OMXAL/OpenMAXAL.h&gt;
111#include &lt;OMXAL/OpenMAXAL_Android.h&gt;
112</pre>
113
114<h3>Makefile</h3>
115
116Modify your Android.mk as follows:
117<pre>
118LOCAL_LDLIBS += libOpenMAXAL
119</pre>
120
121<h3>Multimedia content</h3>
122
123The only supported way to supply multimedia content is via an MPEG-2
124transport stream.
125<p>
126Finding or creating useful multimedia content for your application is
127beyond the scope of this article.
128<p>
129Note that it is your responsibility to ensure that you are legally
130permitted to play the content.
131
132<h3>Debugging</h3>
133
134For robustness, we recommend that you examine the <code>XAresult</code>
135value which is returned by most APIs. Use of <code>assert</code>
136vs. more advanced error handling logic is a matter of coding style
137and the particular API; see the Wikipedia article on
138<a href="http://en.wikipedia.org/wiki/Assertion_(computing)">assert</a>
139for more information. In the supplied example, we have used <code>assert</code>
140for "impossible" conditions which would indicate a coding error, and
141explicit error handling for others which are more likely to occur
142in production.
143<p>
144Many API errors result in a log entry, in addition to the non-zero
145result code. These log entries provide additional detail which can
146be especially useful for the more complex APIs such as
147<code>Engine::CreateMediaPlayer</code>.
148<p>
149Use <a href="http://developer.android.com/guide/developing/tools/adb.html">
150adb logcat</a>, the
151<a href="http://developer.android.com/guide/developing/eclipse-adt.html">
152Eclipse ADT plugin</a> LogCat pane, or
153<a href="http://developer.android.com/guide/developing/tools/ddms.html#logcat">
154ddms logcat</a> to see the log.
155
156<h2>Supported features from OpenMAX AL 1.0.1</h2>
157
158This section summarizes available features. In some
159cases, there are limitations which are described in the next
160sub-section.
161
162<h3>Global entry points</h3>
163
164Supported global entry points:
165<ul>
166<li><code>xaCreateEngine</code>
167<li><code>xaQueryNumSupportedEngineInterfaces</code>
168<li><code>xaQuerySupportedEngineInterfaces</code>
169</ul>
170
171<h3>Objects and interfaces</h3>
172
173The following figure indicates objects and interfaces supported by
174Android's OpenMAX AL implementation.  A green cell means the feature
175is supported.
176
177<p>
178<img src="chart3.png" alt="Supported objects and interfaces">
179
180<h3>Limitations</h3>
181
182This section details limitations with respect to the supported
183objects and interfaces from the previous section.
184
185<h4>Audio</h4>
186
187The audio stream type cannot be configured; it is always <code>AudioManager.STREAM_MUSIC</code>.
188<p>
189Effects are not supported.
190
191<h4>Dynamic interface management</h4>
192
193<code>RemoveInterface</code> and <code>ResumeInterface</code> are not supported.
194
195<h4>Engine</h4>
196
197Supported:
198<ul>
199<li><code>CreateMediaPlayer</code>
200</ul>
201
202Not supported:
203<ul>
204<li><code>CreateCameraDevice</code>
205<li><code>CreateRadioDevice</code>
206<li><code>CreateLEDDevice</code>
207<li><code>CreateVibraDevice</code>
208<li><code>CreateMetadataExtractor</code>
209<li><code>CreateExtensionObject</code>
210<li><code>GetImplementationInfo</code>
211</ul>
212
213For <code>CreateMediaPlayer</code>, these restrictions apply:
214<ul>
215<li>audio sink is an output mix data locator
216<li>video sink is a native display data locator
217<li>soundbank, LED array, and vibra sinks must be <code>NULL</code>
218</ul>
219
220<h4>MIME data format</h4>
221
222In the current Android implementation of OpenMAX AL, a media player
223receives its source data as an MPEG-2 transport stream via a
224buffer queue.
225<p>
226The source data locator must be <code>XA_DATALOCATOR_ANDROIDBUFFERQUEUE</code>
227(see "Android extensions" below).
228<p>
229The source data format must be <code>XADataFormat_MIME</code>.
230Initialize <code>mimeType</code> to <code>XA_ANDROID_MIME_MP2TS</code>,
231and <code>containerType</code> to <code>XA_CONTAINERTYPE_MPEG_TS</code>.
232<p>
233The contained transport stream must have a single program with one H.264
234video elementary stream and one AAC audio elementary stream.
235
236<h4>Object</h4>
237
238<code>Resume</code>, <code>RegisterCallback</code>,
239<code>AbortAsyncOperation</code>, <code>SetPriority</code>,
240<code>GetPriority</code>, and <code>SetLossOfControlInterfaces</code>
241are not supported.
242
243<h4>StreamInformation</h4>
244
245Use the StreamInformation interface on a media player object to discover
246when the video metrics (height/width or aspect ratio) are available or
247changed, and to then get the sizes.
248<p>
249
250Supported:
251<ul>
252<li><code>RegisterStreamChangeCallback</code>
253<li><code>QueryMediaContainerInformation</code>
254<li><code>QueryStreamInformation</code>
255<li><code>QueryStreamType</code>
256</ul>
257
258Not supported:
259<ul>
260<li><code>QueryActiveStreams</code>
261<li><code>QueryStreamName</code>
262<li><code>SetActiveStream</code>
263</ul>
264
265<h4>VideoDecoderCapabilities</h4>
266
267This interface on the engine object reports video decoder capabilities
268without interpretation, exactly as claimed by the underlying OpenMAX IL
269implementation.
270<p>
271These fields in <code>XAVideoCodecDescriptor</code> are filled:
272<ul>
273<li><code>codecId</code>
274<li><code>profileSetting</code>
275<li><code>levelSetting</code>
276</ul>
277The other fields are not filled and should be ignored.
278<p>
279Applications should rely on the capabilities documented at
280<a href="http://developer.android.com/guide/appendix/media-formats.html">Android Supported Media Formats</a>,
281not the information reported by this interface.
282
283<h3>Data structures</h3>
284
285Android API level 14 supports these OpenMAX AL 1.0.1 data structures:
286<ul>
287<li>XADataFormat_MIME
288<li>XADataLocator_NativeDisplay
289<li>XADataLocator_OutputMix
290<li>XADataSink
291<li>XADataSource
292<li>XAEngineOption
293<li>XAInterfaceID
294<li>XAMediaContainerInformation
295<li>XANativeHandle
296<li>XA*StreamInformation
297<li>XAVideoCodecDescriptor
298</ul>
299
300<h4>XADataLocator_NativeDisplay</h4>
301
302The native display data locator is used to specify the video sink:
303<pre>
304typedef struct XADataLocator_NativeDisplay_ {
305    XAuint32 locatorType;      // XA_DATALOCATOR_NATIVEDISPLAY
306    XANativeHandle hWindow;    // ANativeWindow *
307    XANativeHandle hDisplay;   // NULL
308} XADataLocator_NativeDisplay;
309</pre>
310
311Set the <code>hWindow</code> field to an
312<code>ANativeWindow *</code> and set <code>hDisplay</code> to <code>NULL</code>.
313You can get a <code>ANativeWindow *</code> handle from an <code>android.view.Surface</code>,
314using this NDK function:
315<pre>
316#include &lt;android/native_window_jni.h&gt;
317
318ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
319</pre>
320Don't forget to free this handle in your shutdown code with <code>ANativeWindow_release</code>.
321
322<h3>Platform configuration</h3>
323
324OpenMAX AL for Android is designed for multi-threaded applications,
325and is thread-safe.
326<p>
327OpenMAX AL for Android supports a single engine per application, and
328up to 32 objects. Available device memory and CPU may further
329restrict the usable number of objects.
330<p>
331<code>xaCreateEngine</code> recognizes, but ignores, these engine options:
332<ul>
333<li><code>XA_ENGINEOPTION_THREADSAFE</code>
334<li><code>XA_ENGINEOPTION_LOSSOFCONTROL</code>
335</ul>
336
337OpenMAX AL and OpenSL ES may be used together in the same application.
338In this case, there is internally a single shared engine object,
339and the 32 object limit is shared between OpenMAX AL and OpenSL ES.
340The application should first create both engines, then use both engines,
341and finally destroy both engines.  The implementation maintains a
342reference count on the shared engine, so that it is correctly destroyed
343at the second destroy.
344
345<h2>Planning for future versions of OpenMAX AL</h2>
346
347The Android native multimedia APIs at level 14 are based on Khronos
348Group OpenMAX AL 1.0.1 (see section "References" below).
349Khronos has released
350a revised version 1.1 of the standard. The revised version
351includes new features, clarifications, correction of
352typographical errors, and some incompatibilities. Most of the
353incompatibilities are relatively minor, or are in areas of OpenMAX AL
354not supported by Android. However, even a small change
355can be significant for an application developer, so it is important
356to prepare for this.
357<p>
358The Android team is committed to preserving future API binary
359compatibility for developers to the extent feasible. It is our
360intention to continue to support future binary compatibility of the
3611.0.1-based API, even as we add support for later versions of the
362standard. An application developed with this version should
363work on future versions of the Android platform, provided that
364you follow the guidelines listed in section "Planning for
365binary compatibility" below.
366<p>
367Note that future source compatibility will <i>not</i> be a goal. That is,
368if you upgrade to a newer version of the NDK, you may need to modify
369your application source code to conform to the new API. We expect
370that most such changes will be minor; see details below.
371
372<h3>Planning for binary compatibility</h3>
373
374We recommend that your application follow these guidelines,
375to improve future binary compatibility:
376<ul>
377<li>
378Use only the documented subset of Android-supported features from
379OpenMAX AL 1.0.1.
380<li>
381Do not depend on a particular result code for an unsuccessful
382operation; be prepared to deal with a different result code.
383<li>
384Application callback handlers generally run in a restricted context,
385and should be written to perform their work quickly and then return
386as soon as possible. Do not do complex operations within a callback
387handler. For example, within a buffer queue completion callback,
388you can enqueue another buffer, but do not create a media player.
389<li>
390Callback handlers should be prepared to be called more or less
391frequently, to receive additional event types, and should ignore
392event types that they do not recognize. Callbacks that are configured
393with an event mask of enabled event types should be prepared to be
394called with multiple event type bits set simultaneously.
395Use "&amp;" to test for each event bit rather than a switch case.
396<li>
397Use prefetch status and callbacks as a general indication of progress, but do
398not depend on specific hard-coded fill levels or callback sequence.
399The meaning of the prefetch status fill level, and the behavior for
400errors that are detected during prefetch, may change.
401</ul>
402
403<h3>Planning for source compatibility</h3>
404
405As mentioned, source code incompatibilities are expected in the next
406version of OpenMAX AL from Khronos Group. Likely areas of change include:
407
408<ul>
409<li>Addition of <code>const</code> to input parameters passed by reference,
410and to <code>XAchar *</code> struct fields used as input values.
411This should not require any changes to your code.
412<li>Substitution of unsigned types for some parameters that are
413currently signed.  You may need to change a parameter type from
414<code>XAint32</code> to <code>XAuint32</code> or similar, or add a cast.
415<li>Additional fields in struct types. For output parameters, these
416new fields can be ignored, but for input parameters the new fields
417will need to be initialized. Fortunately, these are expected to all
418be in areas not supported by Android.
419<li>Interface
420<a href="http://en.wikipedia.org/wiki/Globally_unique_identifier">
421GUIDs</a> will change. Refer to interfaces by symbolic name rather than GUID
422to avoid a dependency.
423<li><code>XAchar</code> will change from <code>unsigned char</code>
424to <code>char</code>. This primarily affects the MIME data format.
425<li><code>XADataFormat_MIME.mimeType</code> will be renamed to <code>pMimeType</code>.
426We recommend that you initialize the <code>XADataFormat_MIME</code>
427data structure using a brace-enclosed comma-separated list of values,
428rather than by field name, to isolate your code from this change.
429In the example code we have used this technique.
430</ul>
431
432<h2>Android extensions</h2>
433
434The API for Android extensions is defined in <code>OMXAL/OpenMAXAL_Android.h</code>
435.
436Consult that file for details on these extensions. Unless otherwise
437noted, all interfaces are "explicit".
438<p>
439Note that use these extensions will limit your application's
440portability to other OpenMAX AL implementations. If this is a concern,
441we advise that you avoid using them, or isolate your use of these
442with <code>#ifdef</code> etc.
443<p>
444The following figure shows which Android-specific interfaces and
445data locators are available for each object type.
446
447<p>
448<img src="chart4.png" alt="Android extensions">
449
450<h3>Android buffer queue data locator and interface</h3>
451
452<h4>Comparison with OpenSL ES buffer queue</h4>
453
454The Android buffer queue data locator and interface are based on
455similar concepts from OpenSL ES 1.0.1, with these differences:
456<ul>
457<li>Though currently usable with only a media player and MPEG-2 transport
458stream data, the Android buffer queue API is designed for flexibility
459so that the API can also apply to other use cases in the future.
460<li>Commands may be
461optionally specified by the application at time of <code>Enqueue</code>.
462Each command consists of an item key and optional item value.
463Command key/value pairs are carried alongside the corresponding buffer in the queue,
464and thus are processed in synchrony with the buffer.
465<li>To enqueue command(s) without associated data, specify
466a buffer address of NULL and buffer size of zero, along
467with at least one command.
468<li>Status may be
469provided by the implementation during a completion callback.
470Each status consists of an item key and optional item value.
471Status key/value pairs are carried alongside
472the corresponding buffer in the queue, and thus are received by the
473application in synchrony with the completion callback.
474<li>The completion callback receives additional parameters:
475buffer address, buffer maximum data size, buffer actual size consumed (or filled by a future
476recorder object), and a <code>void *</code> for application.
477<li>The callback returns a value, which must be <code>XA_RESULT_SUCCESS</code>.
478</ul>
479
480The data locator type code is <code>XA_DATALOCATOR_ANDROIDBUFFERQUEUE</code> and
481the associated structure is <code>XADataLocator_AndroidBufferQueue</code>.
482<p>
483The interface ID is <code>XA_IID_ANDROIDBUFFERQUEUESOURCE</code>.
484
485<h4>Usage</h4>
486
487A typical buffer queue configuration is 8 buffers of 1880 bytes each.
488<p>
489The application enqueues filled buffers of data in MPEG-2 transport
490stream format.  The buffer size must be a multiple of 188 bytes,
491the size of an MPEG-2 transport stream packet. The buffer data must
492be properly aligned on a packet boundary, and formatted per the MPEG-2
493Part 1 specification.
494<p>
495An application may supply zero or one of these item codes
496(command key/value pairs) at <code>Enqueue</code>:
497<dl>
498<dt>XA_ANDROID_ITEMKEY_EOS</dt>
499<dd>End of stream. Informs the decode and rendering components that playback is complete.
500The application must not call <code>Enqueue</code> again.
501There is no associated value, so <code>itemSize</code> must be zero.
502There must be no data buffer alongside the EOS command.
503</dd>
504<dt>XA_ANDROID_ITEMKEY_DISCONTINUITY</dt>
505<dd>Discontinuity. This and following buffers have a new presentation time.
506The new presentation time may be optionally specified as a parameter,
507expressed in <code>itemData</code> as a 64-bit unsigned integer in units of 90 kHz clock ticks.
508The <code>itemSize</code> should be either zero or 8.
509The discontinuity command is intended for seeking to a new point in
510the stream.  The application should flush its internal data, then send
511the discontinuity command prior to, or alongside of, the first buffer
512corresponding to the new stream position.
513The initial packets in the video elementary stream
514should describe an IDR (Instantaneous Decoding Refresh) frame.
515Note that the discontinuity
516command is not intended for stream configuration / format changes;
517for these use <code>XA_ANDROID_ITEMKEY_FORMAT_CHANGE</code>.
518</dd>
519<dt>XA_ANDROID_ITEMKEY_FORMAT_CHANGE</dt>
520<dd>Format change. This and following buffers have a new format,
521for example for MBR (Multiple Bit Rate) or resolution switching.
522</dd>
523</dl>
524<p>
525Upon notification of completion via a registered callback, the now
526consumed buffer is available for the application to re-fill.
527<p>
528The implementation may supply zero or more of these item codes
529(status key/value pairs) to the callback handler:
530<dl>
531<dt>XA_ANDROID_ITEMKEY_BUFFERQUEUEEVENT</dt>
532<dd>Buffer queue event mask. The <code>itemSize</code> is 4, and <code>itemData</code> contains
533the bit-wise "or" of zero or more of the <code>XA_ANDROIDBUFFERQUEUEEVENT_*</code>
534symbols. This event mask explains the reason(s) why the callback handler
535was called.</dd>
536</dl>
537
538<h3>Reporting of extensions</h3>
539
540<code>Engine::QueryNumSupportedExtensions</code>,
541<code>Engine::QuerySupportedExtension</code>,
542<code>Engine::IsExtensionSupported</code> report these extensions:
543<ul>
544<li><code>ANDROID_SDK_LEVEL_#</code>
545where # is the platform API level, 14 or higher
546</ul>
547
548<h2>Programming notes</h2>
549
550These notes supplement the OpenMAX AL 1.0.1 specification,
551available in the "References" section below.
552
553<h3>Objects and interface initialization</h3>
554
555Two aspects of the OpenMAX AL programming model that may be unfamiliar
556to new developers are the distinction between objects and interfaces,
557and the initialization sequence.
558<p>
559Briefly, an OpenMAX AL object is similar to the object concept
560in programming languages such as Java and C++, except an OpenMAX AL
561object is <i>only</i> visible via its associated interfaces. This
562includes the initial interface for all objects, called
563<code>XAObjectItf</code>.  There is no handle for an object itself,
564only a handle to the <code>XAObjectItf</code> interface of the object.
565<p>
566An OpenMAX AL object is first "created", which returns an
567<code>XAObjectItf</code>, then "realized". This is similar to the
568common programming pattern of first constructing an object (which
569should never fail other than for lack of memory or invalid parameters),
570and then completing initialization (which may fail due to lack of
571resources).  The realize step gives the implementation a
572logical place to allocate additional resources if needed.
573<p>
574As part of the API to create an object, an application specifies
575an array of desired interfaces that it plans to acquire later. Note
576that this array does <i>not</i> automatically acquire the interfaces;
577it merely indicates a future intention to acquire them.  Interfaces
578are distinguished as "implicit" or "explicit".  An explicit interface
579<i>must</i> be listed in the array if it will be acquired later.
580An implicit interface need not be listed in the object create array,
581but there is no harm in listing it there.  OpenMAX AL has one more
582kind of interface called "dynamic", which does not need to be
583specified in the object create array, and can be added later after
584the object is created.  The Android implementation provides a
585convenience feature to avoid this complexity; see section "Dynamic
586interfaces at object creation" above.
587<p>
588After the object is created and realized, the application should
589acquire interfaces for each feature it needs, using
590<code>GetInterface</code> on the initial <code>XAObjectItf</code>.
591<p>
592Finally, the object is available for use via its interfaces, though
593note that some objects require further setup.
594Some use cases needs a bit more preparation in
595order to detect connection errors. See the next section
596"Media player prefetch" for details.
597<p>
598After your application is done with the object, you should explicitly
599destroy it; see section "Destroy" below.
600
601<h3>Media player prefetch</h3>
602
603For a media player, <code>Object::Realize</code> allocates resources
604but does not connect to the data source (i.e. "prepare") or begin
605pre-fetching data. These occur once the player state is set to
606either <code>XA_PLAYSTATE_PAUSED</code> or <code>XA_PLAYSTATE_PLAYING</code>.
607<p>
608The prefetch status interface is useful for detecting errors.
609Register a callback and enable at least the
610<code>XA_PREFETCHEVENT_FILLLEVELCHANGE</code> and
611<code>XA_PREFETCHEVENT_STATUSCHANGE</code> events. If both of these
612events are delivered simultaneously, and
613<code>PrefetchStatus::GetFillLevel</code> reports a zero level, and
614<code>PrefetchStatus::GetPrefetchStatus</code> reports
615<code>XA_PREFETCHSTATUS_UNDERFLOW</code>, then this indicates a
616non-recoverable error in the data source or in rendering to the video sink.
617<p>
618The next version of OpenMAX AL is expected to add more explicit
619support for handling errors in the data source. However, for future
620binary compatibility, we intend to continue to support the current
621method for reporting a non-recoverable error.
622<p>
623In summary, a recommended code sequence is:
624<ul>
625<li>Engine::CreateMediaPlayer
626<li>Object:Realize
627<li>Object::GetInterface for XA_IID_PREFETCHSTATUS
628<li>PrefetchStatus::SetCallbackEventsMask
629<li>PrefetchStatus::RegisterCallback
630<li>Object::GetInterface for XA_IID_PLAY
631<li>Play::SetPlayState to XA_PLAYSTATE_PAUSED or XA_PLAYSTATE_PLAYING
632<li>preparation and prefetching occur here; during this time your
633callback will be called with periodic status updates and
634error notifications
635</ul>
636
637<h3>Destroy</h3>
638
639Be sure to destroy all objects on exit from your application.  Objects
640should be destroyed in reverse order of their creation, as it is
641not safe to destroy an object that has any dependent objects.
642For example, destroy in this order: audio players and recorders,
643output mix, then finally the engine.
644<p>
645OpenMAX AL does not support automatic garbage collection or
646<a href="http://en.wikipedia.org/wiki/Reference_counting">reference counting</a>
647of interfaces. After you call <code>Object::Destroy</code>, all extant
648interfaces derived from the associated object become <i>undefined</i>.
649<p>
650The Android OpenMAX AL implementation does not detect the incorrect
651use of such interfaces.
652Continuing to use such interfaces after the object is destroyed will
653cause your application to crash or behave in unpredictable ways.
654<p>
655We recommend that you explicitly set both the primary object interface
656and all associated interfaces to NULL as part of your object
657destruction sequence, to prevent the accidental misuse of a stale
658interface handle.
659
660<h3>Callbacks and threads</h3>
661
662Callback handlers are generally called <i>synchronously</i> with
663respect to the event, that is, at the moment and location where the
664event is detected by the implementation. But this point is
665<i>asynchronous</i> with respect to the application. Thus you should
666use a mutex or other synchronization mechanism to control access
667to any variables shared between the application and the callback
668handler. In the example code, such as for buffer queues, we have
669omitted this synchronization in the interest of simplicity. However,
670proper mutual exclusion would be critical for any production code.
671<p>
672Callback handlers are called from internal
673non-application thread(s) which are not attached to the Dalvik virtual machine and thus
674are ineligible to use JNI. Because these internal threads are
675critical to the integrity of the OpenMAX AL implementation, a callback
676handler should also not block or perform excessive work. Therefore,
677if your callback handler needs to use JNI or do anything significant
678(e.g. beyond an <code>Enqueue</code> or something else simple such as the "Get"
679family), the handler should instead post an event for another thread
680to process.
681<p>
682Note that the converse is safe: a Dalvik application thread which has
683entered JNI is allowed to directly call OpenMAX AL APIs, including
684those which block. However, blocking calls are not recommended from
685the main thread, as they may result in the dreaded "Application Not
686Responding" (ANR).
687<p>
688(Throughout this document, "Dalvik" can be considered to also refer to "ART").
689
690<h3>Performance</h3>
691
692As OpenMAX AL is a native C API, non-Dalvik application threads which
693call OpenMAX AL have no Dalvik-related overhead such as garbage
694collection pauses. However, there is no additional performance
695benefit to the use of OpenMAX AL other than this. In particular, use
696of OpenMAX AL does not result in lower audio or video latency, higher scheduling
697priority, etc. than what the platform generally provides.
698On the other hand, as the Android platform and specific device
699implementations continue to evolve, an OpenMAX AL application can
700expect to benefit from any future system performance improvements.
701
702<h3>Security and permissions</h3>
703
704As far as who can do what, security in Android is done at the
705process level. Java programming language code can't do anything more than native code, nor
706can native code do anything more than Java programming language code. The only differences
707between them are what APIs are available that provide functionality
708that the platform promises to support in the future and across
709different devices.
710<p>
711Applications using OpenMAX AL must request whatever permissions they
712would need for similar non-native APIs.
713Applications that play
714network resources need <code>android.permission.NETWORK</code>.
715Note that the current Android implementation does not directly access the network,
716but many applications that play multimedia receive their data via the network.
717
718<h2>Platform issues</h2>
719
720This section describes known issues in the initial platform
721release which supports these APIs.
722
723<h3>Dynamic interface management</h3>
724
725<code>DynamicInterfaceManagement::AddInterface</code> does not work.
726Instead, specify the interface in the array passed to Create.
727
728<h2>References and resources</h2>
729
730Android:
731<ul>
732<li><a href="http://developer.android.com/resources/index.html">
733Android developer resources</a>
734<li><a href="http://groups.google.com/group/android-developers">
735Android developers discussion group</a>
736<li><a href="http://developer.android.com/sdk/ndk/index.html">Android NDK</a>
737<li><a href="http://groups.google.com/group/android-ndk">
738Android NDK discussion group</a> (for developers of native code, including OpenMAX AL)
739<li><a href="http://code.google.com/p/android/issues/">
740Android open source bug database</a>
741</ul>
742
743Khronos Group:
744<ul>
745<li><a href="http://www.khronos.org/openmax/al/">
746Khronos Group OpenMAX AL Overview</a>
747<li><a href="http://www.khronos.org/registry/omxal/">
748Khronos Group OpenMAX AL 1.0.1 specification</a>
749<li><a href="http://www.khronos.org/message_boards/viewforum.php?f=30">
750Khronos Group public message board for OpenMAX AL</a>
751(please limit to non-Android questions)
752</ul>
753For convenience, we have included a copy of the OpenMAX AL 1.0.1
754specification with the NDK in
755<code>docs/openmaxal/OpenMAX_AL_1_0_1_Specification.pdf</code>.
756
757<p>
758Miscellaneous:
759<ul>
760<li><a href="http://en.wikipedia.org/wiki/Java_Native_Interface">JNI</a>
761<li><a href="http://en.wikipedia.org/wiki/MPEG-2">MPEG-2</a>
762<li><a href="http://en.wikipedia.org/wiki/MPEG_transport_stream">MPEG-2 transport stream</a>
763<li><a href="http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC">H.264</a>
764<li><a href="http://en.wikipedia.org/wiki/Advanced_Audio_Coding">AAC</a>
765</ul>
766
767</body>
768</html>
769