From 2d1fa4713fe4f81a0474dd3e4ee9d75223310a52 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Fri, 24 Mar 2023 11:44:39 +0000 Subject: [PATCH] Use MediaCodec API keys and values directly Replace locally-defined keys and values with constants from MediaCodec API (MediaFormat.KEY_..., etc). Value of a constant field is resolved at compile time according to 13.1.1 [1]. I.e., it is safe to reference a constant field not available in older API (MediaCodec API ignores unrecognized MediaFormat.KEY_ values). [1] https://docs.oracle.com/javase/specs/jls/se20/html/jls-13.html#jls-13.1 Bug: none Change-Id: I3c63cfd67cc22db1b957f908508b434d36d88806 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298940 Commit-Queue: Sergey Silkin Reviewed-by: Linus Nilsson Cr-Commit-Position: refs/heads/main@{#39668} --- .../java/org/webrtc/AndroidVideoDecoder.java | 39 +++++++------------ .../java/org/webrtc/HardwareVideoEncoder.java | 25 +++++------- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java b/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java index ad40898e4c..47cb5689ce 100644 --- a/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java +++ b/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java @@ -26,20 +26,9 @@ import org.webrtc.ThreadUtils.ThreadChecker; /** * Android hardware video decoder. */ -@SuppressWarnings("deprecation") -// Cannot support API 16 without using deprecated methods. -// TODO(sakal): Rename to MediaCodecVideoDecoder once the deprecated implementation is removed. class AndroidVideoDecoder implements VideoDecoder, VideoSink { private static final String TAG = "AndroidVideoDecoder"; - // TODO(magjed): Use MediaFormat.KEY_* constants when part of the public API. - private static final String MEDIA_FORMAT_KEY_STRIDE = "stride"; - private static final String MEDIA_FORMAT_KEY_SLICE_HEIGHT = "slice-height"; - private static final String MEDIA_FORMAT_KEY_CROP_LEFT = "crop-left"; - private static final String MEDIA_FORMAT_KEY_CROP_RIGHT = "crop-right"; - private static final String MEDIA_FORMAT_KEY_CROP_TOP = "crop-top"; - private static final String MEDIA_FORMAT_KEY_CROP_BOTTOM = "crop-bottom"; - // MediaCodec.release() occasionally hangs. Release stops waiting and reports failure after // this timeout. private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000; @@ -162,7 +151,7 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink { decoderThreadChecker.checkIsOnValidThread(); Logging.d(TAG, "initDecodeInternal name: " + codecName + " type: " + codecType + " width: " + width - + " height: " + height); + + " height: " + height + " color format: " + colorFormat); if (outputThread != null) { Logging.e(TAG, "initDecodeInternal called while the codec is already running"); return VideoCodecStatus.FALLBACK_SOFTWARE; @@ -568,17 +557,17 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink { private void reformat(MediaFormat format) { outputThreadChecker.checkIsOnValidThread(); - Logging.d(TAG, "Decoder format changed: " + format.toString()); + Logging.d(TAG, "Decoder format changed: " + format); final int newWidth; final int newHeight; - if (format.containsKey(MEDIA_FORMAT_KEY_CROP_LEFT) - && format.containsKey(MEDIA_FORMAT_KEY_CROP_RIGHT) - && format.containsKey(MEDIA_FORMAT_KEY_CROP_BOTTOM) - && format.containsKey(MEDIA_FORMAT_KEY_CROP_TOP)) { - newWidth = 1 + format.getInteger(MEDIA_FORMAT_KEY_CROP_RIGHT) - - format.getInteger(MEDIA_FORMAT_KEY_CROP_LEFT); - newHeight = 1 + format.getInteger(MEDIA_FORMAT_KEY_CROP_BOTTOM) - - format.getInteger(MEDIA_FORMAT_KEY_CROP_TOP); + if (format.containsKey(MediaFormat.KEY_CROP_LEFT) + && format.containsKey(MediaFormat.KEY_CROP_RIGHT) + && format.containsKey(MediaFormat.KEY_CROP_BOTTOM) + && format.containsKey(MediaFormat.KEY_CROP_TOP)) { + newWidth = 1 + format.getInteger(MediaFormat.KEY_CROP_RIGHT) + - format.getInteger(MediaFormat.KEY_CROP_LEFT); + newHeight = 1 + format.getInteger(MediaFormat.KEY_CROP_BOTTOM) + - format.getInteger(MediaFormat.KEY_CROP_TOP); } else { newWidth = format.getInteger(MediaFormat.KEY_WIDTH); newHeight = format.getInteger(MediaFormat.KEY_HEIGHT); @@ -615,11 +604,11 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink { // Save stride and sliceHeight under the dimension lock. synchronized (dimensionLock) { - if (format.containsKey(MEDIA_FORMAT_KEY_STRIDE)) { - stride = format.getInteger(MEDIA_FORMAT_KEY_STRIDE); + if (format.containsKey(MediaFormat.KEY_STRIDE)) { + stride = format.getInteger(MediaFormat.KEY_STRIDE); } - if (format.containsKey(MEDIA_FORMAT_KEY_SLICE_HEIGHT)) { - sliceHeight = format.getInteger(MEDIA_FORMAT_KEY_SLICE_HEIGHT); + if (format.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) { + sliceHeight = format.getInteger(MediaFormat.KEY_SLICE_HEIGHT); } Logging.d(TAG, "Frame stride and slice height: " + stride + " x " + sliceHeight); stride = Math.max(width, stride); diff --git a/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java b/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java index 41d97359eb..b5f7629230 100644 --- a/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java +++ b/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java @@ -10,6 +10,10 @@ package org.webrtc; +import static android.media.MediaCodecInfo.CodecProfileLevel.AVCLevel3; +import static android.media.MediaCodecInfo.CodecProfileLevel.AVCProfileHigh; +import static android.media.MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR; + import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; @@ -32,16 +36,6 @@ import org.webrtc.ThreadUtils.ThreadChecker; class HardwareVideoEncoder implements VideoEncoder { private static final String TAG = "HardwareVideoEncoder"; - // Bitrate modes - should be in sync with OMX_VIDEO_CONTROLRATETYPE defined - // in OMX_Video.h - private static final int VIDEO_ControlRateConstant = 2; - // Key associated with the bitrate control mode value (above). Not present as a MediaFormat - // constant until API level 21. - private static final String KEY_BITRATE_MODE = "bitrate-mode"; - - private static final int VIDEO_AVC_PROFILE_HIGH = 8; - private static final int VIDEO_AVC_LEVEL_3 = 0x100; - private static final int MAX_VIDEO_FRAMERATE = 30; // See MAX_ENCODER_Q_SIZE in androidmediaencoder.cc. @@ -220,8 +214,9 @@ class HardwareVideoEncoder implements VideoEncoder { adjustedBitrate = bitrateAdjuster.getAdjustedBitrateBps(); Logging.d(TAG, - "initEncode: " + width + " x " + height + ". @ " + settings.startBitrate - + "kbps. Fps: " + settings.maxFramerate + " Use surface mode: " + useSurfaceMode); + "initEncode name: " + codecName + " type: " + codecType + " width: " + width + + " height: " + height + " framerate_fps: " + settings.maxFramerate + + " bitrate_kbps: " + settings.startBitrate + " surface mode: " + useSurfaceMode); return initEncodeInternal(); } @@ -242,7 +237,7 @@ class HardwareVideoEncoder implements VideoEncoder { try { MediaFormat format = MediaFormat.createVideoFormat(codecType.mimeType(), width, height); format.setInteger(MediaFormat.KEY_BIT_RATE, adjustedBitrate); - format.setInteger(KEY_BITRATE_MODE, VIDEO_ControlRateConstant); + format.setInteger(MediaFormat.KEY_BITRATE_MODE, BITRATE_MODE_CBR); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); format.setFloat( MediaFormat.KEY_FRAME_RATE, (float) bitrateAdjuster.getAdjustedFramerateFps()); @@ -254,8 +249,8 @@ class HardwareVideoEncoder implements VideoEncoder { } switch (profileLevelId) { case VideoCodecInfo.H264_CONSTRAINED_HIGH_3_1: - format.setInteger("profile", VIDEO_AVC_PROFILE_HIGH); - format.setInteger("level", VIDEO_AVC_LEVEL_3); + format.setInteger("profile", AVCProfileHigh); + format.setInteger("level", AVCLevel3); break; case VideoCodecInfo.H264_CONSTRAINED_BASELINE_3_1: break;