summaryrefslogtreecommitdiff
path: root/src/camera/veyeimx287m.h
blob: 03b7df9f617fee54a80f4ac2560b2c06fa58ff5f (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
#pragma once

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

#include <QReadWriteLock>

#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;

    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 calcFrameLoop(std::stop_token stopToken);

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

    static constexpr uint8_t BUFFER_COUNT{16};

    struct MA
    {
        QReadWriteLock rwLock;
        Image image;
    } bbbbb[BUFFER_COUNT];

    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;
    /*!
     * \todo copy image right after dequeue to avoid situation with ioctl writing
     * to m_videoBuffers[i] which is being copied to m_images[i]. In theory, it
     * should not overlap if BUFFER_COUNT > theads count
     */
    std::array<uint8_t *, BUFFER_COUNT> m_videoBuffers{0};

    struct buffer
    {
        unsigned int idx{std::numeric_limits<unsigned int>::max()};
        unsigned int padding[VIDEO_MAX_PLANES]{
            std::numeric_limits<unsigned int>::max()};
        unsigned int size[VIDEO_MAX_PLANES]{
            std::numeric_limits<unsigned int>::max()};
        void *mem[VIDEO_MAX_PLANES]{nullptr};
    };
    std::vector<buffer> buffers;

    // std::mutex m_queueMtx;
    std::mutex m_camMtx;
    std::queue<size_t> m_buffersQueue;

    std::jthread m_streamThread;
    // std::jthread m_calcThreads[1];
    std::jthread m_calcThreads[4];

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