diff options
-rw-r--r-- | assets/dependency.json | 15 | ||||
-rwxr-xr-x[-rw-r--r--] | res/layout/bestpicture_page.xml | 6 | ||||
-rw-r--r-- | res/layout/scene_mode_label.xml | 12 | ||||
-rw-r--r-- | res/xml/setting_menu_preferences.xml | 7 | ||||
-rwxr-xr-x | rs/rotator.rs | 9 | ||||
-rw-r--r-- | src/com/android/camera/CaptureModule.java | 382 | ||||
-rw-r--r-- | src/com/android/camera/CaptureUI.java | 17 | ||||
-rw-r--r-- | src/com/android/camera/ComboPreferences.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/PhotoModule.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/SettingsManager.java | 37 | ||||
-rwxr-xr-x | src/com/android/camera/imageprocessor/FrameProcessor.java | 3 | ||||
-rwxr-xr-x | src/com/android/camera/ui/OneUICameraControls.java | 1 | ||||
-rw-r--r-- | src/com/android/camera/ui/PanoCaptureProcessView.java | 30 | ||||
-rw-r--r-- | src/com/android/camera/ui/ProMode.java | 8 | ||||
-rwxr-xr-x | src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java | 6 |
15 files changed, 413 insertions, 124 deletions
diff --git a/assets/dependency.json b/assets/dependency.json index 6c8584cad..cbc96587d 100644 --- a/assets/dependency.json +++ b/assets/dependency.json @@ -86,6 +86,14 @@ "103": {"pref_camera2_coloreffect_key":"0"} , + "104": + {"pref_camera2_coloreffect_key":"0"} + , + "105": + {"pref_camera2_flashmode_key":"off", + "pref_camera2_coloreffect_key":"0", + "pref_camera2_longshot_key":"off"} + , "106": {"pref_camera2_coloreffect_key":"0"} , @@ -95,13 +103,8 @@ "108": {"pref_camera2_coloreffect_key":"0"} , - "104": + "109": {"pref_camera2_coloreffect_key":"0"} - , - "105": - {"pref_camera2_flashmode_key":"off", - "pref_camera2_coloreffect_key":"0", - "pref_camera2_longshot_key":"off"} }, "pref_camera2_clearsight_key": { diff --git a/res/layout/bestpicture_page.xml b/res/layout/bestpicture_page.xml index d6b6022c8..5a1b604f0 100644..100755 --- a/res/layout/bestpicture_page.xml +++ b/res/layout/bestpicture_page.xml @@ -34,9 +34,9 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. <ImageView android:id="@+id/image_view" android:adjustViewBounds="true" - android:scaleType="fitXY" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:scaleType="fitCenter" + android:layout_width="match_parent" + android:layout_height="match_parent" android:layout_gravity="center" /> <RelativeLayout android:layout_width="match_parent" diff --git a/res/layout/scene_mode_label.xml b/res/layout/scene_mode_label.xml index aa5ef211c..e0d8d43b8 100644 --- a/res/layout/scene_mode_label.xml +++ b/res/layout/scene_mode_label.xml @@ -33,7 +33,8 @@ android:layout_height="wrap_content" android:layout_marginRight="20dp" android:background="#90000000" - android:orientation="horizontal"> + android:orientation="horizontal" + android:gravity="center_vertical"> <TextView android:id="@+id/scene_mode_label" android:singleLine="true" @@ -43,8 +44,13 @@ style="@style/OnViewfinderSceneLabel" /> <ImageView android:id="@+id/scene_mode_label_close" - android:src="@drawable/x" - style="@style/OnViewfinderSceneLabel"/> + android:layout_width="15dp" + android:layout_height="15dp" + android:layout_marginLeft="10dp" + android:layout_marginRight="10dp" + android:layout_marginTop="5dp" + android:layout_marginBottom="5dp" + android:src="@drawable/x" /> </LinearLayout> </com.android.camera.ui.RotateLayout> </LinearLayout>
\ No newline at end of file diff --git a/res/xml/setting_menu_preferences.xml b/res/xml/setting_menu_preferences.xml index 5cf6c0dd1..9c9d5d26a 100644 --- a/res/xml/setting_menu_preferences.xml +++ b/res/xml/setting_menu_preferences.xml @@ -196,11 +196,14 @@ android:layout="@layout/preference" android:title="@string/pref_camera_dis_title" /> - <SwitchPreference - android:defaultValue="false" + <ListPreference + android:defaultValue="@string/pref_camera_noise_reduction_default" + android:entries="@array/pref_camera2_noise_reduction_entries" + android:entryValues="@array/pref_camera2_noise_reduction_entryvalues" android:icon="@drawable/noise_reduction" android:key="pref_camera2_noise_reduction_key" android:layout="@layout/preference" + android:summary="%s" android:title="@string/pref_camera_noise_reduction_title" /> <ListPreference diff --git a/rs/rotator.rs b/rs/rotator.rs index 2c57951d6..62257d2cf 100755 --- a/rs/rotator.rs +++ b/rs/rotator.rs @@ -50,6 +50,10 @@ uchar __attribute__((kernel)) rotate90andMerge(uint32_t x, uint32_t y) { if(x >= width - pad) return (uchar)0; rsSetElementAt_uchar(gOut, yValue, (width-1-x-pad)*height + y); + } else if (degree == 0) { + if(x >= width - pad) + return (uchar)0; + rsSetElementAt_uchar(gOut, yValue, x*height + y); } @@ -71,6 +75,11 @@ uchar __attribute__((kernel)) rotate90andMerge(uint32_t x, uint32_t y) { return (uchar)0; rsSetElementAt_uchar(gOut, uValue, ySize + (width-1-x-pad)/2*height + y -1); rsSetElementAt_uchar(gOut, vValue, ySize + (width-1-x-pad)/2*height + y); + } else if (degree == 0) { + if(x >= (width - pad)) + return (uchar)0; + rsSetElementAt_uchar(gOut, uValue, ySize + x/2*height + y - 1); + rsSetElementAt_uchar(gOut, vValue, ySize + x/2*height + y); } } return (uchar)0; diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index ae8676b50..e870161f3 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -56,11 +56,14 @@ import android.media.ImageReader; import android.media.MediaActionSound; import android.media.MediaMetadataRetriever; import android.media.MediaRecorder; +import android.media.EncoderCapabilities; +import android.media.EncoderCapabilities.VideoEncoderCap; import android.net.Uri; import android.os.Debug; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; +import android.os.Bundle; import android.os.Message; import android.os.SystemClock; import android.provider.MediaStore; @@ -76,7 +79,6 @@ import android.view.WindowManager; import android.widget.Toast; import com.android.camera.exif.ExifInterface; -import com.android.camera.Exif; import com.android.camera.imageprocessor.filter.BlurbusterFilter; import com.android.camera.imageprocessor.filter.ChromaflashFilter; import com.android.camera.imageprocessor.filter.ImageFilter; @@ -236,6 +238,13 @@ public class CaptureModule implements CameraModule, PhotoController, private int mChosenImageFormat; private Toast mToast; + private boolean mStartRecPending = false; + private boolean mStopRecPending = false; + + boolean mUnsupportedResolution = false; + + private static final int SDCARD_SIZE_LIMIT = 4000 * 1024 * 1024; + /** * A {@link CameraCaptureSession } for camera preview. */ @@ -312,6 +321,7 @@ public class CaptureModule implements CameraModule, PhotoController, private MediaActionSound mSound; private Size mSupportedMaxPictureSize; + private class SelfieThread extends Thread { public void run() { try { @@ -632,10 +642,10 @@ public class CaptureModule implements CameraModule, PhotoController, break; } case STATE_AF_AE_LOCKED: { - Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); - Log.d(TAG, "STATE_AF_AE_LOCKED id: " + id + " afState:" + afState + " aeState:" + aeState); - break; + Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); + Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); + Log.d(TAG, "STATE_AF_AE_LOCKED id: " + id + " afState:" + afState + " aeState:" + aeState); + break; } case STATE_WAITING_TOUCH_FOCUS: break; @@ -913,7 +923,7 @@ public class CaptureModule implements CameraModule, PhotoController, @Override public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { - Log.e(TAG, "cameracapturesession - onConfigureFailed "+id); + Log.e(TAG, "cameracapturesession - onConfigureFailed "+ id); if (mActivity.isFinishing()) { return; } @@ -986,6 +996,9 @@ public class CaptureModule implements CameraModule, PhotoController, } public void setAFModeToPreview(int id, int afMode) { + if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + return; + } Log.d(TAG, "setAFModeToPreview " + afMode); mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AF_MODE, afMode); applyAFRegions(mPreviewRequestBuilder[id], id); @@ -994,14 +1007,17 @@ public class CaptureModule implements CameraModule, PhotoController, try { mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id] .build(), mCaptureCallback, mCameraHandler); - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } public void setFlashModeToPreview(int id, boolean isFlashOn) { Log.d(TAG, "setFlashModeToPreview " + isFlashOn); - if(isFlashOn) { + if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + return; + } + if (isFlashOn) { mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); mPreviewRequestBuilder[id].set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE); } else { @@ -1014,23 +1030,26 @@ public class CaptureModule implements CameraModule, PhotoController, try { mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id] .build(), mCaptureCallback, mCameraHandler); - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } public void setFocusDistanceToPreview(int id, float fd) { + if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + return; + } mPreviewRequestBuilder[id].set(CaptureRequest.LENS_FOCUS_DISTANCE, fd); mPreviewRequestBuilder[id].setTag(id); try { - if(id == MONO_ID && !canStartMonoPreview()) { + if (id == MONO_ID && !canStartMonoPreview()) { mCaptureSession[id].capture(mPreviewRequestBuilder[id] .build(), mCaptureCallback, mCameraHandler); } else { mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id] .build(), mCaptureCallback, mCameraHandler); } - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } @@ -1123,7 +1142,9 @@ public class CaptureModule implements CameraModule, PhotoController, * Lock the focus as the first step for a still image capture. */ private void lockFocus(int id) { - if (mActivity == null || mCameraDevice[id] == null) { + if (mActivity == null || mCameraDevice[id] == null + || !checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + mUI.enableShutter(true); warningToast("Camera is not ready yet to take a picture."); return; } @@ -1166,14 +1187,15 @@ public class CaptureModule implements CameraModule, PhotoController, mLockRequestHashCode[id] = request.hashCode(); mState[id] = STATE_WAITING_AF_LOCK; mCaptureSession[id].capture(request, mCaptureCallback, mCameraHandler); - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } private void autoFocusTrigger(int id) { Log.d(TAG, "autoFocusTrigger " + id); - if (null == mActivity || null == mCameraDevice[id]) { + if (null == mActivity || null == mCameraDevice[id] + || !checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { warningToast("Camera is not ready yet to take a picture."); return; } @@ -1190,7 +1212,7 @@ public class CaptureModule implements CameraModule, PhotoController, Message message = mCameraHandler.obtainMessage( CANCEL_TOUCH_FOCUS, Integer.valueOf(mCameraId[id]), 0); mCameraHandler.sendMessageDelayed(message, CANCEL_TOUCH_FOCUS_DELAY); - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } @@ -1383,7 +1405,7 @@ public class CaptureModule implements CameraModule, PhotoController, private void captureVideoSnapshot(final int id) { Log.d(TAG, "captureStillPicture " + id); try { - if (null == mActivity || null == mCameraDevice[id]) { + if (null == mActivity || null == mCameraDevice[id] || mCurrentSession == null) { warningToast("Camera is not ready yet to take a video snapshot."); return; } @@ -1433,6 +1455,9 @@ public class CaptureModule implements CameraModule, PhotoController, */ private void runPrecaptureSequence(int id) { Log.d(TAG, "runPrecaptureSequence: " + id); + if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + return; + } try { CaptureRequest.Builder builder = getRequestBuilder(id); builder.setTag(id); @@ -1443,7 +1468,7 @@ public class CaptureModule implements CameraModule, PhotoController, mState[id] = STATE_WAITING_PRECAPTURE; mCaptureSession[id].capture(request, mCaptureCallback, mCameraHandler); - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } @@ -1588,6 +1613,9 @@ public class CaptureModule implements CameraModule, PhotoController, */ public void unlockFocus(int id) { Log.d(TAG, "unlockFocus " + id); + if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + return; + } try { CaptureRequest.Builder builder = getRequestBuilder(id); builder.setTag(id); @@ -1619,12 +1647,8 @@ public class CaptureModule implements CameraModule, PhotoController, } }); } - } catch (NullPointerException e) { + } catch (NullPointerException | IllegalStateException | CameraAccessException e) { Log.w(TAG, "Session is already closed"); - } catch (IllegalStateException e) { - Log.w(TAG, "Session is already closed"); - } catch (CameraAccessException e) { - e.printStackTrace(); } } @@ -1645,6 +1669,15 @@ public class CaptureModule implements CameraModule, PhotoController, } } + public boolean isAllSessionClosed() { + for (int i = MAX_NUM_CAM - 1; i >= 0; i--) { + if (mCaptureSession[i] != null) { + return false; + } + } + return true; + } + private void closeSessions() { for (int i = MAX_NUM_CAM-1; i >= 0; i--) { if (null != mCaptureSession[i]) { @@ -1727,13 +1760,16 @@ public class CaptureModule implements CameraModule, PhotoController, * Lock the exposure for capture */ private void lockExposure(int id) { + if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + return; + } Log.d(TAG, "lockExposure: " + id); try { applySettingsForLockExposure(mPreviewRequestBuilder[id], id); mState[id] = STATE_WAITING_AE_LOCK; mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id].build(), mCaptureCallback, mCameraHandler); - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } @@ -1918,6 +1954,7 @@ public class CaptureModule implements CameraModule, PhotoController, mFirstPreviewLoaded = false; stopBackgroundThread(); mLastJpegData = null; + setProModeVisible(); } @Override @@ -2132,14 +2169,9 @@ public class CaptureModule implements CameraModule, PhotoController, }); mUI.enableShutter(true); mUI.enableVideo(true); - String scene = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE); - boolean promode = false; - if (scene != null) { - int mode = Integer.parseInt(scene); - if (mode == SettingsManager.SCENE_MODE_PROMODE_INT) promode = true; - } - mUI.initializeProMode(promode); + setProModeVisible(); + String scene = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE); if(isPanoSetting(scene)) { mActivity.onModuleSelected(ModuleSwitcher.PANOCAPTURE_MODULE_INDEX); } @@ -2403,8 +2435,8 @@ public class CaptureModule implements CameraModule, PhotoController, @Override public void onCountDownFinished() { - mUI.showUIAfterCountDown(); checkSelfieFlashAndTakePicture(); + mUI.showUIAfterCountDown(); } @Override @@ -2603,30 +2635,54 @@ public class CaptureModule implements CameraModule, PhotoController, } } - private void startRecordingVideo(final int cameraId) { + private boolean startRecordingVideo(final int cameraId) { if (null == mCameraDevice[cameraId]) { - return; + return false; } Log.d(TAG, "StartRecordingVideo " + cameraId); + mStartRecPending = true; mIsRecordingVideo = true; mMediaRecorderPausing = false; mUI.hideUIwhileRecording(); - mUI.clearFocus(); - mCameraHandler.removeMessages(CANCEL_TOUCH_FOCUS, mCameraId[cameraId]); - mState[cameraId] = STATE_PREVIEW; - mControlAFMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE; - closePreviewSession(); - mFrameProcessor.onClose(); - boolean changed = mUI.setPreviewSize(mVideoPreviewSize.getWidth(), - mVideoPreviewSize.getHeight()); - if (changed) { - mUI.hideSurfaceView(); - mUI.showSurfaceView(); + + mActivity.updateStorageSpaceAndHint(); + if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) { + Log.w(TAG, "Storage issue, ignore the start request"); + mStartRecPending = false; + mIsRecordingVideo = false; + return false; } - mUI.resetTrackingFocus(); try { setUpMediaRecorder(cameraId); + if (mUnsupportedResolution == true ) { + Log.v(TAG, "Unsupported Resolution according to target"); + mStartRecPending = false; + mIsRecordingVideo = false; + return false; + } + if (mMediaRecorder == null) { + Log.e(TAG, "Fail to initialize media recorder"); + mStartRecPending = false; + mIsRecordingVideo = false; + return false; + } + + requestAudioFocus(); + mUI.clearFocus(); + mCameraHandler.removeMessages(CANCEL_TOUCH_FOCUS, mCameraId[cameraId]); + mState[cameraId] = STATE_PREVIEW; + mControlAFMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE; + closePreviewSession(); + mFrameProcessor.onClose(); + boolean changed = mUI.setPreviewSize(mVideoPreviewSize.getWidth(), + mVideoPreviewSize.getHeight()); + if (changed) { + mUI.hideSurfaceView(); + mUI.showSurfaceView(); + } + mUI.resetTrackingFocus(); + createVideoSnapshotImageReader(); mVideoRequestBuilder = mCameraDevice[cameraId].createCaptureRequest(CameraDevice.TEMPLATE_RECORD); mVideoRequestBuilder.setTag(cameraId); @@ -2676,7 +2732,17 @@ public class CaptureModule implements CameraModule, PhotoController, + e.getMessage()); e.printStackTrace(); } - mMediaRecorder.start(); + try { + mMediaRecorder.start(); // Recording is now started + } catch (RuntimeException e) { + Toast.makeText(mActivity,"Could not start media recorder.\n " + + "Can't start video recording.", Toast.LENGTH_LONG).show(); + releaseMediaRecorder(); + releaseAudioFocus(); + mStartRecPending = false; + mIsRecordingVideo = false; + return; + } mUI.clearFocus(); mUI.resetPauseButton(); mRecordingTotalTime = 0L; @@ -2705,11 +2771,23 @@ public class CaptureModule implements CameraModule, PhotoController, try { setUpVideoCaptureRequestBuilder(mVideoRequestBuilder); mCurrentSession.setRepeatingRequest(mVideoRequestBuilder.build(), - mCaptureCallback, mCameraHandler); + mCaptureCallback, mCameraHandler); } catch (CameraAccessException e) { e.printStackTrace(); + } catch (IllegalStateException e) { + e.printStackTrace(); + } + try { + mMediaRecorder.start(); // Recording is now started + } catch (RuntimeException e) { + Toast.makeText(mActivity,"Could not start media recorder.\n " + + "Can't start video recording.", Toast.LENGTH_LONG).show(); + releaseMediaRecorder(); + releaseAudioFocus(); + mStartRecPending = false; + mIsRecordingVideo = false; + return; } - mMediaRecorder.start(); mUI.clearFocus(); mUI.resetPauseButton(); mRecordingTotalTime = 0L; @@ -2730,6 +2808,8 @@ public class CaptureModule implements CameraModule, PhotoController, } catch (IOException e) { e.printStackTrace(); } + mStartRecPending = false; + return true; } private void updateTimeLapseSetting() { @@ -2799,7 +2879,7 @@ public class CaptureModule implements CameraModule, PhotoController, private void applyVideoStabilization(CaptureRequest.Builder builder) { String value = mSettingsManager.getValue(SettingsManager.KEY_DIS); if (value == null) return; - if (value.equals("enable")) { + if (value.equals("on")) { builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, CaptureRequest .CONTROL_VIDEO_STABILIZATION_MODE_ON); } else { @@ -2903,6 +2983,7 @@ public class CaptureModule implements CameraModule, PhotoController, private void stopRecordingVideo(int cameraId) { Log.d(TAG, "stopRecordingVideo " + cameraId); + mStopRecPending = true; boolean shouldAddToMediaStoreNow = false; // Stop recording mFrameProcessor.setVideoOutputSurface(null); @@ -2916,7 +2997,7 @@ public class CaptureModule implements CameraModule, PhotoController, AccessibilityUtils.makeAnnouncement(mUI.getVideoButton(), mActivity.getString(R.string.video_recording_stopped)); } catch (RuntimeException e) { - Log.e(TAG, "MediaRecoder stop fail", e); + Log.w(TAG, "MediaRecoder stop fail", e); if (mVideoFilename != null) deleteVideoFile(mVideoFilename); } if (shouldAddToMediaStoreNow) { @@ -2943,6 +3024,7 @@ public class CaptureModule implements CameraModule, PhotoController, createSessions(); mUI.showUIafterRecording(); mUI.resetTrackingFocus(); + mStopRecPending = false; } private void closePreviewSession() { @@ -3024,11 +3106,19 @@ public class CaptureModule implements CameraModule, PhotoController, size = CameraSettings.getTimeLapseQualityFor(size); } + Intent intent = mActivity.getIntent(); + Bundle myExtras = intent.getExtras(); + if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder(); updateHFRSetting(); boolean hfr = mHighSpeedCapture && !mHighSpeedRecordingMode; + mProfile = CamcorderProfile.get(cameraId, size); + int videoWidth = mProfile.videoFrameWidth; + int videoHeight = mProfile.videoFrameHeight; + mUnsupportedResolution = false; + int videoEncoder = SettingTranslation .getVideoEncoder(mSettingsManager.getValue(SettingsManager.KEY_VIDEO_ENCODER)); int audioEncoder = SettingTranslation @@ -3081,6 +3171,54 @@ public class CaptureModule implements CameraModule, PhotoController, mMediaRecorder.setVideoEncodingBitRate(scaledBitrate); } + long requestedSizeLimit = 0; + if (isVideoCaptureIntent() && myExtras != null) { + requestedSizeLimit = myExtras.getLong(MediaStore.EXTRA_SIZE_LIMIT); + } + //check if codec supports the resolution, otherwise throw toast + List<VideoEncoderCap> videoEncoders = EncoderCapabilities.getVideoEncoders(); + for (VideoEncoderCap videoEnc: videoEncoders) { + if (videoEnc.mCodec == videoEncoder) { + if (videoWidth > videoEnc.mMaxFrameWidth || + videoWidth < videoEnc.mMinFrameWidth || + videoHeight > videoEnc.mMaxFrameHeight || + videoHeight < videoEnc.mMinFrameHeight) { + Log.e(TAG, "Selected codec " + videoEncoder + + " does not support "+ videoWidth + "x" + videoHeight + + " resolution"); + Log.e(TAG, "Codec capabilities: " + + "mMinFrameWidth = " + videoEnc.mMinFrameWidth + " , " + + "mMinFrameHeight = " + videoEnc.mMinFrameHeight + " , " + + "mMaxFrameWidth = " + videoEnc.mMaxFrameWidth + " , " + + "mMaxFrameHeight = " + videoEnc.mMaxFrameHeight); + mUnsupportedResolution = true; + RotateTextToast.makeText(mActivity, R.string.error_app_unsupported, + Toast.LENGTH_LONG).show(); + return; + } + break; + } + } + + // Set maximum file size. + long maxFileSize = mActivity.getStorageSpaceBytes() - Storage.LOW_STORAGE_THRESHOLD_BYTES; + if (requestedSizeLimit > 0 && requestedSizeLimit < maxFileSize) { + maxFileSize = requestedSizeLimit; + } + + if (Storage.isSaveSDCard() && maxFileSize > SDCARD_SIZE_LIMIT) { + maxFileSize = SDCARD_SIZE_LIMIT; + } + Log.i(TAG, "MediaRecorder setMaxFileSize: " + maxFileSize); + try { + mMediaRecorder.setMaxFileSize(maxFileSize); + } catch (RuntimeException exception) { + // We are going to ignore failure of setMaxFileSize here, as + // a) The composer selected may simply not support it, or + // b) The underlying media framework may not handle 64-bit range + // on the size restriction. + } + Location loc = mLocationManager.getCurrentLocation(); if (loc != null) { mMediaRecorder.setLocation((float) loc.getLatitude(), @@ -3110,11 +3248,17 @@ public class CaptureModule implements CameraModule, PhotoController, } public void onVideoButtonClick() { + if (isRecorderReady() == false) return; + if (getCameraMode() == DUAL_MODE) return; if (mIsRecordingVideo) { stopRecordingVideo(getMainCameraId()); } else { - startRecordingVideo(getMainCameraId()); + if (!startRecordingVideo(getMainCameraId())) { + // Show ui when start recording failed. + mUI.showUIafterRecording(); + releaseMediaRecorder(); + } } } @@ -3200,7 +3344,7 @@ public class CaptureModule implements CameraModule, PhotoController, } private void estimateJpegFileSize() { - String quality = mSettingsManager.getValue(SettingsManager + String quality = mSettingsManager.getValue(SettingsManager .KEY_JPEG_QUALITY); int[] ratios = mActivity.getResources().getIntArray(R.array.jpegquality_compression_ratio); String[] qualities = mActivity.getResources().getStringArray( @@ -3307,6 +3451,9 @@ public class CaptureModule implements CameraModule, PhotoController, } private boolean applyPreferenceToPreview(int cameraId, String key, String value) { + if (!checkSessionAndBuilder(mCaptureSession[cameraId], mPreviewRequestBuilder[cameraId])) { + return false; + } boolean updatePreview = false; switch (key) { case SettingsManager.KEY_WHITE_BALANCE: @@ -3341,6 +3488,9 @@ public class CaptureModule implements CameraModule, PhotoController, } private void applyZoomAndUpdate(int id) { + if (!checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) { + return; + } applyZoom(mPreviewRequestBuilder[id], id); try { if(id == MONO_ID && !canStartMonoPreview()) { @@ -3350,7 +3500,7 @@ public class CaptureModule implements CameraModule, PhotoController, mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id] .build(), mCaptureCallback, mCameraHandler); } - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } @@ -3464,11 +3614,11 @@ public class CaptureModule implements CameraModule, PhotoController, } private void applyFaceDetection(CaptureRequest.Builder request) { - String value = mSettingsManager.getValue(SettingsManager.KEY_FACE_DETECTION); - if (value != null && value.equals("on")) { - request.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, - CaptureRequest.STATISTICS_FACE_DETECT_MODE_SIMPLE); - } + String value = mSettingsManager.getValue(SettingsManager.KEY_FACE_DETECTION); + if (value != null && value.equals("on")) { + request.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, + CaptureRequest.STATISTICS_FACE_DETECT_MODE_SIMPLE); + } } private void applyFlash(CaptureRequest.Builder request, int id) { @@ -3681,30 +3831,39 @@ public class CaptureModule implements CameraModule, PhotoController, } if (updatePreviewBayer) { try { - mCaptureSession[BAYER_ID].setRepeatingRequest(mPreviewRequestBuilder[BAYER_ID] - .build(), mCaptureCallback, mCameraHandler); - } catch (CameraAccessException e) { + if (checkSessionAndBuilder(mCaptureSession[BAYER_ID], + mPreviewRequestBuilder[BAYER_ID])) { + mCaptureSession[BAYER_ID].setRepeatingRequest(mPreviewRequestBuilder[BAYER_ID] + .build(), mCaptureCallback, mCameraHandler); + } + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } if (updatePreviewMono) { try { - if(canStartMonoPreview()) { - mCaptureSession[MONO_ID].setRepeatingRequest(mPreviewRequestBuilder[MONO_ID] - .build(), mCaptureCallback, mCameraHandler); - } else { - mCaptureSession[MONO_ID].capture(mPreviewRequestBuilder[MONO_ID] - .build(), mCaptureCallback, mCameraHandler); + if (checkSessionAndBuilder(mCaptureSession[MONO_ID], + mPreviewRequestBuilder[MONO_ID])) { + if (canStartMonoPreview()) { + mCaptureSession[MONO_ID].setRepeatingRequest(mPreviewRequestBuilder[MONO_ID] + .build(), mCaptureCallback, mCameraHandler); + } else { + mCaptureSession[MONO_ID].capture(mPreviewRequestBuilder[MONO_ID] + .build(), mCaptureCallback, mCameraHandler); + } } - } catch (CameraAccessException e) { + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } if (updatePreviewFront) { try { - mCaptureSession[FRONT_ID].setRepeatingRequest(mPreviewRequestBuilder[FRONT_ID] - .build(), mCaptureCallback, mCameraHandler); - } catch (CameraAccessException e) { + if (checkSessionAndBuilder(mCaptureSession[FRONT_ID], + mPreviewRequestBuilder[FRONT_ID])) { + mCaptureSession[FRONT_ID].setRepeatingRequest(mPreviewRequestBuilder[FRONT_ID] + .build(), mCaptureCallback, mCameraHandler); + } + } catch (CameraAccessException | IllegalStateException e) { e.printStackTrace(); } } @@ -3745,25 +3904,36 @@ public class CaptureModule implements CameraModule, PhotoController, } public void restartSession(boolean isSurfaceChanged) { + Log.d(TAG, "restartSession isSurfaceChanged = " + isSurfaceChanged); + if (isAllSessionClosed()) return; + + closeProcessors(); + closeSessions(); + if(isSurfaceChanged) { mUI.hideSurfaceView(); + mUI.showSurfaceView(); } - closeProcessors(); - closeSessions(); + initializeValues(); updatePreviewSize(); openProcessors(); - if(isSurfaceChanged) { - mUI.showSurfaceView(); - } else { - createSessions(); - } + createSessions(); if(isTrackingFocusSettingOn()) { mUI.resetTrackingFocus(); } + resetStateMachine(); } + private void resetStateMachine() { + for (int i = 0; i < MAX_NUM_CAM; i++) { + mState[i] = STATE_PREVIEW; + } + mUI.enableShutter(true); + } + + private Size getOptimalPreviewSize(Size pictureSize, Size[] prevSizes, int screenW, int screenH) { if (pictureSize.getWidth() <= screenH && pictureSize.getHeight() <= screenW) { @@ -4027,6 +4197,36 @@ public class CaptureModule implements CameraModule, PhotoController, } } + private void showToast(String tips) { + if (mToast == null) { + mToast = Toast.makeText(mActivity, tips, Toast.LENGTH_LONG); + } + mToast.setText(tips); + mToast.show(); + } + + private boolean isRecorderReady() { + if ((mStartRecPending == true || mStopRecPending == true)) + return false; + else + return true; + } + + /* + * Make sure we're not recording music playing in the background, ask the + * MediaPlaybackService to pause playback. + */ + private void requestAudioFocus() { + AudioManager am = (AudioManager)mActivity.getSystemService(Context.AUDIO_SERVICE); + // Send request to obtain audio focus. This will stop other + // music stream. + int result = am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); + if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { + Log.v(TAG, "Audio focus request failed"); + } + } + private void releaseAudioFocus() { AudioManager am = (AudioManager)mActivity.getSystemService(Context.AUDIO_SERVICE); int result = am.abandonAudioFocus(null); @@ -4035,12 +4235,9 @@ public class CaptureModule implements CameraModule, PhotoController, } } - private void showToast(String tips) { - if (mToast == null) { - mToast = Toast.makeText(mActivity, tips, Toast.LENGTH_LONG); - } - mToast.setText(tips); - mToast.show(); + private boolean isVideoCaptureIntent() { + String action = mActivity.getIntent().getAction(); + return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); } private void resetScreenOn() { @@ -4058,4 +4255,21 @@ public class CaptureModule implements CameraModule, PhotoController, mHandler.removeMessages(CLEAR_SCREEN_DELAY); mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } + + + private void setProModeVisible() { + String scene = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE); + boolean promode = false; + if (scene != null) { + int mode = Integer.parseInt(scene); + if (mode == SettingsManager.SCENE_MODE_PROMODE_INT) { + promode = true; + } + } + mUI.initializeProMode(!mPaused && promode); + } + + boolean checkSessionAndBuilder(CameraCaptureSession session, CaptureRequest.Builder builder) { + return session != null && builder != null; + } } diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java index aed62aaa9..1bb20e9f7 100644 --- a/src/com/android/camera/CaptureUI.java +++ b/src/com/android/camera/CaptureUI.java @@ -228,7 +228,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, return mDisplaySize; } - public CaptureUI(CameraActivity activity, CaptureModule module, View parent) { + public CaptureUI(CameraActivity activity, final CaptureModule module, View parent) { mActivity = activity; mModule = module; mRootView = parent; @@ -298,8 +298,10 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, mMakeupButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { - toggleMakeup(); - updateMenus(); + if (module != null && !module.isAllSessionClosed()) { + toggleMakeup(); + updateMenus(); + } } }); setMakeupButtonIcon(); @@ -315,6 +317,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, initSceneModeButton(); initSwitchCamera(); initFlashButton(); + updateMenus(); mRecordingTimeView = (TextView) mRootView.findViewById(R.id.recording_time); mRecordingTimeRect = (RotateLayout) mRootView.findViewById(R.id.recording_time_rect); @@ -448,6 +451,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, initFlashButton(); setMakeupButtonIcon(); showSceneModeLabel(); + updateMenus(); if(mModule.isTrackingFocusSettingOn()) { mTrackingFocusRenderer.setVisible(false); mTrackingFocusRenderer.setVisible(true); @@ -655,7 +659,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.scene_mode_instructional, null); - int index = mSettingsManager.getValueIndex(SettingsManager.KEY_SCENE_MODE); + final int index = mSettingsManager.getValueIndex(SettingsManager.KEY_SCENE_MODE); TextView name = (TextView)view.findViewById(R.id.scene_mode_name); CharSequence sceneModeNameArray[] = mSettingsManager.getEntries(SettingsManager.KEY_SCENE_MODE); @@ -1042,13 +1046,18 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, boolean enableSceneMenu = true; String makeupValue = mSettingsManager.getValue(SettingsManager.KEY_MAKEUP); int colorEffect = mSettingsManager.getValueIndex(SettingsManager.KEY_COLOR_EFFECT); + String sceneMode = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE); if (makeupValue != null && !makeupValue.equals("0")) { enableSceneMenu = false; enableFilterMenu = false; } else if (colorEffect != 0 || mFilterMenuStatus == FILTER_MENU_ON){ enableSceneMenu = false; enableMakeupMenu = false; + }else if ( sceneMode != null && !sceneMode.equals("0")){ + enableMakeupMenu = false; + enableFilterMenu = false; } + mMakeupButton.setEnabled(enableMakeupMenu); mFilterModeSwitcher.setEnabled(enableFilterMenu); mSceneModeSwitcher.setEnabled(enableSceneMenu); diff --git a/src/com/android/camera/ComboPreferences.java b/src/com/android/camera/ComboPreferences.java index a30dd9448..401289fc3 100644 --- a/src/com/android/camera/ComboPreferences.java +++ b/src/com/android/camera/ComboPreferences.java @@ -68,7 +68,7 @@ public class ComboPreferences implements } } - private static String getLocalSharedPreferencesName( + public static String getLocalSharedPreferencesName( Context context, int cameraId) { return context.getPackageName() + "_preferences_" + cameraId; } diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index 884fe142e..2d67fa9c0 100644 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -2362,7 +2362,7 @@ public class PhotoModule String zsl = mPreferences.getString(CameraSettings.KEY_ZSL, mActivity.getString(R.string.pref_camera_zsl_default)); mUI.overrideSettings(CameraSettings.KEY_ZSL, zsl); - mUI.startCountDown(seconds, isShutterSoundOn()); + mUI.startCountDown(seconds, playSound); } else { mSnapshotOnIdle = false; initiateSnap(); diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java index 7d0f202e1..6adbcfb64 100644 --- a/src/com/android/camera/SettingsManager.java +++ b/src/com/android/camera/SettingsManager.java @@ -451,6 +451,28 @@ public class SettingsManager implements ListMenu.SettingsListener { return pref.findIndexOfValue(value); } + private boolean setFocusValue(String key, float value) { + boolean result = false; + String prefName = ComboPreferences.getLocalSharedPreferencesName(mContext, mCameraId); + SharedPreferences sharedPreferences = mContext.getSharedPreferences(prefName, + Context.MODE_PRIVATE); + float prefValue = sharedPreferences.getFloat(key, 0.5f); + if (prefValue != value) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putFloat(key, value); + editor.apply(); + result = true; + } + return result; + } + + public float getFocusValue(String key) { + String prefName = ComboPreferences.getLocalSharedPreferencesName(mContext, mCameraId); + SharedPreferences sharedPreferences = mContext.getSharedPreferences(prefName, + Context.MODE_PRIVATE); + return sharedPreferences.getFloat(key, 0.5f); + } + public boolean isOverriden(String key) { Values values = mValuesMap.get(key); return values.overriddenValue != null; @@ -479,12 +501,15 @@ public class SettingsManager implements ListMenu.SettingsListener { } } - public void setFocusDistance(float value) { - List<SettingState> list = new ArrayList<>(); - Values values = new Values("" + value, null); - SettingState ss = new SettingState(KEY_FOCUS_DISTANCE, values); - list.add(ss); - notifyListeners(list); + public void setFocusDistance(String key, float value, float minFocus) { + boolean isSuccess = setFocusValue(key, value); + if (isSuccess) { + List<SettingState> list = new ArrayList<>(); + Values values = new Values("" + value * minFocus, null); + SettingState ss = new SettingState(KEY_FOCUS_DISTANCE, values); + list.add(ss); + notifyListeners(list); + } } private void updateMapAndNotify(ListPreference pref) { diff --git a/src/com/android/camera/imageprocessor/FrameProcessor.java b/src/com/android/camera/imageprocessor/FrameProcessor.java index 5dc50c4e5..519d77458 100755 --- a/src/com/android/camera/imageprocessor/FrameProcessor.java +++ b/src/com/android/camera/imageprocessor/FrameProcessor.java @@ -160,6 +160,9 @@ public class FrameProcessor { if(mModule.getMainCameraCharacteristics() != null) { degree = mModule.getMainCameraCharacteristics(). get(CameraCharacteristics.SENSOR_ORIENTATION); + if (mModule.getMainCameraId() == CaptureModule.FRONT_ID) { + degree = Math.abs(degree - 90); + } } mRsRotator.set_degree(degree); mRsYuvToRGB.set_gIn(mProcessAllocation); diff --git a/src/com/android/camera/ui/OneUICameraControls.java b/src/com/android/camera/ui/OneUICameraControls.java index 0388b5761..3dce60d22 100755 --- a/src/com/android/camera/ui/OneUICameraControls.java +++ b/src/com/android/camera/ui/OneUICameraControls.java @@ -532,6 +532,7 @@ public class OneUICameraControls extends RotatableLayout { mProModeOn = promode; initializeProMode(mProModeOn); resetProModeIcons(); + mProMode.reinit(); } private void resetProModeIcons() { diff --git a/src/com/android/camera/ui/PanoCaptureProcessView.java b/src/com/android/camera/ui/PanoCaptureProcessView.java index 2b37fd61e..95e9a095f 100644 --- a/src/com/android/camera/ui/PanoCaptureProcessView.java +++ b/src/com/android/camera/ui/PanoCaptureProcessView.java @@ -120,6 +120,7 @@ public class PanoCaptureProcessView extends View implements SensorEventListener private static final boolean DEBUG = false; //TODO: This has to be false before release private BitmapArrayOutputStream mBitmapStream; private static boolean mIsSupported = false; + private Object mBitmapStreamLock = new Object(); private boolean mIsFrameProcessing = false; enum PANO_STATUS { @@ -337,13 +338,15 @@ public class PanoCaptureProcessView extends View implements SensorEventListener public void onPause() { mSensorManager.unregisterListener(this, mRotationSensor); - if(mBitmapStream != null) { - try { - mBitmapStream.close(); - } catch (IOException e) { - //Ignore + synchronized (mBitmapStreamLock) { + if(mBitmapStream != null) { + try { + mBitmapStream.close(); + } catch (IOException e) { + //Ignore + } + mBitmapStream = null; } - mBitmapStream = null; } } @@ -510,13 +513,16 @@ public class PanoCaptureProcessView extends View implements SensorEventListener } private void doTask(BitmapTask bitmapTask) { - if(mBitmapStream == null) { - mBitmapStream = new BitmapArrayOutputStream(1024*1204); + int rtv = -1; + synchronized (mBitmapStreamLock) { + if(mBitmapStream == null) { + mBitmapStream = new BitmapArrayOutputStream(1024*1204); + } + mBitmapStream.reset(); + bitmapTask.bitmap.compress(Bitmap.CompressFormat.JPEG, 100, mBitmapStream); + rtv = callNativeProcessKeyFrame(mBitmapStream.toByteArray(), mBitmapStream.size(), + bitmapTask.x, bitmapTask.y, 0, bitmapTask.dir); } - mBitmapStream.reset(); - bitmapTask.bitmap.compress(Bitmap.CompressFormat.JPEG, 100, mBitmapStream); - int rtv = callNativeProcessKeyFrame(mBitmapStream.toByteArray(), mBitmapStream.size(), - bitmapTask.x, bitmapTask.y, 0, bitmapTask.dir); if(rtv < 0) { mShouldFinish = true; stopPano(false, mActivity.getResources().getString(R.string.panocapture_direction_is_changed)); diff --git a/src/com/android/camera/ui/ProMode.java b/src/com/android/camera/ui/ProMode.java index dbd89ec58..b55d0c425 100644 --- a/src/com/android/camera/ui/ProMode.java +++ b/src/com/android/camera/ui/ProMode.java @@ -169,6 +169,10 @@ public class ProMode extends View { mCurveMeasure = new PathMeasure(mCurvePath, false); } + public void reinit() { + init(); + } + public void setOrientation(int orientation) { mOrientation = orientation; if (mAddedViews != null) { @@ -199,7 +203,7 @@ public class ProMode extends View { if (mMode == MANUAL_MODE) { minFocus = mSettingsManager .getMinimumFocusDistance(mSettingsManager.getCurrentCameraId()); - float value = 0.5f; + float value = mSettingsManager.getFocusValue(SettingsManager.KEY_FOCUS_DISTANCE); setSlider(value); int stride = mCurveRight - mCurveLeft; for (int i = 0; i < 2; i++) { @@ -288,7 +292,7 @@ public class ProMode extends View { public void setSlider(float slider) { mSlider = slider; - mSettingsManager.setFocusDistance(mSlider * minFocus); + mSettingsManager.setFocusDistance(SettingsManager.KEY_FOCUS_DISTANCE, mSlider, minFocus); mUI.updateProModeText(mMode, "Manual"); invalidate(); } diff --git a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java index bd54dc76a..944bf0800 100755 --- a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java +++ b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java @@ -912,6 +912,12 @@ public class ClearSightImageProcessor { mImageEncodeHandler.obtainMessage(MSG_START_CAPTURE).sendToTarget(); short encodeRequest = 0; + /* In same case, timeout will reset ClearSightNativeEngine object, so fields + in the object is not initial, need to return and skip process. + */ + if (ClearSightNativeEngine.getInstance().getReferenceImage(true) == null) { + return; + } long csTs = ClearSightNativeEngine.getInstance().getReferenceImage(true).getTimestamp(); CaptureRequest.Builder csRequest = createEncodeReprocRequest( ClearSightNativeEngine.getInstance().getReferenceResult(true), CAM_TYPE_BAYER); |