mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Implement device based encoder bitrate mapping.
This feature is disabled by default for now. PiperOrigin-RevId: 458932471 (cherry picked from commit 7d2eb7601947570245dcd2ff86b7dcf1c8393d40)
This commit is contained in:
parent
3bdecf2ac9
commit
ebf1ae49b7
@ -56,6 +56,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
@Nullable private EncoderSelector encoderSelector;
|
@Nullable private EncoderSelector encoderSelector;
|
||||||
@Nullable private VideoEncoderSettings requestedVideoEncoderSettings;
|
@Nullable private VideoEncoderSettings requestedVideoEncoderSettings;
|
||||||
private boolean enableFallback;
|
private boolean enableFallback;
|
||||||
|
private boolean automaticQualityAdjustment;
|
||||||
|
|
||||||
/** Creates a new {@link Builder}. */
|
/** Creates a new {@link Builder}. */
|
||||||
public Builder(Context context) {
|
public Builder(Context context) {
|
||||||
@ -76,10 +77,18 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
/**
|
/**
|
||||||
* Sets the requested {@link VideoEncoderSettings}.
|
* Sets the requested {@link VideoEncoderSettings}.
|
||||||
*
|
*
|
||||||
* <p>Values in {@code requestedVideoEncoderSettings} could be adjusted to improve encoding
|
* <p>Values in {@code requestedVideoEncoderSettings} may be ignored to improve encoding quality
|
||||||
* quality and/or reduce failures. Specifically, {@link VideoEncoderSettings#profile} and {@link
|
* and/or reduce failures.
|
||||||
* VideoEncoderSettings#level} are ignored for {@link MimeTypes#VIDEO_H264}. Consider
|
*
|
||||||
* implementing {@link Codec.EncoderFactory} if such adjustments are unwanted.
|
* <ul>
|
||||||
|
* <li>{@link VideoEncoderSettings#bitrate} is ignored if {@link
|
||||||
|
* Builder#setAutomaticQualityAdjustment(boolean)} is enabled and {@link
|
||||||
|
* VideoEncoderSettings#bitrateMode} is VBR.
|
||||||
|
* <li>{@link VideoEncoderSettings#profile} and {@link VideoEncoderSettings#level} are ignored
|
||||||
|
* for {@link MimeTypes#VIDEO_H264}
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>Consider implementing {@link Codec.EncoderFactory} if such adjustments are unwanted.
|
||||||
*
|
*
|
||||||
* <p>{@code requestedVideoEncoderSettings} should be handled with care because there is no
|
* <p>{@code requestedVideoEncoderSettings} should be handled with care because there is no
|
||||||
* fallback support for it. For example, using incompatible {@link VideoEncoderSettings#profile}
|
* fallback support for it. For example, using incompatible {@link VideoEncoderSettings#profile}
|
||||||
@ -110,8 +119,19 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to use automatic quality adjustment.
|
||||||
|
*
|
||||||
|
* <p>With this enabled, encoders are configured to output high quality video.
|
||||||
|
*
|
||||||
|
* <p>Default value is {@code false}.
|
||||||
|
*/
|
||||||
|
public Builder setAutomaticQualityAdjustment(boolean automaticQualityAdjustment) {
|
||||||
|
this.automaticQualityAdjustment = automaticQualityAdjustment;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates an instance of {@link DefaultEncoderFactory}, using defaults if values are unset. */
|
/** Creates an instance of {@link DefaultEncoderFactory}, using defaults if values are unset. */
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public DefaultEncoderFactory build() {
|
public DefaultEncoderFactory build() {
|
||||||
if (encoderSelector == null) {
|
if (encoderSelector == null) {
|
||||||
encoderSelector = EncoderSelector.DEFAULT;
|
encoderSelector = EncoderSelector.DEFAULT;
|
||||||
@ -120,7 +140,11 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
requestedVideoEncoderSettings = VideoEncoderSettings.DEFAULT;
|
requestedVideoEncoderSettings = VideoEncoderSettings.DEFAULT;
|
||||||
}
|
}
|
||||||
return new DefaultEncoderFactory(
|
return new DefaultEncoderFactory(
|
||||||
context, encoderSelector, requestedVideoEncoderSettings, enableFallback);
|
context,
|
||||||
|
encoderSelector,
|
||||||
|
requestedVideoEncoderSettings,
|
||||||
|
enableFallback,
|
||||||
|
automaticQualityAdjustment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +152,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
private final EncoderSelector videoEncoderSelector;
|
private final EncoderSelector videoEncoderSelector;
|
||||||
private final VideoEncoderSettings requestedVideoEncoderSettings;
|
private final VideoEncoderSettings requestedVideoEncoderSettings;
|
||||||
private final boolean enableFallback;
|
private final boolean enableFallback;
|
||||||
|
private final boolean automaticQualityAdjustment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link Builder} instead.
|
* @deprecated Use {@link Builder} instead.
|
||||||
@ -157,10 +182,25 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
EncoderSelector videoEncoderSelector,
|
EncoderSelector videoEncoderSelector,
|
||||||
VideoEncoderSettings requestedVideoEncoderSettings,
|
VideoEncoderSettings requestedVideoEncoderSettings,
|
||||||
boolean enableFallback) {
|
boolean enableFallback) {
|
||||||
|
this(
|
||||||
|
context,
|
||||||
|
videoEncoderSelector,
|
||||||
|
requestedVideoEncoderSettings,
|
||||||
|
enableFallback,
|
||||||
|
/* automaticQualityAdjustment= */ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DefaultEncoderFactory(
|
||||||
|
Context context,
|
||||||
|
EncoderSelector videoEncoderSelector,
|
||||||
|
VideoEncoderSettings requestedVideoEncoderSettings,
|
||||||
|
boolean enableFallback,
|
||||||
|
boolean automaticQualityAdjustment) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.videoEncoderSelector = videoEncoderSelector;
|
this.videoEncoderSelector = videoEncoderSelector;
|
||||||
this.requestedVideoEncoderSettings = requestedVideoEncoderSettings;
|
this.requestedVideoEncoderSettings = requestedVideoEncoderSettings;
|
||||||
this.enableFallback = enableFallback;
|
this.enableFallback = enableFallback;
|
||||||
|
this.automaticQualityAdjustment = automaticQualityAdjustment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -234,12 +274,20 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
String mimeType = checkNotNull(format.sampleMimeType);
|
String mimeType = checkNotNull(format.sampleMimeType);
|
||||||
MediaFormat mediaFormat = MediaFormat.createVideoFormat(mimeType, format.width, format.height);
|
MediaFormat mediaFormat = MediaFormat.createVideoFormat(mimeType, format.width, format.height);
|
||||||
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, round(format.frameRate));
|
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, round(format.frameRate));
|
||||||
mediaFormat.setInteger(
|
|
||||||
MediaFormat.KEY_BIT_RATE,
|
|
||||||
supportedVideoEncoderSettings.bitrate != VideoEncoderSettings.NO_VALUE
|
|
||||||
? supportedVideoEncoderSettings.bitrate
|
|
||||||
: getSuggestedBitrate(format.width, format.height, format.frameRate));
|
|
||||||
|
|
||||||
|
int bitrate;
|
||||||
|
if (automaticQualityAdjustment) {
|
||||||
|
bitrate =
|
||||||
|
new DeviceMappedEncoderBitrateProvider()
|
||||||
|
.getBitrate(
|
||||||
|
encoderInfo.getName(), format.width, format.height, round(format.frameRate));
|
||||||
|
} else if (supportedVideoEncoderSettings.bitrate != VideoEncoderSettings.NO_VALUE) {
|
||||||
|
bitrate = supportedVideoEncoderSettings.bitrate;
|
||||||
|
} else {
|
||||||
|
bitrate = getSuggestedBitrate(format.width, format.height, format.frameRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
|
||||||
mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, supportedVideoEncoderSettings.bitrateMode);
|
mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, supportedVideoEncoderSettings.bitrateMode);
|
||||||
|
|
||||||
if (supportedVideoEncoderSettings.profile != VideoEncoderSettings.NO_VALUE
|
if (supportedVideoEncoderSettings.profile != VideoEncoderSettings.NO_VALUE
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package androidx.media3.transformer;
|
||||||
|
|
||||||
|
import android.media.MediaCodecInfo;
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
|
||||||
|
/** Provides bitrates for encoders to use as a target. */
|
||||||
|
@UnstableApi
|
||||||
|
public interface EncoderBitrateProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a recommended bitrate that the encoder should target.
|
||||||
|
*
|
||||||
|
* @param encoderName The name of the encoder, see {@link MediaCodecInfo#getName()}
|
||||||
|
* @param width The output width of the video after encoding.
|
||||||
|
* @param height The output height of the video after encoding.
|
||||||
|
* @param frameRate The expected output frame rate of the video after encoding.
|
||||||
|
* @return The bitrate the encoder should target.
|
||||||
|
*/
|
||||||
|
int getBitrate(String encoderName, int width, int height, int frameRate);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user