NativeMedia.java revision 8cae77b0b4d0fb72ff2aba2066b65c0d73c98355
197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten/*
297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * Copyright (C) 2010 The Android Open Source Project
397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten *
497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * you may not use this file except in compliance with the License.
697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * You may obtain a copy of the License at
797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten *
897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten *
1097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * Unless required by applicable law or agreed to in writing, software
1197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
1297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * See the License for the specific language governing permissions and
1497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten * limitations under the License.
1597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten */
1697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
1797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenpackage com.example.nativemedia;
1897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
1997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.app.Activity;
20b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kastenimport android.graphics.SurfaceTexture;
2197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.media.MediaPlayer;
2297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.os.Bundle;
2397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.util.Log;
2497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.view.Surface;
2597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.view.SurfaceHolder;
2697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.view.SurfaceView;
2797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.view.View;
28b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kastenimport android.widget.AdapterView;
29b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kastenimport android.widget.ArrayAdapter;
3097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport android.widget.Button;
31b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kastenimport android.widget.Spinner;
3297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenimport java.io.IOException;
33b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
34b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kastenimport android.content.Context;
35b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
36ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kastenimport android.graphics.SurfaceTexture;
3797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
38b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kastenimport android.media.MediaPlayer.OnPreparedListener;
39b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kastenimport android.media.MediaPlayer;
40b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
4197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kastenpublic class NativeMedia extends Activity {
42b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    static final String TAG = "NativeMedia";
4397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
44b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    String mSourceString = null;
45b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    String mSinkString = null;
46b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
47b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    // member variables for Java media player
48b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    MediaPlayer mMediaPlayer;
49b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    boolean mMediaPlayerIsPrepared = false;
50b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    SurfaceView mSurfaceView1;
51b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    SurfaceHolder mSurfaceHolder1;
52b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
53b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    // member variables for native media player
54b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    boolean mIsPlayingStreaming = false;
55b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    SurfaceView mSurfaceView2;
56b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    SurfaceHolder mSurfaceHolder2;
57b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
58b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    VideoSink mSelectedVideoSink;
59b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    VideoSink mJavaMediaPlayerVideoSink;
60b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    VideoSink mNativeMediaPlayerVideoSink;
61b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
62b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    SurfaceHolderVideoSink mSurfaceHolder1VideoSink, mSurfaceHolder2VideoSink;
63b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    GLViewVideoSink mGLView1VideoSink, mGLView2VideoSink;
6497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
6597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Called when the activity is first created. */
6697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    @Override
6797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public void onCreate(Bundle icicle) {
6897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        super.onCreate(icicle);
6997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        setContentView(R.layout.main);
7097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
71b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView1 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview1);
72b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView2 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview2);
73b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
74b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        //setContentView(mGLView);
75b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        //setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
7697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
77b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // initialize native media system
7897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        createEngine();
7997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
80b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // set up the Surface 1 video sink
81b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceView1 = (SurfaceView) findViewById(R.id.surfaceview1);
82b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceHolder1 = mSurfaceView1.getHolder();
83b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
84b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceHolder1.addCallback(new SurfaceHolder.Callback() {
85b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
86b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
87b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" + height);
88b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
89b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
90b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void surfaceCreated(SurfaceHolder holder) {
91b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "surfaceCreated");
92b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                setSurface(holder.getSurface());
93b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
94b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
95b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void surfaceDestroyed(SurfaceHolder holder) {
96b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "surfaceDestroyed");
97b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
98b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
99b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
10097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
101b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // set up the Surface 2 video sink
102b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceView2 = (SurfaceView) findViewById(R.id.surfaceview2);
103b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceHolder2 = mSurfaceView2.getHolder();
10497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
105b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceHolder2.addCallback(new SurfaceHolder.Callback() {
10697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
107b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
108b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" + height);
10997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
11097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
11197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            public void surfaceCreated(SurfaceHolder holder) {
11297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                Log.v(TAG, "surfaceCreated");
11397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                setSurface(holder.getSurface());
11497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
11597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
11697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            public void surfaceDestroyed(SurfaceHolder holder) {
11797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                Log.v(TAG, "surfaceDestroyed");
11897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
11997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
12097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        });
12197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
122b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // create Java media player
123b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mMediaPlayer = new MediaPlayer();
12497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
125b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // set up Java media player listeners
126b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
12797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
128b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onPrepared(MediaPlayer mediaPlayer) {
129b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                int width = mediaPlayer.getVideoWidth();
130b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                int height = mediaPlayer.getVideoHeight();
131b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onPrepared width=" + width + ", height=" + height);
132b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
133b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
134b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
135b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mMediaPlayerIsPrepared = true;
136b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mediaPlayer.start();
137b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
138b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
139b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
140b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
141b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
142b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
143b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
144b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onVideoSizeChanged width=" + width + ", height=" + height);
145b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
146b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
147b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
148b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
149b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
150b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
151b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
152b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // initialize content source spinner
153b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        Spinner sourceSpinner = (Spinner) findViewById(R.id.source_spinner);
154b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(
155b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                this, R.array.source_array, android.R.layout.simple_spinner_item);
156b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
157b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sourceSpinner.setAdapter(sourceAdapter);
158b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sourceSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
159b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
160b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
161b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSourceString = parent.getItemAtPosition(pos).toString();
162b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onItemSelected " + mSourceString);
163b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
164b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
165b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onNothingSelected(AdapterView parent) {
166b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onNothingSelected");
167b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSourceString = null;
168b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
169b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
170b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
171b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
172b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // initialize video sink spinner
173b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        Spinner sinkSpinner = (Spinner) findViewById(R.id.sink_spinner);
174b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ArrayAdapter<CharSequence> sinkAdapter = ArrayAdapter.createFromResource(
175b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                this, R.array.sink_array, android.R.layout.simple_spinner_item);
176b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sinkAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
177b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sinkSpinner.setAdapter(sinkAdapter);
178b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sinkSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
179b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
180b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
181b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSinkString = parent.getItemAtPosition(pos).toString();
182b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onItemSelected " + mSinkString);
183b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if ("Surface 1".equals(mSinkString)) {
184b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSurfaceHolder1VideoSink == null) {
185b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mSurfaceHolder1VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder1);
18697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                    }
187b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mSurfaceHolder1VideoSink;
188b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if ("Surface 2".equals(mSinkString)) {
189b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSurfaceHolder2VideoSink == null) {
190b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mSurfaceHolder2VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder2);
191b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
192b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mSurfaceHolder2VideoSink;
193b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if ("SurfaceTexture 1".equals(mSinkString)) {
194b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mGLView1VideoSink == null) {
195b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mGLView1VideoSink = new GLViewVideoSink(mGLView1);
196b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
197b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mGLView1VideoSink;
198b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if ("SurfaceTexture 2".equals(mSinkString)) {
199b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mGLView2VideoSink == null) {
200b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mGLView2VideoSink = new GLViewVideoSink(mGLView2);
201b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
202b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mGLView2VideoSink;
203b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
204b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
20597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
206b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onNothingSelected(AdapterView parent) {
207b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onNothingSelected");
208b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSinkString = null;
209b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSelectedVideoSink = null;
21097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
211b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
21297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        });
21397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
21497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        // initialize button click handlers
21597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
216b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // Java MediaPlayer start/pause
217b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
218b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ((Button) findViewById(R.id.start_java)).setOnClickListener(new View.OnClickListener() {
219b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
22097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            public void onClick(View view) {
221b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (mJavaMediaPlayerVideoSink == null) {
222b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSelectedVideoSink == null) {
223b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        return;
224b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
225b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink.useAsSinkForJava(mMediaPlayer);
226b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mJavaMediaPlayerVideoSink = mSelectedVideoSink;
227b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
228b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (!mMediaPlayerIsPrepared) {
229b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSourceString != null) {
230b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        try {
231b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                            mMediaPlayer.setDataSource(mSourceString);
232b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        } catch (IOException e) {
233b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                            Log.e(TAG, "IOException " + e);
234b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        }
235b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mMediaPlayer.prepareAsync();
236b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
237b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if (mMediaPlayer.isPlaying()) {
238b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mMediaPlayer.pause();
23997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                } else {
240b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mMediaPlayer.start();
24197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                }
24297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
243b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
24497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        });
24597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
246b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // native MediaPlayer start/pause
24797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
248b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ((Button) findViewById(R.id.start_native)).setOnClickListener(new View.OnClickListener() {
249b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
250b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            boolean created = false;
251b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onClick(View view) {
252b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (!created) {
253b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mNativeMediaPlayerVideoSink == null) {
254b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        if (mSelectedVideoSink == null) {
255b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                            return;
256b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        }
257b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mSelectedVideoSink.useAsSinkForNative();
258b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mNativeMediaPlayerVideoSink = mSelectedVideoSink;
259b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
260b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSourceString != null) {
261b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        created = createStreamingMediaPlayer(mSourceString);
262b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
263b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
264b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (created) {
265b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mIsPlayingStreaming = !mIsPlayingStreaming;
266b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    setPlayingStreamingMediaPlayer(mIsPlayingStreaming);
267b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
268b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
269b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
270b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
27197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
2723bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten        // Java MediaPlayer rewind
2733bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
2743bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten        ((Button) findViewById(R.id.rewind_java)).setOnClickListener(new View.OnClickListener() {
2753bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
2763bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten            public void onClick(View view) {
2773bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten                if (mMediaPlayerIsPrepared) {
2783bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten                    mMediaPlayer.seekTo(0);
2793bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten                }
2803bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten            }
2813bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
2823bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten        });
2833bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
284ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten        // native MediaPlayer rewind
285ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten
286ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten        ((Button) findViewById(R.id.rewind_native)).setOnClickListener(new View.OnClickListener() {
287ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten
288ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten            public void onClick(View view) {
289ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten                if (mNativeMediaPlayerVideoSink != null) {
290ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten                    rewindStreamingMediaPlayer();
291ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten                }
292ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten            }
293ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten
294ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten        });
2953bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
29697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
29797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
29897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Called when the activity is about to be paused. */
29997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    @Override
30097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    protected void onPause()
30197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    {
302b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mIsPlayingStreaming = false;
30397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        setPlayingStreamingMediaPlayer(false);
304b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView1.onPause();
305b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView2.onPause();
30697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        super.onPause();
30797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
30897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
309b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    @Override
310b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    protected void onResume() {
311b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        super.onResume();
312b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView1.onResume();
313b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView2.onResume();
314b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
315b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
31697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Called when the activity is about to be destroyed. */
31797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    @Override
31897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    protected void onDestroy()
31997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    {
32097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        shutdown();
32197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        super.onDestroy();
32297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
32397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
324b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    private MyGLSurfaceView mGLView1, mGLView2;
325b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
32697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Native methods, implemented in jni folder */
32797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void createEngine();
32897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native boolean createStreamingMediaPlayer(String filename);
32997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void setPlayingStreamingMediaPlayer(boolean isPlaying);
33097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void shutdown();
33197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void setSurface(Surface surface);
332ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    public static native void setSurfaceTexture(SurfaceTexture surfaceTexture);
333ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten    public static native void rewindStreamingMediaPlayer();
33497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
33597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Load jni .so on initialization */
33697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    static {
33797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten         System.loadLibrary("native-media-jni");
33897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
33997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
340b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    // VideoSink abstracts out the difference between Surface and SurfaceTexture
341b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    // aka SurfaceHolder and GLSurfaceView
342b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    static abstract class VideoSink {
343b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
344b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        abstract void setFixedSize(int width, int height);
345b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        abstract void useAsSinkForJava(MediaPlayer mediaPlayer);
346b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        abstract void useAsSinkForNative();
347b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
348b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
349b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
350b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    static class SurfaceHolderVideoSink extends VideoSink {
351b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
352b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        private final SurfaceHolder mSurfaceHolder;
353b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
354b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        SurfaceHolderVideoSink(SurfaceHolder surfaceHolder) {
355b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mSurfaceHolder = surfaceHolder;
356b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
357b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
358b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void setFixedSize(int width, int height) {
359b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mSurfaceHolder.setFixedSize(width, height);
360b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
361b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
362b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForJava(MediaPlayer mediaPlayer) {
363b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mediaPlayer.setDisplay(mSurfaceHolder);
364b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
365b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
366b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForNative() {
367b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            setSurface(mSurfaceHolder.getSurface());
368b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
369b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
370b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
371b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
372b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    static class GLViewVideoSink extends VideoSink {
373b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
374b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        private final MyGLSurfaceView mMyGLSurfaceView;
375b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
376b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        GLViewVideoSink(MyGLSurfaceView myGLSurfaceView) {
377b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mMyGLSurfaceView = myGLSurfaceView;
378b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
379b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
380b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void setFixedSize(int width, int height) {
381b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
382b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
383b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForJava(MediaPlayer mediaPlayer) {
3848cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            SurfaceTexture st = mMyGLSurfaceView.getSurfaceTexture();
3858cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            Surface s = new Surface(st);
3868cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            mediaPlayer.setSurface(s);
3878cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            s.release();
388b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
389b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
390b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForNative() {
391b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            setSurfaceTexture(mMyGLSurfaceView.getSurfaceTexture());
392b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
393b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
394b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
395b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
39697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten}
397