Skip to content

Commit

Permalink
Pass transfer id to SbMediaIsVideoSupported
Browse files Browse the repository at this point in the history
Pass transfer id to SbMediaIsVideoSupported to allow platforms to
express support of eotf in combination with resolution, fps, etc.

b/37353136

Change-Id: Id4533dd7b231d9dbc214126ac807cc79de96dc30
  • Loading branch information
joe-woodworth authored and briantting committed Aug 27, 2018
1 parent 7c90c94 commit afd3f68
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,15 @@ public static MediaCodecBridge createVideoMediaCodecBridge(
MediaCrypto crypto,
ColorInfo colorInfo) {
MediaCodec mediaCodec = null;

boolean findHDRDecoder = android.os.Build.VERSION.SDK_INT >= 24 && colorInfo != null;
// On first pass, try to find a decoder with HDR if the color info is non-null.
MediaCodecUtil.FindVideoDecoderResult findVideoDecoderResult =
MediaCodecUtil.findVideoDecoder(mime, isSecure, 0, 0, 0, 0);
MediaCodecUtil.findVideoDecoder(mime, isSecure, 0, 0, 0, 0, findHDRDecoder);
if (findVideoDecoderResult.name.equals("") && findHDRDecoder) {
// On second pass, forget HDR.
findVideoDecoderResult = MediaCodecUtil.findVideoDecoder(mime, isSecure, 0, 0, 0, 0, false);
}
try {
String decoderName = findVideoDecoderResult.name;
if (decoderName.equals("") || findVideoDecoderResult.videoCapabilities == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,17 @@ private MediaCodecUtil() {}
@SuppressWarnings("unused")
@UsedByNative
public static boolean hasVideoDecoderFor(
String mimeType, boolean secure, int frameWidth, int frameHeight, int bitrate, int fps) {
return !findVideoDecoder(mimeType, secure, frameWidth, frameHeight, bitrate, fps)
.name
.equals("");
String mimeType,
boolean secure,
int frameWidth,
int frameHeight,
int bitrate,
int fps,
boolean mustSupportHdr) {
FindVideoDecoderResult findVideoDecoderResult =
findVideoDecoder(mimeType, secure, frameWidth, frameHeight, bitrate, fps, mustSupportHdr);
return !findVideoDecoderResult.name.equals("")
&& (!mustSupportHdr || isHdrCapableVp9Decoder(findVideoDecoderResult));
}

/**
Expand All @@ -406,16 +413,8 @@ public static boolean hasHdrCapableVp9Decoder() {
return false;
}

// Ideally we would just add this as a parameter to |findVideoDecoder|,
// however the shared starboard player implementation of
// |CanPlayMimeAndKeySystem| will call
// |SbMediaIsTransferCharacteristicsSupported| as a separate function. We
// make the reasonable assumption that no system will have two hardware
// VP9 decoders with one capable of playing HDR at lower
// resolutions/bitrates, and another not capable of playing HDR at higher
// resolutions/bitrates.
FindVideoDecoderResult findVideoDecoderResult =
findVideoDecoder(VP9_MIME_TYPE, false, 0, 0, 0, 0);
findVideoDecoder(VP9_MIME_TYPE, false, 0, 0, 0, 0, true);
return isHdrCapableVp9Decoder(findVideoDecoderResult);
}

Expand Down Expand Up @@ -444,7 +443,13 @@ public static boolean isHdrCapableVp9Decoder(FindVideoDecoderResult findVideoDec
* "" otherwise.
*/
public static FindVideoDecoderResult findVideoDecoder(
String mimeType, boolean secure, int frameWidth, int frameHeight, int bitrate, int fps) {
String mimeType,
boolean secure,
int frameWidth,
int frameHeight,
int bitrate,
int fps,
boolean hdr) {
Log.v(
TAG,
String.format(
Expand Down Expand Up @@ -560,8 +565,13 @@ public static FindVideoDecoderResult findVideoDecoder(
(secure && !name.endsWith(SECURE_DECODER_SUFFIX))
? (name + SECURE_DECODER_SUFFIX)
: name;
FindVideoDecoderResult findVideoDecoderResult =
new FindVideoDecoderResult(resultName, videoCapabilities, codecCapabilities);
if (hdr && !isHdrCapableVp9Decoder(findVideoDecoderResult)) {
continue;
}
Log.v(TAG, String.format("Found suitable decoder, %s", name));
return new FindVideoDecoderResult(resultName, videoCapabilities, codecCapabilities);
return findVideoDecoderResult;
}
}
return new FindVideoDecoderResult("", null, null);
Expand Down
4 changes: 4 additions & 0 deletions starboard/android/shared/configuration_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@
// stack size for media stack threads.
#define SB_MEDIA_THREAD_STACK_SIZE 0U

// SbMediaTransferId argument |eotf| to SbMediaIsVideoSupported and remove the
// function SbMediaIsTransferCharacteristicsSupported.
#define SB_HAS_MEDIA_EOTF_CHECK_SUPPORT 1

// --- Decoder-only Params ---

// Specifies how media buffers must be aligned on this platform as some
Expand Down
52 changes: 49 additions & 3 deletions starboard/android/shared/media_is_video_supported.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,55 @@ using starboard::android::shared::JniEnvExt;
using starboard::android::shared::ScopedLocalJavaRef;
using starboard::android::shared::SupportedVideoCodecToMimeType;

namespace {

// https://developer.android.com/reference/android/view/Display.HdrCapabilities.html#HDR_TYPE_HDR10
const jint HDR_TYPE_DOLBY_VISION = 1;
const jint HDR_TYPE_HDR10 = 2;
const jint HDR_TYPE_HLG = 3;

bool IsTransferCharacteristicsSupported(SbMediaTransferId transfer_id) {
// Bt709 and unspecified are assumed to always be supported.
if (transfer_id == kSbMediaTransferIdBt709 ||
transfer_id == kSbMediaTransferIdUnspecified) {
return true;
}
// An HDR capable VP9 decoder is needed to handle HDR at all.
bool has_hdr_capable_vp9_decoder =
JniEnvExt::Get()->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasHdrCapableVp9Decoder",
"()Z") == JNI_TRUE;
if (!has_hdr_capable_vp9_decoder) {
return false;
}

jint hdr_type;
if (transfer_id == kSbMediaTransferIdSmpteSt2084) {
hdr_type = HDR_TYPE_HDR10;
} else if (transfer_id == kSbMediaTransferIdAribStdB67) {
hdr_type = HDR_TYPE_HLG;
} else {
// No other transfer functions are supported, see
// https://source.android.com/devices/tech/display/hdr.
return false;
}

return JniEnvExt::Get()->CallStarboardBooleanMethodOrAbort(
"isHdrTypeSupported", "(I)Z", hdr_type) == JNI_TRUE;
}

} // namespace

SB_EXPORT bool SbMediaIsVideoSupported(SbMediaVideoCodec video_codec,
int frame_width,
int frame_height,
int64_t bitrate,
int fps,
bool decode_to_texture_required) {
bool decode_to_texture_required,
SbMediaTransferId eotf) {
if (!IsTransferCharacteristicsSupported(eotf)) {
return false;
}
// While not necessarily true, for now we assume that all Android devices
// can play decode-to-texture video just as well as normal video.
SB_UNREFERENCED_PARAMETER(decode_to_texture_required);
Expand All @@ -40,8 +83,11 @@ SB_EXPORT bool SbMediaIsVideoSupported(SbMediaVideoCodec video_codec,
}
JniEnvExt* env = JniEnvExt::Get();
ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
bool must_support_hdr = (eotf != kSbMediaTransferIdBt709 &&
eotf != kSbMediaTransferIdUnspecified);
return env->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasVideoDecoderFor",
"(Ljava/lang/String;ZIIII)Z", j_mime.Get(), false, frame_width,
frame_height, static_cast<jint>(bitrate), fps) == JNI_TRUE;
"(Ljava/lang/String;ZIIIIZ)Z", j_mime.Get(), false, frame_width,
frame_height, static_cast<jint>(bitrate), fps,
must_support_hdr) == JNI_TRUE;
}
1 change: 0 additions & 1 deletion starboard/android/shared/starboard_platform.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@
'media_is_audio_supported.cc',
'media_is_output_protected.cc',
'media_is_supported.cc',
'media_is_transfer_characteristics_supported.cc',
'media_is_video_supported.cc',
'media_set_output_protection.cc',
'microphone_impl.cc',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ SbMediaSupportType CanPlayProgressiveVideo(const MimeType& mime_type,
,
decode_to_texture_required
#endif // SB_API_VERSION >= 10
#if SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
,
kSbMediaTransferIdUnspecified
#endif // SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
)) {
return kSbMediaSupportTypeNotSupported;
}
Expand Down Expand Up @@ -203,9 +207,12 @@ SbMediaSupportType CanPlayMimeAndKeySystem(const MimeType& mime_type,
}

std::string eotf = mime_type.GetParamStringValue("eotf", "");
SbMediaTransferId transfer_id = kSbMediaTransferIdUnspecified;
if (!eotf.empty()) {
SbMediaTransferId transfer_id = GetTransferIdFromString(eotf);
if (!SbMediaIsTransferCharacteristicsSupported(transfer_id)) {
transfer_id = GetTransferIdFromString(eotf);
// If the eotf is not known, reject immediately - without checking with
// the platform.
if (transfer_id == kSbMediaTransferIdUnknown) {
return kSbMediaSupportTypeNotSupported;
}
}
Expand Down Expand Up @@ -239,6 +246,10 @@ SbMediaSupportType CanPlayMimeAndKeySystem(const MimeType& mime_type,
,
decode_to_texture_required
#endif // SB_API_VERSION >= 10
#if SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
,
transfer_id
#endif // SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
)) {
return kSbMediaSupportTypeProbably;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/starboard/media/media_support_internal.h"

#include "starboard/media.h"

#if !SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
SB_EXPORT bool SbMediaIsTransferCharacteristicsSupported(
SbMediaTransferId transfer_id) {
return transfer_id == kSbMediaTransferIdBt709 ||
transfer_id == kSbMediaTransferIdUnspecified;
}
#endif // !SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
6 changes: 6 additions & 0 deletions starboard/shared/starboard/media/media_support_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ SB_EXPORT bool SbMediaIsVideoSupported(SbMediaVideoCodec video_codec,
,
bool decode_to_texture_required
#endif // SB_API_VERSION >= 10
#if SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
,
SbMediaTransferId eotf
#endif // SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
);

// Indicates whether this platform supports |audio_codec| at |bitrate|.
Expand All @@ -57,13 +61,15 @@ SB_EXPORT bool SbMediaIsVideoSupported(SbMediaVideoCodec video_codec,
SB_EXPORT bool SbMediaIsAudioSupported(SbMediaAudioCodec audio_codec,
int64_t bitrate);

#if !SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
// Indicates whether this platform supports |transfer_id| as a transfer
// characteristics. If |transfer_id| is not supported under any condition, this
// function returns |false|.
//
// |transfer_id|: The id of transfer charateristics listed in SbMediaTransferId.
SB_EXPORT bool SbMediaIsTransferCharacteristicsSupported(
SbMediaTransferId transfer_id);
#endif // !SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)

#ifdef __cplusplus
} // extern "C"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,10 @@ std::vector<TestParam> GetSupportedTests() {
,
false
#endif // SB_API_VERSION >= 10
#if SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
,
kSbMediaTransferIdUnspecified
#endif // SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
)) {
test_params.push_back({output_mode, filename});
}
Expand Down
4 changes: 4 additions & 0 deletions starboard/shared/starboard/player/player_create.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ SbPlayer SbPlayerCreate(SbWindow window,
,
output_mode == kSbPlayerOutputModeDecodeToTexture
#endif
#if SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
,
kSbMediaTransferIdUnspecified
#endif // SB_HAS(MEDIA_EOTF_CHECK_SUPPORT)
)) {
SB_LOG(ERROR) << "Unsupported video codec " << video_codec;
return kSbPlayerInvalid;
Expand Down

0 comments on commit afd3f68

Please sign in to comment.