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

Side by Side Diff: media/gpu/v4l2_image_processor.cc

Issue 1939683002: Test X11 header pollution (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 | « media/gpu/v4l2_image_processor.h ('k') | media/gpu/v4l2_jpeg_decode_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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <errno.h> 5 #include <errno.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <linux/videodev2.h> 7 #include <linux/videodev2.h>
8 #include <poll.h> 8 #include <poll.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/eventfd.h> 10 #include <sys/eventfd.h>
11 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
12 #include <sys/mman.h> 12 #include <sys/mman.h>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/bind_helpers.h" 15 #include "base/bind_helpers.h"
16 #include "base/callback.h" 16 #include "base/callback.h"
17 #include "base/numerics/safe_conversions.h" 17 #include "base/numerics/safe_conversions.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "content/common/gpu/media/v4l2_image_processor.h" 19 #include "media/gpu/v4l2_image_processor.h"
20 20
21 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \ 21 #define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
22 do { \ 22 do { \
23 if (device_->Ioctl(type, arg) != 0) { \ 23 if (device_->Ioctl(type, arg) != 0) { \
24 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \ 24 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \
25 return value; \ 25 return value; \
26 } \ 26 } \
27 } while (0) 27 } while (0)
28 28
29 #define IOCTL_OR_ERROR_RETURN(type, arg) \ 29 #define IOCTL_OR_ERROR_RETURN(type, arg) \
30 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type) 30 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, ((void)0), #type)
31 31
32 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \ 32 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
33 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type) 33 IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
34 34
35 #define IOCTL_OR_LOG_ERROR(type, arg) \ 35 #define IOCTL_OR_LOG_ERROR(type, arg) \
36 do { \ 36 do { \
37 if (device_->Ioctl(type, arg) != 0) \ 37 if (device_->Ioctl(type, arg) != 0) \
38 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 38 PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
39 } while (0) 39 } while (0)
40 40
41 namespace content { 41 namespace media {
42 42
43 V4L2ImageProcessor::InputRecord::InputRecord() : at_device(false) { 43 V4L2ImageProcessor::InputRecord::InputRecord() : at_device(false) {}
44 }
45 44
46 V4L2ImageProcessor::InputRecord::~InputRecord() { 45 V4L2ImageProcessor::InputRecord::~InputRecord() {}
47 }
48 46
49 V4L2ImageProcessor::OutputRecord::OutputRecord() : at_device(false) {} 47 V4L2ImageProcessor::OutputRecord::OutputRecord() : at_device(false) {}
50 48
51 V4L2ImageProcessor::OutputRecord::~OutputRecord() { 49 V4L2ImageProcessor::OutputRecord::~OutputRecord() {}
52 }
53 50
54 V4L2ImageProcessor::JobRecord::JobRecord() : output_buffer_index(-1) {} 51 V4L2ImageProcessor::JobRecord::JobRecord() : output_buffer_index(-1) {}
55 52
56 V4L2ImageProcessor::JobRecord::~JobRecord() { 53 V4L2ImageProcessor::JobRecord::~JobRecord() {}
57 }
58 54
59 V4L2ImageProcessor::V4L2ImageProcessor(const scoped_refptr<V4L2Device>& device) 55 V4L2ImageProcessor::V4L2ImageProcessor(const scoped_refptr<V4L2Device>& device)
60 : input_format_(media::PIXEL_FORMAT_UNKNOWN), 56 : input_format_(media::PIXEL_FORMAT_UNKNOWN),
61 output_format_(media::PIXEL_FORMAT_UNKNOWN), 57 output_format_(media::PIXEL_FORMAT_UNKNOWN),
62 input_memory_type_(V4L2_MEMORY_USERPTR), 58 input_memory_type_(V4L2_MEMORY_USERPTR),
63 input_format_fourcc_(0), 59 input_format_fourcc_(0),
64 output_format_fourcc_(0), 60 output_format_fourcc_(0),
65 input_planes_count_(0), 61 input_planes_count_(0),
66 output_planes_count_(0), 62 output_planes_count_(0),
67 child_task_runner_(base::ThreadTaskRunnerHandle::Get()), 63 child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 output_visible_size_ = output_visible_size; 129 output_visible_size_ = output_visible_size;
134 output_allocated_size_ = output_allocated_size; 130 output_allocated_size_ = output_allocated_size;
135 131
136 // Capabilities check. 132 // Capabilities check.
137 struct v4l2_capability caps; 133 struct v4l2_capability caps;
138 memset(&caps, 0, sizeof(caps)); 134 memset(&caps, 0, sizeof(caps));
139 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 135 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
140 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); 136 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
141 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 137 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
142 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: " 138 LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP: "
143 "caps check failed: 0x" << std::hex << caps.capabilities; 139 "caps check failed: 0x"
140 << std::hex << caps.capabilities;
144 return false; 141 return false;
145 } 142 }
146 143
147 if (!CreateInputBuffers() || !CreateOutputBuffers()) 144 if (!CreateInputBuffers() || !CreateOutputBuffers())
148 return false; 145 return false;
149 146
150 if (!device_thread_.Start()) { 147 if (!device_thread_.Start()) {
151 LOG(ERROR) << "Initialize(): encoder thread failed to start"; 148 LOG(ERROR) << "Initialize(): encoder thread failed to start";
152 return false; 149 return false;
153 } 150 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 int output_buffer_index, 223 int output_buffer_index,
227 const FrameReadyCB& cb) { 224 const FrameReadyCB& cb) {
228 DVLOG(3) << __func__ << ": ts=" << frame->timestamp().InMilliseconds(); 225 DVLOG(3) << __func__ << ": ts=" << frame->timestamp().InMilliseconds();
229 226
230 std::unique_ptr<JobRecord> job_record(new JobRecord()); 227 std::unique_ptr<JobRecord> job_record(new JobRecord());
231 job_record->frame = frame; 228 job_record->frame = frame;
232 job_record->output_buffer_index = output_buffer_index; 229 job_record->output_buffer_index = output_buffer_index;
233 job_record->ready_cb = cb; 230 job_record->ready_cb = cb;
234 231
235 device_thread_.message_loop()->PostTask( 232 device_thread_.message_loop()->PostTask(
236 FROM_HERE, 233 FROM_HERE, base::Bind(&V4L2ImageProcessor::ProcessTask,
237 base::Bind(&V4L2ImageProcessor::ProcessTask, 234 base::Unretained(this), base::Passed(&job_record)));
238 base::Unretained(this),
239 base::Passed(&job_record)));
240 } 235 }
241 236
242 void V4L2ImageProcessor::ProcessTask(std::unique_ptr<JobRecord> job_record) { 237 void V4L2ImageProcessor::ProcessTask(std::unique_ptr<JobRecord> job_record) {
243 int index = job_record->output_buffer_index; 238 int index = job_record->output_buffer_index;
244 DVLOG(3) << __func__ << ": Reusing output buffer, index=" << index; 239 DVLOG(3) << __func__ << ": Reusing output buffer, index=" << index;
245 DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current()); 240 DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
246 241
247 EnqueueOutput(index); 242 EnqueueOutput(index);
248 input_queue_.push(make_linked_ptr(job_record.release())); 243 input_queue_.push(make_linked_ptr(job_record.release()));
249 EnqueueInput(); 244 EnqueueInput();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 memset(&format, 0, sizeof(format)); 302 memset(&format, 0, sizeof(format));
308 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 303 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
309 format.fmt.pix_mp.width = input_allocated_size_.width(); 304 format.fmt.pix_mp.width = input_allocated_size_.width();
310 format.fmt.pix_mp.height = input_allocated_size_.height(); 305 format.fmt.pix_mp.height = input_allocated_size_.height();
311 format.fmt.pix_mp.pixelformat = input_format_fourcc_; 306 format.fmt.pix_mp.pixelformat = input_format_fourcc_;
312 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); 307 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
313 308
314 input_planes_count_ = format.fmt.pix_mp.num_planes; 309 input_planes_count_ = format.fmt.pix_mp.num_planes;
315 DCHECK_LE(input_planes_count_, static_cast<size_t>(VIDEO_MAX_PLANES)); 310 DCHECK_LE(input_planes_count_, static_cast<size_t>(VIDEO_MAX_PLANES));
316 input_allocated_size_ = V4L2Device::CodedSizeFromV4L2Format(format); 311 input_allocated_size_ = V4L2Device::CodedSizeFromV4L2Format(format);
317 DCHECK(gfx::Rect(input_allocated_size_).Contains( 312 DCHECK(gfx::Rect(input_allocated_size_)
318 gfx::Rect(input_visible_size_))); 313 .Contains(gfx::Rect(input_visible_size_)));
319 314
320 struct v4l2_crop crop; 315 struct v4l2_crop crop;
321 memset(&crop, 0, sizeof(crop)); 316 memset(&crop, 0, sizeof(crop));
322 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 317 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
323 crop.c.left = 0; 318 crop.c.left = 0;
324 crop.c.top = 0; 319 crop.c.top = 0;
325 crop.c.width = base::checked_cast<__u32>(input_visible_size_.width()); 320 crop.c.width = base::checked_cast<__u32>(input_visible_size_.width());
326 crop.c.height = base::checked_cast<__u32>(input_visible_size_.height()); 321 crop.c.height = base::checked_cast<__u32>(input_visible_size_.height());
327 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CROP, &crop); 322 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CROP, &crop);
328 323
(...skipping 28 matching lines...) Expand all
357 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 352 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
358 format.fmt.pix_mp.width = output_allocated_size_.width(); 353 format.fmt.pix_mp.width = output_allocated_size_.width();
359 format.fmt.pix_mp.height = output_allocated_size_.height(); 354 format.fmt.pix_mp.height = output_allocated_size_.height();
360 format.fmt.pix_mp.pixelformat = output_format_fourcc_; 355 format.fmt.pix_mp.pixelformat = output_format_fourcc_;
361 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); 356 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
362 357
363 output_planes_count_ = format.fmt.pix_mp.num_planes; 358 output_planes_count_ = format.fmt.pix_mp.num_planes;
364 DCHECK_LE(output_planes_count_, static_cast<size_t>(VIDEO_MAX_PLANES)); 359 DCHECK_LE(output_planes_count_, static_cast<size_t>(VIDEO_MAX_PLANES));
365 gfx::Size adjusted_allocated_size = 360 gfx::Size adjusted_allocated_size =
366 V4L2Device::CodedSizeFromV4L2Format(format); 361 V4L2Device::CodedSizeFromV4L2Format(format);
367 DCHECK(gfx::Rect(adjusted_allocated_size).Contains( 362 DCHECK(gfx::Rect(adjusted_allocated_size)
368 gfx::Rect(output_allocated_size_))); 363 .Contains(gfx::Rect(output_allocated_size_)));
369 output_allocated_size_ = adjusted_allocated_size; 364 output_allocated_size_ = adjusted_allocated_size;
370 365
371 struct v4l2_crop crop; 366 struct v4l2_crop crop;
372 memset(&crop, 0, sizeof(crop)); 367 memset(&crop, 0, sizeof(crop));
373 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 368 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
374 crop.c.left = 0; 369 crop.c.left = 0;
375 crop.c.top = 0; 370 crop.c.top = 0;
376 crop.c.width = base::checked_cast<__u32>(output_visible_size_.width()); 371 crop.c.width = base::checked_cast<__u32>(output_visible_size_.width());
377 crop.c.height = base::checked_cast<__u32>(output_visible_size_.height()); 372 crop.c.height = base::checked_cast<__u32>(output_visible_size_.height());
378 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CROP, &crop); 373 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_CROP, &crop);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 424
430 bool event_pending; 425 bool event_pending;
431 if (!device_->Poll(poll_device, &event_pending)) { 426 if (!device_->Poll(poll_device, &event_pending)) {
432 NotifyError(); 427 NotifyError();
433 return; 428 return;
434 } 429 }
435 430
436 // All processing should happen on ServiceDeviceTask(), since we shouldn't 431 // All processing should happen on ServiceDeviceTask(), since we shouldn't
437 // touch encoder state from this thread. 432 // touch encoder state from this thread.
438 device_thread_.message_loop()->PostTask( 433 device_thread_.message_loop()->PostTask(
439 FROM_HERE, 434 FROM_HERE, base::Bind(&V4L2ImageProcessor::ServiceDeviceTask,
440 base::Bind(&V4L2ImageProcessor::ServiceDeviceTask, 435 base::Unretained(this)));
441 base::Unretained(this)));
442 } 436 }
443 437
444 void V4L2ImageProcessor::ServiceDeviceTask() { 438 void V4L2ImageProcessor::ServiceDeviceTask() {
445 DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current()); 439 DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
446 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 440 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
447 // so either: 441 // so either:
448 // * device_poll_thread_ is running normally 442 // * device_poll_thread_ is running normally
449 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down, 443 // * device_poll_thread_ scheduled us, but then a DestroyTask() shut it down,
450 // in which case we should early-out. 444 // in which case we should early-out.
451 if (!device_poll_thread_.message_loop()) 445 if (!device_poll_thread_.message_loop())
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 struct v4l2_buffer qbuf; 594 struct v4l2_buffer qbuf;
601 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES]; 595 struct v4l2_plane qbuf_planes[VIDEO_MAX_PLANES];
602 memset(&qbuf, 0, sizeof(qbuf)); 596 memset(&qbuf, 0, sizeof(qbuf));
603 memset(qbuf_planes, 0, sizeof(qbuf_planes)); 597 memset(qbuf_planes, 0, sizeof(qbuf_planes));
604 qbuf.index = index; 598 qbuf.index = index;
605 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 599 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
606 qbuf.memory = input_memory_type_; 600 qbuf.memory = input_memory_type_;
607 qbuf.m.planes = qbuf_planes; 601 qbuf.m.planes = qbuf_planes;
608 qbuf.length = input_planes_count_; 602 qbuf.length = input_planes_count_;
609 for (size_t i = 0; i < input_planes_count_; ++i) { 603 for (size_t i = 0; i < input_planes_count_; ++i) {
610 qbuf.m.planes[i].bytesused = media::VideoFrame::PlaneSize( 604 qbuf.m.planes[i].bytesused =
611 input_record.frame->format(), i, input_allocated_size_).GetArea(); 605 media::VideoFrame::PlaneSize(input_record.frame->format(), i,
606 input_allocated_size_)
607 .GetArea();
612 qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused; 608 qbuf.m.planes[i].length = qbuf.m.planes[i].bytesused;
613 if (input_memory_type_ == V4L2_MEMORY_USERPTR) { 609 if (input_memory_type_ == V4L2_MEMORY_USERPTR) {
614 qbuf.m.planes[i].m.userptr = 610 qbuf.m.planes[i].m.userptr =
615 reinterpret_cast<unsigned long>(input_record.frame->data(i)); 611 reinterpret_cast<unsigned long>(input_record.frame->data(i));
616 } else { 612 } else {
617 qbuf.m.planes[i].m.fd = input_record.frame->dmabuf_fd(i); 613 qbuf.m.planes[i].m.fd = input_record.frame->dmabuf_fd(i);
618 } 614 }
619 } 615 }
620 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf); 616 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QBUF, &qbuf);
621 input_record.at_device = true; 617 input_record.at_device = true;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 653
658 // Start up the device poll thread and schedule its first DevicePollTask(). 654 // Start up the device poll thread and schedule its first DevicePollTask().
659 if (!device_poll_thread_.Start()) { 655 if (!device_poll_thread_.Start()) {
660 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 656 LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
661 NotifyError(); 657 NotifyError();
662 return false; 658 return false;
663 } 659 }
664 // Enqueue a poll task with no devices to poll on - will wait only for the 660 // Enqueue a poll task with no devices to poll on - will wait only for the
665 // poll interrupt 661 // poll interrupt
666 device_poll_thread_.message_loop()->PostTask( 662 device_poll_thread_.message_loop()->PostTask(
667 FROM_HERE, 663 FROM_HERE, base::Bind(&V4L2ImageProcessor::DevicePollTask,
668 base::Bind( 664 base::Unretained(this), false));
669 &V4L2ImageProcessor::DevicePollTask, base::Unretained(this), false));
670 665
671 return true; 666 return true;
672 } 667 }
673 668
674 bool V4L2ImageProcessor::StopDevicePoll() { 669 bool V4L2ImageProcessor::StopDevicePoll() {
675 DVLOG(3) << __func__ << ": stopping device poll"; 670 DVLOG(3) << __func__ << ": stopping device poll";
676 if (device_thread_.IsRunning()) 671 if (device_thread_.IsRunning())
677 DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current()); 672 DCHECK_EQ(device_thread_.message_loop(), base::MessageLoop::current());
678 673
679 // Signal the DevicePollTask() to stop, and stop the device poll thread. 674 // Signal the DevicePollTask() to stop, and stop the device poll thread.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 714
720 return true; 715 return true;
721 } 716 }
722 717
723 void V4L2ImageProcessor::FrameReady(const FrameReadyCB& cb, 718 void V4L2ImageProcessor::FrameReady(const FrameReadyCB& cb,
724 int output_buffer_index) { 719 int output_buffer_index) {
725 DCHECK(child_task_runner_->BelongsToCurrentThread()); 720 DCHECK(child_task_runner_->BelongsToCurrentThread());
726 cb.Run(output_buffer_index); 721 cb.Run(output_buffer_index);
727 } 722 }
728 723
729 } // namespace content 724 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/v4l2_image_processor.h ('k') | media/gpu/v4l2_jpeg_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698