diff options
author | Alok Kediya <kediya@codeaurora.org> | 2013-09-23 14:31:42 +0530 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2013-10-31 19:38:25 -0600 |
commit | aed65253fb207b952a29e416a02d5b9a0c492416 (patch) | |
tree | 541d555d05d0a4da1ab25cb7720084ff23cc599e /src/com/android/camera | |
parent | e04982ad43fa3672cadf821a1bbc9c6454ce20f3 (diff) | |
download | android_packages_apps_Snap-aed65253fb207b952a29e416a02d5b9a0c492416.tar.gz android_packages_apps_Snap-aed65253fb207b952a29e416a02d5b9a0c492416.tar.bz2 android_packages_apps_Snap-aed65253fb207b952a29e416a02d5b9a0c492416.zip |
Camera: Add initial QCom value add features.
- Enhance the camera picture size table by adding more number of
supported resolutions.
- Enhance the camcorder menu by adding support for additional video
and audio codecs.
- Also provide option to select the duration of the recording clip.
(cherry picked from commit 7a5402332f3b527767b85c1fc112880d02a47c0e)
Change-Id: I553d4eb74337701bc57d069c8374646a7e15c2d5
(cherry picked from commit cdffd7510e1f9a236e43438f035bc5be9e3c0c17)
(cherry picked from commit 93c32e9e069d7c48b71fbbe45cae59a54df443ec)
(cherry picked from commit f6b24346ab9d28953a5697924d6815ed2c006cf3)
Diffstat (limited to 'src/com/android/camera')
-rw-r--r-- | src/com/android/camera/CameraSettings.java | 100 | ||||
-rw-r--r-- | src/com/android/camera/VideoMenu.java | 3 | ||||
-rw-r--r-- | src/com/android/camera/VideoModule.java | 136 | ||||
-rw-r--r-- | src/com/android/camera/util/ApiHelper.java | 3 |
4 files changed, 231 insertions, 11 deletions
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index 55867a1e8..38dcc6965 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -16,12 +16,14 @@ package com.android.camera; +import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.res.Resources; import android.content.res.TypedArray; +import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.Size; @@ -36,6 +38,7 @@ import com.android.camera2.R; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import android.os.Build; /** * Provides utilities and keys for Camera settings. @@ -67,6 +70,9 @@ public class CameraSettings { public static final String KEY_PHOTOSPHERE_PICTURESIZE = "pref_photosphere_picturesize_key"; public static final String KEY_STARTUP_MODULE_INDEX = "camera.startup_module"; + public static final String KEY_VIDEO_ENCODER = "pref_camera_videoencoder_key"; + public static final String KEY_AUDIO_ENCODER = "pref_camera_audioencoder_key"; + public static final String KEY_VIDEO_DURATION = "pref_camera_video_duration_key"; public static final String EXPOSURE_DEFAULT_VALUE = "0"; public static final int CURRENT_VERSION = 5; @@ -96,10 +102,10 @@ public class CameraSettings { } public static String getSupportedHighestVideoQuality(int cameraId, - String defaultQuality) { + String defaultQuality,Parameters parameters) { // When launching the camera app first time, we will set the video quality // to the first one (i.e. highest quality) in the supported list - List<String> supported = getSupportedVideoQuality(cameraId); + List<String> supported = getSupportedVideoQuality(cameraId,parameters); if (supported == null) { Log.e(TAG, "No supported video quality is found"); return defaultQuality; @@ -177,7 +183,8 @@ public class CameraSettings { // Since the screen could be loaded from different resources, we need // to check if the preference is available here if (videoQuality != null) { - filterUnsupportedOptions(group, videoQuality, getSupportedVideoQuality(mCameraId)); + filterUnsupportedOptions(group, videoQuality, getSupportedVideoQuality( + mCameraId,mParameters)); } if (pictureSize != null) { @@ -484,19 +491,96 @@ public class CameraSettings { initialCameraPictureSize(context, parameters); writePreferredCameraId(preferences, currentCameraId); } + private static boolean checkSupportedVideoQuality(Parameters parameters,int width, int height){ + List <Size> supported = parameters.getSupportedVideoSizes(); + int flag = 0; + for (Size size : supported){ + //since we are having two profiles with same height, we are checking with height + if (size.height == 480) { + if (size.height == height && size.width == width) { + flag = 1; + break; + } + } else { + if (size.width == width) { + flag = 1; + break; + } + } + } + if (flag == 1) + return true; - private static ArrayList<String> getSupportedVideoQuality(int cameraId) { + return false; + } + private static ArrayList<String> getSupportedVideoQuality(int cameraId,Parameters parameters) { ArrayList<String> supported = new ArrayList<String>(); // Check for supported quality + if (ApiHelper.HAS_FINE_RESOLUTION_QUALITY_LEVELS) { + getFineResolutionQuality(supported,cameraId,parameters); + } else { + supported.add(Integer.toString(CamcorderProfile.QUALITY_HIGH)); + CamcorderProfile high = CamcorderProfile.get( + cameraId, CamcorderProfile.QUALITY_HIGH); + CamcorderProfile low = CamcorderProfile.get( + cameraId, CamcorderProfile.QUALITY_LOW); + if (high.videoFrameHeight * high.videoFrameWidth > + low.videoFrameHeight * low.videoFrameWidth) { + supported.add(Integer.toString(CamcorderProfile.QUALITY_LOW)); + } + } + + return supported; + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) + private static void getFineResolutionQuality(ArrayList<String> supported, + int cameraId,Parameters parameters) { if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_1080P)) { - supported.add(Integer.toString(CamcorderProfile.QUALITY_1080P)); + if (checkSupportedVideoQuality(parameters,1920,1080)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_1080P)); + } } if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_720P)) { - supported.add(Integer.toString(CamcorderProfile.QUALITY_720P)); + if (checkSupportedVideoQuality(parameters,1280,720)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_720P)); + } } if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_480P)) { - supported.add(Integer.toString(CamcorderProfile.QUALITY_480P)); + if (checkSupportedVideoQuality(parameters,720,480)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_480P)); + } } - return supported; + if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_FWVGA)) { + if (checkSupportedVideoQuality(parameters,864,480)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_FWVGA)); + } + } + if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_WVGA)) { + if (checkSupportedVideoQuality(parameters,800,480)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_WVGA)); + } + } + if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_VGA)) { + if (checkSupportedVideoQuality(parameters,640,480)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_VGA)); + } + } + if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_CIF)) { + if (checkSupportedVideoQuality(parameters,352,288)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_CIF)); + } + } + if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_QVGA)) { + if (checkSupportedVideoQuality(parameters,320,240)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_QVGA)); + } + } + if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_QCIF)) { + if (checkSupportedVideoQuality(parameters,176,144)){ + supported.add(Integer.toString(CamcorderProfile.QUALITY_QCIF)); + } + } + } } diff --git a/src/com/android/camera/VideoMenu.java b/src/com/android/camera/VideoMenu.java index f0c7db272..8db219924 100644 --- a/src/com/android/camera/VideoMenu.java +++ b/src/com/android/camera/VideoMenu.java @@ -67,6 +67,9 @@ public class VideoMenu extends PieController CameraSettings.KEY_VIDEO_EFFECT, CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, CameraSettings.KEY_VIDEO_QUALITY, + CameraSettings.KEY_VIDEO_ENCODER, + CameraSettings.KEY_AUDIO_ENCODER, + CameraSettings.KEY_VIDEO_DURATION, CameraSettings.KEY_RECORD_LOCATION }; item = makeItem(R.drawable.ic_settings_holo_light); diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index fdd48e264..74fd4aff9 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -70,6 +70,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.HashMap; public class VideoModule implements CameraModule, VideoController, @@ -216,6 +217,72 @@ public class VideoModule implements CameraModule, mParameters = mCameraDevice.getParameters(); } + //QCOM data Members Starts here + static class DefaultHashMap<K, V> extends HashMap<K, V> { + private V mDefaultValue; + + public void putDefault(V defaultValue) { + mDefaultValue = defaultValue; + } + + @Override + public V get(Object key) { + V value = super.get(key); + return (value == null) ? mDefaultValue : value; + } + public K getKey(V toCheck) { + Iterator<K> it = this.keySet().iterator(); + V val; + K key; + while(it.hasNext()) { + key = it.next(); + val = this.get(key); + if (val.equals(toCheck)) { + return key; + } + } + return null; + } + } + + + private static final DefaultHashMap<String, Integer> + OUTPUT_FORMAT_TABLE = new DefaultHashMap<String, Integer>(); + private static final DefaultHashMap<String, Integer> + VIDEO_ENCODER_TABLE = new DefaultHashMap<String, Integer>(); + private static final DefaultHashMap<String, Integer> + AUDIO_ENCODER_TABLE = new DefaultHashMap<String, Integer>(); + private static final DefaultHashMap<String, Integer> + VIDEOQUALITY_BITRATE_TABLE = new DefaultHashMap<String, Integer>(); + + static { + OUTPUT_FORMAT_TABLE.put("3gp", MediaRecorder.OutputFormat.THREE_GPP); + OUTPUT_FORMAT_TABLE.put("mp4", MediaRecorder.OutputFormat.MPEG_4); + OUTPUT_FORMAT_TABLE.putDefault(MediaRecorder.OutputFormat.DEFAULT); + + VIDEO_ENCODER_TABLE.put("h263", MediaRecorder.VideoEncoder.H263); + VIDEO_ENCODER_TABLE.put("h264", MediaRecorder.VideoEncoder.H264); + VIDEO_ENCODER_TABLE.put("m4v", MediaRecorder.VideoEncoder.MPEG_4_SP); + VIDEO_ENCODER_TABLE.putDefault(MediaRecorder.VideoEncoder.DEFAULT); + + AUDIO_ENCODER_TABLE.put("amrnb", MediaRecorder.AudioEncoder.AMR_NB); + // Enabled once support is added in MediaRecorder. + // AUDIO_ENCODER_TABLE.put("qcelp", MediaRecorder.AudioEncoder.QCELP); + // AUDIO_ENCODER_TABLE.put("evrc", MediaRecorder.AudioEncoder.EVRC); + AUDIO_ENCODER_TABLE.put("amrwb", MediaRecorder.AudioEncoder.AMR_WB); + AUDIO_ENCODER_TABLE.put("aac", MediaRecorder.AudioEncoder.AAC); + AUDIO_ENCODER_TABLE.putDefault(MediaRecorder.AudioEncoder.DEFAULT); + + } + + private int mVideoEncoder; + private int mAudioEncoder; + private boolean mRestartPreview = false; + private int videoWidth; + private int videoHeight; + boolean mUnsupportedResolution = false; + + // This Handler is used to post message back onto the main thread of the // application private class MainHandler extends Handler { @@ -547,15 +614,53 @@ public class VideoModule implements CameraModule, mUI.setShutterPressed(pressed); } + private void qcomReadVideoPreferences() { + String videoEncoder = mPreferences.getString( + CameraSettings.KEY_VIDEO_ENCODER, + mActivity.getString(R.string.pref_camera_videoencoder_default)); + mVideoEncoder = VIDEO_ENCODER_TABLE.get(videoEncoder); + + Log.v(TAG, "Video Encoder selected = " +mVideoEncoder); + + String audioEncoder = mPreferences.getString( + CameraSettings.KEY_AUDIO_ENCODER, + mActivity.getString(R.string.pref_camera_audioencoder_default)); + mAudioEncoder = AUDIO_ENCODER_TABLE.get(audioEncoder); + + Log.v(TAG, "Audio Encoder selected = " +mAudioEncoder); + + String minutesStr = mPreferences.getString( + CameraSettings.KEY_VIDEO_DURATION, + mActivity.getString(R.string.pref_camera_video_duration_default)); + int minutes = -1; + try { + minutes = Integer.parseInt(minutesStr); + } catch(NumberFormatException npe) { + // use default value continue + minutes = Integer.parseInt(mActivity.getString( + R.string.pref_camera_video_duration_default)); + } + if (minutes == -1) { + // User wants lowest, set 30s */ + mMaxVideoDurationInMs = 30000; + } else { + // 1 minute = 60000ms + mMaxVideoDurationInMs = 60000 * minutes; + } + + } + private void readVideoPreferences() { // The preference stores values from ListPreference and is thus string type for all values. // We need to convert it to int manually. String videoQuality = mPreferences.getString(CameraSettings.KEY_VIDEO_QUALITY, null); if (videoQuality == null) { + mParameters = mCameraDevice.getParameters(); // check for highest quality before setting default value videoQuality = CameraSettings.getSupportedHighestVideoQuality(mCameraId, - mActivity.getResources().getString(R.string.pref_video_quality_default)); + mActivity.getResources().getString(R.string.pref_video_quality_default), + mParameters); mPreferences.edit().putString(CameraSettings.KEY_VIDEO_QUALITY, videoQuality); } int quality = Integer.valueOf(videoQuality); @@ -592,6 +697,7 @@ public class VideoModule implements CameraModule, if (mCaptureTimeLapse) quality += 1000; mProfile = CamcorderProfile.get(mCameraId, quality); getDesiredPreviewSize(); + qcomReadVideoPreferences(); mPreferenceRead = true; } @@ -945,6 +1051,19 @@ public class VideoModule implements CameraModule, Intent intent = mActivity.getIntent(); Bundle myExtras = intent.getExtras(); + videoWidth = mProfile.videoFrameWidth; + videoHeight = mProfile.videoFrameHeight; + mUnsupportedResolution = false; + + if (mVideoEncoder == MediaRecorder.VideoEncoder.H263) { + if (videoWidth >= 1280 && videoHeight >= 720) { + mUnsupportedResolution = true; + Toast.makeText(mActivity, R.string.error_app_unsupported, + Toast.LENGTH_LONG).show(); + return; + } + } + long requestedSizeLimit = 0; closeVideoFileDescriptor(); mCurrentVideoUriFromMediaSaved = false; @@ -970,8 +1089,13 @@ public class VideoModule implements CameraModule, mMediaRecorder.setCamera(mCameraDevice.getCamera()); if (!mCaptureTimeLapse) { mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); + mProfile.audioCodec = mAudioEncoder; } mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + + mProfile.videoCodec = mVideoEncoder; + mProfile.duration = mMaxVideoDurationInMs; + mMediaRecorder.setProfile(mProfile); mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs); if (mCaptureTimeLapse) { @@ -1183,6 +1307,10 @@ public class VideoModule implements CameraModule, mCurrentVideoUri = null; initializeRecorder(); + if (mUnsupportedResolution == true) { + Log.v(TAG, "Unsupported Resolution according to target"); + return; + } if (mMediaRecorder == null) { Log.e(TAG, "Fail to initialize media recorder"); return; @@ -1472,7 +1600,11 @@ public class VideoModule implements CameraModule, } forceFlashOffIfSupported(!mUI.isVisible()); - + videoWidth = mProfile.videoFrameWidth; + videoHeight = mProfile.videoFrameHeight; + String recordSize = videoWidth + "x" + videoHeight; + Log.e(TAG,"Video dimension in App->"+recordSize); + mParameters.set("video-size", recordSize); // Set white balance parameter. String whiteBalance = mPreferences.getString( CameraSettings.KEY_WHITE_BALANCE, diff --git a/src/com/android/camera/util/ApiHelper.java b/src/com/android/camera/util/ApiHelper.java index dd5208cc8..4a917799e 100644 --- a/src/com/android/camera/util/ApiHelper.java +++ b/src/com/android/camera/util/ApiHelper.java @@ -49,7 +49,8 @@ public class ApiHelper { Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; public static final boolean HAS_ROTATION_ANIMATION = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; - + public static final boolean HAS_FINE_RESOLUTION_QUALITY_LEVELS = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; public static final boolean HAS_HIDEYBARS = isKitKatOrHigher(); public static int getIntFieldIfExists(Class<?> klass, String fieldName, |