• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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_EMULVIDEOCAPTURE_H
17 #define ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EMULVIDEOCAPTURE_H
18 
19 #include <atomic>
20 #include <filesystem>
21 #include <functional>
22 #include <thread>
23 
24 #include <android-base/chrono_utils.h>
25 #include <linux/videodev2.h>
26 #include <utils/Looper.h>
27 #include <utils/Mutex.h>
28 #include <utils/Timers.h>
29 
30 namespace {
31 
32     // Careful changing these -- we're using bit-wise ops to manipulate these
33     enum RunModes {
34         STOPPED     = 0,
35         RUN         = 1,
36         STOPPING    = 2,
37     };
38 
39     enum StreamEvent {
40         INIT = 0,
41         PERIODIC,
42         STOP,
43         TERMINATED,
44     };
45 
46     struct imageMetadata {
47         uint32_t width;     // Image width in pixels
48         uint32_t height;    // Image height in pixels
49         uint32_t stride;    // Number of bytes from one row in memory
50         uint32_t format;    // Image format
51     };
52 }
53 
54 
55 typedef struct {
56         struct imageMetadata info;
57         uint32_t sequence;        // Counting frames in sequence
58         struct timeval timestamp; // Tells when this frame is generated
59 } imageBufferDesc;
60 
61 
62 namespace android {
63 namespace automotive {
64 namespace evs {
65 namespace V1_1 {
66 namespace implementation {
67 
68 class VideoCapture : public MessageHandler {
69 public:
VideoCapture()70     explicit VideoCapture() {};
71     virtual ~VideoCapture();
72     bool open(const std::string& path,
73               const std::chrono::nanoseconds interval);
74     void close();
75 
76     bool startStream(
77             std::function<void(VideoCapture*, imageBufferDesc*, void*)> callback = nullptr);
78     void stopStream();
79 
80     // Valid only after open()
getWidth()81     __u32   getWidth()          { return mBufferInfo.info.width; }
getHeight()82     __u32   getHeight()         { return mBufferInfo.info.height; }
getStride()83     __u32   getStride()         { return mBufferInfo.info.stride; }
getV4LFormat()84     __u32   getV4LFormat()      { return mBufferInfo.info.format; }
85 
86     // NULL until stream is started
getLatestData()87     void* getLatestData()       { return mPixelBuffer; }
isFrameReady()88     bool isFrameReady()         { return mFrameReady; }
markFrameConsumed()89     void markFrameConsumed()    { returnFrame(); }
isOpen()90     bool isOpen()               { return mVideoReady; }
91 
92     int setParameter(struct v4l2_control& control);
93     int getParameter(struct v4l2_control& control);
94 
95 private:
96     void collectFrames();
97     void markFrameReady();
98     bool returnFrame();
99 
100     // Handles the message from the looper
101     void handleMessage(const android::Message& message) override;
102 
103     // Looper to message the frame generator thread
104     android::sp<android::Looper> mLooper;
105 
106     // Background thread to dispatch generated frames
107     std::thread mCaptureThread;
108 
109     // Stream event to control the looper
110     StreamEvent mCurrentStreamEvent = StreamEvent::INIT;
111 
112     // Directory where source files exist
113     std::filesystem::path mSourceDir;
114     std::filesystem::directory_iterator mSrcIter;
115 
116     // Last time the frame was generated and sent
117     nsecs_t mLastTimeFrameSent;
118 
119     // Desired interval to generate and send a frame
120     std::chrono::nanoseconds mDesiredFrameInterval = 1000ms;
121 
122     // Source image descriptor
123     imageBufferDesc mBufferInfo = {};
124 
125     // Buffer to store the source pixel data
126     char* mPixelBuffer = nullptr;
127 
128     // Current pixel buffer size
129     size_t mPixelBufferSize = 0;
130 
131     // Callback to tell about new frames
132     std::function<void(VideoCapture*, imageBufferDesc*, void*)> mCallback;
133 
134     // Used to signal the frame loop (see RunModes below)
135     std::atomic<int> mRunMode;
136 
137     // Set when a frame has been delivered
138     std::atomic<bool> mFrameReady;
139 
140     // flag to tell whether it is ready to start a stream
141     bool mVideoReady = false;
142 };
143 
144 } // namespace implementation
145 } // namespace V1_1
146 } // namespace evs
147 } // namespace automotive
148 } // namespace android
149 
150 #endif // ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EMULVIDEOCAPTURE_
151