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) {
8768686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" +
8868686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten                        height);
89b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
90b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
91b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void surfaceCreated(SurfaceHolder holder) {
92b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "surfaceCreated");
93b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                setSurface(holder.getSurface());
94b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
95b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
96b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void surfaceDestroyed(SurfaceHolder holder) {
97b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "surfaceDestroyed");
98b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
99b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
100b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
10197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
102b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // set up the Surface 2 video sink
103b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceView2 = (SurfaceView) findViewById(R.id.surfaceview2);
104b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceHolder2 = mSurfaceView2.getHolder();
10597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
106b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mSurfaceHolder2.addCallback(new SurfaceHolder.Callback() {
10797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
108b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
10968686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten                Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" +
11068686bd0cb31f99f07ebc176176f8b51adf8d1d5Glenn Kasten                        height);
11197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
11297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
11397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            public void surfaceCreated(SurfaceHolder holder) {
11497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                Log.v(TAG, "surfaceCreated");
11597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                setSurface(holder.getSurface());
11697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
11797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
11897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            public void surfaceDestroyed(SurfaceHolder holder) {
11997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                Log.v(TAG, "surfaceDestroyed");
12097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
12197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
12297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        });
12397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
124b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // create Java media player
125b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mMediaPlayer = new MediaPlayer();
12697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
127b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // set up Java media player listeners
128b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
12997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
130b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onPrepared(MediaPlayer mediaPlayer) {
131b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                int width = mediaPlayer.getVideoWidth();
132b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                int height = mediaPlayer.getVideoHeight();
133b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onPrepared width=" + width + ", height=" + height);
134b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
135b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
136b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
137b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mMediaPlayerIsPrepared = true;
138b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mediaPlayer.start();
139b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
140b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
141b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
142b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
143b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
144b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
145b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
146b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onVideoSizeChanged width=" + width + ", height=" + height);
147b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
148b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mJavaMediaPlayerVideoSink.setFixedSize(width, height);
149b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
150b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
151b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
152b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
153b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
154b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // initialize content source spinner
155b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        Spinner sourceSpinner = (Spinner) findViewById(R.id.source_spinner);
156b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(
157b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                this, R.array.source_array, android.R.layout.simple_spinner_item);
158b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
159b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sourceSpinner.setAdapter(sourceAdapter);
160b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sourceSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
161b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
162b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
163b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSourceString = parent.getItemAtPosition(pos).toString();
164b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onItemSelected " + mSourceString);
165b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
166b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
167b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onNothingSelected(AdapterView parent) {
168b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onNothingSelected");
169b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSourceString = null;
170b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
171b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
172b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
173b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
174b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // initialize video sink spinner
175b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        Spinner sinkSpinner = (Spinner) findViewById(R.id.sink_spinner);
176b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ArrayAdapter<CharSequence> sinkAdapter = ArrayAdapter.createFromResource(
177b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                this, R.array.sink_array, android.R.layout.simple_spinner_item);
178b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sinkAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
179b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sinkSpinner.setAdapter(sinkAdapter);
180b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        sinkSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
181b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
182b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
183b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSinkString = parent.getItemAtPosition(pos).toString();
184b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onItemSelected " + mSinkString);
185b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if ("Surface 1".equals(mSinkString)) {
186b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSurfaceHolder1VideoSink == null) {
187b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mSurfaceHolder1VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder1);
18897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                    }
189b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mSurfaceHolder1VideoSink;
190b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if ("Surface 2".equals(mSinkString)) {
191b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSurfaceHolder2VideoSink == null) {
192b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mSurfaceHolder2VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder2);
193b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
194b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mSurfaceHolder2VideoSink;
195b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if ("SurfaceTexture 1".equals(mSinkString)) {
196b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mGLView1VideoSink == null) {
197b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mGLView1VideoSink = new GLViewVideoSink(mGLView1);
198b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
199b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mGLView1VideoSink;
200b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if ("SurfaceTexture 2".equals(mSinkString)) {
201b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mGLView2VideoSink == null) {
202b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mGLView2VideoSink = new GLViewVideoSink(mGLView2);
203b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
204b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink = mGLView2VideoSink;
205b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
206b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
20797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
208b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onNothingSelected(AdapterView parent) {
209b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                Log.v(TAG, "onNothingSelected");
210b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSinkString = null;
211b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                mSelectedVideoSink = null;
21297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
213b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
21497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        });
21597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
21697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        // initialize button click handlers
21797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
218b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // Java MediaPlayer start/pause
219b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
220b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ((Button) findViewById(R.id.start_java)).setOnClickListener(new View.OnClickListener() {
221b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
22297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            public void onClick(View view) {
223b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (mJavaMediaPlayerVideoSink == null) {
224b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSelectedVideoSink == null) {
225b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        return;
226b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
227b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mSelectedVideoSink.useAsSinkForJava(mMediaPlayer);
228b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mJavaMediaPlayerVideoSink = mSelectedVideoSink;
229b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
230b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (!mMediaPlayerIsPrepared) {
231b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSourceString != null) {
232b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        try {
233b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                            mMediaPlayer.setDataSource(mSourceString);
234b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        } catch (IOException e) {
235b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                            Log.e(TAG, "IOException " + e);
236b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        }
237b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mMediaPlayer.prepareAsync();
238b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
239b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                } else if (mMediaPlayer.isPlaying()) {
240b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mMediaPlayer.pause();
24197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                } else {
242b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mMediaPlayer.start();
24397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten                }
24497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten            }
245b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
24697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        });
24797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
248b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        // native MediaPlayer start/pause
24997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
250b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        ((Button) findViewById(R.id.start_native)).setOnClickListener(new View.OnClickListener() {
251b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
252b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            boolean created = false;
253b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            public void onClick(View view) {
254b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (!created) {
255b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mNativeMediaPlayerVideoSink == null) {
256b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        if (mSelectedVideoSink == null) {
257b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                            return;
258b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        }
259b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mSelectedVideoSink.useAsSinkForNative();
260b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        mNativeMediaPlayerVideoSink = mSelectedVideoSink;
261b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
262b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    if (mSourceString != null) {
263b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                        created = createStreamingMediaPlayer(mSourceString);
264b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    }
265b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
266b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                if (created) {
267b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    mIsPlayingStreaming = !mIsPlayingStreaming;
268b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                    setPlayingStreamingMediaPlayer(mIsPlayingStreaming);
269b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten                }
270b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            }
271b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
272b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        });
27397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
2743bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten        // Java MediaPlayer rewind
2753bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
2763bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten        ((Button) findViewById(R.id.rewind_java)).setOnClickListener(new View.OnClickListener() {
2773bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
2783bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten            public void onClick(View view) {
2793bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten                if (mMediaPlayerIsPrepared) {
2803bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten                    mMediaPlayer.seekTo(0);
2813bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten                }
2823bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten            }
2833bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
2843bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten        });
2853bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
286ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten        // native MediaPlayer rewind
287ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten
288ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten        ((Button) findViewById(R.id.rewind_native)).setOnClickListener(new View.OnClickListener() {
289ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten
290ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten            public void onClick(View view) {
291ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten                if (mNativeMediaPlayerVideoSink != null) {
292ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten                    rewindStreamingMediaPlayer();
293ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten                }
294ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten            }
295ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten
296ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten        });
2973bbd3bb7fcb082eba313614f072c11c41b38ebfeGlenn Kasten
29897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
29997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
30097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Called when the activity is about to be paused. */
30197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    @Override
30297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    protected void onPause()
30397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    {
304b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mIsPlayingStreaming = false;
30597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        setPlayingStreamingMediaPlayer(false);
306b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView1.onPause();
307b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView2.onPause();
30897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        super.onPause();
30997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
31097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
311b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    @Override
312b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    protected void onResume() {
313b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        super.onResume();
314b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView1.onResume();
315b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        mGLView2.onResume();
316b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
317b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
31897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Called when the activity is about to be destroyed. */
31997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    @Override
32097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    protected void onDestroy()
32197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    {
32297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        shutdown();
32397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten        super.onDestroy();
32497bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
32597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
326b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    private MyGLSurfaceView mGLView1, mGLView2;
327b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
32897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Native methods, implemented in jni folder */
32997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void createEngine();
33097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native boolean createStreamingMediaPlayer(String filename);
33197bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void setPlayingStreamingMediaPlayer(boolean isPlaying);
33297bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void shutdown();
33397bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    public static native void setSurface(Surface surface);
334ac8c7318e1d7ec1358bbf924e1bc2cee45b44fc6Glenn Kasten    public static native void rewindStreamingMediaPlayer();
33597bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
33697bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    /** Load jni .so on initialization */
33797bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    static {
33897bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten         System.loadLibrary("native-media-jni");
33997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten    }
34097bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten
341b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    // VideoSink abstracts out the difference between Surface and SurfaceTexture
342b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    // aka SurfaceHolder and GLSurfaceView
343b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    static abstract class VideoSink {
344b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
345b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        abstract void setFixedSize(int width, int height);
346b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        abstract void useAsSinkForJava(MediaPlayer mediaPlayer);
347b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        abstract void useAsSinkForNative();
348b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
349b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
350b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
351b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    static class SurfaceHolderVideoSink extends VideoSink {
352b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
353b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        private final SurfaceHolder mSurfaceHolder;
354b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
355b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        SurfaceHolderVideoSink(SurfaceHolder surfaceHolder) {
356b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mSurfaceHolder = surfaceHolder;
357b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
358b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
359b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void setFixedSize(int width, int height) {
360b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mSurfaceHolder.setFixedSize(width, height);
361b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
362b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
363b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForJava(MediaPlayer mediaPlayer) {
364b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mediaPlayer.setDisplay(mSurfaceHolder);
365b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
366b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
367b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForNative() {
368b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            setSurface(mSurfaceHolder.getSurface());
369b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
370b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
371b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
372b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
373b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    static class GLViewVideoSink extends VideoSink {
374b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
375b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        private final MyGLSurfaceView mMyGLSurfaceView;
376b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
377b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        GLViewVideoSink(MyGLSurfaceView myGLSurfaceView) {
378b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten            mMyGLSurfaceView = myGLSurfaceView;
379b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
380b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
381b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void setFixedSize(int width, int height) {
382b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
383b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
384b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForJava(MediaPlayer mediaPlayer) {
3858cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            SurfaceTexture st = mMyGLSurfaceView.getSurfaceTexture();
3868cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            Surface s = new Surface(st);
3878cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            mediaPlayer.setSurface(s);
3888cae77b0b4d0fb72ff2aba2066b65c0d73c98355Jamie Gennis            s.release();
389b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
390b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
391b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        void useAsSinkForNative() {
392738e761c42f146b655fa01707b82be25c2200d63Glenn Kasten            Surface surface = new Surface(mMyGLSurfaceView.getSurfaceTexture());
393738e761c42f146b655fa01707b82be25c2200d63Glenn Kasten            setSurface(surface);
394738e761c42f146b655fa01707b82be25c2200d63Glenn Kasten            surface.release();
395b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten        }
396b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
397b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten    }
398b66b0745d45f4c0c7620749185f7fb3306804ce3Glenn Kasten
39997bdbe13fc48640babe6c1ce270660476f04c3dfGlenn Kasten}
400