xref: /aosp_15_r20/external/v4l2_codec2/v4l2/include/v4l2_codec2/v4l2/V4L2DevicePoller.h (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
1 // Copyright 2019 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 // Note: ported from Chromium commit head: f65c38dcdac2
5 
6 #ifndef ANDROID_V4L2_CODEC2_V4L2_V4L2_DEVICE_POLLER_H
7 #define ANDROID_V4L2_CODEC2_V4L2_V4L2_DEVICE_POLLER_H
8 
9 #include <atomic>
10 
11 #include <base/callback_forward.h>
12 #include <base/sequence_checker.h>
13 #include <base/sequenced_task_runner.h>
14 #include <base/synchronization/waitable_event.h>
15 #include <base/threading/thread.h>
16 
17 namespace android {
18 
19 class V4L2Device;
20 
21 // Allows a client to poll() on a given V4L2Device and be signaled when a buffer is ready to be
22 // dequeued or a V4L2 event has been received. Polling is done on a dedicated thread, and
23 // notifications are delivered in the form of a callback to the listener's sequence.
24 //
25 // All the methods of this class (with the exception of the constructor) must be called from the
26 // same sequence.
27 //
28 // Note that the service callback may also be called when no particular event occurred due to the
29 // way poll() works. It is the responsibility of the caller to call SchedulePoll() again if there
30 // may still be pending events.
31 class V4L2DevicePoller {
32 public:
33     // Callback to be called when buffer ready/V4L2 event has potentially been polled. |event| is
34     // set if a V4L2 event has been detected.
35     using EventCallback = ::base::RepeatingCallback<void(bool event)>;
36 
37     // Create a poller for |device|, using a thread named |threadName|. Notification won't start
38     // until |startPolling()| is called.
39     V4L2DevicePoller(V4L2Device* const device, const std::string& threadName,
40                      scoped_refptr<::base::SequencedTaskRunner> taskRunner);
41     ~V4L2DevicePoller();
42 
43     // Starts polling. |mEventCallback| will be posted on the caller's sequence every time an event
44     // occurs. The client is then responsible for consuming all pending events in that callback. If
45     // new events may still happen after the callback has run, the client must call |schedulePoll()|
46     // again in order to be notified for them.
47     //
48     // If an error occurs during polling, |mErrorCallback| will be posted on the caller's sequence.
49     bool startPolling(EventCallback eventCallback, ::base::RepeatingClosure errorCallback);
50     // Stop polling and stop the thread. The poller won't post any new event to the caller's
51     // sequence after this method has returned.
52     bool stopPolling();
53     // Returns true if currently polling, false otherwise.
54     bool isPolling() const;
55     // Attempts polling the V4L2 device. This method should be called whenever doing something that
56     // may trigger an event of interest (buffer dequeue or V4L2 event), for instance queueing a
57     // buffer. In the absence of a pending event, poll() will return immediately and the service
58     // callback will be posted to the caller's sequence. The client is then responsible for calling
59     // this method again when it is interested in receiving events.
60     void schedulePoll();
61 
62 private:
63     // Perform a poll() on |mDevice| and post either |mEventCallback| or |mErrorCallback| on the
64     // client's sequence when poll() returns.
65     void devicePollTask();
66 
67     // V4L2 device we are polling.
68     V4L2Device* const mDevice;
69     // Thread on which polling is done.
70     ::base::Thread mPollThread;
71     // Callback to post to the client's sequence when an event occurs.
72     EventCallback mEventCallback;
73     // Closure to post to the client's sequence when an error occurs.
74     ::base::RepeatingClosure mErrorCallback;
75     // Client sequence's task runner, where closures are posted.
76     scoped_refptr<::base::SequencedTaskRunner> mClientTaskTunner;
77 
78     // Set to true when we wish to stop polling, instructing the poller thread to break its loop.
79     std::atomic_bool mStopPolling;
80     // Set to true when we wish poll to await for QBUF/DQBUF readiness
81     std::atomic_bool mPollBuffers;
82 };
83 
84 }  // namespace android
85 
86 #endif  // ANDROID_V4L2_CODEC2_V4L2_V4L2_DEVICE_POLLER_H
87