1 // Copyright 2014 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.
4 //
5 // This file defines the V4L2Device which is used by the V4L2Decoder and V4L2Encoder classes to
6 // delegate/pass the device specific handling of any of the functionalities.
7 // Note: ported from Chromium commit head: 2f13d62f0c0d, but some parts have been removed.
8 
9 #ifndef ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_H
10 #define ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_H
11 
12 #include <linux/videodev2.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #include <optional>
17 #include <vector>
18 
19 #include <C2Config.h>
20 #include <base/containers/flat_map.h>
21 #include <base/files/scoped_file.h>
22 #include <base/memory/ref_counted.h>
23 
24 #include <ui/Size.h>
25 #include <v4l2_codec2/common/Common.h>
26 #include <v4l2_codec2/common/V4L2DevicePoller.h>
27 #include <v4l2_codec2/common/VideoTypes.h>
28 
29 namespace android {
30 
31 class V4L2Queue;
32 class V4L2BufferRefBase;
33 class V4L2BuffersList;
34 class V4L2DecodeSurface;
35 
36 // Wrapper for the 'v4l2_ext_control' structure.
37 struct V4L2ExtCtrl {
38     V4L2ExtCtrl(uint32_t id);
39     V4L2ExtCtrl(uint32_t id, int32_t val);
40     struct v4l2_ext_control ctrl;
41 };
42 
43 // A unique reference to a buffer for clients to prepare and submit.
44 //
45 // Clients can prepare a buffer for queuing using the methods of this class, and then either queue
46 // it using the Queue() method corresponding to the memory type of the buffer, or drop the reference
47 // to make the buffer available again.
48 class V4L2WritableBufferRef {
49 public:
50     V4L2WritableBufferRef(V4L2WritableBufferRef&& other);
51     V4L2WritableBufferRef() = delete;
52     V4L2WritableBufferRef& operator=(V4L2WritableBufferRef&& other);
53 
54     // Return the memory type of the buffer. Useful to e.g. decide which Queue() method to use.
55     enum v4l2_memory memory() const;
56 
57     // Queue a MMAP buffer. If successful, true is returned and the reference to the buffer is
58     // dropped so this reference becomes invalid. In case of error, false is returned and the buffer
59     // is returned to the free list.
60     bool queueMMap() &&;
61     // Queue a USERPTR buffer, assigning |ptrs| as pointer for each plane. The size of |ptrs| must
62     // be equal to the number of planes of this buffer. If successful, true is returned and the
63     // reference to the buffer is dropped so this reference becomes invalid. In case of error, false
64     // is returned and the buffer is returned to the free list.
65     bool queueUserPtr(const std::vector<void*>& ptrs) &&;
66     // Queue a DMABUF buffer, assigning |fds| as file descriptors for each plane. It is allowed the
67     // number of |fds| might be greater than the number of planes of this buffer. It happens when
68     // the v4l2 pixel format is single planar. The fd of the first plane is only used in that case.
69     // If successful, true is returned and the reference to the buffer is dropped so this reference
70     // becomes invalid. In case of error, false is returned and the buffer is returned to the free
71     // list.
72     bool queueDMABuf(const std::vector<int>& fds) &&;
73 
74     // Returns the number of planes in this buffer.
75     size_t planesCount() const;
76     // Returns the size of the requested |plane|, in bytes.
77     size_t getPlaneSize(const size_t plane) const;
78     // Set the size of the requested |plane|, in bytes. It is only valid for USERPTR and DMABUF
79     // buffers. When using an MMAP buffer, this method triggers an assert and is a no-op for release
80     // builds.
81     void setPlaneSize(const size_t plane, const size_t size);
82     // This method can only be used with MMAP buffers. It will return a pointer to the data of the
83     // |plane|th plane. In case of error (invalid plane index or mapping failed), a nullptr is
84     // returned.
85     void* getPlaneMapping(const size_t plane);
86     // Set the timestamp field for this buffer.
87     void setTimeStamp(const struct timeval& timestamp);
88     // Return the previously-set timestamp field for this buffer.
89     const struct timeval& getTimeStamp() const;
90     // Set the number of bytes used for |plane|.
91     void setPlaneBytesUsed(const size_t plane, const size_t bytesUsed);
92     // Returns the previously-set number of bytes used for |plane|.
93     size_t getPlaneBytesUsed(const size_t plane) const;
94     // Set the data offset for |plane|, in bytes.
95     void setPlaneDataOffset(const size_t plane, const size_t dataOffset);
96 
97     // Return the V4L2 buffer ID of the underlying buffer.
98     size_t bufferId() const;
99 
100     ~V4L2WritableBufferRef();
101 
102 private:
103     friend class V4L2BufferRefFactory;
104 
105     // Do the actual queue operation once the v4l2_buffer structure is properly filled.
106     bool doQueue() &&;
107 
108     V4L2WritableBufferRef(const struct v4l2_buffer& v4l2Buffer, base::WeakPtr<V4L2Queue> queue);
109 
110     V4L2WritableBufferRef(const V4L2WritableBufferRef&) = delete;
111     V4L2WritableBufferRef& operator=(const V4L2WritableBufferRef&) = delete;
112 
113     std::unique_ptr<V4L2BufferRefBase> mBufferData;
114 
115     SEQUENCE_CHECKER(mSequenceChecker);
116 };
117 
118 // A reference to a read-only, dequeued buffer.
119 //
120 // Clients use this class to query the buffer state and content, and are guaranteed that the buffer
121 // will not be reused until all references are destroyed.
122 // All methods of this class must be called from the same sequence, but instances of
123 // V4L2ReadableBuffer objects can be destroyed from any sequence. They can even outlive the V4L2
124 // buffers they originate from. This flexibility is required because V4L2ReadableBufferRefs can be
125 // embedded into VideoFrames, which are then passed to other threads and not necessarily destroyed
126 // before the V4L2Queue buffers are freed.
127 class V4L2ReadableBuffer : public base::RefCountedThreadSafe<V4L2ReadableBuffer> {
128 public:
129     // Returns whether the V4L2_BUF_FLAG_LAST flag is set for this buffer.
130     bool isLast() const;
131     // Returns whether the V4L2_BUF_FLAG_KEYFRAME flag is set for this buffer.
132     bool isKeyframe() const;
133     // Return the timestamp set by the driver on this buffer.
134     struct timeval getTimeStamp() const;
135     // Returns the number of planes in this buffer.
136     size_t planesCount() const;
137     // Returns the number of bytes used for |plane|.
138     size_t getPlaneBytesUsed(size_t plane) const;
139     // Returns the data offset for |plane|.
140     size_t getPlaneDataOffset(size_t plane) const;
141     // This method can only be used with MMAP buffers. It will return a pointer to the data of the
142     // |plane|th plane. In case of error (invalid plane index or mapping failed), a nullptr is
143     // returned.
144     const void* getPlaneMapping(const size_t plane) const;
145 
146     // Return the V4L2 buffer ID of the underlying buffer.
147     size_t bufferId() const;
148 
149 private:
150     friend class V4L2BufferRefFactory;
151     friend class base::RefCountedThreadSafe<V4L2ReadableBuffer>;
152 
153     ~V4L2ReadableBuffer();
154 
155     V4L2ReadableBuffer(const struct v4l2_buffer& v4l2Buffer, base::WeakPtr<V4L2Queue> queue);
156 
157     V4L2ReadableBuffer(const V4L2ReadableBuffer&) = delete;
158     V4L2ReadableBuffer& operator=(const V4L2ReadableBuffer&) = delete;
159 
160     std::unique_ptr<V4L2BufferRefBase> mBufferData;
161 
162     SEQUENCE_CHECKER(mSequenceChecker);
163 };
164 
165 // Shortcut for naming consistency.
166 using V4L2ReadableBufferRef = scoped_refptr<V4L2ReadableBuffer>;
167 
168 class V4L2Device;
169 class V4L2Buffer;
170 
171 // Interface representing a specific queue of a |V4L2Device|. It provides free and queued buffer
172 // management that is commonly required by clients.
173 //
174 // Buffers managed by this class undergo the following cycle:
175 // 1) Allocated buffers are put into a free buffers pool, indicating that they are used neither by
176 //    the client nor the hardware.
177 // 2) The client obtains a unique, writable reference to one of the free  buffers in order to set
178 //    its content and other parameters.
179 // 3) The client then queues the buffer obtained in 2), which invalidates its reference. The buffer
180 //    is now prepared to be processed by the hardware.
181 // 4) Once the hardware is done with the buffer, it is ready to be dequeued by the client. The
182 //    client obtains a read-only, counted reference to the buffer and can read its content and
183 //    metadata, as well as making other references to it. The buffer will not be reused until all
184 //    the references are dropped. Once this happens, the buffer goes back to the free list described
185 //    in 1).
186 class V4L2Queue : public base::RefCountedThreadSafe<V4L2Queue> {
187 public:
188     // Set |fourcc| as the current format on this queue. |size| corresponds to the desired buffer's
189     // dimensions (i.e. width and height members of v4l2_pix_format_mplane (if not applicable, pass
190     // Size()).
191     // |bufferSize| is the desired size in bytes of the buffer for single-planar formats (i.e.
192     // sizeimage of the first plane). It can be set to 0 if not relevant for the desired format.
193     // |stride| is the desired stride in bytes of the buffer (i.e. bytesperline). It can be set to 0
194     // if not relevant or to let the driver decide. If the format could be set, then the
195     // |v4l2_format| reflecting the actual format is returned. It is guaranteed to feature the
196     // specified |fourcc|, but any other parameter (including |size| and |bufferSize| may have been
197     // adjusted by the driver, so the caller must check their values.
198     std::optional<struct v4l2_format> setFormat(uint32_t fourcc, const ui::Size& size,
199                                                 size_t bufferSize,
200                                                 uint32_t stride = 0) WARN_UNUSED_RESULT;
201 
202     // Identical to |setFormat|, but does not actually apply the format, and can be called anytime.
203     // Returns an adjusted V4L2 format if |fourcc| is supported by the queue, or |nullopt| if
204     // |fourcc| is not supported or an ioctl error happened.
205     std::optional<struct v4l2_format> tryFormat(uint32_t fourcc, const ui::Size& size,
206                                                 size_t bufferSize) WARN_UNUSED_RESULT;
207 
208     // Returns the currently set format on the queue. The result is returned as a std::pair where
209     // the first member is the format, or base::nullopt if the format could not be obtained due to
210     // an ioctl error. The second member is only used in case of an error and contains the |errno|
211     // set by the failing ioctl. If the first member is not base::nullopt, the second member will
212     // always be zero.
213     //
214     // If the second member is 0, then the first member is guaranteed to have a valid value. So
215     // clients that are not interested in the precise error message can just check that the first
216     // member is valid and go on.
217     //
218     // This pair is used because not all failures to get the format are necessarily errors, so we
219     // need to way to let the use decide whether it is one or not.
220     std::pair<std::optional<struct v4l2_format>, int> getFormat();
221 
222     // Allocate |count| buffers for the current format of this queue, with a specific |memory|
223     // allocation, and returns the number of buffers allocated or zero if an error occurred, or if
224     // references to any previously allocated buffers are still held by any clients.
225     //
226     // The number of allocated buffers may be larger than the number requested, so callers must
227     // always check the return value.
228     //
229     // Calling this method while buffers are still allocated results in an error.
230     size_t allocateBuffers(size_t count, enum v4l2_memory memory) WARN_UNUSED_RESULT;
231 
232     // Deallocate all buffers previously allocated by |allocateBuffers|. Any references to buffers
233     // previously allocated held by the client must be released, or this call will fail.
234     bool deallocateBuffers();
235 
236     // Returns the memory usage of v4l2 buffers owned by this V4L2Queue which are mapped in user
237     // space memory.
238     size_t getMemoryUsage() const;
239 
240     // Returns |mMemory|, memory type of last buffers allocated by this V4L2Queue.
241     v4l2_memory getMemoryType() const;
242 
243     // Return a reference to a free buffer for the caller to prepare and submit, or nullopt if no
244     // buffer is currently free.
245     //
246     // If the caller discards the returned reference, the underlying buffer is made available to
247     // clients again.
248     std::optional<V4L2WritableBufferRef> getFreeBuffer();
249     std::optional<V4L2WritableBufferRef> getFreeBuffer(size_t requestedBufferId);
250 
251     // Attempt to dequeue a buffer, and return a reference to it if one was available.
252     //
253     // The first element of the returned pair will be false if an error occurred, in which case the
254     // second element will be nullptr. If no error occurred, then the first element will be true and
255     // the second element will contain a reference to the dequeued buffer if one was available, or
256     // nullptr otherwise. Dequeued buffers will not be reused by the driver until all references to
257     // them are dropped.
258     std::pair<bool, V4L2ReadableBufferRef> dequeueBuffer();
259 
260     // Returns true if this queue is currently streaming.
261     bool isStreaming() const;
262     // If not currently streaming, starts streaming. Returns true if we started streaming, or were
263     // already streaming, or false if we were not streaming and an error occurred when attempting to
264     // start the stream. On failure, any previously-queued buffers will be dequeued without
265     // processing and made available to the client, while any buffers held by the client will remain
266     // unchanged and their ownership will remain with the client.
267     bool streamon();
268     // If currently streaming, stops streaming. Also make all queued buffers available to the client
269     // again regardless of the streaming state. If an error occurred while attempting to stop
270     // streaming, then false is returned and queued buffers are left untouched since the V4L2 queue
271     // may still be using them.
272     bool streamoff();
273 
274     // Returns the number of buffers currently allocated for this queue.
275     size_t allocatedBuffersCount() const;
276     // Returns the number of currently free buffers on this queue.
277     size_t freeBuffersCount() const;
278     // Returns the number of buffers currently queued on this queue.
279     size_t queuedBuffersCount() const;
280 
281 private:
282     ~V4L2Queue();
283 
284     V4L2Queue(const V4L2Queue&) = delete;
285     V4L2Queue& operator=(const V4L2Queue&) = delete;
286 
287     // Called when clients request a buffer to be queued.
288     bool queueBuffer(struct v4l2_buffer* v4l2Buffer);
289 
290     const enum v4l2_buf_type mType;
291     enum v4l2_memory mMemory = V4L2_MEMORY_MMAP;
292     bool mIsStreaming = false;
293     size_t mPlanesCount = 0;
294     // Current format as set by SetFormat.
295     std::optional<struct v4l2_format> mCurrentFormat;
296 
297     std::vector<std::unique_ptr<V4L2Buffer>> mBuffers;
298 
299     // Buffers that are available for client to get and submit. Buffers in this list are not
300     // referenced by anyone else than ourselves.
301     scoped_refptr<V4L2BuffersList> mFreeBuffers;
302     // Buffers that have been queued by the client, and not dequeued yet.
303     std::set<size_t> mQueuedBuffers;
304 
305     scoped_refptr<V4L2Device> mDevice;
306     // Callback to call in this queue's destructor.
307     base::OnceClosure mDestroyCb;
308 
309     V4L2Queue(scoped_refptr<V4L2Device> dev, enum v4l2_buf_type type, base::OnceClosure destroyCb);
310     friend class V4L2QueueFactory;
311     friend class V4L2BufferRefBase;
312     friend class base::RefCountedThreadSafe<V4L2Queue>;
313 
314     SEQUENCE_CHECKER(mSequenceChecker);
315 
316     base::WeakPtrFactory<V4L2Queue> mWeakThisFactory{this};
317 };
318 
319 class V4L2Device : public base::RefCountedThreadSafe<V4L2Device> {
320 public:
321     // Specification of an encoding profile supported by an encoder.
322     struct SupportedEncodeProfile {
323         C2Config::profile_t profile = C2Config::PROFILE_UNUSED;
324         ui::Size min_resolution;
325         ui::Size max_resolution;
326         uint32_t max_framerate_numerator = 0;
327         uint32_t max_framerate_denominator = 0;
328     };
329     using SupportedEncodeProfiles = std::vector<SupportedEncodeProfile>;
330 
331     // Specification of a decoding profile supported by an decoder.
332     // |max_resolution| and |min_resolution| are inclusive.
333     struct SupportedDecodeProfile {
334         C2Config::profile_t profile = C2Config::PROFILE_UNUSED;
335         ui::Size max_resolution;
336         ui::Size min_resolution;
337         bool encrypted_only = false;
338     };
339     using SupportedDecodeProfiles = std::vector<SupportedDecodeProfile>;
340 
341     // Utility format conversion functions
342     // If there is no corresponding single- or multi-planar format, returns 0.
343     static uint32_t C2ProfileToV4L2PixFmt(C2Config::profile_t profile, bool sliceBased);
344     static C2Config::profile_t v4L2ProfileToC2Profile(VideoCodec codec, uint32_t profile);
345     std::vector<C2Config::profile_t> v4L2PixFmtToC2Profiles(uint32_t pixFmt, bool isEncoder);
346     // Calculates the largest plane's allocation size requested by a V4L2 device.
347     static ui::Size allocatedSizeFromV4L2Format(const struct v4l2_format& format);
348 
349     // Convert required H264 profile and level to V4L2 enums.
350     static int32_t c2ProfileToV4L2H264Profile(C2Config::profile_t profile);
351     static int32_t h264LevelIdcToV4L2H264Level(uint8_t levelIdc);
352 
353     // Converts v4l2_memory to a string.
354     static const char* v4L2MemoryToString(const v4l2_memory memory);
355 
356     // Returns the printable name of a v4l2_buf_type.
357     static const char* v4L2BufferTypeToString(const enum v4l2_buf_type bufType);
358 
359     // Composes human readable string of v4l2_format.
360     static std::string v4L2FormatToString(const struct v4l2_format& format);
361 
362     // Composes human readable string of v4l2_buffer.
363     static std::string v4L2BufferToString(const struct v4l2_buffer& buffer);
364 
365     // Composes VideoFrameLayout based on v4l2_format. If error occurs, it returns base::nullopt.
366     static std::optional<VideoFrameLayout> v4L2FormatToVideoFrameLayout(
367             const struct v4l2_format& format);
368 
369     // Returns number of planes of |pixFmt|.
370     static size_t getNumPlanesOfV4L2PixFmt(uint32_t pixFmt);
371 
372     enum class Type { kDecoder, kEncoder };
373 
374     // Create and initialize an appropriate V4L2Device instance for the current platform, or return
375     // nullptr if not available.
376     static scoped_refptr<V4L2Device> create();
377 
378     // Open a V4L2 device of |type| for use with |v4l2PixFmt|. Return true on success. The device
379     // will be closed in the destructor.
380     bool open(Type type, uint32_t v4l2PixFmt);
381 
382     // Returns the V4L2Queue corresponding to the requested |type|, or nullptr if the requested
383     // queue type is not supported.
384     scoped_refptr<V4L2Queue> getQueue(enum v4l2_buf_type type);
385 
386     // Parameters and return value are the same as for the standard ioctl() system call.
387     int ioctl(int request, void* arg);
388 
389     // This method sleeps until either:
390     // - SetDevicePollInterrupt() is called (on another thread),
391     // - |pollDevice| is true, and there is new data to be read from the device,
392     //   or an event from the device has arrived; in the latter case
393     //   |*eventPending| will be set to true.
394     // Returns false on error, true otherwise. This method should be called from a separate thread.
395     bool poll(bool pollDevice, bool* eventPending);
396 
397     // These methods are used to interrupt the thread sleeping on poll() and force it to return
398     // regardless of device state, which is usually when the client is no longer interested in what
399     // happens with the device (on cleanup, client state change, etc.). When
400     // setDevicePollInterrupt() is called, poll() will return immediately, and any subsequent calls
401     // to it will also do so until clearDevicePollInterrupt() is called.
402     bool setDevicePollInterrupt();
403     bool clearDevicePollInterrupt();
404 
405     // Wrappers for standard mmap/munmap system calls.
406     void* mmap(void* addr, unsigned int len, int prot, int flags, unsigned int offset);
407     void munmap(void* addr, unsigned int len);
408 
409     // Return a vector of dmabuf file descriptors, exported for V4L2 buffer with |index|, assuming
410     // the buffer contains |numPlanes| V4L2 planes and is of |bufType|. Return an empty vector on
411     // failure. The caller is responsible for closing the file descriptors after use.
412     std::vector<base::ScopedFD> getDmabufsForV4L2Buffer(int index, size_t numPlanes,
413                                                         enum v4l2_buf_type bufType);
414 
415     // Returns the preferred V4L2 input formats for |type| or empty if none.
416     std::vector<uint32_t> preferredInputFormat(Type type);
417 
418     // NOTE: The below methods to query capabilities have a side effect of closing the
419     // previously-open device, if any, and should not be called after Open().
420 
421     // Get minimum and maximum resolution for fourcc |pixelFormat| and store to |minResolution| and
422     // |maxResolution|.
423     void getSupportedResolution(uint32_t pixelFormat, ui::Size* minResolution,
424                                 ui::Size* maxResolution);
425 
426     std::vector<uint32_t> enumerateSupportedPixelformats(v4l2_buf_type bufType);
427 
428     // Return supported profiles for decoder, including only profiles for given fourcc
429     // |pixelFormats|.
430     SupportedDecodeProfiles getSupportedDecodeProfiles(const size_t numFormats,
431                                                        const uint32_t pixelFormats[]);
432 
433     // Return supported profiles for encoder.
434     SupportedEncodeProfiles getSupportedEncodeProfiles();
435 
436     // Start polling on this V4L2Device. |eventCallback| will be posted to the caller's sequence if
437     // a buffer is ready to be dequeued and/or a V4L2 event has been posted. |errorCallback| will
438     // be posted to the client's
439     // sequence if a polling error has occurred.
440     bool startPolling(android::V4L2DevicePoller::EventCallback eventCallback,
441                       base::RepeatingClosure errorCallback);
442     // Stop polling this V4L2Device if polling was active. No new events will be posted after this
443     // method has returned.
444     bool stopPolling();
445     // Schedule a polling event if polling is enabled. This method is intended to be called from
446     // V4L2Queue, clients should not need to call it directly.
447     void schedulePoll();
448 
449     // Check whether the V4L2 control with specified |ctrlId| is supported.
450     bool isCtrlExposed(uint32_t ctrlId);
451     // Set the specified list of |ctrls| for the specified |ctrlClass|, returns whether the
452     // operation succeeded.
453     bool setExtCtrls(uint32_t ctrlClass, std::vector<V4L2ExtCtrl> ctrls);
454 
455     // Check whether the V4L2 command with specified |commandId| is supported.
456     bool isCommandSupported(uint32_t commandId);
457     // Check whether the V4L2 device has the specified |capabilities|.
458     bool hasCapabilities(uint32_t capabilities);
459 
460 private:
461     // Vector of video device node paths and corresponding pixelformats supported by each device node.
462     using Devices = std::vector<std::pair<std::string, std::vector<uint32_t>>>;
463 
464     friend class base::RefCountedThreadSafe<V4L2Device>;
465     V4L2Device();
466     ~V4L2Device();
467 
468     V4L2Device(const V4L2Device&) = delete;
469     V4L2Device& operator=(const V4L2Device&) = delete;
470 
471     SupportedDecodeProfiles enumerateSupportedDecodeProfiles(const size_t numFormats,
472                                                              const uint32_t pixelFormats[]);
473 
474     SupportedEncodeProfiles enumerateSupportedEncodeProfiles();
475 
476     // Open device node for |path| as a device of |type|.
477     bool openDevicePath(const std::string& path, Type type);
478 
479     // Close the currently open device.
480     void closeDevice();
481 
482     // Enumerate all V4L2 devices on the system for |type| and store the results under
483     // mDevicesByType[type].
484     void enumerateDevicesForType(V4L2Device::Type type);
485 
486     // Return device information for all devices of |type| available in the system. Enumerates and
487     // queries devices on first run and caches the results for subsequent calls.
488     const Devices& getDevicesForType(V4L2Device::Type type);
489 
490     // Return device node path for device of |type| supporting |pixFmt|, or an empty string if the
491     // given combination is not supported by the system.
492     std::string getDevicePathFor(V4L2Device::Type type, uint32_t pixFmt);
493 
494     // Callback that is called upon a queue's destruction, to cleanup its pointer in mQueues.
495     void onQueueDestroyed(v4l2_buf_type buf_type);
496 
497     // Stores information for all devices available on the system for each device Type.
498     std::map<V4L2Device::Type, Devices> mDevicesByType;
499 
500     // The actual device fd.
501     base::ScopedFD mDeviceFd;
502 
503     // eventfd fd to signal device poll thread when its poll() should be interrupted.
504     base::ScopedFD mDevicePollInterruptFd;
505 
506     // Associates a v4l2_buf_type to its queue.
507     base::flat_map<enum v4l2_buf_type, V4L2Queue*> mQueues;
508 
509     // Used if EnablePolling() is called to signal the user that an event happened or a buffer is
510     // ready to be dequeued.
511     std::unique_ptr<android::V4L2DevicePoller> mDevicePoller;
512 
513     SEQUENCE_CHECKER(mClientSequenceChecker);
514 };
515 
516 }  // namespace android
517 
518 #endif  // ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_H
519