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

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

// qt
#include <QQueue>
#include <QReadWriteLock>
#include <QSemaphore>

// orpheus
#include "constants.h"
#include "icamera.h"
#include "image.h"
#include "utils/sem_queue.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:
    [[nodiscard]] static std::vector<std::shared_ptr<ICamera>> search();

public:
    [[nodiscard]] bool startStream() override;

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

    bool init();

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

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

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

    [[nodiscard]] bool set_gain(const float value) override;
    [[nodiscard]] 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:
    [[nodiscard]] bool openCam();
    [[nodiscard]] bool initCam();

    [[nodiscard]] bool initI2C();

    void getFramesLoop(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};

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

    // TODO: split this
    // there should be no chance of changing image by ioctl during futher processing
    struct buffer
    {
        void *mem{nullptr};
        std::shared_ptr<Image> image{std::make_shared<Image>()};
    };
    std::vector<buffer> m_rawBuffers;
    // std::array<Image, BUFFER_COUNT> m_images;

    std::mutex m_camMtx;

    std::jthread m_streamThread;
    std::jthread m_getThreads[1];
    std::mutex m_lastImageMtx;
    std::shared_ptr<Image> m_lastProcessedImage{};

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