Skip to content

Commit

Permalink
[XB] Workaround to fix memory issue for Xbox One X (#787)
Browse files Browse the repository at this point in the history
Number of the video decoder output buffers was decreased from 10 to 5

b/268591344

Change-Id: Icbbdab428196c119e606ef7653b3b17a8e9ec846
(cherry picked from commit 0a69bb9)
  • Loading branch information
iuriionishchenko authored and TyHolc committed Jul 27, 2023
1 parent c014690 commit c495e63
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 3 deletions.
7 changes: 4 additions & 3 deletions starboard/shared/win32/video_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,9 @@ void VideoDecoder::InitializeCodec() {

ComPtr<IMFAttributes> attributes = transform->GetAttributes();
SB_DCHECK(attributes);
CheckResult(attributes->SetUINT32(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT,
kMaxOutputSamples));
CheckResult(
attributes->SetUINT32(MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT,
static_cast<UINT32>(GetMaxNumberOfCachedFrames())));

UpdateVideoArea(transform->GetCurrentOutputType());

Expand Down Expand Up @@ -704,7 +705,7 @@ void VideoDecoder::DecoderThreadRun() {
// MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT.
thread_lock_.Acquire();
bool input_full = thread_events_.size() >= kMaxInputSamples;
bool output_full = thread_outputs_.size() >= kMaxOutputSamples;
bool output_full = thread_outputs_.size() >= GetMaxNumberOfCachedFrames();
thread_lock_.Release();

Status status = input_full ? kBufferFull : kNeedMoreInput;
Expand Down
96 changes: 96 additions & 0 deletions starboard/xb1/shared/video_decoder_uwp.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2020 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/xb1/shared/video_decoder_uwp.h"

#include <windows.h>

#include "starboard/shared/uwp/async_utils.h"
#include "starboard/shared/uwp/decoder_utils.h"
#include "third_party/angle/include/angle_hdr.h"

using ::starboard::shared::uwp::ApplicationUwp;
using ::starboard::shared::uwp::UpdateHdrColorMetadataToCurrentDisplay;
using ::starboard::shared::uwp::WaitForComplete;
using Windows::Graphics::Display::Core::HdmiDisplayInformation;

namespace starboard {
namespace xb1 {
namespace shared {

const int kXboxeOneXMaxOutputSamples = 5;

VideoDecoderUwp::~VideoDecoderUwp() {
if (IsHdrSupported() && IsHdrAngleModeEnabled()) {
SetHdrAngleModeEnabled(false);
auto hdmi_display_info = HdmiDisplayInformation::GetForCurrentView();
WaitForComplete(hdmi_display_info->SetDefaultDisplayModeAsync());
}
}

// static
bool VideoDecoderUwp::IsHardwareVp9DecoderSupported() {
return ::starboard::shared::win32::VideoDecoder::
IsHardwareVp9DecoderSupported(ApplicationUwp::Get()->IsHdrSupported());
}

// static
bool VideoDecoderUwp::IsHardwareAv1DecoderSupported() {
// XboxOneS/Base has av1 mft decoder, but sw av1 decoder
// is more preferred for Xbox OneS/Base because of performance.
// So to avoid using av1 mft in these devices we test if
// the current XBOX has vp9 hw decoder. If it doesn't it means
// that there is XboxOneS/Base and we don't use mft av1 decoder.
return VideoDecoderUwp::IsHardwareVp9DecoderSupported() &&
::starboard::shared::win32::IsHardwareAv1DecoderSupported();
}

bool VideoDecoderUwp::TryUpdateOutputForHdrVideo(
const VideoStreamInfo& stream_info) {
bool is_hdr_video =
stream_info.color_metadata.primaries == kSbMediaPrimaryIdBt2020;
if (is_hdr_video && !ApplicationUwp::Get()->IsHdrSupported()) {
return false;
}
if (is_first_input_) {
is_first_input_ = false;
const SbMediaColorMetadata& color_metadata = stream_info.color_metadata;
if (is_hdr_video && IsHdrSupported()) {
if (!IsHdrAngleModeEnabled()) {
SetHdrAngleModeEnabled(true);
}
if (memcmp(&color_metadata, &current_color_metadata_,
sizeof(color_metadata)) != 0) {
current_color_metadata_ = color_metadata;
UpdateHdrColorMetadataToCurrentDisplay(color_metadata);
}
}
}
return true;
}

size_t VideoDecoderUwp::GetPrerollFrameCount() {
return GetMaxNumberOfCachedFrames();
}

size_t VideoDecoderUwp::GetMaxNumberOfCachedFrames() {
return (::starboard::shared::uwp::kXboxOneX ==
::starboard::shared::uwp::GetXboxType())
? kXboxeOneXMaxOutputSamples
: ::starboard::shared::win32::VideoDecoder::GetPrerollFrameCount();
}

} // namespace shared
} // namespace xb1
} // namespace starboard
64 changes: 64 additions & 0 deletions starboard/xb1/shared/video_decoder_uwp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2020 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.

#ifndef STARBOARD_XB1_SHARED_VIDEO_DECODER_UWP_H_
#define STARBOARD_XB1_SHARED_VIDEO_DECODER_UWP_H_

#include "starboard/shared/starboard/media/media_util.h"
#include "starboard/shared/uwp/application_uwp.h"
#include "starboard/shared/uwp/xb1_get_type.h"
#include "starboard/shared/win32/video_decoder.h"

namespace starboard {
namespace xb1 {
namespace shared {

class VideoDecoderUwp : public ::starboard::shared::win32::VideoDecoder {
public:
typedef ::starboard::shared::starboard::media::VideoStreamInfo
VideoStreamInfo;

VideoDecoderUwp::VideoDecoderUwp(
SbMediaVideoCodec video_codec,
SbPlayerOutputMode output_mode,
SbDecodeTargetGraphicsContextProvider* graphics_context_provider,
SbDrmSystem drm_system)
: VideoDecoder(
video_codec,
output_mode,
graphics_context_provider,
drm_system,
::starboard::shared::uwp::ApplicationUwp::Get()->IsHdrSupported()) {
}

~VideoDecoderUwp() override;

static bool IsHardwareVp9DecoderSupported();
static bool IsHardwareAv1DecoderSupported();

bool TryUpdateOutputForHdrVideo(const VideoStreamInfo& stream_info) override;

size_t GetPrerollFrameCount() const override;
size_t GetMaxNumberOfCachedFrames() const override;

private:
SbMediaColorMetadata current_color_metadata_ = {};
bool is_first_input_ = true;
};

} // namespace shared
} // namespace xb1
} // namespace starboard

#endif // STARBOARD_XB1_SHARED_VIDEO_DECODER_UWP_H_

0 comments on commit c495e63

Please sign in to comment.