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 <ssilkin@webrtc.org>
Reviewed-by: Linus Nilsson <lnilsson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39668}
This commit is contained in:
Sergey Silkin 2023-03-24 11:44:39 +00:00 committed by WebRTC LUCI CQ
parent 94b51210f8
commit 2d1fa4713f
2 changed files with 24 additions and 40 deletions

View File

@ -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);

View File

@ -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;