Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: chrome/gpu/gpu_arc_video_encode_accelerator.cc

Issue 2892863002: ArcBridge: Add VideoEncodeAccelerator implementation. (Closed)
Patch Set: add missing public_dep to the typemap file. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/gpu/gpu_arc_video_encode_accelerator.h ('k') | components/arc/common/typemaps.gni » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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 "chrome/gpu/gpu_arc_video_encode_accelerator.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "base/sys_info.h"
11 #include "media/base/video_types.h"
12 #include "media/gpu/gpu_video_encode_accelerator_factory.h"
13 #include "mojo/public/cpp/bindings/strong_binding.h"
14 #include "mojo/public/cpp/bindings/type_converter.h"
15 #include "mojo/public/cpp/system/platform_handle.h"
16
17 #define DVLOGF(x) DVLOG(x) << __func__ << "(): "
18
19 namespace chromeos {
20 namespace arc {
21
22 GpuArcVideoEncodeAccelerator::GpuArcVideoEncodeAccelerator(
23 const gpu::GpuPreferences& gpu_preferences)
24 : gpu_preferences_(gpu_preferences) {}
25
26 GpuArcVideoEncodeAccelerator::~GpuArcVideoEncodeAccelerator() = default;
27
28 // VideoEncodeAccelerator::Client implementation.
29 void GpuArcVideoEncodeAccelerator::RequireBitstreamBuffers(
30 unsigned int input_count,
31 const gfx::Size& coded_size,
32 size_t output_buffer_size) {
33 DVLOGF(2) << "input_count=" << input_count
34 << ", coded_size=" << coded_size.ToString()
35 << ", output_buffer_size=" << output_buffer_size;
36 DCHECK(client_);
37 coded_size_ = coded_size;
38 client_->RequireBitstreamBuffers(input_count, coded_size, output_buffer_size);
39 }
40
41 void GpuArcVideoEncodeAccelerator::BitstreamBufferReady(
42 int32_t bitstream_buffer_id,
43 size_t payload_size,
44 bool key_frame,
45 base::TimeDelta timestamp) {
46 DVLOGF(2) << "id=" << bitstream_buffer_id;
47 DCHECK(client_);
48 client_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame,
49 timestamp.InMicroseconds());
50 }
51
52 void GpuArcVideoEncodeAccelerator::NotifyError(Error error) {
53 DVLOGF(2) << "error=" << error;
54 DCHECK(client_);
55 client_->NotifyError(error);
56 }
57
58 // ::arc::mojom::VideoEncodeAccelerator implementation.
59 void GpuArcVideoEncodeAccelerator::GetSupportedProfiles(
60 const GetSupportedProfilesCallback& callback) {
61 callback.Run(media::GpuVideoEncodeAcceleratorFactory::GetSupportedProfiles(
62 gpu_preferences_));
63 }
64
65 void GpuArcVideoEncodeAccelerator::Initialize(
66 VideoPixelFormat input_format,
67 const gfx::Size& visible_size,
68 VideoEncodeAccelerator::StorageType input_storage,
69 VideoCodecProfile output_profile,
70 uint32_t initial_bitrate,
71 VideoEncodeClientPtr client,
72 const InitializeCallback& callback) {
73 DVLOGF(2) << "visible_size=" << visible_size.ToString()
74 << ", profile=" << output_profile;
75
76 input_pixel_format_ = input_format;
77 visible_size_ = visible_size;
78 accelerator_ = media::GpuVideoEncodeAcceleratorFactory::CreateVEA(
79 input_pixel_format_, visible_size_, output_profile, initial_bitrate, this,
80 gpu_preferences_);
81 if (accelerator_ == nullptr) {
82 DLOG(ERROR) << "Failed to create a VideoEncodeAccelerator.";
83 callback.Run(false);
84 return;
85 }
86 client_ = std::move(client);
87 callback.Run(true);
88 }
89
90 static void DropSharedMemory(std::unique_ptr<base::SharedMemory> shm) {
91 // Just let |shm| fall out of scope.
92 }
93
94 void GpuArcVideoEncodeAccelerator::Encode(
95 mojo::ScopedHandle handle,
96 std::vector<::arc::VideoFramePlane> planes,
97 int64_t timestamp,
98 bool force_keyframe) {
99 DVLOGF(2) << "timestamp=" << timestamp;
100 if (!accelerator_) {
101 DLOG(ERROR) << "Accelerator is not initialized.";
102 return;
103 }
104
105 if (planes.empty()) { // EOS
106 accelerator_->Encode(media::VideoFrame::CreateEOSFrame(), force_keyframe);
107 return;
108 }
109
110 base::ScopedFD fd = UnwrapFdFromMojoHandle(std::move(handle));
111 if (!fd.is_valid())
112 return;
113
114 size_t allocation_size =
115 media::VideoFrame::AllocationSize(input_pixel_format_, coded_size_);
116
117 // TODO(rockot): Pass GUIDs through Mojo. https://crbug.com/713763.
118 // TODO(rockot): This fd comes from a mojo::ScopedHandle in
119 // GpuArcVideoService::BindSharedMemory. That should be passed through,
120 // rather than pulling out the fd. https://crbug.com/713763.
121 // TODO(rockot): Pass through a real size rather than |0|.
122 base::UnguessableToken guid = base::UnguessableToken::Create();
123 base::SharedMemoryHandle shm_handle(base::FileDescriptor(fd.release(), true),
124 0u, guid);
125 auto shm = base::MakeUnique<base::SharedMemory>(shm_handle, true);
126
127 base::CheckedNumeric<off_t> map_offset = planes[0].offset;
128 base::CheckedNumeric<size_t> map_size = allocation_size;
129 const uint32_t aligned_offset =
130 planes[0].offset % base::SysInfo::VMAllocationGranularity();
131 map_offset -= aligned_offset;
132 map_size += aligned_offset;
133
134 if (!map_offset.IsValid() || !map_size.IsValid()) {
135 DLOG(ERROR) << "Invalid map_offset or map_size";
136 client_->NotifyError(Error::kInvalidArgumentError);
137 return;
138 }
139 if (!shm->MapAt(map_offset.ValueOrDie(), map_size.ValueOrDie())) {
140 DLOG(ERROR) << "Failed to map memory.";
141 client_->NotifyError(Error::kPlatformFailureError);
142 return;
143 }
144
145 uint8_t* shm_memory = reinterpret_cast<uint8_t*>(shm->memory());
146 auto frame = media::VideoFrame::WrapExternalSharedMemory(
147 input_pixel_format_, coded_size_, gfx::Rect(visible_size_), visible_size_,
148 shm_memory + aligned_offset, allocation_size, shm_handle,
149 planes[0].offset, base::TimeDelta::FromMicroseconds(timestamp));
150
151 // Wrap |shm| in a callback and add it as a destruction observer, so it
152 // stays alive and mapped until |frame| goes out of scope.
153 frame->AddDestructionObserver(
154 base::Bind(&DropSharedMemory, base::Passed(&shm)));
155 accelerator_->Encode(frame, force_keyframe);
156 }
157
158 void GpuArcVideoEncodeAccelerator::UseOutputBitstreamBuffer(
159 int32_t bitstream_buffer_id,
160 mojo::ScopedHandle shmem_fd,
161 uint32_t offset,
162 uint32_t size) {
163 DVLOGF(2) << "id=" << bitstream_buffer_id;
164 if (!accelerator_) {
165 DLOG(ERROR) << "Accelerator is not initialized.";
166 return;
167 }
168
169 base::ScopedFD fd = UnwrapFdFromMojoHandle(std::move(shmem_fd));
170 if (!fd.is_valid())
171 return;
172
173 // TODO(rockot): Pass GUIDs through Mojo. https://crbug.com/713763.
174 // TODO(rockot): This fd comes from a mojo::ScopedHandle in
175 // GpuArcVideoService::BindSharedMemory. That should be passed through,
176 // rather than pulling out the fd. https://crbug.com/713763.
177 // TODO(rockot): Pass through a real size rather than |0|.
178 base::UnguessableToken guid = base::UnguessableToken::Create();
179 base::SharedMemoryHandle shm_handle(base::FileDescriptor(fd.release(), true),
180 0u, guid);
181 accelerator_->UseOutputBitstreamBuffer(
182 media::BitstreamBuffer(bitstream_buffer_id, shm_handle, size, offset));
183 }
184
185 void GpuArcVideoEncodeAccelerator::RequestEncodingParametersChange(
186 uint32_t bitrate,
187 uint32_t framerate) {
188 DVLOGF(2) << "bitrate=" << bitrate << ", framerate=" << framerate;
189 if (!accelerator_) {
190 DLOG(ERROR) << "Accelerator is not initialized.";
191 return;
192 }
193 accelerator_->RequestEncodingParametersChange(bitrate, framerate);
194 }
195
196 base::ScopedFD GpuArcVideoEncodeAccelerator::UnwrapFdFromMojoHandle(
197 mojo::ScopedHandle handle) {
198 DCHECK(client_);
199 if (!handle.is_valid()) {
200 DLOG(ERROR) << "handle is invalid.";
201 client_->NotifyError(Error::kInvalidArgumentError);
202 return base::ScopedFD();
203 }
204
205 base::PlatformFile platform_file;
206 MojoResult mojo_result =
207 mojo::UnwrapPlatformFile(std::move(handle), &platform_file);
208 if (mojo_result != MOJO_RESULT_OK) {
209 DLOG(ERROR) << "UnwrapPlatformFile failed: " << mojo_result;
210 client_->NotifyError(Error::kPlatformFailureError);
211 return base::ScopedFD();
212 }
213
214 return base::ScopedFD(platform_file);
215 }
216
217 } // namespace arc
218 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/gpu/gpu_arc_video_encode_accelerator.h ('k') | components/arc/common/typemaps.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698