1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_VIDEOCAPTURE_H
17 #define ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_VIDEOCAPTURE_H
18 
19 #include <linux/videodev2.h>
20 
21 #include <atomic>
22 #include <functional>
23 #include <set>
24 #include <thread>
25 
26 typedef v4l2_buffer imageBuffer;
27 
28 class VideoCapture {
29 public:
30     bool open(const char* deviceName, const int32_t width = 0, const int32_t height = 0);
31     void close();
32 
33     bool startStream(std::function<void(VideoCapture*, imageBuffer*, void*)> callback = nullptr);
34     void stopStream();
35 
36     // Valid only after open()
getWidth()37     __u32 getWidth() { return mWidth; };
getHeight()38     __u32 getHeight() { return mHeight; };
getStride()39     __u32 getStride() { return mStride; };
getV4LFormat()40     __u32 getV4LFormat() { return mFormat; };
41 
42     // NULL until stream is started
getLatestData()43     void* getLatestData() {
44         if (mFrames.empty()) {
45             // No frame is available
46             return nullptr;
47         }
48 
49         // Return a pointer to the buffer captured most recently
50         const int latestBufferId = *mFrames.end();
51         return mPixelBuffers[latestBufferId];
52     }
53 
isFrameReady()54     bool isFrameReady() { return !mFrames.empty(); }
markFrameConsumed(int id)55     void markFrameConsumed(int id) { returnFrame(id); }
56 
isOpen()57     bool isOpen() { return mDeviceFd >= 0; }
58 
59     int setParameter(struct v4l2_control& control);
60     int getParameter(struct v4l2_control& control);
61     std::set<uint32_t> enumerateCameraControls();
62 
63 private:
64     void collectFrames();
65     bool returnFrame(int id);
66 
67     int mDeviceFd = -1;
68 
69     int mNumBuffers = 0;
70     std::unique_ptr<v4l2_buffer[]> mBufferInfos = nullptr;
71     std::unique_ptr<void*[]> mPixelBuffers = nullptr;
72 
73     __u32 mFormat = 0;
74     __u32 mWidth = 0;
75     __u32 mHeight = 0;
76     __u32 mStride = 0;
77 
78     std::function<void(VideoCapture*, imageBuffer*, void*)> mCallback;
79 
80     std::thread mCaptureThread;  // The thread we'll use to dispatch frames
81     std::atomic<int> mRunMode;   // Used to signal the frame loop (see RunModes below)
82     std::set<int> mFrames;       // Set of available frame buffers
83 
84     // Careful changing these -- we're using bit-wise ops to manipulate these
85     enum RunModes {
86         STOPPED = 0,
87         RUN = 1,
88         STOPPING = 2,
89     };
90 };
91 
92 #endif  // ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_0_VIDEOCAPTURE_
93