Chromium Code Reviews| 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 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 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. |
| 28 static scoped_refptr<V4L2CaptureDelegate> CreateV4L2CaptureDelegate( | 28 static scoped_refptr<V4L2CaptureDelegate> CreateV4L2CaptureDelegate( |
| 29 const VideoCaptureDevice::Name& device_name, | 29 const VideoCaptureDevice::Name& device_name, |
| 30 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, | 30 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, |
| 31 VideoCaptureDevice::Client* client, | |
| 31 int power_line_frequency); | 32 int power_line_frequency); |
| 32 | 33 |
| 33 // Retrieves the #planes for a given |fourcc|, or 0 if unknown. | 34 // Retrieves the #planes for a given |fourcc|, or 0 if unknown. |
| 34 static size_t GetNumPlanesForFourCc(uint32_t fourcc); | 35 static size_t GetNumPlanesForFourCc(uint32_t fourcc); |
| 35 // Returns the Chrome pixel format for |v4l2_fourcc| or PIXEL_FORMAT_UNKNOWN. | 36 // Returns the Chrome pixel format for |v4l2_fourcc| or PIXEL_FORMAT_UNKNOWN. |
| 36 static VideoPixelFormat V4l2FourCcToChromiumPixelFormat(uint32_t v4l2_fourcc); | 37 static VideoPixelFormat V4l2FourCcToChromiumPixelFormat(uint32_t v4l2_fourcc); |
| 37 | 38 |
| 38 // Composes a list of usable and supported pixel formats, in order of | 39 // Composes a list of usable and supported pixel formats, in order of |
| 39 // preference, with MJPEG prioritised depending on |prefer_mjpeg|. | 40 // preference, with MJPEG prioritised depending on |prefer_mjpeg|. |
| 40 static std::list<uint32_t> GetListOfUsableFourCcs(bool prefer_mjpeg); | 41 static std::list<uint32_t> GetListOfUsableFourCcs(bool prefer_mjpeg); |
| 41 | 42 |
| 42 // Forward-to versions of VideoCaptureDevice virtual methods. | 43 // Forward-to versions of VideoCaptureDevice virtual methods. |
| 43 void AllocateAndStart(int width, | 44 void AllocateAndStart(int width, |
| 44 int height, | 45 int height, |
| 45 float frame_rate, | 46 float frame_rate, |
| 46 scoped_ptr<VideoCaptureDevice::Client> client); | 47 scoped_ptr<VideoCaptureDevice::Client> client); |
| 47 void StopAndDeAllocate(); | 48 void StopAndDeAllocate(); |
| 48 | 49 |
| 49 void SetRotation(int rotation); | 50 void SetRotation(int rotation); |
| 50 | 51 |
| 51 protected: | 52 protected: |
| 52 // Class keeping track of SPLANE/MPLANE V4L2 buffers, mmap()ed on construction | 53 // Class keeping track of SPLANE/MPLANE V4L2 buffers, mappable or not. Non |
| 53 // and munmap()ed on destruction. Destruction is syntactically equal for | 54 // mappable buffer keep track of the associated |fd|. |
| 54 // S/MPLANE but not construction, so this is implemented in derived classes. | 55 // Mappable buffers are mmap()ed on Init() and munmap()ed on destruction. |
| 56 // Destruction is syntactically equal for S/MPLANE but not construction, so | |
| 57 // this must be implemented in derived classes. | |
| 55 // Internally it has a vector of planes, which for SPLANE will contain only | 58 // Internally it has a vector of planes, which for SPLANE will contain only |
| 56 // one element. | 59 // one element. |
| 57 class BufferTracker : public base::RefCounted<BufferTracker> { | 60 class BufferTracker : public base::RefCounted<BufferTracker> { |
| 58 public: | 61 public: |
| 59 BufferTracker(); | 62 BufferTracker(); |
| 60 // Abstract method to mmap() given |fd| according to |buffer|, planarity | 63 // Abstract method to init the BufferTracker according to |buffer|. |
| 61 // specific. | |
| 62 virtual bool Init(int fd, const v4l2_buffer& buffer) = 0; | 64 virtual bool Init(int fd, const v4l2_buffer& buffer) = 0; |
| 63 | 65 |
| 64 uint8_t* const GetPlaneStart(size_t plane) const { | 66 uint8_t* const GetPlaneStart(size_t plane) const { |
| 65 DCHECK_LT(plane, planes_.size()); | 67 DCHECK_LT(plane, planes_.size()); |
| 66 return planes_[plane].start; | 68 return planes_[plane].start; |
| 67 } | 69 } |
| 70 int const GetFd(size_t plane) const { | |
|
Pawel Osciak
2015/06/15 10:34:55
GetPlaneFd()
Also, please add an empty line above
mcasas
2015/06/17 01:30:53
Done.
| |
| 71 DCHECK_LT(plane, planes_.size()); | |
| 72 return planes_[plane].fd; | |
| 73 } | |
| 68 | 74 |
| 69 size_t GetPlanePayloadSize(size_t plane) const { | 75 size_t GetPlanePayloadSize(size_t plane) const { |
| 70 DCHECK_LT(plane, planes_.size()); | 76 DCHECK_LT(plane, planes_.size()); |
| 71 return planes_[plane].payload_size; | 77 return planes_[plane].payload_size; |
| 72 } | 78 } |
| 73 | 79 |
| 74 void SetPlanePayloadSize(size_t plane, size_t payload_size) { | 80 void SetPlanePayloadSize(size_t plane, size_t payload_size) { |
| 75 DCHECK_LT(plane, planes_.size()); | 81 DCHECK_LT(plane, planes_.size()); |
| 76 DCHECK_LE(payload_size, planes_[plane].length); | 82 DCHECK_LE(payload_size, planes_[plane].length); |
| 77 planes_[plane].payload_size = payload_size; | 83 planes_[plane].payload_size = payload_size; |
| 78 } | 84 } |
| 79 | 85 |
| 80 protected: | 86 protected: |
| 81 friend class base::RefCounted<BufferTracker>; | 87 friend class base::RefCounted<BufferTracker>; |
| 82 virtual ~BufferTracker(); | 88 virtual ~BufferTracker(); |
| 83 // Adds a given mmap()ed plane to |planes_|. | 89 // Adds a given mmap()ed plane to |planes_|. |
| 84 void AddMmapedPlane(uint8_t* const start, size_t length); | 90 void AddMmapedPlane(uint8_t* const start, size_t length); |
| 91 void AddNonMmapedPlane(int fd); | |
| 85 | 92 |
| 86 private: | 93 private: |
| 94 // A Plane can be composed of |start| and |length|, for mappable resources | |
| 95 // (basically, memory), or by a |fd|, for non mappable resources (dma-buf). | |
| 87 struct Plane { | 96 struct Plane { |
| 88 uint8_t* start; | 97 uint8_t* start; |
| 89 size_t length; | 98 size_t length; |
| 90 size_t payload_size; | 99 size_t payload_size; |
| 100 int fd; | |
| 91 }; | 101 }; |
| 92 std::vector<Plane> planes_; | 102 std::vector<Plane> planes_; |
| 93 }; | 103 }; |
| 94 | 104 |
| 95 V4L2CaptureDelegate( | 105 V4L2CaptureDelegate( |
| 96 const VideoCaptureDevice::Name& device_name, | 106 const VideoCaptureDevice::Name& device_name, |
| 97 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, | 107 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, |
| 98 int power_line_frequency); | 108 int power_line_frequency); |
| 99 virtual ~V4L2CaptureDelegate(); | 109 virtual ~V4L2CaptureDelegate(); |
| 100 | 110 |
| 101 // Creates the necessary, planarity-specific, internal tracking schemes, | 111 // Creates the necessary, planarity-specific, internal tracking schemes, |
| 102 virtual scoped_refptr<BufferTracker> CreateBufferTracker() const = 0; | 112 virtual scoped_refptr<BufferTracker> CreateBufferTracker() const = 0; |
| 103 | 113 |
| 104 // Fill in |format| with the given parameters, in a planarity dependent way. | 114 // Fill in |format| with the given parameters, in a planarity dependent way. |
| 105 virtual bool FillV4L2Format(v4l2_format* format, | 115 virtual bool FillV4L2Format(v4l2_format* format, |
| 106 uint32_t width, | 116 uint32_t width, |
| 107 uint32_t height, | 117 uint32_t height, |
| 108 uint32_t pixelformat_fourcc) const = 0; | 118 uint32_t pixelformat_fourcc) const = 0; |
| 109 | 119 |
| 110 // Finish filling |buffer| struct with planarity-dependent data. | 120 // Finish filling |buffer| struct with planarity-dependent data. Underlying |
| 111 virtual void FinishFillingV4L2Buffer(v4l2_buffer* buffer) const = 0; | 121 // implementation might need to know if it's for enqueueing, to allocate |
| 122 // resources. | |
| 123 virtual void FinishFillingV4L2Buffer(v4l2_buffer* buffer, | |
| 124 bool for_enqueue) const = 0; | |
| 125 | |
| 126 // Finish filling in |request| with DmaBuf or normal buffers. | |
| 127 virtual void FinishFillingV4L2RequestBuffers( | |
|
Pawel Osciak
2015/06/15 10:34:55
This could just be a simple memory_type() const ge
mcasas
2015/06/17 01:30:53
Done.
| |
| 128 v4l2_requestbuffers* request) const = 0; | |
| 112 | 129 |
| 113 // Fetch the number of bytes occupied by data in |buffer| and set to | 130 // Fetch the number of bytes occupied by data in |buffer| and set to |
| 114 // |buffer_tracker|. | 131 // |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( |
| 121 const scoped_refptr<BufferTracker>& buffer_tracker, | 138 const scoped_refptr<BufferTracker>& buffer_tracker, |
| 122 const v4l2_format& format) const = 0; | 139 const v4l2_format& format) const = 0; |
| 123 | 140 |
| 124 // A few accessors for SendBuffer()'s to access private member variables. | 141 // A few accessors for SendBuffer()'s to access private member variables. |
| 125 VideoCaptureFormat capture_format() const { return capture_format_; } | 142 VideoCaptureFormat capture_format() const { return capture_format_; } |
| 126 VideoCaptureDevice::Client* client() const { return client_.get(); } | 143 VideoCaptureDevice::Client* client() const { return client_.get(); } |
| 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 |
| 154 // Vector of BufferTracker to keep track of mmap()ed pointers and their use. | 171 // Vector of BufferTracker to keep track of mmap()ed pointers and their use. |
| 155 std::vector<scoped_refptr<BufferTracker>> buffer_tracker_pool_; | 172 std::vector<scoped_refptr<BufferTracker>> buffer_tracker_pool_; |
| 156 | 173 |
| 157 bool is_capturing_; | 174 bool is_capturing_; |
| 158 int timeout_count_; | 175 int timeout_count_; |
| 159 | 176 |
| 160 // Clockwise rotation in degrees. This value should be 0, 90, 180, or 270. | 177 // Clockwise rotation in degrees. This value should be 0, 90, 180, or 270. |
| 161 int rotation_; | 178 int rotation_; |
| 162 | 179 |
| 163 DISALLOW_COPY_AND_ASSIGN(V4L2CaptureDelegate); | 180 DISALLOW_COPY_AND_ASSIGN(V4L2CaptureDelegate); |
| 164 }; | 181 }; |
| 165 | 182 |
| 166 } // namespace media | 183 } // namespace media |
| 167 | 184 |
| 168 #endif // MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ | 185 #endif // MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_ |
| OLD | NEW |