0

[media] Use WrapMappableSharedImage in VideoFrame mojom

Update SharedImageVideoFrameData mojom struct to take in
is_mappable_si_enabled passed in by the VideoFrame to check for
mappable shared image support. Based on the flag, use
WrapMappableSharedImage to create a mappable VideoFrame passing in
the ExportedSharedImage that contains the GpuMemoryBufferHandle.

Make this conversion behind a killswitch to guard against rollout
issues.

Bug: 391865297
Change-Id: Iba04429ce1d09bddc21cdb977edf9bd705c03511
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6287668
Commit-Queue: vikas soni <vikassoni@chromium.org>
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: Eugene Zemtsov <eugene@chromium.org>
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: vikas soni <vikassoni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1423518}
This commit is contained in:
Saifuddin Hitawala
2025-02-21 18:27:39 -08:00
committed by Chromium LUCI CQ
parent 7833b9b41d
commit ae53187242
6 changed files with 62 additions and 9 deletions

@ -319,6 +319,7 @@ ClientSharedImage::ClientSharedImage(
: mailbox_(exported_si.mailbox_),
metadata_(exported_si.metadata_),
creation_sync_token_(exported_si.creation_sync_token_),
buffer_usage_(exported_si.buffer_usage_),
sii_holder_(std::move(sii_holder)),
texture_target_(exported_si.texture_target_) {
if (exported_si.buffer_handle_) {
@ -330,10 +331,10 @@ ClientSharedImage::ClientSharedImage(
#endif
gpu_memory_buffer_ =
GpuMemoryBufferSupport().CreateGpuMemoryBufferImplFromHandle(
std::move(*exported_si.buffer_handle_), metadata_.size,
std::move(exported_si.buffer_handle_.value()), metadata_.size,
viz::SharedImageFormatToBufferFormatRestrictedUtils::ToBufferFormat(
metadata_.format),
*exported_si.buffer_usage_, base::DoNothing(),
exported_si.buffer_usage_.value(), base::DoNothing(),
gpu_memory_buffer_manager_.get());
}
CHECK(!mailbox_.IsZero());
@ -347,6 +348,7 @@ ClientSharedImage::ClientSharedImage(ExportedSharedImage exported_si)
: mailbox_(exported_si.mailbox_),
metadata_(exported_si.metadata_),
creation_sync_token_(exported_si.creation_sync_token_),
buffer_usage_(exported_si.buffer_usage_),
texture_target_(exported_si.texture_target_) {
if (exported_si.buffer_handle_) {
#if BUILDFLAG(IS_WIN)
@ -357,10 +359,10 @@ ClientSharedImage::ClientSharedImage(ExportedSharedImage exported_si)
#endif
gpu_memory_buffer_ =
GpuMemoryBufferSupport().CreateGpuMemoryBufferImplFromHandle(
std::move(*exported_si.buffer_handle_), metadata_.size,
std::move(exported_si.buffer_handle_.value()), metadata_.size,
viz::SharedImageFormatToBufferFormatRestrictedUtils::ToBufferFormat(
metadata_.format),
*exported_si.buffer_usage_, base::DoNothing(),
exported_si.buffer_usage_.value(), base::DoNothing(),
gpu_memory_buffer_manager_.get());
}
CHECK(!mailbox_.IsZero());

@ -1684,6 +1684,12 @@ BASE_FEATURE(kRenderMutedAudio,
"RenderMutedAudio",
base::FEATURE_ENABLED_BY_DEFAULT);
// Serves as killswitch for rolling out Mappable SharedImage mojom support.
// TODO(crbug.com/40263579): Eliminate post safe rollout.
BASE_FEATURE(kSupportMappableSharedImageOverMojo,
"SupportMappableSharedImageOverMojo",
base::FEATURE_ENABLED_BY_DEFAULT);
bool IsChromeWideEchoCancellationEnabled() {
#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
return base::FeatureList::IsEnabled(kChromeWideEchoCancellation) &&

@ -533,6 +533,10 @@ MEDIA_EXPORT BASE_DECLARE_FEATURE(kMediaFoundationSharedImageEncode);
MEDIA_EXPORT BASE_DECLARE_FEATURE(kRenderMutedAudio);
// Serves as killswitch for rolling out Mappable SharedImage mojom support.
// TODO(crbug.com/40263579): Eliminate post safe rollout.
MEDIA_EXPORT BASE_DECLARE_FEATURE(kSupportMappableSharedImageOverMojo);
// Based on a |command_line| and the current platform, returns the effective
// autoplay policy. In other words, it will take into account the default policy
// if none is specified via the command line and options passed for testing.

@ -709,6 +709,8 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
return const_cast<uint8_t*>(data(plane));
}
bool is_mappable_si_enabled() const { return is_mappable_si_enabled_; }
const std::optional<gpu::VulkanYCbCrInfo>& ycbcr_info() const {
return wrapped_frame_ ? wrapped_frame_->ycbcr_info() : ycbcr_info_;
}

@ -496,6 +496,9 @@ struct GpuMemoryBufferSharedImageVideoFrameData {
struct SharedImageVideoFrameData {
gpu.mojom.ExportedSharedImage shared_image;
gpu.mojom.SyncToken sync_token;
// TODO(crbug.com/40263579): Remove this bool once all VideoFrame
// clients use MappableSI.
bool is_mappable_si_enabled;
// |ycbcr_data| is present on Android (and sometimes Fuchsia) when the
// video is hardware decoded and the display compositor uses Vulkan.
gpu.mojom.VulkanYCbCrInfo? ycbcr_data;

@ -7,6 +7,7 @@
#include <utility>
#include <vector>
#include "base/feature_list.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/unsafe_shared_memory_region.h"
@ -15,6 +16,7 @@
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
#include "media/base/color_plane_layout.h"
#include "media/base/format_utils.h"
#include "media/base/media_switches.h"
#include "media/mojo/mojom/video_frame_metadata_mojom_traits.h"
#include "mojo/public/cpp/base/time_mojom_traits.h"
#include "mojo/public/cpp/system/handle.h"
@ -30,6 +32,12 @@ namespace mojo {
namespace {
// Determines whether Mappable SharedImage over mojo is supported.
bool SupportMappableSI() {
return base::FeatureList::IsEnabled(
media::kSupportMappableSharedImageOverMojo);
}
base::ReadOnlySharedMemoryRegion CreateRegion(const media::VideoFrame& frame,
std::vector<uint32_t>& offsets,
std::vector<int32_t>& strides) {
@ -115,6 +123,7 @@ media::mojom::VideoFrameDataPtr MakeVideoFrameData(
std::move(region), std::move(strides), std::move(offsets)));
}
bool is_mappable_si_enabled = input->is_mappable_si_enabled();
if (input->HasMappableGpuBuffer()) {
auto gpu_memory_buffer_handle = input->GetGpuMemoryBufferHandle();
@ -122,8 +131,16 @@ media::mojom::VideoFrameDataPtr MakeVideoFrameData(
std::optional<gpu::ExportedSharedImage> shared_image;
gpu::SyncToken sync_token;
if (input->HasSharedImage()) {
shared_image = input->shared_image()->Export();
bool with_buffer_handle = is_mappable_si_enabled && SupportMappableSI();
shared_image = input->shared_image()->Export(with_buffer_handle);
sync_token = input->acquire_sync_token();
if (with_buffer_handle) {
return media::mojom::VideoFrameData::NewSharedImageData(
media::mojom::SharedImageVideoFrameData::New(
std::move(shared_image.value()), std::move(sync_token),
is_mappable_si_enabled, std::move(input->ycbcr_info())));
}
}
return media::mojom::VideoFrameData::NewGpuMemoryBufferSharedImageData(
@ -133,11 +150,14 @@ media::mojom::VideoFrameDataPtr MakeVideoFrameData(
}
if (input->HasSharedImage()) {
// Mappable SI should only be used with `HasMappableGpuBuffer()`
// VideoFrames.
CHECK(!is_mappable_si_enabled);
gpu::ExportedSharedImage shared_image = input->shared_image()->Export();
return media::mojom::VideoFrameData::NewSharedImageData(
media::mojom::SharedImageVideoFrameData::New(
std::move(shared_image), input->acquire_sync_token(),
std::move(input->ycbcr_info())));
/*is_mappable_si_enabled=*/false, std::move(input->ycbcr_info())));
}
if (input->storage_type() == media::VideoFrame::STORAGE_OPAQUE) {
@ -341,9 +361,25 @@ bool StructTraits<media::mojom::VideoFrameDataView,
return false;
}
frame = media::VideoFrame::WrapSharedImage(
format, shared_image, sync_token, media::VideoFrame::ReleaseMailboxCB(),
coded_size, visible_rect, natural_size, timestamp);
bool is_mappable_si_enabled = shared_image_data.is_mappable_si_enabled();
if (is_mappable_si_enabled && SupportMappableSI()) {
// VideoFrame should have buffer usage if Mappable SharedImage is enabled.
// NOTE: This isn't exactly correct for software SharedImages can be
// mappable but do not have buffer usage. But since, such software
// SharedImages are not used with VideoFrames this should work.
if (!shared_image->buffer_usage().has_value()) {
return false;
}
frame = media::VideoFrame::WrapMappableSharedImage(
shared_image, sync_token,
media::VideoFrame::ReleaseMailboxAndGpuMemoryBufferCB(), visible_rect,
natural_size, timestamp);
} else {
frame = media::VideoFrame::WrapSharedImage(
format, shared_image, sync_token,
media::VideoFrame::ReleaseMailboxCB(), coded_size, visible_rect,
natural_size, timestamp);
}
frame->set_ycbcr_info(ycbcr_info);
} else if (data.is_opaque_data()) {