summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/VideoModule.java
diff options
context:
space:
mode:
authorPraveen Chavan <pchavan@codeaurora.org>2016-01-07 22:36:51 +0100
committerDaniel Hillenbrand <codeworkx@cyanogenmod.org>2016-01-07 13:45:38 -0800
commit3626f48bf1293ba1e8b15309df9a698a77fe786e (patch)
tree061c8b27a80c527db34272f79f7c42d7903f0a60 /src/com/android/camera/VideoModule.java
parent06ac71fabf96e0a6d6ef5b0a96f729b4a1c0e412 (diff)
downloadandroid_packages_apps_Snap-3626f48bf1293ba1e8b15309df9a698a77fe786e.tar.gz
android_packages_apps_Snap-3626f48bf1293ba1e8b15309df9a698a77fe786e.tar.bz2
android_packages_apps_Snap-3626f48bf1293ba1e8b15309df9a698a77fe786e.zip
SnapdragonCamera: Add support for high-speed video recording
[1] Use combination of MediaRecorder.setCaptureRate and setVideoFrameRate API to achieve HFR/HSR ------------------------------------------------------------ CaptureRate videoFrameRate Recorded-video ------------------------------------------------------------ 120 30 slow-mo @30fps 120 120 high-speed-video @120fps ------------------------------------------------------------ Deprecate usage of custom fields added to media-profiles for checking max-capabilities. Instead, introduce high-speed profiles and advertize correct values (resolution, fps) to indicate target capabilities. Add conversion routines in CameraSettings to convert from normal quality level to time-lapse/high-speed quality. Also, add back 4KDCI and VGA support TODO: Implement bitrate scaling if AOSP does not implement in native. Change-Id: Ic1d5ed8ef52348cab2383abe304056e0401f7069
Diffstat (limited to 'src/com/android/camera/VideoModule.java')
-rw-r--r--src/com/android/camera/VideoModule.java180
1 files changed, 119 insertions, 61 deletions
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 70cfba011..b9bf36d35 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -892,8 +892,35 @@ public class VideoModule implements CameraModule,
mActivity.getString(R.string.pref_video_time_lapse_frame_interval_default));
mTimeBetweenTimeLapseFrameCaptureMs = Integer.parseInt(frameIntervalStr);
mCaptureTimeLapse = (mTimeBetweenTimeLapseFrameCaptureMs != 0);
- // TODO: This should be checked instead directly +1000.
- if (mCaptureTimeLapse) quality += 1000;
+
+ int hfrRate = 0;
+ String highFrameRate = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE,
+ mActivity. getString(R.string.pref_camera_hfr_default));
+ if (("hfr".equals(highFrameRate.substring(0,3))) ||
+ ("hsr".equals(highFrameRate.substring(0,3)))) {
+ String rate = highFrameRate.substring(3);
+ Log.i(TAG,"HFR :" + highFrameRate + " : rate = " + rate);
+ try {
+ hfrRate = Integer.parseInt(rate);
+ } catch (NumberFormatException nfe) {
+ Log.e(TAG, "Invalid hfr rate " + rate);
+ }
+ }
+
+ int mappedQuality = quality;
+ if (mCaptureTimeLapse) {
+ mappedQuality = CameraSettings.getTimeLapseQualityFor(quality);
+ } else if (hfrRate > 0) {
+ mappedQuality = CameraSettings.getHighSpeedQualityFor(quality);
+ Log.i(TAG,"NOTE: HighSpeed quality (" + mappedQuality + ") for (" + quality + ")");
+ }
+
+ if (CamcorderProfile.hasProfile(mCameraId, mappedQuality)) {
+ quality = mappedQuality;
+ } else {
+ Log.e(TAG,"NOTE: Quality " + mappedQuality + " is not supported ! Will use " + quality);
+ }
mProfile = CamcorderProfile.get(mCameraId, quality);
getDesiredPreviewSize();
qcomReadVideoPreferences();
@@ -909,8 +936,8 @@ public class VideoModule implements CameraModule,
}
private boolean is4KEnabled() {
- if (mProfile.quality == CamcorderProfile.QUALITY_2160P /*||
- mProfile.quality == CamcorderProfile.QUALITY_4kDCI*/) {
+ if (mProfile.quality == CamcorderProfile.QUALITY_2160P ||
+ mProfile.quality == CamcorderProfile.QUALITY_4KDCI) {
return true;
} else {
return false;
@@ -933,6 +960,32 @@ public class VideoModule implements CameraModule,
}
}
+ private boolean isSessionSupportedByEncoder(int w, int h, int fps) {
+ int expectedMBsPerSec = w * h * fps;
+
+ List<VideoEncoderCap> videoEncoders = EncoderCapabilities.getVideoEncoders();
+ for (VideoEncoderCap videoEncoder: videoEncoders) {
+ if (videoEncoder.mCodec == mVideoEncoder) {
+ int maxMBsPerSec = (videoEncoder.mMaxFrameWidth * videoEncoder.mMaxFrameHeight
+ * videoEncoder.mMaxFrameRate);
+ if (expectedMBsPerSec > maxMBsPerSec) {
+ Log.e(TAG,"Selected codec " + mVideoEncoder
+ + " does not support width(" + w
+ + ") X height ("+ h
+ + "@ " + fps +" fps");
+ Log.e(TAG, "Max capabilities: " +
+ "MaxFrameWidth = " + videoEncoder.mMaxFrameWidth + " , " +
+ "MaxFrameHeight = " + videoEncoder.mMaxFrameHeight + " , " +
+ "MaxFrameRate = " + videoEncoder.mMaxFrameRate);
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
boolean isHFREnabled(int videoWidth, int videoHeight) {
if ((null == mPreferences) || (null == mParameters)) {
return false;
@@ -942,7 +995,7 @@ public class VideoModule implements CameraModule,
CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE,
mActivity. getString(R.string.pref_camera_hfr_default));
- if(!("off".equals(HighFrameRate))) {
+ if (!("off".equals(HighFrameRate))) {
Size size = null;
try {
if (isSupported(HighFrameRate.substring(3), mParameters.getSupportedVideoHighFrameRateModes())) {
@@ -967,25 +1020,8 @@ public class VideoModule implements CameraModule,
}
int hfrFps = Integer.parseInt(HighFrameRate.substring(3));
- int inputBitrate = videoWidth * videoHeight * hfrFps;
-
- boolean supported = false;
- List<VideoEncoderCap> videoEncoders = EncoderCapabilities.getVideoEncoders();
- for (VideoEncoderCap videoEncoder: videoEncoders) {
-//TODO: How to handle HFRFrameWidth and HFRFrameHeight
-/* if (videoEncoder.mCodec == mVideoEncoder) {
- int maxBitrate = (videoEncoder.mMaxHFRFrameWidth *
- videoEncoder.mMaxHFRFrameHeight *
- videoEncoder.mMaxHFRMode);
- if (inputBitrate > 0 && inputBitrate <= maxBitrate ) {
- supported = true;
- }
- break;
- }
-*/
- }
- return supported;
+ return isSessionSupportedByEncoder(videoWidth, videoHeight, hfrFps);
}
return false;
@@ -1518,25 +1554,61 @@ public class VideoModule implements CameraModule,
// Unlock the camera object before passing it to media recorder.
mCameraDevice.unlock();
mMediaRecorder.setCamera(mCameraDevice.getCamera());
+
String hfr = mParameters.getVideoHighFrameRate();
- if (!mCaptureTimeLapse && ((hfr == null) || ("off".equals(hfr)))) {
- mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
- mProfile.audioCodec = mAudioEncoder;
- } else {
- mProfile.audioCodec = -1; //not set
+ String hsr = mParameters.get(CameraSettings.KEY_VIDEO_HSR);
+ Log.i(TAG,"NOTE: hfr = " + hfr + " : hsr = " + hsr);
+
+ int captureRate = 0;
+ boolean isHFR = (hfr != null && !hfr.equals("off"));
+ boolean isHSR = (hsr != null && !hsr.equals("off"));
+
+ try {
+ captureRate = isHFR ? Integer.parseInt(hfr) :
+ isHSR ? Integer.parseInt(hsr) : 0;
+ } catch (NumberFormatException nfe) {
+ Log.e(TAG, "Invalid hfr(" + hfr + ") or hsr(" + hsr + ")");
}
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mProfile.videoCodec = mVideoEncoder;
+ mProfile.audioCodec = mAudioEncoder;
mProfile.duration = mMaxVideoDurationInMs;
- mMediaRecorder.setProfile(mProfile);
+ // Set params individually for HFR case, as we do not want to encode audio
+ if ((isHFR || isHSR) && captureRate > 0) {
+ mMediaRecorder.setOutputFormat(mProfile.fileFormat);
+ mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);
+ mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate);
+ mMediaRecorder.setVideoEncoder(mProfile.videoCodec);
+ } else {
+ if (!mCaptureTimeLapse) {
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+ }
+
+ mMediaRecorder.setProfile(mProfile);
+ }
+
mMediaRecorder.setVideoSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs);
if (mCaptureTimeLapse) {
double fps = 1000 / (double) mTimeBetweenTimeLapseFrameCaptureMs;
setCaptureRate(mMediaRecorder, fps);
+ } else if (captureRate > 0) {
+ Log.i(TAG, "Setting capture-rate = " + captureRate);
+ mMediaRecorder.setCaptureRate(captureRate);
+ // for HFR, encoder's target-framerate = capture-rate
+ if (isHSR) {
+ Log.i(TAG, "Setting fps = " + captureRate + " for HSR");
+ mMediaRecorder.setVideoFrameRate(captureRate);
+ }
+ // for HFR, encoder's taget-framerate = 30fps (from profile)
+ if (isHFR) {
+ Log.i(TAG, "Setting fps = 30 for HFR");
+ mMediaRecorder.setVideoFrameRate(30);
+ }
+ // TODO : bitrate correction..check with google
}
setRecordLocation();
@@ -2181,6 +2253,7 @@ public class VideoModule implements CameraModule,
private void qcomSetCameraParameters(){
// add QCOM Parameters here
// Set color effect parameter.
+ Log.i(TAG,"NOTE: qcomSetCameraParameters " + videoWidth + " x " + videoHeight);
String colorEffect = mPreferences.getString(
CameraSettings.KEY_VIDEOCAMERA_COLOR_EFFECT,
mActivity.getString(R.string.pref_camera_coloreffect_default));
@@ -2286,18 +2359,21 @@ public class VideoModule implements CameraModule,
String HighFrameRate = mPreferences.getString(
CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE,
mActivity. getString(R.string.pref_camera_hfr_default));
- if (("hfr".equals(HighFrameRate.substring(0,3))) ||
- ("hsr".equals(HighFrameRate.substring(0,3)))) {
+ boolean isHFR = "hfr".equals(HighFrameRate.substring(0,3));
+ boolean isHSR = "hsr".equals(HighFrameRate.substring(0,3));
+
+ if (isHFR || isHSR) {
String hfrRate = HighFrameRate.substring(3);
- if ("hfr".equals(HighFrameRate.substring(0,3))) {
+ if (isHFR) {
mUnsupportedHFRVideoSize = true;
} else {
mUnsupportedHSRVideoSize = true;
}
String hfrsize = videoWidth+"x"+videoHeight;
- Log.v(TAG, "current set resolution is : "+hfrsize);
+ Log.v(TAG, "current set resolution is : "+hfrsize+ " : Rate is : " + hfrRate );
try {
Size size = null;
+ Log.i(TAG,"supported rate = " + mParameters.getSupportedVideoHighFrameRateModes());
if (isSupported(hfrRate, mParameters.getSupportedVideoHighFrameRateModes())) {
int index = mParameters.getSupportedVideoHighFrameRateModes().indexOf(
hfrRate);
@@ -2305,7 +2381,7 @@ public class VideoModule implements CameraModule,
}
if (size != null) {
if (videoWidth <= size.width && videoHeight <= size.height) {
- if ("hfr".equals(HighFrameRate.substring(0,3))) {
+ if (isHFR) {
mUnsupportedHFRVideoSize = false;
} else {
mUnsupportedHSRVideoSize = false;
@@ -2318,35 +2394,16 @@ public class VideoModule implements CameraModule,
}
int hfrFps = Integer.parseInt(hfrRate);
- int inputBitrate = videoWidth*videoHeight*hfrFps;
-
- //check if codec supports the resolution, otherwise throw toast
- List<VideoEncoderCap> videoEncoders = EncoderCapabilities.getVideoEncoders();
- for (VideoEncoderCap videoEncoder: videoEncoders) {
- if (videoEncoder.mCodec == mVideoEncoder){
-/* TODO:
- int maxBitrate = (videoEncoder.mMaxHFRFrameWidth *
- videoEncoder.mMaxHFRFrameHeight *
- videoEncoder.mMaxHFRMode);
- if (inputBitrate > maxBitrate ) {
- Log.e(TAG,"Selected codec "+mVideoEncoder+
- " does not support HFR " + HighFrameRate + " with "+ videoWidth
- + "x" + videoHeight +" resolution");
- Log.e(TAG, "Codec capabilities: " +
- "mMaxHFRFrameWidth = " + videoEncoder.mMaxHFRFrameWidth + " , " +
- "mMaxHFRFrameHeight = " + videoEncoder.mMaxHFRFrameHeight + " , " +
- "mMaxHFRMode = " + videoEncoder.mMaxHFRMode);
- if ("hfr".equals(HighFrameRate.substring(0,3))) {
- mUnsupportedHFRVideoSize = true;
- } else {
- mUnsupportedHSRVideoSize = true;
- }
- }
- break;
-*/
+
+ if (!isSessionSupportedByEncoder(videoWidth, videoHeight, hfrFps)) {
+ if (isHFR) {
+ mUnsupportedHFRVideoSize = true;
+ } else {
+ mUnsupportedHSRVideoSize = true;
}
}
- if ("hfr".equals(HighFrameRate.substring(0,3))) {
+
+ if (isHFR) {
mParameters.set(CameraSettings.KEY_VIDEO_HSR, "off");
if (mUnsupportedHFRVideoSize) {
mParameters.setVideoHighFrameRate("off");
@@ -2496,6 +2553,7 @@ public class VideoModule implements CameraModule,
forceFlashOffIfSupported(!mPreviewFocused);
videoWidth = mProfile.videoFrameWidth;
videoHeight = mProfile.videoFrameHeight;
+
String recordSize = videoWidth + "x" + videoHeight;
Log.e(TAG,"Video dimension in App->"+recordSize);
if (CameraUtil.isSupported(mParameters, "video-size")) {