uvccamerasession.h 4.13 KB
Newer Older
Thiago C. Santini's avatar
Thiago C. Santini committed
1 2 3 4 5 6 7
#ifndef UVCCAMERASESSION_H
#define UVCCAMERASESSION_H

#include <QObject>
#include <QTime>
#include <QUrl>
#include <QMutex>
8
#include <QThread>
Thiago C. Santini's avatar
Thiago C. Santini committed
9 10 11 12 13 14 15

#include <qcamera.h>
#include <QtMultimedia/qvideoframe.h>
#include <QtMultimedia/qabstractvideosurface.h>
#include <QtMultimedia/qvideosurfaceformat.h>
#include <QtMultimedia/qcameraimageprocessingcontrol.h>
#include <QtMultimedia/qabstractvideobuffer.h>
16
#include <QtMultimedia/qcameraexposurecontrol.h>
Thiago C. Santini's avatar
Thiago C. Santini committed
17 18 19 20

#include <QElapsedTimer>

#include <vector>
21
#include <atomic>
Thiago C. Santini's avatar
Thiago C. Santini committed
22 23 24 25 26 27

#include "libuvc/libuvc.h"

QT_BEGIN_NAMESPACE

// Maximum acceptable latency for calling the surface present method
28
#define MAX_LATENCY_MS 1.0e3/25
Thiago C. Santini's avatar
Thiago C. Santini committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

class UVCCameraSession : public QObject
{
    Q_OBJECT
public:
    UVCCameraSession(QObject *parent = 0);
    ~UVCCameraSession();

    QCamera::Status status() const { return m_status; }

    void setSurface(QAbstractVideoSurface* surface);

    QList<QCameraViewfinderSettings> supportedViewfinderSettings();
    QCameraViewfinderSettings viewfinderSettings();
    void setViewfinderSettings(const QCameraViewfinderSettings &settings);

45
	bool setDevice(const QString &device);
Thiago C. Santini's avatar
Thiago C. Santini committed
46 47 48 49 50 51 52

    bool load();
    bool unload();
    bool startPreview();
    bool stopPreview();
    void callback(uvc_frame_t *frame);

53 54
    bool streaming;
    uvc_stream_handle_t *strmh;
55
    QMutex getFrameMutex;
56
	double interval;
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
	// Image Processing
	template<typename T>
	QVariant uvc_get( uvc_device_handle_t *devh,
					  uvc_error_t (*get)( uvc_device_handle_t *, T *, enum uvc_req_code)
					  ) const {
		T mn, val, mx;
		get(devh, &mn,  UVC_GET_MIN);
		get(devh, &val, UVC_GET_CUR);
		get(devh, &mx,  UVC_GET_MAX);
		//qDebug() << mn << val << mx;
		return (val - mn) / (double) (mx - mn) ;
	}
	template<typename T>
	void uvc_set( uvc_device_handle_t *devh,
					  uvc_error_t (*set)( uvc_device_handle_t *, T),
					  QVariant val,
					  uvc_error_t (*get)( uvc_device_handle_t *, T *, enum uvc_req_code)
					  ) {
		T mn, mx;
		get(devh, &mn,  UVC_GET_MIN);
		get(devh, &mx,  UVC_GET_MAX);
		double value = val.toDouble();
		value = value * (mx - mn ) + mn;
		//qDebug() << val;
		set(devh, static_cast<T>(value));
	}

Thiago Santini's avatar
Thiago Santini committed
85
	// Image Processing
86 87 88 89 90 91 92
	bool isImageProcessingParameterSupported(QCameraImageProcessingControl::ProcessingParameter parameter) const;
	bool isImageProcessingParameterValueSupported(QCameraImageProcessingControl::ProcessingParameter parameter,
			const QVariant &value) const;
	QVariant imageProcessingParameter(QCameraImageProcessingControl::ProcessingParameter parameter) const;
	void setImageProcessingParameter(QCameraImageProcessingControl::ProcessingParameter parameter,
			const QVariant &value);

Thiago Santini's avatar
Thiago Santini committed
93 94 95 96 97 98 99
	// Exposure
	QVariant actualExposureValue(QCameraExposureControl::ExposureParameter parameter) const;
	bool isExposureParameterSupported(QCameraExposureControl::ExposureParameter parameter) const;
	QVariant requestedExposureValue(QCameraExposureControl::ExposureParameter parameter) const;
	bool setExposureValue(QCameraExposureControl::ExposureParameter parameter, const QVariant &value);
	QVariantList supportedExposureParameterRange(QCameraExposureControl::ExposureParameter parameter, bool *continuous) const;

Thiago C. Santini's avatar
Thiago C. Santini committed
100
private Q_SLOTS:
101
    void presentFrame(QVideoFrame frame, const qreal t);
Thiago C. Santini's avatar
Thiago C. Santini committed
102 103

private:
104
    float bandwidthFactor;
Thiago C. Santini's avatar
Thiago C. Santini committed
105 106
    QCamera::Status m_status;
    QAbstractVideoSurface *m_surface;
107 108
	QMutex surfaceMutex;
	QString deviceName;
Thiago C. Santini's avatar
Thiago C. Santini committed
109 110

    // Source (camera)
111 112
	uvc_context_t* ctx;
	uvc_device_t *dev;
Thiago C. Santini's avatar
Thiago C. Santini committed
113 114 115 116 117 118 119 120 121 122 123 124
    uvc_device_handle_t *devh;
    uvc_stream_ctrl_t ctrl;

    // Frame
    QVideoFrame currentFrame;
    unsigned char* yuvBuffer;
    long unsigned int yuvBufferSize;
    QElapsedTimer frameReference;

    // capabilities
    QList<QCameraViewfinderSettings> m_supportedViewfinderSettings;
    void updateSourceCapabilities();
125
	QCameraViewfinderSettings settings;
Thiago C. Santini's avatar
Thiago C. Santini committed
126
    bool qPixelFormat2UVCFrameFormat(const QVideoFrame::PixelFormat &qFormat, uvc_frame_format &uvcFormat);
127 128

    static QMutex sessionMutex;
129

130 131 132 133 134
	// device availability
	static QMap<QString,bool> UVCCameraSession::devices;
	static QMutex UVCCameraSession::devicesMutex;
	bool acquire(const QString &device);
	void release(const QString &device);
Thiago C. Santini's avatar
Thiago C. Santini committed
135 136 137 138 139 140
};

QT_END_NAMESPACE


#endif // UVCCAMERASESSION_H