osr: Add more info in accelerated callback (fixes #3730)

This commit is contained in:
reito
2024-12-03 12:55:24 -05:00
committed by Marshall Greenblatt
parent 1f48ecb4be
commit 174044c64c
7 changed files with 194 additions and 32 deletions

View File

@@ -99,6 +99,30 @@ void CefVideoConsumerOSR::OnFrameCaptured(
callbacks) {
ScopedVideoFrameDone scoped_done(std::move(callbacks));
media::VideoFrameMetadata metadata = info->metadata;
gfx::Rect damage_rect;
if (bounds_in_pixels_) {
// Use the bounds passed to RequestRefreshFrame().
damage_rect = gfx::Rect(info->coded_size);
damage_rect.Intersect(*bounds_in_pixels_);
bounds_in_pixels_ = std::nullopt;
} else {
// Retrieve the rectangular region of the frame that has changed since the
// frame with the directly preceding CAPTURE_COUNTER. If that frame was not
// received, typically because it was dropped during transport from the
// producer, clients must assume that the entire frame has changed.
// This rectangle is relative to the full frame data, i.e. [0, 0,
// coded_size.width(), coded_size.height()]. It does not have to be
// fully contained within visible_rect.
if (metadata.capture_update_rect) {
damage_rect = *metadata.capture_update_rect;
}
if (damage_rect.IsEmpty()) {
damage_rect = gfx::Rect(info->coded_size);
}
}
// If it is GPU Texture OSR.
if (use_shared_texture_) {
CHECK(data->is_gpu_memory_buffer_handle() &&
@@ -112,24 +136,61 @@ void CefVideoConsumerOSR::OnFrameCaptured(
? CEF_COLOR_TYPE_RGBA_8888
: CEF_COLOR_TYPE_BGRA_8888;
// Build extra common info.
cef_accelerated_paint_info_common_t extra = {};
extra.timestamp = info->timestamp.InMicroseconds();
extra.coded_size = {info->coded_size.width(), info->coded_size.height()};
extra.visible_rect = {info->visible_rect.x(), info->visible_rect.y(),
info->visible_rect.width(),
info->visible_rect.height()};
extra.content_rect = {content_rect.x(), content_rect.y(),
content_rect.width(), content_rect.height()};
extra.timestamp = info->timestamp.InMicroseconds();
extra.has_capture_counter = info->metadata.capture_counter.has_value();
extra.has_capture_update_rect =
info->metadata.capture_update_rect.has_value();
extra.has_region_capture_rect =
info->metadata.region_capture_rect.has_value();
extra.has_source_size = info->metadata.source_size.has_value();
extra.capture_counter = info->metadata.capture_counter.value_or(0);
if (extra.has_capture_update_rect) {
auto rect = info->metadata.capture_update_rect.value();
extra.capture_update_rect = {rect.x(), rect.y(), rect.width(),
rect.height()};
}
if (extra.has_region_capture_rect) {
auto rect = info->metadata.region_capture_rect.value();
extra.region_capture_rect = {rect.x(), rect.y(), rect.width(),
rect.height()};
}
if (extra.has_source_size) {
auto size = info->metadata.source_size.value();
extra.source_size = {size.width(), size.height()};
}
#if BUILDFLAG(IS_WIN)
auto& gmb_handle = data->get_gpu_memory_buffer_handle();
cef_accelerated_paint_info_t paint_info;
paint_info.extra = extra;
paint_info.shared_texture_handle = gmb_handle.dxgi_handle.Get();
paint_info.format = pixel_format;
view_->OnAcceleratedPaint(content_rect, info->coded_size, paint_info);
view_->OnAcceleratedPaint(damage_rect, info->coded_size, paint_info);
#elif BUILDFLAG(IS_APPLE)
auto& gmb_handle = data->get_gpu_memory_buffer_handle();
cef_accelerated_paint_info_t paint_info;
paint_info.extra = extra;
paint_info.shared_texture_io_surface = gmb_handle.io_surface.get();
paint_info.format = pixel_format;
view_->OnAcceleratedPaint(content_rect, info->coded_size, paint_info);
view_->OnAcceleratedPaint(damage_rect, info->coded_size, paint_info);
#elif BUILDFLAG(IS_LINUX)
auto& gmb_handle = data->get_gpu_memory_buffer_handle();
auto& native_pixmap = gmb_handle.native_pixmap_handle;
CHECK(native_pixmap.planes.size() <= kAcceleratedPaintMaxPlanes);
cef_accelerated_paint_info_t paint_info;
paint_info.extra = extra;
paint_info.plane_count = native_pixmap.planes.size();
paint_info.modifier = native_pixmap.modifier;
paint_info.format = pixel_format;
@@ -143,11 +204,12 @@ void CefVideoConsumerOSR::OnFrameCaptured(
cef_plane.fd = plane.fd.get();
paint_info.planes[cef_plain_index++] = cef_plane;
}
view_->OnAcceleratedPaint(content_rect, info->coded_size, paint_info);
view_->OnAcceleratedPaint(damage_rect, info->coded_size, paint_info);
#endif
return;
}
// If it is CPU bitmap OSR.
if (info->pixel_format != media::PIXEL_FORMAT_ARGB) {
DLOG(ERROR) << "Unsupported pixel format " << info->pixel_format;
return;
@@ -179,29 +241,5 @@ void CefVideoConsumerOSR::OnFrameCaptured(
// API requires a non-const pointer. So, cast away the const.
void* const pixels = const_cast<void*>(mapping.memory());
media::VideoFrameMetadata metadata = info->metadata;
gfx::Rect damage_rect;
if (bounds_in_pixels_) {
// Use the bounds passed to RequestRefreshFrame().
damage_rect = gfx::Rect(info->coded_size);
damage_rect.Intersect(*bounds_in_pixels_);
bounds_in_pixels_ = std::nullopt;
} else {
// Retrieve the rectangular region of the frame that has changed since the
// frame with the directly preceding CAPTURE_COUNTER. If that frame was not
// received, typically because it was dropped during transport from the
// producer, clients must assume that the entire frame has changed.
// This rectangle is relative to the full frame data, i.e. [0, 0,
// coded_size.width(), coded_size.height()]. It does not have to be
// fully contained within visible_rect.
if (metadata.capture_update_rect) {
damage_rect = *metadata.capture_update_rect;
}
if (damage_rect.IsEmpty()) {
damage_rect = gfx::Rect(info->coded_size);
}
}
view_->OnPaint(damage_rect, info->coded_size, pixels);
}