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
3 // found in the LICENSE file.
5 #ifndef MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_
6 #define MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_
8 #if defined(OS_OPENBSD)
9 #include <sys/videoio.h>
11 #include <linux/videodev2.h>
14 #include "base/files/scoped_file.h"
15 #include "base/memory/ref_counted.h"
16 #include "media/capture/video/video_capture_device.h"
20 // Class doing the actual Linux capture using V4L2 API. V4L2 SPLANE/MPLANE
21 // capture specifics are implemented in derived classes. Created and destroyed
22 // on the owner's thread, otherwise living and operating on |v4l2_task_runner_|.
23 class V4L2CaptureDelegate
24 : public base::RefCountedThreadSafe
<V4L2CaptureDelegate
> {
26 // Creates the appropiate VideoCaptureDelegate according to parameters.
27 static scoped_refptr
<V4L2CaptureDelegate
> CreateV4L2CaptureDelegate(
28 const VideoCaptureDevice::Name
& device_name
,
29 const scoped_refptr
<base::SingleThreadTaskRunner
>& v4l2_task_runner
,
30 int power_line_frequency
);
32 // Retrieves the #planes for a given |fourcc|, or 0 if unknown.
33 static size_t GetNumPlanesForFourCc(uint32_t fourcc
);
34 // Returns the Chrome pixel format for |v4l2_fourcc| or PIXEL_FORMAT_UNKNOWN.
35 static VideoPixelFormat
V4l2FourCcToChromiumPixelFormat(
36 uint32_t v4l2_fourcc
);
38 // Composes a list of usable and supported pixel formats, in order of
39 // preference, with MJPEG prioritised depending on |prefer_mjpeg|.
40 static std::list
<uint32_t> GetListOfUsableFourCcs(bool prefer_mjpeg
);
42 // Forward-to versions of VideoCaptureDevice virtual methods.
43 void AllocateAndStart(int width
,
46 scoped_ptr
<VideoCaptureDevice::Client
> client
);
47 void StopAndDeAllocate();
49 void SetRotation(int rotation
);
52 // Class keeping track of SPLANE/MPLANE V4L2 buffers, mmap()ed on construction
53 // and munmap()ed on destruction. Destruction is syntactically equal for
54 // S/MPLANE but not construction, so this is implemented in derived classes.
55 // Internally it has a vector of planes, which for SPLANE will contain only
57 class BufferTracker
: public base::RefCounted
<BufferTracker
> {
60 // Abstract method to mmap() given |fd| according to |buffer|, planarity
62 virtual bool Init(int fd
, const v4l2_buffer
& buffer
) = 0;
64 uint8_t* const GetPlaneStart(size_t plane
) const {
65 DCHECK_LT(plane
, planes_
.size());
66 return planes_
[plane
].start
;
69 size_t GetPlanePayloadSize(size_t plane
) const {
70 DCHECK_LT(plane
, planes_
.size());
71 return planes_
[plane
].payload_size
;
74 void SetPlanePayloadSize(size_t plane
, size_t payload_size
) {
75 DCHECK_LT(plane
, planes_
.size());
76 DCHECK_LE(payload_size
, planes_
[plane
].length
);
77 planes_
[plane
].payload_size
= payload_size
;
81 friend class base::RefCounted
<BufferTracker
>;
82 virtual ~BufferTracker();
83 // Adds a given mmap()ed plane to |planes_|.
84 void AddMmapedPlane(uint8_t* const start
, size_t length
);
92 std::vector
<Plane
> planes_
;
96 const VideoCaptureDevice::Name
& device_name
,
97 const scoped_refptr
<base::SingleThreadTaskRunner
>& v4l2_task_runner
,
98 int power_line_frequency
);
99 virtual ~V4L2CaptureDelegate();
101 // Creates the necessary, planarity-specific, internal tracking schemes,
102 virtual scoped_refptr
<BufferTracker
> CreateBufferTracker() const = 0;
104 // Fill in |format| with the given parameters, in a planarity dependent way.
105 virtual bool FillV4L2Format(v4l2_format
* format
,
108 uint32_t pixelformat_fourcc
) const = 0;
110 // Finish filling |buffer| struct with planarity-dependent data.
111 virtual void FinishFillingV4L2Buffer(v4l2_buffer
* buffer
) const = 0;
113 // Fetch the number of bytes occupied by data in |buffer| and set to
115 virtual void SetPayloadSize(
116 const scoped_refptr
<BufferTracker
>& buffer_tracker
,
117 const v4l2_buffer
& buffer
) const = 0;
119 // Sends the captured |buffer| to the |client_|, synchronously.
120 virtual void SendBuffer(const scoped_refptr
<BufferTracker
>& buffer_tracker
,
121 const v4l2_format
& format
) const = 0;
123 // A few accessors for SendBuffer()'s to access private member variables.
124 VideoCaptureFormat
capture_format() const { return capture_format_
; }
125 VideoCaptureDevice::Client
* client() const { return client_
.get(); }
126 int rotation() const { return rotation_
; }
129 friend class base::RefCountedThreadSafe
<V4L2CaptureDelegate
>;
131 // Returns the input |fourcc| as a std::string four char representation.
132 static std::string
FourccToString(uint32_t fourcc
);
133 // VIDIOC_QUERYBUFs a buffer from V4L2, creates a BufferTracker for it and
134 // enqueues it (VIDIOC_QBUF) back into V4L2.
135 bool MapAndQueueBuffer(int index
);
136 // Fills all common parts of |buffer|. Delegates to FinishFillingV4L2Buffer()
137 // for filling in the planar-dependent parts.
138 void FillV4L2Buffer(v4l2_buffer
* buffer
, int i
) const;
140 void SetErrorState(const std::string
& reason
);
142 const v4l2_buf_type capture_type_
;
143 const scoped_refptr
<base::SingleThreadTaskRunner
> v4l2_task_runner_
;
144 const VideoCaptureDevice::Name device_name_
;
145 const int power_line_frequency_
;
147 // The following members are only known on AllocateAndStart().
148 VideoCaptureFormat capture_format_
;
149 v4l2_format video_fmt_
;
150 scoped_ptr
<VideoCaptureDevice::Client
> client_
;
151 base::ScopedFD device_fd_
;
153 // Vector of BufferTracker to keep track of mmap()ed pointers and their use.
154 std::vector
<scoped_refptr
<BufferTracker
>> buffer_tracker_pool_
;
159 // Clockwise rotation in degrees. This value should be 0, 90, 180, or 270.
162 DISALLOW_COPY_AND_ASSIGN(V4L2CaptureDelegate
);
167 #endif // MEDIA_VIDEO_CAPTURE_LINUX_V4L2_VIDEO_CAPTURE_DELEGATE_H_