mirror of
https://github.com/androidx/media.git
synced 2025-05-08 08:00:49 +08:00
Size dolby vision buffers for H265 by default
PiperOrigin-RevId: 391965200
This commit is contained in:
parent
082542c152
commit
03d0b34ab9
@ -17,8 +17,10 @@
|
|||||||
calls from the player to `Surface.setFrameRate`. This is useful for
|
calls from the player to `Surface.setFrameRate`. This is useful for
|
||||||
applications wanting to call `Surface.setFrameRate` directly from
|
applications wanting to call `Surface.setFrameRate` directly from
|
||||||
application code with Android 12's `Surface.CHANGE_FRAME_RATE_ALWAYS`.
|
application code with Android 12's `Surface.CHANGE_FRAME_RATE_ALWAYS`.
|
||||||
* GVR extension:
|
* Video
|
||||||
* Remove `GvrAudioProcessor`, which has been deprecated since 2.11.0.
|
* 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
|
* UI
|
||||||
* `SubtitleView` no longer implements `TextOutput`. `SubtitleView`
|
* `SubtitleView` no longer implements `TextOutput`. `SubtitleView`
|
||||||
implements `Player.Listener`, so can be registered to a player with
|
implements `Player.Listener`, so can be registered to a player with
|
||||||
@ -41,6 +43,8 @@
|
|||||||
`VideoListener`. Use `Player.addListener` and `Player.Listener` instead.
|
`VideoListener`. Use `Player.addListener` and `Player.Listener` instead.
|
||||||
* Remove `DefaultHttpDataSourceFactory`. Use
|
* Remove `DefaultHttpDataSourceFactory`. Use
|
||||||
`DefaultHttpDataSource.Factory` instead.
|
`DefaultHttpDataSource.Factory` instead.
|
||||||
|
* Remove `GvrAudioProcessor` and the GVR extension, which has been
|
||||||
|
deprecated since 2.11.0.
|
||||||
|
|
||||||
### 2.15.0 (2021-08-10)
|
### 2.15.0 (2021-08-10)
|
||||||
|
|
||||||
|
@ -1364,8 +1364,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
|
||||||
@ -1402,7 +1401,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1481,29 +1481,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;
|
||||||
@ -1513,9 +1530,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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user