OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 "media/capture/video/linux/v4l2_capture_delegate.h" | 5 #include "media/capture/video/linux/v4l2_capture_delegate.h" |
6 | 6 |
7 #include <linux/version.h> | 7 #include <linux/version.h> |
8 #include <linux/videodev2.h> | 8 #include <linux/videodev2.h> |
9 #include <poll.h> | 9 #include <poll.h> |
10 #include <sys/fcntl.h> | 10 #include <sys/fcntl.h> |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 | 367 |
368 V4L2CaptureDelegate::V4L2CaptureDelegate( | 368 V4L2CaptureDelegate::V4L2CaptureDelegate( |
369 const VideoCaptureDeviceDescriptor& device_descriptor, | 369 const VideoCaptureDeviceDescriptor& device_descriptor, |
370 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, | 370 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, |
371 int power_line_frequency) | 371 int power_line_frequency) |
372 : v4l2_task_runner_(v4l2_task_runner), | 372 : v4l2_task_runner_(v4l2_task_runner), |
373 device_descriptor_(device_descriptor), | 373 device_descriptor_(device_descriptor), |
374 power_line_frequency_(power_line_frequency), | 374 power_line_frequency_(power_line_frequency), |
375 is_capturing_(false), | 375 is_capturing_(false), |
376 timeout_count_(0), | 376 timeout_count_(0), |
377 rotation_(0) {} | 377 rotation_(0), |
| 378 weak_factory_(this) {} |
378 | 379 |
379 void V4L2CaptureDelegate::AllocateAndStart( | 380 void V4L2CaptureDelegate::AllocateAndStart( |
380 int width, | 381 int width, |
381 int height, | 382 int height, |
382 float frame_rate, | 383 float frame_rate, |
383 std::unique_ptr<VideoCaptureDevice::Client> client) { | 384 std::unique_ptr<VideoCaptureDevice::Client> client) { |
384 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 385 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
385 DCHECK(client); | 386 DCHECK(client); |
386 client_ = std::move(client); | 387 client_ = std::move(client); |
387 | 388 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 0) { | 500 0) { |
500 SetErrorState(FROM_HERE, "VIDIOC_STREAMON failed"); | 501 SetErrorState(FROM_HERE, "VIDIOC_STREAMON failed"); |
501 return; | 502 return; |
502 } | 503 } |
503 | 504 |
504 client_->OnStarted(); | 505 client_->OnStarted(); |
505 is_capturing_ = true; | 506 is_capturing_ = true; |
506 | 507 |
507 // Post task to start fetching frames from v4l2. | 508 // Post task to start fetching frames from v4l2. |
508 v4l2_task_runner_->PostTask( | 509 v4l2_task_runner_->PostTask( |
509 FROM_HERE, base::Bind(&V4L2CaptureDelegate::DoCapture, this)); | 510 FROM_HERE, |
| 511 base::Bind(&V4L2CaptureDelegate::DoCapture, weak_factory_.GetWeakPtr())); |
510 } | 512 } |
511 | 513 |
512 void V4L2CaptureDelegate::StopAndDeAllocate() { | 514 void V4L2CaptureDelegate::StopAndDeAllocate() { |
513 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 515 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
514 // The order is important: stop streaming, clear |buffer_pool_|, | 516 // The order is important: stop streaming, clear |buffer_pool_|, |
515 // thus munmap()ing the v4l2_buffers, and then return them to the OS. | 517 // thus munmap()ing the v4l2_buffers, and then return them to the OS. |
516 v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 518 v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
517 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_STREAMOFF, &capture_type)) < | 519 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_STREAMOFF, &capture_type)) < |
518 0) { | 520 0) { |
519 SetErrorState(FROM_HERE, "VIDIOC_STREAMOFF failed"); | 521 SetErrorState(FROM_HERE, "VIDIOC_STREAMOFF failed"); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 cb.Run(std::move(blob)); | 815 cb.Run(std::move(blob)); |
814 } | 816 } |
815 | 817 |
816 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) { | 818 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) { |
817 SetErrorState(FROM_HERE, "Failed to enqueue capture buffer"); | 819 SetErrorState(FROM_HERE, "Failed to enqueue capture buffer"); |
818 return; | 820 return; |
819 } | 821 } |
820 } | 822 } |
821 | 823 |
822 v4l2_task_runner_->PostTask( | 824 v4l2_task_runner_->PostTask( |
823 FROM_HERE, base::Bind(&V4L2CaptureDelegate::DoCapture, this)); | 825 FROM_HERE, |
| 826 base::Bind(&V4L2CaptureDelegate::DoCapture, weak_factory_.GetWeakPtr())); |
824 } | 827 } |
825 | 828 |
826 void V4L2CaptureDelegate::SetErrorState( | 829 void V4L2CaptureDelegate::SetErrorState( |
827 const tracked_objects::Location& from_here, | 830 const tracked_objects::Location& from_here, |
828 const std::string& reason) { | 831 const std::string& reason) { |
829 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 832 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
830 is_capturing_ = false; | 833 is_capturing_ = false; |
831 client_->OnError(from_here, reason); | 834 client_->OnError(from_here, reason); |
832 } | 835 } |
833 | 836 |
(...skipping 16 matching lines...) Expand all Loading... |
850 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; | 853 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; |
851 return false; | 854 return false; |
852 } | 855 } |
853 start_ = static_cast<uint8_t*>(start); | 856 start_ = static_cast<uint8_t*>(start); |
854 length_ = buffer.length; | 857 length_ = buffer.length; |
855 payload_size_ = 0; | 858 payload_size_ = 0; |
856 return true; | 859 return true; |
857 } | 860 } |
858 | 861 |
859 } // namespace media | 862 } // namespace media |
OLD | NEW |