From fef825d2a82687a400c089e9f63f98329b437027 Mon Sep 17 00:00:00 2001 From: codeworkx Date: Sun, 3 Sep 2017 12:41:13 +0200 Subject: Snap: fix highspeed and high-framerate video recording This commit adds parts of the following commits: From: Jay Wang Date: Fri, 28 Oct 2016 14:42:04 -0700 Subject: [PATCH] SnapdragonCamera: Adjust video encoder bit rate and add 60fps support - Configure the video encoder bit rate to the recommended value - Add 60fps video frame rate support Change-Id: I477487c4c4fab5479534896d90e08c3eadddc54f CRs-Fixed: 1074187 From: Sai Kumar Sanagavarapu Date: Tue, 11 Aug 2015 15:23:15 +0530 Subject: [PATCH] SnapdragonCamera: Query encoder capabilities for unsupported profiles. Query encoder capabilities like max fps, width, height ,etc and based on this result enable/disable certain profiles/hfr modes. Change-Id: Ib5adf74eaa8d50f9ed8337a88932527624727cd4 --- src/com/android/camera/CameraSettings.java | 10 ++++++++++ src/com/android/camera/CaptureModule.java | 31 ++++++++++++++++------------- src/com/android/camera/SettingsManager.java | 13 ++++++++++++ src/com/android/camera/VideoModule.java | 16 ++++++++++++--- 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index 15480ed18..aa0fee8f4 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -293,6 +293,8 @@ public class CameraSettings { VIDEO_ENCODER_TABLE = new HashMap(); public static final HashMap VIDEO_QUALITY_TABLE = new HashMap(); + public static final HashMap + VIDEO_ENCODER_BITRATE = new HashMap(); static { //video encoders @@ -319,6 +321,14 @@ public class CameraSettings { VIDEO_QUALITY_TABLE.put("352x288", CamcorderProfile.QUALITY_CIF); VIDEO_QUALITY_TABLE.put("320x240", CamcorderProfile.QUALITY_QVGA); VIDEO_QUALITY_TABLE.put("176x144", CamcorderProfile.QUALITY_QCIF); + + //video encoder bitrate + VIDEO_ENCODER_BITRATE.put("1920x1080:60", 32000000); + VIDEO_ENCODER_BITRATE.put("1920x1080:120", 50000000); + VIDEO_ENCODER_BITRATE.put("1280x720:120", 35000000); + VIDEO_ENCODER_BITRATE.put("1280x720:240", 72000000); + VIDEO_ENCODER_BITRATE.put("720:480:120", 5200000); + } // Following maps help find a corresponding time-lapse or high-speed quality diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 0ad6212df..46f12948d 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -276,7 +276,7 @@ public class CaptureModule extends BaseModule implements PhotoControl private ImageReader mVideoSnapshotImageReader; private Range mHighSpeedFPSRange; private boolean mHighSpeedCapture = false; - private boolean mHighSpeedCaptureSlowMode = false; //HFR + private boolean mHighSpeedRecordingMode = false; //HFR private int mHighSpeedCaptureRate; private static final int SELFIE_FLASH_DURATION = 680; @@ -2497,7 +2497,7 @@ public class CaptureModule extends BaseModule implements PhotoControl } else { mHighSpeedCapture = true; String mode = value.substring(0, 3); - mHighSpeedCaptureSlowMode = mode.equals("hsr"); + mHighSpeedRecordingMode = mode.equals("hsr"); mHighSpeedCaptureRate = Integer.parseInt(value.substring(3)); } } @@ -2661,7 +2661,7 @@ public class CaptureModule extends BaseModule implements PhotoControl size = CameraSettings.getTimeLapseQualityFor(size); } updateHFRSetting(); - boolean hfr = mHighSpeedCapture && !mHighSpeedCaptureSlowMode; + boolean hfr = mHighSpeedCapture && !mHighSpeedRecordingMode; mProfile = CamcorderProfile.get(cameraId, size); int videoEncoder = SettingTranslation @@ -2669,15 +2669,18 @@ public class CaptureModule extends BaseModule implements PhotoControl int audioEncoder = SettingTranslation .getAudioEncoder(mSettingsManager.getValue(SettingsManager.KEY_AUDIO_ENCODER)); - int outputFormat = MediaRecorder.OutputFormat.MPEG_4; - + mProfile.videoCodec = videoEncoder; if (!mCaptureTimeLapse && !hfr) { mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + mProfile.audioCodec = audioEncoder; + if (mProfile.audioCodec == MediaRecorder.AudioEncoder.AMR_NB) { + mProfile.fileFormat = MediaRecorder.OutputFormat.THREE_GPP; + } } mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(mProfile.fileFormat); - String fileName = generateVideoFilename(outputFormat); + String fileName = generateVideoFilename(mProfile.fileFormat); Log.v(TAG, "New video filename: " + fileName); mMediaRecorder.setOutputFile(fileName); mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); @@ -2695,6 +2698,9 @@ public class CaptureModule extends BaseModule implements PhotoControl mMediaRecorder.setAudioEncoder(audioEncoder); } mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs); + + Log.i(TAG, "Profile video bitrate: "+ mProfile.videoBitRate); + Log.i(TAG, "Profile video frame rate: "+ mProfile.videoFrameRate); if (mCaptureTimeLapse) { double fps = 1000 / (double) mTimeBetweenTimeLapseFrameCaptureMs; mMediaRecorder.setCaptureRate(fps); @@ -2702,14 +2708,11 @@ public class CaptureModule extends BaseModule implements PhotoControl mHighSpeedFPSRange = new Range(mHighSpeedCaptureRate, mHighSpeedCaptureRate); int fps = (int) mHighSpeedFPSRange.getUpper(); mMediaRecorder.setCaptureRate(fps); - if (mHighSpeedCaptureSlowMode) { - mMediaRecorder.setVideoFrameRate(30); - } else { - mMediaRecorder.setVideoFrameRate(fps); - } - - int scaledBitrate = mProfile.videoBitRate * fps / mProfile.videoFrameRate; - Log.i(TAG, "Scaled Video bitrate : " + scaledBitrate); + int targetRate = mHighSpeedRecordingMode ? fps : 30; + mMediaRecorder.setVideoFrameRate(targetRate); + Log.i(TAG, "Capture rate: "+fps+", Target rate: "+targetRate); + int scaledBitrate = mSettingsManager.getHighSpeedVideoEncoderBitRate(mProfile, targetRate); + Log.i(TAG, "Scaled video bitrate : " + scaledBitrate); mMediaRecorder.setVideoEncodingBitRate(scaledBitrate); } diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java index c242224c7..bea1e4014 100644 --- a/src/com/android/camera/SettingsManager.java +++ b/src/com/android/camera/SettingsManager.java @@ -39,6 +39,7 @@ import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.params.StreamConfigurationMap; import android.media.MediaRecorder; +import android.media.CamcorderProfile; import android.util.Log; import android.util.Range; import android.util.Rational; @@ -927,6 +928,18 @@ public class SettingsManager implements ListMenu.SettingsListener { return map.getHighSpeedVideoFpsRangesFor(videoSize); } + public int getHighSpeedVideoEncoderBitRate(CamcorderProfile profile, int targetRate) { + int bitRate; + String key = profile.videoFrameWidth+"x"+profile.videoFrameHeight+":"+targetRate; + if (CameraSettings.VIDEO_ENCODER_BITRATE.containsKey(key)) { + bitRate = CameraSettings.VIDEO_ENCODER_BITRATE.get(key); + } else { + Log.i(TAG, "No pre-defined bitrate for "+key); + bitRate = (profile.videoBitRate * targetRate) / profile.videoFrameRate; + } + return bitRate; + } + private List getSupportedRedeyeReduction(int cameraId) { int[] flashModes = mCharacteristics.get(cameraId).get(CameraCharacteristics .CONTROL_AE_AVAILABLE_MODES); diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index e4f5bc225..a8e990d32 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -1689,6 +1689,17 @@ public class VideoModule extends BaseModule implements mMediaRecorder.setPreviewDisplay(mUI.getSurfaceHolder().getSurface()); } } + private int getHighSpeedVideoEncoderBitRate(CamcorderProfile profile, int targetRate) { + int bitRate; + String key = profile.videoFrameWidth+"x"+profile.videoFrameHeight+":"+targetRate; + if (CameraSettings.VIDEO_ENCODER_BITRATE.containsKey(key)) { + bitRate = CameraSettings.VIDEO_ENCODER_BITRATE.get(key); + } else { + Log.i(TAG, "No pre-defined bitrate for "+key); + bitRate = (profile.videoBitRate * targetRate) / profile.videoFrameRate; + } + return bitRate; + } // Prepares media recorder. private void initializeRecorder() { @@ -1792,8 +1803,7 @@ public class VideoModule extends BaseModule implements } mMediaRecorder.setOutputFormat(mProfile.fileFormat); mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); - mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate * - ((isHSR ? captureRate : 30) / 30)); + mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate); mMediaRecorder.setVideoEncoder(mProfile.videoCodec); if (isHSR) { Log.i(TAG, "Configuring audio for HSR"); @@ -1829,7 +1839,7 @@ public class VideoModule extends BaseModule implements // Profiles advertizes bitrate corresponding to published framerate. // In case framerate is different, scale the bitrate - int scaledBitrate = mProfile.videoBitRate * (targetFrameRate / mProfile.videoFrameRate); + int scaledBitrate = getHighSpeedVideoEncoderBitRate(mProfile, targetFrameRate); Log.i(TAG, "Scaled Video bitrate : " + scaledBitrate); mMediaRecorder.setVideoEncodingBitRate(scaledBitrate); } -- cgit v1.2.3