Size dolby vision buffers for H265 by default

PiperOrigin-RevId: 391965200
This commit is contained in:
olly 2021-08-20 12:47:58 +01:00 committed by Oliver Woodman
parent 082542c152
commit 03d0b34ab9
2 changed files with 35 additions and 17 deletions

View File

@ -17,8 +17,10 @@
calls from the player to `Surface.setFrameRate`. This is useful for
applications wanting to call `Surface.setFrameRate` directly from
application code with Android 12's `Surface.CHANGE_FRAME_RATE_ALWAYS`.
* GVR extension:
* Remove `GvrAudioProcessor`, which has been deprecated since 2.11.0.
* 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.
* UI
* `SubtitleView` no longer implements `TextOutput`. `SubtitleView`
implements `Player.Listener`, so can be registered to a player with
@ -41,6 +43,8 @@
`VideoListener`. Use `Player.addListener` and `Player.Listener` instead.
* Remove `DefaultHttpDataSourceFactory`. Use
`DefaultHttpDataSource.Factory` instead.
* Remove `GvrAudioProcessor` and the GVR extension, which has been
deprecated since 2.11.0.
### 2.15.0 (2021-08-10)

View File

@ -1364,8 +1364,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// The single entry in streamFormats must correspond to the format for which the codec is
// being configured.
if (maxInputSize != Format.NO_VALUE) {
int codecMaxInputSize =
getCodecMaxInputSize(codecInfo, format.sampleMimeType, format.width, format.height);
int codecMaxInputSize = getCodecMaxInputSize(codecInfo, format);
if (codecMaxInputSize != Format.NO_VALUE) {
// 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
@ -1402,7 +1401,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
maxInputSize =
max(
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);
}
}
@ -1481,29 +1481,46 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
}
return format.maxInputSize + totalInitializationDataSize;
} else {
// Calculated maximum input sizes are overestimates, so it's not necessary to add the size of
// initialization data.
return getCodecMaxInputSize(codecInfo, format.sampleMimeType, format.width, format.height);
return getCodecMaxInputSize(codecInfo, format);
}
}
/**
* 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 sampleMimeType The format mime type.
* @param width The width in pixels.
* @param height The height in pixels.
* @param format The format.
* @return A maximum input size in bytes, or {@link Format#NO_VALUE} if a maximum could not be
* determined.
*/
private static int getCodecMaxInputSize(
MediaCodecInfo codecInfo, String sampleMimeType, int width, int height) {
private static int getCodecMaxInputSize(MediaCodecInfo codecInfo, Format format) {
int width = format.width;
int height = format.height;
if (width == Format.NO_VALUE || height == Format.NO_VALUE) {
// We can't infer a maximum input size without video dimensions.
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.
int maxPixels;
int minCompressionRatio;
@ -1513,9 +1530,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
maxPixels = width * height;
minCompressionRatio = 2;
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:
if ("BRAVIA 4K 2015".equals(Util.MODEL) // Sony Bravia 4K
|| ("Amazon".equals(Util.MANUFACTURER)