MediaSource.java revision 2dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1
14a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala/* 24a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * Copyright (C) 2011 The Android Open Source Project 34a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * 44a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 54a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * you may not use this file except in compliance with the License. 64a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * You may obtain a copy of the License at 74a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * 84a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 94a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * 104a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 114a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 124a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * See the License for the specific language governing permissions and 144a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * limitations under the License. 154a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala */ 164a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 174a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 184a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalapackage android.filterpacks.videosrc; 194a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 204a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.content.Context; 214a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.content.res.AssetFileDescriptor; 224a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.Filter; 234a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.FilterContext; 244a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.Frame; 254a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.FrameFormat; 264a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.FrameManager; 2721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Rennimport android.filterfw.core.GenerateFieldPort; 2821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Rennimport android.filterfw.core.GenerateFinalPort; 2921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Rennimport android.filterfw.core.GLFrame; 304a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.KeyValueMap; 314a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.MutableFrameFormat; 324a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.NativeFrame; 334a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.Program; 344a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.filterfw.core.ShaderProgram; 3521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Rennimport android.filterfw.format.ImageFormat; 364a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.graphics.SurfaceTexture; 374a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.media.MediaPlayer; 384a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.os.ConditionVariable; 394a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 404a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport java.io.IOException; 414a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport java.io.FileDescriptor; 424a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport java.lang.IllegalArgumentException; 434a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport java.util.List; 444a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport java.util.Set; 454a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 464a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 474a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalaimport android.util.Log; 484a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 49a3bfbe5389c6146abe318a7add3fa688d69bc01bEino-Ville Talvala/** 50a3bfbe5389c6146abe318a7add3fa688d69bc01bEino-Ville Talvala * @hide 51a3bfbe5389c6146abe318a7add3fa688d69bc01bEino-Ville Talvala */ 524a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvalapublic class MediaSource extends Filter { 534a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 544a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala /** User-visible parameters */ 554a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 564a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala /** The source URL for the media source. Can be an http: link to a remote 574a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * resource, or a file: link to a local media file */ 5821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn @GenerateFieldPort(name = "sourceUrl", hasDefault = true) 594a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private String mSourceUrl = ""; 604a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 612dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen /** An open asset file descriptor to a local media source. Default is null */ 6221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn @GenerateFieldPort(name = "sourceAsset", hasDefault = true) 639b393be2b4b7e70abe38237ba3eda3dc009d6230Eino-Ville Talvala private AssetFileDescriptor mSourceAsset = null; 644a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 654a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala /** Whether the filter will always wait for a new video frame, or whether it 664a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala * will output an old frame again if a new frame isn't available. Defaults to true. 674a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala */ 6821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn @GenerateFinalPort(name = "waitForNewFrame", hasDefault = true) 694a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private boolean mWaitForNewFrame = true; 704a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 714a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala /** Whether the media source should loop automatically or not. Defaults to true. */ 7221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn @GenerateFieldPort(name = "loop", hasDefault = true) 734a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private boolean mLooping = true; 744a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 752dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen /** Whether the media source is a URL or an asset file descriptor. Defaults to false. */ 762dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen @GenerateFieldPort(name = "sourceIsUrl", hasDefault = true) 772dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen private boolean mSelectedIsUrl = false; 782dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen 794a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private MediaPlayer mMediaPlayer; 804a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private GLFrame mMediaFrame; 814a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private SurfaceTexture mSurfaceTexture; 824a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private ShaderProgram mFrameExtractor; 834a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private MutableFrameFormat mOutputFormat; 844a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private ConditionVariable mNewFrameAvailable; 854a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private float[] mFrameTransform; 864a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 874a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private final String mFrameShader = 884a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala "#extension GL_OES_EGL_image_external : require\n" + 894a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala "precision mediump float;\n" + 904a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala "uniform mat4 frame_transform;\n" + 914a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala "uniform samplerExternalOES tex_sampler_0;\n" + 924a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala "varying vec2 v_texcoord;\n" + 934a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala "void main() {\n" + 944a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala " vec2 transformed_texcoord = (frame_transform * vec4(v_texcoord, 0., 1.) ).xy;" + 954a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala " gl_FragColor = texture2D(tex_sampler_0, transformed_texcoord);\n" + 964a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala "}\n"; 974a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 984a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private boolean mGotSize; 994a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private boolean mPrepared; 1004a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private boolean mPlaying; 1011df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala private boolean mPaused; 1024a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1038dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala private final boolean mLogVerbose; 1044a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private static final String TAG = "MediaSource"; 1054a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1064a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala public MediaSource(String name) { 1074a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala super(name); 1084a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mNewFrameAvailable = new ConditionVariable(); 1094a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mFrameTransform = new float[16]; 1108dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala 1118dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); 1124a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1134a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1144a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala @Override 11521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public void setupPorts() { 11621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn // Add input port 11721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn addOutputPort("video", ImageFormat.create(ImageFormat.COLORSPACE_RGBA, 11821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn FrameFormat.TARGET_GPU)); 1194a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1204a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 12121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn private void createFormats() { 12221d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mOutputFormat = ImageFormat.create(ImageFormat.COLORSPACE_RGBA, 12321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn FrameFormat.TARGET_GPU); 1244a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1254a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1264a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala @Override 1274a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala protected void prepare(FilterContext context) { 1288dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Preparing MediaSource"); 1294a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1304a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mFrameExtractor = new ShaderProgram(mFrameShader); 1314a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // SurfaceTexture defines (0,0) to be bottom-left. The filter framework 1324a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // defines (0,0) as top-left, so do the flip here. 1334a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mFrameExtractor.setSourceRect(0, 1, 1, -1); 1344a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 13521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn createFormats(); 13621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn 137edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvala mMediaFrame = (GLFrame)context.getFrameManager().newBoundFrame(mOutputFormat, 138edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvala GLFrame.EXTERNAL_TEXTURE, 139edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvala 0); 1404a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mSurfaceTexture = new SurfaceTexture(mMediaFrame.getTextureId()); 1412dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen 1424a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1434a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1444a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala @Override 14521d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public void open(FilterContext context) { 1468dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Opening MediaSource"); 1472dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (mLogVerbose) { 1482dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (mSelectedIsUrl) { 1492dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen Log.v(TAG, "Current URL is " + mSourceUrl); 1502dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } else { 1512dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen Log.v(TAG, "Current source is Asset!"); 1522dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } 1532dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } 1542dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (!setupMediaPlayer(mSelectedIsUrl)) { 1552dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen throw new RuntimeException("Error setting up MediaPlayer!"); 15621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } 1574a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1584a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1594a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala @Override 16021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public void process(FilterContext context) { 1616aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala // Note: process is synchronized by its caller in the Filter base class 1628dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Processing new frame"); 1634a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1644a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (mMediaPlayer == null) { 1654a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // Something went wrong in initialization or parameter updates 16621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn throw new NullPointerException("Unexpected null media player!"); 1674a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1684a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1694a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (!mPlaying) { 1706aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala int waitCount = 0; 1716aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala while (!mGotSize || !mPrepared) { 1726aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala try { 17321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn this.wait(100); 1746aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala } catch (InterruptedException e) { 1756aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala // ignoring 1766aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala } 1776aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala waitCount++; 1786aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala if (waitCount == 50) { 1796aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala mMediaPlayer.release(); 18021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn throw new RuntimeException("MediaPlayer timed out while preparing!"); 1814a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1824a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1834a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.start(); 1844a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1854a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1861df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala // Use last frame if paused, unless just starting playback, in which case 1871df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala // we want at least one valid frame before pausing 1881df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala if (!mPaused || !mPlaying) { 1891df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala if (mWaitForNewFrame) { 1901df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala boolean gotNewFrame; 1911df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala gotNewFrame = mNewFrameAvailable.block(1000); 1921df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala if (!gotNewFrame) { 19321d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn throw new RuntimeException("Timeout waiting for new frame!"); 1941df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala } 1951df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala mNewFrameAvailable.close(); 1964a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 1974a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 1981df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala mSurfaceTexture.updateTexImage(); 1994a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2001df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala mSurfaceTexture.getTransformMatrix(mFrameTransform); 2011df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala mFrameExtractor.setHostValue("frame_transform", mFrameTransform); 2021df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala } 2034a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2044a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala Frame output = context.getFrameManager().newFrame(mOutputFormat); 2054a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mFrameExtractor.process(mMediaFrame, output); 2064a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2078dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala long timestamp = mSurfaceTexture.getTimestamp(); 2088dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Timestamp: " + (timestamp / 1000000000.0) + " s"); 2098dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala output.setTimestamp(timestamp); 2108dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala 21121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn pushOutput("video", output); 2124a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala output.release(); 2134a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2141df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala mPlaying = true; 2154a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2164a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2174a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala @Override 2184a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala public void close(FilterContext context) { 2194a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (mMediaPlayer.isPlaying()) { 2204a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.stop(); 2214a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2224a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.release(); 2234a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer = null; 2248dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "MediaSource closed"); 2254a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2264a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2274a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala @Override 2284a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala public void tearDown(FilterContext context) { 2294a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (mMediaFrame != null) { 2304a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaFrame.release(); 2314a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2324a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2334a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2342dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen // When updating the port values of the filter, users can update sourceIsUrl to switch 2352dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen // between using URL objects or Assets. 2362dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen // If updating only sourceUrl/sourceAsset, MediaPlayer gets reset if the current player 2372dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen // uses Url objects/Asset. 2382dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen // Otherwise the new sourceUrl/sourceAsset is stored and will be used when users switch 2392dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen // sourceIsUrl next time. 2404a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala @Override 24121d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn public void fieldPortValueUpdated(String name, FilterContext context) { 2422dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (name.equals("sourceUrl")) { 2432dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (isOpen()) { 2448dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Opening new source URL"); 2452dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (mSelectedIsUrl) { 2462dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen setupMediaPlayer(mSelectedIsUrl); 2472dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } 2484a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 24921d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } else if (name.equals("sourceAsset") ) { 2504a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (isOpen()) { 2512dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (mLogVerbose) Log.v(TAG, "Opening new source FD"); 2522dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (!mSelectedIsUrl) { 2532dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen setupMediaPlayer(mSelectedIsUrl); 2544a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2554a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 25621d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn } else if (name.equals("loop")) { 2574a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (isOpen()) { 25821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn mMediaPlayer.setLooping(mLooping); 2594a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2602dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } else if (name.equals("sourceIsUrl")) { 2612dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (isOpen()){ 2622dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (mSelectedIsUrl){ 2632dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (mLogVerbose) Log.v(TAG, "Opening new source URL"); 2642dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } else { 2652dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (mLogVerbose) Log.v(TAG, "Opening new source Asset"); 2662dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } 2672dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen setupMediaPlayer(mSelectedIsUrl); 2682dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen } 2694a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2704a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2714a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2721df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala synchronized public void pauseVideo(boolean pauseState) { 2736aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala if (isOpen()) { 2746aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala if (pauseState && !mPaused) { 2756aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala mMediaPlayer.pause(); 2766aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala } else if (!pauseState && mPaused) { 2776aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala mMediaPlayer.start(); 2786aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala } 2796aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala } 2801df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala mPaused = pauseState; 2811df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala } 2821df612099dde7e43249468d46e5b8064d8c33b77Eino-Ville Talvala 2834a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala /** Creates a media player, sets it up, and calls prepare */ 2842dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen synchronized private boolean setupMediaPlayer(boolean useUrl) { 2854a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mPrepared = false; 2864a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mGotSize = false; 2874a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mPlaying = false; 2886aa4072be405da80b7abcc732befe819cfa932eaEino-Ville Talvala mPaused = false; 2894a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2904a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (mMediaPlayer != null) { 2914a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // Clean up existing media player 2924a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.reset(); 2934a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } else { 2944a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // Create new media player 2954a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer = new MediaPlayer(); 2964a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 2974a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 2984a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (mMediaPlayer == null) { 2994a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala Log.e(TAG, "Unable to create a media player!"); 30021d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return false; 3014a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3024a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3034a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // Set up data sources, etc 3044a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala try { 3052dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (useUrl) { 3064a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.setDataSource(mSourceUrl); 3074a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } else { 3084a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.setDataSource(mSourceAsset.getFileDescriptor(), mSourceAsset.getStartOffset(), mSourceAsset.getLength()); 3094a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3104a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } catch(IOException e) { 3112dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (useUrl) { 3124a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala Log.e(TAG, "Unable to set media player source to " + mSourceUrl + ". Exception: " + e); 3134a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } else { 3144a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala Log.e(TAG, "Unable to set media player source to " + mSourceAsset + ". Exception: " + e); 3154a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3164a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.release(); 3174a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer = null; 31821d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return false; 3194a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } catch(IllegalArgumentException e) { 3202dfe9bbf05b260944ef5fa42aa5dfd2fd312aba1Christine Chen if (useUrl) { 3214a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala Log.e(TAG, "Unable to set media player source to " + mSourceUrl + ". Exception: " + e); 3224a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } else { 3234a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala Log.e(TAG, "Unable to set media player source to " + mSourceAsset + ". Exception: " + e); 3244a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3254a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.release(); 3264a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer = null; 32721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return false; 3284a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3294a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3304a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.setLooping(mLooping); 3314a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3324a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // Bind it to our media frame 3334a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.setTexture(mSurfaceTexture); 3344a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3354a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // Connect Media Player to callbacks 3364a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3374a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.setOnVideoSizeChangedListener(onVideoSizeChangedListener); 3384a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.setOnPreparedListener(onPreparedListener); 3394a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.setOnCompletionListener(onCompletionListener); 3404a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3414a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala // Connect SurfaceTexture to callback 3424a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mSurfaceTexture.setOnFrameAvailableListener(onMediaFrameAvailableListener); 3434a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3444a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mMediaPlayer.prepareAsync(); 3454a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3468dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "MediaPlayer now preparing."); 34721d0ac7403b836e32e2bdbdc8dc98f42b2dfa4e5Marius Renn return true; 3484a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3494a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3504a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private MediaPlayer.OnVideoSizeChangedListener onVideoSizeChangedListener = 3514a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala new MediaPlayer.OnVideoSizeChangedListener() { 3524a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 3538dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "MediaPlayer sent dimensions: " + width + " x " + height); 3544a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (!mGotSize) { 3554a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mOutputFormat.setDimensions(width, height); 3564a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } else { 3574a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala if (mOutputFormat.getWidth() != width || 3584a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mOutputFormat.getHeight() != height) { 3594a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala Log.e(TAG, "Multiple video size change events received!"); 3604a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3614a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3624a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala synchronized(this) { 3634a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mGotSize = true; 3644a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala this.notify(); 3654a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3664a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3674a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala }; 3684a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3694a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private MediaPlayer.OnPreparedListener onPreparedListener = 3704a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala new MediaPlayer.OnPreparedListener() { 3714a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala public void onPrepared(MediaPlayer mp) { 3728dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "MediaPlayer is prepared"); 3734a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala synchronized(this) { 3744a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mPrepared = true; 3754a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala this.notify(); 3764a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3774a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3784a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala }; 3794a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3804a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private MediaPlayer.OnCompletionListener onCompletionListener = 3814a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala new MediaPlayer.OnCompletionListener() { 3824a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala public void onCompletion(MediaPlayer mp) { 3838dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "MediaPlayer has completed playback"); 3844a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3854a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala }; 3864a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3874a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala private SurfaceTexture.OnFrameAvailableListener onMediaFrameAvailableListener = 3884a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala new SurfaceTexture.OnFrameAvailableListener() { 3894a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala public void onFrameAvailable(SurfaceTexture surfaceTexture) { 3908dd704358d808382465666354fc891af59b21e18Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "New frame from media player"); 3914a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala mNewFrameAvailable.open(); 3924a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala } 3934a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala }; 3944a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala 3954a0c538853d7858d59cbc7f4dc7ece5d942e0b7cEino-Ville Talvala} 396