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

Side by Side Diff: media/gpu/mojo/service/gpu_jpeg_decode_accelerator.cc

Issue 2923933004: [NotForReview] Move GJDAH and GJDA to media/gpu/mojo
Patch Set: . Created 3 years, 6 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
OLDNEW
(Empty)
1 // Copyright 2015 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/gpu/mojo/service/gpu_jpeg_decode_accelerator.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10 #include <utility>
11
12 #include "base/command_line.h"
13 #include "base/containers/hash_tables.h"
14 #include "base/logging.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/memory/shared_memory.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/trace_event/trace_event.h"
20 #include "build/build_config.h"
21 #include "media/base/media_switches.h"
22 #include "media/filters/jpeg_parser.h"
23 #include "media/gpu/fake_jpeg_decode_accelerator.h"
24 #include "mojo/public/cpp/bindings/strong_binding.h"
25 #include "mojo/public/cpp/system/platform_handle.h"
26 #include "ui/gfx/geometry/size.h"
27
28 #if defined(OS_CHROMEOS)
29 #if defined(ARCH_CPU_X86_FAMILY)
30 #include "media/gpu/vaapi_jpeg_decode_accelerator.h"
31 #endif
32 #if defined(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY)
33 #include "media/gpu/v4l2_device.h"
34 #include "media/gpu/v4l2_jpeg_decode_accelerator.h"
35 #endif
36
37 #endif
38
39 namespace {
40
41 std::unique_ptr<media::JpegDecodeAccelerator> CreateV4L2JDA(
42 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
43 std::unique_ptr<media::JpegDecodeAccelerator> decoder;
44 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) && \
45 defined(ARCH_CPU_ARM_FAMILY)
46 scoped_refptr<media::V4L2Device> device = media::V4L2Device::Create();
47 if (device)
48 decoder.reset(new media::V4L2JpegDecodeAccelerator(
49 device, std::move(io_task_runner)));
50 #endif
51 return decoder;
52 }
53
54 std::unique_ptr<media::JpegDecodeAccelerator> CreateVaapiJDA(
55 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
56 std::unique_ptr<media::JpegDecodeAccelerator> decoder;
57 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
58 decoder.reset(
59 new media::VaapiJpegDecodeAccelerator(std::move(io_task_runner)));
60 #endif
61 return decoder;
62 }
63
64 std::unique_ptr<media::JpegDecodeAccelerator> CreateFakeJDA(
65 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
66 return base::MakeUnique<media::FakeJpegDecodeAccelerator>(
67 std::move(io_task_runner));
68 }
69
70 void DecodeFinished(std::unique_ptr<base::SharedMemory> shm) {
71 // Do nothing. Because VideoFrame is backed by |shm|, the purpose of this
72 // function is to just keep reference of |shm| to make sure it lives until
73 // decode finishes.
74 }
75
76 bool VerifyDecodeParams(const gfx::Size& coded_size,
77 mojo::ScopedSharedBufferHandle* output_handle,
78 uint32_t output_buffer_size) {
79 const int kJpegMaxDimension = UINT16_MAX;
80 if (coded_size.IsEmpty() || coded_size.width() > kJpegMaxDimension ||
81 coded_size.height() > kJpegMaxDimension) {
82 LOG(ERROR) << "invalid coded_size " << coded_size.ToString();
83 return false;
84 }
85
86 if (!output_handle->is_valid()) {
87 LOG(ERROR) << "invalid output_handle";
88 return false;
89 }
90
91 if (output_buffer_size <
92 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, coded_size)) {
93 LOG(ERROR) << "output_buffer_size is too small: " << output_buffer_size;
94 return false;
95 }
96
97 return true;
98 }
99
100 } // namespace
101
102 namespace media {
103
104 // static
105 bool GpuJpegDecodeAcceleratorFactoryProvider::
106 IsAcceleratedJpegDecodeSupported() {
107 auto accelerator_factory_functions = GetAcceleratorFactories();
108 for (const auto& create_jda_function : accelerator_factory_functions) {
109 std::unique_ptr<JpegDecodeAccelerator> accelerator =
110 create_jda_function.Run(base::ThreadTaskRunnerHandle::Get());
111 if (accelerator && accelerator->IsSupported())
112 return true;
113 }
114 return false;
115 }
116
117 // static
118 std::vector<GpuJpegDecodeAcceleratorFactoryProvider::CreateAcceleratorCB>
119 GpuJpegDecodeAcceleratorFactoryProvider::GetAcceleratorFactories() {
120 // This list is ordered by priority of use.
121 std::vector<CreateAcceleratorCB> result;
122 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
123 switches::kUseFakeJpegDecodeAccelerator)) {
124 result.push_back(base::Bind(&CreateFakeJDA));
125 } else {
126 result.push_back(base::Bind(&CreateV4L2JDA));
127 result.push_back(base::Bind(&CreateVaapiJDA));
128 }
129 return result;
130 }
131
132 // static
133 void GpuJpegDecodeAccelerator::Create(
134 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
135 const service_manager::BindSourceInfo& source_info,
136 mojom::GpuJpegDecodeAcceleratorRequest request) {
137 auto* jpeg_decoder = new GpuJpegDecodeAccelerator(std::move(io_task_runner));
138 mojo::MakeStrongBinding(base::WrapUnique(jpeg_decoder), std::move(request));
139 }
140
141 GpuJpegDecodeAccelerator::GpuJpegDecodeAccelerator(
142 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
143 : accelerator_factory_functions_(
144 GpuJpegDecodeAcceleratorFactoryProvider::GetAcceleratorFactories()),
145 child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
146 io_task_runner_(std::move(io_task_runner)) {}
147
148 GpuJpegDecodeAccelerator::~GpuJpegDecodeAccelerator() {
149 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
150 }
151
152 void GpuJpegDecodeAccelerator::NotifyDecodeStatus(int32_t bitstream_buffer_id,
153 mojom::Error error) {
154 if (io_task_runner_->BelongsToCurrentThread()) {
155 child_task_runner_->PostTask(
156 FROM_HERE,
157 base::Bind(&GpuJpegDecodeAccelerator::NotifyDecodeStatus,
158 base::Unretained(this), bitstream_buffer_id, error));
159 return;
160 }
161
162 DCHECK(decode_cb_);
163 std::move(decode_cb_).Run(bitstream_buffer_id, error);
164 }
165
166 void GpuJpegDecodeAccelerator::VideoFrameReady(int32_t bitstream_buffer_id) {
167 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
168 NotifyDecodeStatus(bitstream_buffer_id, mojom::Error::NO_ERRORS);
169 }
170
171 void GpuJpegDecodeAccelerator::NotifyError(int32_t bitstream_buffer_id,
172 JpegDecodeAccelerator::Error error) {
173 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
174 NotifyDecodeStatus(bitstream_buffer_id, static_cast<mojom::Error>(error));
175 }
176
177 void GpuJpegDecodeAccelerator::Initialize(InitializeCallback callback) {
178 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
179
180 // When adding non-chromeos platforms, VideoCaptureGpuJpegDecoder::Initialize
181 // needs to be updated.
182
183 std::unique_ptr<JpegDecodeAccelerator> accelerator;
184 for (const auto& create_jda_function : accelerator_factory_functions_) {
185 std::unique_ptr<JpegDecodeAccelerator> tmp_accelerator =
186 create_jda_function.Run(io_task_runner_);
187 if (tmp_accelerator && tmp_accelerator->Initialize(this)) {
188 accelerator = std::move(tmp_accelerator);
189 break;
190 }
191 }
192
193 if (!accelerator) {
194 DLOG(ERROR) << "JPEG accelerator Initialize failed";
195 std::move(callback).Run(false);
196 return;
197 }
198
199 accelerator_ = std::move(accelerator);
200 std::move(callback).Run(true);
201 }
202
203 void GpuJpegDecodeAccelerator::Decode(
204 mojom::BitstreamBufferPtr input_buffer,
205 const gfx::Size& coded_size,
206 mojo::ScopedSharedBufferHandle output_handle,
207 uint32_t output_buffer_size,
208 DecodeCallback callback) {
209 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
210 decode_cb_ = std::move(callback);
211 io_task_runner_->PostTask(
212 FROM_HERE,
213 base::Bind(&GpuJpegDecodeAccelerator::DecodeOnIOThread,
214 base::Unretained(this), base::Passed(&input_buffer),
215 coded_size, base::Passed(&output_handle), output_buffer_size));
216 }
217
218 void GpuJpegDecodeAccelerator::DecodeOnIOThread(
219 mojom::BitstreamBufferPtr input_buffer,
220 const gfx::Size& coded_size,
221 mojo::ScopedSharedBufferHandle output_handle,
222 uint32_t output_buffer_size) {
223 DCHECK(io_task_runner_->BelongsToCurrentThread());
224 TRACE_EVENT0("jpeg", "GpuJpegDecodeAccelerator::DecodeOnIOThread");
225
226 if (!VerifyDecodeParams(coded_size, &output_handle, output_buffer_size)) {
227 NotifyDecodeStatus(input_buffer->id, mojom::Error::INVALID_ARGUMENT);
228 return;
229 }
230
231 base::SharedMemoryHandle memory_handle;
232 size_t memory_size = 0;
233 bool read_only_flag = false;
234
235 MojoResult result = mojo::UnwrapSharedMemoryHandle(
236 std::move(output_handle), &memory_handle, &memory_size, &read_only_flag);
237 DCHECK_EQ(MOJO_RESULT_OK, result);
238
239 std::unique_ptr<base::SharedMemory> output_shm(
240 new base::SharedMemory(memory_handle, false));
241 if (!output_shm->Map(output_buffer_size)) {
242 LOG(ERROR) << "Could not map output shared memory for input buffer id "
243 << input_buffer->id;
244 NotifyDecodeStatus(input_buffer->id, mojom::Error::PLATFORM_FAILURE);
245 return;
246 }
247
248 uint8_t* shm_memory = static_cast<uint8_t*>(output_shm->memory());
249 scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalSharedMemory(
250 PIXEL_FORMAT_I420, // format
251 coded_size, // coded_size
252 gfx::Rect(coded_size), // visible_rect
253 coded_size, // natural_size
254 shm_memory, // data
255 output_buffer_size, // data_size
256 memory_handle, // handle
257 0, // data_offset
258 base::TimeDelta()); // timestamp
259 if (!frame.get()) {
260 LOG(ERROR) << "Could not create VideoFrame for input buffer id "
261 << input_buffer->id;
262 NotifyDecodeStatus(input_buffer->id, mojom::Error::PLATFORM_FAILURE);
263 return;
264 }
265 frame->AddDestructionObserver(
266 base::Bind(DecodeFinished, base::Passed(&output_shm)));
267
268 result = mojo::UnwrapSharedMemoryHandle(
269 std::move(input_buffer->memory_handle), &memory_handle, &memory_size,
270 &read_only_flag);
271 DCHECK_EQ(MOJO_RESULT_OK, result);
272
273 BitstreamBuffer bitstream_buffer(input_buffer->id, memory_handle,
274 input_buffer->size, input_buffer->offset,
275 input_buffer->timestamp);
276
277 bitstream_buffer.SetDecryptConfig(DecryptConfig(
278 input_buffer->key_id, input_buffer->iv, input_buffer->subsamples));
279
280 DCHECK(accelerator_);
281 accelerator_->Decode(bitstream_buffer, frame);
282 }
283
284 void GpuJpegDecodeAccelerator::Uninitialize() {
285 // TODO(c.padhi): see http://crbug.com/699255.
286 NOTIMPLEMENTED();
287 }
288
289 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/mojo/service/gpu_jpeg_decode_accelerator.h ('k') | media/gpu/mojo/service/gpu_jpeg_decode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698