Commit 54418eb6 by olly Committed by Christos Tsilopoulos

Size dolby vision buffers for H265 by default

PiperOrigin-RevId: 391965200
parent 287e72c4
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
* Core Library: * Core Library:
* Fix track selection in `StyledPlayerControlView` when using * Fix track selection in `StyledPlayerControlView` when using
`ForwardingPlayer`. `ForwardingPlayer`.
* Video
* Request smaller decoder input buffers for Dolby Vision. This fixes an
issue that could cause UHD Dolby Vision playbacks to fail on some
devices, including Amazon Fire TV 4K.
### 2.15.0 (2021-08-10) ### 2.15.0 (2021-08-10)
......
...@@ -1359,8 +1359,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1359,8 +1359,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// The single entry in streamFormats must correspond to the format for which the codec is // The single entry in streamFormats must correspond to the format for which the codec is
// being configured. // being configured.
if (maxInputSize != Format.NO_VALUE) { if (maxInputSize != Format.NO_VALUE) {
int codecMaxInputSize = int codecMaxInputSize = getCodecMaxInputSize(codecInfo, format);
getCodecMaxInputSize(codecInfo, format.sampleMimeType, format.width, format.height);
if (codecMaxInputSize != Format.NO_VALUE) { if (codecMaxInputSize != Format.NO_VALUE) {
// Scale up the initial video decoder maximum input size so playlist item transitions with // Scale up the initial video decoder maximum input size so playlist item transitions with
// small increases in maximum sample size don't require reinitialization. This only makes // small increases in maximum sample size don't require reinitialization. This only makes
...@@ -1397,7 +1396,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1397,7 +1396,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
maxInputSize = maxInputSize =
max( max(
maxInputSize, maxInputSize,
getCodecMaxInputSize(codecInfo, format.sampleMimeType, maxWidth, maxHeight)); getCodecMaxInputSize(
codecInfo, format.buildUpon().setWidth(maxWidth).setHeight(maxHeight).build()));
Log.w(TAG, "Codec max resolution adjusted to: " + maxWidth + "x" + maxHeight); Log.w(TAG, "Codec max resolution adjusted to: " + maxWidth + "x" + maxHeight);
} }
} }
...@@ -1476,29 +1476,46 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1476,29 +1476,46 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
return format.maxInputSize + totalInitializationDataSize; return format.maxInputSize + totalInitializationDataSize;
} else { } else {
// Calculated maximum input sizes are overestimates, so it's not necessary to add the size of return getCodecMaxInputSize(codecInfo, format);
// initialization data.
return getCodecMaxInputSize(codecInfo, format.sampleMimeType, format.width, format.height);
} }
} }
/** /**
* Returns a maximum input size for a given codec, MIME type, width and height. * Returns a maximum input size for a given codec and format.
* *
* @param codecInfo Information about the {@link MediaCodec} being configured. * @param codecInfo Information about the {@link MediaCodec} being configured.
* @param sampleMimeType The format mime type. * @param format The format.
* @param width The width in pixels.
* @param height The height in pixels.
* @return A maximum input size in bytes, or {@link Format#NO_VALUE} if a maximum could not be * @return A maximum input size in bytes, or {@link Format#NO_VALUE} if a maximum could not be
* determined. * determined.
*/ */
private static int getCodecMaxInputSize( private static int getCodecMaxInputSize(MediaCodecInfo codecInfo, Format format) {
MediaCodecInfo codecInfo, String sampleMimeType, int width, int height) { int width = format.width;
int height = format.height;
if (width == Format.NO_VALUE || height == Format.NO_VALUE) { if (width == Format.NO_VALUE || height == Format.NO_VALUE) {
// We can't infer a maximum input size without video dimensions. // We can't infer a maximum input size without video dimensions.
return Format.NO_VALUE; return Format.NO_VALUE;
} }
String sampleMimeType = format.sampleMimeType;
if (MimeTypes.VIDEO_DOLBY_VISION.equals(sampleMimeType)) {
// Dolby vision can be a wrapper around H264 or H265. We assume it's wrapping H265 by default
// because it's the common case, and because some devices may fail to allocate the codec when
// the larger buffer size required for H264 is requested. We size buffers for H264 only if the
// format contains sufficient information for us to determine unambiguously that it's a H264
// profile.
sampleMimeType = MimeTypes.VIDEO_H265;
@Nullable
Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format);
if (codecProfileAndLevel != null) {
int profile = codecProfileAndLevel.first;
if (profile == CodecProfileLevel.DolbyVisionProfileDvavSe
|| profile == CodecProfileLevel.DolbyVisionProfileDvavPer
|| profile == CodecProfileLevel.DolbyVisionProfileDvavPen) {
sampleMimeType = MimeTypes.VIDEO_H264;
}
}
}
// Attempt to infer a maximum input size from the format. // Attempt to infer a maximum input size from the format.
int maxPixels; int maxPixels;
int minCompressionRatio; int minCompressionRatio;
...@@ -1508,9 +1525,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -1508,9 +1525,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
maxPixels = width * height; maxPixels = width * height;
minCompressionRatio = 2; minCompressionRatio = 2;
break; break;
case MimeTypes.VIDEO_DOLBY_VISION:
// Dolby vision can be a wrapper around H264 or H265. We assume H264 here because the
// minimum compression ratio is lower, meaning we overestimate the maximum input size.
case MimeTypes.VIDEO_H264: case MimeTypes.VIDEO_H264:
if ("BRAVIA 4K 2015".equals(Util.MODEL) // Sony Bravia 4K if ("BRAVIA 4K 2015".equals(Util.MODEL) // Sony Bravia 4K
|| ("Amazon".equals(Util.MANUFACTURER) || ("Amazon".equals(Util.MANUFACTURER)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment