├── README.md
└── graphics
└── opengl
└── video
└── surfaceview
├── AndroidManifest.xml
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── layout
│ └── activity_main.xml
├── menu
│ └── main.xml
└── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── src
└── com
└── example
├── custom
└── view
│ └── CustomVideoView.java
└── samplevideoview
└── MainActivity.java
/README.md:
--------------------------------------------------------------------------------
1 | Android_Programs
2 | ================
3 | Contains Android Programming Material
4 |
5 | The corresponding folder is to be selected to get the source code of a project
6 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/satish13131/Android_Programs/1c82ed124a2350e1ffd4ecf9697b0dca2b5b0d8c/graphics/opengl/video/surfaceview/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SampleVideoView
5 | Settings
6 | Hello world!
7 |
8 |
9 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/src/com/example/custom/view/CustomVideoView.java:
--------------------------------------------------------------------------------
1 | package com.example.custom.view;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.nio.ByteBuffer;
6 | import java.nio.ByteOrder;
7 | import java.nio.FloatBuffer;
8 |
9 | import javax.microedition.khronos.egl.EGLConfig;
10 | import javax.microedition.khronos.opengles.GL10;
11 |
12 | import android.content.Context;
13 | import android.graphics.PixelFormat;
14 | import android.graphics.SurfaceTexture;
15 | import android.media.MediaPlayer;
16 | import android.net.Uri;
17 | import android.opengl.GLES20;
18 | import android.opengl.GLSurfaceView;
19 | import android.opengl.Matrix;
20 | import android.util.Log;
21 | import android.view.Surface;
22 |
23 | public class CustomVideoView extends GLSurfaceView {
24 |
25 | VideoRender mRenderer;
26 | private MediaPlayer mMediaPlayer = null;
27 | private File file = null;
28 | private String filePath = null;
29 | private Uri uri = null;
30 |
31 | public CustomVideoView(Context context, File file) {
32 | super(context);
33 |
34 | this.file = file;
35 |
36 | init();
37 |
38 | }
39 |
40 | public CustomVideoView(Context context, String filePath) {
41 | super(context);
42 |
43 | this.filePath = filePath;
44 |
45 | init();
46 |
47 | }
48 |
49 | public CustomVideoView(Context context, Uri uri) {
50 | super(context);
51 |
52 | this.uri = uri;
53 |
54 | init();
55 |
56 | }
57 |
58 | private void init() {
59 |
60 | setEGLContextClientVersion(2);
61 |
62 | getHolder().setFormat(PixelFormat.TRANSLUCENT);
63 | setEGLConfigChooser(8, 8, 8, 8, 16, 0);
64 |
65 | mRenderer = new VideoRender(getContext());
66 | setRenderer(mRenderer);
67 |
68 | }
69 |
70 | @Override
71 | public void onResume() {
72 | super.onResume();
73 | }
74 |
75 | @Override
76 | public void onPause() {
77 | super.onPause();
78 | }
79 |
80 | @Override
81 | protected void onDetachedFromWindow() {
82 | // TODO Auto-generated method stub
83 | super.onDetachedFromWindow();
84 |
85 | if (mMediaPlayer != null) {
86 | mMediaPlayer.stop();
87 | mMediaPlayer.release();
88 | }
89 | }
90 |
91 | private class VideoRender implements GLSurfaceView.Renderer,
92 | SurfaceTexture.OnFrameAvailableListener {
93 | private String TAG = "VideoRender";
94 |
95 | private static final int FLOAT_SIZE_BYTES = 4;
96 | private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 3 * FLOAT_SIZE_BYTES;
97 | private static final int TEXTURE_VERTICES_DATA_STRIDE_BYTES = 2 * FLOAT_SIZE_BYTES;
98 | private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
99 | private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 0;
100 | private final float[] mTriangleVerticesData = { -1.0f, -1.0f, 0, 1.0f,
101 | -1.0f, 0, -1.0f, 1.0f, 0, 1.0f, 1.0f, 0, };
102 |
103 | private final float[] mTextureVerticesData = { 0.f, 0.0f, 1.0f, 0.f,
104 | 0.0f, 1.f, 1.0f, 1.0f };
105 |
106 | private FloatBuffer mTriangleVertices;
107 |
108 | // extra
109 | private FloatBuffer mTextureVertices;
110 |
111 | private final String mVertexShader = "uniform mat4 uMVPMatrix;\n"
112 | + "uniform mat4 uSTMatrix;\n" + "attribute vec4 aPosition;\n"
113 | + "attribute vec4 aTextureCoord;\n"
114 | + "varying vec2 vTextureCoord;\n" + "void main() {\n"
115 | + " gl_Position = uMVPMatrix * aPosition;\n"
116 | + " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + "}\n";
117 |
118 | private final String mFragmentShader = "#extension GL_OES_EGL_image_external : require\n"
119 | + "precision mediump float;\n"
120 | + "varying vec2 vTextureCoord;\n"
121 | + "uniform samplerExternalOES sTexture;\n"
122 | + "void main() {\n"
123 | + " gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
124 | + "}\n";
125 |
126 | private float[] mMVPMatrix = new float[16];
127 | private float[] mSTMatrix = new float[16];
128 | private float[] projectionMatrix = new float[16];
129 |
130 | private int mProgram;
131 | private int mTextureID;
132 | private int muMVPMatrixHandle;
133 | private int muSTMatrixHandle;
134 | private int maPositionHandle;
135 | private int maTextureHandle;
136 |
137 | private SurfaceTexture mSurface;
138 | private boolean updateSurface = false;
139 |
140 | private int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
141 |
142 | public VideoRender(Context context) {
143 | mTriangleVertices = ByteBuffer
144 | .allocateDirect(
145 | mTriangleVerticesData.length * FLOAT_SIZE_BYTES)
146 | .order(ByteOrder.nativeOrder()).asFloatBuffer();
147 | mTriangleVertices.put(mTriangleVerticesData).position(0);
148 |
149 | // extra
150 | mTextureVertices = ByteBuffer
151 | .allocateDirect(
152 | mTextureVerticesData.length * FLOAT_SIZE_BYTES)
153 | .order(ByteOrder.nativeOrder()).asFloatBuffer();
154 | mTextureVertices.put(mTextureVerticesData).position(0);
155 |
156 | Matrix.setIdentityM(mSTMatrix, 0);
157 | }
158 |
159 | public void onDrawFrame(GL10 glUnused) {
160 |
161 | synchronized (this) {
162 | if (updateSurface) {
163 | mSurface.updateTexImage();
164 | mSurface.getTransformMatrix(mSTMatrix);
165 | updateSurface = false;
166 | } else {
167 | return;
168 | }
169 | }
170 |
171 | GLES20.glClearColor(255.0f, 255.0f, 255.0f, 1.0f);
172 | GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT
173 | | GLES20.GL_COLOR_BUFFER_BIT);
174 |
175 | GLES20.glUseProgram(mProgram);
176 | checkGlError("glUseProgram");
177 |
178 | GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
179 | GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
180 |
181 | mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
182 | GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT,
183 | false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES,
184 | mTriangleVertices);
185 | checkGlError("glVertexAttribPointer maPosition");
186 | GLES20.glEnableVertexAttribArray(maPositionHandle);
187 | checkGlError("glEnableVertexAttribArray maPositionHandle");
188 |
189 | mTextureVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
190 | GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT,
191 | false, TEXTURE_VERTICES_DATA_STRIDE_BYTES, mTextureVertices);
192 |
193 | checkGlError("glVertexAttribPointer maTextureHandle");
194 | GLES20.glEnableVertexAttribArray(maTextureHandle);
195 | checkGlError("glEnableVertexAttribArray maTextureHandle");
196 |
197 | Matrix.setIdentityM(mMVPMatrix, 0);
198 |
199 | GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix,
200 | 0);
201 | GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
202 |
203 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
204 | checkGlError("glDrawArrays");
205 | GLES20.glFinish();
206 |
207 | }
208 |
209 | public void onSurfaceChanged(GL10 glUnused, int width, int height) {
210 |
211 | GLES20.glViewport(0, 0, width, height);
212 |
213 | Matrix.frustumM(projectionMatrix, 0, -1.0f, 1.0f, -1.0f, 1.0f,
214 | 1.0f, 10.0f);
215 |
216 | }
217 |
218 | @Override
219 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
220 | mProgram = createProgram(mVertexShader, mFragmentShader);
221 | if (mProgram == 0) {
222 | return;
223 | }
224 | maPositionHandle = GLES20
225 | .glGetAttribLocation(mProgram, "aPosition");
226 | checkGlError("glGetAttribLocation aPosition");
227 | if (maPositionHandle == -1) {
228 | throw new RuntimeException(
229 | "Could not get attrib location for aPosition");
230 | }
231 | maTextureHandle = GLES20.glGetAttribLocation(mProgram,
232 | "aTextureCoord");
233 | checkGlError("glGetAttribLocation aTextureCoord");
234 | if (maTextureHandle == -1) {
235 | throw new RuntimeException(
236 | "Could not get attrib location for aTextureCoord");
237 | }
238 |
239 | muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram,
240 | "uMVPMatrix");
241 | checkGlError("glGetUniformLocation uMVPMatrix");
242 | if (muMVPMatrixHandle == -1) {
243 | throw new RuntimeException(
244 | "Could not get attrib location for uMVPMatrix");
245 | }
246 |
247 | muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram,
248 | "uSTMatrix");
249 | checkGlError("glGetUniformLocation uSTMatrix");
250 | if (muSTMatrixHandle == -1) {
251 | throw new RuntimeException(
252 | "Could not get attrib location for uSTMatrix");
253 | }
254 |
255 | int[] textures = new int[1];
256 | GLES20.glGenTextures(1, textures, 0);
257 |
258 | mTextureID = textures[0];
259 | GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
260 | checkGlError("glBindTexture mTextureID");
261 |
262 | GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
263 | GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
264 | GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
265 | GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
266 |
267 | mSurface = new SurfaceTexture(mTextureID);
268 | mSurface.setOnFrameAvailableListener(this);
269 |
270 | Surface surface = new Surface(mSurface);
271 |
272 | mMediaPlayer = new MediaPlayer();
273 |
274 | if (file != null) {
275 | try {
276 | mMediaPlayer.setDataSource(file.getAbsolutePath());
277 | } catch (IllegalArgumentException e) {
278 | // TODO Auto-generated catch block
279 | e.printStackTrace();
280 | } catch (SecurityException e) {
281 | // TODO Auto-generated catch block
282 | e.printStackTrace();
283 | } catch (IllegalStateException e) {
284 | // TODO Auto-generated catch block
285 | e.printStackTrace();
286 | } catch (IOException e) {
287 | // TODO Auto-generated catch block
288 | e.printStackTrace();
289 | }
290 | } else if (filePath != null) {
291 | try {
292 | mMediaPlayer.setDataSource(filePath);
293 | } catch (IllegalArgumentException e) {
294 | // TODO Auto-generated catch block
295 | e.printStackTrace();
296 | } catch (SecurityException e) {
297 | // TODO Auto-generated catch block
298 | e.printStackTrace();
299 | } catch (IllegalStateException e) {
300 | // TODO Auto-generated catch block
301 | e.printStackTrace();
302 | } catch (IOException e) {
303 | // TODO Auto-generated catch block
304 | e.printStackTrace();
305 | }
306 | } else if (uri != null) {
307 | try {
308 | mMediaPlayer.setDataSource(getContext(), uri);
309 | } catch (IllegalArgumentException e) {
310 | // TODO Auto-generated catch block
311 | e.printStackTrace();
312 | } catch (SecurityException e) {
313 | // TODO Auto-generated catch block
314 | e.printStackTrace();
315 | } catch (IllegalStateException e) {
316 | // TODO Auto-generated catch block
317 | e.printStackTrace();
318 | } catch (IOException e) {
319 | // TODO Auto-generated catch block
320 | e.printStackTrace();
321 | }
322 | }
323 |
324 | mMediaPlayer.setSurface(surface);
325 | surface.release();
326 |
327 | try {
328 | mMediaPlayer.prepare();
329 | } catch (IOException t) {
330 | Log.e(TAG, "media player prepare failed");
331 | }
332 |
333 | synchronized (this) {
334 | updateSurface = false;
335 | }
336 |
337 | mMediaPlayer.start();
338 |
339 | }
340 |
341 | synchronized public void onFrameAvailable(SurfaceTexture surface) {
342 |
343 | updateSurface = true;
344 | }
345 |
346 | private int loadShader(int shaderType, String source) {
347 | int shader = GLES20.glCreateShader(shaderType);
348 | if (shader != 0) {
349 | GLES20.glShaderSource(shader, source);
350 | GLES20.glCompileShader(shader);
351 | int[] compiled = new int[1];
352 | GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS,
353 | compiled, 0);
354 | if (compiled[0] == 0) {
355 | Log.e(TAG, "Could not compile shader " + shaderType + ":");
356 | Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
357 | GLES20.glDeleteShader(shader);
358 | shader = 0;
359 | }
360 | }
361 | return shader;
362 | }
363 |
364 | private int createProgram(String vertexSource, String fragmentSource) {
365 | int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
366 | if (vertexShader == 0) {
367 | return 0;
368 | }
369 | int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
370 | fragmentSource);
371 | if (pixelShader == 0) {
372 | return 0;
373 | }
374 |
375 | int program = GLES20.glCreateProgram();
376 | if (program != 0) {
377 | GLES20.glAttachShader(program, vertexShader);
378 | checkGlError("glAttachShader");
379 | GLES20.glAttachShader(program, pixelShader);
380 | checkGlError("glAttachShader");
381 | GLES20.glLinkProgram(program);
382 | int[] linkStatus = new int[1];
383 | GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS,
384 | linkStatus, 0);
385 | if (linkStatus[0] != GLES20.GL_TRUE) {
386 | Log.e(TAG, "Could not link program: ");
387 | Log.e(TAG, GLES20.glGetProgramInfoLog(program));
388 | GLES20.glDeleteProgram(program);
389 | program = 0;
390 | }
391 | }
392 | return program;
393 | }
394 |
395 | private void checkGlError(String op) {
396 | int error;
397 | while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
398 | Log.e(TAG, op + ": glError " + error);
399 | throw new RuntimeException(op + ": glError " + error);
400 | }
401 | }
402 |
403 | }
404 |
405 | }
406 |
--------------------------------------------------------------------------------
/graphics/opengl/video/surfaceview/src/com/example/samplevideoview/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.samplevideoview;
2 |
3 | import java.io.File;
4 |
5 | import android.app.Activity;
6 | import android.os.Bundle;
7 | import android.widget.RelativeLayout;
8 |
9 | import com.example.custom.view.CustomVideoView;
10 |
11 | public class MainActivity extends Activity {
12 |
13 | private CustomVideoView videoView = null;
14 | private RelativeLayout relativeLayout = null;
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_main);
20 |
21 | relativeLayout = (RelativeLayout) findViewById(R.id.main_relative_layout);
22 |
23 | RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
24 | 300, 300);
25 | params.leftMargin = 50;
26 | params.topMargin = 50;
27 |
28 | videoView = new CustomVideoView(this, new File("/sdcard/1.mp4"));
29 | // videoView = new CustomVideoView(this, "/sdcard/1.mp4");
30 | // videoView = new CustomVideoView(this,
31 | // Uri.parse("android.resource://com.example.samplevideoview/" +
32 | // R.raw.video));
33 | relativeLayout.addView(videoView, params);
34 |
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------