Merge "Add timelapse recording support to effects mode." into ics-mr0
diff --git a/res/raw/backdropper.graph b/res/raw/backdropper.graph
index 3a48fc4..a903f12 100644
--- a/res/raw/backdropper.graph
+++ b/res/raw/backdropper.graph
@@ -30,7 +30,6 @@
 @external recordingHeight;
 @external recordingProfile;
 @external recordingDoneListener;
-@external audioSource;
 
 @external previewSurface;
 @external previewWidth;
@@ -73,11 +72,11 @@
 
 // Recording output
 @filter MediaEncoderFilter recorder {
-  audioSource = $audioSource;
   recordingProfile = $recordingProfile;
   recordingDoneListener = $recordingDoneListener;
   recording = false;
-  // outputFile, orientationHint, inputRegion, listeners
+  // outputFile, orientationHint, inputRegion,
+  // audioSource, listeners, captureRate
   // will be set when recording starts
 }
 
diff --git a/res/raw/goofy_face.graph b/res/raw/goofy_face.graph
index 7145033..fa2df43 100644
--- a/res/raw/goofy_face.graph
+++ b/res/raw/goofy_face.graph
@@ -32,7 +32,6 @@
 @external recordingHeight;
 @external recordingProfile;
 @external recordingDoneListener;
-@external audioSource;
 
 @external previewSurface;
 @external previewWidth;
@@ -97,11 +96,11 @@
 
 // Recording output
 @filter MediaEncoderFilter recorder {
-  audioSource = $audioSource;
   recordingProfile = $recordingProfile;
   recordingDoneListener = $recordingDoneListener;
   recording = false;
-  // outputFile, orientationHint, inputRegion, listeners
+  // outputFile, orientationHint, inputRegion,
+  // audioSource, listeners, captureRate
   // will be set when recording starts
 }
 
diff --git a/src/com/android/camera/EffectsRecorder.java b/src/com/android/camera/EffectsRecorder.java
index bd0aff5..8b63ceb 100644
--- a/src/com/android/camera/EffectsRecorder.java
+++ b/src/com/android/camera/EffectsRecorder.java
@@ -80,6 +80,7 @@
 
     private Camera mCameraDevice;
     private CamcorderProfile mProfile;
+    private double mCaptureRate = 0;
     private SurfaceHolder mPreviewSurfaceHolder;
     private int mPreviewWidth;
     private int mPreviewHeight;
@@ -222,9 +223,31 @@
      * disable the limit
     */
     public synchronized void setMaxFileSize(long maxFileSize) {
+        switch (mState) {
+            case STATE_RECORD:
+                throw new RuntimeException("setMaxFileSize cannot be called while recording!");
+            case STATE_RELEASED:
+                throw new RuntimeException("setMaxFileSize called on an already released recorder!");
+            default:
+                break;
+        }
         mMaxFileSize = maxFileSize;
     }
 
+    public void setCaptureRate(double fps) {
+        switch (mState) {
+            case STATE_RECORD:
+                throw new RuntimeException("setCaptureRate cannot be called while recording!");
+            case STATE_RELEASED:
+                throw new RuntimeException("setCaptureRate called on an already released recorder!");
+            default:
+                break;
+        }
+
+        if (mLogVerbose) Log.v(TAG, "Setting time lapse capture rate to " + fps + " fps");
+        mCaptureRate = fps;
+    }
+
     public void setPreviewDisplay(SurfaceHolder previewSurfaceHolder,
                                   int previewWidth,
                                   int previewHeight) {
@@ -382,10 +405,8 @@
                 "recordingWidth", mProfile.videoFrameWidth,
                 "recordingHeight", mProfile.videoFrameHeight,
                 "recordingProfile", mProfile,
-                "audioSource", MediaRecorder.AudioSource.CAMCORDER,
                 "learningDoneListener", mLearningDoneListener,
                 "recordingDoneListener", mRecordingDoneListener);
-
         mRunner = null;
         mGraphId = -1;
         mCurrentEffect = EFFECT_NONE;
@@ -592,17 +613,34 @@
         } else {
             recorder.setInputValue("outputFile", mOutputFile);
         }
+        // It is ok to set the audiosource without checking for timelapse here
+        // since that check will be done in the MediaEncoderFilter itself
+        recorder.setInputValue("audioSource", MediaRecorder.AudioSource.CAMCORDER);
 
+        recorder.setInputValue("recordingProfile", mProfile);
         recorder.setInputValue("orientationHint", mOrientationHint);
+        // Important to set the timelapseinterval to 0 if the capture rate is not >0
+        // since the recorder does not get created every time the recording starts.
+        // The recorder infers whether the capture is timelapsed based on the value of
+        // this interval
+        boolean captureTimeLapse = mCaptureRate > 0;
+        if (captureTimeLapse) {
+            double timeBetweenFrameCapture = 1 / mCaptureRate;
+            recorder.setInputValue("timelapseRecordingIntervalUs",
+                    (long) (1000000 * timeBetweenFrameCapture));
+        } else {
+            recorder.setInputValue("timelapseRecordingIntervalUs", 0L);
+        }
+
         if (mInfoListener != null) {
             recorder.setInputValue("infoListener", mInfoListener);
         }
         if (mErrorListener != null) {
             recorder.setInputValue("errorListener", mErrorListener);
         }
+        recorder.setInputValue("maxFileSize", mMaxFileSize);
         recorder.setInputValue("recording", true);
         if (mRecordSound != null) mRecordSound.play();
-        recorder.setInputValue("maxFileSize", mMaxFileSize);
         mState = STATE_RECORD;
     }
 
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index df8adb9..6a251d4 100755
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -1243,6 +1243,8 @@
 
         mEffectsRecorder = new EffectsRecorder(this);
 
+        // TODO: Confirm none of the foll need to go to initializeEffectsRecording()
+        // and none of these change even when the preview is not refreshed.
         mEffectsRecorder.setCamera(mCameraDevice);
         mEffectsRecorder.setCameraFacing(info.facing);
         mEffectsRecorder.setProfile(mProfile);
@@ -1294,7 +1296,15 @@
             requestedSizeLimit = myExtras.getLong(MediaStore.EXTRA_SIZE_LIMIT);
         }
 
-        // TODO: Timelapse
+        mEffectsRecorder.setProfile(mProfile);
+        // important to set the capture rate to zero if not timelapsed, since the
+        // effectsrecorder object does not get created again for each recording
+        // session
+        if (mCaptureTimeLapse) {
+            mEffectsRecorder.setCaptureRate((1000 / (double) mTimeBetweenTimeLapseFrameCaptureMs));
+        } else {
+            mEffectsRecorder.setCaptureRate(0);
+        }
 
         // Set output file
         if (mVideoFileDescriptor != null) {