| 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 #ifndef MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ | 5 #ifndef MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ |
| 6 #define MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ | 6 #define MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ |
| 7 | 7 |
| 8 #if defined(OS_OPENBSD) | 8 #if defined(OS_OPENBSD) |
| 9 #include <sys/videoio.h> | 9 #include <sys/videoio.h> |
| 10 #else | 10 #else |
| 11 #include <linux/videodev2.h> | 11 #include <linux/videodev2.h> |
| 12 #endif | 12 #endif |
| 13 | 13 |
| 14 #include "base/files/scoped_file.h" | 14 #include "base/files/scoped_file.h" |
| 15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 16 #include "base/memory/scoped_vector.h" | 16 #include "base/memory/scoped_vector.h" |
| 17 #include "media/video/capture/video_capture_device.h" | 17 #include "media/video/capture/video_capture_device.h" |
| 18 | 18 |
| 19 namespace media { | 19 namespace media { |
| 20 | 20 |
| 21 // Class doing the actual Linux capture using V4L2 API. V4L2 SPLANE/MPLANE | 21 // Class doing the actual Linux capture using V4L2 API. V4L2 SPLANE/MPLANE |
| 22 // capture specifics are implemented in derived classes. Created and destroyed | 22 // capture specifics are implemented in derived classes. Created and destroyed |
| 23 // on the owner's thread, otherwise living and operating on |v4l2_task_runner_|. | 23 // on the owner's thread, otherwise living and operating on |v4l2_task_runner_|. |
| 24 class V4L2CaptureDelegate | 24 class V4L2CaptureDelegate |
| 25 : public base::RefCountedThreadSafe<V4L2CaptureDelegate> { | 25 : public base::RefCountedThreadSafe<V4L2CaptureDelegate> { |
| 26 public: | 26 public: |
| 27 // Creates the appropiate VideoCaptureDelegate according to parameters. | 27 // Creates the appropiate VideoCaptureDelegate according to parameters. The |
| 28 // caller instructs via |allow_using_dma_bufs| if DmaBufs should be used. |
| 28 static scoped_refptr<V4L2CaptureDelegate> CreateV4L2CaptureDelegate( | 29 static scoped_refptr<V4L2CaptureDelegate> CreateV4L2CaptureDelegate( |
| 29 const VideoCaptureDevice::Name& device_name, | 30 const VideoCaptureDevice::Name& device_name, |
| 30 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, | 31 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, |
| 32 VideoCaptureDevice::Client* client, |
| 33 bool allow_using_dma_bufs, |
| 31 int power_line_frequency); | 34 int power_line_frequency); |
| 32 | 35 |
| 33 // Retrieves the #planes for a given |fourcc|, or 0 if unknown. | 36 // Retrieves the #planes for a given |fourcc|, or 0 if unknown. |
| 34 static size_t GetNumPlanesForFourCc(uint32_t fourcc); | 37 static size_t GetNumPlanesForFourCc(uint32_t fourcc); |
| 35 // Returns the Chrome pixel format for |v4l2_fourcc| or PIXEL_FORMAT_UNKNOWN. | 38 // Returns the Chrome pixel format for |v4l2_fourcc| or PIXEL_FORMAT_UNKNOWN. |
| 36 static VideoPixelFormat V4l2FourCcToChromiumPixelFormat(uint32_t v4l2_fourcc); | 39 static VideoPixelFormat V4l2FourCcToChromiumPixelFormat(uint32_t v4l2_fourcc); |
| 37 | 40 |
| 38 // Composes a list of usable and supported pixel formats, in order of | 41 // Composes a list of usable and supported pixel formats, in order of |
| 39 // preference, with MJPEG prioritised depending on |prefer_mjpeg|. | 42 // preference, with MJPEG prioritised depending on |prefer_mjpeg|. |
| 40 static std::list<uint32_t> GetListOfUsableFourCcs(bool prefer_mjpeg); | 43 static std::list<uint32_t> GetListOfUsableFourCcs(bool prefer_mjpeg); |
| 41 | 44 |
| 42 // Forward-to versions of VideoCaptureDevice virtual methods. | 45 // Forward-to versions of VideoCaptureDevice virtual methods. |
| 43 void AllocateAndStart(int width, | 46 void AllocateAndStart(int width, |
| 44 int height, | 47 int height, |
| 45 float frame_rate, | 48 float frame_rate, |
| 46 scoped_ptr<VideoCaptureDevice::Client> client); | 49 scoped_ptr<VideoCaptureDevice::Client> client); |
| 47 void StopAndDeAllocate(); | 50 void StopAndDeAllocate(); |
| 48 | 51 |
| 49 void SetRotation(int rotation); | 52 void SetRotation(int rotation); |
| 50 | 53 |
| 51 protected: | 54 protected: |
| 52 // Class keeping track of SPLANE/MPLANE V4L2 buffers, mmap()ed on construction | 55 // Class keeping track of SPLANE/MPLANE V4L2 buffers, mappable or not. Non |
| 53 // and munmap()ed on destruction. Destruction is syntactically equal for | 56 // mappable buffer keep track of the associated |fd|. |
| 54 // S/MPLANE but not construction, so this is implemented in derived classes. | 57 // Mappable buffers are mmap()ed on Init() and munmap()ed on destruction. |
| 58 // Destruction is syntactically equal for S/MPLANE but not construction, so |
| 59 // this must be implemented in derived classes. |
| 55 // Internally it has a vector of planes, which for SPLANE will contain only | 60 // Internally it has a vector of planes, which for SPLANE will contain only |
| 56 // one element. | 61 // one element. |
| 57 class BufferTracker : public base::RefCounted<BufferTracker> { | 62 class BufferTracker : public base::RefCounted<BufferTracker> { |
| 58 public: | 63 public: |
| 59 BufferTracker(); | 64 BufferTracker(); |
| 60 // Abstract method to mmap() given |fd| according to |buffer|, planarity | 65 // Abstract method to init the BufferTracker according to |buffer|. |
| 61 // specific. | |
| 62 virtual bool Init(int fd, const v4l2_buffer& buffer) = 0; | 66 virtual bool Init(int fd, const v4l2_buffer& buffer) = 0; |
| 63 | 67 |
| 64 uint8_t* const GetPlaneStart(size_t plane) const { | 68 uint8_t* const GetPlaneStart(size_t plane) const { |
| 65 DCHECK_LT(plane, planes_.size()); | 69 DCHECK_LT(plane, planes_.size()); |
| 66 return planes_[plane].start; | 70 return planes_[plane].start; |
| 67 } | 71 } |
| 68 | 72 |
| 73 int const GetPlaneFd(size_t plane) const { |
| 74 DCHECK_LT(plane, planes_.size()); |
| 75 return planes_[plane].fd; |
| 76 } |
| 77 |
| 69 size_t GetPlanePayloadSize(size_t plane) const { | 78 size_t GetPlanePayloadSize(size_t plane) const { |
| 70 DCHECK_LT(plane, planes_.size()); | 79 DCHECK_LT(plane, planes_.size()); |
| 71 return planes_[plane].payload_size; | 80 return planes_[plane].payload_size; |
| 72 } | 81 } |
| 73 | 82 |
| 74 void SetPlanePayloadSize(size_t plane, size_t payload_size) { | 83 void SetPlanePayloadSize(size_t plane, size_t payload_size) { |
| 75 DCHECK_LT(plane, planes_.size()); | 84 DCHECK_LT(plane, planes_.size()); |
| 76 DCHECK_LE(payload_size, planes_[plane].length); | 85 DCHECK_LE(payload_size, planes_[plane].length); |
| 77 planes_[plane].payload_size = payload_size; | 86 planes_[plane].payload_size = payload_size; |
| 78 } | 87 } |
| 79 | 88 |
| 80 protected: | 89 protected: |
| 81 friend class base::RefCounted<BufferTracker>; | 90 friend class base::RefCounted<BufferTracker>; |
| 82 virtual ~BufferTracker(); | 91 virtual ~BufferTracker(); |
| 83 // Adds a given mmap()ed plane to |planes_|. | 92 // Adds a given mmap()ed plane to |planes_|. |
| 84 void AddMmapedPlane(uint8_t* const start, size_t length); | 93 void AddMmapedPlane(uint8_t* const start, size_t length); |
| 94 void AddNonMmapedPlane(int fd); |
| 85 | 95 |
| 86 private: | 96 private: |
| 97 // A Plane can be composed of |start| and |length|, for mappable resources |
| 98 // (basically, memory), or by a |fd and a |capture_buffer|, for non mappable |
| 99 // resources (dma-buf).|length| is needed for munmap(). |
| 87 struct Plane { | 100 struct Plane { |
| 88 uint8_t* start; | 101 uint8_t* start; |
| 89 size_t length; | 102 size_t length; |
| 90 size_t payload_size; | 103 size_t payload_size; |
| 104 int fd; |
| 91 }; | 105 }; |
| 92 std::vector<Plane> planes_; | 106 std::vector<Plane> planes_; |
| 93 }; | 107 }; |
| 94 | 108 |
| 95 V4L2CaptureDelegate( | 109 V4L2CaptureDelegate( |
| 96 const VideoCaptureDevice::Name& device_name, | 110 const VideoCaptureDevice::Name& device_name, |
| 97 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, | 111 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, |
| 112 v4l2_memory memory_type, |
| 98 int power_line_frequency); | 113 int power_line_frequency); |
| 99 virtual ~V4L2CaptureDelegate(); | 114 virtual ~V4L2CaptureDelegate(); |
| 100 | 115 |
| 101 // Creates the necessary, planarity-specific, internal tracking schemes, | 116 // Creates the necessary, planarity-specific, internal tracking schemes, |
| 102 virtual scoped_refptr<BufferTracker> CreateBufferTracker() const = 0; | 117 virtual scoped_refptr<BufferTracker> CreateBufferTracker() const = 0; |
| 103 | 118 |
| 104 // Fill in |format| with the given parameters, in a planarity dependent way. | 119 // Fill in |format| with the given parameters, in a planarity dependent way. |
| 105 virtual bool FillV4L2Format(v4l2_format* format, | 120 virtual bool FillV4L2Format(v4l2_format* format, |
| 106 uint32_t width, | 121 uint32_t width, |
| 107 uint32_t height, | 122 uint32_t height, |
| 108 uint32_t pixelformat_fourcc) const = 0; | 123 uint32_t pixelformat_fourcc) const = 0; |
| 109 | 124 |
| 110 // Finish filling |buffer| struct with planarity-dependent data. | 125 // Finish filling |buffer| struct with planarity-dependent data. Underlying |
| 111 virtual void FinishFillingV4L2Buffer(v4l2_buffer* buffer) const = 0; | 126 // implementation might need to know if it's for enqueueing, to allocate |
| 127 // resources. |
| 128 virtual void FinishFillingV4L2Buffer(v4l2_buffer* buffer, |
| 129 bool for_enqueue) const = 0; |
| 112 | 130 |
| 113 // Fetch the number of bytes occupied by data in |buffer| and set to | 131 // Set |buffer_tracker|s payload size from |buffer|. |
| 114 // |buffer_tracker|. | |
| 115 virtual void SetPayloadSize( | 132 virtual void SetPayloadSize( |
| 116 const scoped_refptr<BufferTracker>& buffer_tracker, | 133 const scoped_refptr<BufferTracker>& buffer_tracker, |
| 117 const v4l2_buffer& buffer) const = 0; | 134 const v4l2_buffer& buffer) const = 0; |
| 118 | 135 |
| 119 // Sends the captured |buffer| to the |client_|, synchronously. | 136 // Sends the captured |buffer| to the |client_|, synchronously. |
| 120 virtual void SendBuffer( | 137 virtual void SendBuffer(const scoped_refptr<BufferTracker>& buffer_tracker, |
| 121 const scoped_refptr<BufferTracker>& buffer_tracker, | 138 const v4l2_format& format) const = 0; |
| 122 const v4l2_format& format) const = 0; | |
| 123 | 139 |
| 124 // A few accessors for SendBuffer()'s to access private member variables. | 140 // A few accessors for SendBuffer()'s to access private member variables. |
| 125 VideoCaptureFormat capture_format() const { return capture_format_; } | 141 VideoCaptureFormat capture_format() const { return capture_format_; } |
| 126 VideoCaptureDevice::Client* client() const { return client_.get(); } | 142 VideoCaptureDevice::Client* client() const { return client_.get(); } |
| 143 v4l2_memory memory_type() const { return memory_type_; } |
| 127 int rotation() const { return rotation_; } | 144 int rotation() const { return rotation_; } |
| 128 | 145 |
| 129 private: | 146 private: |
| 130 friend class base::RefCountedThreadSafe<V4L2CaptureDelegate>; | 147 friend class base::RefCountedThreadSafe<V4L2CaptureDelegate>; |
| 131 | 148 |
| 132 // Returns the input |fourcc| as a std::string four char representation. | 149 // Returns the input |fourcc| as a std::string four char representation. |
| 133 static std::string FourccToString(uint32_t fourcc); | 150 static std::string FourccToString(uint32_t fourcc); |
| 134 // VIDIOC_QUERYBUFs a buffer from V4L2, creates a BufferTracker for it and | 151 // VIDIOC_QUERYBUFs a buffer from V4L2, creates a BufferTracker for it and |
| 135 // enqueues it (VIDIOC_QBUF) back into V4L2. | 152 // enqueues it (VIDIOC_QBUF) back into V4L2. |
| 136 bool MapAndQueueBuffer(int index); | 153 bool MapAndQueueBuffer(int index); |
| 137 // Fills all common parts of |buffer|. Delegates to FinishFillingV4L2Buffer() | 154 // Fills all common parts of |buffer|. Delegates to FinishFillingV4L2Buffer() |
| 138 // for filling in the planar-dependent parts. | 155 // for filling in the planar-dependent parts. |
| 139 void FillV4L2Buffer(v4l2_buffer* buffer, int i) const; | 156 void FillV4L2Buffer(v4l2_buffer* buffer, int i, bool for_enqueue) const; |
| 140 void DoCapture(); | 157 void DoCapture(); |
| 141 void SetErrorState(const std::string& reason); | 158 void SetErrorState(const std::string& reason); |
| 142 | 159 |
| 143 const v4l2_buf_type capture_type_; | 160 const v4l2_buf_type capture_type_; |
| 144 const scoped_refptr<base::SingleThreadTaskRunner> v4l2_task_runner_; | 161 const scoped_refptr<base::SingleThreadTaskRunner> v4l2_task_runner_; |
| 145 const VideoCaptureDevice::Name device_name_; | 162 const VideoCaptureDevice::Name device_name_; |
| 146 const int power_line_frequency_; | 163 const int power_line_frequency_; |
| 147 | 164 |
| 148 // The following members are only known on AllocateAndStart(). | 165 // The following members are only known on AllocateAndStart(). |
| 149 VideoCaptureFormat capture_format_; | 166 VideoCaptureFormat capture_format_; |
| 150 v4l2_format video_fmt_; | 167 v4l2_format video_fmt_; |
| 151 scoped_ptr<VideoCaptureDevice::Client> client_; | 168 scoped_ptr<VideoCaptureDevice::Client> client_; |
| 152 base::ScopedFD device_fd_; | 169 base::ScopedFD device_fd_; |
| 153 | 170 |
| 171 // Memory Type (DmaBuf or Mmap) configured on ctor. |
| 172 const v4l2_memory memory_type_; |
| 173 |
| 154 // Vector of BufferTracker to keep track of mmap()ed pointers and their use. | 174 // Vector of BufferTracker to keep track of mmap()ed pointers and their use. |
| 155 std::vector<scoped_refptr<BufferTracker>> buffer_tracker_pool_; | 175 std::vector<scoped_refptr<BufferTracker>> buffer_tracker_pool_; |
| 156 | 176 |
| 157 bool is_capturing_; | 177 bool is_capturing_; |
| 158 int timeout_count_; | 178 int timeout_count_; |
| 159 | 179 |
| 160 // Clockwise rotation in degrees. This value should be 0, 90, 180, or 270. | 180 // Clockwise rotation in degrees. This value should be 0, 90, 180, or 270. |
| 161 int rotation_; | 181 int rotation_; |
| 162 | 182 |
| 163 DISALLOW_COPY_AND_ASSIGN(V4L2CaptureDelegate); | 183 DISALLOW_COPY_AND_ASSIGN(V4L2CaptureDelegate); |
| 164 }; | 184 }; |
| 165 | 185 |
| 166 } // namespace media | 186 } // namespace media |
| 167 | 187 |
| 168 #endif // MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ | 188 #endif // MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ |
| OLD | NEW |