├── 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 | 2 | 3 | 8 | 9 | 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 | --------------------------------------------------------------------------------