summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2021-01-08 19:54:37 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-01-08 19:54:37 +0000
commit3e0290b3ad0cc497414d24f601a2ccb33ed5e183 (patch)
tree0b438e7083160572ece93069830980b250987376
parenteab713e3517d60ea08f63c85d69d1be1acf65c01 (diff)
parent57c0f56bf7d0f13b9db05e516ec32c5a1bcc3f02 (diff)
Merge "transcoding: Use CamcorderProfile bitrate for transcoding."
-rw-r--r--apex/media/framework/java/android/media/MediaTranscodeManager.java87
1 files changed, 84 insertions, 3 deletions
diff --git a/apex/media/framework/java/android/media/MediaTranscodeManager.java b/apex/media/framework/java/android/media/MediaTranscodeManager.java
index d449289f156f..3d706e40bc0b 100644
--- a/apex/media/framework/java/android/media/MediaTranscodeManager.java
+++ b/apex/media/framework/java/android/media/MediaTranscodeManager.java
@@ -109,6 +109,9 @@ public final class MediaTranscodeManager {
/** Interval between trying to reconnect to the service. */
private static final int INTERVAL_CONNECT_SERVICE_RETRY_MS = 40;
+ /** Default bpp(bits-per-pixel) to use for calculating default bitrate. */
+ private static final float BPP = 0.25f;
+
/**
* Default transcoding type.
* @hide
@@ -1002,15 +1005,93 @@ public final class MediaTranscodeManager {
if (!shouldTranscode()) {
return null;
}
- // TODO(hkuang): Only modified the video codec type, and use fixed bitrate for now.
- // May switch to transcoding profile when it's available.
+
MediaFormat videoTrackFormat = new MediaFormat(mSrcVideoFormatHint);
videoTrackFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC);
- videoTrackFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
+
+ int width = mSrcVideoFormatHint.getInteger(MediaFormat.KEY_WIDTH);
+ int height = mSrcVideoFormatHint.getInteger(MediaFormat.KEY_HEIGHT);
+ if (width <= 0 || height <= 0) {
+ throw new IllegalArgumentException(
+ "Source Width and height must be larger than 0");
+ }
+
+ // TODO(hkuang): Remove the hardcoded frameRate after b/176940364 is fixed.
+ float frameRate = (float) 30.0;
+ /*mSrcVideoFormatHint.getFloat(MediaFormat.KEY_FRAME_RATE, frameRate);
+ if (frameRate <= 0) {
+ throw new IllegalArgumentException(
+ "frameRate must be larger than 0");
+ }*/
+
+ int bitrate = getAVCBitrate(width, height, frameRate);
+ videoTrackFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
return videoTrackFormat;
}
/**
+ * Generate a default bitrate with the fixed bpp(bits-per-pixel) 0.25.
+ * This maps to:
+ * 1080P@30fps -> 16Mbps
+ * 1080P@60fps-> 32Mbps
+ * 4K@30fps -> 62Mbps
+ */
+ private static int getDefaultBitrate(int width, int height, float frameRate) {
+ return (int) (width * height * frameRate * BPP);
+ }
+
+ /**
+ * Query the bitrate from CamcorderProfile. If there are two profiles that match the
+ * width/height/framerate, we will use the higher one to get better quality.
+ * Return default bitrate if could not find any match profile.
+ */
+ private static int getAVCBitrate(int width, int height, float frameRate) {
+ int bitrate = -1;
+ int[] cameraIds = {0, 1};
+
+ // Profiles ordered in decreasing order of preference.
+ int[] preferQualities = {
+ CamcorderProfile.QUALITY_2160P,
+ CamcorderProfile.QUALITY_1080P,
+ CamcorderProfile.QUALITY_720P,
+ CamcorderProfile.QUALITY_480P,
+ CamcorderProfile.QUALITY_LOW,
+ };
+
+ for (int cameraId : cameraIds) {
+ for (int quality : preferQualities) {
+ // Check if camera id has profile for the quality level.
+ if (!CamcorderProfile.hasProfile(cameraId, quality)) {
+ continue;
+ }
+ CamcorderProfile profile = CamcorderProfile.get(cameraId, quality);
+ // Check the width/height/framerate/codec, also consider portrait case.
+ if (((width == profile.videoFrameWidth
+ && height == profile.videoFrameHeight)
+ || (height == profile.videoFrameWidth
+ && width == profile.videoFrameHeight))
+ && (int) frameRate == profile.videoFrameRate
+ && profile.videoCodec == MediaRecorder.VideoEncoder.H264) {
+ if (bitrate < profile.videoBitRate) {
+ bitrate = profile.videoBitRate;
+ }
+ break;
+ }
+ }
+ }
+
+ if (bitrate == -1) {
+ Log.w(TAG, "Failed to find CamcorderProfile for w: " + width + "h: " + height
+ + " fps: "
+ + frameRate);
+ bitrate = getDefaultBitrate(width, height, frameRate);
+ }
+ Log.d(TAG, "Using bitrate " + bitrate + " for " + width + " " + height + " "
+ + frameRate);
+ return bitrate;
+ }
+
+ /**
* Retrieves the audio track format to be used for transcoding.
*
* @return the audio track format to be used if transcoding should be performed, and