OSDN Git Service

6120776dd0548ad8acaa7dddb71b68b171fef41d
[android-x86/system-media.git] / wilhelm / tests / native-media / src / com / example / nativemedia / NativeMedia.java
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.example.nativemedia;
18
19 import android.app.Activity;
20 import android.graphics.SurfaceTexture;
21 import android.media.MediaPlayer;
22 import android.os.Bundle;
23 import android.util.Log;
24 import android.view.Surface;
25 import android.view.SurfaceHolder;
26 import android.view.SurfaceView;
27 import android.view.View;
28 import android.widget.AdapterView;
29 import android.widget.ArrayAdapter;
30 import android.widget.Button;
31 import android.widget.Spinner;
32 import java.io.IOException;
33
34 import android.content.Context;
35
36 import android.graphics.SurfaceTexture;
37
38 import android.media.MediaPlayer.OnPreparedListener;
39 import android.media.MediaPlayer;
40
41 public class NativeMedia extends Activity {
42     static final String TAG = "NativeMedia";
43
44     String mSourceString = null;
45     String mSinkString = null;
46
47     // member variables for Java media player
48     MediaPlayer mMediaPlayer;
49     boolean mMediaPlayerIsPrepared = false;
50     SurfaceView mSurfaceView1;
51     SurfaceHolder mSurfaceHolder1;
52
53     // member variables for native media player
54     boolean mIsPlayingStreaming = false;
55     SurfaceView mSurfaceView2;
56     SurfaceHolder mSurfaceHolder2;
57
58     VideoSink mSelectedVideoSink;
59     VideoSink mJavaMediaPlayerVideoSink;
60     VideoSink mNativeMediaPlayerVideoSink;
61
62     SurfaceHolderVideoSink mSurfaceHolder1VideoSink, mSurfaceHolder2VideoSink;
63     GLViewVideoSink mGLView1VideoSink, mGLView2VideoSink;
64
65     /** Called when the activity is first created. */
66     @Override
67     public void onCreate(Bundle icicle) {
68         super.onCreate(icicle);
69         setContentView(R.layout.main);
70
71         mGLView1 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview1);
72         mGLView2 = (MyGLSurfaceView) findViewById(R.id.glsurfaceview2);
73
74         //setContentView(mGLView);
75         //setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
76
77         // initialize native media system
78         createEngine();
79
80         // set up the Surface 1 video sink
81         mSurfaceView1 = (SurfaceView) findViewById(R.id.surfaceview1);
82         mSurfaceHolder1 = mSurfaceView1.getHolder();
83
84         mSurfaceHolder1.addCallback(new SurfaceHolder.Callback() {
85
86             public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
87                 Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" + height);
88             }
89
90             public void surfaceCreated(SurfaceHolder holder) {
91                 Log.v(TAG, "surfaceCreated");
92                 setSurface(holder.getSurface());
93             }
94
95             public void surfaceDestroyed(SurfaceHolder holder) {
96                 Log.v(TAG, "surfaceDestroyed");
97             }
98
99         });
100
101         // set up the Surface 2 video sink
102         mSurfaceView2 = (SurfaceView) findViewById(R.id.surfaceview2);
103         mSurfaceHolder2 = mSurfaceView2.getHolder();
104
105         mSurfaceHolder2.addCallback(new SurfaceHolder.Callback() {
106
107             public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
108                 Log.v(TAG, "surfaceChanged format=" + format + ", width=" + width + ", height=" + height);
109             }
110
111             public void surfaceCreated(SurfaceHolder holder) {
112                 Log.v(TAG, "surfaceCreated");
113                 setSurface(holder.getSurface());
114             }
115
116             public void surfaceDestroyed(SurfaceHolder holder) {
117                 Log.v(TAG, "surfaceDestroyed");
118             }
119
120         });
121
122         // create Java media player
123         mMediaPlayer = new MediaPlayer();
124
125         // set up Java media player listeners
126         mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
127
128             public void onPrepared(MediaPlayer mediaPlayer) {
129                 int width = mediaPlayer.getVideoWidth();
130                 int height = mediaPlayer.getVideoHeight();
131                 Log.v(TAG, "onPrepared width=" + width + ", height=" + height);
132                 if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
133                     mJavaMediaPlayerVideoSink.setFixedSize(width, height);
134                 }
135                 mMediaPlayerIsPrepared = true;
136                 mediaPlayer.start();
137             }
138
139         });
140
141         mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
142
143             public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
144                 Log.v(TAG, "onVideoSizeChanged width=" + width + ", height=" + height);
145                 if (width != 0 && height != 0 && mJavaMediaPlayerVideoSink != null) {
146                     mJavaMediaPlayerVideoSink.setFixedSize(width, height);
147                 }
148             }
149
150         });
151
152         // initialize content source spinner
153         Spinner sourceSpinner = (Spinner) findViewById(R.id.source_spinner);
154         ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(
155                 this, R.array.source_array, android.R.layout.simple_spinner_item);
156         sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
157         sourceSpinner.setAdapter(sourceAdapter);
158         sourceSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
159
160             public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
161                 mSourceString = parent.getItemAtPosition(pos).toString();
162                 Log.v(TAG, "onItemSelected " + mSourceString);
163             }
164
165             public void onNothingSelected(AdapterView parent) {
166                 Log.v(TAG, "onNothingSelected");
167                 mSourceString = null;
168             }
169
170         });
171
172         // initialize video sink spinner
173         Spinner sinkSpinner = (Spinner) findViewById(R.id.sink_spinner);
174         ArrayAdapter<CharSequence> sinkAdapter = ArrayAdapter.createFromResource(
175                 this, R.array.sink_array, android.R.layout.simple_spinner_item);
176         sinkAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
177         sinkSpinner.setAdapter(sinkAdapter);
178         sinkSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
179
180             public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
181                 mSinkString = parent.getItemAtPosition(pos).toString();
182                 Log.v(TAG, "onItemSelected " + mSinkString);
183                 if ("Surface 1".equals(mSinkString)) {
184                     if (mSurfaceHolder1VideoSink == null) {
185                         mSurfaceHolder1VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder1);
186                     }
187                     mSelectedVideoSink = mSurfaceHolder1VideoSink;
188                 } else if ("Surface 2".equals(mSinkString)) {
189                     if (mSurfaceHolder2VideoSink == null) {
190                         mSurfaceHolder2VideoSink = new SurfaceHolderVideoSink(mSurfaceHolder2);
191                     }
192                     mSelectedVideoSink = mSurfaceHolder2VideoSink;
193                 } else if ("SurfaceTexture 1".equals(mSinkString)) {
194                     if (mGLView1VideoSink == null) {
195                         mGLView1VideoSink = new GLViewVideoSink(mGLView1);
196                     }
197                     mSelectedVideoSink = mGLView1VideoSink;
198                 } else if ("SurfaceTexture 2".equals(mSinkString)) {
199                     if (mGLView2VideoSink == null) {
200                         mGLView2VideoSink = new GLViewVideoSink(mGLView2);
201                     }
202                     mSelectedVideoSink = mGLView2VideoSink;
203                 }
204             }
205
206             public void onNothingSelected(AdapterView parent) {
207                 Log.v(TAG, "onNothingSelected");
208                 mSinkString = null;
209                 mSelectedVideoSink = null;
210             }
211
212         });
213
214         // initialize button click handlers
215
216         // Java MediaPlayer start/pause
217
218         ((Button) findViewById(R.id.start_java)).setOnClickListener(new View.OnClickListener() {
219
220             public void onClick(View view) {
221                 if (mJavaMediaPlayerVideoSink == null) {
222                     if (mSelectedVideoSink == null) {
223                         return;
224                     }
225                     mSelectedVideoSink.useAsSinkForJava(mMediaPlayer);
226                     mJavaMediaPlayerVideoSink = mSelectedVideoSink;
227                 }
228                 if (!mMediaPlayerIsPrepared) {
229                     if (mSourceString != null) {
230                         try {
231                             mMediaPlayer.setDataSource(mSourceString);
232                         } catch (IOException e) {
233                             Log.e(TAG, "IOException " + e);
234                         }
235                         mMediaPlayer.prepareAsync();
236                     }
237                 } else if (mMediaPlayer.isPlaying()) {
238                     mMediaPlayer.pause();
239                 } else {
240                     mMediaPlayer.start();
241                 }
242             }
243
244         });
245
246         // native MediaPlayer start/pause
247
248         ((Button) findViewById(R.id.start_native)).setOnClickListener(new View.OnClickListener() {
249
250             boolean created = false;
251             public void onClick(View view) {
252                 if (!created) {
253                     if (mNativeMediaPlayerVideoSink == null) {
254                         if (mSelectedVideoSink == null) {
255                             return;
256                         }
257                         mSelectedVideoSink.useAsSinkForNative();
258                         mNativeMediaPlayerVideoSink = mSelectedVideoSink;
259                     }
260                     if (mSourceString != null) {
261                         created = createStreamingMediaPlayer(mSourceString);
262                     }
263                 }
264                 if (created) {
265                     mIsPlayingStreaming = !mIsPlayingStreaming;
266                     setPlayingStreamingMediaPlayer(mIsPlayingStreaming);
267                 }
268             }
269
270         });
271
272     }
273
274     /** Called when the activity is about to be paused. */
275     @Override
276     protected void onPause()
277     {
278         mIsPlayingStreaming = false;
279         setPlayingStreamingMediaPlayer(false);
280         mGLView1.onPause();
281         mGLView2.onPause();
282         super.onPause();
283     }
284
285     @Override
286     protected void onResume() {
287         super.onResume();
288         mGLView1.onResume();
289         mGLView2.onResume();
290     }
291
292     /** Called when the activity is about to be destroyed. */
293     @Override
294     protected void onDestroy()
295     {
296         shutdown();
297         super.onDestroy();
298     }
299
300     private MyGLSurfaceView mGLView1, mGLView2;
301
302     /** Native methods, implemented in jni folder */
303     public static native void createEngine();
304     public static native boolean createStreamingMediaPlayer(String filename);
305     public static native void setPlayingStreamingMediaPlayer(boolean isPlaying);
306     public static native void shutdown();
307     public static native void setSurface(Surface surface);
308     public static native void setSurfaceTexture(SurfaceTexture surfaceTexture);
309
310     /** Load jni .so on initialization */
311     static {
312          System.loadLibrary("native-media-jni");
313     }
314
315     // VideoSink abstracts out the difference between Surface and SurfaceTexture
316     // aka SurfaceHolder and GLSurfaceView
317     static abstract class VideoSink {
318
319         abstract void setFixedSize(int width, int height);
320         abstract void useAsSinkForJava(MediaPlayer mediaPlayer);
321         abstract void useAsSinkForNative();
322
323     }
324
325     static class SurfaceHolderVideoSink extends VideoSink {
326
327         private final SurfaceHolder mSurfaceHolder;
328
329         SurfaceHolderVideoSink(SurfaceHolder surfaceHolder) {
330             mSurfaceHolder = surfaceHolder;
331         }
332
333         void setFixedSize(int width, int height) {
334             mSurfaceHolder.setFixedSize(width, height);
335         }
336
337         void useAsSinkForJava(MediaPlayer mediaPlayer) {
338             mediaPlayer.setDisplay(mSurfaceHolder);
339         }
340
341         void useAsSinkForNative() {
342             setSurface(mSurfaceHolder.getSurface());
343         }
344
345     }
346
347     static class GLViewVideoSink extends VideoSink {
348
349         private final MyGLSurfaceView mMyGLSurfaceView;
350
351         GLViewVideoSink(MyGLSurfaceView myGLSurfaceView) {
352             mMyGLSurfaceView = myGLSurfaceView;
353         }
354
355         void setFixedSize(int width, int height) {
356         }
357
358         void useAsSinkForJava(MediaPlayer mediaPlayer) {
359             // This API is @hide currently, so use reflection instead:
360             // mMediaPlayer.setTexture(surfaceTexture);
361             Class clazz = MediaPlayer.class;
362             Class[] types = new Class[] { SurfaceTexture.class };
363             Object[] arglist = new Object[] { mMyGLSurfaceView.getSurfaceTexture() };
364             try {
365                 clazz.getMethod("setTexture", types).invoke(mediaPlayer, arglist);
366             } catch (NoSuchMethodException e) {
367             } catch (IllegalAccessException e) {
368             } catch (java.lang.reflect.InvocationTargetException e) {
369             }
370         }
371
372         void useAsSinkForNative() {
373             setSurfaceTexture(mMyGLSurfaceView.getSurfaceTexture());
374         }
375
376     }
377
378 }