1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/capture/video/gpu_memory_buffer_utils.h"
6
7 #include "base/bind_helpers.h"
8 #include "gpu/ipc/common/gpu_memory_buffer_support.h"
9 #include "ui/gfx/gpu_memory_buffer.h"
10
11 namespace media {
12
ScopedNV12GpuMemoryBufferMapping(std::unique_ptr<gfx::GpuMemoryBuffer> gmb)13 ScopedNV12GpuMemoryBufferMapping::ScopedNV12GpuMemoryBufferMapping(
14 std::unique_ptr<gfx::GpuMemoryBuffer> gmb)
15 : gmb_(std::move(gmb)) {
16 gmb_->Map();
17 }
18
~ScopedNV12GpuMemoryBufferMapping()19 ScopedNV12GpuMemoryBufferMapping::~ScopedNV12GpuMemoryBufferMapping() {
20 gmb_->Unmap();
21 }
22
y_plane()23 uint8_t* ScopedNV12GpuMemoryBufferMapping::y_plane() {
24 return static_cast<uint8_t*>(gmb_->memory(0));
25 }
26
uv_plane()27 uint8_t* ScopedNV12GpuMemoryBufferMapping::uv_plane() {
28 return static_cast<uint8_t*>(gmb_->memory(1));
29 }
30
y_stride()31 size_t ScopedNV12GpuMemoryBufferMapping::y_stride() {
32 return gmb_->stride(0);
33 }
34
uv_stride()35 size_t ScopedNV12GpuMemoryBufferMapping::uv_stride() {
36 return gmb_->stride(1);
37 }
38
AllocateNV12GpuMemoryBuffer(VideoCaptureDevice::Client * capture_client,const gfx::Size & buffer_size,gpu::GpuMemoryBufferSupport * gmb_support,std::unique_ptr<gfx::GpuMemoryBuffer> * out_gpu_memory_buffer,VideoCaptureDevice::Client::Buffer * out_capture_buffer)39 VideoCaptureDevice::Client::ReserveResult AllocateNV12GpuMemoryBuffer(
40 VideoCaptureDevice::Client* capture_client,
41 const gfx::Size& buffer_size,
42 gpu::GpuMemoryBufferSupport* gmb_support,
43 std::unique_ptr<gfx::GpuMemoryBuffer>* out_gpu_memory_buffer,
44 VideoCaptureDevice::Client::Buffer* out_capture_buffer) {
45 CHECK(out_gpu_memory_buffer);
46 CHECK(out_capture_buffer);
47
48 // When GpuMemoryBuffer is used, the frame data is opaque to the CPU for most
49 // of the time. Currently the only supported underlying format is NV12.
50 constexpr VideoPixelFormat kOpaqueVideoFormat = PIXEL_FORMAT_NV12;
51 constexpr gfx::BufferFormat kOpaqueGfxFormat =
52 gfx::BufferFormat::YUV_420_BIPLANAR;
53
54 const int arbitrary_frame_feedback_id = 0;
55 const auto reserve_result = capture_client->ReserveOutputBuffer(
56 buffer_size, kOpaqueVideoFormat, arbitrary_frame_feedback_id,
57 out_capture_buffer);
58 if (reserve_result != VideoCaptureDevice::Client::ReserveResult::kSucceeded) {
59 return reserve_result;
60 }
61
62 *out_gpu_memory_buffer = gmb_support->CreateGpuMemoryBufferImplFromHandle(
63 out_capture_buffer->handle_provider->GetGpuMemoryBufferHandle(),
64 buffer_size, kOpaqueGfxFormat,
65 gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, base::NullCallback());
66 return reserve_result;
67 }
68
69 } // namespace media
70