diff --git a/src/QtAV/VideoCapture.h b/src/QtAV/VideoCapture.h index ade5ce78..8af59194 100644 --- a/src/QtAV/VideoCapture.h +++ b/src/QtAV/VideoCapture.h @@ -20,15 +20,14 @@ ******************************************************************************/ -#ifndef VIDEOCAPTURE_H -#define VIDEOCAPTURE_H +#ifndef QTAV_VIDEOCAPTURE_H +#define QTAV_VIDEOCAPTURE_H #include #include #include #include -class QSize; namespace QtAV { //on capture per thread or all in one thread? @@ -44,7 +43,6 @@ class Q_AV_EXPORT VideoCapture : public QObject Q_PROPERTY(QString captureDir READ captureDir WRITE setCaptureDir NOTIFY captureDirChanged) public: explicit VideoCapture(QObject *parent = 0); - ~VideoCapture(); void setAsync(bool value = true); bool isAsync() const; /*! @@ -101,7 +99,7 @@ Q_SIGNALS: * Emitted when captured video frame is converted to a QImage. * \param image */ - void imageCaptured(const QImage& image); + void imageCaptured(const QImage& image); //TODO: emit only if not original format is set? void failed(); /*! * \brief saved @@ -117,6 +115,8 @@ Q_SIGNALS: void qualityChanged(); void captureNameChanged(); void captureDirChanged(); +private slots: + void handleAppQuit(); private: void setVideoFrame(const VideoFrame& frame); // It's called by VideoThread after immediatly setVideoFrame(). Will emit ready() @@ -137,4 +137,4 @@ private: }; } //namespace QtAV -#endif // VIDEOCAPTURE_H +#endif // QTAV_VIDEOCAPTURE_H diff --git a/src/VideoCapture.cpp b/src/VideoCapture.cpp index d356d211..e403251e 100644 --- a/src/VideoCapture.cpp +++ b/src/VideoCapture.cpp @@ -20,23 +20,23 @@ ******************************************************************************/ -#include -#include -#include +#include "QtAV/VideoCapture.h" +#include "QtAV/ImageConverterTypes.h" #include #include #include #include -#include -#include "utils/Logger.h" - #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #include #else #include #endif +#include "utils/Logger.h" + namespace QtAV { +Q_GLOBAL_STATIC(QThreadPool, videoCaptureThreadPool) +static bool app_is_dieing = false; // TODO: cancel if qapp is quit class CaptureTask : public QRunnable { @@ -48,6 +48,11 @@ public: setAutoDelete(true); } virtual void run() { + if (app_is_dieing) { + qDebug("app is dieing. cancel capture task %p", this); + return; + } + // TODO: add VideoFrame::toImage(QImage::Format),toFormat(VideoFormat)... ImageConverter *conv = ImageConverterFactory::create(ImageConverterId_FF); const VideoFormat vformat(frame.format()); conv->setInFormat(vformat.pixelFormatFFmpeg()); @@ -138,11 +143,8 @@ VideoCapture::VideoCapture(QObject *parent) : dir = qApp->applicationDirPath() + "/capture"; fmt = "PNG"; qual = -1; -} - -VideoCapture::~VideoCapture() -{ - qDebug("%p %s %s", QThread::currentThreadId(), __FILE__, __FUNCTION__); + // seems no direct connection is fine too + connect(qApp, SIGNAL(aboutToQuit()), SLOT(handleAppQuit()), Qt::DirectConnection); } void VideoCapture::setAsync(bool value) @@ -184,6 +186,17 @@ bool VideoCapture::isOriginalFormat() const return original_fmt; } +void VideoCapture::handleAppQuit() +{ + app_is_dieing = true; + // TODO: how to cancel? since qt5.2, we can use clear() +#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + videoCaptureThreadPool()->clear(); +#endif + videoCaptureThreadPool()->setExpiryTimeout(0); + videoCaptureThreadPool()->waitForDone(); +} + void VideoCapture::request() { emit requested(); @@ -204,7 +217,7 @@ void VideoCapture::start() task->qfmt = qfmt; task->frame = frame; //copy here and it's safe in capture thread because start() is called immediatly after setVideoFrame if (isAsync()) { - QThreadPool::globalInstance()->start(task); + videoCaptureThreadPool()->start(task); } else { task->run(); }