mirror of
https://github.com/androidx/media.git
synced 2025-05-14 02:59:52 +08:00
Improve video canReconfigureCodec accuracy
The codec cannot be reconfigured if the format rotation changes, or if the format dimensions exceed the current decoder's configured maximum dimensions. Issue #1707 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=129004187
This commit is contained in:
parent
ced7906737
commit
02a79f8c51
@ -60,8 +60,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
private final int maxDroppedFramesToNotify;
|
private final int maxDroppedFramesToNotify;
|
||||||
private final boolean deviceNeedsAutoFrcWorkaround;
|
private final boolean deviceNeedsAutoFrcWorkaround;
|
||||||
|
|
||||||
private int adaptiveMaxWidth;
|
private int maxWidth;
|
||||||
private int adaptiveMaxHeight;
|
private int maxHeight;
|
||||||
|
private int configuredMaxWidth;
|
||||||
|
private int configuredMaxHeight;
|
||||||
|
|
||||||
private Surface surface;
|
private Surface surface;
|
||||||
private boolean reportedDrawnToSurface;
|
private boolean reportedDrawnToSurface;
|
||||||
@ -219,18 +221,17 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats) throws ExoPlaybackException {
|
protected void onStreamChanged(Format[] formats) throws ExoPlaybackException {
|
||||||
adaptiveMaxWidth = Format.NO_VALUE;
|
maxWidth = Format.NO_VALUE;
|
||||||
adaptiveMaxHeight = Format.NO_VALUE;
|
maxHeight = Format.NO_VALUE;
|
||||||
if (formats.length > 1) {
|
for (Format format : formats) {
|
||||||
for (Format format : formats) {
|
maxWidth = Math.max(maxWidth, format.width);
|
||||||
adaptiveMaxWidth = Math.max(adaptiveMaxWidth, format.width);
|
maxHeight = Math.max(maxHeight, format.height);
|
||||||
adaptiveMaxHeight = Math.max(adaptiveMaxHeight, format.height);
|
}
|
||||||
}
|
if (formats.length > 1 && (maxWidth == Format.NO_VALUE || maxHeight == Format.NO_VALUE)) {
|
||||||
if (adaptiveMaxWidth == Format.NO_VALUE || adaptiveMaxHeight == Format.NO_VALUE) {
|
// TODO: Consider replacing this block with one that sets values injected via the constructor.
|
||||||
Log.w(TAG, "Maximum dimensions unknown. Assuming 1920x1080.");
|
Log.w(TAG, "Maximum dimensions unknown for adaptive playback. Assuming 1920x1080.");
|
||||||
adaptiveMaxWidth = 1920;
|
maxWidth = 1920;
|
||||||
adaptiveMaxHeight = 1080;
|
maxHeight = 1080;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.onStreamChanged(formats);
|
super.onStreamChanged(formats);
|
||||||
}
|
}
|
||||||
@ -325,7 +326,12 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
// Override configureCodec to provide the surface.
|
// Override configureCodec to provide the surface.
|
||||||
@Override
|
@Override
|
||||||
protected void configureCodec(MediaCodec codec, Format format, MediaCrypto crypto) {
|
protected void configureCodec(MediaCodec codec, Format format, MediaCrypto crypto) {
|
||||||
codec.configure(getFrameworkMediaFormat(format), surface, crypto, 0);
|
maxWidth = Math.max(maxWidth, format.width);
|
||||||
|
maxHeight = Math.max(maxHeight, format.height);
|
||||||
|
codec.configure(getFrameworkFormat(format, maxWidth, maxHeight, deviceNeedsAutoFrcWorkaround),
|
||||||
|
surface, crypto, 0);
|
||||||
|
configuredMaxWidth = maxWidth;
|
||||||
|
configuredMaxHeight = maxHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -338,10 +344,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
|
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
|
||||||
super.onInputFormatChanged(newFormat);
|
super.onInputFormatChanged(newFormat);
|
||||||
eventDispatcher.inputFormatChanged(newFormat);
|
eventDispatcher.inputFormatChanged(newFormat);
|
||||||
pendingPixelWidthHeightRatio = newFormat.pixelWidthHeightRatio == Format.NO_VALUE ? 1
|
pendingPixelWidthHeightRatio = getPixelWidthHeightRatio(newFormat);
|
||||||
: newFormat.pixelWidthHeightRatio;
|
pendingRotationDegrees = getRotationDegrees(newFormat);
|
||||||
pendingRotationDegrees = newFormat.rotationDegrees == Format.NO_VALUE ? 0
|
|
||||||
: newFormat.rotationDegrees;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -378,6 +382,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
protected boolean canReconfigureCodec(MediaCodec codec, boolean codecIsAdaptive,
|
protected boolean canReconfigureCodec(MediaCodec codec, boolean codecIsAdaptive,
|
||||||
Format oldFormat, Format newFormat) {
|
Format oldFormat, Format newFormat) {
|
||||||
return newFormat.sampleMimeType.equals(oldFormat.sampleMimeType)
|
return newFormat.sampleMimeType.equals(oldFormat.sampleMimeType)
|
||||||
|
&& getRotationDegrees(newFormat) == getRotationDegrees(oldFormat)
|
||||||
|
&& newFormat.width <= configuredMaxWidth && newFormat.height <= configuredMaxHeight
|
||||||
&& (codecIsAdaptive
|
&& (codecIsAdaptive
|
||||||
|| (oldFormat.width == newFormat.width && oldFormat.height == newFormat.height));
|
|| (oldFormat.width == newFormat.width && oldFormat.height == newFormat.height));
|
||||||
}
|
}
|
||||||
@ -496,18 +502,17 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("InlinedApi")
|
@SuppressLint("InlinedApi")
|
||||||
private android.media.MediaFormat getFrameworkMediaFormat(Format format) {
|
private static android.media.MediaFormat getFrameworkFormat(Format format, int maxWidth,
|
||||||
|
int maxHeight, boolean deviceNeedsAutoFrcWorkaround) {
|
||||||
android.media.MediaFormat frameworkMediaFormat = format.getFrameworkMediaFormatV16();
|
android.media.MediaFormat frameworkMediaFormat = format.getFrameworkMediaFormatV16();
|
||||||
|
|
||||||
if (deviceNeedsAutoFrcWorkaround) {
|
if (deviceNeedsAutoFrcWorkaround) {
|
||||||
frameworkMediaFormat.setInteger("auto-frc", 0);
|
frameworkMediaFormat.setInteger("auto-frc", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the maximum adaptive video dimensions if applicable.
|
// Set the maximum adaptive video dimensions.
|
||||||
if (adaptiveMaxWidth != Format.NO_VALUE && adaptiveMaxHeight != Format.NO_VALUE) {
|
frameworkMediaFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, maxWidth);
|
||||||
frameworkMediaFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, adaptiveMaxWidth);
|
frameworkMediaFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, maxHeight);
|
||||||
frameworkMediaFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, adaptiveMaxHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format.maxInputSize > 0) {
|
if (format.maxInputSize > 0) {
|
||||||
// The format already has a maximum input size.
|
// The format already has a maximum input size.
|
||||||
@ -515,8 +520,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the format doesn't define a maximum input size, determine one ourselves.
|
// If the format doesn't define a maximum input size, determine one ourselves.
|
||||||
int maxWidth = Math.max(adaptiveMaxWidth, format.width);
|
|
||||||
int maxHeight = Math.max(adaptiveMaxHeight, format.height);
|
|
||||||
int maxPixels;
|
int maxPixels;
|
||||||
int minCompressionRatio;
|
int minCompressionRatio;
|
||||||
switch (format.sampleMimeType) {
|
switch (format.sampleMimeType) {
|
||||||
@ -603,4 +606,12 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
return Util.SDK_INT <= 22 && "foster".equals(Util.DEVICE) && "NVIDIA".equals(Util.MANUFACTURER);
|
return Util.SDK_INT <= 22 && "foster".equals(Util.DEVICE) && "NVIDIA".equals(Util.MANUFACTURER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float getPixelWidthHeightRatio(Format format) {
|
||||||
|
return format.pixelWidthHeightRatio == Format.NO_VALUE ? 1 : format.pixelWidthHeightRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getRotationDegrees(Format format) {
|
||||||
|
return format.rotationDegrees == Format.NO_VALUE ? 0 : format.rotationDegrees;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user