native-media-jni.c revision fcc996296bdbf6c3949ad4312991fdde4ae2e157
19a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten/*
29a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
39a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten *
49a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
59a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * you may not use this file except in compliance with the License.
69a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * You may obtain a copy of the License at
79a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten *
89a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
99a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten *
109a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * Unless required by applicable law or agreed to in writing, software
119a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
129a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * See the License for the specific language governing permissions and
149a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten * limitations under the License.
159a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten */
169a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
179a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten#include <assert.h>
189a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten#include <jni.h>
199a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten#include <pthread.h>
209a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten#include <string.h>
21fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi#define LOG_NDEBUG 0
229a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten#define LOG_TAG "NativeMedia"
239a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten#include <utils/Log.h>
24c09fe859aabccb8b18e6c857d087686b37d48c1fJean-Michel Trivi
259a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten#include "OMXAL/OpenMAXAL.h"
262f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi#include "OMXAL/OpenMAXAL_Android.h"
27c09fe859aabccb8b18e6c857d087686b37d48c1fJean-Michel Trivi
2873d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivi#include <android/native_window_jni.h>
299a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3013a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten// define as 1 if ANativeWindow * is not supported as a video sink
3113a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#define NO_NATIVE_WINDOW 1
3213a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten
339a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// engine interfaces
349a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenstatic XAObjectItf engineObject = NULL;
359a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenstatic XAEngineItf engineEngine;
369a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
379a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// output mix interfaces
389a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenstatic XAObjectItf outputMixObject = NULL;
399a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
409a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// streaming media player interfaces
412f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivistatic XAObjectItf             playerObj = NULL;
422f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivistatic XAPlayItf               playerPlayItf = NULL;
432f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivistatic XAAndroidBufferQueueItf playerBQItf = NULL;
44fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivistatic XAStreamInformationItf  playerStreamInfoItf = NULL;
45fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivistatic XAVolumeItf             playerVolItf;
46f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi// number of required interfaces for the MediaPlayer creation
47fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi#define NB_MAXAL_INTERFACES 3 // XAAndroidBufferQueueItf, XAStreamInformationItf and XAPlayItf
489a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
4973d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivi// cached surface where the video display happens
5013a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#if NO_NATIVE_WINDOW
5113a07de046bce3663b905a892dbaf770a54d982dGlenn Kastenstatic jobject theSurfaceOrSurfaceTexture;
5213a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#else
5373d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivistatic ANativeWindow* theNativeWindow;
5413a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#endif
559a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
56f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi// number of buffers in our buffer queue
57f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi#define NB_BUFFERS 16
58f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi// we're streaming MPEG-2 transport stream data, operate on transport stream block size
59f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi#define MPEG2_TS_BLOCK_SIZE 188
60f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi// determines how much memory we're dedicating to memory caching
61f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi#define BUFFER_SIZE 20*MPEG2_TS_BLOCK_SIZE // 20 is an arbitrary number chosen here
62f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi
63f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi// where we cache in memory the data to play
64f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivichar dataCache[BUFFER_SIZE * NB_BUFFERS];
652f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi// handle of the file to play
662f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel TriviFILE *file;
675b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi// has the app reached the end of the file
685b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivichar reachedEof = 0;
692f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
702f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi// AndroidBufferQueueItf callback for an audio player
712f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel TriviXAresult AndroidBufferQueueCallback(
722f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        XAAndroidBufferQueueItf caller,
73fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        void *pCallbackContext,        /* input */
74fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        void *pBufferContext,          /* input */
75fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        void *pBufferData,             /* input */
76f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        XAuint32 dataSize,             /* input */
77f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        XAuint32 dataUsed,             /* input */
78f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        const XAAndroidBufferItem *pItems,/* input */
79f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        XAuint32 itemsLength           /* input */)
802f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi{
81f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    // assert(BUFFER_SIZE <= dataSize);
82fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    if (pBufferData == NULL) {
83fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        // this is the case when our buffer with the EOS message has been consumed
84fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        return XA_RESULT_SUCCESS;
85fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    }
86fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
87fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi#if 0
88fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    // sample code to use the XAVolumeItf
89fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    XAAndroidBufferQueueState state;
90fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    (*caller)->GetState(caller, &state);
91fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    switch (state.index) {
92fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    case 300:
93fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->SetVolumeLevel(playerVolItf, -600); // -6dB
94fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGV("setting volume to -6dB");
95fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
96fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    case 400:
97fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->SetVolumeLevel(playerVolItf, -1200); // -12dB
98fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGV("setting volume to -12dB");
99fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
100fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    case 500:
101fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->SetVolumeLevel(playerVolItf, 0); // full volume
102fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGV("setting volume to 0dB (full volume)");
103fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
104fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    case 600:
105fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->SetMute(playerVolItf, XA_BOOLEAN_TRUE); // mute
106fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGV("muting player");
107fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
108fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    case 700:
109fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->SetMute(playerVolItf, XA_BOOLEAN_FALSE); // unmute
110fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGV("unmuting player");
111fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
112fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    case 800:
113fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->SetStereoPosition(playerVolItf, -1000);
114fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->EnableStereoPosition(playerVolItf, XA_BOOLEAN_TRUE);
115fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGV("pan sound to the left (hard-left)");
116fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
117fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    case 900:
118fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*playerVolItf)->EnableStereoPosition(playerVolItf, XA_BOOLEAN_FALSE);
119fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGV("disabling stereo position");
120fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
121fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    default:
122fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
123fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    }
124fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi#endif
125fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
126f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    size_t nbRead = fread((void*)pBufferData, 1, BUFFER_SIZE, file);
127fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    if ((nbRead > 0) && (NULL != pBufferData)) {
128fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*caller)->Enqueue(caller, NULL /*pBufferContext*/,
129f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi                pBufferData /*pData*/,
130f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi                nbRead /*dataLength*/,
131f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi                NULL /*pMsg*/,
132f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi                0 /*msgLength*/);
1335b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi    } else if (!reachedEof) {
134f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        // signal EOS
135f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        XAAndroidBufferItem msgEos;
136f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        msgEos.itemKey = XA_ANDROID_ITEMKEY_EOS;
137f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        msgEos.itemSize = 0;
138f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        // EOS message has no parameters, so the total size of the message is the size of the key
139f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        //   plus the size if itemSize, both XAuint32
140fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        (*caller)->Enqueue(caller, NULL /*pBufferContext*/,
141fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                NULL /*pData*/, 0 /*dataLength*/,
142fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                &msgEos /*pMsg*/,
143fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                sizeof(XAuint32)*2 /*msgLength*/);
1445b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi        reachedEof = 1;
1452f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    }
1462f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
1472f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    return XA_RESULT_SUCCESS;
1482f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi}
1492f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
1502f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
151fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivivoid StreamChangeCallback (XAStreamInformationItf caller,
152fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        XAuint32 eventId,
153fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        XAuint32 streamIndex,
154fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        void * pEventData,
155fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        void * pContext )
156fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi{
157fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    if (XA_STREAMCBEVENT_PROPERTYCHANGE == eventId) {
158fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        LOGD("StreamChangeCallback called for stream %lu", streamIndex);
159fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
160fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        XAuint32 domain;
161fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        if (XA_RESULT_SUCCESS == (*caller)->QueryStreamType(caller, streamIndex, &domain)) {
162fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi            if (XA_DOMAINTYPE_VIDEO == domain) {
163fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                XAVideoStreamInformation videoInfo;
164fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                if (XA_RESULT_SUCCESS == (*caller)->QueryStreamInformation(caller, streamIndex,
165fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                        &videoInfo)) {
166fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                    LOGI("Found video size %lu x %lu", videoInfo.width, videoInfo.height);
167fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                }
168fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi            }
169fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        }
170fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    }
171fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi}
172fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
173fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
1749a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// create the engine and output mix objects
1759a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenvoid Java_com_example_nativemedia_NativeMedia_createEngine(JNIEnv* env, jclass clazz)
1769a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten{
1772f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    XAresult res;
1789a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1799a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // create engine
1802f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = xaCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
1812f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
1829a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1839a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // realize the engine
1842f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*engineObject)->Realize(engineObject, XA_BOOLEAN_FALSE);
1852f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
1869a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1879a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // get the engine interface, which is needed in order to create other objects
1882f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*engineObject)->GetInterface(engineObject, XA_IID_ENGINE, &engineEngine);
1892f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
1909a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1919a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // create output mix
1922f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
1932f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
1949a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1959a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // realize the output mix
1962f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*outputMixObject)->Realize(outputMixObject, XA_BOOLEAN_FALSE);
1972f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
1989a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1999a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten}
2009a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2019a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2029a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// create streaming media player
2039a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenjboolean Java_com_example_nativemedia_NativeMedia_createStreamingMediaPlayer(JNIEnv* env,
2049a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        jclass clazz, jstring filename)
2059a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten{
2062f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    XAresult res;
2079a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2089a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // convert Java string to UTF-8
2099a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    const char *utf8 = (*env)->GetStringUTFChars(env, filename, NULL);
2109a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    assert(NULL != utf8);
2119a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2122f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    // open the file to play
2132f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    file = fopen(utf8, "rb");
2142f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    if (file == NULL) {
2152f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        LOGE("Failed to open %s", utf8);
2162f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        return JNI_FALSE;
2172f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    }
2182f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
2192f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    // configure data source
220f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    XADataLocator_AndroidBufferQueue loc_abq = { XA_DATALOCATOR_ANDROIDBUFFERQUEUE, NB_BUFFERS };
221f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    XADataFormat_MIME format_mime = {
222f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi            XA_DATAFORMAT_MIME, (XAchar *)"video/mp2ts", XA_CONTAINERTYPE_MPEG_TS };
2232f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    XADataSource dataSrc = {&loc_abq, &format_mime};
2249a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2259a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // configure audio sink
226f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    XADataLocator_OutputMix loc_outmix = { XA_DATALOCATOR_OUTPUTMIX, outputMixObject };
227f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    XADataSink audioSnk = { &loc_outmix, NULL };
2289a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2299a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // configure image video sink
23073d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivi    XADataLocator_NativeDisplay loc_nd = {
23113a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            XA_DATALOCATOR_NATIVEDISPLAY,        // locatorType
23213a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#if NO_NATIVE_WINDOW
23313a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            (void *) theSurfaceOrSurfaceTexture, // jobject
23413a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            (void *) env                         // JNIEnv *env
23513a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#else
23613a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            // later the video sink can be an ANativeWindow created from a Surface or SurfaceTexture
23713a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            (void*)theNativeWindow,              // hWindow
23813a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            // must be NULL
23913a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            NULL                                 // hDisplay
24013a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#endif
24113a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    };
2429a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    XADataSink imageVideoSink = {&loc_nd, NULL};
2439a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2442f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    // declare interfaces to use
245fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    XAboolean     required[NB_MAXAL_INTERFACES]
246fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                           = {XA_BOOLEAN_TRUE, XA_BOOLEAN_TRUE,           XA_BOOLEAN_TRUE};
247fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    XAInterfaceID iidArray[NB_MAXAL_INTERFACES]
248fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                           = {XA_IID_PLAY,     XA_IID_ANDROIDBUFFERQUEUE, XA_IID_STREAMINFORMATION};
249fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
2502f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
2519a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // create media player
2522f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*engineEngine)->CreateMediaPlayer(engineEngine, &playerObj, &dataSrc,
2532f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi            NULL, &audioSnk, &imageVideoSink, NULL, NULL,
254f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi            NB_MAXAL_INTERFACES /*XAuint32 numInterfaces*/,
2552f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi            iidArray /*const XAInterfaceID *pInterfaceIds*/,
2562f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi            required /*const XAboolean *pInterfaceRequired*/);
2572f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
2589a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2599a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // release the Java string and UTF-8
2609a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    (*env)->ReleaseStringUTFChars(env, filename, utf8);
2619a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2629a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // realize the player
2632f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*playerObj)->Realize(playerObj, XA_BOOLEAN_FALSE);
2642f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
2659a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2669a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // get the play interface
2672f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*playerObj)->GetInterface(playerObj, XA_IID_PLAY, &playerPlayItf);
2682f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
2692f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
270fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    // get the stream information interface (for video size)
271fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    res = (*playerObj)->GetInterface(playerObj, XA_IID_STREAMINFORMATION, &playerStreamInfoItf);
272fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
273fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
274fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    // get the volume interface
275fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    res = (*playerObj)->GetInterface(playerObj, XA_IID_VOLUME, &playerVolItf);
276fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
277fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
2782f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    // get the Android buffer queue interface
2792f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*playerObj)->GetInterface(playerObj, XA_IID_ANDROIDBUFFERQUEUE, &playerBQItf);
2802f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
2812f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
2822f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    // register the callback from which OpenMAX AL can retrieve the data to play
283f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    res = (*playerBQItf)->RegisterCallback(playerBQItf, AndroidBufferQueueCallback, NULL);
284fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
285fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
286fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    // we want to be notified of the video size once it's found, so we register a callback for that
287fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    res = (*playerStreamInfoItf)->RegisterStreamChangeCallback(playerStreamInfoItf,
288fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi            StreamChangeCallback, NULL);
289f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi
290f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    /* Fill our cache */
291f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    if (fread(dataCache, 1, BUFFER_SIZE * NB_BUFFERS, file) <= 0) {
292f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        LOGE("Error filling cache, exiting\n");
293f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        return JNI_FALSE;
294f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    }
295f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    /* Enqueue the content of our cache before starting to play,
296f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi       we don't want to starve the player */
297f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    int i;
298f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    for (i=0 ; i < NB_BUFFERS ; i++) {
299fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        res = (*playerBQItf)->Enqueue(playerBQItf, NULL /*pBufferContext*/,
300fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi                dataCache + i*BUFFER_SIZE, BUFFER_SIZE, NULL, 0);
301f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi        assert(XA_RESULT_SUCCESS == res);
302f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    }
303f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi
3042f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    // prepare the player
3052f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*playerPlayItf)->SetPlayState(playerPlayItf, XA_PLAYSTATE_PAUSED);
3062f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
3072f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi
308fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    // set the volume
309fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    res = (*playerVolItf)->SetVolumeLevel(playerVolItf, 0);//-300);
310fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    assert(XA_RESULT_SUCCESS == res);
311fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
312fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    // start the playback
3132f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    res = (*playerPlayItf)->SetPlayState(playerPlayItf, XA_PLAYSTATE_PLAYING);
3142f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        assert(XA_RESULT_SUCCESS == res);
3159a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3169a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    return JNI_TRUE;
3179a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten}
3189a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3199a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3209a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// set the playing state for the streaming media player
3219a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenvoid Java_com_example_nativemedia_NativeMedia_setPlayingStreamingMediaPlayer(JNIEnv* env,
3229a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        jclass clazz, jboolean isPlaying)
3239a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten{
3242f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    XAresult res;
3259a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3269a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // make sure the streaming media player was created
3272f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    if (NULL != playerPlayItf) {
3289a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3299a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        // set the player's state
3302f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        res = (*playerPlayItf)->SetPlayState(playerPlayItf, isPlaying ?
3319a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            XA_PLAYSTATE_PLAYING : XA_PLAYSTATE_PAUSED);
3322f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        assert(XA_RESULT_SUCCESS == res);
3339a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3349a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
3359a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3369a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten}
3379a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3389a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3399a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// shut down the native media system
3409a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenvoid Java_com_example_nativemedia_NativeMedia_shutdown(JNIEnv* env, jclass clazz)
3419a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten{
3429a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // destroy streaming media player object, and invalidate all associated interfaces
3432f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    if (playerObj != NULL) {
3442f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        (*playerObj)->Destroy(playerObj);
3452f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        playerObj = NULL;
3462f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        playerPlayItf = NULL;
3472f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        playerBQItf = NULL;
3489a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
3499a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3509a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // destroy output mix object, and invalidate all associated interfaces
3519a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    if (outputMixObject != NULL) {
3529a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        (*outputMixObject)->Destroy(outputMixObject);
3539a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        outputMixObject = NULL;
3549a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
3559a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3569a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    // destroy engine object, and invalidate all associated interfaces
3579a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    if (engineObject != NULL) {
3589a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        (*engineObject)->Destroy(engineObject);
3599a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        engineObject = NULL;
3609a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        engineEngine = NULL;
3619a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
3629a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3632f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    // close the file
3642f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    if (file != NULL) {
3652f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi        fclose(file);
3662a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        file = NULL;
3672f4002b9f37501cd15a7e06cd8e19453d2770f30Jean-Michel Trivi    }
36873d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivi
36913a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#if !NO_NATIVE_WINDOW
37073d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivi    // make sure we don't leak native windows
37113a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    if (theNativeWindow != NULL) {
37213a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten        ANativeWindow_release(theNativeWindow);
3732a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        theNativeWindow = NULL;
37413a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    }
37513a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#endif
3769a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten}
3779a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3789a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3799a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten// set the surface
3809a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenvoid Java_com_example_nativemedia_NativeMedia_setSurface(JNIEnv *env, jclass clazz, jobject surface)
3819a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten{
38213a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#if NO_NATIVE_WINDOW
38313a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    theSurfaceOrSurfaceTexture = surface;
38413a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#else
38573d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivi    // obtain a native window from a Java surface
38673d888bb7b15745c6456dc0fab97c39854827d2aJean-Michel Trivi    theNativeWindow = ANativeWindow_fromSurface(env, surface);
38713a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#endif
38813a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten}
38913a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten
39013a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten
39113a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten// set the surface texture
39213a07de046bce3663b905a892dbaf770a54d982dGlenn Kastenvoid Java_com_example_nativemedia_NativeMedia_setSurfaceTexture(JNIEnv *env, jclass clazz,
39313a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten        jobject surfaceTexture)
39413a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten{
39513a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#if NO_NATIVE_WINDOW
39613a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    theSurfaceOrSurfaceTexture = surfaceTexture;
39713a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#else
39813a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    // obtain a native window from a Java surface texture
39913a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    theNativeWindow = ANativeWindow_fromSurfaceTexture(env, surfaceTexture);
40013a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten#endif
4019a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten}
402