diff --git a/starboard/shared/win32/media_transform.cc b/starboard/shared/win32/media_transform.cc index 6367f80d0a6d..11273a80ee3e 100644 --- a/starboard/shared/win32/media_transform.cc +++ b/starboard/shared/win32/media_transform.cc @@ -51,6 +51,9 @@ MediaTransform::MediaTransform(CLSID clsid) if (FAILED(hr) || !transform_) { transform_ = nullptr; state_ = kDrained; + transform_create_error_message_ = + "Could not create decoder transform. " + + ::starboard::shared::win32::HResultToString(hr); } } @@ -310,6 +313,10 @@ HRESULT MediaTransform::SendMessage(MFT_MESSAGE_TYPE msg, return transform_->ProcessMessage(msg, data); } +std::string MediaTransform::GetTransformCreateError() const { + return transform_create_error_message_; +} + void MediaTransform::Reset() { if (stream_begun_) { SendMessage(MFT_MESSAGE_COMMAND_FLUSH); diff --git a/starboard/shared/win32/media_transform.h b/starboard/shared/win32/media_transform.h index ecc9abd81e47..d939998f51d1 100644 --- a/starboard/shared/win32/media_transform.h +++ b/starboard/shared/win32/media_transform.h @@ -20,6 +20,7 @@ #include #include +#include #include #include "starboard/media.h" @@ -84,6 +85,8 @@ class MediaTransform { HRESULT SendMessage(MFT_MESSAGE_TYPE msg, ULONG_PTR data = 0); + std::string GetTransformCreateError() const; + // Reset the media transform to its original state. void Reset(); @@ -106,6 +109,7 @@ class MediaTransform { bool stream_begun_; bool discontinuity_; bool throttle_inputs_; + std::string transform_create_error_message_; }; } // namespace win32 diff --git a/starboard/shared/win32/video_decoder.cc b/starboard/shared/win32/video_decoder.cc index f8890195d88b..fa0c495cb633 100644 --- a/starboard/shared/win32/video_decoder.cc +++ b/starboard/shared/win32/video_decoder.cc @@ -98,10 +98,12 @@ scoped_ptr CreateVideoTransform( const GUID& decoder_guid, const GUID& input_guid, const GUID& output_guid, - const IMFDXGIDeviceManager* device_manager) { + const IMFDXGIDeviceManager* device_manager, + std::string* error_message) { scoped_ptr media_transform(new MediaTransform(decoder_guid)); if (!media_transform->HasValidTransform()) { // Decoder Transform setup failed + *error_message = media_transform->GetTransformCreateError(); return scoped_ptr().Pass(); } media_transform->EnableInputThrottle(true); @@ -109,6 +111,7 @@ scoped_ptr CreateVideoTransform( ComPtr attributes = media_transform->GetAttributes(); if (!attributes) { // Decoder Transform setup failed + *error_message = "Invalid MediaTransform attributes"; return scoped_ptr().Pass(); } @@ -124,6 +127,8 @@ scoped_ptr CreateVideoTransform( hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, FALSE); if (FAILED(hr)) { SB_LOG(WARNING) << "Unable to disable DXVA."; + *error_message = "Unable to disable DXVA. " + + ::starboard::shared::win32::HResultToString(hr); return scoped_ptr().Pass(); } } else { @@ -139,11 +144,13 @@ scoped_ptr CreateVideoTransform( // Tell the decoder to allocate resources for the maximum resolution in // order to minimize glitching on resolution changes. if (FAILED(attributes->SetUINT32(MF_MT_DECODER_USE_MAX_RESOLUTION, 1))) { + *error_message = "Cannot allocate resources for maximum resolution."; return scoped_ptr().Pass(); } ComPtr input_type; if (FAILED(MFCreateMediaType(&input_type)) || !input_type) { + *error_message = "Invalid IMFMediaType."; return scoped_ptr().Pass(); } CheckResult(input_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); @@ -274,11 +281,13 @@ void VideoDecoder::Initialize(const DecoderStatusCB& decoder_status_cb, SB_DCHECK(error_cb); decoder_status_cb_ = decoder_status_cb; error_cb_ = error_cb; + std::string error_message; if (video_device_) { - InitializeCodec(); + InitializeCodec(&error_message); } if (!decoder_) { - error_cb_(kSbPlayerErrorDecode, "Cannot initialize codec."); + error_cb_(kSbPlayerErrorDecode, + "Cannot initialize codec. Error: " + error_message); } } @@ -421,43 +430,49 @@ SbDecodeTarget VideoDecoder::CreateDecodeTarget() { return decode_target; } -void VideoDecoder::InitializeCodec() { +void VideoDecoder::InitializeCodec(std::string* error_message) { scoped_ptr media_transform; // If this is updated then media_is_video_supported.cc also needs to be // updated. switch (video_codec_) { case kSbMediaVideoCodecH264: { - media_transform = - CreateVideoTransform(CLSID_MSH264DecoderMFT, MFVideoFormat_H264, - MFVideoFormat_NV12, device_manager_.Get()); + media_transform = CreateVideoTransform( + CLSID_MSH264DecoderMFT, MFVideoFormat_H264, MFVideoFormat_NV12, + device_manager_.Get(), error_message); priming_output_count_ = 0; if (!media_transform) { SB_LOG(WARNING) << "H264 hardware decoder creation failed."; + *error_message = + "H264 hardware decoder creation failed. " + *error_message; return; } break; } case kSbMediaVideoCodecVp9: { if (IsHardwareVp9DecoderSupported()) { - media_transform = - CreateVideoTransform(CLSID_MSVPxDecoder, MFVideoFormat_VP90, - MFVideoFormat_NV12, device_manager_.Get()); + media_transform = CreateVideoTransform( + CLSID_MSVPxDecoder, MFVideoFormat_VP90, MFVideoFormat_NV12, + device_manager_.Get(), error_message); priming_output_count_ = kVp9PrimingFrameCount; } if (!media_transform) { SB_LOG(WARNING) << "VP9 hardware decoder creation failed."; + *error_message = + "VP9 hardware decoder creation failed. " + *error_message; return; } break; } case kSbMediaVideoCodecAv1: { - media_transform = - CreateVideoTransform(MFVideoFormat_AV1, MFVideoFormat_AV1, - MFVideoFormat_NV12, device_manager_.Get()); + media_transform = CreateVideoTransform( + MFVideoFormat_AV1, MFVideoFormat_AV1, MFVideoFormat_NV12, + device_manager_.Get(), error_message); priming_output_count_ = 0; if (!media_transform) { SB_LOG(WARNING) << "AV1 hardware decoder creation failed."; + *error_message = + "AV1 hardware decoder creation failed. " + *error_message; return; } break; diff --git a/starboard/shared/win32/video_decoder.h b/starboard/shared/win32/video_decoder.h index 8457a23bb6c5..249eda2eeb65 100644 --- a/starboard/shared/win32/video_decoder.h +++ b/starboard/shared/win32/video_decoder.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "starboard/common/mutex.h" #include "starboard/common/ref_counted.h" @@ -100,7 +101,7 @@ class VideoDecoder return true; } - void InitializeCodec(); + void InitializeCodec(std::string* error_message); void ShutdownCodec(); static void ReleaseDecodeTargets(void* context);