Tue. Jul 28th, 2026
sudo apt update
sudo apt install libcamera-dev pkg-config cmake Build-essential
cmake_minimum_required(VERSION 3.16)
project(HQCameraApp CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Find libcamera using pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBCAMERA REQUIRED libcamera)

add_executable(hq_camera_test main.cpp)

target_include_directories(hq_camera_test PRIVATE ${LIBCAMERA_INCLUDE_DIRS})
target_link_libraries(hq_camera_test PRIVATE ${LIBCAMERA_LIBRARIES})
#ifndef PI_HQ_CAMERA_H
#define PI_HQ_CAMERA_H

#include "device_base.h"
#include <QMutex>
#include <QByteArray>
#include <QSize>
#include <QString>

// Forward declarations of native libcamera structures to prevent polluting 
// this header file with complex, external dependencies.
namespace libcamera {
    class CameraManager;
    class Camera;
    class FrameBufferAllocator;
    class CameraConfiguration;
    class Request;
}

namespace LigDeviceNS {

/**
 * Concrete driver class implementing the Raspberry Pi HQ Camera (Sony IMX477 sensor)
 * within the DeviceBase framework. Maps standard controls to the native Linux libcamera stack.
 */
class PiHqCamera : public DeviceBase
{
public:
    /**
     * Constructor. Initializes the underlying Camera Manager.
     */
    PiHqCamera(int camIndex = 0);
    
    /**
     * Destructor. Ensures clean device detachment and hardware release.
     */
    ~PiHqCamera();

    // --- DeviceBase Interface Overrides ---
    int mode() const override;
    void setMode(int n) override;
    int modeCount() const override;
    QString modeInfo(int n) const override;
    QSize imageSize() const override;

    bool isAutoExposureSupported() const override;
    bool autoExposureEnabled() const override;
    void setAutoExposureEnabled(bool enabled) override;

    double shutter() override;
    void setShutter(double ms) override;

    double minGain() const override;
    double maxGain() const override;
    double gain() override;
    void setGain(double db) override;

    double effectiveIntensity() override;
    void setEffectiveIntensity(double f) override;

    bool autoBalanceEnabled() override;
    void setAutoBalanceEnabled(bool enabled) override;

    // Custom color balance values can be stored, though standard libcamera 
    // groups manual adjustments under native AWB algorithms.
    double balanceBlue() override;
    void setBalanceBlue(double blue) override;
    double balanceRed() override;
    void setBalanceRed(double red) override;

    /**
     * Synchronously fetches the latest frame buffer captured by the background hardware loop.
     * Maps the pixel data directly into a thread-safe QImage wrapper.
     */
    QImage acquire() override;

    QString deviceName() const override;
    QString controllerName() const override;
    QString info() const override;

    bool queryConnection() override;
    bool connect() override;
    void disconnect() override;

private:
    // Internal hardware tracking configuration parameters
    int _camIndex {0};
    int _mode {0};
    bool _autoExposureEnabled {false};
    bool _autoBalanceEnabled {false};
    double _shutter {10.0};          // Exposure time tracker in milliseconds
    double _gain {0.0};              // Analogue gain tracker in decibels
    double _effectiveIntensity {0.5}; // Target exposure reference point
    double _balanceBlue {0.15};
    double _balanceRed {0.19};
    
    QString _deviceName {"Raspberry Pi HQ Camera"};
    QString _deviceSerial {"Unknown"};
    QString _firmwareVersion {"1.0"};

    // Native libcamera core pipeline control handles
    std::unique_ptr<libcamera::CameraManager> _cameraManager;
    std::shared_ptr<libcamera::Camera> _libcamDevice;
    std::unique_ptr<libcamera::FrameBufferAllocator> _allocator;
    std::vector<std::unique_ptr<libcamera::Request>> _requests;

    // Buffer state variables to synchronize the asynchronous callback with acquire()
    QMutex _bufferMutex;
    QByteArray _latestFrameData; 
    bool _frameAvailable {false};

    // Internal execution workers
    void requestComplete(libcamera::Request *request);
    bool applyDeviceControls();
    
    // Static mapping routine matching codebase standard patterns
    static int camToCbit(int camIdx, int cbn);
};

} // namespace LigDeviceNS

#endif // PI_HQ_CAMERA_H
#include <opencv2/opencv.hpp>
#include <iostream>
#include <thread>
#include <mutex>
#include <queue>

// Thread-safe frame queue for processing
std::queue<cv::Mat> frameQueue;
std::mutex queueMutex;
bool running = true;

void captureThread(cv::VideoCapture& cap) {
    while (running) {
        cv::Mat frame;
        cap >> frame; // Capture the latest frame
        if (frame.empty()) continue;

        std::lock_guard<std::mutex> lock(queueMutex);
        if (frameQueue.size() < 10) { // Prevent memory bloating
            frameQueue.push(frame.clone());
        }
    }
}

By admin

Leave a Reply

Your email address will not be published. Required fields are marked *