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 <poll.h> | 7 #include <poll.h> |
8 #include <sys/fcntl.h> | 8 #include <sys/fcntl.h> |
9 #include <sys/ioctl.h> | 9 #include <sys/ioctl.h> |
10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/files/file_enumerator.h" | 14 #include "base/files/file_enumerator.h" |
15 #include "base/posix/eintr_wrapper.h" | 15 #include "base/posix/eintr_wrapper.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
18 #include "media/base/bind_to_current_loop.h" | 18 #include "media/base/bind_to_current_loop.h" |
19 #include "media/capture/video/blob_utils.h" | 19 #include "media/capture/video/blob_utils.h" |
20 #include "media/capture/video/linux/video_capture_device_linux.h" | 20 #include "media/capture/video/linux/video_capture_device_linux.h" |
21 | 21 |
22 // TODO(astojilj): Remove V4L2_PIX_FMT_Z16/INVZ when videodev2.h gets updated. | |
23 #ifndef V4L2_PIX_FMT_Z16 | |
mcasas
2016/10/24 19:48:47
These two identifiers were introduced in
kernel 4
aleksandar.stojiljkovic
2016/10/25 10:12:28
Done. Thanks.
| |
24 // 16 bit depth, Realsense F200. | |
25 #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') | |
26 #endif | |
27 #ifndef V4L2_PIX_FMT_INVZ | |
28 // 16 bit depth, Realsense SR300. | |
29 #define V4L2_PIX_FMT_INVZ v4l2_fourcc('I', 'N', 'V', 'Z') | |
30 #endif | |
31 | |
22 namespace media { | 32 namespace media { |
23 | 33 |
24 // Desired number of video buffers to allocate. The actual number of allocated | 34 // Desired number of video buffers to allocate. The actual number of allocated |
25 // buffers by v4l2 driver can be higher or lower than this number. | 35 // buffers by v4l2 driver can be higher or lower than this number. |
26 // kNumVideoBuffers should not be too small, or Chrome may not return enough | 36 // kNumVideoBuffers should not be too small, or Chrome may not return enough |
27 // buffers back to driver in time. | 37 // buffers back to driver in time. |
28 const uint32_t kNumVideoBuffers = 4; | 38 const uint32_t kNumVideoBuffers = 4; |
29 // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw. | 39 // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw. |
30 // This value has been fine tuned. Before changing or modifying it see | 40 // This value has been fine tuned. Before changing or modifying it see |
31 // https://crbug.com/470717 | 41 // https://crbug.com/470717 |
(...skipping 11 matching lines...) Expand all Loading... | |
43 const int kZoomMultiplier = 100; | 53 const int kZoomMultiplier = 100; |
44 | 54 |
45 // V4L2 color formats supported by V4L2CaptureDelegate derived classes. | 55 // V4L2 color formats supported by V4L2CaptureDelegate derived classes. |
46 // This list is ordered by precedence of use -- but see caveats for MJPEG. | 56 // This list is ordered by precedence of use -- but see caveats for MJPEG. |
47 static struct { | 57 static struct { |
48 uint32_t fourcc; | 58 uint32_t fourcc; |
49 VideoPixelFormat pixel_format; | 59 VideoPixelFormat pixel_format; |
50 size_t num_planes; | 60 size_t num_planes; |
51 } const kSupportedFormatsAndPlanarity[] = { | 61 } const kSupportedFormatsAndPlanarity[] = { |
52 {V4L2_PIX_FMT_YUV420, PIXEL_FORMAT_I420, 1}, | 62 {V4L2_PIX_FMT_YUV420, PIXEL_FORMAT_I420, 1}, |
63 {V4L2_PIX_FMT_Y16, PIXEL_FORMAT_Y16, 1}, | |
64 {V4L2_PIX_FMT_Z16, PIXEL_FORMAT_Y16, 1}, | |
65 {V4L2_PIX_FMT_INVZ, PIXEL_FORMAT_Y16, 1}, | |
53 {V4L2_PIX_FMT_YUYV, PIXEL_FORMAT_YUY2, 1}, | 66 {V4L2_PIX_FMT_YUYV, PIXEL_FORMAT_YUY2, 1}, |
54 {V4L2_PIX_FMT_UYVY, PIXEL_FORMAT_UYVY, 1}, | 67 {V4L2_PIX_FMT_UYVY, PIXEL_FORMAT_UYVY, 1}, |
55 {V4L2_PIX_FMT_RGB24, PIXEL_FORMAT_RGB24, 1}, | 68 {V4L2_PIX_FMT_RGB24, PIXEL_FORMAT_RGB24, 1}, |
56 // MJPEG is usually sitting fairly low since we don't want to have to | 69 // MJPEG is usually sitting fairly low since we don't want to have to |
57 // decode. However, it is needed for large resolutions due to USB bandwidth | 70 // decode. However, it is needed for large resolutions due to USB bandwidth |
58 // limitations, so GetListOfUsableFourCcs() can duplicate it on top, see | 71 // limitations, so GetListOfUsableFourCcs() can duplicate it on top, see |
59 // that method. | 72 // that method. |
60 {V4L2_PIX_FMT_MJPEG, PIXEL_FORMAT_MJPEG, 1}, | 73 {V4L2_PIX_FMT_MJPEG, PIXEL_FORMAT_MJPEG, 1}, |
61 // JPEG works as MJPEG on some gspca webcams from field reports, see | 74 // JPEG works as MJPEG on some gspca webcams from field reports, see |
62 // https://code.google.com/p/webrtc/issues/detail?id=529, put it as the | 75 // https://code.google.com/p/webrtc/issues/detail?id=529, put it as the |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
560 return; | 573 return; |
561 } | 574 } |
562 | 575 |
563 buffer_tracker_pool_[buffer.index]->set_payload_size(buffer.bytesused); | 576 buffer_tracker_pool_[buffer.index]->set_payload_size(buffer.bytesused); |
564 const scoped_refptr<BufferTracker>& buffer_tracker = | 577 const scoped_refptr<BufferTracker>& buffer_tracker = |
565 buffer_tracker_pool_[buffer.index]; | 578 buffer_tracker_pool_[buffer.index]; |
566 | 579 |
567 base::TimeDelta timestamp = | 580 base::TimeDelta timestamp = |
568 base::TimeDelta::FromSeconds(buffer.timestamp.tv_sec) + | 581 base::TimeDelta::FromSeconds(buffer.timestamp.tv_sec) + |
569 base::TimeDelta::FromMicroseconds(buffer.timestamp.tv_usec); | 582 base::TimeDelta::FromMicroseconds(buffer.timestamp.tv_usec); |
570 client_->OnIncomingCapturedData( | 583 #ifdef V4L2_BUF_FLAG_ERROR |
571 buffer_tracker->start(), buffer_tracker->payload_size(), | 584 if (buffer.flags & V4L2_BUF_FLAG_ERROR) { |
572 capture_format_, rotation_, base::TimeTicks::Now(), timestamp); | 585 LOG(ERROR) << "Dequeued v4l2 buffer contains corrupted data (" |
586 << buffer.bytesused << " bytes)."; | |
587 buffer.bytesused = 0; | |
588 } else | |
589 #endif | |
590 client_->OnIncomingCapturedData( | |
591 buffer_tracker->start(), buffer_tracker->payload_size(), | |
592 capture_format_, rotation_, base::TimeTicks::Now(), timestamp); | |
573 | 593 |
574 while (!take_photo_callbacks_.empty()) { | 594 while (!take_photo_callbacks_.empty()) { |
575 VideoCaptureDevice::TakePhotoCallback cb = | 595 VideoCaptureDevice::TakePhotoCallback cb = |
576 std::move(take_photo_callbacks_.front()); | 596 std::move(take_photo_callbacks_.front()); |
577 take_photo_callbacks_.pop(); | 597 take_photo_callbacks_.pop(); |
578 | 598 |
579 mojom::BlobPtr blob = | 599 mojom::BlobPtr blob = |
580 Blobify(buffer_tracker->start(), buffer.bytesused, capture_format_); | 600 Blobify(buffer_tracker->start(), buffer.bytesused, capture_format_); |
581 if (blob) | 601 if (blob) |
582 cb.Run(std::move(blob)); | 602 cb.Run(std::move(blob)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; | 639 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; |
620 return false; | 640 return false; |
621 } | 641 } |
622 start_ = static_cast<uint8_t*>(start); | 642 start_ = static_cast<uint8_t*>(start); |
623 length_ = buffer.length; | 643 length_ = buffer.length; |
624 payload_size_ = 0; | 644 payload_size_ = 0; |
625 return true; | 645 return true; |
626 } | 646 } |
627 | 647 |
628 } // namespace media | 648 } // namespace media |
OLD | NEW |