151 lines
4.4 KiB
C++
151 lines
4.4 KiB
C++
/*
|
|
* Copyright 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EMULVIDEOCAPTURE_H
|
|
#define ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EMULVIDEOCAPTURE_H
|
|
|
|
#include <atomic>
|
|
#include <filesystem>
|
|
#include <functional>
|
|
#include <thread>
|
|
|
|
#include <android-base/chrono_utils.h>
|
|
#include <linux/videodev2.h>
|
|
#include <utils/Looper.h>
|
|
#include <utils/Mutex.h>
|
|
#include <utils/Timers.h>
|
|
|
|
namespace {
|
|
|
|
// Careful changing these -- we're using bit-wise ops to manipulate these
|
|
enum RunModes {
|
|
STOPPED = 0,
|
|
RUN = 1,
|
|
STOPPING = 2,
|
|
};
|
|
|
|
enum StreamEvent {
|
|
INIT = 0,
|
|
PERIODIC,
|
|
STOP,
|
|
TERMINATED,
|
|
};
|
|
|
|
struct imageMetadata {
|
|
uint32_t width; // Image width in pixels
|
|
uint32_t height; // Image height in pixels
|
|
uint32_t stride; // Number of bytes from one row in memory
|
|
uint32_t format; // Image format
|
|
};
|
|
}
|
|
|
|
|
|
typedef struct {
|
|
struct imageMetadata info;
|
|
uint32_t sequence; // Counting frames in sequence
|
|
struct timeval timestamp; // Tells when this frame is generated
|
|
} imageBufferDesc;
|
|
|
|
|
|
namespace android {
|
|
namespace automotive {
|
|
namespace evs {
|
|
namespace V1_1 {
|
|
namespace implementation {
|
|
|
|
class VideoCapture : public MessageHandler {
|
|
public:
|
|
explicit VideoCapture() {};
|
|
virtual ~VideoCapture();
|
|
bool open(const std::string& path,
|
|
const std::chrono::nanoseconds interval);
|
|
void close();
|
|
|
|
bool startStream(
|
|
std::function<void(VideoCapture*, imageBufferDesc*, void*)> callback = nullptr);
|
|
void stopStream();
|
|
|
|
// Valid only after open()
|
|
__u32 getWidth() { return mBufferInfo.info.width; }
|
|
__u32 getHeight() { return mBufferInfo.info.height; }
|
|
__u32 getStride() { return mBufferInfo.info.stride; }
|
|
__u32 getV4LFormat() { return mBufferInfo.info.format; }
|
|
|
|
// NULL until stream is started
|
|
void* getLatestData() { return mPixelBuffer; }
|
|
bool isFrameReady() { return mFrameReady; }
|
|
void markFrameConsumed() { returnFrame(); }
|
|
bool isOpen() { return mVideoReady; }
|
|
|
|
int setParameter(struct v4l2_control& control);
|
|
int getParameter(struct v4l2_control& control);
|
|
|
|
private:
|
|
void collectFrames();
|
|
void markFrameReady();
|
|
bool returnFrame();
|
|
|
|
// Handles the message from the looper
|
|
void handleMessage(const android::Message& message) override;
|
|
|
|
// Looper to message the frame generator thread
|
|
android::sp<android::Looper> mLooper;
|
|
|
|
// Background thread to dispatch generated frames
|
|
std::thread mCaptureThread;
|
|
|
|
// Stream event to control the looper
|
|
StreamEvent mCurrentStreamEvent = StreamEvent::INIT;
|
|
|
|
// Directory where source files exist
|
|
std::filesystem::path mSourceDir;
|
|
std::filesystem::directory_iterator mSrcIter;
|
|
|
|
// Last time the frame was generated and sent
|
|
nsecs_t mLastTimeFrameSent;
|
|
|
|
// Desired interval to generate and send a frame
|
|
std::chrono::nanoseconds mDesiredFrameInterval = 1000ms;
|
|
|
|
// Source image descriptor
|
|
imageBufferDesc mBufferInfo = {};
|
|
|
|
// Buffer to store the source pixel data
|
|
char* mPixelBuffer = nullptr;
|
|
|
|
// Current pixel buffer size
|
|
size_t mPixelBufferSize = 0;
|
|
|
|
// Callback to tell about new frames
|
|
std::function<void(VideoCapture*, imageBufferDesc*, void*)> mCallback;
|
|
|
|
// Used to signal the frame loop (see RunModes below)
|
|
std::atomic<int> mRunMode;
|
|
|
|
// Set when a frame has been delivered
|
|
std::atomic<bool> mFrameReady;
|
|
|
|
// flag to tell whether it is ready to start a stream
|
|
bool mVideoReady = false;
|
|
};
|
|
|
|
} // namespace implementation
|
|
} // namespace V1_1
|
|
} // namespace evs
|
|
} // namespace automotive
|
|
} // namespace android
|
|
|
|
#endif // ANDROID_HARDWARE_AUTOMOTIVE_EVS_V1_1_EMULVIDEOCAPTURE_
|