DirectShow: Refactor camera backend.
Almost entire rewrite of the camera backend. It doesn't provide new features but is more stable and behave as it should. - Correctly report camera state and status - Correctly report if the camera is ready to capture - Emit imageExposed() signal - Save captured images in an appropriate directory - Images can be captured even without a viewport - Better error handling Removed the custom QVideoWidgetControl as it doesn't provide anything more than the QVideoWidget's renderer control fallback. Task-number: QTBUG-33782 Change-Id: I9baf6f83e7c69619f20a101921f7865a1c90d5e4 Reviewed-by: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <QtMultimedia/qvideoframe.h>
|
||||
#include <QtMultimedia/qabstractvideosurface.h>
|
||||
#include <QtMultimedia/qvideosurfaceformat.h>
|
||||
#include <private/qmediastoragelocation_p.h>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <dshow.h>
|
||||
@@ -75,18 +76,8 @@ struct ISampleGrabber;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class DSVideoRenderer;
|
||||
class SampleGrabberCallbackPrivate;
|
||||
|
||||
|
||||
struct video_buffer {
|
||||
unsigned char* buffer;
|
||||
int length;
|
||||
qint64 time;
|
||||
};
|
||||
|
||||
typedef QMap<unsigned int, QList<QSize> > FormatResolutionMap;
|
||||
|
||||
class DSCameraSession : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -94,113 +85,82 @@ public:
|
||||
DSCameraSession(QObject *parent = 0);
|
||||
~DSCameraSession();
|
||||
|
||||
bool deviceReady();
|
||||
bool pictureInProgress();
|
||||
QCamera::Status status() const { return m_status; }
|
||||
|
||||
// camera controls
|
||||
|
||||
int framerate() const;
|
||||
void setFrameRate(int rate);
|
||||
int brightness() const;
|
||||
void setBrightness(int b);
|
||||
int contrast() const;
|
||||
void setContrast(int c);
|
||||
int saturation() const;
|
||||
void setSaturation(int s);
|
||||
int hue() const;
|
||||
void setHue(int h);
|
||||
int sharpness() const;
|
||||
void setSharpness(int s);
|
||||
int zoom() const;
|
||||
void setZoom(int z);
|
||||
bool backlightCompensation() const;
|
||||
void setBacklightCompensation(bool);
|
||||
int whitelevel() const;
|
||||
void setWhitelevel(int w);
|
||||
int rotation() const;
|
||||
void setRotation(int r);
|
||||
bool flash() const;
|
||||
void setFlash(bool f);
|
||||
bool autofocus() const;
|
||||
void setAutofocus(bool f);
|
||||
|
||||
QSize frameSize() const;
|
||||
void setFrameSize(const QSize& s);
|
||||
void setDevice(const QString &device);
|
||||
QList<QVideoFrame::PixelFormat> supportedPixelFormats();
|
||||
QVideoFrame::PixelFormat pixelFormat() const;
|
||||
void setPixelFormat(QVideoFrame::PixelFormat fmt);
|
||||
QList<QSize> supportedResolutions(QVideoFrame::PixelFormat format);
|
||||
|
||||
// media control
|
||||
bool load();
|
||||
bool unload();
|
||||
bool startPreview();
|
||||
bool stopPreview();
|
||||
|
||||
bool setOutputLocation(const QUrl &sink);
|
||||
QUrl outputLocation() const;
|
||||
qint64 position() const;
|
||||
int state() const;
|
||||
void record();
|
||||
void pause();
|
||||
void stop();
|
||||
bool isReadyForCapture();
|
||||
int captureImage(const QString &fileName);
|
||||
|
||||
void setSurface(QAbstractVideoSurface* surface);
|
||||
|
||||
int captureImage(const QString &fileName);
|
||||
|
||||
AM_MEDIA_TYPE StillMediaType;
|
||||
QList<video_buffer*> frames;
|
||||
SampleGrabberCallbackPrivate* StillCapCB;
|
||||
|
||||
QMutex mutex;
|
||||
|
||||
Q_SIGNALS:
|
||||
void stateChanged(QCamera::State);
|
||||
void statusChanged(QCamera::Status);
|
||||
void imageExposed(int id);
|
||||
void imageCaptured(int id, const QImage &preview);
|
||||
void imageSaved(int id, const QString &fileName);
|
||||
void readyForCaptureChanged(bool);
|
||||
void captureError(int id, int error, const QString &errorString);
|
||||
|
||||
private Q_SLOTS:
|
||||
void captureFrame();
|
||||
void presentFrame();
|
||||
void updateReadyForCapture();
|
||||
|
||||
private:
|
||||
QVideoSurfaceFormat actualFormat;
|
||||
QList<QVideoFrame::PixelFormat> types;
|
||||
void setStatus(QCamera::Status status);
|
||||
void populateCommonResolutions();
|
||||
|
||||
QTime timeStamp;
|
||||
bool graph;
|
||||
bool active;
|
||||
bool opened;
|
||||
bool available;
|
||||
QCamera::State m_state;
|
||||
QByteArray m_device;
|
||||
QUrl m_sink;
|
||||
DSVideoRenderer* m_output;
|
||||
QAbstractVideoSurface* m_surface;
|
||||
QVideoFrame::PixelFormat pixelF;
|
||||
QSize m_windowSize;
|
||||
FormatResolutionMap resolutions;
|
||||
void onFrameAvailable(const char *frameData, long len);
|
||||
void saveCapturedImage(int id, const QImage &image, const QString &path);
|
||||
|
||||
ICaptureGraphBuilder2* pBuild;
|
||||
IGraphBuilder* pGraph;
|
||||
IBaseFilter* pCap;
|
||||
IBaseFilter* pSG_Filter;
|
||||
ISampleGrabber *pSG;
|
||||
|
||||
|
||||
QString m_snapshot;
|
||||
int m_currentImageId;
|
||||
bool needsHorizontalMirroring;
|
||||
bool needsVerticalMirroring;
|
||||
protected:
|
||||
HRESULT getPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);
|
||||
bool createFilterGraph();
|
||||
void updateProperties();
|
||||
bool setProperties();
|
||||
bool openStream();
|
||||
void closeStream();
|
||||
bool startStream();
|
||||
void stopStream();
|
||||
void suspendStream();
|
||||
void resumeStream();
|
||||
bool connectGraph();
|
||||
void disconnectGraph();
|
||||
void updateSourceCapabilities();
|
||||
bool configurePreviewFormat();
|
||||
|
||||
QMutex m_presentMutex;
|
||||
QMutex m_captureMutex;
|
||||
|
||||
// Capture Graph
|
||||
ICaptureGraphBuilder2* m_graphBuilder;
|
||||
IGraphBuilder* m_filterGraph;
|
||||
|
||||
// Source (camera)
|
||||
QString m_sourceDeviceName;
|
||||
IBaseFilter* m_sourceFilter;
|
||||
AM_MEDIA_TYPE m_sourcePreferredFormat;
|
||||
QSize m_sourcePreferredResolution;
|
||||
bool m_needsHorizontalMirroring;
|
||||
|
||||
// Preview
|
||||
IBaseFilter *m_previewFilter;
|
||||
ISampleGrabber *m_previewSampleGrabber;
|
||||
IBaseFilter *m_nullRendererFilter;
|
||||
QVideoFrame m_currentFrame;
|
||||
bool m_previewStarted;
|
||||
QAbstractVideoSurface* m_surface;
|
||||
QVideoSurfaceFormat m_previewSurfaceFormat;
|
||||
QVideoFrame::PixelFormat m_previewPixelFormat;
|
||||
QSize m_previewSize;
|
||||
|
||||
// Image capture
|
||||
QString m_imageCaptureFileName;
|
||||
QMediaStorageLocation m_fileNameGenerator;
|
||||
bool m_readyForCapture;
|
||||
int m_imageIdCounter;
|
||||
int m_currentImageId;
|
||||
QVideoFrame m_capturedFrame;
|
||||
|
||||
// Internal state
|
||||
QCamera::Status m_status;
|
||||
|
||||
friend class SampleGrabberCallbackPrivate;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Reference in New Issue
Block a user