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