blob: 10b2a91ea5b53559eb5ff50e5f8e6135374e340e [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/video_capture/lacros/video_frame_handler_proxy_lacros.h"
#include <memory>
#include <utility>
#include "base/notreached.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/mojom/buffer_types.mojom.h"
#include "ui/gfx/mojom/native_handle_types.mojom.h"
namespace video_capture {
namespace {
mojom::ReadyFrameInBufferPtr ToVideoCaptureBuffer(
crosapi::mojom::ReadyFrameInBufferPtr buffer) {
auto video_capture_buffer = mojom::ReadyFrameInBuffer::New();
video_capture_buffer->buffer_id = buffer->buffer_id;
video_capture_buffer->frame_feedback_id = buffer->frame_feedback_id;
mojo::PendingRemote<mojom::ScopedAccessPermission> access_permission;
mojo::MakeSelfOwnedReceiver(
std::make_unique<VideoFrameHandlerProxyLacros::AccessPermissionProxy>(
std::move(buffer->access_permission)),
access_permission.InitWithNewPipeAndPassReceiver());
video_capture_buffer->access_permission = std::move(access_permission);
const auto& buffer_info = buffer->frame_info;
auto video_capture_buffer_info = media::mojom::VideoFrameInfo::New();
video_capture_buffer_info->timestamp = buffer_info->timestamp;
video_capture_buffer_info->pixel_format = buffer_info->pixel_format;
video_capture_buffer_info->coded_size = buffer_info->coded_size;
video_capture_buffer_info->visible_rect = buffer_info->visible_rect;
media::VideoFrameMetadata media_frame_metadata;
switch (buffer_info->rotation) {
case crosapi::mojom::VideoRotation::kVideoRotation0:
media_frame_metadata.transformation =
media::VideoTransformation(media::VideoRotation::VIDEO_ROTATION_0);
break;
case crosapi::mojom::VideoRotation::kVideoRotation90:
media_frame_metadata.transformation =
media::VideoTransformation(media::VideoRotation::VIDEO_ROTATION_90);
break;
case crosapi::mojom::VideoRotation::kVideoRotation180:
media_frame_metadata.transformation =
media::VideoTransformation(media::VideoRotation::VIDEO_ROTATION_180);
break;
case crosapi::mojom::VideoRotation::kVideoRotation270:
media_frame_metadata.transformation =
media::VideoTransformation(media::VideoRotation::VIDEO_ROTATION_270);
break;
default:
NOTREACHED() << "Unexpected rotation in video frame metadata";
}
media_frame_metadata.reference_time = buffer_info->reference_time;
video_capture_buffer_info->metadata = std::move(media_frame_metadata);
video_capture_buffer->frame_info = std::move(video_capture_buffer_info);
return video_capture_buffer;
}
gfx::GpuMemoryBufferHandle ToGfxGpuMemoryBufferHandle(
crosapi::mojom::GpuMemoryBufferHandlePtr buffer_handle) {
gfx::GpuMemoryBufferHandle gfx_buffer_handle;
gfx_buffer_handle.id = gfx::GpuMemoryBufferId(buffer_handle->id);
gfx_buffer_handle.offset = buffer_handle->offset;
gfx_buffer_handle.stride = buffer_handle->stride;
if (buffer_handle->platform_handle) {
auto& platform_handle = buffer_handle->platform_handle;
if (platform_handle->is_shared_memory_handle()) {
gfx_buffer_handle.region =
std::move(platform_handle->get_shared_memory_handle());
} else if (platform_handle->is_native_pixmap_handle()) {
auto& native_pixmap_handle = platform_handle->get_native_pixmap_handle();
gfx::NativePixmapHandle gfx_native_pixmap_handle;
gfx_native_pixmap_handle.planes = std::move(native_pixmap_handle->planes);
gfx_native_pixmap_handle.modifier = native_pixmap_handle->modifier;
gfx_buffer_handle.native_pixmap_handle =
std::move(gfx_native_pixmap_handle);
}
}
return gfx_buffer_handle;
}
} // namespace
VideoFrameHandlerProxyLacros::VideoFrameHandlerProxyLacros(
mojo::PendingReceiver<crosapi::mojom::VideoFrameHandler> proxy_receiver,
mojo::PendingRemote<mojom::VideoFrameHandler> handler_remote)
: handler_(std::move(handler_remote)) {
receiver_.Bind(std::move(proxy_receiver));
}
VideoFrameHandlerProxyLacros::~VideoFrameHandlerProxyLacros() = default;
VideoFrameHandlerProxyLacros::AccessPermissionProxy::AccessPermissionProxy(
mojo::PendingRemote<crosapi::mojom::ScopedAccessPermission> remote)
: remote_(std::move(remote)) {}
VideoFrameHandlerProxyLacros::AccessPermissionProxy::~AccessPermissionProxy() =
default;
void VideoFrameHandlerProxyLacros::OnNewBuffer(
int buffer_id,
crosapi::mojom::VideoBufferHandlePtr buffer_handle) {
media::mojom::VideoBufferHandlePtr media_handle =
media::mojom::VideoBufferHandle::New();
if (buffer_handle->is_shared_buffer_handle()) {
media_handle->set_shared_buffer_handle(
buffer_handle->get_shared_buffer_handle()->Clone(
mojo::SharedBufferHandle::AccessMode::READ_WRITE));
} else if (buffer_handle->is_gpu_memory_buffer_handle()) {
media_handle->set_gpu_memory_buffer_handle(ToGfxGpuMemoryBufferHandle(
std::move(buffer_handle->get_gpu_memory_buffer_handle())));
} else {
NOTREACHED() << "Unexpected new buffer type";
}
handler_->OnNewBuffer(buffer_id, std::move(media_handle));
}
void VideoFrameHandlerProxyLacros::OnFrameReadyInBuffer(
crosapi::mojom::ReadyFrameInBufferPtr buffer,
std::vector<crosapi::mojom::ReadyFrameInBufferPtr> scaled_buffers) {
mojom::ReadyFrameInBufferPtr video_capture_buffer =
ToVideoCaptureBuffer(std::move(buffer));
std::vector<mojom::ReadyFrameInBufferPtr> video_capture_scaled_buffers;
for (auto& b : scaled_buffers)
video_capture_scaled_buffers.push_back(ToVideoCaptureBuffer(std::move(b)));
handler_->OnFrameReadyInBuffer(std::move(video_capture_buffer),
std::move(video_capture_scaled_buffers));
}
void VideoFrameHandlerProxyLacros::OnBufferRetired(int buffer_id) {
handler_->OnBufferRetired(buffer_id);
}
void VideoFrameHandlerProxyLacros::OnError(media::VideoCaptureError error) {
handler_->OnError(error);
}
void VideoFrameHandlerProxyLacros::OnFrameDropped(
media::VideoCaptureFrameDropReason reason) {
handler_->OnFrameDropped(reason);
}
void VideoFrameHandlerProxyLacros::OnLog(const std::string& message) {
handler_->OnLog(message);
}
void VideoFrameHandlerProxyLacros::OnStarted() {
handler_->OnStarted();
}
void VideoFrameHandlerProxyLacros::OnStartedUsingGpuDecode() {
handler_->OnStartedUsingGpuDecode();
}
void VideoFrameHandlerProxyLacros::OnStopped() {
handler_->OnStopped();
}
} // namespace video_capture