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 Kastenpackage com.example.nativemedia;
189a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
199a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.app.Activity;
202a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kastenimport android.graphics.SurfaceTexture;
219a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.media.MediaPlayer;
229a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.os.Bundle;
239a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.util.Log;
249a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.view.Surface;
259a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.view.SurfaceHolder;
269a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.view.SurfaceView;
279a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.view.View;
282a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kastenimport android.widget.AdapterView;
292a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kastenimport android.widget.ArrayAdapter;
309a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport android.widget.Button;
312a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kastenimport android.widget.Spinner;
329a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenimport java.io.IOException;
332a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
342a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kastenimport android.content.Context;
352a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3613a07de046bce3663b905a892dbaf770a54d982dGlenn Kastenimport android.graphics.SurfaceTexture;
379a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
382a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kastenimport android.media.MediaPlayer.OnPreparedListener;
392a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kastenimport android.media.MediaPlayer;
402a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
419a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kastenpublic class NativeMedia extends Activity {
422a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    static final String TAG = "NativeMedia";
439a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
442a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    String mSourceString = null;
452a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    String mSinkString = null;
462a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
472a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    // member variables for Java media player
482a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    MediaPlayer mMediaPlayer;
492a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    boolean mMediaPlayerIsPrepared = false;
502a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    SurfaceView mSurfaceView1;
512a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    SurfaceHolder mSurfaceHolder1;
522a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
532a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    // member variables for native media player
542a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    boolean mIsPlayingStreaming = false;
552a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    SurfaceView mSurfaceView2;
562a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    SurfaceHolder mSurfaceHolder2;
572a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
582a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    VideoSink mSelectedVideoSink;
592a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    VideoSink mJavaMediaPlayerVideoSink;
602a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    VideoSink mNativeMediaPlayerVideoSink;
612a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
622a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    SurfaceHolderVideoSink mSurfaceHolder1VideoSink, mSurfaceHolder2VideoSink;
632a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    GLViewVideoSink mGLView1VideoSink, mGLView2VideoSink;
649a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
659a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    /** Called when the activity is first created. */
669a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    @Override
679a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    public void onCreate(Bundle icicle) {
689a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        super.onCreate(icicle);
699a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        setContentView(R.layout.main);
709a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
712a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mGLView1 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview1);
722a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mGLView2 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview2);
732a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
742a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        //setContentView(mGLView);
752a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        //setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
769a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
772a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // initialize native media system
789a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        createEngine();
799a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
802a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // set up the Surface 1 video sink
812a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mSurfaceView1 = (SurfaceView) findViewById(R.id.surfaceview1);
822a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mSurfaceHolder1 = mSurfaceView1.getHolder();
832a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
842a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mSurfaceHolder1.addCallback(new SurfaceHolder.Callback() {
852a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
862a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
872a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" + height);
882a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
892a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
902a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void surfaceCreated(SurfaceHolder holder) {
912a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "surfaceCreated");
922a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                setSurface(holder.getSurface());
932a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
942a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
952a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void surfaceDestroyed(SurfaceHolder holder) {
962a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "surfaceDestroyed");
972a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
982a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
992a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        });
1009a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1012a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // set up the Surface 2 video sink
1022a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mSurfaceView2 = (SurfaceView) findViewById(R.id.surfaceview2);
1032a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mSurfaceHolder2 = mSurfaceView2.getHolder();
1049a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1052a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mSurfaceHolder2.addCallback(new SurfaceHolder.Callback() {
1069a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1072a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
1082a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" + height);
1099a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            }
1109a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1119a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            public void surfaceCreated(SurfaceHolder holder) {
1129a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten                Log.v(TAG, "surfaceCreated");
1139a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten                setSurface(holder.getSurface());
1149a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            }
1159a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1169a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            public void surfaceDestroyed(SurfaceHolder holder) {
1179a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten                Log.v(TAG, "surfaceDestroyed");
1189a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            }
1199a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1209a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        });
1219a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1222a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // create Java media player
1232a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mMediaPlayer = new MediaPlayer();
1249a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1252a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // set up Java media player listeners
1262a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
1279a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
1282a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void onPrepared(MediaPlayer mediaPlayer) {
1292a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                int width = mediaPlayer.getVideoWidth();
1302a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                int height = mediaPlayer.getVideoHeight();
1312a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "onPrepared width=" + width + ", height=" + height);
1322a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
1332a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
1342a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                }
1352a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                mMediaPlayerIsPrepared = true;
1362a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                mediaPlayer.start();
1372a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
1382a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1392a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        });
1402a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1412a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
1422a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1432a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
1442a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "onVideoSizeChanged width=" + width + ", height=" + height);
1452a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
1462a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
1472a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                }
1482a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
1492a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1502a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        });
1512a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1522a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // initialize content source spinner
1532a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        Spinner sourceSpinner = (Spinner) findViewById(R.id.source_spinner);
1542a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(
1552a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                this, R.array.source_array, android.R.layout.simple_spinner_item);
1562a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
1572a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        sourceSpinner.setAdapter(sourceAdapter);
1582a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        sourceSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
1592a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1602a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
1612a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                mSourceString = parent.getItemAtPosition(pos).toString();
1622a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "onItemSelected " + mSourceString);
1632a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
1642a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1652a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void onNothingSelected(AdapterView parent) {
1662a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "onNothingSelected");
1672a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                mSourceString = null;
1682a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
1692a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1702a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        });
1712a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1722a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // initialize video sink spinner
1732a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        Spinner sinkSpinner = (Spinner) findViewById(R.id.sink_spinner);
1742a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        ArrayAdapter<CharSequence> sinkAdapter = ArrayAdapter.createFromResource(
1752a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                this, R.array.sink_array, android.R.layout.simple_spinner_item);
1762a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        sinkAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
1772a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        sinkSpinner.setAdapter(sinkAdapter);
1782a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        sinkSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
1792a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
1802a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
1812a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                mSinkString = parent.getItemAtPosition(pos).toString();
1822a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "onItemSelected " + mSinkString);
1832a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                if ("Surface 1".equals(mSinkString)) {
1842a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mSurfaceHolder1VideoSink == null) {
1852a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        mSurfaceHolder1VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder1);
1869a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten                    }
1872a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mSelectedVideoSink = mSurfaceHolder1VideoSink;
1882a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                } else if ("Surface 2".equals(mSinkString)) {
1892a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mSurfaceHolder2VideoSink == null) {
1902a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        mSurfaceHolder2VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder2);
1912a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    }
1922a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mSelectedVideoSink = mSurfaceHolder2VideoSink;
1932a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                } else if ("SurfaceTexture 1".equals(mSinkString)) {
1942a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mGLView1VideoSink == null) {
1952a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        mGLView1VideoSink = new GLViewVideoSink(mGLView1);
1962a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    }
1972a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mSelectedVideoSink = mGLView1VideoSink;
1982a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                } else if ("SurfaceTexture 2".equals(mSinkString)) {
1992a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mGLView2VideoSink == null) {
2002a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        mGLView2VideoSink = new GLViewVideoSink(mGLView2);
2012a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    }
2022a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mSelectedVideoSink = mGLView2VideoSink;
2032a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                }
2042a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
2059a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2062a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void onNothingSelected(AdapterView parent) {
2072a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                Log.v(TAG, "onNothingSelected");
2082a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                mSinkString = null;
2092a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                mSelectedVideoSink = null;
2109a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            }
2112a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
2129a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        });
2139a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2149a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        // initialize button click handlers
2159a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2162a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // Java MediaPlayer start/pause
2172a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
2182a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        ((Button) findViewById(R.id.start_java)).setOnClickListener(new View.OnClickListener() {
2192a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
2209a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            public void onClick(View view) {
2212a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                if (mJavaMediaPlayerVideoSink == null) {
2222a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mSelectedVideoSink == null) {
2232a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        return;
2242a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    }
2252a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mSelectedVideoSink.useAsSinkForJava(mMediaPlayer);
2262a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mJavaMediaPlayerVideoSink = mSelectedVideoSink;
2272a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                }
2282a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                if (!mMediaPlayerIsPrepared) {
2292a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mSourceString != null) {
2302a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        try {
2312a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                            mMediaPlayer.setDataSource(mSourceString);
2322a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        } catch (IOException e) {
2332a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                            Log.e(TAG, "IOException " + e);
2342a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        }
2352a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        mMediaPlayer.prepareAsync();
2362a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    }
2372a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                } else if (mMediaPlayer.isPlaying()) {
2382a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mMediaPlayer.pause();
2399a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten                } else {
2402a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mMediaPlayer.start();
2419a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten                }
2429a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten            }
2432a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
2449a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        });
2459a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2462a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        // native MediaPlayer start/pause
2479a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2482a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        ((Button) findViewById(R.id.start_native)).setOnClickListener(new View.OnClickListener() {
2492a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
2502a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            boolean created = false;
2512a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            public void onClick(View view) {
2522a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                if (!created) {
2532a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mNativeMediaPlayerVideoSink == null) {
2542a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        if (mSelectedVideoSink == null) {
2552a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                            return;
2562a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        }
2572a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        mSelectedVideoSink.useAsSinkForNative();
2582a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        mNativeMediaPlayerVideoSink = mSelectedVideoSink;
2592a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    }
2602a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    if (mSourceString != null) {
2612a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                        created = createStreamingMediaPlayer(mSourceString);
2622a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    }
2632a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                }
2642a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                if (created) {
2652a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    mIsPlayingStreaming = !mIsPlayingStreaming;
2662a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                    setPlayingStreamingMediaPlayer(mIsPlayingStreaming);
2672a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten                }
2682a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            }
2692a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
2702a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        });
2719a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
272760518cf3f390986328e272aba88da46794361b1Glenn Kasten        // Java MediaPlayer rewind
273760518cf3f390986328e272aba88da46794361b1Glenn Kasten
274760518cf3f390986328e272aba88da46794361b1Glenn Kasten        ((Button) findViewById(R.id.rewind_java)).setOnClickListener(new View.OnClickListener() {
275760518cf3f390986328e272aba88da46794361b1Glenn Kasten
276760518cf3f390986328e272aba88da46794361b1Glenn Kasten            public void onClick(View view) {
277760518cf3f390986328e272aba88da46794361b1Glenn Kasten                if (mMediaPlayerIsPrepared) {
278760518cf3f390986328e272aba88da46794361b1Glenn Kasten                    mMediaPlayer.seekTo(0);
279760518cf3f390986328e272aba88da46794361b1Glenn Kasten                }
280760518cf3f390986328e272aba88da46794361b1Glenn Kasten            }
281760518cf3f390986328e272aba88da46794361b1Glenn Kasten
282760518cf3f390986328e272aba88da46794361b1Glenn Kasten        });
283760518cf3f390986328e272aba88da46794361b1Glenn Kasten
28434294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten        // native MediaPlayer rewind
28534294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten
28634294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten        ((Button) findViewById(R.id.rewind_native)).setOnClickListener(new View.OnClickListener() {
28734294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten
28834294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten            public void onClick(View view) {
28934294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten                if (mNativeMediaPlayerVideoSink != null) {
29034294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten                    rewindStreamingMediaPlayer();
29134294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten                }
29234294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten            }
29334294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten
29434294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten        });
295760518cf3f390986328e272aba88da46794361b1Glenn Kasten
2969a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
2979a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
2989a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    /** Called when the activity is about to be paused. */
2999a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    @Override
3009a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    protected void onPause()
3019a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    {
3022a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mIsPlayingStreaming = false;
3039a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        setPlayingStreamingMediaPlayer(false);
3042a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mGLView1.onPause();
3052a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mGLView2.onPause();
3069a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        super.onPause();
3079a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
3089a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3092a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    @Override
3102a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    protected void onResume() {
3112a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        super.onResume();
3122a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mGLView1.onResume();
3132a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        mGLView2.onResume();
3142a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    }
3152a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3169a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    /** Called when the activity is about to be destroyed. */
3179a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    @Override
3189a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    protected void onDestroy()
3199a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    {
3209a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        shutdown();
3219a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten        super.onDestroy();
3229a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
3239a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3242a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    private MyGLSurfaceView mGLView1, mGLView2;
3252a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3269a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    /** Native methods, implemented in jni folder */
3279a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    public static native void createEngine();
3289a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    public static native boolean createStreamingMediaPlayer(String filename);
3299a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    public static native void setPlayingStreamingMediaPlayer(boolean isPlaying);
3309a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    public static native void shutdown();
3319a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    public static native void setSurface(Surface surface);
33213a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    public static native void setSurfaceTexture(SurfaceTexture surfaceTexture);
33334294d068e5560ee29e1e326b7bf49a7068e6cb0Glenn Kasten    public static native void rewindStreamingMediaPlayer();
3349a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3359a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    /** Load jni .so on initialization */
3369a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    static {
3379a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten         System.loadLibrary("native-media-jni");
3389a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten    }
3399a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten
3402a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    // VideoSink abstracts out the difference between Surface and SurfaceTexture
3412a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    // aka SurfaceHolder and GLSurfaceView
3422a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    static abstract class VideoSink {
3432a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3442a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        abstract void setFixedSize(int width, int height);
3452a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        abstract void useAsSinkForJava(MediaPlayer mediaPlayer);
3462a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        abstract void useAsSinkForNative();
3472a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3482a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    }
3492a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3502a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    static class SurfaceHolderVideoSink extends VideoSink {
3512a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3522a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        private final SurfaceHolder mSurfaceHolder;
3532a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3542a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        SurfaceHolderVideoSink(SurfaceHolder surfaceHolder) {
3552a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            mSurfaceHolder = surfaceHolder;
3562a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3572a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3582a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        void setFixedSize(int width, int height) {
3592a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            mSurfaceHolder.setFixedSize(width, height);
3602a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3612a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3622a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        void useAsSinkForJava(MediaPlayer mediaPlayer) {
3632a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            mediaPlayer.setDisplay(mSurfaceHolder);
3642a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3652a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3662a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        void useAsSinkForNative() {
3672a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            setSurface(mSurfaceHolder.getSurface());
3682a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3692a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3702a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    }
3712a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3722a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    static class GLViewVideoSink extends VideoSink {
3732a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3742a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        private final MyGLSurfaceView mMyGLSurfaceView;
3752a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3762a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        GLViewVideoSink(MyGLSurfaceView myGLSurfaceView) {
3772a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            mMyGLSurfaceView = myGLSurfaceView;
3782a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3792a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3802a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        void setFixedSize(int width, int height) {
3812a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3822a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3832a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        void useAsSinkForJava(MediaPlayer mediaPlayer) {
384543c7826963411caef0c8052bb4866874def7cd7Jamie Gennis            SurfaceTexture st = mMyGLSurfaceView.getSurfaceTexture();
385543c7826963411caef0c8052bb4866874def7cd7Jamie Gennis            Surface s = new Surface(st);
386543c7826963411caef0c8052bb4866874def7cd7Jamie Gennis            mediaPlayer.setSurface(s);
387543c7826963411caef0c8052bb4866874def7cd7Jamie Gennis            s.release();
3882a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3892a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3902a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        void useAsSinkForNative() {
3912a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten            setSurfaceTexture(mMyGLSurfaceView.getSurfaceTexture());
3922a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten        }
3932a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3942a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten    }
3952a1042f54c8e61a0c2a062709367093100ea6f8fGlenn Kasten
3969a709c6410ac6fd3da51dd02dda72071c5bb9310Glenn Kasten}
397