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#include <atomic>
17#include <thread>
18#include <functional>
19#include <linux/videodev2.h>
20
21
22typedef v4l2_buffer imageBuffer;
23
24
25class VideoCapture {
26public:
27    bool open(const char* deviceName);
28    void close();
29
30    bool startStream(std::function<void(VideoCapture*, imageBuffer*, void*)> callback = nullptr);
31    void stopStream();
32
33    // Valid only after open()
34    __u32   getWidth()          { return mWidth; };
35    __u32   getHeight()         { return mHeight; };
36    __u32   getStride()         { return mStride; };
37    __u32   getV4LFormat()      { return mFormat; };
38
39    // NULL until stream is started
40    void* getLatestData()       { return mPixelBuffer; };
41
42    bool isFrameReady()         { return mFrameReady; };
43    void markFrameConsumed()    { returnFrame(); };
44
45    bool isOpen()               { return mDeviceFd >= 0; };
46
47private:
48    void collectFrames();
49    void markFrameReady();
50    bool returnFrame();
51
52    int mDeviceFd = -1;
53
54    v4l2_buffer mBufferInfo = {};
55    void* mPixelBuffer = nullptr;
56
57    __u32   mFormat = 0;
58    __u32   mWidth  = 0;
59    __u32   mHeight = 0;
60    __u32   mStride = 0;
61
62    std::function<void(VideoCapture*, imageBuffer*, void*)> mCallback;
63
64    std::thread mCaptureThread;             // The thread we'll use to dispatch frames
65    std::atomic<int> mRunMode;              // Used to signal the frame loop (see RunModes below)
66    std::atomic<bool> mFrameReady;          // Set when a frame has been delivered
67
68    // Careful changing these -- we're using bit-wise ops to manipulate these
69    enum RunModes {
70        STOPPED     = 0,
71        RUN         = 1,
72        STOPPING    = 2,
73    };
74};
75
76