aboutsummaryrefslogtreecommitdiff
path: root/common/include/v4l2_codec2
diff options
context:
space:
mode:
Diffstat (limited to 'common/include/v4l2_codec2')
-rw-r--r--common/include/v4l2_codec2/common/V4L2Device.h1009
-rw-r--r--common/include/v4l2_codec2/common/V4L2DevicePoller.h139
2 files changed, 524 insertions, 624 deletions
diff --git a/common/include/v4l2_codec2/common/V4L2Device.h b/common/include/v4l2_codec2/common/V4L2Device.h
index fcd34b8..70a72b7 100644
--- a/common/include/v4l2_codec2/common/V4L2Device.h
+++ b/common/include/v4l2_codec2/common/V4L2Device.h
@@ -2,49 +2,35 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// This file defines the V4L2Device interface which is used by the
-// V4L2DecodeAccelerator class to delegate/pass the device specific
-// handling of any of the functionalities.
-// Note: ported from Chromium commit head: 2f13d62f0c0d
-// Note: the complete v4l2 device code is ported from Chromium, but some parts
-// have been removed:
-// - All V4L2 request functionality has been removed, as it required a newer
-// kernel version.
-// - void SetConfigStore() has been removed as it depends on a newer kernel
-// version.
-// - QueueDMABuf() from native pixmap planes has been removed, as
-// NativePixmapPlane have not been ported.
-// - GetVideoFrame() is removed as it depends on some helper functions that have
-// not been ported.
-// - GL-related functionality has been removed: canCreateEGLImageFrom(),
-// CreateEGLImage(), CreateGLImage() and GetTextureTarget()
-// - V4L2PixFmtToDrmFormat() has been removed, as DRM is not supported yet.
-
-#ifndef V4L2_DEVICE_H_
-#define V4L2_DEVICE_H_
+// This file defines the V4L2Device which is used by the V4L2Decoder and V4L2Encoder classes to
+// delegate/pass the device specific handling of any of the functionalities.
+// Note: ported from Chromium commit head: 2f13d62f0c0d, but some parts have been removed.
+
+#ifndef ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_H
+#define ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_H
#include <linux/videodev2.h>
#include <stddef.h>
#include <stdint.h>
-#include <queue>
+#include <optional>
#include <vector>
-#include "base/containers/flat_map.h"
-#include "base/files/scoped_file.h"
-#include "base/memory/ref_counted.h"
+#include <base/containers/flat_map.h>
+#include <base/files/scoped_file.h>
+#include <base/memory/ref_counted.h>
-#include "fourcc.h"
-#include "size.h"
-#include "video_codecs.h"
-#include "video_decode_accelerator.h"
-#include "video_encode_accelerator.h"
-#include "video_frame.h"
-#include "video_frame_layout.h"
-#include "video_pixel_format.h"
-#include "v4l2_codec2/common/V4L2DevicePoller.h"
+#include <fourcc.h>
+#include <size.h>
+#include <v4l2_codec2/common/V4L2DevicePoller.h>
+#include <video_codecs.h>
+#include <video_decode_accelerator.h>
+#include <video_encode_accelerator.h>
+#include <video_frame.h>
+#include <video_frame_layout.h>
+#include <video_pixel_format.h>
-namespace media {
+namespace android {
class V4L2Queue;
class V4L2BufferRefBase;
@@ -53,154 +39,131 @@ class V4L2DecodeSurface;
// Wrapper for the 'v4l2_ext_control' structure.
struct V4L2ExtCtrl {
- V4L2ExtCtrl(uint32_t id);
- V4L2ExtCtrl(uint32_t id, int32_t val);
- struct v4l2_ext_control ctrl;
+ V4L2ExtCtrl(uint32_t id);
+ V4L2ExtCtrl(uint32_t id, int32_t val);
+ struct v4l2_ext_control ctrl;
};
// A unique reference to a buffer for clients to prepare and submit.
//
-// Clients can prepare a buffer for queuing using the methods of this class, and
-// then either queue it using the Queue() method corresponding to the memory
-// type of the buffer, or drop the reference to make the buffer available again.
+// Clients can prepare a buffer for queuing using the methods of this class, and then either queue
+// it using the Queue() method corresponding to the memory type of the buffer, or drop the reference
+// to make the buffer available again.
class V4L2WritableBufferRef {
- public:
- V4L2WritableBufferRef(V4L2WritableBufferRef&& other);
- V4L2WritableBufferRef() = delete;
- V4L2WritableBufferRef& operator=(V4L2WritableBufferRef&& other);
-
- // Return the memory type of the buffer. Useful to e.g. decide which Queue()
- // method to use.
- enum v4l2_memory Memory() const;
-
- // Queue a MMAP buffer.
- // If successful, true is returned and the reference to the buffer is dropped
- // so this reference becomes invalid.
- // In case of error, false is returned and the buffer is returned to the free
- // list.
- bool QueueMMap() &&;
- // Queue a USERPTR buffer, assigning |ptrs| as pointer for each plane.
- // The size of |ptrs| must be equal to the number of planes of this buffer.
- // If successful, true is returned and the reference to the buffer is dropped
- // so this reference becomes invalid.
- // In case of error, false is returned and the buffer is returned to the free
- // list.
- bool QueueUserPtr(const std::vector<void*>& ptrs) &&;
- // Queue a DMABUF buffer, assigning |fds| as file descriptors for each plane.
- // It is allowed the number of |fds| might be greater than the number of
- // planes of this buffer. It happens when the v4l2 pixel format is single
- // planar. The fd of the first plane is only used in that case.
- // If successful, true is returned and the reference to the buffer is dropped
- // so this reference becomes invalid.
- // In case of error, false is returned and the buffer is returned to the free
- // list.
- bool QueueDMABuf(const std::vector<base::ScopedFD>& scoped_fds) &&;
- // Queue a DMABUF buffer, assigning |fds| as file descriptors for each plane.
- // It is allowed the number of |fds| might be greater than the number of
- // planes of this buffer. It happens when the v4l2 pixel format is single
- // planar. The fd of the first plane is only used in that case.
- // If successful, true is returned and the reference to the buffer is dropped
- // so this reference becomes invalid.
- // In case of error, false is returned and the buffer is returned to the free
- // list.
- bool QueueDMABuf(const std::vector<int>& fds) &&;
-
- // Returns the number of planes in this buffer.
- size_t PlanesCount() const;
- // Returns the size of the requested |plane|, in bytes.
- size_t GetPlaneSize(const size_t plane) const;
- // Set the size of the requested |plane|, in bytes. It is only valid for
- // USERPTR and DMABUF buffers. When using MMAP buffer, this method triggers a
- // DCHECK and is a no-op for release builds.
- void SetPlaneSize(const size_t plane, const size_t size);
- // This method can only be used with MMAP buffers.
- // It will return a pointer to the data of the |plane|th plane.
- // In case of error (invalid plane index or mapping failed), a nullptr is
- // returned.
- void* GetPlaneMapping(const size_t plane);
- // Set the timestamp field for this buffer.
- void SetTimeStamp(const struct timeval& timestamp);
- // Return the previously-set timestamp field for this buffer.
- const struct timeval& GetTimeStamp() const;
- // Set the number of bytes used for |plane|.
- void SetPlaneBytesUsed(const size_t plane, const size_t bytes_used);
- // Returns the previously-set number of bytes used for |plane|.
- size_t GetPlaneBytesUsed(const size_t plane) const;
- // Set the data offset for |plane|, in bytes.
- void SetPlaneDataOffset(const size_t plane, const size_t data_offset);
-
- // Return the V4L2 buffer ID of the underlying buffer.
- // TODO(acourbot) This is used for legacy clients but should be ultimately
- // removed. See crbug/879971
- size_t BufferId() const;
-
- ~V4L2WritableBufferRef();
-
- private:
- // Do the actual queue operation once the v4l2_buffer structure is properly
- // filled.
- bool DoQueue() &&;
-
- V4L2WritableBufferRef(const struct v4l2_buffer& v4l2_buffer,
- base::WeakPtr<V4L2Queue> queue);
- friend class V4L2BufferRefFactory;
-
- std::unique_ptr<V4L2BufferRefBase> buffer_data_;
-
- SEQUENCE_CHECKER(sequence_checker_);
- DISALLOW_COPY_AND_ASSIGN(V4L2WritableBufferRef);
+public:
+ V4L2WritableBufferRef(V4L2WritableBufferRef&& other);
+ V4L2WritableBufferRef() = delete;
+ V4L2WritableBufferRef& operator=(V4L2WritableBufferRef&& other);
+
+ // Return the memory type of the buffer. Useful to e.g. decide which Queue() method to use.
+ enum v4l2_memory memory() const;
+
+ // Queue a MMAP buffer. If successful, true is returned and the reference to the buffer is
+ // dropped so this reference becomes invalid. In case of error, false is returned and the buffer
+ // is returned to the free list.
+ bool queueMMap() &&;
+ // Queue a USERPTR buffer, assigning |ptrs| as pointer for each plane. The size of |ptrs| must
+ // be equal to the number of planes of this buffer. If successful, true is returned and the
+ // reference to the buffer is dropped so this reference becomes invalid. In case of error, false
+ // is returned and the buffer is returned to the free list.
+ bool queueUserPtr(const std::vector<void*>& ptrs) &&;
+ // Queue a DMABUF buffer, assigning |fds| as file descriptors for each plane. It is allowed the
+ // number of |fds| might be greater than the number of planes of this buffer. It happens when
+ // the v4l2 pixel format is single planar. The fd of the first plane is only used in that case.
+ // If successful, true is returned and the reference to the buffer is dropped so this reference
+ // becomes invalid. In case of error, false is returned and the buffer is returned to the free
+ // list.
+ bool queueDMABuf(const std::vector<int>& fds) &&;
+
+ // Returns the number of planes in this buffer.
+ size_t planesCount() const;
+ // Returns the size of the requested |plane|, in bytes.
+ size_t getPlaneSize(const size_t plane) const;
+ // Set the size of the requested |plane|, in bytes. It is only valid for USERPTR and DMABUF
+ // buffers. When using an MMAP buffer, this method triggers an assert and is a no-op for release
+ // builds.
+ void setPlaneSize(const size_t plane, const size_t size);
+ // This method can only be used with MMAP buffers. It will return a pointer to the data of the
+ // |plane|th plane. In case of error (invalid plane index or mapping failed), a nullptr is
+ // returned.
+ void* getPlaneMapping(const size_t plane);
+ // Set the timestamp field for this buffer.
+ void setTimeStamp(const struct timeval& timestamp);
+ // Return the previously-set timestamp field for this buffer.
+ const struct timeval& getTimeStamp() const;
+ // Set the number of bytes used for |plane|.
+ void setPlaneBytesUsed(const size_t plane, const size_t bytesUsed);
+ // Returns the previously-set number of bytes used for |plane|.
+ size_t getPlaneBytesUsed(const size_t plane) const;
+ // Set the data offset for |plane|, in bytes.
+ void setPlaneDataOffset(const size_t plane, const size_t dataOffset);
+
+ // Return the V4L2 buffer ID of the underlying buffer.
+ size_t bufferId() const;
+
+ ~V4L2WritableBufferRef();
+
+private:
+ friend class V4L2BufferRefFactory;
+
+ // Do the actual queue operation once the v4l2_buffer structure is properly filled.
+ bool doQueue() &&;
+
+ V4L2WritableBufferRef(const struct v4l2_buffer& v4l2Buffer, base::WeakPtr<V4L2Queue> queue);
+
+ V4L2WritableBufferRef(const V4L2WritableBufferRef&) = delete;
+ V4L2WritableBufferRef& operator=(const V4L2WritableBufferRef&) = delete;
+
+ std::unique_ptr<V4L2BufferRefBase> mBufferData;
+
+ SEQUENCE_CHECKER(mSequenceChecker);
};
// A reference to a read-only, dequeued buffer.
//
-// Clients use this class to query the buffer state and content, and are
-// guaranteed that the buffer will not be reused until all references are
-// destroyed.
-// All methods of this class must be called from the same sequence, but
-// instances of V4L2ReadableBuffer objects can be destroyed from any sequence.
-// They can even outlive the V4L2 buffers they originate from. This flexibility
-// is required because V4L2ReadableBufferRefs can be embedded into VideoFrames,
-// which are then passed to other threads and not necessarily destroyed before
-// the V4L2Queue buffers are freed.
-class V4L2ReadableBuffer
- : public base::RefCountedThreadSafe<V4L2ReadableBuffer> {
- public:
- // Returns whether the V4L2_BUF_FLAG_LAST flag is set for this buffer.
- bool IsLast() const;
- // Returns whether the V4L2_BUF_FLAG_KEYFRAME flag is set for this buffer.
- bool IsKeyframe() const;
- // Return the timestamp set by the driver on this buffer.
- struct timeval GetTimeStamp() const;
- // Returns the number of planes in this buffer.
- size_t PlanesCount() const;
- // Returns the number of bytes used for |plane|.
- size_t GetPlaneBytesUsed(size_t plane) const;
- // Returns the data offset for |plane|.
- size_t GetPlaneDataOffset(size_t plane) const;
- // This method can only be used with MMAP buffers.
- // It will return a pointer to the data of the |plane|th plane.
- // In case of error (invalid plane index or mapping failed), a nullptr is
- // returned.
- const void* GetPlaneMapping(const size_t plane) const;
-
- // Return the V4L2 buffer ID of the underlying buffer.
- // TODO(acourbot) This is used for legacy clients but should be ultimately
- // removed. See crbug/879971
- size_t BufferId() const;
-
- private:
- friend class V4L2BufferRefFactory;
- friend class base::RefCountedThreadSafe<V4L2ReadableBuffer>;
-
- ~V4L2ReadableBuffer();
-
- V4L2ReadableBuffer(const struct v4l2_buffer& v4l2_buffer,
- base::WeakPtr<V4L2Queue> queue);
-
- std::unique_ptr<V4L2BufferRefBase> buffer_data_;
-
- SEQUENCE_CHECKER(sequence_checker_);
- DISALLOW_COPY_AND_ASSIGN(V4L2ReadableBuffer);
+// Clients use this class to query the buffer state and content, and are guaranteed that the buffer
+// will not be reused until all references are destroyed.
+// All methods of this class must be called from the same sequence, but instances of
+// V4L2ReadableBuffer objects can be destroyed from any sequence. They can even outlive the V4L2
+// buffers they originate from. This flexibility is required because V4L2ReadableBufferRefs can be
+// embedded into VideoFrames, which are then passed to other threads and not necessarily destroyed
+// before the V4L2Queue buffers are freed.
+class V4L2ReadableBuffer : public base::RefCountedThreadSafe<V4L2ReadableBuffer> {
+public:
+ // Returns whether the V4L2_BUF_FLAG_LAST flag is set for this buffer.
+ bool isLast() const;
+ // Returns whether the V4L2_BUF_FLAG_KEYFRAME flag is set for this buffer.
+ bool isKeyframe() const;
+ // Return the timestamp set by the driver on this buffer.
+ struct timeval getTimeStamp() const;
+ // Returns the number of planes in this buffer.
+ size_t planesCount() const;
+ // Returns the number of bytes used for |plane|.
+ size_t getPlaneBytesUsed(size_t plane) const;
+ // Returns the data offset for |plane|.
+ size_t getPlaneDataOffset(size_t plane) const;
+ // This method can only be used with MMAP buffers. It will return a pointer to the data of the
+ // |plane|th plane. In case of error (invalid plane index or mapping failed), a nullptr is
+ // returned.
+ const void* getPlaneMapping(const size_t plane) const;
+
+ // Return the V4L2 buffer ID of the underlying buffer.
+ size_t bufferId() const;
+
+private:
+ friend class V4L2BufferRefFactory;
+ friend class base::RefCountedThreadSafe<V4L2ReadableBuffer>;
+
+ ~V4L2ReadableBuffer();
+
+ V4L2ReadableBuffer(const struct v4l2_buffer& v4l2Buffer, base::WeakPtr<V4L2Queue> queue);
+
+ V4L2ReadableBuffer(const V4L2ReadableBuffer&) = delete;
+ V4L2ReadableBuffer& operator=(const V4L2ReadableBuffer&) = delete;
+
+ std::unique_ptr<V4L2BufferRefBase> mBufferData;
+
+ SEQUENCE_CHECKER(mSequenceChecker);
};
// Shortcut for naming consistency.
@@ -209,389 +172,335 @@ using V4L2ReadableBufferRef = scoped_refptr<V4L2ReadableBuffer>;
class V4L2Device;
class V4L2Buffer;
-// Interface representing a specific queue of a |V4L2Device|. It provides free
-// and queued buffer management that is commonly required by clients.
+// Interface representing a specific queue of a |V4L2Device|. It provides free and queued buffer
+// management that is commonly required by clients.
//
// Buffers managed by this class undergo the following cycle:
-// 1) Allocated buffers are put into a free buffers pool, indicating that they
-// are used neither by the client nor the hardware.
-// 2) The client obtains a unique, writable reference to one of the free
-// buffers in order to set its content and other parameters.
-// 3) The client then queues the buffer obtained in 2), which invalidates its
-// reference. The buffer is now prepared to be processed by the hardware.
-// 4) Once the hardware is done with the buffer, it is ready to be dequeued by
-// the client. The client obtains a read-only, counted reference to the
-// buffer and can read its content and metadata, as well as making other
-// references to it. The buffer will not be reused until all the references
-// are dropped. Once this happens, the buffer goes back to the free list
-// described in 1).
+// 1) Allocated buffers are put into a free buffers pool, indicating that they are used neither by
+// the client nor the hardware.
+// 2) The client obtains a unique, writable reference to one of the free buffers in order to set
+// its content and other parameters.
+// 3) The client then queues the buffer obtained in 2), which invalidates its reference. The buffer
+// is now prepared to be processed by the hardware.
+// 4) Once the hardware is done with the buffer, it is ready to be dequeued by the client. The
+// client obtains a read-only, counted reference to the buffer and can read its content and
+// metadata, as well as making other references to it. The buffer will not be reused until all
+// the references are dropped. Once this happens, the buffer goes back to the free list described
+// in 1).
class V4L2Queue : public base::RefCountedThreadSafe<V4L2Queue> {
- public:
- // Set |fourcc| as the current format on this queue. |size| corresponds to the
- // desired buffer's dimensions (i.e. width and height members of
- // v4l2_pix_format_mplane (if not applicable, pass Size()).
- // |buffer_size| is the desired size in bytes of the buffer for single-planar
- // formats (i.e. sizeimage of the first plane). It can be set to 0 if not
- // relevant for the desired format.
- // |stride| is the desired stride in bytes of the buffer (i.e. bytesperline).
- // It can be set to 0 if not relevant or to let the driver decide.
- // If the format could be set, then the |v4l2_format| reflecting the actual
- // format is returned. It is guaranteed to feature the specified |fourcc|,
- // but any other parameter (including |size| and |buffer_size| may have been
- // adjusted by the driver, so the caller must check their values.
- base::Optional<struct v4l2_format> SetFormat(uint32_t fourcc,
- const Size& size,
- size_t buffer_size,
- uint32_t stride = 0)
- WARN_UNUSED_RESULT;
-
- // Identical to |SetFormat|, but does not actually apply the format, and can
- // be called anytime.
- // Returns an adjusted V4L2 format if |fourcc| is supported by the queue, or
- // |nullopt| if |fourcc| is not supported or an ioctl error happened.
- base::Optional<struct v4l2_format> TryFormat(uint32_t fourcc,
- const Size& size,
- size_t buffer_size)
- WARN_UNUSED_RESULT;
-
- // Returns the currently set format on the queue. The result is returned as
- // a std::pair where the first member is the format, or base::nullopt if the
- // format could not be obtained due to an ioctl error. The second member is
- // only used in case of an error and contains the |errno| set by the failing
- // ioctl. If the first member is not base::nullopt, the second member will
- // always be zero.
- //
- // If the second member is 0, then the first member is guaranteed to have
- // a valid value. So clients that are not interested in the precise error
- // message can just check that the first member is valid and go on.
- //
- // This pair is used because not all failures to get the format are
- // necessarily errors, so we need to way to let the use decide whether it
- // is one or not.
- std::pair<base::Optional<struct v4l2_format>, int> GetFormat();
-
- // Allocate |count| buffers for the current format of this queue, with a
- // specific |memory| allocation, and returns the number of buffers allocated
- // or zero if an error occurred, or if references to any previously allocated
- // buffers are still held by any clients.
- //
- // The number of allocated buffers may be larger than the number requested, so
- // callers must always check the return value.
- //
- // Calling this method while buffers are still allocated results in an error.
- size_t AllocateBuffers(size_t count,
- enum v4l2_memory memory) WARN_UNUSED_RESULT;
-
- // Deallocate all buffers previously allocated by |AllocateBuffers|. Any
- // references to buffers previously allocated held by the client must be
- // released, or this call will fail.
- bool DeallocateBuffers();
-
- // Returns the memory usage of v4l2 buffers owned by this V4L2Queue which are
- // mapped in user space memory.
- size_t GetMemoryUsage() const;
-
- // Returns |memory_|, memory type of last buffers allocated by this V4L2Queue.
- v4l2_memory GetMemoryType() const;
-
- // Return a reference to a free buffer for the caller to prepare and submit,
- // or nullopt if no buffer is currently free.
- //
- // If the caller discards the returned reference, the underlying buffer is
- // made available to clients again.
- base::Optional<V4L2WritableBufferRef> GetFreeBuffer();
- base::Optional<V4L2WritableBufferRef> GetFreeBuffer(
- size_t requested_buffer_id);
-
- // Attempt to dequeue a buffer, and return a reference to it if one was
- // available.
- //
- // The first element of the returned pair will be false if an error occurred,
- // in which case the second element will be nullptr. If no error occurred,
- // then the first element will be true and the second element will contain a
- // reference to the dequeued buffer if one was available, or nullptr
- // otherwise.
- // Dequeued buffers will not be reused by the driver until all references to
- // them are dropped.
- std::pair<bool, V4L2ReadableBufferRef> DequeueBuffer();
-
- // Returns true if this queue is currently streaming.
- bool IsStreaming() const;
- // If not currently streaming, starts streaming. Returns true if we started
- // streaming, or were already streaming, or false if we were not streaming
- // and an error occurred when attempting to start the stream. On failure, any
- // previously-queued buffers will be dequeued without processing and made
- // available to the client, while any buffers held by the client will remain
- // unchanged and their ownership will remain with the client.
- bool Streamon();
- // If currently streaming, stops streaming. Also make all queued buffers
- // available to the client again regardless of the streaming state.
- // If an error occurred while attempting to stop streaming, then false is
- // returned and queued buffers are left untouched since the V4L2 queue may
- // still be using them.
- bool Streamoff();
-
- // Returns the number of buffers currently allocated for this queue.
- size_t AllocatedBuffersCount() const;
- // Returns the number of currently free buffers on this queue.
- size_t FreeBuffersCount() const;
- // Returns the number of buffers currently queued on this queue.
- size_t QueuedBuffersCount() const;
-
- private:
- ~V4L2Queue();
-
- // Called when clients request a buffer to be queued.
- bool QueueBuffer(struct v4l2_buffer* v4l2_buffer);
-
- const enum v4l2_buf_type type_;
- enum v4l2_memory memory_ = V4L2_MEMORY_MMAP;
- bool is_streaming_ = false;
- size_t planes_count_ = 0;
- // Current format as set by SetFormat.
- base::Optional<struct v4l2_format> current_format_;
-
- std::vector<std::unique_ptr<V4L2Buffer>> buffers_;
-
- // Buffers that are available for client to get and submit.
- // Buffers in this list are not referenced by anyone else than ourselves.
- scoped_refptr<V4L2BuffersList> free_buffers_;
- // Buffers that have been queued by the client, and not dequeued yet.
- std::set<size_t> queued_buffers_;
-
- scoped_refptr<V4L2Device> device_;
- // Callback to call in this queue's destructor.
- base::OnceClosure destroy_cb_;
-
- V4L2Queue(scoped_refptr<V4L2Device> dev,
- enum v4l2_buf_type type,
- base::OnceClosure destroy_cb);
- friend class V4L2QueueFactory;
- friend class V4L2BufferRefBase;
- friend class base::RefCountedThreadSafe<V4L2Queue>;
-
- SEQUENCE_CHECKER(sequence_checker_);
-
- base::WeakPtrFactory<V4L2Queue> weak_this_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(V4L2Queue);
+public:
+ // Set |fourcc| as the current format on this queue. |size| corresponds to the desired buffer's
+ // dimensions (i.e. width and height members of v4l2_pix_format_mplane (if not applicable, pass
+ // Size()).
+ // |bufferSize| is the desired size in bytes of the buffer for single-planar formats (i.e.
+ // sizeimage of the first plane). It can be set to 0 if not relevant for the desired format.
+ // |stride| is the desired stride in bytes of the buffer (i.e. bytesperline). It can be set to 0
+ // if not relevant or to let the driver decide. If the format could be set, then the
+ // |v4l2_format| reflecting the actual format is returned. It is guaranteed to feature the
+ // specified |fourcc|, but any other parameter (including |size| and |bufferSize| may have been
+ // adjusted by the driver, so the caller must check their values.
+ std::optional<struct v4l2_format> setFormat(uint32_t fourcc, const media::Size& size,
+ size_t bufferSize,
+ uint32_t stride = 0) WARN_UNUSED_RESULT;
+
+ // Identical to |setFormat|, but does not actually apply the format, and can be called anytime.
+ // Returns an adjusted V4L2 format if |fourcc| is supported by the queue, or |nullopt| if
+ // |fourcc| is not supported or an ioctl error happened.
+ std::optional<struct v4l2_format> tryFormat(uint32_t fourcc, const media::Size& size,
+ size_t bufferSize) WARN_UNUSED_RESULT;
+
+ // Returns the currently set format on the queue. The result is returned as a std::pair where
+ // the first member is the format, or base::nullopt if the format could not be obtained due to
+ // an ioctl error. The second member is only used in case of an error and contains the |errno|
+ // set by the failing ioctl. If the first member is not base::nullopt, the second member will
+ // always be zero.
+ //
+ // If the second member is 0, then the first member is guaranteed to have a valid value. So
+ // clients that are not interested in the precise error message can just check that the first
+ // member is valid and go on.
+ //
+ // This pair is used because not all failures to get the format are necessarily errors, so we
+ // need to way to let the use decide whether it is one or not.
+ std::pair<std::optional<struct v4l2_format>, int> getFormat();
+
+ // Allocate |count| buffers for the current format of this queue, with a specific |memory|
+ // allocation, and returns the number of buffers allocated or zero if an error occurred, or if
+ // references to any previously allocated buffers are still held by any clients.
+ //
+ // The number of allocated buffers may be larger than the number requested, so callers must
+ // always check the return value.
+ //
+ // Calling this method while buffers are still allocated results in an error.
+ size_t allocateBuffers(size_t count, enum v4l2_memory memory) WARN_UNUSED_RESULT;
+
+ // Deallocate all buffers previously allocated by |allocateBuffers|. Any references to buffers
+ // previously allocated held by the client must be released, or this call will fail.
+ bool deallocateBuffers();
+
+ // Returns the memory usage of v4l2 buffers owned by this V4L2Queue which are mapped in user
+ // space memory.
+ size_t getMemoryUsage() const;
+
+ // Returns |mMemory|, memory type of last buffers allocated by this V4L2Queue.
+ v4l2_memory getMemoryType() const;
+
+ // Return a reference to a free buffer for the caller to prepare and submit, or nullopt if no
+ // buffer is currently free.
+ //
+ // If the caller discards the returned reference, the underlying buffer is made available to
+ // clients again.
+ std::optional<V4L2WritableBufferRef> getFreeBuffer();
+ std::optional<V4L2WritableBufferRef> getFreeBuffer(size_t requestedBufferId);
+
+ // Attempt to dequeue a buffer, and return a reference to it if one was available.
+ //
+ // The first element of the returned pair will be false if an error occurred, in which case the
+ // second element will be nullptr. If no error occurred, then the first element will be true and
+ // the second element will contain a reference to the dequeued buffer if one was available, or
+ // nullptr otherwise. Dequeued buffers will not be reused by the driver until all references to
+ // them are dropped.
+ std::pair<bool, V4L2ReadableBufferRef> dequeueBuffer();
+
+ // Returns true if this queue is currently streaming.
+ bool isStreaming() const;
+ // If not currently streaming, starts streaming. Returns true if we started streaming, or were
+ // already streaming, or false if we were not streaming and an error occurred when attempting to
+ // start the stream. On failure, any previously-queued buffers will be dequeued without
+ // processing and made available to the client, while any buffers held by the client will remain
+ // unchanged and their ownership will remain with the client.
+ bool streamon();
+ // If currently streaming, stops streaming. Also make all queued buffers available to the client
+ // again regardless of the streaming state. If an error occurred while attempting to stop
+ // streaming, then false is returned and queued buffers are left untouched since the V4L2 queue
+ // may still be using them.
+ bool streamoff();
+
+ // Returns the number of buffers currently allocated for this queue.
+ size_t allocatedBuffersCount() const;
+ // Returns the number of currently free buffers on this queue.
+ size_t freeBuffersCount() const;
+ // Returns the number of buffers currently queued on this queue.
+ size_t queuedBuffersCount() const;
+
+private:
+ ~V4L2Queue();
+
+ V4L2Queue(const V4L2Queue&) = delete;
+ V4L2Queue& operator=(const V4L2Queue&) = delete;
+
+ // Called when clients request a buffer to be queued.
+ bool queueBuffer(struct v4l2_buffer* v4l2Buffer);
+
+ const enum v4l2_buf_type mType;
+ enum v4l2_memory mMemory = V4L2_MEMORY_MMAP;
+ bool mIsStreaming = false;
+ size_t mPlanesCount = 0;
+ // Current format as set by SetFormat.
+ std::optional<struct v4l2_format> mCurrentFormat;
+
+ std::vector<std::unique_ptr<V4L2Buffer>> mBuffers;
+
+ // Buffers that are available for client to get and submit. Buffers in this list are not
+ // referenced by anyone else than ourselves.
+ scoped_refptr<V4L2BuffersList> mFreeBuffers;
+ // Buffers that have been queued by the client, and not dequeued yet.
+ std::set<size_t> mQueuedBuffers;
+
+ scoped_refptr<V4L2Device> mDevice;
+ // Callback to call in this queue's destructor.
+ base::OnceClosure mDestroyCb;
+
+ V4L2Queue(scoped_refptr<V4L2Device> dev, enum v4l2_buf_type type, base::OnceClosure destroyCb);
+ friend class V4L2QueueFactory;
+ friend class V4L2BufferRefBase;
+ friend class base::RefCountedThreadSafe<V4L2Queue>;
+
+ SEQUENCE_CHECKER(mSequenceChecker);
+
+ base::WeakPtrFactory<V4L2Queue> mWeakThisFactory{this};
};
class V4L2Device : public base::RefCountedThreadSafe<V4L2Device> {
- public:
- // Utility format conversion functions
- // If there is no corresponding single- or multi-planar format, returns 0.
- static uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
- bool slice_based);
- static VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec,
- uint32_t profile);
- std::vector<VideoCodecProfile> V4L2PixFmtToVideoCodecProfiles(
- uint32_t pix_fmt,
- bool is_encoder);
- // Calculates the largest plane's allocation size requested by a V4L2 device.
- static Size AllocatedSizeFromV4L2Format(const struct v4l2_format& format);
-
- // Convert required H264 profile and level to V4L2 enums.
- static int32_t VideoCodecProfileToV4L2H264Profile(VideoCodecProfile profile);
- static int32_t H264LevelIdcToV4L2H264Level(uint8_t level_idc);
-
- // Converts v4l2_memory to a string.
- static const char* V4L2MemoryToString(const v4l2_memory memory);
-
- // Returns the printable name of a v4l2_buf_type.
- static const char* V4L2BufferTypeToString(const enum v4l2_buf_type buf_type);
-
- // Composes human readable string of v4l2_format.
- static std::string V4L2FormatToString(const struct v4l2_format& format);
-
- // Composes human readable string of v4l2_buffer.
- static std::string V4L2BufferToString(const struct v4l2_buffer& buffer);
-
- // Composes VideoFrameLayout based on v4l2_format.
- // If error occurs, it returns base::nullopt.
- static base::Optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
- const struct v4l2_format& format);
-
- // Returns number of planes of |pix_fmt|.
- static size_t GetNumPlanesOfV4L2PixFmt(uint32_t pix_fmt);
-
- enum class Type {
- kDecoder,
- kEncoder,
- };
-
- // Create and initialize an appropriate V4L2Device instance for the current
- // platform, or return nullptr if not available.
- static scoped_refptr<V4L2Device> Create();
-
- // Open a V4L2 device of |type| for use with |v4l2_pixfmt|.
- // Return true on success.
- // The device will be closed in the destructor.
- bool Open(Type type, uint32_t v4l2_pixfmt);
-
- // Returns the V4L2Queue corresponding to the requested |type|, or nullptr
- // if the requested queue type is not supported.
- scoped_refptr<V4L2Queue> GetQueue(enum v4l2_buf_type type);
-
- // Parameters and return value are the same as for the standard ioctl() system
- // call.
- int Ioctl(int request, void* arg);
-
- // This method sleeps until either:
- // - SetDevicePollInterrupt() is called (on another thread),
- // - |poll_device| is true, and there is new data to be read from the device,
- // or an event from the device has arrived; in the latter case
- // |*event_pending| will be set to true.
- // Returns false on error, true otherwise.
- // This method should be called from a separate thread.
- bool Poll(bool poll_device, bool* event_pending);
-
- // These methods are used to interrupt the thread sleeping on Poll() and force
- // it to return regardless of device state, which is usually when the client
- // is no longer interested in what happens with the device (on cleanup,
- // client state change, etc.). When SetDevicePollInterrupt() is called, Poll()
- // will return immediately, and any subsequent calls to it will also do so
- // until ClearDevicePollInterrupt() is called.
- bool SetDevicePollInterrupt();
- bool ClearDevicePollInterrupt();
-
- // Wrappers for standard mmap/munmap system calls.
- void* Mmap(void* addr,
- unsigned int len,
- int prot,
- int flags,
- unsigned int offset);
- void Munmap(void* addr, unsigned int len);
-
- // Return a vector of dmabuf file descriptors, exported for V4L2 buffer with
- // |index|, assuming the buffer contains |num_planes| V4L2 planes and is of
- // |type|. Return an empty vector on failure.
- // The caller is responsible for closing the file descriptors after use.
- std::vector<base::ScopedFD> GetDmabufsForV4L2Buffer(
- int index,
- size_t num_planes,
- enum v4l2_buf_type type);
-
- // Returns the preferred V4L2 input formats for |type| or empty if none.
- std::vector<uint32_t> PreferredInputFormat(Type type);
-
- // NOTE: The below methods to query capabilities have a side effect of
- // closing the previously-open device, if any, and should not be called after
- // Open().
- // TODO(posciak): fix this.
-
- // Get minimum and maximum resolution for fourcc |pixelformat| and store to
- // |min_resolution| and |max_resolution|.
- void GetSupportedResolution(uint32_t pixelformat,
- Size* min_resolution,
- Size* max_resolution);
-
- std::vector<uint32_t> EnumerateSupportedPixelformats(v4l2_buf_type buf_type);
-
- // Return supported profiles for decoder, including only profiles for given
- // fourcc |pixelformats|.
- VideoDecodeAccelerator::SupportedProfiles GetSupportedDecodeProfiles(
- const size_t num_formats,
- const uint32_t pixelformats[]);
-
- // Return supported profiles for encoder.
- VideoEncodeAccelerator::SupportedProfiles
- GetSupportedEncodeProfiles();
-
- // Start polling on this V4L2Device. |event_callback| will be posted to
- // the caller's sequence if a buffer is ready to be dequeued and/or a V4L2
- // event has been posted. |error_callback| will be posted to the client's
- // sequence if a polling error has occurred.
- bool StartPolling(V4L2DevicePoller::EventCallback event_callback,
- base::RepeatingClosure error_callback);
- // Stop polling this V4L2Device if polling was active. No new events will
- // be posted after this method has returned.
- bool StopPolling();
- // Schedule a polling event if polling is enabled. This method is intended
- // to be called from V4L2Queue, clients should not need to call it directly.
- void SchedulePoll();
-
- // Check whether the V4L2 control with specified |ctrl_id| is supported.
- bool IsCtrlExposed(uint32_t ctrl_id);
- // Set the specified list of |ctrls| for the specified |ctrl_class|, returns
- // whether the operation succeeded.
- bool SetExtCtrls(uint32_t ctrl_class, std::vector<V4L2ExtCtrl> ctrls);
-
- // Check whether the V4L2 command with specified |command_id| is supported.
- bool IsCommandSupported(uint32_t command_id);
- // Check whether the V4L2 device has the specified |capabilities|.
- bool HasCapabilities(uint32_t capabilities);
-
- private:
- // Vector of video device node paths and corresponding pixelformats supported
- // by each device node.
- using Devices = std::vector<std::pair<std::string, std::vector<uint32_t>>>;
-
- friend class base::RefCountedThreadSafe<V4L2Device>;
- V4L2Device();
- ~V4L2Device();
-
- VideoDecodeAccelerator::SupportedProfiles EnumerateSupportedDecodeProfiles(
- const size_t num_formats,
- const uint32_t pixelformats[]);
-
- VideoEncodeAccelerator::SupportedProfiles EnumerateSupportedEncodeProfiles();
-
- // Perform platform-specific initialization of the device instance.
- // Return true on success, false on error or if the particular implementation
- // is not available.
- bool Initialize();
-
- // Open device node for |path| as a device of |type|.
- bool OpenDevicePath(const std::string& path, Type type);
-
- // Close the currently open device.
- void CloseDevice();
-
- // Enumerate all V4L2 devices on the system for |type| and store the results
- // under devices_by_type_[type].
- void EnumerateDevicesForType(V4L2Device::Type type);
-
- // Return device information for all devices of |type| available in the
- // system. Enumerates and queries devices on first run and caches the results
- // for subsequent calls.
- const Devices& GetDevicesForType(V4L2Device::Type type);
-
- // Return device node path for device of |type| supporting |pixfmt|, or
- // an empty string if the given combination is not supported by the system.
- std::string GetDevicePathFor(V4L2Device::Type type, uint32_t pixfmt);
-
- // Callback that is called upon a queue's destruction, to cleanup its pointer
- // in queues_.
- void OnQueueDestroyed(v4l2_buf_type buf_type);
-
- // Lazily initialize static data after sandbox is enabled. Return false on
- // init failure.
- static bool PostSandboxInitialization();
-
- // Stores information for all devices available on the system
- // for each device Type.
- std::map<V4L2Device::Type, Devices> devices_by_type_;
-
- // The actual device fd.
- base::ScopedFD device_fd_;
-
- // eventfd fd to signal device poll thread when its poll() should be
- // interrupted.
- base::ScopedFD device_poll_interrupt_fd_;
-
- // Associates a v4l2_buf_type to its queue.
- base::flat_map<enum v4l2_buf_type, V4L2Queue*> queues_;
-
- // Used if EnablePolling() is called to signal the user that an event
- // happened or a buffer is ready to be dequeued.
- std::unique_ptr<V4L2DevicePoller> device_poller_;
-
- DISALLOW_COPY_AND_ASSIGN(V4L2Device);
-
- SEQUENCE_CHECKER(client_sequence_checker_);
+public:
+ // Utility format conversion functions
+ // If there is no corresponding single- or multi-planar format, returns 0.
+ static uint32_t videoCodecProfileToV4L2PixFmt(media::VideoCodecProfile profile,
+ bool sliceBased);
+ static media::VideoCodecProfile v4L2ProfileToVideoCodecProfile(media::VideoCodec codec,
+ uint32_t profile);
+ std::vector<media::VideoCodecProfile> v4L2PixFmtToVideoCodecProfiles(uint32_t pixFmt,
+ bool isEncoder);
+ // Calculates the largest plane's allocation size requested by a V4L2 device.
+ static media::Size allocatedSizeFromV4L2Format(const struct v4l2_format& format);
+
+ // Convert required H264 profile and level to V4L2 enums.
+ static int32_t videoCodecProfileToV4L2H264Profile(media::VideoCodecProfile profile);
+ static int32_t h264LevelIdcToV4L2H264Level(uint8_t levelIdc);
+
+ // Converts v4l2_memory to a string.
+ static const char* v4L2MemoryToString(const v4l2_memory memory);
+
+ // Returns the printable name of a v4l2_buf_type.
+ static const char* v4L2BufferTypeToString(const enum v4l2_buf_type bufType);
+
+ // Composes human readable string of v4l2_format.
+ static std::string v4L2FormatToString(const struct v4l2_format& format);
+
+ // Composes human readable string of v4l2_buffer.
+ static std::string v4L2BufferToString(const struct v4l2_buffer& buffer);
+
+ // Composes VideoFrameLayout based on v4l2_format.
+ // If error occurs, it returns base::nullopt.
+ static std::optional<media::VideoFrameLayout> v4L2FormatToVideoFrameLayout(
+ const struct v4l2_format& format);
+
+ // Returns number of planes of |pixFmt|.
+ static size_t getNumPlanesOfV4L2PixFmt(uint32_t pixFmt);
+
+ enum class Type { kDecoder, kEncoder };
+
+ // Create and initialize an appropriate V4L2Device instance for the current platform, or return
+ // nullptr if not available.
+ static scoped_refptr<V4L2Device> create();
+
+ // Open a V4L2 device of |type| for use with |v4l2PixFmt|. Return true on success. The device
+ // will be closed in the destructor.
+ bool open(Type type, uint32_t v4l2PixFmt);
+
+ // Returns the V4L2Queue corresponding to the requested |type|, or nullptr if the requested
+ // queue type is not supported.
+ scoped_refptr<V4L2Queue> getQueue(enum v4l2_buf_type type);
+
+ // Parameters and return value are the same as for the standard ioctl() system call.
+ int ioctl(int request, void* arg);
+
+ // This method sleeps until either:
+ // - SetDevicePollInterrupt() is called (on another thread),
+ // - |pollDevice| is true, and there is new data to be read from the device,
+ // or an event from the device has arrived; in the latter case
+ // |*eventPending| will be set to true.
+ // Returns false on error, true otherwise. This method should be called from a separate thread.
+ bool poll(bool pollDevice, bool* eventPending);
+
+ // These methods are used to interrupt the thread sleeping on poll() and force it to return
+ // regardless of device state, which is usually when the client is no longer interested in what
+ // happens with the device (on cleanup, client state change, etc.). When
+ // setDevicePollInterrupt() is called, poll() will return immediately, and any subsequent calls
+ // to it will also do so until clearDevicePollInterrupt() is called.
+ bool setDevicePollInterrupt();
+ bool clearDevicePollInterrupt();
+
+ // Wrappers for standard mmap/munmap system calls.
+ void* mmap(void* addr, unsigned int len, int prot, int flags, unsigned int offset);
+ void munmap(void* addr, unsigned int len);
+
+ // Return a vector of dmabuf file descriptors, exported for V4L2 buffer with |index|, assuming
+ // the buffer contains |numPlanes| V4L2 planes and is of |bufType|. Return an empty vector on
+ // failure. The caller is responsible for closing the file descriptors after use.
+ std::vector<base::ScopedFD> getDmabufsForV4L2Buffer(int index, size_t numPlanes,
+ enum v4l2_buf_type bufType);
+
+ // Returns the preferred V4L2 input formats for |type| or empty if none.
+ std::vector<uint32_t> preferredInputFormat(Type type);
+
+ // NOTE: The below methods to query capabilities have a side effect of closing the
+ // previously-open device, if any, and should not be called after Open().
+
+ // Get minimum and maximum resolution for fourcc |pixelFormat| and store to |minResolution| and
+ // |maxResolution|.
+ void getSupportedResolution(uint32_t pixelFormat, media::Size* minResolution,
+ media::Size* maxResolution);
+
+ std::vector<uint32_t> enumerateSupportedPixelformats(v4l2_buf_type bufType);
+
+ // Return supported profiles for decoder, including only profiles for given fourcc
+ // |pixelFormats|.
+ media::VideoDecodeAccelerator::SupportedProfiles getSupportedDecodeProfiles(
+ const size_t numFormats, const uint32_t pixelFormats[]);
+
+ // Return supported profiles for encoder.
+ media::VideoEncodeAccelerator::SupportedProfiles getSupportedEncodeProfiles();
+
+ // Start polling on this V4L2Device. |eventCallback| will be posted to the caller's sequence if
+ // a buffer is ready to be dequeued and/or a V4L2 event has been posted. |errorCallback| will
+ // be posted to the client's
+ // sequence if a polling error has occurred.
+ bool startPolling(android::V4L2DevicePoller::EventCallback eventCallback,
+ base::RepeatingClosure errorCallback);
+ // Stop polling this V4L2Device if polling was active. No new events will be posted after this
+ // method has returned.
+ bool stopPolling();
+ // Schedule a polling event if polling is enabled. This method is intended to be called from
+ // V4L2Queue, clients should not need to call it directly.
+ void schedulePoll();
+
+ // Check whether the V4L2 control with specified |ctrlId| is supported.
+ bool isCtrlExposed(uint32_t ctrlId);
+ // Set the specified list of |ctrls| for the specified |ctrlClass|, returns whether the
+ // operation succeeded.
+ bool setExtCtrls(uint32_t ctrlClass, std::vector<V4L2ExtCtrl> ctrls);
+
+ // Check whether the V4L2 command with specified |commandId| is supported.
+ bool isCommandSupported(uint32_t commandId);
+ // Check whether the V4L2 device has the specified |capabilities|.
+ bool hasCapabilities(uint32_t capabilities);
+
+private:
+ // Vector of video device node paths and corresponding pixelformats supported by each device node.
+ using Devices = std::vector<std::pair<std::string, std::vector<uint32_t>>>;
+
+ friend class base::RefCountedThreadSafe<V4L2Device>;
+ V4L2Device();
+ ~V4L2Device();
+
+ V4L2Device(const V4L2Device&) = delete;
+ V4L2Device& operator=(const V4L2Device&) = delete;
+
+ media::VideoDecodeAccelerator::SupportedProfiles enumerateSupportedDecodeProfiles(
+ const size_t numFormats, const uint32_t pixelFormats[]);
+
+ media::VideoEncodeAccelerator::SupportedProfiles enumerateSupportedEncodeProfiles();
+
+ // Open device node for |path| as a device of |type|.
+ bool openDevicePath(const std::string& path, Type type);
+
+ // Close the currently open device.
+ void closeDevice();
+
+ // Enumerate all V4L2 devices on the system for |type| and store the results under
+ // mDevicesByType[type].
+ void enumerateDevicesForType(V4L2Device::Type type);
+
+ // Return device information for all devices of |type| available in the system. Enumerates and
+ // queries devices on first run and caches the results for subsequent calls.
+ const Devices& getDevicesForType(V4L2Device::Type type);
+
+ // Return device node path for device of |type| supporting |pixFmt|, or an empty string if the
+ // given combination is not supported by the system.
+ std::string getDevicePathFor(V4L2Device::Type type, uint32_t pixFmt);
+
+ // Callback that is called upon a queue's destruction, to cleanup its pointer in mQueues.
+ void onQueueDestroyed(v4l2_buf_type buf_type);
+
+ // Stores information for all devices available on the system for each device Type.
+ std::map<V4L2Device::Type, Devices> mDevicesByType;
+
+ // The actual device fd.
+ base::ScopedFD mDeviceFd;
+
+ // eventfd fd to signal device poll thread when its poll() should be interrupted.
+ base::ScopedFD mDevicePollInterruptFd;
+
+ // Associates a v4l2_buf_type to its queue.
+ base::flat_map<enum v4l2_buf_type, V4L2Queue*> mQueues;
+
+ // Used if EnablePolling() is called to signal the user that an event happened or a buffer is
+ // ready to be dequeued.
+ std::unique_ptr<android::V4L2DevicePoller> mDevicePoller;
+
+ SEQUENCE_CHECKER(mClientSequenceChecker);
};
-} // namespace media
+} // namespace android
-#endif // V4L2_DEVICE_H_
+#endif // ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_H
diff --git a/common/include/v4l2_codec2/common/V4L2DevicePoller.h b/common/include/v4l2_codec2/common/V4L2DevicePoller.h
index aac3d8c..ad256be 100644
--- a/common/include/v4l2_codec2/common/V4L2DevicePoller.h
+++ b/common/include/v4l2_codec2/common/V4L2DevicePoller.h
@@ -3,95 +3,86 @@
// found in the LICENSE file.
// Note: ported from Chromium commit head: f65c38dcdac2
-#ifndef V4L2_V4L2_DEVICE_POLLER_H_
-#define V4L2_V4L2_DEVICE_POLLER_H_
+#ifndef ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_POLLER_H
+#define ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_POLLER_H
#include <atomic>
-#include "base/callback_forward.h"
-#include "base/sequence_checker.h"
-#include "base/sequenced_task_runner.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
+#include <base/callback_forward.h>
+#include <base/sequence_checker.h>
+#include <base/sequenced_task_runner.h>
+#include <base/synchronization/waitable_event.h>
+#include <base/threading/thread.h>
-namespace media {
+namespace android {
class V4L2Device;
-// Allows a client to poll() on a given V4L2Device and be signaled when
-// a buffer is ready to be dequeued or a V4L2 event has been received. Polling
-// is done on a dedicated thread, and notifications are delivered in the form of
-// a callback to the listener's sequence.
+// Allows a client to poll() on a given V4L2Device and be signaled when a buffer is ready to be
+// dequeued or a V4L2 event has been received. Polling is done on a dedicated thread, and
+// notifications are delivered in the form of a callback to the listener's sequence.
//
-// All the methods of this class (with the exception of the constructor) must be
-// called from the same sequence.
+// All the methods of this class (with the exception of the constructor) must be called from the
+// same sequence.
//
-// Note that the service callback may also be called when no particular event
-// occurred due to the way poll() works. It is the responsibility of the caller
-// to call SchedulePoll() again if there may still be pending events.
+// Note that the service callback may also be called when no particular event occurred due to the
+// way poll() works. It is the responsibility of the caller to call SchedulePoll() again if there
+// may still be pending events.
class V4L2DevicePoller {
- public:
- // Callback to be called when buffer ready/V4L2 event has potentially been
- // polled. |event| is set if a V4L2 event has been detected.
- using EventCallback = base::RepeatingCallback<void(bool event)>;
+public:
+ // Callback to be called when buffer ready/V4L2 event has potentially been polled. |event| is
+ // set if a V4L2 event has been detected.
+ using EventCallback = base::RepeatingCallback<void(bool event)>;
- // Create a poller for |device|, using a thread named |thread_name|.
- // Notification won't start until |StartPolling()| is called.
- V4L2DevicePoller(V4L2Device* const device, const std::string& thread_name);
- ~V4L2DevicePoller();
+ // Create a poller for |device|, using a thread named |threadName|. Notification won't start
+ // until |startPolling()| is called.
+ V4L2DevicePoller(V4L2Device* const device, const std::string& threadName);
+ ~V4L2DevicePoller();
- // Starts polling. |event_callback| will be posted on the caller's sequence
- // every time an event occurs. The client is then responsible for consuming
- // all pending events in that callback. If new events may still happen after
- // the callback has run, the client must call |SchedulePoll()| again in order
- // to be notified for them.
- //
- // If an error occurs during polling, |error_callback| will be posted on the
- // caller's sequence.
- bool StartPolling(EventCallback event_callback,
- base::RepeatingClosure error_callback);
- // Stop polling and stop the thread. The poller won't post any new event to
- // the caller's sequence after this method has returned.
- bool StopPolling();
- // Returns true if currently polling, false otherwise.
- bool IsPolling() const;
- // Attempts polling the V4L2 device. This method should be called whenever
- // doing something that may trigger an event of interest (buffer dequeue or
- // V4L2 event), for instance queueing a buffer. In the absence of a pending
- // event, poll() will return immediately and the service callback will be
- // posted to the caller's sequence. The client is then responsible for calling
- // this method again when it is interested in receiving events.
- void SchedulePoll();
+ // Starts polling. |mEventCallback| will be posted on the caller's sequence every time an event
+ // occurs. The client is then responsible for consuming all pending events in that callback. If
+ // new events may still happen after the callback has run, the client must call |schedulePoll()|
+ // again in order to be notified for them.
+ //
+ // If an error occurs during polling, |mErrorCallback| will be posted on the caller's sequence.
+ bool startPolling(EventCallback eventCallback, base::RepeatingClosure errorCallback);
+ // Stop polling and stop the thread. The poller won't post any new event to the caller's
+ // sequence after this method has returned.
+ bool stopPolling();
+ // Returns true if currently polling, false otherwise.
+ bool isPolling() const;
+ // Attempts polling the V4L2 device. This method should be called whenever doing something that
+ // may trigger an event of interest (buffer dequeue or V4L2 event), for instance queueing a
+ // buffer. In the absence of a pending event, poll() will return immediately and the service
+ // callback will be posted to the caller's sequence. The client is then responsible for calling
+ // this method again when it is interested in receiving events.
+ void schedulePoll();
- private:
- // Perform a poll() on |device_| and post either |service_task_| or
- // |error_callback_| on the client's sequence when poll() returns.
- void DevicePollTask();
+private:
+ // Perform a poll() on |mDevice| and post either |mEventCallback| or |mErrorCallback| on the
+ // client's sequence when poll() returns.
+ void devicePollTask();
- // V4L2 device we are polling.
- V4L2Device* const device_;
- // Thread on which polling is done.
- base::Thread poll_thread_;
- // Callback to post to the client's sequence when an event occurs.
- EventCallback event_callback_;
- // Closure to post to the client's sequence when an error occurs.
- base::RepeatingClosure error_callback_;
- // Client sequence's task runner, where closures are posted.
- scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
+ // V4L2 device we are polling.
+ V4L2Device* const mDevice;
+ // Thread on which polling is done.
+ base::Thread mPollThread;
+ // Callback to post to the client's sequence when an event occurs.
+ EventCallback mEventCallback;
+ // Closure to post to the client's sequence when an error occurs.
+ base::RepeatingClosure mErrorCallback;
+ // Client sequence's task runner, where closures are posted.
+ scoped_refptr<base::SequencedTaskRunner> mClientTaskTunner;
- // Since poll() returns immediately if no buffers have been queued, we cannot
- // rely on it to pause the polling thread until an event occurs. Instead,
- // the polling thread will wait on this WaitableEvent (signaled by
- // |SchedulePoll| before calling poll(), so we only call it when we are
- // actually waiting for an event.
- base::WaitableEvent trigger_poll_;
- // Set to true when we wish to stop polling, instructing the poller thread
- // to break its loop.
- std::atomic_bool stop_polling_;
-
- SEQUENCE_CHECKER(client_sequence_checker_);
+ // Since poll() returns immediately if no buffers have been queued, we cannot rely on it to
+ // pause the polling thread until an event occurs. Instead,
+ // the polling thread will wait on this WaitableEvent (signaled by |schedulePoll| before calling
+ // poll(), so we only call it when we are actually waiting for an event.
+ base::WaitableEvent mTriggerPoll;
+ // Set to true when we wish to stop polling, instructing the poller thread to break its loop.
+ std::atomic_bool mStopPolling;
};
-} // namespace media
+} // namespace android
-#endif // V4L2_V4L2_DEVICE_POLLER_H_
+#endif // ANDROID_V4L2_CODEC2_COMMON_V4L2_DEVICE_POLLER_H