mirror of
https://github.com/androidx/media.git
synced 2025-05-04 14:10:40 +08:00
Prefer hardware encoders in EncoderSelector.
In encoding small and odd-numbered resolutions, like `316x61` ([this image](https://upload.wikimedia.org/wikipedia/commons/6/65/100winners.png)), the current fallback logic prefers a software encoder to hardware ones. The assumption was, the encoder factory applies the encoder size alignment and changes the resolution to `316x60` for SW encoders and `316x64` for HW ones. SW encoders is selected because the supported resolution 60 is closer to requested 61, than the hardware supported 64. This change changes the default encoder selection process to only expose hardware encoders if there is any. PiperOrigin-RevId: 506879983
This commit is contained in:
parent
14210d3df3
commit
c09904e143
@ -56,7 +56,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
public static final class Builder {
|
||||
private final Context context;
|
||||
|
||||
@Nullable private EncoderSelector encoderSelector;
|
||||
@Nullable private EncoderSelector videoEncoderSelector;
|
||||
@Nullable private VideoEncoderSettings requestedVideoEncoderSettings;
|
||||
private boolean enableFallback;
|
||||
|
||||
@ -72,8 +72,8 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
* <p>The default value is {@link EncoderSelector#DEFAULT}.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setVideoEncoderSelector(EncoderSelector encoderSelector) {
|
||||
this.encoderSelector = encoderSelector;
|
||||
public Builder setVideoEncoderSelector(EncoderSelector videoEncoderSelector) {
|
||||
this.videoEncoderSelector = videoEncoderSelector;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -121,14 +121,14 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
/** Creates an instance of {@link DefaultEncoderFactory}, using defaults if values are unset. */
|
||||
@SuppressWarnings("deprecation")
|
||||
public DefaultEncoderFactory build() {
|
||||
if (encoderSelector == null) {
|
||||
encoderSelector = EncoderSelector.DEFAULT;
|
||||
if (videoEncoderSelector == null) {
|
||||
videoEncoderSelector = EncoderSelector.DEFAULT;
|
||||
}
|
||||
if (requestedVideoEncoderSettings == null) {
|
||||
requestedVideoEncoderSettings = VideoEncoderSettings.DEFAULT;
|
||||
}
|
||||
return new DefaultEncoderFactory(
|
||||
context, encoderSelector, requestedVideoEncoderSettings, enableFallback);
|
||||
context, videoEncoderSelector, requestedVideoEncoderSettings, enableFallback);
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,6 +450,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
/** Returns a list of encoders that support the requested resolution most closely. */
|
||||
private static ImmutableList<MediaCodecInfo> filterEncodersByResolution(
|
||||
List<MediaCodecInfo> encoders, String mimeType, int requestedWidth, int requestedHeight) {
|
||||
// TODO(b/267740292): Investigate the fallback logic that might prefer software encoders.
|
||||
return filterEncoders(
|
||||
encoders,
|
||||
/* cost= */ (encoderInfo) -> {
|
||||
|
@ -20,15 +20,29 @@ import android.media.MediaCodec;
|
||||
import android.media.MediaCodecInfo;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/** Selector of {@link MediaCodec} encoder instances. */
|
||||
public interface EncoderSelector {
|
||||
|
||||
/**
|
||||
* Default implementation of {@link EncoderSelector}, which returns the preferred encoders for the
|
||||
* Default implementation of {@code EncoderSelector}, which returns the preferred encoders for the
|
||||
* given {@link MimeTypes MIME type}.
|
||||
*
|
||||
* <p>The {@code EncoderSelector} selection result contains only hardware encoders if they exist,
|
||||
* or only software encoders otherwise.
|
||||
*/
|
||||
EncoderSelector DEFAULT = EncoderUtil::getSupportedEncoders;
|
||||
EncoderSelector DEFAULT =
|
||||
mimeType -> {
|
||||
ImmutableList<MediaCodecInfo> supportedEncoders =
|
||||
EncoderUtil.getSupportedEncoders(mimeType);
|
||||
ImmutableList<MediaCodecInfo> supportedHardwareEncoders =
|
||||
ImmutableList.copyOf(
|
||||
Iterables.filter(
|
||||
supportedEncoders,
|
||||
encoderInfo -> EncoderUtil.isHardwareAccelerated(encoderInfo, mimeType)));
|
||||
return supportedHardwareEncoders.isEmpty() ? supportedEncoders : supportedHardwareEncoders;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a list of encoders that can encode media in the specified {@code mimeType}, in priority
|
||||
|
Loading…
x
Reference in New Issue
Block a user