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 <media/NdkMedia*.h>) 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™ 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 <OMXAL/OpenMAXAL.h> 111#include <OMXAL/OpenMAXAL_Android.h> 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 <android/native_window_jni.h> 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 "&" 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