diff options
author | Nipun Kwatra <nkwatra@google.com> | 2010-08-05 21:17:04 -0700 |
---|---|---|
committer | Nipun Kwatra <nkwatra@google.com> | 2010-08-10 16:13:31 -0700 |
commit | 6227fa641518492a6b660c78463da18d9ec8fcd8 (patch) | |
tree | 5a1e119ce65e88fb8a04a8f0f2e235973344d448 | |
parent | 80a188c1743205093794a81b021b2ca232423d36 (diff) | |
download | packages_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
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 Binary files differnew file mode 100644 index 0000000..d2a39e4 --- /dev/null +++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png 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 Binary files differnew file mode 100644 index 0000000..5567eb0 --- /dev/null +++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png 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 Binary files differnew file mode 100644 index 0000000..ce0cf42 --- /dev/null +++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png 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 Binary files differnew file mode 100644 index 0000000..cb66c52 --- /dev/null +++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png 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 Binary files differnew file mode 100644 index 0000000..199e0ef --- /dev/null +++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png 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 Binary files differnew file mode 100644 index 0000000..1104ce5 --- /dev/null +++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png 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 Binary files differnew file mode 100644 index 0000000..8b99109 --- /dev/null +++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png 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 Binary files differnew file mode 100644 index 0000000..36e2c1a --- /dev/null +++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png 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); + } } } |