summaryrefslogtreecommitdiff
path: root/src/camera/veyeimx287m.h
blob: ab7e3e541ac8a6b69a229bb86a6514ff21b74ef8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#pragma once

#include <cstdint>
#include <linux/videodev2.h>
#include <queue>
#include <thread>

#include <QReadWriteLock>
#include <QSemaphore>

#include "constants.h"
#include "image.h"

#include "icamera.h"

namespace veye {
namespace imx287m {
class i2c;
} // namespace imx287m
} // namespace veye

class HttpServer;

class VeyeIMX287m : public ICamera
{
    constexpr static char videoDevice[] = "/dev/video0";

public:
    using buffer_t = std::array<uint8_t, img_size>;

public:
    VeyeIMX287m();
    ~VeyeIMX287m() override;

public:
    static std::vector<std::shared_ptr<ICamera>> search();

public:
    bool startStream() override;

    bool dequeueImageBuffer(size_t &image);
    // bool getImage(Image &image);
    bool getImage(Image *image) override;
    std::shared_ptr<Image> getImage() override;

    bool init();

    // parameters
public:
    bool set_autoExposure(const bool enable) override;
    std::optional<bool> get_autoExposure() override;

    bool set_autoGain(const bool enable) override;
    std::optional<bool> get_autoGain() override;

    bool set_exposureTime(const std::chrono::microseconds us) override;
    std::optional<const std::chrono::microseconds> get_exposureTime() override;

    bool set_gain(const float value) override;
    std::optional<float> get_gain() override;

public:
    /*!
     * \brief processedCounter - count of images processed in current second.
     * Used for performance measurement and bottlenecks analysing
     */
    uint32_t processedCounter{0};

private:
    bool openCam();
    bool initCam();

    bool initI2C();
    // bool initHttpServer();

    void getFrameLoop(std::stop_token stopToken);
    void rotateFrameLoop(std::stop_token stopToken);

private:
    /*!
     * \brief m_cam_fd - camera file descriptor
     */
    int m_cam_fd{-1};

    /*!
     * \brief m_previousFrameCounter - used to detect dropped frames
     */
    std::optional<int64_t> m_previousFrameCounter{};

    static constexpr uint8_t BUFFER_COUNT{16};

    // std::array<Image, BUFFER_COUNT> m_images;
    /*!
     * \brief m_imageMutexes - lock while processing image from m_images
     */
    std::array<std::mutex, BUFFER_COUNT> m_imageMutexes;

    struct buffer
    {
        unsigned int padding{0};
        unsigned int size{0};
        void *mem{nullptr};
        std::shared_ptr<Image> image{std::make_shared<Image>()};
    };
    std::vector<buffer> m_buffers;

    struct Semaphore
    {
        const uint8_t maxSize{BUFFER_COUNT};
        uint8_t bufferIdx{std::numeric_limits<decltype(bufferIdx)>::max()};
        std::binary_semaphore main2calc{0};
        std::binary_semaphore calc2main{0};
    } m_receiverCalculatorSem;

    // std::mutex m_queueMtx;
    std::mutex m_camMtx;
    /*!
     * \brief m_buffersQueue - queue of buffers which require extracting pixels
     */
    std::queue<std::remove_const<decltype(BUFFER_COUNT)>> m_buffersQueue;

    std::jthread m_streamThread;
    // std::jthread m_getThreads[1];
    std::jthread m_getThreads[4];
    std::jthread m_rotateThreads[1];

    std::shared_ptr<veye::imx287m::i2c> m_i2c;
    std::shared_ptr<HttpServer> m_httpServer;
};