summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNipun Kwatra <nkwatra@google.com>2010-08-05 21:17:04 -0700
committerNipun Kwatra <nkwatra@google.com>2010-08-10 16:13:31 -0700
commit6227fa641518492a6b660c78463da18d9ec8fcd8 (patch)
tree5a1e119ce65e88fb8a04a8f0f2e235973344d448
parent80a188c1743205093794a81b021b2ca232423d36 (diff)
downloadpackages_apps_LegacyCamera-6227fa641518492a6b660c78463da18d9ec8fcd8.zip
packages_apps_LegacyCamera-6227fa641518492a6b660c78463da18d9ec8fcd8.tar.gz
packages_apps_LegacyCamera-6227fa641518492a6b660c78463da18d9ec8fcd8.tar.bz2
Added support for time lapse video capture.
Changes in individual files: VideoCamera.java: - Added swith to time lapse option in Menu. - initializeHeadUpDisplay(): sets up display according to the current mode (timelapse/no timelapse). - readTimeLapseVideoPreferences(): sets parameters according to the chosen quality. Eventually this should move to CamcorderProfile through media_profiles.xml files. - switchTimeLapseMode(): handles switching between time lapse mode normal mode. - Since preview size may be different from video size for HD time lapse capture, we save the desired preview size in mDesiredPreviewWidth, mDesiredPreviewHeight and use it for comparison in resetCameraParameters(). - Time lapse mode is enabled/disabled by calling mMediaRecorder.setTimeLapseParameters(). CamcorderHeadUpDisplay.java: Constructor now takes in a boolean (captureTimeLapse) telling whether to enable time lapse quality options or the normal camcorder quality options. Camera.java: Moved getOptimalPreviewSize() to Util.java to enable use from VideoCamera.java. Also needed to pass activity, so that can use getWindowManager(), getSystemService(). CameraSettings.java: added support for time lapse parameters. The function getVideoTimeLapseQuality() returns the quality identifier from the passed in string. res/: added string, array values for time lapse. res/xml/video_time_lapse_preferences.xml: contains all the preferences for time lapse mode. Change-Id: I194e7bc0b6218aa742d91c859a122de2b953a314
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.pngbin0 -> 561 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.pngbin0 -> 553 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.pngbin0 -> 422 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.pngbin0 -> 518 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.pngbin0 -> 871 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.pngbin0 -> 972 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.pngbin0 -> 808 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.pngbin0 -> 736 bytes
-rw-r--r--res/values/arrays.xml22
-rw-r--r--res/values/strings.xml17
-rw-r--r--res/xml/video_preferences.xml7
-rw-r--r--src/com/android/camera/Camera.java49
-rw-r--r--src/com/android/camera/CameraSettings.java26
-rw-r--r--src/com/android/camera/MenuHelper.java1
-rw-r--r--src/com/android/camera/Util.java49
-rw-r--r--src/com/android/camera/VideoCamera.java191
-rw-r--r--src/com/android/camera/ui/CamcorderHeadUpDisplay.java10
17 files changed, 292 insertions, 80 deletions
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
new file mode 100644
index 0000000..d2a39e4
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png
new file mode 100644
index 0000000..5567eb0
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png
new file mode 100644
index 0000000..ce0cf42
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png
new file mode 100644
index 0000000..cb66c52
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
new file mode 100644
index 0000000..199e0ef
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png
new file mode 100644
index 0000000..1104ce5
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png
new file mode 100644
index 0000000..8b99109
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png
new file mode 100644
index 0000000..36e2c1a
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png
Binary files differ
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 473fb47..2e24f5a 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -38,6 +38,28 @@
<item>@drawable/ic_viewfinder_video_quality_youtube</item>
</array>
+ <!-- Camera Preferences Time Lapse Video Quality entries -->
+ <string-array name="pref_video_time_lapse_quality_entries" translatable="false">
+ <item>@string/pref_video_time_lapse_quality_entry_low</item>
+ <item>@string/pref_video_time_lapse_quality_entry_high</item>
+ <item>@string/pref_video_time_lapse_quality_entry_720p</item>
+ <item>@string/pref_video_time_lapse_quality_entry_1080p</item>
+ </string-array>
+
+ <string-array name="pref_video_time_lapse_quality_entryvalues" translatable="false">
+ <item>low</item>
+ <item>high</item>
+ <item>720p</item>
+ <item>1080p</item>
+ </string-array>
+
+ <array name="video_time_lapse_quality_icons" translatable="false">
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_low</item>
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_high</item>
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_720p</item>
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_1080p</item>
+ </array>
+
<!-- Camera Preferences Picture size dialog box entries -->
<string-array name="pref_camera_picturesize_entries" translatable="false">
<!-- TODO: Change to a better name of the preference.
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a1e4a23..055112d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -105,6 +105,12 @@
<!-- Button indicating to switch to another camera -->
<string name="switch_camera_id">Switch Camera</string>
+ <!-- Button indicating to enable the time lapse mode -->
+ <string name="enable_time_lapse_mode">Enable Time Lapse</string>
+
+ <!-- Button indicating to disable the time lapse mode -->
+ <string name="disable_time_lapse_mode">Disable Time Lapse</string>
+
<!-- Settings screen, setting title text -->
<string name="pref_camera_recordlocation_title">Store location</string>
@@ -122,12 +128,23 @@
<string name="pref_video_quality_entry_mms">MMS (Low, 30s)</string>
<string name="pref_video_quality_entry_youtube">YouTube (High, 10m)</string>
+ <!-- The Time Lapse Video quality settings in preference -->
+ <string name="pref_video_time_lapse_quality_title">Time lapse video quality</string>
+ <string name="pref_video_time_lapse_quality_default" translatable="false">high</string>
+ <string name="pref_video_time_lapse_quality_entry_low">Low</string>
+ <string name="pref_video_time_lapse_quality_entry_high">High</string>
+ <string name="pref_video_time_lapse_quality_entry_720p">720p</string>
+ <string name="pref_video_time_lapse_quality_entry_1080p">1080p</string>
+
<!-- Settings screen, Camera setting category title -->
<string name="pref_camera_settings_category">Camera settings</string>
<!-- Settings screen, Camcorder setting category title -->
<string name="pref_camcorder_settings_category">Camcorder settings</string>
+ <!-- Settings screen, Camcorder Time Lapse setting category title -->
+ <string name="pref_camcorder_time_lapse_settings_category">Camcorder Time Lapse settings</string>
+
<!-- Settings screen, Picture size title -->
<string name="pref_camera_picturesize_title">Picture size</string>
diff --git a/res/xml/video_preferences.xml b/res/xml/video_preferences.xml
index eb8e344..6345351 100644
--- a/res/xml/video_preferences.xml
+++ b/res/xml/video_preferences.xml
@@ -26,6 +26,13 @@
camera:entries="@array/pref_video_quality_entries"
camera:entryValues="@array/pref_video_quality_entryvalues"/>
<IconListPreference
+ camera:key="pref_video_time_lapse_quality_key"
+ camera:defaultValue="@string/pref_video_time_lapse_quality_default"
+ camera:title="@string/pref_video_time_lapse_quality_title"
+ camera:largeIcons="@array/video_time_lapse_quality_icons"
+ camera:entries="@array/pref_video_time_lapse_quality_entries"
+ camera:entryValues="@array/pref_video_time_lapse_quality_entryvalues"/>
+ <IconListPreference
camera:key="pref_camera_video_flashmode_key"
camera:defaultValue="@string/pref_camera_video_flashmode_default"
camera:title="@string/pref_camera_flashmode_title"
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 0502d97..07adcee 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -1672,53 +1672,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
clearFocusState();
}
- private Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) {
- final double ASPECT_TOLERANCE = 0.05;
- if (sizes == null) return null;
-
- Size optimalSize = null;
- double minDiff = Double.MAX_VALUE;
-
- // Because of bugs of overlay and layout, we sometimes will try to
- // layout the viewfinder in the portrait orientation and thus get the
- // wrong size of mSurfaceView. When we change the preview size, the
- // new overlay will be created before the old one closed, which causes
- // an exception. For now, just get the screen size
-
- Display display = getWindowManager().getDefaultDisplay();
- int targetHeight = Math.min(display.getHeight(), display.getWidth());
-
- if (targetHeight <= 0) {
- // We don't know the size of SurefaceView, use screen height
- WindowManager windowManager = (WindowManager)
- getSystemService(Context.WINDOW_SERVICE);
- targetHeight = windowManager.getDefaultDisplay().getHeight();
- }
-
- // Try to find an size match aspect ratio and size
- for (Size size : sizes) {
- double ratio = (double) size.width / size.height;
- if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
-
- // Cannot find the one match the aspect ratio, ignore the requirement
- if (optimalSize == null) {
- Log.v(TAG, "No preview size match the aspect ratio");
- minDiff = Double.MAX_VALUE;
- for (Size size : sizes) {
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
- }
- return optimalSize;
- }
-
private static boolean isSupported(String value, List<String> supported) {
return supported == null ? false : supported.indexOf(value) >= 0;
}
@@ -1762,7 +1715,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Set a preview size that is closest to the viewfinder height and has
// the right aspect ratio.
List<Size> sizes = mParameters.getSupportedPreviewSizes();
- Size optimalSize = getOptimalPreviewSize(
+ Size optimalSize = Util.getOptimalPreviewSize(this,
sizes, (double) size.width / size.height);
if (optimalSize != null) {
Size original = mParameters.getPreviewSize();
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index f6b95f6..a97c5f2 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -38,6 +38,7 @@ public class CameraSettings {
public static final String KEY_LOCAL_VERSION = "pref_local_version_key";
public static final String KEY_RECORD_LOCATION = RecordLocationPreference.KEY;
public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
+ public static final String KEY_VIDEO_TIME_LAPSE_QUALITY = "pref_video_time_lapse_quality_key";
public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
@@ -58,6 +59,16 @@ public class CameraSettings {
private static final String VIDEO_QUALITY_MMS = "mms";
private static final String VIDEO_QUALITY_YOUTUBE = "youtube";
+ private static final String VIDEO_TIME_LAPSE_QUALITY_LOW= "low";
+ private static final String VIDEO_TIME_LAPSE_QUALITY_HIGH= "high";
+ private static final String VIDEO_TIME_LAPSE_QUALITY_720P = "720p";
+ private static final String VIDEO_TIME_LAPSE_QUALITY_1080P = "1080p";
+
+ public static final int TIME_LAPSE_VIDEO_QUALITY_LOW = 1;
+ public static final int TIME_LAPSE_VIDEO_QUALITY_HIGH = 2;
+ public static final int TIME_LAPSE_VIDEO_QUALITY_720P = 3;
+ public static final int TIME_LAPSE_VIDEO_QUALITY_1080P = 4;
+
public static final String EXPOSURE_DEFAULT_VALUE = "0";
public static final int CURRENT_VERSION = 4;
@@ -69,6 +80,7 @@ public class CameraSettings {
private static final int DEFAULT_VIDEO_DURATION = 30 * 60; // 10 mins
public static final String DEFAULT_VIDEO_QUALITY_VALUE = "high";
+ public static final String DEFAULT_VIDEO_TIME_LAPSE_QUALITY_VALUE = "high";
// MMS video length
public static final int DEFAULT_VIDEO_DURATION_VALUE = -1;
@@ -341,6 +353,20 @@ public class CameraSettings {
quality) || VIDEO_QUALITY_HIGH.equals(quality);
}
+ public static int getVideoTimeLapseQuality(String quality) {
+ if (VIDEO_TIME_LAPSE_QUALITY_LOW.equals(quality)) {
+ return TIME_LAPSE_VIDEO_QUALITY_LOW;
+ } else if (VIDEO_TIME_LAPSE_QUALITY_HIGH.equals(quality)) {
+ return TIME_LAPSE_VIDEO_QUALITY_HIGH;
+ } else if (VIDEO_TIME_LAPSE_QUALITY_720P.equals(quality)) {
+ return TIME_LAPSE_VIDEO_QUALITY_720P;
+ } else if (VIDEO_TIME_LAPSE_QUALITY_1080P.equals(quality)) {
+ return TIME_LAPSE_VIDEO_QUALITY_1080P;
+ } else {
+ throw new IllegalArgumentException("Unknown quality" + quality);
+ }
+ }
+
public static int getVidoeDurationInMillis(String quality) {
if (VIDEO_QUALITY_MMS.equals(quality)) {
return MMS_VIDEO_DURATION * 1000;
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java
index 17755f9..b5e4a13 100644
--- a/src/com/android/camera/MenuHelper.java
+++ b/src/com/android/camera/MenuHelper.java
@@ -59,6 +59,7 @@ public class MenuHelper {
public static final int POSITION_SWITCH_CAMERA_MODE = 1;
public static final int POSITION_GOTO_GALLERY = 2;
public static final int POSITION_SWITCH_CAMERA_ID = 3;
+ public static final int POSITION_SWITCH_TIME_LAPSE_MODE = 4;
public static final int NO_STORAGE_ERROR = -1;
public static final int CANNOT_STAT_ERROR = -2;
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index de99562..2af46fd 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -22,7 +22,9 @@ import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
+import android.hardware.Camera.Size;
import android.util.Log;
+import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.animation.Animation;
@@ -31,6 +33,7 @@ import android.view.animation.TranslateAnimation;
import com.android.camera.gallery.IImage;
import com.android.camera.R;
+import java.util.List;
import java.io.Closeable;
/**
@@ -298,4 +301,50 @@ public class Util {
int result = (info.mOrientation - degrees + 360) % 360;
camera.setDisplayOrientation(result);
}
+
+ public static Size getOptimalPreviewSize(Activity currentActivity,
+ List<Size> sizes, double targetRatio) {
+ final double ASPECT_TOLERANCE = 0.05;
+ if (sizes == null) return null;
+
+ Size optimalSize = null;
+ double minDiff = Double.MAX_VALUE;
+
+ // Because of bugs of overlay and layout, we sometimes will try to
+ // layout the viewfinder in the portrait orientation and thus get the
+ // wrong size of mSurfaceView. When we change the preview size, the
+ // new overlay will be created before the old one closed, which causes
+ // an exception. For now, just get the screen size
+
+ Display display = currentActivity.getWindowManager().getDefaultDisplay();
+ int targetHeight = Math.min(display.getHeight(), display.getWidth());
+
+ if (targetHeight <= 0) {
+ // We don't know the size of SurfaceView, use screen height
+ targetHeight = display.getHeight();
+ }
+
+ // Try to find an size match aspect ratio and size
+ for (Size size : sizes) {
+ double ratio = (double) size.width / size.height;
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+
+ // Cannot find the one match the aspect ratio, ignore the requirement
+ if (optimalSize == null) {
+ Log.v(TAG, "No preview size match the aspect ratio");
+ minDiff = Double.MAX_VALUE;
+ for (Size size : sizes) {
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ }
+ return optimalSize;
+ }
}
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index b5cafe3..04b3c26 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -52,6 +52,7 @@ import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.MediaStore.Video;
import android.util.Log;
+import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -130,6 +131,7 @@ public class VideoCamera extends NoSearchActivity
private ImageView mVideoFrame;
private GLRootView mGLRootView;
private CamcorderHeadUpDisplay mHeadUpDisplay;
+ private MenuItem mSwitchTimeLapseMenuItem;
private boolean mIsVideoCaptureIntent;
private boolean mQuickCapture;
@@ -160,6 +162,15 @@ public class VideoCamera extends NoSearchActivity
// The video duration limit. 0 menas no limit.
private int mMaxVideoDurationInMs;
+ // Time Lapse parameters.
+ private boolean mCaptureTimeLapse = false;
+ private boolean mUseStillCameraForTimeLapse = false;
+ private int mTimeBetweenTimeLapseFrameCaptureMs = 2000;
+ private int mEncoderLevel;
+
+ private int mDesiredPreviewWidth;
+ private int mDesiredPreviewHeight;
+
boolean mPausing = false;
boolean mSwitching;
boolean mPreviewing = false; // True if preview is started.
@@ -388,11 +399,10 @@ public class VideoCamera extends NoSearchActivity
}
private void initializeHeadUpDisplay() {
- mHeadUpDisplay = new CamcorderHeadUpDisplay(this);
+ mHeadUpDisplay = new CamcorderHeadUpDisplay(this, mCaptureTimeLapse);
CameraSettings settings = new CameraSettings(this, mParameters);
- PreferenceGroup group =
- settings.getPreferenceGroup(R.xml.video_preferences);
+ PreferenceGroup group = settings.getPreferenceGroup(R.xml.video_preferences);
if (mIsVideoCaptureIntent) {
group = filterPreferenceScreenByIntent(group);
}
@@ -538,7 +548,76 @@ public class VideoCamera extends NoSearchActivity
: STORAGE_STATUS_OK;
}
+ private void readTimeLapseVideoPreferences() {
+ String qualityStr = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_TIME_LAPSE_QUALITY,
+ CameraSettings.DEFAULT_VIDEO_TIME_LAPSE_QUALITY_VALUE);
+
+ int quality = CameraSettings.getVideoTimeLapseQuality(qualityStr);
+
+ mProfile = CamcorderProfile.get(
+ (quality == CameraSettings.TIME_LAPSE_VIDEO_QUALITY_LOW)
+ ? CamcorderProfile.QUALITY_LOW
+ : CamcorderProfile.QUALITY_HIGH);
+
+ mTimeBetweenTimeLapseFrameCaptureMs = 2000;
+
+ // TODO: Add new profiles for time lapse instead of setting mProfile
+ // values here.
+ switch (quality) {
+ case CameraSettings.TIME_LAPSE_VIDEO_QUALITY_LOW:
+ mUseStillCameraForTimeLapse = false;
+ mProfile.videoFrameWidth = 176;
+ mProfile.videoFrameHeight = 144;
+ mEncoderLevel = 0;
+ break;
+
+ case CameraSettings.TIME_LAPSE_VIDEO_QUALITY_HIGH:
+ mUseStillCameraForTimeLapse = false;
+ mProfile.videoFrameWidth = 720;
+ mProfile.videoFrameHeight = 480;
+ mEncoderLevel = 0;
+ break;
+
+ case CameraSettings.TIME_LAPSE_VIDEO_QUALITY_720P:
+ mUseStillCameraForTimeLapse = true;
+ mProfile.videoFrameWidth = 1280;
+ mProfile.videoFrameHeight = 720;
+ mProfile.videoBitRate = 20000000;
+ mEncoderLevel = 50;
+ break;
+
+ case CameraSettings.TIME_LAPSE_VIDEO_QUALITY_1080P:
+ mUseStillCameraForTimeLapse = true;
+ mProfile.videoFrameWidth = 1920;
+ mProfile.videoFrameHeight = 1088;
+ mProfile.videoBitRate = 20000000;
+ mEncoderLevel = 50;
+ break;
+ }
+
+ if (mUseStillCameraForTimeLapse) {
+ // When using still camera for capturing time lapse frames
+ // mProfile.{videoFrameWidth,videoFrameHeight} may correspond to
+ // HD resolution not supported by the video camera. So choose
+ // preview size optimally from the supported preview sizes.
+ List<Size> sizes = mParameters.getSupportedPreviewSizes();
+ Size optimalSize = Util.getOptimalPreviewSize(this,
+ sizes, (double) mProfile.videoFrameWidth / mProfile.videoFrameHeight);
+ mDesiredPreviewWidth = optimalSize.width;
+ mDesiredPreviewHeight = optimalSize.height;
+ } else {
+ mDesiredPreviewWidth = mProfile.videoFrameWidth;
+ mDesiredPreviewHeight = mProfile.videoFrameHeight;
+ }
+ }
+
private void readVideoPreferences() {
+ if (mCaptureTimeLapse) {
+ readTimeLapseVideoPreferences();
+ return;
+ }
+
String quality = mPreferences.getString(
CameraSettings.KEY_VIDEO_QUALITY,
CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE);
@@ -566,6 +645,9 @@ public class VideoCamera extends NoSearchActivity
mProfile = CamcorderProfile.get(videoQualityHigh
? CamcorderProfile.QUALITY_HIGH
: CamcorderProfile.QUALITY_LOW);
+
+ mDesiredPreviewWidth = mProfile.videoFrameWidth;
+ mDesiredPreviewHeight = mProfile.videoFrameHeight;
}
private void resizeForPreviewAspectRatio() {
@@ -672,17 +754,7 @@ public class VideoCamera extends NoSearchActivity
mPreviewing = false;
}
- @Override
- protected void onPause() {
- super.onPause();
- mPausing = true;
-
- changeHeadUpDisplayState();
-
- // Hide the preview now. Otherwise, the preview may be rotated during
- // onPause and it is annoying to users.
- mVideoPreview.setVisibility(View.INVISIBLE);
-
+ private void finishRecorderAndCloseCamera() {
// This is similar to what mShutterButton.performClick() does,
// but not quite the same.
if (mMediaRecorderRecording) {
@@ -696,6 +768,20 @@ public class VideoCamera extends NoSearchActivity
stopVideoRecording();
}
closeCamera();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mPausing = true;
+
+ changeHeadUpDisplayState();
+
+ // Hide the preview now. Otherwise, the preview may be rotated during
+ // onPause and it is annoying to users.
+ mVideoPreview.setVisibility(View.INVISIBLE);
+
+ finishRecorderAndCloseCamera();
if (mReceiver != null) {
unregisterReceiver(mReceiver);
@@ -923,6 +1009,10 @@ public class VideoCamera extends NoSearchActivity
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setProfile(mProfile);
mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs);
+ if (mCaptureTimeLapse) {
+ mMediaRecorder.setTimeLapseParameters(mCaptureTimeLapse, mUseStillCameraForTimeLapse,
+ mTimeBetweenTimeLapseFrameCaptureMs, mEncoderLevel);
+ }
// Set output file.
if (mStorageStatus != STORAGE_STATUS_OK) {
@@ -1045,6 +1135,14 @@ public class VideoCamera extends NoSearchActivity
}
}
+ private void setTimeLapseSwitchTitle(boolean enableTimeLapse) {
+ int labelId = enableTimeLapse
+ ? R.string.enable_time_lapse_mode
+ : R.string.disable_time_lapse_mode;
+
+ mSwitchTimeLapseMenuItem.setTitle(labelId);
+ }
+
private void addBaseMenuItems(Menu menu) {
MenuHelper.addSwitchModeMenuItem(menu, false, new Runnable() {
public void run() {
@@ -1075,6 +1173,51 @@ public class VideoCamera extends NoSearchActivity
}
}).setIcon(android.R.drawable.ic_menu_camera);
}
+
+ mSwitchTimeLapseMenuItem = menu.add(Menu.NONE, Menu.NONE,
+ MenuHelper.POSITION_SWITCH_TIME_LAPSE_MODE,
+ R.string.enable_time_lapse_mode)
+ .setOnMenuItemClickListener(new OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ switchTimeLapseMode();
+ return true;
+ }
+ }).setIcon(android.R.drawable.ic_menu_camera);
+ }
+
+ private void switchTimeLapseMode() {
+ mCaptureTimeLapse = !mCaptureTimeLapse;
+
+ mSwitching = true;
+ changeHeadUpDisplayState();
+
+ finishRecorderAndCloseCamera();
+ mHandler.removeMessages(INIT_RECORDER);
+
+ // Read the video preferences
+ readVideoPreferences();
+ resetCameraParameters();
+
+ // Restart preview
+ try {
+ startPreview();
+ } catch (CameraHardwareException e) {
+ showCameraBusyAndFinish();
+ return;
+ }
+
+ // Reload the UI.
+ initializeHeadUpDisplay();
+
+ if (mSurfaceHolder != null) {
+ mHandler.sendEmptyMessage(INIT_RECORDER);
+ }
+
+ mSwitching = false;
+ changeHeadUpDisplayState();
+
+ // Change menu
+ setTimeLapseSwitchTitle(!mCaptureTimeLapse);
}
private void switchCameraId() {
@@ -1085,19 +1228,7 @@ public class VideoCamera extends NoSearchActivity
changeHeadUpDisplayState();
- // This is similar to what mShutterButton.performClick() does,
- // but not quite the same.
- if (mMediaRecorderRecording) {
- if (mIsVideoCaptureIntent) {
- stopVideoRecording();
- showAlert();
- } else {
- stopVideoRecordingAndGetThumbnail();
- }
- } else {
- stopVideoRecording();
- }
- closeCamera();
+ finishRecorderAndCloseCamera();
mHandler.removeMessages(INIT_RECORDER);
// Reload the preferences.
@@ -1443,7 +1574,7 @@ public class VideoCamera extends NoSearchActivity
private void setCameraParameters() {
mParameters = mCameraDevice.getParameters();
- mParameters.setPreviewSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
+ mParameters.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight);
mParameters.setPreviewFrameRate(mProfile.videoFrameRate);
// Set flash mode.
@@ -1516,8 +1647,8 @@ public class VideoCamera extends NoSearchActivity
private void resetCameraParameters() {
// We need to restart the preview if preview size is changed.
Size size = mParameters.getPreviewSize();
- if (size.width != mProfile.videoFrameWidth
- || size.height != mProfile.videoFrameHeight) {
+ if (size.width != mDesiredPreviewWidth
+ || size.height != mDesiredPreviewHeight) {
// It is assumed media recorder is released before
// onSharedPreferenceChanged, so we can close the camera here.
closeCamera();
diff --git a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
index c90917d..8c8ed5a 100644
--- a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
+++ b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
@@ -26,10 +26,12 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay {
private static final String TAG = "CamcorderHeadUpDisplay";
+ private boolean mCaptureTimeLapse;
private OtherSettingsIndicator mOtherSettings;
- public CamcorderHeadUpDisplay(Context context) {
+ public CamcorderHeadUpDisplay(Context context, boolean captureTimeLapse) {
super(context);
+ mCaptureTimeLapse = captureTimeLapse;
}
@Override
@@ -57,6 +59,10 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay {
addIndicator(context, group, CameraSettings.KEY_WHITE_BALANCE);
addIndicator(context, group, CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE);
- addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY);
+ if (mCaptureTimeLapse) {
+ addIndicator(context, group, CameraSettings.KEY_VIDEO_TIME_LAPSE_QUALITY);
+ } else {
+ addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY);
+ }
}
}