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

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

Issue 1953683002: Add stride for imported Dmabuf in ArcVideoAccelerator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: verify the stride. Created 4 years, 7 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/arc_gpu_video_decode_accelerator.h ('k') | chrome/gpu/arc_video_accelerator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/gpu/arc_gpu_video_decode_accelerator.h" 5 #include "chrome/gpu/arc_gpu_video_decode_accelerator.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "content/public/gpu/gpu_video_decode_accelerator_factory.h" 10 #include "content/public/gpu/gpu_video_decode_accelerator_factory.h"
11 #include "media/base/video_frame.h" 11 #include "media/base/video_frame.h"
12 12
13 namespace chromeos { 13 namespace chromeos {
14 namespace arc { 14 namespace arc {
15 15
16 ArcGpuVideoDecodeAccelerator::InputRecord::InputRecord( 16 ArcGpuVideoDecodeAccelerator::InputRecord::InputRecord(
17 int32_t bitstream_buffer_id, 17 int32_t bitstream_buffer_id,
18 uint32_t buffer_index, 18 uint32_t buffer_index,
19 int64_t timestamp) 19 int64_t timestamp)
20 : bitstream_buffer_id(bitstream_buffer_id), 20 : bitstream_buffer_id(bitstream_buffer_id),
21 buffer_index(buffer_index), 21 buffer_index(buffer_index),
22 timestamp(timestamp) {} 22 timestamp(timestamp) {}
23 23
24 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo() 24 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo() = default;
25 : offset(0), length(0) {}
26 25
27 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo( 26 ArcGpuVideoDecodeAccelerator::InputBufferInfo::InputBufferInfo(
28 InputBufferInfo&& other) 27 InputBufferInfo&& other) = default;
29 : handle(std::move(other.handle)),
30 offset(other.offset),
31 length(other.length) {}
32 28
33 ArcGpuVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() {} 29 ArcGpuVideoDecodeAccelerator::InputBufferInfo::~InputBufferInfo() = default;
30
31 ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo() = default;
32
33 ArcGpuVideoDecodeAccelerator::OutputBufferInfo::OutputBufferInfo(
34 OutputBufferInfo&& other) = default;
35
36 ArcGpuVideoDecodeAccelerator::OutputBufferInfo::~OutputBufferInfo() = default;
34 37
35 ArcGpuVideoDecodeAccelerator::ArcGpuVideoDecodeAccelerator() 38 ArcGpuVideoDecodeAccelerator::ArcGpuVideoDecodeAccelerator()
36 : pending_eos_output_buffer_(false), 39 : pending_eos_output_buffer_(false),
37 arc_client_(nullptr), 40 arc_client_(nullptr),
38 next_bitstream_buffer_id_(0), 41 next_bitstream_buffer_id_(0),
42 output_pixel_format_(media::PIXEL_FORMAT_UNKNOWN),
39 output_buffer_size_(0) {} 43 output_buffer_size_(0) {}
40 44
41 ArcGpuVideoDecodeAccelerator::~ArcGpuVideoDecodeAccelerator() {} 45 ArcGpuVideoDecodeAccelerator::~ArcGpuVideoDecodeAccelerator() {}
42 46
43 namespace { 47 namespace {
44 48
45 // An arbitrary chosen limit of the number of buffers. The number of 49 // An arbitrary chosen limit of the number of buffers. The number of
46 // buffers used is requested from the untrusted client side. 50 // buffers used is requested from the untrusted client side.
47 const size_t kMaxBufferCount = 128; 51 const size_t kMaxBufferCount = 128;
48 52
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 if (!ValidatePortAndIndex(port, index)) { 151 if (!ValidatePortAndIndex(port, index)) {
148 arc_client_->OnError(INVALID_ARGUMENT); 152 arc_client_->OnError(INVALID_ARGUMENT);
149 return; 153 return;
150 } 154 }
151 InputBufferInfo* input_info = &input_buffer_info_[index]; 155 InputBufferInfo* input_info = &input_buffer_info_[index];
152 input_info->handle = std::move(ashmem_fd); 156 input_info->handle = std::move(ashmem_fd);
153 input_info->offset = offset; 157 input_info->offset = offset;
154 input_info->length = length; 158 input_info->length = length;
155 } 159 }
156 160
161 bool ArcGpuVideoDecodeAccelerator::VerifyStride(const base::ScopedFD& dmabuf_fd,
162 int32_t stride) {
163 off_t size = lseek(dmabuf_fd.get(), 0, SEEK_END);
164 lseek(dmabuf_fd.get(), 0, SEEK_SET);
165
166 if (size < 0) {
167 DLOG(ERROR) << "fail to find the size of dmabuf" << errno;
168 return false;
169 }
170
171 int height = coded_size_.height();
172 switch (output_pixel_format_) {
173 case media::PIXEL_FORMAT_I420:
174 case media::PIXEL_FORMAT_YV12:
175 case media::PIXEL_FORMAT_NV12:
176 case media::PIXEL_FORMAT_NV21:
177 // Adjusts the height for UV plane.
178 height = height * 3 / 2;
dcheng 2016/05/17 01:12:28 What happens if height isn't even divisible by two
Owen Lin 2016/05/17 08:52:16 The coded height should be always even for YUV fra
179 break;
180 case media::PIXEL_FORMAT_ARGB:
181 // No need to adjust height.
182 break;
183 default:
184 DLOG(ERROR) << "Format not supported: " << output_pixel_format_;
185 return false;
186 }
187
188 if (stride < 0 || height * stride > size) {
dcheng 2016/05/17 01:12:27 height * stride should use CheckedNumeric: https:/
Owen Lin 2016/05/17 08:52:16 Thanks.
189 DLOG(ERROR) << "invalid stride: " << stride << ", height: " << height
190 << ", size of dmabuf: " << size;
191 return false;
192 }
193
194 return true;
195 }
196
157 void ArcGpuVideoDecodeAccelerator::BindDmabuf(PortType port, 197 void ArcGpuVideoDecodeAccelerator::BindDmabuf(PortType port,
158 uint32_t index, 198 uint32_t index,
159 base::ScopedFD dmabuf_fd) { 199 base::ScopedFD dmabuf_fd,
200 int32_t stride) {
160 DCHECK(thread_checker_.CalledOnValidThread()); 201 DCHECK(thread_checker_.CalledOnValidThread());
161 202
162 if (!vda_) { 203 if (!vda_) {
163 DLOG(ERROR) << "VDA not initialized"; 204 DLOG(ERROR) << "VDA not initialized";
164 return; 205 return;
165 } 206 }
166 207
167 if (port != PORT_OUTPUT) { 208 if (port != PORT_OUTPUT) {
168 DLOG(ERROR) << "Dmabuf is only supported for input"; 209 DLOG(ERROR) << "Dmabuf is only supported for input";
169 arc_client_->OnError(INVALID_ARGUMENT); 210 arc_client_->OnError(INVALID_ARGUMENT);
170 return; 211 return;
171 } 212 }
172 if (!ValidatePortAndIndex(port, index)) { 213 if (!ValidatePortAndIndex(port, index)) {
173 arc_client_->OnError(INVALID_ARGUMENT); 214 arc_client_->OnError(INVALID_ARGUMENT);
174 return; 215 return;
175 } 216 }
176 buffers_pending_import_[index] = std::move(dmabuf_fd); 217 if (!VerifyStride(dmabuf_fd, stride)) {
218 arc_client_->OnError(INVALID_ARGUMENT);
219 return;
220 }
221
222 OutputBufferInfo& info = buffers_pending_import_[index];
223 info.handle = std::move(dmabuf_fd);
224 info.stride = stride;
177 } 225 }
178 226
179 void ArcGpuVideoDecodeAccelerator::UseBuffer(PortType port, 227 void ArcGpuVideoDecodeAccelerator::UseBuffer(PortType port,
180 uint32_t index, 228 uint32_t index,
181 const BufferMetadata& metadata) { 229 const BufferMetadata& metadata) {
182 DVLOG(5) << "UseBuffer(port=" << port << ", index=" << index 230 DVLOG(5) << "UseBuffer(port=" << port << ", index=" << index
183 << ", metadata=(bytes_used=" << metadata.bytes_used 231 << ", metadata=(bytes_used=" << metadata.bytes_used
184 << ", timestamp=" << metadata.timestamp << ")"; 232 << ", timestamp=" << metadata.timestamp << ")";
185 DCHECK(thread_checker_.CalledOnValidThread()); 233 DCHECK(thread_checker_.CalledOnValidThread());
186 if (!vda_) { 234 if (!vda_) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers( 282 void ArcGpuVideoDecodeAccelerator::ProvidePictureBuffers(
235 uint32_t requested_num_of_buffers, 283 uint32_t requested_num_of_buffers,
236 uint32_t textures_per_buffer, 284 uint32_t textures_per_buffer,
237 const gfx::Size& dimensions, 285 const gfx::Size& dimensions,
238 uint32_t texture_target) { 286 uint32_t texture_target) {
239 DVLOG(5) << "ProvidePictureBuffers(" 287 DVLOG(5) << "ProvidePictureBuffers("
240 << "requested_num_of_buffers=" << requested_num_of_buffers 288 << "requested_num_of_buffers=" << requested_num_of_buffers
241 << ", dimensions=" << dimensions.ToString() << ")"; 289 << ", dimensions=" << dimensions.ToString() << ")";
242 DCHECK(thread_checker_.CalledOnValidThread()); 290 DCHECK(thread_checker_.CalledOnValidThread());
243 coded_size_ = dimensions; 291 coded_size_ = dimensions;
292 output_pixel_format_ = vda_->GetOutputFormat();
244 293
245 VideoFormat video_format; 294 VideoFormat video_format;
246 media::VideoPixelFormat output_format = vda_->GetOutputFormat(); 295 switch (output_pixel_format_) {
247 switch (output_format) {
248 case media::PIXEL_FORMAT_I420: 296 case media::PIXEL_FORMAT_I420:
249 case media::PIXEL_FORMAT_YV12: 297 case media::PIXEL_FORMAT_YV12:
250 case media::PIXEL_FORMAT_NV12: 298 case media::PIXEL_FORMAT_NV12:
251 case media::PIXEL_FORMAT_NV21: 299 case media::PIXEL_FORMAT_NV21:
252 // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android 300 // HAL_PIXEL_FORMAT_YCbCr_420_888 is the flexible pixel format in Android
253 // which handles all 420 formats, with both orderings of chroma (CbCr and 301 // which handles all 420 formats, with both orderings of chroma (CbCr and
254 // CrCb) as well as planar and semi-planar layouts. 302 // CrCb) as well as planar and semi-planar layouts.
255 video_format.pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888; 303 video_format.pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
256 break; 304 break;
257 default: 305 default:
258 DLOG(ERROR) << "Format not supported: " << output_format; 306 DLOG(ERROR) << "Format not supported: " << output_pixel_format_;
259 arc_client_->OnError(PLATFORM_FAILURE); 307 arc_client_->OnError(PLATFORM_FAILURE);
260 return; 308 return;
261 } 309 }
262 video_format.buffer_size = 310 video_format.buffer_size =
263 media::VideoFrame::AllocationSize(output_format, coded_size_); 311 media::VideoFrame::AllocationSize(output_pixel_format_, coded_size_);
264 output_buffer_size_ = video_format.buffer_size; 312 output_buffer_size_ = video_format.buffer_size;
265 video_format.min_num_buffers = requested_num_of_buffers; 313 video_format.min_num_buffers = requested_num_of_buffers;
266 video_format.coded_width = dimensions.width(); 314 video_format.coded_width = dimensions.width();
267 video_format.coded_height = dimensions.height(); 315 video_format.coded_height = dimensions.height();
268 // TODO(owenlin): How to get visible size? 316 // TODO(owenlin): How to get visible size?
269 video_format.crop_top = 0; 317 video_format.crop_top = 0;
270 video_format.crop_left = 0; 318 video_format.crop_left = 0;
271 video_format.crop_width = dimensions.width(); 319 video_format.crop_width = dimensions.width();
272 video_format.crop_height = dimensions.height(); 320 video_format.crop_height = dimensions.height();
273 arc_client_->OnOutputFormatChanged(video_format); 321 arc_client_->OnOutputFormatChanged(video_format);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } 402 }
355 403
356 void ArcGpuVideoDecodeAccelerator::SendEosIfNeededOrReusePicture( 404 void ArcGpuVideoDecodeAccelerator::SendEosIfNeededOrReusePicture(
357 uint32_t index) { 405 uint32_t index) {
358 if (pending_eos_output_buffer_) { 406 if (pending_eos_output_buffer_) {
359 BufferMetadata metadata; 407 BufferMetadata metadata;
360 metadata.flags = BUFFER_FLAG_EOS; 408 metadata.flags = BUFFER_FLAG_EOS;
361 arc_client_->OnBufferDone(PORT_OUTPUT, index, metadata); 409 arc_client_->OnBufferDone(PORT_OUTPUT, index, metadata);
362 pending_eos_output_buffer_ = false; 410 pending_eos_output_buffer_ = false;
363 } else { 411 } else {
364 if (buffers_pending_import_[index].is_valid()) { 412 OutputBufferInfo& info = buffers_pending_import_[index];
365 std::vector<gfx::GpuMemoryBufferHandle> buffers; 413 if (info.handle.is_valid()) {
366 buffers.push_back(gfx::GpuMemoryBufferHandle()); 414 gfx::GpuMemoryBufferHandle handle;
367 #if defined(USE_OZONE) 415 #if defined(USE_OZONE)
368 buffers.back().native_pixmap_handle.fd = 416 handle.native_pixmap_handle.fd =
369 base::FileDescriptor(buffers_pending_import_[index].release(), true); 417 base::FileDescriptor(info.handle.release(), true);
418 handle.native_pixmap_handle.stride = info.stride;
370 #endif 419 #endif
371 vda_->ImportBufferForPicture(index, buffers); 420 vda_->ImportBufferForPicture(index, {handle});
372 } else { 421 } else {
373 vda_->ReusePictureBuffer(index); 422 vda_->ReusePictureBuffer(index);
374 } 423 }
375 } 424 }
376 } 425 }
377 426
378 void ArcGpuVideoDecodeAccelerator::CreateInputRecord( 427 void ArcGpuVideoDecodeAccelerator::CreateInputRecord(
379 int32_t bitstream_buffer_id, 428 int32_t bitstream_buffer_id,
380 uint32_t buffer_index, 429 uint32_t buffer_index,
381 int64_t timestamp) { 430 int64_t timestamp) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 } 466 }
418 return true; 467 return true;
419 default: 468 default:
420 DLOG(ERROR) << "Invalid port: " << port; 469 DLOG(ERROR) << "Invalid port: " << port;
421 return false; 470 return false;
422 } 471 }
423 } 472 }
424 473
425 } // namespace arc 474 } // namespace arc
426 } // namespace chromeos 475 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/gpu/arc_gpu_video_decode_accelerator.h ('k') | chrome/gpu/arc_video_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698