19efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala/* 29efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * Copyright (C) 2011 The Android Open Source Project 39efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * 49efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); you may not 59efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * use this file except in compliance with the License. You may obtain a copy of 69efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * the License at 79efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * 89efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 99efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * 109efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 119efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * License for the specific language governing permissions and limitations under 149efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * the License. 159efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala */ 169efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 179efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalapackage com.android.camera; 189efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 199efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.content.Context; 2085a5556fb58f1cdc016f5afe5e07cbe1b419ffd8Eino-Ville Talvalaimport android.content.res.AssetFileDescriptor; 219efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.filterfw.GraphEnvironment; 229efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.filterfw.core.Filter; 23a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvalaimport android.filterfw.core.GLEnvironment; 249efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.filterfw.core.GraphRunner; 259efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.filterfw.core.GraphRunner.OnRunnerDoneListener; 262c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvalaimport android.filterfw.geometry.Point; 272c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvalaimport android.filterfw.geometry.Quad; 289efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.filterpacks.videoproc.BackDropperFilter; 299efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.filterpacks.videoproc.BackDropperFilter.LearningDoneListener; 30caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroniimport android.filterpacks.videosink.MediaEncoderFilter.OnRecordingDoneListener; 31caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroniimport android.filterpacks.videosrc.SurfaceTextureSource.SurfaceTextureSourceListener; 329efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 339efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.graphics.SurfaceTexture; 349efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.hardware.Camera; 351461b5333aab31faee65272d64c2ac7f9809d4d0Eino-Ville Talvalaimport android.media.MediaActionSound; 369efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.media.MediaRecorder; 379efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.media.CamcorderProfile; 389efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.os.Handler; 399efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.os.Looper; 409efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.os.ParcelFileDescriptor; 419efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.util.Log; 429efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.view.Surface; 439efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport android.view.SurfaceHolder; 449efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 459efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport java.io.IOException; 4685a5556fb58f1cdc016f5afe5e07cbe1b419ffd8Eino-Ville Talvalaimport java.io.FileNotFoundException; 4785a5556fb58f1cdc016f5afe5e07cbe1b419ffd8Eino-Ville Talvalaimport java.io.File; 489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalaimport java.lang.Runnable; 49dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketiimport java.io.FileDescriptor; 509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5185a5556fb58f1cdc016f5afe5e07cbe1b419ffd8Eino-Ville Talvala 529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala/** 539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * Encapsulates the mobile filter framework components needed to record video with 549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * effects applied. Modeled after MediaRecorder. 559efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala */ 569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvalapublic class EffectsRecorder { 579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_NONE = 0; 599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_GOOFY_FACE = 1; 609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_BACKDROPPER = 2; 619efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_GF_SQUEEZE = 0; 639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_GF_BIG_EYES = 1; 649efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_GF_BIG_MOUTH = 2; 659efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_GF_SMALL_MOUTH = 3; 669efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_GF_BIG_NOSE = 4; 679efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_GF_SMALL_EYES = 5; 681e99673af90451eaffeb100735f38e6ce0f18456Wu-cheng Li public static final int NUM_OF_GF_EFFECTS = EFFECT_GF_SMALL_EYES + 1; 699efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 709efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_MSG_STARTED_LEARNING = 0; 719efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static final int EFFECT_MSG_DONE_LEARNING = 1; 72926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala public static final int EFFECT_MSG_SWITCHING_EFFECT = 2; 73926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala public static final int EFFECT_MSG_EFFECTS_STOPPED = 3; 74caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni public static final int EFFECT_MSG_RECORDING_DONE = 4; 7587e72ba9d89f8b83b1356f17077b9652346a29d4Pannag Sanketi public static final int EFFECT_MSG_PREVIEW_RUNNING = 5; 769efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 779efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private Context mContext; 789efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private Handler mHandler; 799efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private boolean mReleased; 809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private Camera mCameraDevice; 829efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private CamcorderProfile mProfile; 83d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala private double mCaptureRate = 0; 849efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private SurfaceHolder mPreviewSurfaceHolder; 859efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private int mPreviewWidth; 869efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private int mPreviewHeight; 879efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private MediaRecorder.OnInfoListener mInfoListener; 889efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private MediaRecorder.OnErrorListener mErrorListener; 899efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 909efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private String mOutputFile; 91dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi private FileDescriptor mFd; 929efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private int mOrientationHint = 0; 939c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi private long mMaxFileSize = 0; 94db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi private int mMaxDurationMs = 0; 952c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala private int mCameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK; 9614a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala private boolean mAppIsLandscape; 979efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 989efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private int mEffect = EFFECT_NONE; 999efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private int mCurrentEffect = EFFECT_NONE; 1009efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private EffectsListener mEffectsListener; 1019efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1029efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private Object mEffectParameter; 1039efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1049efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private GraphEnvironment mGraphEnv; 1059efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private int mGraphId; 1062670b3d7c318604f07b680b22360d349103144beWei Hua private GraphRunner mRunner = null; 107a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala private GraphRunner mOldRunner = null; 1089efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1099efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private SurfaceTexture mTextureSource; 1109efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1119efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private static final int STATE_CONFIGURE = 0; 1129efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private static final int STATE_WAITING_FOR_SURFACE = 1; 113cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala private static final int STATE_STARTING_PREVIEW = 2; 114cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala private static final int STATE_PREVIEW = 3; 115cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala private static final int STATE_RECORD = 4; 116cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala private static final int STATE_RELEASED = 5; 1179efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private int mState = STATE_CONFIGURE; 1189efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1197e6b690c96b36b134d6825562b4ae66e055ba6a8Eino-Ville Talvala private boolean mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); 1209efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private static final String TAG = "effectsrecorder"; 1211461b5333aab31faee65272d64c2ac7f9809d4d0Eino-Ville Talvala private MediaActionSound mCameraSound; 1229efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1239efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala /** Determine if a given effect is supported at runtime 1249efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala * Some effects require libraries not available on all devices 1259efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala */ 1269efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public static boolean isEffectSupported(int effectId) { 1279efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (effectId) { 1289efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case EFFECT_GOOFY_FACE: 1299efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return Filter.isAvailable("com.google.android.filterpacks.facedetect.GoofyRenderFilter"); 1309efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case EFFECT_BACKDROPPER: 1319efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return Filter.isAvailable("android.filterpacks.videoproc.BackDropperFilter"); 1329efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 1339efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return false; 1349efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1359efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1369efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1379efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public EffectsRecorder(Context context) { 1389efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "EffectsRecorder created (" + this + ")"); 1399efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mContext = context; 1409efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mHandler = new Handler(Looper.getMainLooper()); 1411461b5333aab31faee65272d64c2ac7f9809d4d0Eino-Ville Talvala mCameraSound = new MediaActionSound(); 1429efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1439efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1449efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setCamera(Camera cameraDevice) { 1459efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 1469efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_PREVIEW: 1479efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setCamera cannot be called while previewing!"); 1489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 1499efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setCamera cannot be called while recording!"); 1509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 1519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setCamera called on an already released recorder!"); 1529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 1539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 1549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1559efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCameraDevice = cameraDevice; 1579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setProfile(CamcorderProfile profile) { 1609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 1619efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 1629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setProfile cannot be called while recording!"); 1639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 1649efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setProfile called on an already released recorder!"); 1659efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 1669efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 1679efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1689efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mProfile = profile; 1699efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1709efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1719efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setOutputFile(String outputFile) { 1729efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 1739efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 1749efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setOutputFile cannot be called while recording!"); 1759efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 1769efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setOutputFile called on an already released recorder!"); 1779efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 1789efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 1799efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mOutputFile = outputFile; 182dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi mFd = null; 183dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi } 184dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi 185dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi public void setOutputFile(FileDescriptor fd) { 186dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi switch (mState) { 187dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi case STATE_RECORD: 188dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi throw new RuntimeException("setOutputFile cannot be called while recording!"); 189dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi case STATE_RELEASED: 190dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi throw new RuntimeException("setOutputFile called on an already released recorder!"); 191dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi default: 192dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi break; 193dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi } 194dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi 195dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi mOutputFile = null; 196dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi mFd = fd; 1979efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 1989efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 1999c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi /** 2009c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi * Sets the maximum filesize (in bytes) of the recording session. 2019c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi * This will be passed on to the MediaEncoderFilter and then to the 2029c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi * MediaRecorder ultimately. If zero or negative, the MediaRecorder will 2039c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi * disable the limit 2049c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi */ 2059c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi public synchronized void setMaxFileSize(long maxFileSize) { 206d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala switch (mState) { 207d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala case STATE_RECORD: 208d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala throw new RuntimeException("setMaxFileSize cannot be called while recording!"); 209d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala case STATE_RELEASED: 210d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala throw new RuntimeException("setMaxFileSize called on an already released recorder!"); 211d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala default: 212d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala break; 213d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala } 2149c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi mMaxFileSize = maxFileSize; 2159c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi } 2169c96da0c452cf980eb368cbb5a63afc4ab5f4bc4Pannag Sanketi 217db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi /** 218db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi * Sets the maximum recording duration (in ms) for the next recording session 219db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi * Setting it to zero (the default) disables the limit. 220db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi */ 221db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi public synchronized void setMaxDuration(int maxDurationMs) { 222db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi switch (mState) { 223db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi case STATE_RECORD: 224db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi throw new RuntimeException("setMaxDuration cannot be called while recording!"); 225db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi case STATE_RELEASED: 226db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi throw new RuntimeException("setMaxDuration called on an already released recorder!"); 227db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi default: 228db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi break; 229db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi } 230db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi mMaxDurationMs = maxDurationMs; 231db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi } 232db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi 233db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi 234d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala public void setCaptureRate(double fps) { 235d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala switch (mState) { 236d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala case STATE_RECORD: 237d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala throw new RuntimeException("setCaptureRate cannot be called while recording!"); 238d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala case STATE_RELEASED: 239d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala throw new RuntimeException("setCaptureRate called on an already released recorder!"); 240d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala default: 241d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala break; 242d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala } 243d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala 244d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Setting time lapse capture rate to " + fps + " fps"); 245d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala mCaptureRate = fps; 246d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala } 247d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala 2489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setPreviewDisplay(SurfaceHolder previewSurfaceHolder, 2499efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala int previewWidth, 2509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala int previewHeight) { 2519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "setPreviewDisplay (" + this + ")"); 2529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 2539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 2549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setPreviewDisplay cannot be called while recording!"); 2559efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 2569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setPreviewDisplay called on an already released recorder!"); 2579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 2589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 2599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 2609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 2619efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mPreviewSurfaceHolder = previewSurfaceHolder; 2629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mPreviewWidth = previewWidth; 2639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mPreviewHeight = previewHeight; 2649efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 2659efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 2669efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_WAITING_FOR_SURFACE: 2679efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala startPreview(); 2689efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 269cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala case STATE_STARTING_PREVIEW: 2709efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_PREVIEW: 2719efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala initializeEffect(true); 2729efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 2739efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 2749efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 2759efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 2769efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setEffect(int effect, Object effectParameter) { 2779efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, 278926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala "setEffect: effect ID " + effect + 279926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala ", parameter " + effectParameter.toString() ); 2809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 2819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 2829efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setEffect cannot be called while recording!"); 2839efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 2849efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setEffect called on an already released recorder!"); 2859efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 2869efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 2879efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 2889efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 2899efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mEffect = effect; 2909efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mEffectParameter = effectParameter; 2919efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 292cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala if (mState == STATE_PREVIEW || 293cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala mState == STATE_STARTING_PREVIEW) { 2949efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala initializeEffect(false); 2959efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 2969efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 2979efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 2989efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public interface EffectsListener { 2999efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void onEffectsUpdate(int effectId, int effectMsg); 300d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn public void onEffectsError(Exception exception, String filePath); 3019efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 3029efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 3039efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setEffectsListener(EffectsListener listener) { 3049efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mEffectsListener = listener; 3059efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 3069efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 30751b06d6696a4743339d026b3b3bd282645725b27Eino-Ville Talvala private void setFaceDetectOrientation() { 3082670b3d7c318604f07b680b22360d349103144beWei Hua if (mCurrentEffect == EFFECT_GOOFY_FACE) { 3092670b3d7c318604f07b680b22360d349103144beWei Hua Filter rotateFilter = mRunner.getGraph().getFilter("rotate"); 3102670b3d7c318604f07b680b22360d349103144beWei Hua Filter metaRotateFilter = mRunner.getGraph().getFilter("metarotate"); 31151b06d6696a4743339d026b3b3bd282645725b27Eino-Ville Talvala rotateFilter.setInputValue("rotation", mOrientationHint); 31251b06d6696a4743339d026b3b3bd282645725b27Eino-Ville Talvala int reverseDegrees = (360 - mOrientationHint) % 360; 3132670b3d7c318604f07b680b22360d349103144beWei Hua metaRotateFilter.setInputValue("rotation", reverseDegrees); 3142670b3d7c318604f07b680b22360d349103144beWei Hua } 3152670b3d7c318604f07b680b22360d349103144beWei Hua } 3162670b3d7c318604f07b680b22360d349103144beWei Hua 3172c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala private void setRecordingOrientation() { 318c3a0c2d4b7c1ec7bd8dc6190a0a68a6ff90cb629Eino-Ville Talvala if ( mState != STATE_RECORD && mRunner != null) { 3192c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala Point bl = new Point(0, 0); 3202c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala Point br = new Point(1, 0); 3212c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala Point tl = new Point(0, 1); 3222c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala Point tr = new Point(1, 1); 3232c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala Quad recordingRegion; 3242c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) { 3252c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala // The back camera is not mirrored, so use a identity transform 3262c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala recordingRegion = new Quad(bl, br, tl, tr); 3272c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } else { 3282c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala // Recording region needs to be tweaked for front cameras, since they 3292c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala // mirror their preview 3302c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala if (mOrientationHint == 0 || mOrientationHint == 180) { 3312c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala // Horizontal flip in landscape 3322c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala recordingRegion = new Quad(br, bl, tr, tl); 3332c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } else { 3342c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala // Horizontal flip in portrait 3352c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala recordingRegion = new Quad(tl, tr, bl, br); 3362c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } 3372c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } 3382c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala Filter recorder = mRunner.getGraph().getFilter("recorder"); 3392c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala recorder.setInputValue("inputRegion", recordingRegion); 3402c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } 3412c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } 3429efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setOrientationHint(int degrees) { 3439efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 3449efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 3452670b3d7c318604f07b680b22360d349103144beWei Hua throw new RuntimeException( 3462670b3d7c318604f07b680b22360d349103144beWei Hua "setOrientationHint called on an already released recorder!"); 3479efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 3489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 3499efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 3503ac6ed3a95322fa9e29f81377e92669ebaeb77fbEino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Setting orientation hint to: " + degrees); 3519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mOrientationHint = degrees; 35251b06d6696a4743339d026b3b3bd282645725b27Eino-Ville Talvala setFaceDetectOrientation(); 3532c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala setRecordingOrientation(); 3542c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } 3552c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala 35614a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala /** Passes the native orientation of the Camera app (device dependent) 35714a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala * to allow for correct output aspect ratio. Defaults to portrait */ 35814a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala public void setAppToLandscape(boolean landscape) { 35914a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala if (mState != STATE_CONFIGURE) { 36014a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala throw new RuntimeException( 36114a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala "setAppToLandscape called after configuration!"); 36214a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala } 36314a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala mAppIsLandscape = landscape; 36414a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala } 36514a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala 3662c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala public void setCameraFacing(int facing) { 3672c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala switch (mState) { 3682c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala case STATE_RELEASED: 3692c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala throw new RuntimeException( 3702c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala "setCameraFacing called on alrady released recorder!"); 3712c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala default: 3722c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala break; 3732c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala } 3742c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala mCameraFacing = facing; 3752c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala setRecordingOrientation(); 3769efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 3779efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 3789efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setOnInfoListener(MediaRecorder.OnInfoListener infoListener) { 3799efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 3809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 3819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setInfoListener cannot be called while recording!"); 3829efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 3839efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setInfoListener called on an already released recorder!"); 3849efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 3859efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 3869efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 3879efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mInfoListener = infoListener; 3889efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 3899efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 3909efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void setOnErrorListener(MediaRecorder.OnErrorListener errorListener) { 3919efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 3929efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 3939efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setErrorListener cannot be called while recording!"); 3949efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 3959efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setErrorListener called on an already released recorder!"); 3969efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 3979efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 3989efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 3999efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mErrorListener = errorListener; 4009efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 4019efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 402a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala private void initializeFilterFramework() { 4039efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mGraphEnv = new GraphEnvironment(); 4049efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mGraphEnv.createGLEnvironment(); 4059efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 406926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala if (mLogVerbose) { 407926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala Log.v(TAG, "Effects framework initializing. Recording size " 408926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala + mProfile.videoFrameWidth + ", " + mProfile.videoFrameHeight); 409926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala } 41014a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala if (!mAppIsLandscape) { 41114a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala int tmp; 41214a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala tmp = mProfile.videoFrameWidth; 41314a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala mProfile.videoFrameWidth = mProfile.videoFrameHeight; 41414a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala mProfile.videoFrameHeight = tmp; 41514a3ffc328740e8fd4734dfa124e4682df8bdd4aEino-Ville Talvala } 4169efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mGraphEnv.addReferences( 4179efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala "textureSourceCallback", mSourceReadyCallback, 4189efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala "recordingWidth", mProfile.videoFrameWidth, 4199efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala "recordingHeight", mProfile.videoFrameHeight, 4209efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala "recordingProfile", mProfile, 421caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni "learningDoneListener", mLearningDoneListener, 422caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni "recordingDoneListener", mRecordingDoneListener); 4239efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mRunner = null; 4249efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mGraphId = -1; 4259efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCurrentEffect = EFFECT_NONE; 4269efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 4279efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 428a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala private synchronized void initializeEffect(boolean forceReset) { 4299efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (forceReset || 4309efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCurrentEffect != mEffect || 4319efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCurrentEffect == EFFECT_BACKDROPPER) { 432926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala if (mLogVerbose) { 433926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala Log.v(TAG, "Effect initializing. Preview size " 434926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala + mPreviewWidth + ", " + mPreviewHeight); 435926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala } 4362c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala 4379efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mGraphEnv.addReferences( 4389efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala "previewSurface", mPreviewSurfaceHolder.getSurface(), 4399efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala "previewWidth", mPreviewWidth, 440d5ec81fea464e1f9db3cb06f7db3de3cf2e3be94Eino-Ville Talvala "previewHeight", mPreviewHeight, 441d5ec81fea464e1f9db3cb06f7db3de3cf2e3be94Eino-Ville Talvala "orientation", mOrientationHint); 442cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala if (mState == STATE_PREVIEW || 443cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala mState == STATE_STARTING_PREVIEW) { 444a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala // Switching effects while running. Inform video camera. 445926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala sendMessage(mCurrentEffect, EFFECT_MSG_SWITCHING_EFFECT); 4469efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 447a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala 4489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mEffect) { 4499efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case EFFECT_GOOFY_FACE: 4509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mGraphId = mGraphEnv.loadGraph(mContext, R.raw.goofy_face); 4519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 4529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case EFFECT_BACKDROPPER: 4539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_STARTED_LEARNING); 4549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mGraphId = mGraphEnv.loadGraph(mContext, R.raw.backdropper); 4559efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 4569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 4579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("Unknown effect ID" + mEffect + "!"); 4589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 4599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCurrentEffect = mEffect; 4609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 461a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mOldRunner = mRunner; 4629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mRunner = mGraphEnv.getRunner(mGraphId, GraphEnvironment.MODE_ASYNCHRONOUS); 4639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mRunner.setDoneCallback(mRunnerDoneCallback); 464d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala if (mLogVerbose) { 465d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala Log.v(TAG, "New runner: " + mRunner 466d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala + ". Old runner: " + mOldRunner); 467d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala } 468cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala if (mState == STATE_PREVIEW || 469cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala mState == STATE_STARTING_PREVIEW) { 470a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala // Switching effects while running. Stop existing runner. 471a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala // The stop callback will take care of starting new runner. 472a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mCameraDevice.stopPreview(); 473a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala try { 474a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mCameraDevice.setPreviewTexture(null); 475a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala } catch(IOException e) { 476a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala throw new RuntimeException("Unable to connect camera to effect input", e); 477a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala } 478a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mOldRunner.stop(); 479a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala } 4809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 4819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 4829efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mCurrentEffect) { 4839efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case EFFECT_GOOFY_FACE: 48407d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala tryEnableVideoStabilization(true); 4859efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Filter goofyFilter = mRunner.getGraph().getFilter("goofyrenderer"); 4869efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala goofyFilter.setInputValue("currentEffect", 4879efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala ((Integer)mEffectParameter).intValue()); 4889efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 4899efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case EFFECT_BACKDROPPER: 49007d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala tryEnableVideoStabilization(false); 4919efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Filter backgroundSrc = mRunner.getGraph().getFilter("background"); 4929efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala backgroundSrc.setInputValue("sourceUrl", 4939efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala (String)mEffectParameter); 4948d51fc281ca4e14c87eac278d153e162c0e1fcf2Pannag Sanketi // For front camera, the background video needs to be mirrored in the 4958d51fc281ca4e14c87eac278d153e162c0e1fcf2Pannag Sanketi // backdropper filter 4968d51fc281ca4e14c87eac278d153e162c0e1fcf2Pannag Sanketi if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 4978d51fc281ca4e14c87eac278d153e162c0e1fcf2Pannag Sanketi Filter replacer = mRunner.getGraph().getFilter("replacer"); 4988d51fc281ca4e14c87eac278d153e162c0e1fcf2Pannag Sanketi replacer.setInputValue("mirrorBg", true); 4998d51fc281ca4e14c87eac278d153e162c0e1fcf2Pannag Sanketi if (mLogVerbose) Log.v(TAG, "Setting the background to be mirrored"); 5008d51fc281ca4e14c87eac278d153e162c0e1fcf2Pannag Sanketi } 5019efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 5029efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 5039efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 5049efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 50551b06d6696a4743339d026b3b3bd282645725b27Eino-Ville Talvala setFaceDetectOrientation(); 5062c2550bd42c614330a3c968bda005ac23d12f8d1Eino-Ville Talvala setRecordingOrientation(); 5079efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5089efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 509a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala public synchronized void startPreview() { 5109efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Starting preview (" + this + ")"); 5119efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5129efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 513cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala case STATE_STARTING_PREVIEW: 5149efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_PREVIEW: 5159efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Already running preview 5169efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Log.w(TAG, "startPreview called when already running preview"); 5179efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return; 5189efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 5199efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("Cannot start preview when already recording!"); 5209efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 5219efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("setEffect called on an already released recorder!"); 5229efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 5239efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 5249efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5259efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5269efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mEffect == EFFECT_NONE) { 5279efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("No effect selected!"); 5289efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5299efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mEffectParameter == null) { 5309efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("No effect parameter provided!"); 5319efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5329efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mProfile == null) { 5339efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("No recording profile provided!"); 5349efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5359efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mPreviewSurfaceHolder == null) { 5369efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Passed a null surface holder; waiting for valid one"); 5379efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mState = STATE_WAITING_FOR_SURFACE; 5389efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return; 5399efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5409efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mCameraDevice == null) { 5419efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("No camera to record from!"); 5429efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5439efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5449efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Initializing filter graph"); 5459efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5469efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala initializeFilterFramework(); 5479efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala initializeEffect(true); 5499efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Starting filter graph"); 5519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 552cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala mState = STATE_STARTING_PREVIEW; 5539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mRunner.run(); 5549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Rest of preview startup handled in mSourceReadyCallback 5559efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 5569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 5579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private SurfaceTextureSourceListener mSourceReadyCallback = 5589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala new SurfaceTextureSourceListener() { 5599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void onSurfaceTextureSourceReady(SurfaceTexture source) { 5609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "SurfaceTexture ready callback received"); 5619efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala synchronized(EffectsRecorder.this) { 5629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mTextureSource = source; 5639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 56407b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala if (mState == STATE_CONFIGURE) { 56507b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala // Stop preview happened while the runner was doing startup tasks 56607b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala // Since we haven't started anything up, don't do anything 56707b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala // Rest of cleanup will happen in onRunnerDone 56807b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Ready callback: Already stopped, skipping."); 56907b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala return; 57007b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala } 57107b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala if (mState == STATE_RELEASED) { 57207b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala // EffectsRecorder has been released, so don't touch the camera device 57307b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala // or anything else 57407b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Ready callback: Already released, skipping."); 57507b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala return; 57607b77037f2f5aa28d6d3188f78588dc7f2d49398Eino-Ville Talvala } 57758cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala if (source == null) { 57858cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala if (mState == STATE_PREVIEW || 579cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala mState == STATE_STARTING_PREVIEW || 58058cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala mState == STATE_RECORD) { 58158cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala // A null source here means the graph is shutting down 58258cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala // unexpectedly, so we need to turn off preview before 58358cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala // the surface texture goes away. 58458cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala mCameraDevice.stopPreview(); 58558cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala try { 58658cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala mCameraDevice.setPreviewTexture(null); 58758cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala } catch(IOException e) { 58858cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala throw new RuntimeException("Unable to disconnect " + 58958cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala "camera from effect input", e); 59058cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala } 59158cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala } 59258cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala return; 59358cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala } 59458cede9e3e8004f6be9731e9cb9a135238a2efd8Eino-Ville Talvala 59507d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala // Lock AE/AWB to reduce transition flicker 59607d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala tryEnable3ALocks(true); 59707d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala 5989efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCameraDevice.stopPreview(); 5999efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Runner active, connecting effects preview"); 6009efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala try { 6019efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCameraDevice.setPreviewTexture(mTextureSource); 6029efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } catch(IOException e) { 6039efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("Unable to connect camera to effect input", e); 6049efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6059efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 6069efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCameraDevice.startPreview(); 6079efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 6089efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Unlock AE/AWB after preview started 6099efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala tryEnable3ALocks(false); 6109efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 6119efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mState = STATE_PREVIEW; 6129efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 6139efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Start preview/effect switch complete"); 61487e72ba9d89f8b83b1356f17077b9652346a29d4Pannag Sanketi 61587e72ba9d89f8b83b1356f17077b9652346a29d4Pannag Sanketi // Sending a message to listener that preview is complete 61687e72ba9d89f8b83b1356f17077b9652346a29d4Pannag Sanketi sendMessage(mCurrentEffect, EFFECT_MSG_PREVIEW_RUNNING); 6179efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6189efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6199efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala }; 6209efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 6219efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private LearningDoneListener mLearningDoneListener = 6229efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala new LearningDoneListener() { 6239efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void onLearningDone(BackDropperFilter filter) { 6249efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Learning done callback triggered"); 6259efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Called in a processing thread, so have to post message back to UI 6269efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // thread 6279efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_DONE_LEARNING); 6289efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala enable3ALocks(true); 6299efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6309efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala }; 6319efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 632caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni // A callback to finalize the media after the recording is done. 633caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni private OnRecordingDoneListener mRecordingDoneListener = 634caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni new OnRecordingDoneListener() { 635caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni // Forward the callback to the VideoCamera object (as an asynchronous event). 636caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni public void onRecordingDone() { 637caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni if (mLogVerbose) Log.v(TAG, "Recording done callback triggered"); 638caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni sendMessage(EFFECT_NONE, EFFECT_MSG_RECORDING_DONE); 639caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni } 640caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni }; 641caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni 642a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala public synchronized void startRecording() { 6439efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Starting recording (" + this + ")"); 6449efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 6459efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 6469efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 6479efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("Already recording, cannot begin anew!"); 6489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 6499efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("startRecording called on an already released recorder!"); 6509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 6519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 6529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 654dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi if ((mOutputFile == null) && (mFd == null)) { 655dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi throw new RuntimeException("No output file name or descriptor provided!"); 6569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 6589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mState == STATE_CONFIGURE) { 6599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala startPreview(); 6609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 661dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi 6629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Filter recorder = mRunner.getGraph().getFilter("recorder"); 663dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi if (mFd != null) { 664dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi recorder.setInputValue("outputFileDescriptor", mFd); 665dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi } else { 666dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi recorder.setInputValue("outputFile", mOutputFile); 667dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi } 668d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala // It is ok to set the audiosource without checking for timelapse here 669d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala // since that check will be done in the MediaEncoderFilter itself 670d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala recorder.setInputValue("audioSource", MediaRecorder.AudioSource.CAMCORDER); 671dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi 672d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala recorder.setInputValue("recordingProfile", mProfile); 6739efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala recorder.setInputValue("orientationHint", mOrientationHint); 674d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala // Important to set the timelapseinterval to 0 if the capture rate is not >0 675d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala // since the recorder does not get created every time the recording starts. 676d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala // The recorder infers whether the capture is timelapsed based on the value of 677d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala // this interval 678d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala boolean captureTimeLapse = mCaptureRate > 0; 679d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala if (captureTimeLapse) { 680d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala double timeBetweenFrameCapture = 1 / mCaptureRate; 681d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala recorder.setInputValue("timelapseRecordingIntervalUs", 682d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala (long) (1000000 * timeBetweenFrameCapture)); 683d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala } else { 684d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala recorder.setInputValue("timelapseRecordingIntervalUs", 0L); 685d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala } 686d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala 6879efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mInfoListener != null) { 6889efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala recorder.setInputValue("infoListener", mInfoListener); 6899efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6909efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mErrorListener != null) { 6919efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala recorder.setInputValue("errorListener", mErrorListener); 6929efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 693d979079aa0735beb302dd58797af0c6b600edfeaEino-Ville Talvala recorder.setInputValue("maxFileSize", mMaxFileSize); 694db1596dc704d2085a3f2f7b5652e6cb43696c265Pannag Sanketi recorder.setInputValue("maxDurationMs", mMaxDurationMs); 6959efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala recorder.setInputValue("recording", true); 6961461b5333aab31faee65272d64c2ac7f9809d4d0Eino-Ville Talvala mCameraSound.play(MediaActionSound.START_VIDEO_RECORDING); 6979efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mState = STATE_RECORD; 6989efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 6999efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 700a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala public synchronized void stopRecording() { 7019efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Stop recording (" + this + ")"); 7029efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 7039efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 7049efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_CONFIGURE: 705cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala case STATE_STARTING_PREVIEW: 7069efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_PREVIEW: 7079efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Log.w(TAG, "StopRecording called when recording not active!"); 7089efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return; 7099efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 7109efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("stopRecording called on released EffectsRecorder!"); 7119efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 7129efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 7139efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7149efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Filter recorder = mRunner.getGraph().getFilter("recorder"); 7159efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala recorder.setInputValue("recording", false); 7161461b5333aab31faee65272d64c2ac7f9809d4d0Eino-Ville Talvala mCameraSound.play(MediaActionSound.STOP_VIDEO_RECORDING); 7179efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mState = STATE_PREVIEW; 7189efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7199efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 7209efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Stop and release effect resources 721a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala public synchronized void stopPreview() { 7229efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Stopping preview (" + this + ")"); 7239efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 7249efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 7259efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_CONFIGURE: 7269efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Log.w(TAG, "StopPreview called when preview not active!"); 7279efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return; 7289efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RELEASED: 7299efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("stopPreview called on released EffectsRecorder!"); 7309efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 7319efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 7329efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7339efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 7349efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mState == STATE_RECORD) { 7359efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala stopRecording(); 7369efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7379efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 7389efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCurrentEffect = EFFECT_NONE; 7399efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 740a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mCameraDevice.stopPreview(); 741a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala try { 742a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mCameraDevice.setPreviewTexture(null); 743a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala } catch(IOException e) { 744a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala throw new RuntimeException("Unable to connect camera to effect input", e); 745a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala } 74690089f9eddde732725c43dcad07f4567ed8cb776Wu-cheng Li mCameraSound.release(); 747a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala 7489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mState = STATE_CONFIGURE; 749a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mOldRunner = mRunner; 7509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mRunner.stop(); 751d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala mRunner = null; 7529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Rest of stop and release handled in mRunnerDoneCallback 7539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 75507d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala // Try to enable/disable video stabilization if supported; otherwise return false 75607d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala boolean tryEnableVideoStabilization(boolean toggle) { 75707d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala Camera.Parameters params = mCameraDevice.getParameters(); 75807d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala 75907d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala String vstabSupported = params.get("video-stabilization-supported"); 76007d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala if ("true".equals(vstabSupported)) { 76107d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Setting video stabilization to " + toggle); 76207d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala params.set("video-stabilization", toggle ? "true" : "false"); 76307d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala mCameraDevice.setParameters(params); 76407d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala return true; 76507d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala } 76607d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Video stabilization not supported"); 76707d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala return false; 76807d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala } 76907d5f8c27d144f7e72820b48fe5cb08f691435adEino-Ville Talvala 7709efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Try to enable/disable 3A locks if supported; otherwise return false 7719efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala boolean tryEnable3ALocks(boolean toggle) { 7729efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Camera.Parameters params = mCameraDevice.getParameters(); 7739efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (params.isAutoExposureLockSupported() && 7749efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala params.isAutoWhiteBalanceLockSupported() ) { 7759efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala params.setAutoExposureLock(toggle); 7769efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala params.setAutoWhiteBalanceLock(toggle); 7779efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mCameraDevice.setParameters(params); 7789efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return true; 7799efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala return false; 7819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7829efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 7839efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Try to enable/disable 3A locks if supported; otherwise, throw error 7849efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Use this when locks are essential to success 7859efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala void enable3ALocks(boolean toggle) { 7869efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala Camera.Parameters params = mCameraDevice.getParameters(); 7879efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (!tryEnable3ALocks(toggle)) { 7889efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala throw new RuntimeException("Attempt to lock 3A on camera with no locking support!"); 7899efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7909efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 7919efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 7929efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private OnRunnerDoneListener mRunnerDoneCallback = 7939efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala new OnRunnerDoneListener() { 7949efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void onRunnerDone(int result) { 7959efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala synchronized(EffectsRecorder.this) { 796d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala if (mLogVerbose) { 797d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala Log.v(TAG, 798d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala "Graph runner done (" + EffectsRecorder.this 799d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala + ", mRunner " + mRunner 800d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala + ", mOldRunner " + mOldRunner + ")"); 801d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala } 802d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn if (result == GraphRunner.RESULT_ERROR) { 803d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn // Handle error case 804d519d3bff76107eda37dfc81b6d1a7c6e0091e42Eino-Ville Talvala Log.e(TAG, "Error running filter graph!"); 8050e3f8387302b4aa882c20891f1faba74030f1a4fEino-Ville Talvala Exception e = null; 8060e3f8387302b4aa882c20891f1faba74030f1a4fEino-Ville Talvala if (mRunner != null) { 8070e3f8387302b4aa882c20891f1faba74030f1a4fEino-Ville Talvala e = mRunner.getError(); 8080e3f8387302b4aa882c20891f1faba74030f1a4fEino-Ville Talvala } else if (mOldRunner != null) { 8090e3f8387302b4aa882c20891f1faba74030f1a4fEino-Ville Talvala e = mOldRunner.getError(); 8100e3f8387302b4aa882c20891f1faba74030f1a4fEino-Ville Talvala } 8110e3f8387302b4aa882c20891f1faba74030f1a4fEino-Ville Talvala raiseError(e); 812d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn } 813a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala if (mOldRunner != null) { 814d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn // Tear down old graph if available 815a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Tearing down old graph."); 816a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvala GLEnvironment glEnv = mGraphEnv.getContext().getGLEnvironment(); 817a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvala if (glEnv != null && !glEnv.isActive()) { 818a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvala glEnv.activate(); 819a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvala } 820a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mOldRunner.getGraph().tearDown(mGraphEnv.getContext()); 821a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvala if (glEnv != null && glEnv.isActive()) { 822a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvala glEnv.deactivate(); 823a91df49eb460aec8bcae4169e7d29ddc7f9ac3ecEino-Ville Talvala } 824a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala mOldRunner = null; 825a7409d87247162002fca1719c035de67fa7e7535Eino-Ville Talvala } 826cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala if (mState == STATE_PREVIEW || 827cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala mState == STATE_STARTING_PREVIEW) { 8289efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Switching effects, start up the new runner 8299efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Previous effect halted, starting new effect."); 8309efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala tryEnable3ALocks(false); 8319efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mRunner.run(); 8329efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } else if (mState != STATE_RELEASED) { 8339efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Shutting down effects 8349efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Runner halted, restoring direct preview"); 835f3b7efa21a1f2b365655acd8efffbdc1b83e6b0cEino-Ville Talvala tryEnable3ALocks(false); 836926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala sendMessage(EFFECT_NONE, EFFECT_MSG_EFFECTS_STOPPED); 8379efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } else { 8389efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // STATE_RELEASED - camera will be/has been released as well, do nothing. 8399efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 8409efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 8419efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 8429efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala }; 8439efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 8449efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Indicates that all camera/recording activity needs to halt 8459efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public synchronized void release() { 8469efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mLogVerbose) Log.v(TAG, "Releasing (" + this + ")"); 8479efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 8489efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala switch (mState) { 8499efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_RECORD: 850cfc9bcc6dc56135d905ffdaaf1b9838cf12a1558Eino-Ville Talvala case STATE_STARTING_PREVIEW: 8519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala case STATE_PREVIEW: 8529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala stopPreview(); 8539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala // Fall-through 8549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala default: 8559efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mState = STATE_RELEASED; 8569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala break; 8579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 8589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 8599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala 8609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala private void sendMessage(final int effect, final int msg) { 8619efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala if (mEffectsListener != null) { 8629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala mHandler.post(new Runnable() { 8639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala public void run() { 864d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn mEffectsListener.onEffectsUpdate(effect, msg); 865d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn } 866d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn }); 867d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn } 868d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn } 869d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn 870d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn private void raiseError(final Exception exception) { 871d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn if (mEffectsListener != null) { 872d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn mHandler.post(new Runnable() { 873d97adb8f99e522a613d484d9d5725dd84921489fMarius Renn public void run() { 874dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi if (mFd != null) { 875dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi mEffectsListener.onEffectsError(exception, null); 876dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi } else { 877dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi mEffectsListener.onEffectsError(exception, mOutputFile); 878dca2af0a95ccb682d57bcea43f03fb01b929edf3Pannag Sanketi } 8799efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 8809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala }); 8819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 8829efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala } 883caf8466dcdf6d6c496e46961bb3132126363ef83Rodrigo Carceroni 8842670b3d7c318604f07b680b22360d349103144beWei Hua} 885