summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-10-09 18:04:44 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-10-09 18:04:44 +0200
commita7b67a97ecf0d5cf9d1c913c9367b7dd68c0108d (patch)
tree5582b688420ea2a1673337a9845ea2a00aeceb9b /src
parent762ff94f67a58df6c7c6315268ea64a2d2151f95 (diff)
parentca94dc79b6f0e57ba7446a87c70398a178fbcac8 (diff)
Merge remote-tracking branch 'origin/5.4' into dev
Diffstat (limited to 'src')
-rw-r--r--src/gsttools/gsttools.pro2
-rw-r--r--src/gsttools/qgstutils.cpp8
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp86
-rw-r--r--src/imports/multimedia/qdeclarativeradiodata.cpp3
-rw-r--r--src/multimedia/audio/qsoundeffect_qaudio_p.cpp3
-rw-r--r--src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h13
-rw-r--r--src/multimedia/playback/playlistfileparser.cpp149
-rw-r--r--src/multimedia/qmediaopenglhelper_p.h4
-rw-r--r--src/plugins/alsa/qalsaaudioinput.cpp2
-rw-r--r--src/plugins/alsa/qalsaaudiooutput.cpp2
-rw-r--r--src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java20
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp185
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h5
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp4
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp10
-rw-r--r--src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h4
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp133
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h4
-rw-r--r--src/plugins/avfoundation/camera/avfcameraservice.mm4
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm5
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h5
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm126
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowidget.mm4
-rw-r--r--src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm4
-rw-r--r--src/plugins/coreaudio/coreaudiodeviceinfo.mm1
-rw-r--r--src/plugins/coreaudio/coreaudioinput.h1
-rw-r--r--src/plugins/coreaudio/coreaudioinput.mm1
-rw-r--r--src/plugins/coreaudio/coreaudiooutput.h1
-rw-r--r--src/plugins/coreaudio/coreaudiooutput.mm5
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp24
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinaudioencoder.h2
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.cpp57
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.h4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp42
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinvideoencoder.h2
-rw-r--r--src/plugins/gstreamer/mediacapture/mediacapture.pro21
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp9
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h2
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp11
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp99
-rw-r--r--src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h3
-rw-r--r--src/plugins/opensles/qopenslesaudioinput.cpp2
-rw-r--r--src/plugins/opensles/qopenslesaudiooutput.cpp101
-rw-r--r--src/plugins/opensles/qopenslesaudiooutput.h4
-rw-r--r--src/plugins/plugins.pro6
-rw-r--r--src/plugins/pulseaudio/qaudioinput_pulse.cpp2
-rw-r--r--src/plugins/pulseaudio/qaudiooutput_pulse.cpp2
-rw-r--r--src/plugins/qnx-audio/audio/qnxaudioinput.cpp2
-rw-r--r--src/plugins/qnx-audio/audio/qnxaudiooutput.cpp2
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp1
-rw-r--r--src/plugins/qt7/mediaplayer/mediaplayer.pri16
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playercontrol.h98
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playercontrol.mm191
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playermetadata.h66
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playermetadata.mm250
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playerservice.h73
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playerservice.mm128
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playersession.h183
-rw-r--r--src/plugins/qt7/mediaplayer/qt7playersession.mm751
-rw-r--r--src/plugins/qt7/qcvdisplaylink.h80
-rw-r--r--src/plugins/qt7/qcvdisplaylink.mm156
-rw-r--r--src/plugins/qt7/qt7.json4
-rw-r--r--src/plugins/qt7/qt7.pro67
-rw-r--r--src/plugins/qt7/qt7backend.h60
-rw-r--r--src/plugins/qt7/qt7ciimagevideobuffer.h78
-rw-r--r--src/plugins/qt7/qt7ciimagevideobuffer.mm107
-rw-r--r--src/plugins/qt7/qt7movierenderer.h98
-rw-r--r--src/plugins/qt7/qt7movierenderer.mm481
-rw-r--r--src/plugins/qt7/qt7movievideowidget.h117
-rw-r--r--src/plugins/qt7/qt7movievideowidget.mm437
-rw-r--r--src/plugins/qt7/qt7movieviewoutput.h107
-rw-r--r--src/plugins/qt7/qt7movieviewoutput.mm339
-rw-r--r--src/plugins/qt7/qt7movieviewrenderer.h96
-rw-r--r--src/plugins/qt7/qt7movieviewrenderer.mm509
-rw-r--r--src/plugins/qt7/qt7serviceplugin.h69
-rw-r--r--src/plugins/qt7/qt7videooutput.h109
-rw-r--r--src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp30
-rw-r--r--src/plugins/windowsaudio/qwindowsaudioinput.cpp2
-rw-r--r--src/plugins/windowsaudio/qwindowsaudiooutput.cpp2
-rw-r--r--src/plugins/windowsaudio/windowsaudio.pro3
-rw-r--r--src/plugins/winrt/qwinrtcameracontrol.cpp783
-rw-r--r--src/plugins/winrt/qwinrtcameracontrol.h111
-rw-r--r--src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp280
-rw-r--r--src/plugins/winrt/qwinrtcameraimagecapturecontrol.h (renamed from src/plugins/qt7/qt7serviceplugin.mm)96
-rw-r--r--src/plugins/winrt/qwinrtcamerainfocontrol.cpp (renamed from src/plugins/qt7/qt7videooutput.mm)49
-rw-r--r--src/plugins/winrt/qwinrtcamerainfocontrol.h (renamed from src/plugins/qt7/qt7backend.mm)25
-rw-r--r--src/plugins/winrt/qwinrtcameraservice.cpp104
-rw-r--r--src/plugins/winrt/qwinrtcameraservice.h66
-rw-r--r--src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp204
-rw-r--r--src/plugins/winrt/qwinrtcameravideorenderercontrol.h74
-rw-r--r--src/plugins/winrt/qwinrtserviceplugin.cpp39
-rw-r--r--src/plugins/winrt/qwinrtserviceplugin.h14
-rw-r--r--src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp383
-rw-r--r--src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h94
-rw-r--r--src/plugins/winrt/winrt.json2
-rw-r--r--src/plugins/winrt/winrt.pro18
-rw-r--r--src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp3
-rw-r--r--src/plugins/wmf/evrd3dpresentengine.cpp56
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp103
-rw-r--r--src/plugins/wmf/samplegrabber.cpp3
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_rgb.cpp2
102 files changed, 3001 insertions, 5411 deletions
diff --git a/src/gsttools/gsttools.pro b/src/gsttools/gsttools.pro
index 15edd04d2..7c809a777 100644
--- a/src/gsttools/gsttools.pro
+++ b/src/gsttools/gsttools.pro
@@ -100,6 +100,8 @@ config_gstreamer_appsrc {
LIBS_PRIVATE += -lgstapp-0.10
}
+config_linux_v4l: DEFINES += USE_V4L
+
HEADERS += $$PRIVATE_HEADERS
DESTDIR = $$QT.multimedia.libs
diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp
index 9740b9a09..8d484aa6d 100644
--- a/src/gsttools/qgstutils.cpp
+++ b/src/gsttools/qgstutils.cpp
@@ -42,8 +42,10 @@
#include <QtCore/qstringlist.h>
#include <qaudioformat.h>
-#include <private/qcore_unix_p.h>
-#include <linux/videodev2.h>
+#ifdef USE_V4L
+# include <private/qcore_unix_p.h>
+# include <linux/videodev2.h>
+#endif
#include "qgstreamervideoinputdevicecontrol_p.h"
@@ -469,6 +471,7 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa
}
}
+#ifdef USE_V4L
QDir devDir(QStringLiteral("/dev"));
devDir.setFilter(QDir::System);
@@ -516,6 +519,7 @@ QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *fa
}
qt_safe_close(fd);
}
+#endif // USE_V4L
return devices;
}
diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
index 36f8c049b..f3e2d884c 100644
--- a/src/gsttools/qvideosurfacegstsink.cpp
+++ b/src/gsttools/qvideosurfacegstsink.cpp
@@ -56,7 +56,6 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
: m_surface(surface)
, m_pool(0)
, m_renderReturn(GST_FLOW_ERROR)
- , m_lastPrerolledBuffer(0)
, m_bytesPerLine(0)
, m_startCanceled(false)
{
@@ -74,7 +73,6 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
QVideoSurfaceGstDelegate::~QVideoSurfaceGstDelegate()
{
- setLastPrerolledBuffer(0);
}
QList<QVideoFrame::PixelFormat> QVideoSurfaceGstDelegate::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
@@ -209,23 +207,6 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
return m_renderReturn;
}
-void QVideoSurfaceGstDelegate::setLastPrerolledBuffer(GstBuffer *prerolledBuffer)
-{
- // discard previously stored buffer
- if (m_lastPrerolledBuffer) {
- gst_buffer_unref(m_lastPrerolledBuffer);
- m_lastPrerolledBuffer = 0;
- }
-
- if (!prerolledBuffer)
- return;
-
- // store a reference to the buffer
- Q_ASSERT(!m_lastPrerolledBuffer);
- m_lastPrerolledBuffer = prerolledBuffer;
- gst_buffer_ref(m_lastPrerolledBuffer);
-}
-
void QVideoSurfaceGstDelegate::queuedStart()
{
if (!m_startCanceled) {
@@ -397,8 +378,6 @@ QVideoSurfaceGstSink *QVideoSurfaceGstSink::createSink(QAbstractVideoSurface *su
sink->delegate = new QVideoSurfaceGstDelegate(surface);
- g_signal_connect(G_OBJECT(sink), "notify::show-preroll-frame", G_CALLBACK(handleShowPrerollChange), sink);
-
return sink;
}
@@ -434,16 +413,15 @@ void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data)
sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class));
+ GstVideoSinkClass *video_sink_class = reinterpret_cast<GstVideoSinkClass *>(g_class);
+ video_sink_class->show_frame = QVideoSurfaceGstSink::show_frame;
+
GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
base_sink_class->get_caps = QVideoSurfaceGstSink::get_caps;
base_sink_class->set_caps = QVideoSurfaceGstSink::set_caps;
base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc;
base_sink_class->start = QVideoSurfaceGstSink::start;
base_sink_class->stop = QVideoSurfaceGstSink::stop;
- // base_sink_class->unlock = QVideoSurfaceGstSink::unlock; // Not implemented.
- base_sink_class->event = QVideoSurfaceGstSink::event;
- base_sink_class->preroll = QVideoSurfaceGstSink::preroll;
- base_sink_class->render = QVideoSurfaceGstSink::render;
GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
element_class->change_state = QVideoSurfaceGstSink::change_state;
@@ -709,27 +687,6 @@ void QVideoSurfaceGstSink::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buf
}
}
-void QVideoSurfaceGstSink::handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(o);
- Q_UNUSED(p);
- QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>(d);
-
- gboolean value = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &value, NULL);
-
- GstBuffer *buffer = sink->delegate->lastPrerolledBuffer();
- // Render the stored prerolled buffer if requested.
- // e.g. player is in stopped mode, then seek operation is requested,
- // surface now stores a prerolled frame, but doesn't display it until
- // "show-preroll-frame" property is set to "true"
- // when switching to pause or playing state.
- if (value && buffer) {
- sink->delegate->render(buffer);
- sink->delegate->setLastPrerolledBuffer(0);
- }
-}
-
GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
GstBaseSink *base, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer)
{
@@ -842,44 +799,9 @@ gboolean QVideoSurfaceGstSink::stop(GstBaseSink *base)
return TRUE;
}
-gboolean QVideoSurfaceGstSink::unlock(GstBaseSink *base)
-{
- Q_UNUSED(base);
-
- return TRUE;
-}
-
-gboolean QVideoSurfaceGstSink::event(GstBaseSink *base, GstEvent *event)
-{
- // discard prerolled frame
- if (event->type == GST_EVENT_FLUSH_START) {
- VO_SINK(base);
- sink->delegate->setLastPrerolledBuffer(0);
- }
-
- return TRUE;
-}
-
-GstFlowReturn QVideoSurfaceGstSink::preroll(GstBaseSink *base, GstBuffer *buffer)
-{
- VO_SINK(base);
-
- gboolean value = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(base), "show-preroll-frame", &value, NULL);
- if (value) {
- sink->delegate->setLastPrerolledBuffer(0); // discard prerolled buffer
- return sink->delegate->render(buffer); // display frame
- }
-
- // otherwise keep a reference to the buffer to display it later
- sink->delegate->setLastPrerolledBuffer(buffer);
- return GST_FLOW_OK;
-}
-
-GstFlowReturn QVideoSurfaceGstSink::render(GstBaseSink *base, GstBuffer *buffer)
+GstFlowReturn QVideoSurfaceGstSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
{
VO_SINK(base);
- sink->delegate->setLastPrerolledBuffer(0); // discard prerolled buffer
return sink->delegate->render(buffer);
}
diff --git a/src/imports/multimedia/qdeclarativeradiodata.cpp b/src/imports/multimedia/qdeclarativeradiodata.cpp
index e8673905f..6cc829ae9 100644
--- a/src/imports/multimedia/qdeclarativeradiodata.cpp
+++ b/src/imports/multimedia/qdeclarativeradiodata.cpp
@@ -281,6 +281,9 @@ void QDeclarativeRadioData::_q_availabilityChanged(QMultimedia::AvailabilityStat
void QDeclarativeRadioData::connectSignals()
{
+ if (!m_radioData)
+ return;
+
connect(m_radioData, SIGNAL(programTypeChanged(QRadioData::ProgramType)), this,
SLOT(_q_programTypeChanged(QRadioData::ProgramType)));
diff --git a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
index c9f12aeb6..38052de32 100644
--- a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
+++ b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp
@@ -45,9 +45,6 @@
#include "qsoundeffect_qaudio_p.h"
#include <QtCore/qcoreapplication.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qwaitcondition.h>
#include <QtCore/qiodevice.h>
//#include <QDebug>
diff --git a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
index d152e2a44..11b305d27 100644
--- a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
+++ b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
@@ -84,9 +84,6 @@ public:
GstFlowReturn render(GstBuffer *buffer);
- GstBuffer *lastPrerolledBuffer() const { return m_lastPrerolledBuffer; }
- void setLastPrerolledBuffer(GstBuffer *lastPrerolledBuffer); // set prerolledBuffer to 0 to discard prerolled buffer
-
private slots:
void queuedStart();
void queuedStop();
@@ -108,8 +105,6 @@ private:
QVideoSurfaceFormat m_format;
QVideoFrame m_frame;
GstFlowReturn m_renderReturn;
- // this pointer is not 0 when there is a prerolled buffer waiting to be displayed
- GstBuffer *m_lastPrerolledBuffer;
int m_bytesPerLine;
bool m_started;
bool m_startCanceled;
@@ -126,8 +121,6 @@ public:
QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle);
static void setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer);
- static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
-
private:
static GType get_type();
static void class_init(gpointer g_class, gpointer class_data);
@@ -147,11 +140,7 @@ private:
static gboolean start(GstBaseSink *sink);
static gboolean stop(GstBaseSink *sink);
- static gboolean unlock(GstBaseSink *sink);
-
- static gboolean event(GstBaseSink *sink, GstEvent *event);
- static GstFlowReturn preroll(GstBaseSink *sink, GstBuffer *buffer);
- static GstFlowReturn render(GstBaseSink *sink, GstBuffer *buffer);
+ static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
private:
QVideoSurfaceGstDelegate *delegate;
diff --git a/src/multimedia/playback/playlistfileparser.cpp b/src/multimedia/playback/playlistfileparser.cpp
index ac556c25c..a3aba1cab 100644
--- a/src/multimedia/playback/playlistfileparser.cpp
+++ b/src/multimedia/playback/playlistfileparser.cpp
@@ -51,6 +51,30 @@ public:
virtual void parseLine(int lineIndex, const QString& line, const QUrl& root) = 0;
+protected:
+ QUrl expandToFullPath(const QUrl &root, const QString &line)
+ {
+ // On Linux, backslashes are not converted to forward slashes :/
+ if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) {
+ // Network share paths are not resolved
+ return QUrl::fromLocalFile(line);
+ }
+
+ QUrl url(line);
+ if (url.scheme().isEmpty()) {
+ // Resolve it relative to root
+ if (root.isLocalFile())
+ return root.resolved(QUrl::fromLocalFile(line));
+ else
+ return root.resolved(url);
+ } else if (url.scheme().length() == 1) {
+ // Assume it's a drive letter for a Windows path
+ url = QUrl::fromLocalFile(line);
+ }
+
+ return url;
+ }
+
Q_SIGNALS:
void newItem(const QVariant& content);
void finished();
@@ -138,29 +162,6 @@ public:
return -1;
}
- QUrl expandToFullPath(const QUrl& root, const QString& line)
- {
- // On Linux, backslashes are not converted to forward slashes :/
- if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) {
- // Network share paths are not resolved
- return QUrl::fromLocalFile(line);
- }
-
- QUrl url(line);
- if (url.scheme().isEmpty()) {
- // Resolve it relative to root
- if (root.isLocalFile())
- return root.resolved(QUrl::fromLocalFile(line));
- else
- return root.resolved(url);
- } else if (url.scheme().length() == 1) {
- // Assume it's a drive letter for a Windows path
- url = QUrl::fromLocalFile(line);
- }
-
- return url;
- }
-
private:
bool m_extendedFormat;
QVariantMap m_extraInfo;
@@ -172,27 +173,9 @@ class PLSParser : public ParserBase
public:
PLSParser(QObject *parent)
: ParserBase(parent)
- , m_state(Header)
- , m_count(0)
- , m_readFlags(0)
{
}
- enum ReadFlags
- {
- FileRead = 0x1,
- TitleRead = 0x2,
- LengthRead = 0x4,
- All = FileRead | TitleRead | LengthRead
- };
-
- enum State
- {
- Header,
- Track,
- Footer
- };
-
/*
*
The format is essentially that of an INI file structured as follows:
@@ -231,89 +214,25 @@ NumberOfEntries=2
Version=2
*/
- inline bool containsFlag(const ReadFlags& flag)
+ void parseLine(int, const QString &line, const QUrl &root)
{
- return (m_readFlags & int(flag)) == flag;
- }
+ // We ignore everything but 'File' entries, since that's the only thing we care about.
+ if (!line.startsWith(QLatin1String("File")))
+ return;
- inline void setFlag(const ReadFlags& flag)
- {
- m_readFlags |= int(flag);
- }
+ QString value = getValue(line);
+ if (value.isEmpty())
+ return;
- void parseLine(int lineIndex, const QString& line, const QUrl&)
- {
- switch (m_state) {
- case Header:
- if (line == QLatin1String("[playlist]")) {
- m_state = Track;
- setCount(1);
- }
- break;
- case Track:
- if (!containsFlag(FileRead) && line.startsWith(m_fileName)) {
- m_item[QLatin1String("url")] = getValue(lineIndex, line);
- setFlag(FileRead);
- } else if (!containsFlag(TitleRead) && line.startsWith(m_titleName)) {
- m_item[QMediaMetaData::Title] = getValue(lineIndex, line);
- setFlag(TitleRead);
- } else if (!containsFlag(LengthRead) && line.startsWith(m_lengthName)) {
- //convert from seconds to miliseconds
- int length = getValue(lineIndex, line).toInt();
- if (length > 0)
- m_item[QMediaMetaData::Duration] = length * 1000;
- setFlag(LengthRead);
- } else if (line.startsWith(QLatin1String("NumberOfEntries"))) {
- m_state = Footer;
- int entries = getValue(lineIndex, line).toInt();
- int count = m_readFlags == 0 ? (m_count - 1) : m_count;
- if (entries != count) {
- emit error(QPlaylistFileParser::FormatError, tr("Error parsing playlist: %1, expected count = %2").
- arg(line, QString::number(count)));
- }
- break;
- }
- if (m_readFlags == int(All)) {
- emit newItem(m_item);
- setCount(m_count + 1);
- }
- break;
- case Footer:
- if (line.startsWith(QLatin1String("Version"))) {
- int version = getValue(lineIndex, line).toInt();
- if (version != 2)
- emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1], expected version = 2")).arg(line));
- }
- break;
- }
+ emit newItem(expandToFullPath(root, value));
}
- QString getValue(int lineIndex, const QString& line) {
+ QString getValue(const QString& line) {
int start = line.indexOf('=');
- if (start < 0) {
- emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1]:%2")).arg(QString::number(lineIndex), line));
+ if (start < 0)
return QString();
- }
return line.midRef(start + 1).trimmed().toString();
}
-
- void setCount(int count) {
- m_count = count;
- m_fileName = QStringLiteral("File%1").arg(count);
- m_titleName = QStringLiteral("Title%1").arg(count);
- m_lengthName = QStringLiteral("Length%1").arg(count);
- m_item.clear();
- m_readFlags = 0;
- }
-
-private:
- State m_state;
- int m_count;
- QString m_titleName;
- QString m_fileName;
- QString m_lengthName;
- QVariantMap m_item;
- int m_readFlags;
};
}
diff --git a/src/multimedia/qmediaopenglhelper_p.h b/src/multimedia/qmediaopenglhelper_p.h
index d42dfba42..0dbd79d47 100644
--- a/src/multimedia/qmediaopenglhelper_p.h
+++ b/src/multimedia/qmediaopenglhelper_p.h
@@ -66,7 +66,7 @@ inline bool QMediaOpenGLHelper::isANGLE()
#else
bool isANGLE = false;
-# if defined(Q_OS_WIN) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC))
+# if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC))
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
// Although unlikely, technically LibGLES could mean a non-ANGLE EGL/GLES2 implementation too.
// Verify that it is indeed ANGLE.
@@ -98,7 +98,7 @@ inline bool QMediaOpenGLHelper::isANGLE()
# endif // QT_OPENGL_ES_2_ANGLE_STATIC
}
-# endif // Q_OS_WIN && (QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC)
+# endif // Q_OS_WIN && !Q_OS_WINCE && (QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC)
return isANGLE;
#endif // Q_OS_WINRT
diff --git a/src/plugins/alsa/qalsaaudioinput.cpp b/src/plugins/alsa/qalsaaudioinput.cpp
index bb0182a3e..adaa41c6e 100644
--- a/src/plugins/alsa/qalsaaudioinput.cpp
+++ b/src/plugins/alsa/qalsaaudioinput.cpp
@@ -760,7 +760,7 @@ qint64 QAlsaAudioInput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return clockStamp.elapsed()*1000;
+ return clockStamp.elapsed() * qint64(1000);
}
void QAlsaAudioInput::reset()
diff --git a/src/plugins/alsa/qalsaaudiooutput.cpp b/src/plugins/alsa/qalsaaudiooutput.cpp
index 07dd17362..fde2bc9bf 100644
--- a/src/plugins/alsa/qalsaaudiooutput.cpp
+++ b/src/plugins/alsa/qalsaaudiooutput.cpp
@@ -774,7 +774,7 @@ qint64 QAlsaAudioOutput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return clockStamp.elapsed()*1000;
+ return clockStamp.elapsed() * qint64(1000);
}
void QAlsaAudioOutput::reset()
diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
index ade2517d2..5e6630de8 100644
--- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
+++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java
@@ -83,23 +83,6 @@ public class QtAndroidMediaPlayer
private volatile int mState = State.Uninitialized;
- private class ProgressWatcher
- implements Runnable
- {
- @Override
- public void run()
- {
- try {
- while ((mState & (State.Started)) != 0) {
- onProgressUpdateNative(getCurrentPosition(), mID);
- Thread.sleep(1000);
- }
- } catch (final InterruptedException e) {
- // Ignore
- }
- }
- }
-
/**
* MediaPlayer OnErrorListener
*/
@@ -257,8 +240,6 @@ public class QtAndroidMediaPlayer
try {
mMediaPlayer.start();
setState(State.Started);
- Thread progressThread = new Thread(new ProgressWatcher());
- progressThread.start();
} catch (final IllegalStateException e) {
Log.d(TAG, "" + e.getMessage());
}
@@ -309,7 +290,6 @@ public class QtAndroidMediaPlayer
try {
mMediaPlayer.seekTo(msec);
- onProgressUpdateNative(msec, mID);
} catch (final IllegalStateException e) {
Log.d(TAG, "" + e.getMessage());
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
index 47dd94ccd..eae09c64f 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp
@@ -37,6 +37,36 @@
QT_BEGIN_NAMESPACE
+class StateChangeNotifier
+{
+public:
+ StateChangeNotifier(QAndroidMediaPlayerControl *mp)
+ : mControl(mp)
+ , mPreviousState(mp->state())
+ , mPreviousMediaStatus(mp->mediaStatus())
+ {
+ ++mControl->mActiveStateChangeNotifiers;
+ }
+
+ ~StateChangeNotifier()
+ {
+ if (--mControl->mActiveStateChangeNotifiers)
+ return;
+
+ if (mPreviousState != mControl->state())
+ Q_EMIT mControl->stateChanged(mControl->state());
+
+ if (mPreviousMediaStatus != mControl->mediaStatus())
+ Q_EMIT mControl->mediaStatusChanged(mControl->mediaStatus());
+ }
+
+private:
+ QAndroidMediaPlayerControl *mControl;
+ QMediaPlayer::State mPreviousState;
+ QMediaPlayer::MediaStatus mPreviousMediaStatus;
+};
+
+
QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
: QMediaPlayerControl(parent),
mMediaPlayer(new AndroidMediaPlayer),
@@ -55,7 +85,9 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
mPendingPosition(-1),
mPendingSetMedia(false),
mPendingVolume(-1),
- mPendingMute(-1)
+ mPendingMute(-1),
+ mReloadingMedia(false),
+ mActiveStateChangeNotifiers(0)
{
connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)),
this,SLOT(onBufferingChanged(qint32)));
@@ -107,17 +139,14 @@ qint64 QAndroidMediaPlayerControl::position() const
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
return duration();
- if ((mState & (AndroidMediaPlayer::Idle
- | AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Prepared
+ if ((mState & (AndroidMediaPlayer::Prepared
| AndroidMediaPlayer::Started
| AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::Stopped
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- return (mPendingPosition == -1) ? 0 : mPendingPosition;
+ | AndroidMediaPlayer::PlaybackCompleted))) {
+ return mMediaPlayer->getCurrentPosition();
}
- return (mCurrentState == QMediaPlayer::StoppedState) ? 0 : mMediaPlayer->getCurrentPosition();
+ return (mPendingPosition == -1) ? 0 : mPendingPosition;
}
void QAndroidMediaPlayerControl::setPosition(qint64 position)
@@ -127,24 +156,25 @@ void QAndroidMediaPlayerControl::setPosition(qint64 position)
const int seekPosition = (position > INT_MAX) ? INT_MAX : position;
- if ((mState & (AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- if (mPendingPosition != seekPosition) {
- mPendingPosition = seekPosition;
- Q_EMIT positionChanged(seekPosition);
- }
+ if (seekPosition == this->position())
return;
- }
+
+ StateChangeNotifier notifier(this);
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
setMediaStatus(QMediaPlayer::LoadedMedia);
- mMediaPlayer->seekTo(seekPosition);
+ if ((mState & (AndroidMediaPlayer::Prepared
+ | AndroidMediaPlayer::Started
+ | AndroidMediaPlayer::Paused
+ | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
+ mPendingPosition = seekPosition;
+ } else {
+ mMediaPlayer->seekTo(seekPosition);
- if (mPendingPosition != -1) {
- mPendingPosition = -1;
+ if (mPendingPosition != -1) {
+ mPendingPosition = -1;
+ }
}
Q_EMIT positionChanged(seekPosition);
@@ -275,9 +305,11 @@ const QIODevice *QAndroidMediaPlayerControl::mediaStream() const
void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
QIODevice *stream)
{
- const bool reloading = (mMediaContent == mediaContent);
+ StateChangeNotifier notifier(this);
+
+ mReloadingMedia = (mMediaContent == mediaContent);
- if (!reloading) {
+ if (!mReloadingMedia) {
mMediaContent = mediaContent;
mMediaStream = stream;
}
@@ -286,41 +318,45 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized)) == 0)
mMediaPlayer->release();
+ QString mediaPath;
+
if (mediaContent.isNull()) {
setMediaStatus(QMediaPlayer::NoMedia);
- return;
- }
-
- if (mVideoOutput && !mVideoOutput->isReady()) {
- // if a video output is set but the video texture is not ready, delay loading the media
- // since it can cause problems on some hardware
- mPendingSetMedia = true;
- return;
- }
-
- const QUrl url = mediaContent.canonicalUrl();
- QString mediaPath;
- if (url.scheme() == QLatin1String("qrc")) {
- const QString path = url.toString().mid(3);
- mTempFile.reset(QTemporaryFile::createNativeFile(path));
- if (!mTempFile.isNull())
- mediaPath = QStringLiteral("file://") + mTempFile->fileName();
} else {
- mediaPath = url.toString();
- }
+ if (mVideoOutput && !mVideoOutput->isReady()) {
+ // if a video output is set but the video texture is not ready, delay loading the media
+ // since it can cause problems on some hardware
+ mPendingSetMedia = true;
+ return;
+ }
- if (mVideoSize.isValid() && mVideoOutput)
- mVideoOutput->setVideoSize(mVideoSize);
+ const QUrl url = mediaContent.canonicalUrl();
+ if (url.scheme() == QLatin1String("qrc")) {
+ const QString path = url.toString().mid(3);
+ mTempFile.reset(QTemporaryFile::createNativeFile(path));
+ if (!mTempFile.isNull())
+ mediaPath = QStringLiteral("file://") + mTempFile->fileName();
+ } else {
+ mediaPath = url.toString();
+ }
- if ((mMediaPlayer->display() == 0) && mVideoOutput)
- mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
- mMediaPlayer->setDataSource(mediaPath);
- mMediaPlayer->prepareAsync();
+ if (mVideoSize.isValid() && mVideoOutput)
+ mVideoOutput->setVideoSize(mVideoSize);
- if (!reloading)
+ if ((mMediaPlayer->display() == 0) && mVideoOutput)
+ mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
+ mMediaPlayer->setDataSource(mediaPath);
+ mMediaPlayer->prepareAsync();
+ }
+
+ if (!mReloadingMedia) {
Q_EMIT mediaChanged(mMediaContent);
+ Q_EMIT actualMediaLocationChanged(mediaPath);
+ }
resetBufferingProgress();
+
+ mReloadingMedia = false;
}
void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput)
@@ -344,6 +380,8 @@ void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput)
void QAndroidMediaPlayerControl::play()
{
+ StateChangeNotifier notifier(this);
+
// We need to prepare the mediaplayer again.
if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isNull()) {
setMedia(mMediaContent, mMediaStream);
@@ -364,6 +402,8 @@ void QAndroidMediaPlayerControl::play()
void QAndroidMediaPlayerControl::pause()
{
+ StateChangeNotifier notifier(this);
+
setState(QMediaPlayer::PausedState);
if ((mState & (AndroidMediaPlayer::Started
@@ -378,6 +418,8 @@ void QAndroidMediaPlayerControl::pause()
void QAndroidMediaPlayerControl::stop()
{
+ StateChangeNotifier notifier(this);
+
setState(QMediaPlayer::StoppedState);
if ((mState & (AndroidMediaPlayer::Prepared
@@ -395,6 +437,8 @@ void QAndroidMediaPlayerControl::stop()
void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
{
+ StateChangeNotifier notifier(this);
+
Q_UNUSED(extra);
switch (what) {
case AndroidMediaPlayer::MEDIA_INFO_UNKNOWN:
@@ -426,6 +470,8 @@ void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
{
+ StateChangeNotifier notifier(this);
+
QString errorString;
QMediaPlayer::Error error = QMediaPlayer::ResourceError;
@@ -478,6 +524,8 @@ void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onBufferingChanged(qint32 percent)
{
+ StateChangeNotifier notifier(this);
+
mBuffering = percent != 100;
mBufferPercent = percent;
@@ -509,6 +557,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
return;
}
+ StateChangeNotifier notifier(this);
+
mState = state;
switch (mState) {
case AndroidMediaPlayer::Idle:
@@ -516,7 +566,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
case AndroidMediaPlayer::Initialized:
break;
case AndroidMediaPlayer::Preparing:
- setMediaStatus(QMediaPlayer::LoadingMedia);
+ if (!mReloadingMedia)
+ setMediaStatus(QMediaPlayer::LoadingMedia);
break;
case AndroidMediaPlayer::Prepared:
setMediaStatus(QMediaPlayer::LoadedMedia);
@@ -537,6 +588,7 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
} else {
setMediaStatus(QMediaPlayer::BufferedMedia);
}
+ Q_EMIT positionChanged(position());
break;
case AndroidMediaPlayer::Paused:
setState(QMediaPlayer::PausedState);
@@ -545,27 +597,32 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
setState(QMediaPlayer::StoppedState);
setMediaStatus(QMediaPlayer::UnknownMediaStatus);
mMediaPlayer->release();
+ Q_EMIT positionChanged(0);
break;
case AndroidMediaPlayer::Stopped:
setState(QMediaPlayer::StoppedState);
setMediaStatus(QMediaPlayer::LoadedMedia);
- setPosition(0);
+ Q_EMIT positionChanged(0);
break;
case AndroidMediaPlayer::PlaybackCompleted:
setState(QMediaPlayer::StoppedState);
- setPosition(0);
setMediaStatus(QMediaPlayer::EndOfMedia);
break;
case AndroidMediaPlayer::Uninitialized:
- // reset some properties
- resetBufferingProgress();
- mPendingPosition = -1;
- mPendingSetMedia = false;
- mPendingState = -1;
-
- setAudioAvailable(false);
- setVideoAvailable(false);
- setSeekable(true);
+ // reset some properties (unless we reload the same media)
+ if (!mReloadingMedia) {
+ resetBufferingProgress();
+ mPendingPosition = -1;
+ mPendingSetMedia = false;
+ mPendingState = -1;
+
+ Q_EMIT durationChanged(0);
+ Q_EMIT positionChanged(0);
+
+ setAudioAvailable(false);
+ setVideoAvailable(false);
+ setSeekable(true);
+ }
break;
default:
break;
@@ -597,7 +654,6 @@ void QAndroidMediaPlayerControl::setState(QMediaPlayer::State state)
return;
mCurrentState = state;
- Q_EMIT stateChanged(mCurrentState);
}
void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status)
@@ -605,14 +661,13 @@ void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status
if (mCurrentMediaStatus == status)
return;
+ mCurrentMediaStatus = status;
+
if (status == QMediaPlayer::NoMedia || status == QMediaPlayer::InvalidMedia)
Q_EMIT durationChanged(0);
if (status == QMediaPlayer::EndOfMedia)
- Q_EMIT durationChanged(duration());
-
- mCurrentMediaStatus = status;
- Q_EMIT mediaStatusChanged(mCurrentMediaStatus);
+ Q_EMIT positionChanged(position());
updateBufferStatus();
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
index 86d99e822..64b88f49e 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h
@@ -72,6 +72,7 @@ public:
Q_SIGNALS:
void metaDataUpdated();
+ void actualMediaLocationChanged(const QString &url);
public Q_SLOTS:
void setPosition(qint64 position) Q_DECL_OVERRIDE;
@@ -110,7 +111,9 @@ private:
bool mPendingSetMedia;
int mPendingVolume;
int mPendingMute;
+ bool mReloadingMedia;
QScopedPointer<QTemporaryFile> mTempFile;
+ int mActiveStateChangeNotifiers;
void setState(QMediaPlayer::State state);
void setMediaStatus(QMediaPlayer::MediaStatus status);
@@ -121,6 +124,8 @@ private:
void resetBufferingProgress();
void flushPendingStates();
void updateBufferStatus();
+
+ friend class StateChangeNotifier;
};
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp
index 00e8b6184..05cee3b9d 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp
@@ -45,8 +45,8 @@ QAndroidMediaService::QAndroidMediaService(QObject *parent)
{
mMediaControl = new QAndroidMediaPlayerControl;
mMetadataControl = new QAndroidMetaDataReaderControl;
- connect(mMediaControl, SIGNAL(mediaChanged(QMediaContent)),
- mMetadataControl, SLOT(onMediaChanged(QMediaContent)));
+ connect(mMediaControl, SIGNAL(actualMediaLocationChanged(QString)),
+ mMetadataControl, SLOT(onMediaChanged(QString)));
connect(mMediaControl, SIGNAL(metaDataUpdated()),
mMetadataControl, SLOT(onUpdateMetaData()));
}
diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
index a3598228c..a9c87488a 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
+++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp
@@ -93,18 +93,18 @@ QStringList QAndroidMetaDataReaderControl::availableMetaData() const
return m_metadata.keys();
}
-void QAndroidMetaDataReaderControl::onMediaChanged(const QMediaContent &media)
+void QAndroidMetaDataReaderControl::onMediaChanged(const QString &url)
{
if (!m_retriever)
return;
- m_mediaContent = media;
+ m_mediaLocation = url;
updateData();
}
void QAndroidMetaDataReaderControl::onUpdateMetaData()
{
- if (!m_retriever || m_mediaContent.isNull())
+ if (!m_retriever || m_mediaLocation.isEmpty())
return;
updateData();
@@ -114,8 +114,8 @@ void QAndroidMetaDataReaderControl::updateData()
{
m_metadata.clear();
- if (!m_mediaContent.isNull()) {
- if (m_retriever->setDataSource(m_mediaContent.canonicalUrl())) {
+ if (!m_mediaLocation.isEmpty()) {
+ if (m_retriever->setDataSource(m_mediaLocation)) {
QString mimeType = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::MimeType);
if (!mimeType.isNull())
m_metadata.insert(QMediaMetaData::MediaType, mimeType);
diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h
index 72df6eecc..f8720b77a 100644
--- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h
+++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h
@@ -54,13 +54,13 @@ public:
QStringList availableMetaData() const Q_DECL_OVERRIDE;
public Q_SLOTS:
- void onMediaChanged(const QMediaContent &media);
+ void onMediaChanged(const QString &url);
void onUpdateMetaData();
private:
void updateData();
- QMediaContent m_mediaContent;
+ QString m_mediaLocation;
bool m_available;
QVariantMap m_metadata;
diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp
index a01aacf5e..df5345053 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp
@@ -35,9 +35,24 @@
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
+#include <QtCore/QUrl>
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
+static bool exceptionCheckAndClear(JNIEnv *env)
+{
+ if (Q_UNLIKELY(env->ExceptionCheck())) {
+#ifdef QT_DEBUG
+ env->ExceptionDescribe();
+#endif // QT_DEBUG
+ env->ExceptionClear();
+ return true;
+ }
+
+ return false;
+}
+
AndroidMediaMetadataRetriever::AndroidMediaMetadataRetriever()
{
m_metadataRetriever = QJNIObjectPrivate("android/media/MediaMetadataRetriever");
@@ -68,55 +83,105 @@ void AndroidMediaMetadataRetriever::release()
m_metadataRetriever.callMethod<void>("release");
}
-bool AndroidMediaMetadataRetriever::setDataSource(const QUrl &url)
+bool AndroidMediaMetadataRetriever::setDataSource(const QString &urlString)
{
if (!m_metadataRetriever.isValid())
return false;
QJNIEnvironmentPrivate env;
+ QUrl url(urlString);
- bool loaded = false;
+ if (url.isLocalFile()) { // also includes qrc files (copied to a temp file)
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path());
+ QJNIObjectPrivate fileInputStream("java/io/FileInputStream",
+ "(Ljava/lang/String;)V",
+ string.object());
- QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString());
+ if (exceptionCheckAndClear(env))
+ return false;
+
+ QJNIObjectPrivate fd = fileInputStream.callObjectMethod("getFD",
+ "()Ljava/io/FileDescriptor;");
+ if (exceptionCheckAndClear(env)) {
+ fileInputStream.callMethod<void>("close");
+ exceptionCheckAndClear(env);
+ return false;
+ }
- QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri",
- "parse",
- "(Ljava/lang/String;)Landroid/net/Uri;",
- string.object());
- if (env->ExceptionCheck()) {
- env->ExceptionClear();
- } else {
m_metadataRetriever.callMethod<void>("setDataSource",
- "(Landroid/content/Context;Landroid/net/Uri;)V",
- QtAndroidPrivate::activity(),
- uri.object());
- if (env->ExceptionCheck())
- env->ExceptionClear();
- else
- loaded = true;
- }
+ "(Ljava/io/FileDescriptor;)V",
+ fd.object());
+
+ bool ok = !exceptionCheckAndClear(env);
+
+ fileInputStream.callMethod<void>("close");
+ exceptionCheckAndClear(env);
+
+ if (!ok)
+ return false;
+ } else if (url.scheme() == QLatin1String("assets")) {
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.path().mid(1)); // remove first '/'
+ QJNIObjectPrivate activity(QtAndroidPrivate::activity());
+ QJNIObjectPrivate assetManager = activity.callObjectMethod("getAssets",
+ "()Landroid/content/res/AssetManager;");
+ QJNIObjectPrivate assetFd = assetManager.callObjectMethod("openFd",
+ "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;",
+ string.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+
+ QJNIObjectPrivate fd = assetFd.callObjectMethod("getFileDescriptor",
+ "()Ljava/io/FileDescriptor;");
+ if (exceptionCheckAndClear(env)) {
+ assetFd.callMethod<void>("close");
+ exceptionCheckAndClear(env);
+ return false;
+ }
- return loaded;
-}
+ m_metadataRetriever.callMethod<void>("setDataSource",
+ "(Ljava/io/FileDescriptor;JJ)V",
+ fd.object(),
+ assetFd.callMethod<jlong>("getStartOffset"),
+ assetFd.callMethod<jlong>("getLength"));
-bool AndroidMediaMetadataRetriever::setDataSource(const QString &path)
-{
- if (!m_metadataRetriever.isValid())
- return false;
+ bool ok = !exceptionCheckAndClear(env);
- QJNIEnvironmentPrivate env;
+ assetFd.callMethod<void>("close");
+ exceptionCheckAndClear(env);
- bool loaded = false;
+ if (!ok)
+ return false;
+ } else if (QtAndroidPrivate::androidSdkVersion() >= 14) {
+ // On API levels >= 14, only setDataSource(String, Map<String, String>) accepts remote media
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(urlString);
+ QJNIObjectPrivate hash("java/util/HashMap");
- m_metadataRetriever.callMethod<void>("setDataSource",
- "(Ljava/lang/String;)V",
- QJNIObjectPrivate::fromString(path).object());
- if (env->ExceptionCheck())
- env->ExceptionClear();
- else
- loaded = true;
+ m_metadataRetriever.callMethod<void>("setDataSource",
+ "(Ljava/lang/String;Ljava/util/Map;)V",
+ string.object(),
+ hash.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+ } else {
+ // While on API levels < 14, only setDataSource(Context, Uri) is available and works for
+ // remote media...
+ QJNIObjectPrivate string = QJNIObjectPrivate::fromString(urlString);
+ QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri",
+ "parse",
+ "(Ljava/lang/String;)Landroid/net/Uri;",
+ string.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+
+ m_metadataRetriever.callMethod<void>("setDataSource",
+ "(Landroid/content/Context;Landroid/net/Uri;)V",
+ QtAndroidPrivate::activity(),
+ uri.object());
+ if (exceptionCheckAndClear(env))
+ return false;
+ }
- return loaded;
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h
index 1cf0bcc91..c1633580f 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h
+++ b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h
@@ -35,7 +35,6 @@
#define ANDROIDMEDIAMETADATARETRIEVER_H
#include <QtCore/private/qjni_p.h>
-#include <qurl.h>
QT_BEGIN_NAMESPACE
@@ -73,8 +72,7 @@ public:
QString extractMetadata(MetadataKey key);
void release();
- bool setDataSource(const QUrl &url);
- bool setDataSource(const QString &path);
+ bool setDataSource(const QString &url);
private:
QJNIObjectPrivate m_metadataRetriever;
diff --git a/src/plugins/avfoundation/camera/avfcameraservice.mm b/src/plugins/avfoundation/camera/avfcameraservice.mm
index 20792000a..77a145ba3 100644
--- a/src/plugins/avfoundation/camera/avfcameraservice.mm
+++ b/src/plugins/avfoundation/camera/avfcameraservice.mm
@@ -142,9 +142,9 @@ QMediaControl *AVFCameraService::requestControl(const char *name)
void AVFCameraService::releaseControl(QMediaControl *control)
{
if (m_videoOutput == control) {
- m_videoOutput = 0;
m_session->setVideoOutput(0);
- delete control;
+ delete m_videoOutput;
+ m_videoOutput = 0;
}
AVFMediaVideoProbeControl *videoProbe = qobject_cast<AVFMediaVideoProbeControl *>(control);
if (videoProbe) {
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
index e5549803f..bb75adb8b 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm
@@ -118,14 +118,15 @@ void AVFMediaPlayerService::releaseControl(QMediaControl *control)
#ifdef QT_DEBUG_AVF
qDebug() << Q_FUNC_INFO << control;
#endif
-#if defined(Q_OS_OSX)
if (m_videoOutput == control) {
+#if defined(Q_OS_OSX)
AVFVideoRendererControl *renderControl = qobject_cast<AVFVideoRendererControl*>(m_videoOutput);
if (renderControl)
renderControl->setSurface(0);
+#endif
m_videoOutput = 0;
m_session->setVideoOutput(0);
+
delete control;
}
-#endif
}
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
index 09ac4b5b3..5157a8571 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h
@@ -97,8 +97,6 @@ public Q_SLOTS:
void processPositionChange();
void processMediaLoadError();
- void processCurrentItemChanged();
-
Q_SIGNALS:
void positionChanged(qint64 position);
void durationChanged(qint64 duration);
@@ -148,6 +146,9 @@ private:
QByteArray rawData;
};
+ void setAudioAvailable(bool available);
+ void setVideoAvailable(bool available);
+
AVFMediaPlayerService *m_service;
AVFVideoOutput *m_videoOutput;
diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
index a73974ccd..73e9d764e 100644
--- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm
@@ -70,15 +70,11 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
AVPlayerItem *m_playerItem;
AVPlayerLayer *m_playerLayer;
NSURL *m_URL;
- bool m_audioAvailable;
- bool m_videoAvailable;
}
@property (readonly, getter=player) AVPlayer* m_player;
@property (readonly, getter=playerItem) AVPlayerItem* m_playerItem;
@property (readonly, getter=playerLayer) AVPlayerLayer* m_playerLayer;
-@property (readonly, getter=audioAvailable) bool m_audioAvailable;
-@property (readonly, getter=videoAvailable) bool m_videoAvailable;
@property (readonly, getter=session) AVFMediaPlayerSession* m_session;
- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session;
@@ -96,7 +92,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
@implementation AVFMediaPlayerSessionObserver
-@synthesize m_player, m_playerItem, m_playerLayer, m_audioAvailable, m_videoAvailable, m_session;
+@synthesize m_player, m_playerItem, m_playerLayer, m_session;
- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session
{
@@ -186,18 +182,6 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
return;
}
- m_audioAvailable = false;
- m_videoAvailable = false;
-
- //Check each track of asset for audio and video content
- NSArray *tracks = [asset tracks];
- for (AVAssetTrack *track in tracks) {
- if ([track hasMediaCharacteristic:AVMediaCharacteristicAudible])
- m_audioAvailable = true;
- if ([track hasMediaCharacteristic:AVMediaCharacteristicVisual])
- m_videoAvailable = true;
- }
-
//At this point we're ready to set up for playback of the asset.
//Stop observing our prior AVPlayerItem, if we have one.
if (m_playerItem)
@@ -258,18 +242,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:m_player];
[m_playerLayer retain];
m_playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
-
- //Get the native size of the new item, and reset the bounds of the player layer
- AVAsset *asset = m_playerItem.asset;
- if (asset) {
- NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
- if ([tracks count]) {
- AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
- m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f);
- m_playerLayer.bounds = CGRectMake(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height);
- }
- }
-
+ m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f);
}
//Observe the AVPlayer "currentItem" property to find out when any
@@ -322,7 +295,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
//AVPlayerItem "status" property value observer.
if (context == AVFMediaPlayerSessionObserverStatusObservationContext)
{
- AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
+ AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status)
{
//Indicates that the status of the player is not yet known because
@@ -366,24 +339,7 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe
{
AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey];
if (m_playerItem != newPlayerItem)
- {
m_playerItem = newPlayerItem;
-
- //Get the native size of the new item, and reset the bounds of the player layer
- //AVAsset *asset = m_playerItem.asset;
- AVAsset *asset = [m_playerItem asset];
- if (asset) {
- NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
- if ([tracks count]) {
- AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
- m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f);
- m_playerLayer.bounds = CGRectMake(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height);
- }
- }
-
- }
- if (self.session)
- QMetaObject::invokeMethod(m_session, "processCurrentItemChanged", Qt::AutoConnection);
}
else
{
@@ -513,6 +469,9 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
m_resources = content;
m_mediaStream = stream;
+ setAudioAvailable(false);
+ setVideoAvailable(false);
+
QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
if (content.isNull() || content.canonicalUrl().isEmpty()) {
@@ -582,14 +541,32 @@ bool AVFMediaPlayerSession::isMuted() const
return m_muted;
}
+void AVFMediaPlayerSession::setAudioAvailable(bool available)
+{
+ if (m_audioAvailable == available)
+ return;
+
+ m_audioAvailable = available;
+ Q_EMIT audioAvailableChanged(available);
+}
+
bool AVFMediaPlayerSession::isAudioAvailable() const
{
- return [(AVFMediaPlayerSessionObserver*)m_observer audioAvailable];
+ return m_audioAvailable;
+}
+
+void AVFMediaPlayerSession::setVideoAvailable(bool available)
+{
+ if (m_videoAvailable == available)
+ return;
+
+ m_videoAvailable = available;
+ Q_EMIT videoAvailableChanged(available);
}
bool AVFMediaPlayerSession::isVideoAvailable() const
{
- return [(AVFMediaPlayerSessionObserver*)m_observer videoAvailable];
+ return m_videoAvailable;
}
bool AVFMediaPlayerSession::isSeekable() const
@@ -802,16 +779,41 @@ void AVFMediaPlayerSession::processLoadStateChange()
bool isPlaying = (m_state != QMediaPlayer::StoppedState);
if (currentStatus == AVPlayerStatusReadyToPlay) {
+ AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
+ if (playerItem) {
+ // Check each track for audio and video content
+ AVAssetTrack *videoTrack = nil;
+ NSArray *tracks = playerItem.tracks;
+ for (AVPlayerItemTrack *track in tracks) {
+ AVAssetTrack *assetTrack = track.assetTrack;
+ if (assetTrack) {
+ if ([assetTrack.mediaType isEqualToString:AVMediaTypeAudio])
+ setAudioAvailable(true);
+ if ([assetTrack.mediaType isEqualToString:AVMediaTypeVideo]) {
+ setVideoAvailable(true);
+ if (!videoTrack)
+ videoTrack = assetTrack;
+ }
+ }
+ }
+
+ // Get the native size of the video, and reset the bounds of the player layer
+ AVPlayerLayer *playerLayer = [(AVFMediaPlayerSessionObserver*)m_observer playerLayer];
+ if (videoTrack && playerLayer) {
+ playerLayer.bounds = CGRectMake(0.0f, 0.0f,
+ videoTrack.naturalSize.width,
+ videoTrack.naturalSize.height);
+
+ if (m_videoOutput && m_state != QMediaPlayer::StoppedState) {
+ m_videoOutput->setLayer(playerLayer);
+ }
+ }
+ }
+
qint64 currentDuration = duration();
if (m_duration != currentDuration)
Q_EMIT durationChanged(m_duration = currentDuration);
- if (m_audioAvailable != isAudioAvailable())
- Q_EMIT audioAvailableChanged(m_audioAvailable = !m_audioAvailable);
-
- if (m_videoAvailable != isVideoAvailable())
- Q_EMIT videoAvailableChanged(m_videoAvailable = !m_videoAvailable);
-
newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
if (m_state == QMediaPlayer::PlayingState && [(AVFMediaPlayerSessionObserver*)m_observer player]) {
@@ -835,17 +837,3 @@ void AVFMediaPlayerSession::processMediaLoadError()
Q_EMIT mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia);
Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
}
-
-void AVFMediaPlayerSession::processCurrentItemChanged()
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO;
-#endif
-
- AVPlayerLayer *playerLayer = [(AVFMediaPlayerSessionObserver*)m_observer playerLayer];
-
- if (m_videoOutput && m_state != QMediaPlayer::StoppedState) {
- m_videoOutput->setLayer(playerLayer);
- }
-
-}
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
index d4fa7c4c6..2893921f3 100644
--- a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm
@@ -64,8 +64,10 @@ AVFVideoWidget::~AVFVideoWidget()
qDebug() << Q_FUNC_INFO;
#endif
- if (m_playerLayer)
+ if (m_playerLayer) {
+ [m_playerLayer removeFromSuperlayer];
[m_playerLayer release];
+ }
}
QSize AVFVideoWidget::sizeHint() const
diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm
index 17fc94de7..8e96d732f 100644
--- a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm
+++ b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm
@@ -61,8 +61,10 @@ AVFVideoWindowControl::AVFVideoWindowControl(QObject *parent)
AVFVideoWindowControl::~AVFVideoWindowControl()
{
- if (m_playerLayer)
+ if (m_playerLayer) {
+ [m_playerLayer removeFromSuperlayer];
[m_playerLayer release];
+ }
}
WId AVFVideoWindowControl::winId() const
diff --git a/src/plugins/coreaudio/coreaudiodeviceinfo.mm b/src/plugins/coreaudio/coreaudiodeviceinfo.mm
index ac41a310c..2faeac8c9 100644
--- a/src/plugins/coreaudio/coreaudiodeviceinfo.mm
+++ b/src/plugins/coreaudio/coreaudiodeviceinfo.mm
@@ -45,6 +45,7 @@
# include "coreaudiosessionmanager.h"
#endif
+#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QSet>
diff --git a/src/plugins/coreaudio/coreaudioinput.h b/src/plugins/coreaudio/coreaudioinput.h
index 64691eb36..533b7fef4 100644
--- a/src/plugins/coreaudio/coreaudioinput.h
+++ b/src/plugins/coreaudio/coreaudioinput.h
@@ -38,6 +38,7 @@
#include <CoreAudio/CoreAudioTypes.h>
#include <AudioToolbox/AudioToolbox.h>
+#include <QtCore/QIODevice>
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
#include <QtCore/QTimer>
diff --git a/src/plugins/coreaudio/coreaudioinput.mm b/src/plugins/coreaudio/coreaudioinput.mm
index a0b9e9d25..972f959f5 100644
--- a/src/plugins/coreaudio/coreaudioinput.mm
+++ b/src/plugins/coreaudio/coreaudioinput.mm
@@ -52,6 +52,7 @@
#endif
#include <QtMultimedia/private/qaudiohelpers_p.h>
+#include <QtCore/QDataStream>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/coreaudio/coreaudiooutput.h b/src/plugins/coreaudio/coreaudiooutput.h
index 84083acea..23b229379 100644
--- a/src/plugins/coreaudio/coreaudiooutput.h
+++ b/src/plugins/coreaudio/coreaudiooutput.h
@@ -41,6 +41,7 @@
#include <AudioUnit/AudioUnit.h>
#include <CoreAudio/CoreAudioTypes.h>
+#include <QtCore/QIODevice>
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
diff --git a/src/plugins/coreaudio/coreaudiooutput.mm b/src/plugins/coreaudio/coreaudiooutput.mm
index e5e1c65e5..7bb5c0e15 100644
--- a/src/plugins/coreaudio/coreaudiooutput.mm
+++ b/src/plugins/coreaudio/coreaudiooutput.mm
@@ -43,6 +43,7 @@
#include "coreaudiodeviceinfo.h"
#include "coreaudioutils.h"
+#include <QtCore/QDataStream>
#include <QtCore/QTimer>
#include <QtCore/QDebug>
@@ -698,14 +699,14 @@ void CoreAudioOutput::audioThreadStop()
{
stopTimers();
if (m_audioThreadState.testAndSetAcquire(Running, Stopped))
- m_threadFinished.wait(&m_mutex);
+ m_threadFinished.wait(&m_mutex, 500);
}
void CoreAudioOutput::audioThreadDrain()
{
stopTimers();
if (m_audioThreadState.testAndSetAcquire(Running, Draining))
- m_threadFinished.wait(&m_mutex);
+ m_threadFinished.wait(&m_mutex, 500);
}
void CoreAudioOutput::audioDeviceStop()
diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
index fe8098a02..865a764a8 100644
--- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
@@ -117,4 +117,28 @@ GstEncodingProfile *CameraBinAudioEncoder::createProfile()
return profile;
}
+void CameraBinAudioEncoder::applySettings(GstElement *encoder)
+{
+ GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder);
+ const char * const name = gst_plugin_feature_get_name(
+ GST_PLUGIN_FEATURE(gst_element_get_factory(encoder)));
+
+ const bool isVorbis = qstrcmp(name, "vorbisenc") == 0;
+
+ const int bitRate = m_actualAudioSettings.bitRate();
+ if (!isVorbis && bitRate == -1) {
+ // Bit rate is invalid, don't evaluate the remaining conditions unless the encoder is
+ // vorbisenc which is known to accept -1 as an unspecified bitrate.
+ } else if (g_object_class_find_property(objectClass, "bitrate")) {
+ g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL);
+ } else if (g_object_class_find_property(objectClass, "target-bitrate")) {
+ g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL);
+ }
+
+ if (isVorbis) {
+ static const double qualities[] = { 0.1, 0.3, 0.5, 0.7, 1.0 };
+ g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualAudioSettings.quality()], NULL);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
index 46f812a67..f71436552 100644
--- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
+++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
@@ -78,6 +78,8 @@ public:
GstEncodingProfile *createProfile();
+ void applySettings(GstElement *element);
+
Q_SIGNALS:
void settingsChanged();
diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
index 4e7630b72..51024b7d9 100644
--- a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
@@ -38,13 +38,9 @@
#include "camerabinserviceplugin.h"
-
#include "camerabinservice.h"
#include <private/qgstutils_p.h>
-#include <private/qcore_unix_p.h>
-#include <linux/videodev2.h>
-
QT_BEGIN_NAMESPACE
template <typename T, int N> static int lengthOf(const T(&)[N]) { return N; }
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
index 420ce5853..019783971 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
@@ -98,6 +98,8 @@
#define CAPTURE_START "start-capture"
#define CAPTURE_STOP "stop-capture"
+#define FILESINK_BIN_NAME "videobin-filesink"
+
#define CAMERABIN_IMAGE_MODE 1
#define CAMERABIN_VIDEO_MODE 2
@@ -133,6 +135,7 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
m_capsFilter(0),
m_fileSink(0),
m_audioEncoder(0),
+ m_videoEncoder(0),
m_muxer(0)
{
if (m_sourceFactory)
@@ -140,6 +143,8 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
m_camerabin = gst_element_factory_make("camerabin2", "camerabin2");
g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this);
+ g_signal_connect(G_OBJECT(m_camerabin), "element-added", G_CALLBACK(elementAdded), this);
+ g_signal_connect(G_OBJECT(m_camerabin), "element-removed", G_CALLBACK(elementRemoved), this);
qt_gst_object_ref_sink(m_camerabin);
m_bus = gst_element_get_bus(m_camerabin);
@@ -344,6 +349,9 @@ void CameraBinSession::setupCaptureResolution()
} else {
g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, NULL, NULL);
}
+
+ if (m_videoEncoder)
+ m_videoEncodeControl->applySettings(m_videoEncoder);
}
void CameraBinSession::setAudioCaptureCaps()
@@ -370,6 +378,9 @@ void CameraBinSession::setAudioCaptureCaps()
GstCaps *caps = gst_caps_new_full(structure, NULL);
g_object_set(G_OBJECT(m_camerabin), AUDIO_CAPTURE_CAPS_PROPERTY, caps, NULL);
gst_caps_unref(caps);
+
+ if (m_audioEncoder)
+ m_audioEncodeControl->applySettings(m_audioEncoder);
}
GstElement *CameraBinSession::buildCameraSource()
@@ -712,13 +723,19 @@ void CameraBinSession::updateBusyStatus(GObject *o, GParamSpec *p, gpointer d)
qint64 CameraBinSession::duration() const
{
- GstFormat format = GST_FORMAT_TIME;
- gint64 duration = 0;
+ if (m_camerabin) {
+ GstElement *fileSink = gst_bin_get_by_name(GST_BIN(m_camerabin), FILESINK_BIN_NAME);
+ if (fileSink) {
+ GstFormat format = GST_FORMAT_TIME;
+ gint64 duration = 0;
+ bool ret = gst_element_query_position(fileSink, &format, &duration);
+ gst_object_unref(GST_OBJECT(fileSink));
+ if (ret)
+ return duration / 1000000;
+ }
+ }
- if ( m_camerabin && gst_element_query_position(m_camerabin, &format, &duration))
- return duration / 1000000;
- else
- return 0;
+ return 0;
}
bool CameraBinSession::isMuted() const
@@ -1293,4 +1310,32 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
return res;
}
+void CameraBinSession::elementAdded(GstBin *, GstElement *element, CameraBinSession *session)
+{
+ GstElementFactory *factory = gst_element_get_factory(element);
+
+ if (GST_IS_BIN(element)) {
+ g_signal_connect(G_OBJECT(element), "element-added", G_CALLBACK(elementAdded), session);
+ g_signal_connect(G_OBJECT(element), "element-removed", G_CALLBACK(elementRemoved), session);
+ } else if (!factory) {
+ // no-op
+ } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER)) {
+ session->m_audioEncoder = element;
+
+ session->m_audioEncodeControl->applySettings(element);
+ } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER)) {
+ session->m_videoEncoder = element;
+
+ session->m_videoEncodeControl->applySettings(element);
+ }
+}
+
+void CameraBinSession::elementRemoved(GstBin *, GstElement *element, CameraBinSession *session)
+{
+ if (element == session->m_audioEncoder)
+ session->m_audioEncoder = 0;
+ else if (element == session->m_videoEncoder)
+ session->m_videoEncoder = 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h
index 42ed0e988..7e8a46dee 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.h
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.h
@@ -190,6 +190,9 @@ private:
void setAudioCaptureCaps();
static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d);
+ static void elementAdded(GstBin *bin, GstElement *element, CameraBinSession *session);
+ static void elementRemoved(GstBin *bin, GstElement *element, CameraBinSession *session);
+
QUrl m_sink;
QUrl m_actualSink;
bool m_recordingActive;
@@ -241,6 +244,7 @@ private:
GstElement *m_capsFilter;
GstElement *m_fileSink;
GstElement *m_audioEncoder;
+ GstElement *m_videoEncoder;
GstElement *m_muxer;
public:
diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
index 228054318..554437047 100644
--- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
@@ -175,4 +175,46 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile()
return (GstEncodingProfile *)profile;
}
+void CameraBinVideoEncoder::applySettings(GstElement *encoder)
+{
+ GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder);
+ const char * const name = gst_plugin_feature_get_name(
+ GST_PLUGIN_FEATURE(gst_element_get_factory(encoder)));
+
+ const int bitRate = m_actualVideoSettings.bitRate();
+ if (bitRate == -1) {
+ // Bit rate is invalid, don't evaluate the remaining conditions.
+ } else if (g_object_class_find_property(objectClass, "bitrate")) {
+ g_object_set(G_OBJECT(encoder), "bitrate", bitRate, NULL);
+ } else if (g_object_class_find_property(objectClass, "target-bitrate")) {
+ g_object_set(G_OBJECT(encoder), "target-bitrate", bitRate, NULL);
+ }
+
+ if (qstrcmp(name, "theoraenc") == 0) {
+ static const int qualities[] = { 8, 16, 32, 45, 60 };
+ g_object_set(G_OBJECT(encoder), "quality", qualities[m_actualVideoSettings.quality()], NULL);
+ } else if (qstrncmp(name, "avenc_", 6) == 0) {
+ if (g_object_class_find_property(objectClass, "pass")) {
+ static const int modes[] = { 0, 2, 512, 1024 };
+ g_object_set(G_OBJECT(encoder), "pass", modes[m_actualVideoSettings.encodingMode()], NULL);
+ }
+ if (g_object_class_find_property(objectClass, "quantizer")) {
+ static const double qualities[] = { 20, 8.0, 3.0, 2.5, 2.0 };
+ g_object_set(G_OBJECT(encoder), "quantizer", qualities[m_actualVideoSettings.quality()], NULL);
+ }
+ } else if (qstrncmp(name, "omx", 3) == 0) {
+ if (!g_object_class_find_property(objectClass, "control-rate")) {
+ } else switch (m_actualVideoSettings.encodingMode()) {
+ case QMultimedia::ConstantBitRateEncoding:
+ g_object_set(G_OBJECT(encoder), "control-rate", 2, NULL);
+ break;
+ case QMultimedia::AverageBitRateEncoding:
+ g_object_set(G_OBJECT(encoder), "control-rate", 1, NULL);
+ break;
+ default:
+ g_object_set(G_OBJECT(encoder), "control-rate", 0, NULL);
+ }
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
index 0838ba651..dabe098ab 100644
--- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
+++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
@@ -76,6 +76,8 @@ public:
GstEncodingProfile *createProfile();
+ void applySettings(GstElement *encoder);
+
Q_SIGNALS:
void settingsChanged();
diff --git a/src/plugins/gstreamer/mediacapture/mediacapture.pro b/src/plugins/gstreamer/mediacapture/mediacapture.pro
index e8d039f8d..5baa0fd8f 100644
--- a/src/plugins/gstreamer/mediacapture/mediacapture.pro
+++ b/src/plugins/gstreamer/mediacapture/mediacapture.pro
@@ -15,7 +15,6 @@ HEADERS += $$PWD/qgstreamercaptureservice.h \
$$PWD/qgstreamerrecordercontrol.h \
$$PWD/qgstreamermediacontainercontrol.h \
$$PWD/qgstreamercameracontrol.h \
- $$PWD/qgstreamerv4l2input.h \
$$PWD/qgstreamercapturemetadatacontrol.h \
$$PWD/qgstreamerimagecapturecontrol.h \
$$PWD/qgstreamerimageencode.h \
@@ -28,7 +27,6 @@ SOURCES += $$PWD/qgstreamercaptureservice.cpp \
$$PWD/qgstreamerrecordercontrol.cpp \
$$PWD/qgstreamermediacontainercontrol.cpp \
$$PWD/qgstreamercameracontrol.cpp \
- $$PWD/qgstreamerv4l2input.cpp \
$$PWD/qgstreamercapturemetadatacontrol.cpp \
$$PWD/qgstreamerimagecapturecontrol.cpp \
$$PWD/qgstreamerimageencode.cpp \
@@ -37,13 +35,18 @@ SOURCES += $$PWD/qgstreamercaptureservice.cpp \
# Camera usage with gstreamer needs to have
#CONFIG += use_gstreamer_camera
-use_gstreamer_camera {
-DEFINES += USE_GSTREAMER_CAMERA
+use_gstreamer_camera:config_linux_v4l {
+ DEFINES += USE_GSTREAMER_CAMERA
+
+ OTHER_FILES += \
+ mediacapturecamera.json
+
+ HEADERS += \
+ $$PWD/qgstreamerv4l2input.h
+ SOURCES += \
+ $$PWD/qgstreamerv4l2input.cpp
-OTHER_FILES += \
- mediacapturecamera.json
} else {
-OTHER_FILES += \
- mediacapture.json
+ OTHER_FILES += \
+ mediacapture.json
}
-
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
index 2e73797ee..97a165dca 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
@@ -40,9 +40,12 @@
#include "qgstreamerimageencode.h"
#include "qgstreamercameracontrol.h"
#include <private/qgstreamerbushelper_p.h>
-#include "qgstreamerv4l2input.h"
#include "qgstreamercapturemetadatacontrol.h"
+#if defined(USE_GSTREAMER_CAMERA)
+#include "qgstreamerv4l2input.h"
+#endif
+
#include "qgstreamerimagecapturecontrol.h"
#include <private/qgstreameraudioinputselector_p.h>
#include <private/qgstreamervideoinputdevicecontrol_p.h>
@@ -66,7 +69,9 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
m_cameraControl = 0;
m_metaDataControl = 0;
+#if defined(USE_GSTREAMER_CAMERA)
m_videoInput = 0;
+#endif
m_audioInputSelector = 0;
m_videoInputDevice = 0;
@@ -82,6 +87,7 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::Audio, this);
}
+#if defined(USE_GSTREAMER_CAMERA)
if (service == Q_MEDIASERVICE_CAMERA) {
m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::AudioAndVideo, this);
m_cameraControl = new QGstreamerCameraControl(m_captureSession);
@@ -103,6 +109,7 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
#endif
m_imageCaptureControl = new QGstreamerImageCaptureControl(m_captureSession);
}
+#endif
m_audioInputSelector = new QGstreamerAudioInputSelector(this);
connect(m_audioInputSelector, SIGNAL(activeInputChanged(QString)), m_captureSession, SLOT(setCaptureDevice(QString)));
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
index 2b1a0dcca..7ff8ce253 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
@@ -70,7 +70,9 @@ private:
QGstreamerCaptureSession *m_captureSession;
QGstreamerCameraControl *m_cameraControl;
+#if defined(USE_GSTREAMER_CAMERA)
QGstreamerV4L2Input *m_videoInput;
+#endif
QGstreamerCaptureMetaDataControl *m_metaDataControl;
QAudioInputSelectorControl *m_audioInputSelector;
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
index e9c922e28..8ae3a78de 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp
@@ -76,8 +76,10 @@ static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys()
// Music
metadataKeys->insert(GST_TAG_ALBUM, QMediaMetaData::AlbumTitle);
- metadataKeys->insert(GST_TAG_ARTIST, QMediaMetaData::AlbumArtist);
- metadataKeys->insert(GST_TAG_PERFORMER, QMediaMetaData::ContributingArtist);
+#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 25)
+ metadataKeys->insert(GST_TAG_ALBUM_ARTIST, QMediaMetaData::AlbumArtist);
+#endif
+ metadataKeys->insert(GST_TAG_ARTIST, QMediaMetaData::ContributingArtist);
#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19)
metadataKeys->insert(GST_TAG_COMPOSER, QMediaMetaData::Composer);
#endif
@@ -164,6 +166,11 @@ void QGstreamerMetaDataProvider::updateTags()
}
}
+ if (oldTags.isEmpty() != m_tags.isEmpty()) {
+ emit metaDataAvailableChanged(isMetaDataAvailable());
+ changed = true;
+ }
+
if (changed)
emit metaDataChanged();
}
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
index 2f7047f97..fed756ac9 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
@@ -60,7 +60,6 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
, m_currentState(QMediaPlayer::StoppedState)
, m_mediaStatus(QMediaPlayer::NoMedia)
, m_bufferProgress(-1)
- , m_seekToStartPending(false)
, m_pendingSeekPosition(-1)
, m_setMediaPending(false)
, m_stream(0)
@@ -69,7 +68,7 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
Q_ASSERT(m_resources);
connect(m_session, SIGNAL(positionChanged(qint64)),
- this, SLOT(updatePosition(qint64)));
+ this, SIGNAL(positionChanged(qint64)));
connect(m_session, SIGNAL(durationChanged(qint64)),
this, SIGNAL(durationChanged(qint64)));
connect(m_session, SIGNAL(mutedStateChanged(bool)),
@@ -94,8 +93,6 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
this, SLOT(handleInvalidMedia()));
connect(m_session, SIGNAL(playbackRateChanged(qreal)),
this, SIGNAL(playbackRateChanged(qreal)));
- connect(m_session, SIGNAL(seekableChanged(bool)),
- this, SLOT(applyPendingSeek(bool)));
connect(m_resources, SIGNAL(resourcesGranted()), SLOT(handleResourcesGranted()));
//denied signal should be queued to have correct state update process,
@@ -117,7 +114,7 @@ QMediaPlayerResourceSetInterface* QGstreamerPlayerControl::resources() const
qint64 QGstreamerPlayerControl::position() const
{
- return m_seekToStartPending ? 0 : m_session->position();
+ return m_pendingSeekPosition != -1 ? m_pendingSeekPosition : m_session->position();
}
qint64 QGstreamerPlayerControl::duration() const
@@ -183,15 +180,21 @@ void QGstreamerPlayerControl::setPosition(qint64 pos)
if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
m_mediaStatus = QMediaPlayer::LoadedMedia;
- m_seekToStartPending = true;
}
- if (m_session->isSeekable() && m_session->seek(pos)) {
- m_seekToStartPending = false;
- } else {
+ if (m_currentState == QMediaPlayer::StoppedState) {
m_pendingSeekPosition = pos;
- //don't display the first video frame since it's not what user requested.
- m_session->showPrerollFrames(false);
+ emit positionChanged(m_pendingSeekPosition);
+ } else if (m_session->isSeekable()) {
+ m_session->showPrerollFrames(true);
+ m_session->seek(pos);
+ m_pendingSeekPosition = -1;
+ } else if (m_session->state() == QMediaPlayer::StoppedState) {
+ m_pendingSeekPosition = pos;
+ emit positionChanged(m_pendingSeekPosition);
+ } else if (m_pendingSeekPosition != -1) {
+ m_pendingSeekPosition = -1;
+ emit positionChanged(m_pendingSeekPosition);
}
popAndNotifyState();
@@ -239,26 +242,30 @@ void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
}
#endif
+ if (m_mediaStatus == QMediaPlayer::EndOfMedia && m_pendingSeekPosition == -1) {
+ m_pendingSeekPosition = 0;
+ }
+
if (!m_resources->isGranted())
m_resources->acquire();
if (m_resources->isGranted()) {
- if (m_seekToStartPending) {
+ // show prerolled frame if switching from stopped state
+ if (m_pendingSeekPosition == -1) {
+ m_session->showPrerollFrames(true);
+ } else if (m_session->state() == QMediaPlayer::StoppedState) {
+ // Don't evaluate the next two conditions.
+ } else if (m_session->isSeekable()) {
m_session->pause();
- if (!m_session->seek(0)) {
- m_bufferProgress = -1;
- m_session->stop();
- m_mediaStatus = QMediaPlayer::LoadingMedia;
- }
- m_seekToStartPending = false;
+ m_session->showPrerollFrames(true);
+ m_session->seek(m_pendingSeekPosition);
+ m_pendingSeekPosition = -1;
+ } else {
+ m_pendingSeekPosition = -1;
}
bool ok = false;
- // show prerolled frame if switching from stopped state
- if (newState != QMediaPlayer::StoppedState && m_currentState == QMediaPlayer::StoppedState && m_pendingSeekPosition == -1)
- m_session->showPrerollFrames(true);
-
//To prevent displaying the first video frame when playback is resumed
//the pipeline is paused instead of playing, seeked to requested position,
//and after seeking is finished (position updated) playback is restarted
@@ -305,7 +312,7 @@ void QGstreamerPlayerControl::stop()
m_session->pause();
if (m_mediaStatus != QMediaPlayer::EndOfMedia) {
- m_seekToStartPending = true;
+ m_pendingSeekPosition = 0;
emit positionChanged(position());
}
}
@@ -343,7 +350,7 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
m_currentState = QMediaPlayer::StoppedState;
QMediaContent oldMedia = m_currentResource;
- m_pendingSeekPosition = -1;
+ m_pendingSeekPosition = 0;
m_session->showPrerollFrames(false); // do not show prerolled frames until pause() or play() explicitly called
m_setMediaPending = false;
@@ -390,7 +397,6 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
m_currentResource = content;
m_stream = stream;
- m_seekToStartPending = false;
QNetworkRequest request;
@@ -462,8 +468,21 @@ void QGstreamerPlayerControl::updateSessionState(QMediaPlayer::State state)
{
pushState();
- if (state == QMediaPlayer::StoppedState)
+ if (state == QMediaPlayer::StoppedState) {
+ m_session->showPrerollFrames(false);
m_currentState = QMediaPlayer::StoppedState;
+ }
+
+ if (state == QMediaPlayer::PausedState && m_currentState != QMediaPlayer::StoppedState) {
+ if (m_pendingSeekPosition != -1 && m_session->isSeekable()) {
+ m_session->showPrerollFrames(true);
+ m_session->seek(m_pendingSeekPosition);
+ }
+ m_pendingSeekPosition = -1;
+
+ if (m_currentState == QMediaPlayer::PlayingState)
+ m_session->play();
+ }
updateMediaStatus();
@@ -512,7 +531,6 @@ void QGstreamerPlayerControl::processEOS()
m_mediaStatus = QMediaPlayer::EndOfMedia;
emit positionChanged(position());
m_session->endOfMediaReset();
- m_setMediaPending = true;
if (m_currentState != QMediaPlayer::StoppedState) {
m_currentState = QMediaPlayer::StoppedState;
@@ -549,17 +567,12 @@ void QGstreamerPlayerControl::setBufferProgress(int progress)
emit bufferStatusChanged(m_bufferProgress);
}
-void QGstreamerPlayerControl::applyPendingSeek(bool isSeekable)
-{
- if (isSeekable && m_pendingSeekPosition != -1)
- setPosition(m_pendingSeekPosition);
-}
-
void QGstreamerPlayerControl::handleInvalidMedia()
{
pushState();
m_mediaStatus = QMediaPlayer::InvalidMedia;
m_currentState = QMediaPlayer::StoppedState;
+ m_setMediaPending = true;
popAndNotifyState();
}
@@ -636,24 +649,4 @@ void QGstreamerPlayerControl::popAndNotifyState()
}
}
-void QGstreamerPlayerControl::updatePosition(qint64 pos)
-{
-#ifdef DEBUG_PLAYBIN
- qDebug() << Q_FUNC_INFO << pos/1000.0 << "pending:" << m_pendingSeekPosition/1000.0;
-#endif
-
- if (m_pendingSeekPosition != -1) {
- //seek request is complete, it's safe to resume playback
- //with prerolled frame displayed
- m_pendingSeekPosition = -1;
- if (m_currentState != QMediaPlayer::StoppedState)
- m_session->showPrerollFrames(true);
- if (m_currentState == QMediaPlayer::PlayingState) {
- m_session->play();
- }
- }
-
- emit positionChanged(pos);
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
index 94f7b7019..0a5f8af83 100644
--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h
@@ -103,8 +103,6 @@ private Q_SLOTS:
void updateMediaStatus();
void processEOS();
void setBufferProgress(int progress);
- void applyPendingSeek(bool isSeekable);
- void updatePosition(qint64 pos);
void handleInvalidMedia();
@@ -127,7 +125,6 @@ private:
QStack<QMediaPlayer::MediaStatus> m_mediaStatusStack;
int m_bufferProgress;
- bool m_seekToStartPending;
qint64 m_pendingSeekPosition;
bool m_setMediaPending;
QMediaContent m_currentResource;
diff --git a/src/plugins/opensles/qopenslesaudioinput.cpp b/src/plugins/opensles/qopenslesaudioinput.cpp
index 9e344b463..cd592a7d6 100644
--- a/src/plugins/opensles/qopenslesaudioinput.cpp
+++ b/src/plugins/opensles/qopenslesaudioinput.cpp
@@ -474,7 +474,7 @@ qint64 QOpenSLESAudioInput::elapsedUSecs() const
if (m_deviceState == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QOpenSLESAudioInput::setVolume(qreal vol)
diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp
index f055796b5..c45fbd3c5 100644
--- a/src/plugins/opensles/qopenslesaudiooutput.cpp
+++ b/src/plugins/opensles/qopenslesaudiooutput.cpp
@@ -70,7 +70,9 @@ QOpenSLESAudioOutput::QOpenSLESAudioOutput(const QByteArray &device)
m_periodSize(0),
m_elapsedTime(0),
m_processedBytes(0),
- m_availableBuffers(BUFFER_COUNT)
+ m_availableBuffers(BUFFER_COUNT),
+ m_eventMask(SL_PLAYEVENT_HEADATEND),
+ m_startRequiresInit(true)
{
#ifndef ANDROID
m_streamType = -1;
@@ -98,13 +100,10 @@ QAudio::State QOpenSLESAudioOutput::state() const
void QOpenSLESAudioOutput::start(QIODevice *device)
{
Q_ASSERT(device);
- destroyPlayer();
-
- m_pullMode = true;
-
if (!preparePlayer())
return;
+ m_pullMode = true;
m_audioSource = device;
setState(QAudio::ActiveState);
setError(QAudio::NoError);
@@ -125,29 +124,20 @@ void QOpenSLESAudioOutput::start(QIODevice *device)
// Change the state to playing.
// We need to do this after filling the buffers or processedBytes might get corrupted.
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- }
+ startPlayer();
}
QIODevice *QOpenSLESAudioOutput::start()
{
- destroyPlayer();
-
- m_pullMode = false;
-
if (!preparePlayer())
return Q_NULLPTR;
+ m_pullMode = false;
m_audioSource = new SLIODevicePrivate(this);
m_audioSource->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
// Change the state to playing
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- }
+ startPlayer();
setState(QAudio::IdleState);
return m_audioSource;
@@ -158,7 +148,7 @@ void QOpenSLESAudioOutput::stop()
if (m_state == QAudio::StoppedState)
return;
- destroyPlayer();
+ stopPlayer();
setError(QAudio::NoError);
}
@@ -180,6 +170,7 @@ void QOpenSLESAudioOutput::setBufferSize(int value)
if (m_state != QAudio::StoppedState)
return;
+ m_startRequiresInit = true;
m_bufferSize = value;
}
@@ -190,7 +181,33 @@ int QOpenSLESAudioOutput::bufferSize() const
void QOpenSLESAudioOutput::setNotifyInterval(int ms)
{
- m_notifyInterval = ms > 0 ? ms : 0;
+ const int newInterval = ms > 0 ? ms : 0;
+
+ if (newInterval == m_notifyInterval)
+ return;
+
+ const SLuint32 newEvenMask = newInterval == 0 ? m_eventMask & ~SL_PLAYEVENT_HEADATNEWPOS
+ : m_eventMask & SL_PLAYEVENT_HEADATNEWPOS;
+
+ if (m_state == QAudio::StoppedState) {
+ m_eventMask = newEvenMask;
+ m_notifyInterval = newInterval;
+ return;
+ }
+
+ if (newEvenMask != m_eventMask
+ && SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, newEvenMask)) {
+ return;
+ }
+
+ m_eventMask = newEvenMask;
+
+ if (newInterval && SL_RESULT_SUCCESS != (*m_playItf)->SetPositionUpdatePeriod(m_playItf,
+ newInterval)) {
+ return;
+ }
+
+ m_notifyInterval = newInterval;
}
int QOpenSLESAudioOutput::notifyInterval() const
@@ -227,6 +244,7 @@ void QOpenSLESAudioOutput::resume()
void QOpenSLESAudioOutput::setFormat(const QAudioFormat &format)
{
+ m_startRequiresInit = true;
m_format = format;
}
@@ -255,7 +273,7 @@ qint64 QOpenSLESAudioOutput::elapsedUSecs() const
if (m_state == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QOpenSLESAudioOutput::reset()
@@ -298,6 +316,7 @@ void QOpenSLESAudioOutput::setCategory(const QString &category)
return;
}
+ m_startRequiresInit = true;
m_streamType = streamType;
m_category = category;
#endif // ANDROID
@@ -376,6 +395,11 @@ void QOpenSLESAudioOutput::bufferQueueCallback(SLBufferQueueItf bufferQueue, voi
bool QOpenSLESAudioOutput::preparePlayer()
{
+ if (m_startRequiresInit)
+ destroyPlayer();
+ else
+ return true;
+
SLEngineItf engine = QOpenSLESEngine::instance()->slEngine();
if (!engine) {
qWarning() << "No engine";
@@ -480,13 +504,12 @@ bool QOpenSLESAudioOutput::preparePlayer()
return false;
}
- SLuint32 mask = SL_PLAYEVENT_HEADATEND;
if (m_notifyInterval && SL_RESULT_SUCCESS == (*m_playItf)->SetPositionUpdatePeriod(m_playItf,
m_notifyInterval)) {
- mask |= SL_PLAYEVENT_HEADATNEWPOS;
+ m_eventMask |= SL_PLAYEVENT_HEADATNEWPOS;
}
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, mask)) {
+ if (SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, m_eventMask)) {
setError(QAudio::FatalError);
return false;
}
@@ -517,20 +540,15 @@ bool QOpenSLESAudioOutput::preparePlayer()
m_clockStamp.restart();
setError(QAudio::NoError);
+ m_startRequiresInit = false;
return true;
}
void QOpenSLESAudioOutput::destroyPlayer()
{
- setState(QAudio::StoppedState);
-
- // We need to change the state manually...
- if (m_playItf)
- (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED);
-
- if (m_bufferQueueItf && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Clear(m_bufferQueueItf))
- qWarning() << "Unable to clear buffer";
+ if (m_state != QAudio::StoppedState)
+ stopPlayer();
if (m_playerObject) {
(*m_playerObject)->Destroy(m_playerObject);
@@ -556,6 +574,27 @@ void QOpenSLESAudioOutput::destroyPlayer()
m_playItf = Q_NULLPTR;
m_volumeItf = Q_NULLPTR;
m_bufferQueueItf = Q_NULLPTR;
+ m_startRequiresInit = true;
+}
+
+void QOpenSLESAudioOutput::stopPlayer()
+{
+ setState(QAudio::StoppedState);
+
+ // We need to change the state manually...
+ if (m_playItf)
+ (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED);
+
+ if (m_bufferQueueItf && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Clear(m_bufferQueueItf))
+ qWarning() << "Unable to clear buffer";
+}
+
+void QOpenSLESAudioOutput::startPlayer()
+{
+ if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
+ setError(QAudio::FatalError);
+ destroyPlayer();
+ }
}
qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len)
diff --git a/src/plugins/opensles/qopenslesaudiooutput.h b/src/plugins/opensles/qopenslesaudiooutput.h
index 60c8cfa86..200b4a3cc 100644
--- a/src/plugins/opensles/qopenslesaudiooutput.h
+++ b/src/plugins/opensles/qopenslesaudiooutput.h
@@ -86,6 +86,8 @@ private:
bool preparePlayer();
void destroyPlayer();
+ void stopPlayer();
+ void startPlayer();
qint64 writeData(const char *data, qint64 len);
void setState(QAudio::State state);
@@ -112,6 +114,8 @@ private:
qint64 m_elapsedTime;
qint64 m_processedBytes;
QAtomicInt m_availableBuffers;
+ SLuint32 m_eventMask;
+ bool m_startRequiresInit;
qint32 m_streamType;
QTime m_clockStamp;
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 0020203c3..aa28bdd1b 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -44,15 +44,15 @@ unix:!mac:!android {
config_alsa: SUBDIRS += alsa
# v4l is turned off because it is not supported in Qt 5
- # !maemo*:SUBDIRS += v4l
+ # config_linux_v4l {
+ # !maemo*:SUBDIRS += v4l
+ # }
}
mac:!simulator {
SUBDIRS += audiocapture coreaudio
config_avfoundation: SUBDIRS += avfoundation
-
- contains(QT_CONFIG, opengl.*):!ios: SUBDIRS += qt7
}
config_resourcepolicy {
diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/src/plugins/pulseaudio/qaudioinput_pulse.cpp
index b97cd6c4f..ea053578f 100644
--- a/src/plugins/pulseaudio/qaudioinput_pulse.cpp
+++ b/src/plugins/pulseaudio/qaudioinput_pulse.cpp
@@ -684,7 +684,7 @@ qint64 QPulseAudioInput::elapsedUSecs() const
if (m_deviceState == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QPulseAudioInput::reset()
diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
index c55cfe44c..b979450b6 100644
--- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
+++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp
@@ -596,7 +596,7 @@ qint64 QPulseAudioOutput::elapsedUSecs() const
if (m_deviceState == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
void QPulseAudioOutput::reset()
diff --git a/src/plugins/qnx-audio/audio/qnxaudioinput.cpp b/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
index ea9ea5abf..3f60dfc29 100644
--- a/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
+++ b/src/plugins/qnx-audio/audio/qnxaudioinput.cpp
@@ -186,7 +186,7 @@ qint64 QnxAudioInput::elapsedUSecs() const
if (m_state == QAudio::StoppedState)
return 0;
- return m_clockStamp.elapsed() * 1000;
+ return m_clockStamp.elapsed() * qint64(1000);
}
QAudio::Error QnxAudioInput::error() const
diff --git a/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp b/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
index 4604ed542..e7733276e 100644
--- a/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
+++ b/src/plugins/qnx-audio/audio/qnxaudiooutput.cpp
@@ -172,7 +172,7 @@ qint64 QnxAudioOutput::elapsedUSecs() const
if (m_state == QAudio::StoppedState)
return 0;
else
- return m_startTimeStamp.elapsed() * 1000;
+ return m_startTimeStamp.elapsed() * qint64(1000);
}
QAudio::Error QnxAudioOutput::error() const
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
index 217f8b3bb..503c5beb8 100644
--- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
@@ -538,6 +538,7 @@ void MmRendererMediaPlayerControl::play()
return;
}
+ m_stopEventsToIgnore = 0; // once playing, stop events must be proccessed
setState( QMediaPlayer::PlayingState);
}
diff --git a/src/plugins/qt7/mediaplayer/mediaplayer.pri b/src/plugins/qt7/mediaplayer/mediaplayer.pri
deleted file mode 100644
index 2edb1d2c7..000000000
--- a/src/plugins/qt7/mediaplayer/mediaplayer.pri
+++ /dev/null
@@ -1,16 +0,0 @@
-INCLUDEPATH += $$PWD
-
-DEFINES += QMEDIA_QT7_PLAYER
-
-HEADERS += \
- $$PWD/qt7playercontrol.h \
- $$PWD/qt7playermetadata.h \
- $$PWD/qt7playerservice.h \
- $$PWD/qt7playersession.h
-
-OBJECTIVE_SOURCES += \
- $$PWD/qt7playercontrol.mm \
- $$PWD/qt7playermetadata.mm \
- $$PWD/qt7playerservice.mm \
- $$PWD/qt7playersession.mm
-
diff --git a/src/plugins/qt7/mediaplayer/qt7playercontrol.h b/src/plugins/qt7/mediaplayer/qt7playercontrol.h
deleted file mode 100644
index 61fd0a456..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playercontrol.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERCONTROL_H
-#define QT7PLAYERCONTROL_H
-
-#include <QtCore/qobject.h>
-
-#include <qmediaplayercontrol.h>
-#include <qmediaplayer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-class QT7PlayerService;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-
-class QT7PlayerControl : public QMediaPlayerControl
-{
-Q_OBJECT
-public:
- QT7PlayerControl(QObject *parent = 0);
- ~QT7PlayerControl();
-
- void setSession(QT7PlayerSession *session);
-
- QMediaPlayer::State state() const;
- QMediaPlayer::MediaStatus mediaStatus() const;
-
- QMediaContent media() const;
- const QIODevice *mediaStream() const;
- void setMedia(const QMediaContent &content, QIODevice *stream);
-
- qint64 position() const;
- qint64 duration() const;
-
- int bufferStatus() const;
-
- int volume() const;
- bool isMuted() const;
-
- bool isAudioAvailable() const;
- bool isVideoAvailable() const;
-
- bool isSeekable() const;
- QMediaTimeRange availablePlaybackRanges() const;
-
- qreal playbackRate() const;
- void setPlaybackRate(qreal rate);
-
-public Q_SLOTS:
- void setPosition(qint64 pos);
-
- void play();
- void pause();
- void stop();
-
- void setVolume(int volume);
- void setMuted(bool muted);
-
-private:
- QT7PlayerSession *m_session;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playercontrol.mm b/src/plugins/qt7/mediaplayer/qt7playercontrol.mm
deleted file mode 100644
index c48660778..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playercontrol.mm
+++ /dev/null
@@ -1,191 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qt7playercontrol.h"
-#include "qt7playersession.h"
-
-#include <private/qmediaplaylistnavigator_p.h>
-
-#include <QtCore/qurl.h>
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-QT7PlayerControl::QT7PlayerControl(QObject *parent)
- : QMediaPlayerControl(parent)
-{
-}
-
-QT7PlayerControl::~QT7PlayerControl()
-{
-}
-
-void QT7PlayerControl::setSession(QT7PlayerSession *session)
-{
- m_session = session;
-
- connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64)));
- connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
- connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)),
- this, SIGNAL(stateChanged(QMediaPlayer::State)));
- connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
- this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
- connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int)));
- connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
- connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool)));
- connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool)));
- connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
-}
-
-qint64 QT7PlayerControl::position() const
-{
- return m_session->position();
-}
-
-qint64 QT7PlayerControl::duration() const
-{
- return m_session->duration();
-}
-
-QMediaPlayer::State QT7PlayerControl::state() const
-{
- return m_session->state();
-}
-
-QMediaPlayer::MediaStatus QT7PlayerControl::mediaStatus() const
-{
- return m_session->mediaStatus();
-}
-
-int QT7PlayerControl::bufferStatus() const
-{
- return m_session->bufferStatus();
-}
-
-int QT7PlayerControl::volume() const
-{
- return m_session->volume();
-}
-
-bool QT7PlayerControl::isMuted() const
-{
- return m_session->isMuted();
-}
-
-bool QT7PlayerControl::isSeekable() const
-{
- return m_session->isSeekable();
-}
-
-QMediaTimeRange QT7PlayerControl::availablePlaybackRanges() const
-{
- return m_session->availablePlaybackRanges();
-}
-
-qreal QT7PlayerControl::playbackRate() const
-{
- return m_session->playbackRate();
-}
-
-void QT7PlayerControl::setPlaybackRate(qreal rate)
-{
- m_session->setPlaybackRate(rate);
-}
-
-void QT7PlayerControl::setPosition(qint64 pos)
-{
- m_session->setPosition(pos);
-}
-
-void QT7PlayerControl::play()
-{
- m_session->play();
-}
-
-void QT7PlayerControl::pause()
-{
- m_session->pause();
-}
-
-void QT7PlayerControl::stop()
-{
- m_session->stop();
-}
-
-void QT7PlayerControl::setVolume(int volume)
-{
- m_session->setVolume(volume);
-}
-
-void QT7PlayerControl::setMuted(bool muted)
-{
- m_session->setMuted(muted);
-}
-
-QMediaContent QT7PlayerControl::media() const
-{
- return m_session->media();
-}
-
-const QIODevice *QT7PlayerControl::mediaStream() const
-{
- return m_session->mediaStream();
-}
-
-void QT7PlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
-{
- m_session->setMedia(content, stream);
-
- Q_EMIT mediaChanged(content);
-}
-
-bool QT7PlayerControl::isAudioAvailable() const
-{
- return m_session->isAudioAvailable();
-}
-
-bool QT7PlayerControl::isVideoAvailable() const
-{
- return m_session->isVideoAvailable();
-}
-
-
-#include "moc_qt7playercontrol.cpp"
diff --git a/src/plugins/qt7/mediaplayer/qt7playermetadata.h b/src/plugins/qt7/mediaplayer/qt7playermetadata.h
deleted file mode 100644
index 9f0ceae16..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playermetadata.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERMETADATACONTROL_H
-#define QT7PLAYERMETADATACONTROL_H
-
-#include <qmetadatareadercontrol.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-
-class QT7PlayerMetaDataControl : public QMetaDataReaderControl
-{
- Q_OBJECT
-public:
- QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent);
- virtual ~QT7PlayerMetaDataControl();
-
- bool isMetaDataAvailable() const;
- bool isWritable() const;
-
- QVariant metaData(const QString &key) const;
- QStringList availableMetaData() const;
-
-private Q_SLOTS:
- void updateTags();
-
-private:
- QT7PlayerSession *m_session;
- QMap<QString, QVariant> m_tags;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playermetadata.mm b/src/plugins/qt7/mediaplayer/qt7playermetadata.mm
deleted file mode 100644
index 84d434be2..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playermetadata.mm
+++ /dev/null
@@ -1,250 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qt7backend.h"
-#include "qt7playermetadata.h"
-#include "qt7playersession.h"
-#include <QtCore/qvarlengtharray.h>
-#include <QtMultimedia/qmediametadata.h>
-
-#import <QTKit/QTMovie.h>
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- #include <QuickTime/QuickTime.h>
- #undef check // avoid name clash;
-#endif
-
-QT_USE_NAMESPACE
-
-QT7PlayerMetaDataControl::QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent)
- :QMetaDataReaderControl(parent), m_session(session)
-{
-}
-
-QT7PlayerMetaDataControl::~QT7PlayerMetaDataControl()
-{
-}
-
-bool QT7PlayerMetaDataControl::isMetaDataAvailable() const
-{
- return !m_tags.isEmpty();
-}
-
-bool QT7PlayerMetaDataControl::isWritable() const
-{
- return false;
-}
-
-QVariant QT7PlayerMetaDataControl::metaData(const QString &key) const
-{
- return m_tags.value(key);
-}
-
-QStringList QT7PlayerMetaDataControl::availableMetaData() const
-{
- return m_tags.keys();
-}
-
-#ifdef QUICKTIME_C_API_AVAILABLE
-
-static QString stripCopyRightSymbol(const QString &key)
-{
- return key.right(key.length()-1);
-}
-
-static QString convertQuickTimeKeyToUserKey(const QString &key)
-{
- if (key == QLatin1String("com.apple.quicktime.displayname"))
- return QLatin1String("nam");
- else if (key == QLatin1String("com.apple.quicktime.album"))
- return QLatin1String("alb");
- else if (key == QLatin1String("com.apple.quicktime.artist"))
- return QLatin1String("ART");
- else
- return QLatin1String("???");
-}
-
-static OSStatus readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
- QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
-{
- QTPropertyValueType type;
- ByteCount propSize;
- UInt32 propFlags;
- OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
-
- if (err == noErr) {
- *value = malloc(propSize);
- if (*value != 0) {
- err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
-
- if (err == noErr && (type == 'code' || type == 'itsk' || type == 'itlk')) {
- // convert from native endian to big endian
- OSTypePtr pType = (OSTypePtr)*value;
- *pType = EndianU32_NtoB(*pType);
- }
- }
- else
- return -1;
- }
-
- return err;
-}
-
-static UInt32 getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
-{
- QTPropertyValuePtr value = 0;
- ByteCount ignore = 0;
- OSStatus err = readMetaValue(
- metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
-
- if (err == noErr) {
- UInt32 type = *((UInt32 *) value);
- if (value)
- free(value);
- return type;
- }
-
- return 0;
-}
-
-static QString cFStringToQString(CFStringRef str)
-{
- if(!str)
- return QString();
- CFIndex length = CFStringGetLength(str);
- const UniChar *chars = CFStringGetCharactersPtr(str);
- if (chars)
- return QString(reinterpret_cast<const QChar *>(chars), length);
-
- QVarLengthArray<UniChar> buffer(length);
- CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
- return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
-}
-
-
-static QString getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
-{
- QTPropertyValuePtr value = 0;
- ByteCount size = 0;
- OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
- QString string;
-
- if (err == noErr) {
- UInt32 dataType = getMetaType(metaDataRef, item);
- switch (dataType){
- case kQTMetaDataTypeUTF8:
- case kQTMetaDataTypeMacEncodedText:
- string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
- break;
- case kQTMetaDataTypeUTF16BE:
- string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
- break;
- default:
- break;
- }
-
- if (value)
- free(value);
- }
-
- return string;
-}
-
-
-static void readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
-{
- QTMetaDataItem item = kQTMetaDataItemUninitialized;
- OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
- while (err == noErr){
- QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
- if (format == kQTMetaDataStorageFormatQuickTime)
- key = convertQuickTimeKeyToUserKey(key);
- else
- key = stripCopyRightSymbol(key);
-
- if (!result.contains(key)){
- QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
- result.insert(key, val);
- }
- err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
- }
-}
-#endif
-
-
-void QT7PlayerMetaDataControl::updateTags()
-{
- bool wasEmpty = m_tags.isEmpty();
- m_tags.clear();
-
- QTMovie *movie = (QTMovie*)m_session->movie();
-
- if (movie) {
- QMultiMap<QString, QString> metaMap;
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- QTMetaDataRef metaDataRef;
- OSStatus err = QTCopyMovieMetaData([movie quickTimeMovie], &metaDataRef);
- if (err == noErr) {
- readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
- readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
- readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
- }
-#else
- AutoReleasePool pool;
- NSString *name = [movie attributeForKey:@"QTMovieDisplayNameAttribute"];
- metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String]));
-#endif // QUICKTIME_C_API_AVAILABLE
-
- m_tags.insert(QMediaMetaData::AlbumArtist, metaMap.value(QLatin1String("ART")));
- m_tags.insert(QMediaMetaData::AlbumTitle, metaMap.value(QLatin1String("alb")));
- m_tags.insert(QMediaMetaData::Title, metaMap.value(QLatin1String("nam")));
- m_tags.insert(QMediaMetaData::Date, metaMap.value(QLatin1String("day")));
- m_tags.insert(QMediaMetaData::Genre, metaMap.value(QLatin1String("gnre")));
- m_tags.insert(QMediaMetaData::TrackNumber, metaMap.value(QLatin1String("trk")));
- m_tags.insert(QMediaMetaData::Description, metaMap.value(QLatin1String("des")));
- }
-
- if (!wasEmpty || !m_tags.isEmpty())
- Q_EMIT metaDataChanged();
-}
-
-#include "moc_qt7playermetadata.cpp"
diff --git a/src/plugins/qt7/mediaplayer/qt7playerservice.h b/src/plugins/qt7/mediaplayer/qt7playerservice.h
deleted file mode 100644
index 15c1d2cb7..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playerservice.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERSERVICE_H
-#define QT7PLAYERSERVICE_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qset.h>
-#include <qmediaservice.h>
-
-
-QT_BEGIN_NAMESPACE
-class QMediaPlayerControl;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7PlayerControl;
-class QT7PlayerMetaDataControl;
-class QT7VideoWindowControl;
-class QT7VideoWidgetControl;
-class QT7VideoRendererControl;
-class QT7VideoOutput;
-class QT7PlayerSession;
-
-class QT7PlayerService : public QMediaService
-{
-Q_OBJECT
-public:
- QT7PlayerService(QObject *parent = 0);
- ~QT7PlayerService();
-
- QMediaControl* requestControl(const char *name);
- void releaseControl(QMediaControl *control);
-
-private:
- QT7PlayerSession *m_session;
- QT7PlayerControl *m_control;
- QMediaControl * m_videoOutput;
- QT7PlayerMetaDataControl *m_playerMetaDataControl;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playerservice.mm b/src/plugins/qt7/mediaplayer/qt7playerservice.mm
deleted file mode 100644
index 46be5475f..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playerservice.mm
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qvariant.h>
-#include <QtCore/qdebug.h>
-
-#include "qt7backend.h"
-#include "qt7playerservice.h"
-#include "qt7playercontrol.h"
-#include "qt7playersession.h"
-#include "qt7videooutput.h"
-#include "qt7movieviewoutput.h"
-#include "qt7movieviewrenderer.h"
-#include "qt7movierenderer.h"
-#ifndef QT_NO_WIDGETS
-#include "qt7movievideowidget.h"
-#endif
-#include "qt7playermetadata.h"
-
-#include <private/qmediaplaylistnavigator_p.h>
-#include <qmediaplaylist.h>
-
-QT_USE_NAMESPACE
-
-QT7PlayerService::QT7PlayerService(QObject *parent):
- QMediaService(parent),
- m_videoOutput(0)
-{
- m_session = new QT7PlayerSession(this);
-
- m_control = new QT7PlayerControl(this);
- m_control->setSession(m_session);
-
- m_playerMetaDataControl = new QT7PlayerMetaDataControl(m_session, this);
- connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags()));
-}
-
-QT7PlayerService::~QT7PlayerService()
-{
-}
-
-QMediaControl *QT7PlayerService::requestControl(const char *name)
-{
- if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
- return m_control;
-
- if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
- return m_playerMetaDataControl;
-
-#ifndef QT_NO_OPENGL
- if (!m_videoOutput) {
- if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
- m_videoOutput = new QT7MovieViewOutput(this);
- }
-
- if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
-#ifndef QT_NO_WIDGETS
- m_videoOutput = new QT7MovieViewRenderer(this);
-#endif
- }
-
-#ifndef QT_NO_WIDGETS
- if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
-#ifdef QUICKTIME_C_API_AVAILABLE
- m_videoOutput = new QT7MovieVideoWidget(this);
-#endif
- }
-#endif
-
- if (m_videoOutput) {
- QT7VideoOutput *videoOutput = qobject_cast<QT7VideoOutput*>(m_videoOutput);
- m_session->setVideoOutput(videoOutput);
- return m_videoOutput;
- }
- }
-#endif // !defined(QT_NO_OPENGL)
-
- return 0;
-}
-
-void QT7PlayerService::releaseControl(QMediaControl *control)
-{
- if (m_videoOutput == control) {
- m_videoOutput = 0;
- m_session->setVideoOutput(0);
- delete control;
- }
-}
-
-#include "moc_qt7playerservice.cpp"
diff --git a/src/plugins/qt7/mediaplayer/qt7playersession.h b/src/plugins/qt7/mediaplayer/qt7playersession.h
deleted file mode 100644
index 58ea76a01..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playersession.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERSESSION_H
-#define QT7PLAYERSESSION_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qbytearray.h>
-#include <QtCore/qset.h>
-#include <QtCore/qresource.h>
-
-#include <qmediaplayercontrol.h>
-#include <qmediaplayer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerControl;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7VideoOutput;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-
-class QT7PlayerSession : public QObject
-{
- Q_OBJECT
-public:
- QT7PlayerSession(QObject *parent = 0);
- ~QT7PlayerSession();
-
- void *movie() const;
-
- void setControl(QT7PlayerControl *control);
-
- void setVideoOutput(QT7VideoOutput *output);
-
- QMediaPlayer::State state() const;
- QMediaPlayer::MediaStatus mediaStatus() const;
-
- QMediaContent media() const;
- const QIODevice *mediaStream() const;
- void setMedia(const QMediaContent &content, QIODevice *stream);
-
- qint64 position() const;
- qint64 duration() const;
-
- int bufferStatus() const;
-
- int volume() const;
- bool isMuted() const;
-
- bool isAudioAvailable() const;
- bool isVideoAvailable() const;
-
- bool isSeekable() const;
- QMediaTimeRange availablePlaybackRanges() const;
-
- qreal playbackRate() const;
-
-public Q_SLOTS:
- void setPlaybackRate(qreal rate);
-
- void setPosition(qint64 pos);
-
- void play();
- void pause();
- void stop();
-
- void setVolume(int volume);
- void setMuted(bool muted);
-
- void processEOS();
- void processLoadStateChange();
- void processVolumeChange();
- void processNaturalSizeChange();
- void processPositionChange();
-
-Q_SIGNALS:
- void positionChanged(qint64 position);
- void durationChanged(qint64 duration);
- void stateChanged(QMediaPlayer::State newState);
- void mediaStatusChanged(QMediaPlayer::MediaStatus status);
- void volumeChanged(int volume);
- void mutedChanged(bool muted);
- void audioAvailableChanged(bool audioAvailable);
- void videoAvailableChanged(bool videoAvailable);
- void error(int error, const QString &errorString);
-
-private:
- class ResourceHandler {
- public:
- ResourceHandler():resource(0) {}
- ~ResourceHandler() { clear(); }
- void setResourceFile(const QString &file) {
- if (resource) {
- if (resource->fileName() == file)
- return;
- delete resource;
- rawData.clear();
- }
- resource = new QResource(file);
- }
- bool isValid() const { return resource && resource->isValid() && resource->data() != 0; }
- const uchar *data() {
- if (!isValid())
- return 0;
- if (resource->isCompressed()) {
- if (rawData.size() == 0)
- rawData = qUncompress(resource->data(), resource->size());
- return (const uchar *)rawData.constData();
- }
- return resource->data();
- }
- qint64 size() {
- if (data() == 0)
- return 0;
- return resource->isCompressed() ? rawData.size() : resource->size();
- }
- void clear() {
- delete resource;
- rawData.clear();
- }
- QResource *resource;
- QByteArray rawData;
- };
-
- void openMovie(bool tryAsync);
-
- void *m_QTMovie;
- void *m_movieObserver;
-
- QMediaPlayer::State m_state;
- QMediaPlayer::MediaStatus m_mediaStatus;
- QIODevice *m_mediaStream;
- QMediaContent m_resources;
- ResourceHandler m_resourceHandler;
-
- QT7VideoOutput * m_videoOutput;
-
- bool m_muted;
- bool m_tryingAsync;
- int m_volume;
- qreal m_rate;
-
- qint64 m_duration;
- bool m_videoAvailable;
- bool m_audioAvailable;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/mediaplayer/qt7playersession.mm b/src/plugins/qt7/mediaplayer/qt7playersession.mm
deleted file mode 100644
index 4ec015cbf..000000000
--- a/src/plugins/qt7/mediaplayer/qt7playersession.mm
+++ /dev/null
@@ -1,751 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <QTKit/QTDataReference.h>
-#import <QTKit/QTMovie.h>
-
-#include "qt7backend.h"
-
-#include "qt7playersession.h"
-#include "qt7playercontrol.h"
-#include "qt7videooutput.h"
-
-#include <QtNetwork/qnetworkcookie.h>
-#include <private/qmediaplaylistnavigator_p.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qurl.h>
-
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-//#define QT_DEBUG_QT7
-
-@interface QTMovieObserver : NSObject
-{
-@private
- QT7PlayerSession *m_session;
- QTMovie *m_movie;
-}
-
-- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session;
-- (void) setMovie:(QTMovie *)movie;
-- (void) processEOS:(NSNotification *)notification;
-- (void) processLoadStateChange:(NSNotification *)notification;
-- (void) processVolumeChange:(NSNotification *)notification;
-- (void) processNaturalSizeChange :(NSNotification *)notification;
-- (void) processPositionChange :(NSNotification *)notification;
-@end
-
-@implementation QTMovieObserver
-
-- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session
-{
- if (!(self = [super init]))
- return nil;
-
- self->m_session = session;
- return self;
-}
-
-- (void) setMovie:(QTMovie *)movie
-{
- if (m_movie == movie)
- return;
-
- if (m_movie) {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [m_movie release];
- }
-
- m_movie = movie;
-
- if (movie) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processEOS:)
- name:QTMovieDidEndNotification
- object:m_movie];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processLoadStateChange:)
- name:QTMovieLoadStateDidChangeNotification
- object:m_movie];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processVolumeChange:)
- name:QTMovieVolumeDidChangeNotification
- object:m_movie];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processPositionChange:)
- name:QTMovieTimeDidChangeNotification
- object:m_movie];
-
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processNaturalSizeChange:)
- name:@"QTMovieNaturalSizeDidChangeNotification"
- object:m_movie];
-
- }
- else {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(processNaturalSizeChange:)
- name:QTMovieEditedNotification
- object:m_movie];
- }
-
- [movie retain];
- }
-}
-
-- (void) processEOS:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection);
-}
-
-- (void) processLoadStateChange:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection);
-}
-
-- (void) processVolumeChange:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processVolumeChange", Qt::AutoConnection);
-}
-
-- (void) processNaturalSizeChange :(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processNaturalSizeChange", Qt::AutoConnection);
-}
-
-- (void) processPositionChange :(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QMetaObject::invokeMethod(m_session, "processPositionChange", Qt::AutoConnection);
-}
-
-@end
-
-static inline NSString *qString2CFStringRef(const QString &string)
-{
- return [NSString stringWithCharacters:reinterpret_cast<const UniChar *>(string.unicode()) length:string.length()];
-}
-
-QT7PlayerSession::QT7PlayerSession(QObject *parent)
- : QObject(parent)
- , m_QTMovie(0)
- , m_state(QMediaPlayer::StoppedState)
- , m_mediaStatus(QMediaPlayer::NoMedia)
- , m_mediaStream(0)
- , m_videoOutput(0)
- , m_muted(false)
- , m_tryingAsync(false)
- , m_volume(100)
- , m_rate(1.0)
- , m_duration(0)
- , m_videoAvailable(false)
- , m_audioAvailable(false)
-{
- m_movieObserver = [[QTMovieObserver alloc] initWithPlayerSession:this];
-}
-
-QT7PlayerSession::~QT7PlayerSession()
-{
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- [(QTMovieObserver*)m_movieObserver setMovie:nil];
- [(QTMovieObserver*)m_movieObserver release];
- [(QTMovie*)m_QTMovie release];
-}
-
-void *QT7PlayerSession::movie() const
-{
- return m_QTMovie;
-}
-
-void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output)
-{
- if (m_videoOutput == output)
- return;
-
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- m_videoOutput = output;
-
- if (m_videoOutput && m_state != QMediaPlayer::StoppedState)
- m_videoOutput->setMovie(m_QTMovie);
-}
-
-qint64 QT7PlayerSession::position() const
-{
- if (!m_QTMovie)
- return 0;
-
- QTTime qtTime = [(QTMovie*)m_QTMovie currentTime];
-
- return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
-}
-
-qint64 QT7PlayerSession::duration() const
-{
- if (!m_QTMovie)
- return 0;
-
- QTTime qtTime = [(QTMovie*)m_QTMovie duration];
-
- return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
-}
-
-QMediaPlayer::State QT7PlayerSession::state() const
-{
- return m_state;
-}
-
-QMediaPlayer::MediaStatus QT7PlayerSession::mediaStatus() const
-{
- return m_mediaStatus;
-}
-
-int QT7PlayerSession::bufferStatus() const
-{
- return 100;
-}
-
-int QT7PlayerSession::volume() const
-{
- return m_volume;
-}
-
-bool QT7PlayerSession::isMuted() const
-{
- return m_muted;
-}
-
-bool QT7PlayerSession::isSeekable() const
-{
- return true;
-}
-
-#ifndef QUICKTIME_C_API_AVAILABLE
-@interface QTMovie(QtExtensions)
-- (NSArray*)loadedRanges;
-- (QTTime)maxTimeLoaded;
-@end
-#endif
-
-QMediaTimeRange QT7PlayerSession::availablePlaybackRanges() const
-{
- QTMovie *movie = (QTMovie*)m_QTMovie;
-#ifndef QUICKTIME_C_API_AVAILABLE
- AutoReleasePool pool;
- if ([movie respondsToSelector:@selector(loadedRanges)]) {
- QMediaTimeRange rc;
- NSArray *r = [movie loadedRanges];
- for (NSValue *tr in r) {
- QTTimeRange timeRange = [tr QTTimeRangeValue];
- qint64 startTime = qint64(float(timeRange.time.timeValue) / timeRange.time.timeScale * 1000.0);
- rc.addInterval(startTime, startTime + qint64(float(timeRange.duration.timeValue) / timeRange.duration.timeScale * 1000.0));
- }
- return rc;
- }
- else if ([movie respondsToSelector:@selector(maxTimeLoaded)]) {
- QTTime loadedTime = [movie maxTimeLoaded];
- return QMediaTimeRange(0, qint64(float(loadedTime.timeValue) / loadedTime.timeScale * 1000.0));
- }
-#else
- TimeValue loadedTime;
- TimeScale scale;
- Movie m = [movie quickTimeMovie];
- if (GetMaxLoadedTimeInMovie(m, &loadedTime) == noErr) {
- scale = GetMovieTimeScale(m);
- return QMediaTimeRange(0, qint64(float(loadedTime) / scale * 1000.0f));
- }
-#endif
- return QMediaTimeRange(0, duration());
-}
-
-qreal QT7PlayerSession::playbackRate() const
-{
- return m_rate;
-}
-
-void QT7PlayerSession::setPlaybackRate(qreal rate)
-{
- if (qFuzzyCompare(m_rate, rate))
- return;
-
- m_rate = rate;
-
- if (m_QTMovie != 0 && m_state == QMediaPlayer::PlayingState) {
- AutoReleasePool pool;
- float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
- [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
- }
-}
-
-void QT7PlayerSession::setPosition(qint64 pos)
-{
- if ( !isSeekable() || pos == position())
- return;
-
- if (duration() > 0)
- pos = qMin(pos, duration());
-
- QTTime newQTTime = [(QTMovie*)m_QTMovie currentTime];
- newQTTime.timeValue = (pos / 1000.0f) * newQTTime.timeScale;
- [(QTMovie*)m_QTMovie setCurrentTime:newQTTime];
-
- //reset the EndOfMedia status position is changed after playback is finished
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- processLoadStateChange();
-}
-
-void QT7PlayerSession::play()
-{
- if (m_state == QMediaPlayer::PlayingState)
- return;
-
- m_state = QMediaPlayer::PlayingState;
-
- if (m_videoOutput)
- m_videoOutput->setMovie(m_QTMovie);
-
- //reset the EndOfMedia status if the same file is played again
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- processLoadStateChange();
-
- AutoReleasePool pool;
- float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
- [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
-
- processLoadStateChange();
- Q_EMIT stateChanged(m_state);
-}
-
-void QT7PlayerSession::pause()
-{
- if (m_state == QMediaPlayer::PausedState)
- return;
-
- m_state = QMediaPlayer::PausedState;
-
- if (m_videoOutput)
- m_videoOutput->setMovie(m_QTMovie);
-
- //reset the EndOfMedia status if the same file is played again
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- processLoadStateChange();
-
- [(QTMovie*)m_QTMovie setRate:0];
-
- processLoadStateChange();
- Q_EMIT stateChanged(m_state);
-}
-
-void QT7PlayerSession::stop()
-{
- if (m_state == QMediaPlayer::StoppedState)
- return;
-
- m_state = QMediaPlayer::StoppedState;
-
- [(QTMovie*)m_QTMovie setRate:0];
- setPosition(0);
-
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- processLoadStateChange();
- Q_EMIT stateChanged(m_state);
- Q_EMIT positionChanged(position());
-}
-
-void QT7PlayerSession::setVolume(int volume)
-{
- if (m_volume == volume)
- return;
-
- m_volume = volume;
-
- if (m_QTMovie != 0)
- [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
-
- Q_EMIT volumeChanged(m_volume);
-}
-
-void QT7PlayerSession::setMuted(bool muted)
-{
- if (m_muted == muted)
- return;
-
- m_muted = muted;
-
- if (m_QTMovie != 0)
- [(QTMovie*)m_QTMovie setMuted:m_muted];
-
- Q_EMIT mutedChanged(muted);
-}
-
-QMediaContent QT7PlayerSession::media() const
-{
- return m_resources;
-}
-
-const QIODevice *QT7PlayerSession::mediaStream() const
-{
- return m_mediaStream;
-}
-
-void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream)
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << content.canonicalUrl();
-#endif
-
- if (m_QTMovie) {
- [(QTMovieObserver*)m_movieObserver setMovie:nil];
-
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- [(QTMovie*)m_QTMovie release];
- m_QTMovie = 0;
- m_resourceHandler.clear();
- }
-
- m_resources = content;
- m_mediaStream = stream;
- QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
-
- if (content.isNull()) {
- m_mediaStatus = QMediaPlayer::NoMedia;
- if (m_state != QMediaPlayer::StoppedState)
- Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
-
- if (m_mediaStatus != oldMediaStatus)
- Q_EMIT mediaStatusChanged(m_mediaStatus);
- Q_EMIT positionChanged(position());
- return;
- }
-
- m_mediaStatus = QMediaPlayer::LoadingMedia;
- if (m_mediaStatus != oldMediaStatus)
- Q_EMIT mediaStatusChanged(m_mediaStatus);
-
- QNetworkRequest request = content.canonicalResource().request();
-
- QVariant cookies = request.header(QNetworkRequest::CookieHeader);
- if (cookies.isValid()) {
- NSHTTPCookieStorage *store = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- QList<QNetworkCookie> cookieList = cookies.value<QList<QNetworkCookie> >();
-
- Q_FOREACH (const QNetworkCookie &requestCookie, cookieList) {
- NSMutableDictionary *p = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- qString2CFStringRef(requestCookie.name()), NSHTTPCookieName,
- qString2CFStringRef(requestCookie.value()), NSHTTPCookieValue,
- qString2CFStringRef(requestCookie.domain()), NSHTTPCookieDomain,
- qString2CFStringRef(requestCookie.path()), NSHTTPCookiePath,
- nil
- ];
- if (requestCookie.isSessionCookie())
- [p setObject:[NSString stringWithUTF8String:"TRUE"] forKey:NSHTTPCookieDiscard];
- else
- [p setObject:[NSDate dateWithTimeIntervalSince1970:requestCookie.expirationDate().toTime_t()] forKey:NSHTTPCookieExpires];
-
- [store setCookie:[NSHTTPCookie cookieWithProperties:p]];
- }
- }
-
- // Attempt multiple times to open the movie.
- // First try - attempt open in async mode
- openMovie(true);
-
- Q_EMIT positionChanged(position());
-}
-
-void QT7PlayerSession::openMovie(bool tryAsync)
-{
- QUrl requestUrl = m_resources.canonicalResource().request().url();
- if (requestUrl.scheme().isEmpty())
- requestUrl.setScheme(QLatin1String("file"));
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << requestUrl;
-#endif
-
- NSError *err = 0;
- NSString *urlString = [NSString stringWithUTF8String:requestUrl.toEncoded().constData()];
-
- NSMutableDictionary *attr = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute,
- [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute,
- [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute,
- [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute,
- nil];
-
-
- if (requestUrl.scheme() == QLatin1String("qrc")) {
- // Load from Qt resource
- m_resourceHandler.setResourceFile(QLatin1Char(':') + requestUrl.path());
- if (!m_resourceHandler.isValid()) {
- Q_EMIT error(QMediaPlayer::FormatError, tr("Attempting to play invalid Qt resource"));
- return;
- }
-
- CFDataRef resourceData =
- CFDataCreateWithBytesNoCopy(0, m_resourceHandler.data(), m_resourceHandler.size(), kCFAllocatorNull);
-
- QTDataReference *dataReference =
- [QTDataReference dataReferenceWithReferenceToData:(NSData*)resourceData
- name:qString2CFStringRef(requestUrl.path())
- MIMEType:nil];
-
- [attr setObject:dataReference forKey:QTMovieDataReferenceAttribute];
-
- CFRelease(resourceData);
- } else {
- [attr setObject:[NSURL URLWithString:urlString] forKey:QTMovieURLAttribute];
- }
-
- if (tryAsync && QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
- [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenAsyncRequiredAttribute"];
-// XXX: This is disabled for now. causes some problems with video playback for some formats
-// [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"];
- m_tryingAsync = true;
- }
- else
- m_tryingAsync = false;
-
- m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
- if (err != nil) {
- // First attempt to test for inability to perform async
-// if ([err code] == QTErrorMovieOpeningCannotBeAsynchronous) { XXX: error code unknown!
- if (m_tryingAsync) {
- m_tryingAsync = false;
- err = nil;
- [attr removeObjectForKey:@"QTMovieOpenAsyncRequiredAttribute"];
- m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
- }
- }
-
- if (err != nil) {
- m_QTMovie = 0;
- QString description = QString::fromUtf8([[err localizedDescription] UTF8String]);
- Q_EMIT error(QMediaPlayer::FormatError, description);
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << description;
-#endif
- }
- else {
- [(QTMovie*)m_QTMovie retain];
-
- [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie];
-
- if (m_state != QMediaPlayer::StoppedState && m_videoOutput)
- m_videoOutput->setMovie(m_QTMovie);
-
- processLoadStateChange();
-
- [(QTMovie*)m_QTMovie setMuted:m_muted];
- [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
- }
-}
-
-bool QT7PlayerSession::isAudioAvailable() const
-{
- if (!m_QTMovie)
- return false;
-
- AutoReleasePool pool;
- return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasAudioAttribute"] boolValue] == YES;
-}
-
-bool QT7PlayerSession::isVideoAvailable() const
-{
- if (!m_QTMovie)
- return false;
-
- AutoReleasePool pool;
- return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasVideoAttribute"] boolValue] == YES;
-}
-
-void QT7PlayerSession::processEOS()
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO;
-#endif
- Q_EMIT positionChanged(position());
- m_mediaStatus = QMediaPlayer::EndOfMedia;
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
- Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
- Q_EMIT mediaStatusChanged(m_mediaStatus);
-}
-
-void QT7PlayerSession::processLoadStateChange()
-{
- if (!m_QTMovie)
- return;
-
- AutoReleasePool pool;
-
- long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute] longValue];
-
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << state;
-#endif
-
-#ifndef QUICKTIME_C_API_AVAILABLE
- enum {
- kMovieLoadStateError = -1L,
- kMovieLoadStateLoading = 1000,
- kMovieLoadStateLoaded = 2000,
- kMovieLoadStatePlayable = 10000,
- kMovieLoadStatePlaythroughOK = 20000,
- kMovieLoadStateComplete = 100000
- };
-#endif
-
- if (state == kMovieLoadStateError) {
- if (m_tryingAsync) {
- NSError *error = [(QTMovie*)m_QTMovie attributeForKey:@"QTMovieLoadStateErrorAttribute"];
- if ([error code] == componentNotThreadSafeErr) {
- // Last Async check, try again with no such flag
- openMovie(false);
- }
- }
- else {
- if (m_videoOutput)
- m_videoOutput->setMovie(0);
-
- Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media"));
- Q_EMIT mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia);
- Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);
- }
-
- return;
- }
-
- QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia;
- bool isPlaying = (m_state != QMediaPlayer::StoppedState);
-
- if (state >= kMovieLoadStatePlaythroughOK) {
- newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
- } else if (state >= kMovieLoadStatePlayable)
- newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia;
- else if (state >= kMovieLoadStateLoading) {
- if (!isPlaying)
- newStatus = QMediaPlayer::LoadingMedia;
- else if (m_mediaStatus >= QMediaPlayer::LoadedMedia)
- newStatus = QMediaPlayer::StalledMedia;
- else
- newStatus = QMediaPlayer::LoadingMedia;
- }
-
- if (state >= kMovieLoadStatePlayable &&
- m_state == QMediaPlayer::PlayingState &&
- [(QTMovie*)m_QTMovie rate] == 0) {
-
- float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
-
- [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
- }
-
- if (state >= kMovieLoadStateLoaded) {
- qint64 currentDuration = duration();
- if (m_duration != currentDuration)
- Q_EMIT durationChanged(m_duration = currentDuration);
-
- if (m_audioAvailable != isAudioAvailable())
- Q_EMIT audioAvailableChanged(m_audioAvailable = !m_audioAvailable);
-
- if (m_videoAvailable != isVideoAvailable())
- Q_EMIT videoAvailableChanged(m_videoAvailable = !m_videoAvailable);
- }
-
- if (newStatus != m_mediaStatus)
- Q_EMIT mediaStatusChanged(m_mediaStatus = newStatus);
-}
-
-void QT7PlayerSession::processVolumeChange()
-{
- if (!m_QTMovie)
- return;
-
- int newVolume = qRound(100.0f * [((QTMovie*)m_QTMovie) volume]);
-
- if (newVolume != m_volume) {
- Q_EMIT volumeChanged(m_volume = newVolume);
- }
-}
-
-void QT7PlayerSession::processNaturalSizeChange()
-{
- AutoReleasePool pool;
- NSSize size = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
-#ifdef QT_DEBUG_QT7
- qDebug() << Q_FUNC_INFO << QSize(size.width, size.height);
-#endif
-
- if (m_videoOutput)
- m_videoOutput->updateNaturalSize(QSize(size.width, size.height));
-}
-
-void QT7PlayerSession::processPositionChange()
-{
- Q_EMIT positionChanged(position());
-}
-
-#include "moc_qt7playersession.cpp"
diff --git a/src/plugins/qt7/qcvdisplaylink.h b/src/plugins/qt7/qcvdisplaylink.h
deleted file mode 100644
index ec24a0aa9..000000000
--- a/src/plugins/qt7/qcvdisplaylink.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCVDISPLAYLINK_H
-#define QCVDISPLAYLINK_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qtmultimediadefs.h>
-
-#include <QuartzCore/CVDisplayLink.h>
-
-QT_BEGIN_NAMESPACE
-
-class QCvDisplayLink : public QObject
-{
-Q_OBJECT
-public:
- QCvDisplayLink(QObject *parent = 0);
- virtual ~QCvDisplayLink();
-
- bool isValid();
- bool isActive() const;
-
-public Q_SLOTS:
- void start();
- void stop();
-
-Q_SIGNALS:
- void tick(const CVTimeStamp &ts);
-
-public:
- void displayLinkEvent(const CVTimeStamp *);
-
-protected:
- virtual bool event(QEvent *);
-
-private:
- CVDisplayLinkRef m_displayLink;
- QMutex m_displayLinkMutex;
- bool m_pendingDisplayLinkEvent;
- bool m_isActive;
- CVTimeStamp m_frameTimeStamp;
-};
-
-QT_END_NAMESPACE
-
-#endif
-
diff --git a/src/plugins/qt7/qcvdisplaylink.mm b/src/plugins/qt7/qcvdisplaylink.mm
deleted file mode 100644
index 890955492..000000000
--- a/src/plugins/qt7/qcvdisplaylink.mm
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcvdisplaylink.h"
-
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink,
- const CVTimeStamp *inNow,
- const CVTimeStamp *inOutputTime,
- CVOptionFlags flagsIn,
- CVOptionFlags *flagsOut,
- void *displayLinkContext)
-{
- Q_UNUSED(displayLink);
- Q_UNUSED(inNow);
- Q_UNUSED(flagsIn);
- Q_UNUSED(flagsOut);
-
- QCvDisplayLink *link = (QCvDisplayLink *)displayLinkContext;
-
- link->displayLinkEvent(inOutputTime);
- return kCVReturnSuccess;
-}
-
-
-QCvDisplayLink::QCvDisplayLink(QObject *parent)
- :QObject(parent),
- m_pendingDisplayLinkEvent(false),
- m_isActive(false)
-{
- // create display link for the main display
- CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink);
- if (m_displayLink) {
- // set the current display of a display link.
- CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay);
-
- // set the renderer output callback function
- CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback, this);
- }
-}
-
-QCvDisplayLink::~QCvDisplayLink()
-{
- if (m_displayLink) {
- CVDisplayLinkStop(m_displayLink);
- CVDisplayLinkRelease(m_displayLink);
- m_displayLink = NULL;
- }
-}
-
-bool QCvDisplayLink::isValid()
-{
- return m_displayLink != 0;
-}
-
-bool QCvDisplayLink::isActive() const
-{
- return m_isActive;
-}
-
-void QCvDisplayLink::start()
-{
- if (m_displayLink && !m_isActive) {
- CVDisplayLinkStart(m_displayLink);
- m_isActive = true;
- }
-}
-
-void QCvDisplayLink::stop()
-{
- if (m_displayLink && m_isActive) {
- CVDisplayLinkStop(m_displayLink);
- m_isActive = false;
- }
-}
-
-void QCvDisplayLink::displayLinkEvent(const CVTimeStamp *ts)
-{
- // This function is called from a
- // thread != gui thread. So we post the event.
- // But we need to make sure that we don't post faster
- // than the event loop can eat:
- m_displayLinkMutex.lock();
- bool pending = m_pendingDisplayLinkEvent;
- m_pendingDisplayLinkEvent = true;
- m_frameTimeStamp = *ts;
- m_displayLinkMutex.unlock();
-
- if (!pending)
- qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
-}
-
-bool QCvDisplayLink::event(QEvent *event)
-{
- switch (event->type()){
- case QEvent::User: {
- m_displayLinkMutex.lock();
- m_pendingDisplayLinkEvent = false;
- CVTimeStamp ts = m_frameTimeStamp;
- m_displayLinkMutex.unlock();
-
- Q_EMIT tick(ts);
-
- return false;
- }
- break;
- default:
- break;
- }
- return QObject::event(event);
-}
-
-#include "moc_qcvdisplaylink.cpp"
-
diff --git a/src/plugins/qt7/qt7.json b/src/plugins/qt7/qt7.json
deleted file mode 100644
index b4cebad99..000000000
--- a/src/plugins/qt7/qt7.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "Keys": ["qt7"],
- "Services": ["org.qt-project.qt.mediaplayer"]
-}
diff --git a/src/plugins/qt7/qt7.pro b/src/plugins/qt7/qt7.pro
deleted file mode 100644
index b23eba40a..000000000
--- a/src/plugins/qt7/qt7.pro
+++ /dev/null
@@ -1,67 +0,0 @@
-# Avoid clash with a variable named `slots' in a Quartz header
-CONFIG += no_keywords
-
-TARGET = qqt7engine
-QT += multimedia-private network
-qtHaveModule(widgets) {
- QT += multimediawidgets-private widgets
-}
-
-PLUGIN_TYPE = mediaservice
-PLUGIN_CLASS_NAME = QT7ServicePlugin
-load(qt_plugin)
-
-!simulator {
-QT += opengl
-}
-
-#DEFINES += QT_DEBUG_QT7
-
-LIBS += -framework AppKit -framework AudioUnit \
- -framework AudioToolbox -framework CoreAudio \
- -framework QuartzCore -framework QTKit
-
-# QUICKTIME_C_API_AVAILABLE is true only on i386
-# so make sure to link QuickTime
-contains(QT_ARCH, i386) {
- LIBS += -framework QuickTime
-}
-
-HEADERS += \
- qt7backend.h \
- qt7videooutput.h \
- qt7serviceplugin.h
-
-OBJECTIVE_SOURCES += \
- qt7backend.mm \
- qt7serviceplugin.mm
-
-!simulator {
- HEADERS += \
- qt7movieviewoutput.h \
- qt7movierenderer.h \
- qt7ciimagevideobuffer.h \
- qcvdisplaylink.h
-
- OBJECTIVE_SOURCES += \
- qt7movieviewoutput.mm \
- qt7movierenderer.mm \
- qt7videooutput.mm \
- qt7ciimagevideobuffer.mm \
- qcvdisplaylink.mm
-
- qtHaveModule(widgets) {
- HEADERS += \
- qt7movieviewrenderer.h \
- qt7movievideowidget.h
-
- OBJECTIVE_SOURCES += \
- qt7movieviewrenderer.mm \
- qt7movievideowidget.mm
- }
-}
-
-include(mediaplayer/mediaplayer.pri)
-
-OTHER_FILES += \
- qt7.json
diff --git a/src/plugins/qt7/qt7backend.h b/src/plugins/qt7/qt7backend.h
deleted file mode 100644
index e2aa2c5d8..000000000
--- a/src/plugins/qt7/qt7backend.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7BACKEND_H
-#define QT7BACKEND_H
-
-#include "qtmultimediadefs.h"
-
-#include <QtCore/QString>
-
-#ifndef Q_OS_SIMULATOR
-#ifndef Q_OS_MAC64
-#define QUICKTIME_C_API_AVAILABLE
-#endif
-#endif // !defined(Q_WS_SIMULATOR)
-
-QT_BEGIN_NAMESPACE
-
-class AutoReleasePool
-{
-private:
- void *pool;
-public:
- AutoReleasePool();
- ~AutoReleasePool();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7ciimagevideobuffer.h b/src/plugins/qt7/qt7ciimagevideobuffer.h
deleted file mode 100644
index 2ad7957c3..000000000
--- a/src/plugins/qt7/qt7ciimagevideobuffer.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7CIIMAGEVIDEOBUFFER_H
-#define QT7CIIMAGEVIDEOBUFFER_H
-
-#include "qt7backend.h"
-#import <QTKit/QTKit.h>
-
-#include <QtCore/qvariant.h>
-#include <qabstractvideobuffer.h>
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_BEGIN_NAMESPACE
-
-class QT7CIImageVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- QT7CIImageVideoBuffer(CIImage *image);
-
- virtual ~QT7CIImageVideoBuffer();
-
- MapMode mapMode() const;
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine);
- void unmap();
- QVariant handle() const;
-
-private:
- CIImage *m_image;
- NSBitmapImageRep *m_buffer;
- MapMode m_mode;
-};
-
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7ciimagevideobuffer.mm b/src/plugins/qt7/qt7ciimagevideobuffer.mm
deleted file mode 100644
index adb1a689d..000000000
--- a/src/plugins/qt7/qt7ciimagevideobuffer.mm
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qt7ciimagevideobuffer.h"
-
-#include <QuartzCore/CIFilter.h>
-#include <QuartzCore/CIVector.h>
-
-QT7CIImageVideoBuffer::QT7CIImageVideoBuffer(CIImage *image)
- : QAbstractVideoBuffer(CoreImageHandle)
- , m_image(image)
- , m_buffer(0)
- , m_mode(NotMapped)
-{
- [m_image retain];
-}
-
-QT7CIImageVideoBuffer::~QT7CIImageVideoBuffer()
-{
- [m_image release];
- [m_buffer release];
-}
-
-QAbstractVideoBuffer::MapMode QT7CIImageVideoBuffer::mapMode() const
-{
- return m_mode;
-}
-
-uchar *QT7CIImageVideoBuffer::map(QAbstractVideoBuffer::MapMode mode, int *numBytes, int *bytesPerLine)
-{
- if (mode == NotMapped || m_mode != NotMapped || !m_image)
- return 0;
-
- if (!m_buffer) {
- //swap R and B channels
- CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix" keysAndValues:
- @"inputImage", m_image,
- @"inputRVector", [CIVector vectorWithX: 0 Y: 0 Z: 1 W: 0],
- @"inputGVector", [CIVector vectorWithX: 0 Y: 1 Z: 0 W: 0],
- @"inputBVector", [CIVector vectorWithX: 1 Y: 0 Z: 0 W: 0],
- @"inputAVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 1],
- @"inputBiasVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 0],
- nil];
- CIImage *img = [colorSwapFilter valueForKey: @"outputImage"];
-
- m_buffer = [[NSBitmapImageRep alloc] initWithCIImage:img];
- }
-
- if (numBytes)
- *numBytes = [m_buffer bytesPerPlane];
-
- if (bytesPerLine)
- *bytesPerLine = [m_buffer bytesPerRow];
-
- m_mode = mode;
-
- return [m_buffer bitmapData];
-}
-
-void QT7CIImageVideoBuffer::unmap()
-{
- m_mode = NotMapped;
-}
-
-QVariant QT7CIImageVideoBuffer::handle() const
-{
- return QVariant::fromValue<void*>(m_image);
-}
-
diff --git a/src/plugins/qt7/qt7movierenderer.h b/src/plugins/qt7/qt7movierenderer.h
deleted file mode 100644
index 8abbaf847..000000000
--- a/src/plugins/qt7/qt7movierenderer.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIERENDERER_H
-#define QT7MOVIERENDERER_H
-
-#include "qt7backend.h"
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qvideorenderercontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-
-#include <QuartzCore/CVOpenGLTexture.h>
-#include <QuickTime/QuickTime.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGLContext;
-
-class QCvDisplayLink;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-class QT7MovieRenderer : public QT7VideoRendererControl
-{
-Q_OBJECT
-public:
- QT7MovieRenderer(QObject *parent = 0);
- virtual ~QT7MovieRenderer();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- QAbstractVideoSurface *surface() const;
- void setSurface(QAbstractVideoSurface *surface);
-
- QSize nativeSize() const;
-
-private Q_SLOTS:
- void updateVideoFrame(const CVTimeStamp &ts);
-
-private:
- void setupVideoOutput();
- bool createPixelBufferVisualContext();
- bool createGLVisualContext();
-
- void *m_movie;
-
- QMutex m_mutex;
-
- QCvDisplayLink *m_displayLink;
-#ifdef QUICKTIME_C_API_AVAILABLE
- QTVisualContextRef m_visualContext;
- bool m_usingGLContext;
- const QGLContext *m_currentGLContext;
- QSize m_pixelBufferContextGeometry;
-#endif
- QAbstractVideoSurface *m_surface;
- QSize m_nativeSize;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movierenderer.mm b/src/plugins/qt7/qt7movierenderer.mm
deleted file mode 100644
index 9110b821e..000000000
--- a/src/plugins/qt7/qt7movierenderer.mm
+++ /dev/null
@@ -1,481 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <QTKit/QTKit.h>
-
-#include "qt7backend.h"
-
-#include "qt7playercontrol.h"
-#include "qt7movierenderer.h"
-#include "qt7playersession.h"
-#include "qt7ciimagevideobuffer.h"
-#include "qcvdisplaylink.h"
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <qabstractvideobuffer.h>
-#include <qabstractvideosurface.h>
-#include <qvideosurfaceformat.h>
-
-#include <QtOpenGL/QGLContext>
-
-QT_USE_NAMESPACE
-
-//#define USE_MAIN_MONITOR_COLOR_SPACE 1
-
-class CVGLTextureVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- CVGLTextureVideoBuffer(CVOpenGLTextureRef buffer)
- : QAbstractVideoBuffer(GLTextureHandle)
- , m_buffer(buffer)
- , m_mode(NotMapped)
- {
- CVOpenGLTextureRetain(m_buffer);
- }
-
- virtual ~CVGLTextureVideoBuffer()
- {
- CVOpenGLTextureRelease(m_buffer);
- }
-
- QVariant handle() const
- {
- GLuint id = CVOpenGLTextureGetName(m_buffer);
- return QVariant(int(id));
- }
-
- MapMode mapMode() const { return m_mode; }
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
- if (numBytes)
- *numBytes = 0;
-
- if (bytesPerLine)
- *bytesPerLine = 0;
-
- m_mode = mode;
- return 0;
- }
-
- void unmap() { m_mode = NotMapped; }
-
-private:
- CVOpenGLTextureRef m_buffer;
- MapMode m_mode;
-};
-
-
-class CVPixelBufferVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- CVPixelBufferVideoBuffer(CVPixelBufferRef buffer)
- : QAbstractVideoBuffer(NoHandle)
- , m_buffer(buffer)
- , m_mode(NotMapped)
- {
- CVPixelBufferRetain(m_buffer);
- }
-
- virtual ~CVPixelBufferVideoBuffer()
- {
- CVPixelBufferRelease(m_buffer);
- }
-
- MapMode mapMode() const { return m_mode; }
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
- if (mode != NotMapped && m_mode == NotMapped) {
- CVPixelBufferLockBaseAddress(m_buffer, 0);
-
- if (numBytes)
- *numBytes = CVPixelBufferGetDataSize(m_buffer);
-
- if (bytesPerLine)
- *bytesPerLine = CVPixelBufferGetBytesPerRow(m_buffer);
-
- m_mode = mode;
-
- return (uchar*)CVPixelBufferGetBaseAddress(m_buffer);
- } else {
- return 0;
- }
- }
-
- void unmap()
- {
- if (m_mode != NotMapped) {
- m_mode = NotMapped;
- CVPixelBufferUnlockBaseAddress(m_buffer, 0);
- }
- }
-
-private:
- CVPixelBufferRef m_buffer;
- MapMode m_mode;
-};
-
-
-
-QT7MovieRenderer::QT7MovieRenderer(QObject *parent)
- :QT7VideoRendererControl(parent),
- m_movie(0),
-#ifdef QUICKTIME_C_API_AVAILABLE
- m_visualContext(0),
- m_usingGLContext(false),
- m_currentGLContext(0),
-#endif
- m_surface(0)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieRenderer";
-#endif
- m_displayLink = new QCvDisplayLink(this);
- connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp)));
-}
-
-
-bool QT7MovieRenderer::createGLVisualContext()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- AutoReleasePool pool;
- CGLContextObj cglContext = CGLGetCurrentContext();
- NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
- CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
-
- OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault, cglContext,
- cglPixelFormat, NULL, &m_visualContext);
- if (err != noErr)
- qWarning() << "Could not create visual context (OpenGL)";
-
- return (err == noErr);
-#endif // QUICKTIME_C_API_AVAILABLE
-
- return false;
-}
-
-#ifdef QUICKTIME_C_API_AVAILABLE
-static bool DictionarySetValue(CFMutableDictionaryRef dict, CFStringRef key, SInt32 value)
-{
- CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- if (number) {
- CFDictionarySetValue( dict, key, number );
- CFRelease( number );
- return true;
- }
- return false;
-}
-#endif // QUICKTIME_C_API_AVAILABLE
-
-bool QT7MovieRenderer::createPixelBufferVisualContext()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- if (m_visualContext) {
- QTVisualContextRelease(m_visualContext);
- m_visualContext = 0;
- }
-
- m_pixelBufferContextGeometry = m_nativeSize;
-
- CFMutableDictionaryRef pixelBufferOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- //DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32ARGBPixelFormat );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferWidthKey, m_nativeSize.width() );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferHeightKey, m_nativeSize.height() );
- DictionarySetValue(pixelBufferOptions, kCVPixelBufferBytesPerRowAlignmentKey, 16);
- //CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue);
-
- CFMutableDictionaryRef visualContextOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(visualContextOptions, kQTVisualContextPixelBufferAttributesKey, pixelBufferOptions);
-
- CGColorSpaceRef colorSpace = NULL;
-
-#if USE_MAIN_MONITOR_COLOR_SPACE
- CMProfileRef sysprof = NULL;
-
- // Get the Systems Profile for the main display
- if (CMGetSystemProfile(&sysprof) == noErr) {
- // Create a colorspace with the systems profile
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(sysprof);
- CMCloseProfile(sysprof);
- }
-#endif
-
- if (!colorSpace)
- colorSpace = CGColorSpaceCreateDeviceRGB();
-
- CFDictionarySetValue(visualContextOptions, kQTVisualContextOutputColorSpaceKey, colorSpace);
-
- OSStatus err = QTPixelBufferContextCreate(kCFAllocatorDefault,
- visualContextOptions,
- &m_visualContext);
- CFRelease(pixelBufferOptions);
- CFRelease(visualContextOptions);
-
- if (err != noErr) {
- qWarning() << "Could not create visual context (PixelBuffer)";
- return false;
- }
-
- return true;
-#endif // QUICKTIME_C_API_AVAILABLE
-
- return false;
-}
-
-
-QT7MovieRenderer::~QT7MovieRenderer()
-{
- m_displayLink->stop();
-}
-
-void QT7MovieRenderer::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieRenderer::setupVideoOutput" << m_movie;
-#endif
-
- if (m_movie == 0 || m_surface == 0) {
- m_displayLink->stop();
- return;
- }
-
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
- m_nativeSize = QSize(size.width, size.height);
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- bool usedGLContext = m_usingGLContext;
-
- if (!m_nativeSize.isEmpty()) {
-
- bool glSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty();
-
- //Try rendering using opengl textures first:
- if (glSupported) {
- QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32, QAbstractVideoBuffer::GLTextureHandle);
-
- if (m_surface->isActive())
- m_surface->stop();
-
- if (!m_surface->start(format)) {
- qWarning() << "failed to start video surface" << m_surface->error();
- qWarning() << "Surface format:" << format;
- glSupported = false;
- } else {
- m_usingGLContext = true;
- }
-
- }
-
- if (!glSupported) {
- m_usingGLContext = false;
- QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32);
-
- if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Surface format was changed, stop the surface.";
-#endif
- m_surface->stop();
- }
-
- if (!m_surface->isActive()) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Starting the surface with format" << format;
-#endif
- if (!m_surface->start(format)) {
- qWarning() << "failed to start video surface" << m_surface->error();
- qWarning() << "Surface format:" << format;
- }
- }
- }
- }
-
-
- if (m_visualContext) {
- //check if the visual context still can be reused
- if (usedGLContext != m_usingGLContext ||
- (m_usingGLContext && (m_currentGLContext != QGLContext::currentContext())) ||
- (!m_usingGLContext && (m_pixelBufferContextGeometry != m_nativeSize))) {
- QTVisualContextRelease(m_visualContext);
- m_pixelBufferContextGeometry = QSize();
- m_visualContext = 0;
- }
- }
-
- if (!m_nativeSize.isEmpty()) {
- if (!m_visualContext) {
- if (m_usingGLContext) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Building OpenGL visual context" << m_nativeSize;
-#endif
- m_currentGLContext = QGLContext::currentContext();
- if (!createGLVisualContext()) {
- qWarning() << "QT7MovieRenderer: failed to create visual context";
- return;
- }
- } else {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Building Pixel Buffer visual context" << m_nativeSize;
-#endif
- if (!createPixelBufferVisualContext()) {
- qWarning() << "QT7MovieRenderer: failed to create visual context";
- return;
- }
- }
- }
-
- // targets a Movie to render into a visual context
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext);
-
- m_displayLink->start();
- }
-#endif
-
-}
-
-void QT7MovieRenderer::setMovie(void *movie)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieRenderer::setMovie" << movie;
-#endif
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- QMutexLocker locker(&m_mutex);
-
- if (m_movie != movie) {
- if (m_movie) {
- //ensure the old movie doesn't hold the visual context, otherwise it can't be reused
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil);
- [(QTMovie*)m_movie release];
- }
-
- m_movie = movie;
- [(QTMovie*)m_movie retain];
-
- setupVideoOutput();
- }
-#else
- Q_UNUSED(movie);
-#endif
-}
-
-void QT7MovieRenderer::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- setupVideoOutput();
- }
-}
-
-QAbstractVideoSurface *QT7MovieRenderer::surface() const
-{
- return m_surface;
-}
-
-void QT7MovieRenderer::setSurface(QAbstractVideoSurface *surface)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "Set video surface" << surface;
-#endif
-
- if (surface == m_surface)
- return;
-
- QMutexLocker locker(&m_mutex);
-
- if (m_surface && m_surface->isActive())
- m_surface->stop();
-
- m_surface = surface;
- setupVideoOutput();
-}
-
-
-QSize QT7MovieRenderer::nativeSize() const
-{
- return m_nativeSize;
-}
-
-void QT7MovieRenderer::updateVideoFrame(const CVTimeStamp &ts)
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
-
- QMutexLocker locker(&m_mutex);
-
- if (m_surface && m_surface->isActive() &&
- m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) {
-
- CVImageBufferRef imageBuffer = NULL;
-
- OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &imageBuffer);
-
- if (status == noErr && imageBuffer) {
- QAbstractVideoBuffer *buffer = 0;
-
- if (m_usingGLContext) {
- buffer = new QT7CIImageVideoBuffer([CIImage imageWithCVImageBuffer:imageBuffer]);
- CVOpenGLTextureRelease((CVOpenGLTextureRef)imageBuffer);
- } else {
- buffer = new CVPixelBufferVideoBuffer((CVPixelBufferRef)imageBuffer);
- //buffer = new QT7CIImageVideoBuffer( [CIImage imageWithCVImageBuffer:imageBuffer] );
- CVPixelBufferRelease((CVPixelBufferRef)imageBuffer);
- }
-
- QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_RGB32);
- m_surface->present(frame);
- QTVisualContextTask(m_visualContext);
- }
- }
-#else
- Q_UNUSED(ts);
-#endif
-}
-
-#include "moc_qt7movierenderer.cpp"
diff --git a/src/plugins/qt7/qt7movievideowidget.h b/src/plugins/qt7/qt7movievideowidget.h
deleted file mode 100644
index 655037698..000000000
--- a/src/plugins/qt7/qt7movievideowidget.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIEVIDEOWIDGET_H
-#define QT7MOVIEVIDEOWIDGET_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qvideowindowcontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-
-#include <QuartzCore/CVOpenGLTexture.h>
-#include <QuickTime/QuickTime.h>
-
-class GLVideoWidget;
-
-QT_BEGIN_NAMESPACE
-
-class QCvDisplayLink;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-class QT7MovieVideoWidget : public QT7VideoWidgetControl
-{
-Q_OBJECT
-public:
- QT7MovieVideoWidget(QObject *parent = 0);
- virtual ~QT7MovieVideoWidget();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- QWidget *videoWidget();
-
- bool isFullScreen() const;
- void setFullScreen(bool fullScreen);
-
- QSize nativeSize() const;
-
- Qt::AspectRatioMode aspectRatioMode() const;
- void setAspectRatioMode(Qt::AspectRatioMode mode);
-
- int brightness() const;
- void setBrightness(int brightness);
-
- int contrast() const;
- void setContrast(int contrast);
-
- int hue() const;
- void setHue(int hue);
-
- int saturation() const;
- void setSaturation(int saturation);
-
-private Q_SLOTS:
- void updateVideoFrame(const CVTimeStamp &ts);
-
-private:
- void setupVideoOutput();
- bool createVisualContext();
-
- void updateColors();
-
- void *m_movie;
- GLVideoWidget *m_videoWidget;
-
- QCvDisplayLink *m_displayLink;
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- QTVisualContextRef m_visualContext;
-#endif
-
- bool m_fullscreen;
- QSize m_nativeSize;
- Qt::AspectRatioMode m_aspectRatioMode;
- int m_brightness;
- int m_contrast;
- int m_hue;
- int m_saturation;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movievideowidget.mm b/src/plugins/qt7/qt7movievideowidget.mm
deleted file mode 100644
index ec9367bcc..000000000
--- a/src/plugins/qt7/qt7movievideowidget.mm
+++ /dev/null
@@ -1,437 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qt7backend.h"
-
-#import <QTKit/QTDataReference.h>
-#import <QTKit/QTMovie.h>
-#import <QTKit/QTMovieView.h>
-#import <QTKit/QTMovieLayer.h>
-#import <AppKit/NSImage.h>
-#import <OpenGL/glu.h>
-
-
-#include "qt7playercontrol.h"
-#include "qt7movievideowidget.h"
-#include "qt7playersession.h"
-#include "qcvdisplaylink.h"
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <QGLWidget>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#import <QuartzCore/QuartzCore.h>
-
-#include "math.h"
-
-QT_USE_NAMESPACE
-
-class GLVideoWidget : public QGLWidget
-{
-public:
-
- GLVideoWidget(QWidget *parent, const QGLFormat &format)
- : QGLWidget(format, parent),
- m_texRef(0),
- m_nativeSize(640,480),
- m_aspectRatioMode(Qt::KeepAspectRatio)
- {
- setAutoFillBackground(false);
- }
-
- void initializeGL()
- {
- QColor bgColor = palette().color(QPalette::Background);
- glClearColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF(), bgColor.alphaF());
- }
-
- void resizeGL(int w, int h)
- {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glViewport(0, 0, GLsizei(w), GLsizei(h));
- gluOrtho2D(0, GLsizei(w), 0, GLsizei(h));
- updateGL();
- }
-
- void paintGL()
- {
- glClear(GL_COLOR_BUFFER_BIT);
- if (!m_texRef)
- return;
-
- glPushMatrix();
- glDisable(GL_CULL_FACE);
- GLenum target = CVOpenGLTextureGetTarget(m_texRef);
- glEnable(target);
-
- glBindTexture(target, CVOpenGLTextureGetName(m_texRef));
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- GLfloat lowerLeft[2], lowerRight[2], upperRight[2], upperLeft[2];
- CVOpenGLTextureGetCleanTexCoords(m_texRef, lowerLeft, lowerRight, upperRight, upperLeft);
-
- glBegin(GL_QUADS);
- QRect rect = displayRect();
- glTexCoord2f(lowerLeft[0], lowerLeft[1]);
- glVertex2i(rect.topLeft().x(), rect.topLeft().y());
- glTexCoord2f(lowerRight[0], lowerRight[1]);
- glVertex2i(rect.topRight().x() + 1, rect.topRight().y());
- glTexCoord2f(upperRight[0], upperRight[1]);
- glVertex2i(rect.bottomRight().x() + 1, rect.bottomRight().y() + 1);
- glTexCoord2f(upperLeft[0], upperLeft[1]);
- glVertex2i(rect.bottomLeft().x(), rect.bottomLeft().y() + 1);
- glEnd();
- glPopMatrix();
- }
-
- void setCVTexture(CVOpenGLTextureRef texRef)
- {
- if (m_texRef)
- CVOpenGLTextureRelease(m_texRef);
-
- m_texRef = texRef;
-
- if (m_texRef)
- CVOpenGLTextureRetain(m_texRef);
-
- if (isVisible()) {
- makeCurrent();
- paintGL();
- swapBuffers();
- }
- }
-
- QSize sizeHint() const
- {
- return m_nativeSize;
- }
-
- void setNativeSize(const QSize &size)
- {
- m_nativeSize = size;
- }
-
- void setAspectRatioMode(Qt::AspectRatioMode mode)
- {
- if (m_aspectRatioMode != mode) {
- m_aspectRatioMode = mode;
- update();
- }
- }
-
-private:
- QRect displayRect() const
- {
- QRect displayRect = rect();
-
- if (m_aspectRatioMode == Qt::KeepAspectRatio) {
- QSize size = m_nativeSize;
- size.scale(displayRect.size(), Qt::KeepAspectRatio);
-
- displayRect = QRect(QPoint(0, 0), size);
- displayRect.moveCenter(rect().center());
- }
- return displayRect;
- }
-
- CVOpenGLTextureRef m_texRef;
- QSize m_nativeSize;
- Qt::AspectRatioMode m_aspectRatioMode;
-};
-
-QT7MovieVideoWidget::QT7MovieVideoWidget(QObject *parent)
- :QT7VideoWidgetControl(parent),
- m_movie(0),
- m_videoWidget(0),
- m_fullscreen(false),
- m_aspectRatioMode(Qt::KeepAspectRatio),
- m_brightness(0),
- m_contrast(0),
- m_hue(0),
- m_saturation(0)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieVideoWidget";
-#endif
-
- QGLFormat format = QGLFormat::defaultFormat();
- format.setSwapInterval(1); // Vertical sync (avoid tearing)
- m_videoWidget = new GLVideoWidget(0, format);
-
- m_displayLink = new QCvDisplayLink(this);
-
- connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp)));
-
- if (!createVisualContext()) {
- qWarning() << "QT7MovieVideoWidget: failed to create visual context";
- }
-}
-
-bool QT7MovieVideoWidget::createVisualContext()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- m_videoWidget->makeCurrent();
-
- AutoReleasePool pool;
- CGLContextObj cglContext = CGLGetCurrentContext();
- NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
- CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
-
- CFTypeRef keys[] = { kQTVisualContextOutputColorSpaceKey };
- CGColorSpaceRef colorSpace = NULL;
- CMProfileRef sysprof = NULL;
-
- // Get the Systems Profile for the main display
- if (CMGetSystemProfile(&sysprof) == noErr) {
- // Create a colorspace with the systems profile
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(sysprof);
- CMCloseProfile(sysprof);
- }
-
- if (!colorSpace)
- colorSpace = CGColorSpaceCreateDeviceRGB();
-
- CFDictionaryRef textureContextAttributes = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **)keys,
- (const void **)&colorSpace, 1,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault,
- cglContext,
- cglPixelFormat,
- textureContextAttributes,
- &m_visualContext);
- if (err != noErr)
- qWarning() << "Could not create visual context (OpenGL)";
-
-
- return (err == noErr);
-#endif // QUICKTIME_C_API_AVAILABLE
-
- return false;
-}
-
-QT7MovieVideoWidget::~QT7MovieVideoWidget()
-{
- m_displayLink->stop();
- [(QTMovie*)m_movie release];
- delete m_videoWidget;
-}
-
-QWidget *QT7MovieVideoWidget::videoWidget()
-{
- return m_videoWidget;
-}
-
-void QT7MovieVideoWidget::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieVideoWidget::setupVideoOutput" << m_movie;
-#endif
-
- if (m_movie == 0) {
- m_displayLink->stop();
- return;
- }
-
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
- m_nativeSize = QSize(size.width, size.height);
- m_videoWidget->setNativeSize(m_nativeSize);
-
-#ifdef QUICKTIME_C_API_AVAILABLE
- // targets a Movie to render into a visual context
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext);
-#endif
-
- m_displayLink->start();
-}
-
-void QT7MovieVideoWidget::setMovie(void *movie)
-{
- if (m_movie == movie)
- return;
-
- if (m_movie) {
-#ifdef QUICKTIME_C_API_AVAILABLE
- SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil);
-#endif
- [(QTMovie*)m_movie release];
- }
-
- m_movie = movie;
- [(QTMovie*)m_movie retain];
-
- setupVideoOutput();
-}
-
-void QT7MovieVideoWidget::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- setupVideoOutput();
- }
-}
-
-bool QT7MovieVideoWidget::isFullScreen() const
-{
- return m_fullscreen;
-}
-
-void QT7MovieVideoWidget::setFullScreen(bool fullScreen)
-{
- m_fullscreen = fullScreen;
-}
-
-QSize QT7MovieVideoWidget::nativeSize() const
-{
- return m_nativeSize;
-}
-
-Qt::AspectRatioMode QT7MovieVideoWidget::aspectRatioMode() const
-{
- return m_aspectRatioMode;
-}
-
-void QT7MovieVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_aspectRatioMode = mode;
- m_videoWidget->setAspectRatioMode(mode);
-}
-
-int QT7MovieVideoWidget::brightness() const
-{
- return m_brightness;
-}
-
-void QT7MovieVideoWidget::setBrightness(int brightness)
-{
- m_brightness = brightness;
- updateColors();
-}
-
-int QT7MovieVideoWidget::contrast() const
-{
- return m_contrast;
-}
-
-void QT7MovieVideoWidget::setContrast(int contrast)
-{
- m_contrast = contrast;
- updateColors();
-}
-
-int QT7MovieVideoWidget::hue() const
-{
- return m_hue;
-}
-
-void QT7MovieVideoWidget::setHue(int hue)
-{
- m_hue = hue;
- updateColors();
-}
-
-int QT7MovieVideoWidget::saturation() const
-{
- return m_saturation;
-}
-
-void QT7MovieVideoWidget::setSaturation(int saturation)
-{
- m_saturation = saturation;
- updateColors();
-}
-
-void QT7MovieVideoWidget::updateColors()
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- if (m_movie) {
- QTMovie *movie = (QTMovie*)m_movie;
-
- Float32 value;
- value = m_brightness/100.0;
- SetMovieVisualBrightness([movie quickTimeMovie], value, 0);
- value = pow(2, m_contrast/50.0);
- SetMovieVisualContrast([movie quickTimeMovie], value, 0);
- value = m_hue/100.0;
- SetMovieVisualHue([movie quickTimeMovie], value, 0);
- value = 1.0+m_saturation/100.0;
- SetMovieVisualSaturation([movie quickTimeMovie], value, 0);
- }
-#endif
-}
-
-void QT7MovieVideoWidget::updateVideoFrame(const CVTimeStamp &ts)
-{
-#ifdef QUICKTIME_C_API_AVAILABLE
- AutoReleasePool pool;
- // check for new frame
- if (m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) {
- CVOpenGLTextureRef currentFrame = NULL;
-
- // get a "frame" (image buffer) from the Visual Context, indexed by the provided time
- OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &currentFrame);
-
- // the above call may produce a null frame so check for this first
- // if we have a frame, then draw it
- if (status == noErr && currentFrame) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "render video frame";
-#endif
- m_videoWidget->setCVTexture(currentFrame);
- CVOpenGLTextureRelease(currentFrame);
- }
- QTVisualContextTask(m_visualContext);
- }
-#else
- Q_UNUSED(ts);
-#endif
-}
-
-#include "moc_qt7movievideowidget.cpp"
diff --git a/src/plugins/qt7/qt7movieviewoutput.h b/src/plugins/qt7/qt7movieviewoutput.h
deleted file mode 100644
index 874de1a09..000000000
--- a/src/plugins/qt7/qt7movieviewoutput.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIEVIEWOUTPUT_H
-#define QT7MOVIEVIEWOUTPUT_H
-
-#include <QtCore/qobject.h>
-
-#include <qvideowindowcontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-class QT7PlayerService;
-
-class QT7MovieViewOutput : public QT7VideoWindowControl
-{
-public:
- QT7MovieViewOutput(QObject *parent = 0);
- ~QT7MovieViewOutput();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- WId winId() const;
- void setWinId(WId id);
-
- QRect displayRect() const;
- void setDisplayRect(const QRect &rect);
-
- bool isFullScreen() const;
- void setFullScreen(bool fullScreen);
-
- void repaint();
-
- QSize nativeSize() const;
-
- Qt::AspectRatioMode aspectRatioMode() const;
- void setAspectRatioMode(Qt::AspectRatioMode mode);
-
- int brightness() const;
- void setBrightness(int brightness);
-
- int contrast() const;
- void setContrast(int contrast);
-
- int hue() const;
- void setHue(int hue);
-
- int saturation() const;
- void setSaturation(int saturation);
-
-private:
- void setupVideoOutput();
-
- void *m_movie;
- void *m_movieView;
- bool m_layouted;
-
- WId m_winId;
- QRect m_displayRect;
- bool m_fullscreen;
- QSize m_nativeSize;
- Qt::AspectRatioMode m_aspectRatioMode;
- int m_brightness;
- int m_contrast;
- int m_hue;
- int m_saturation;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movieviewoutput.mm b/src/plugins/qt7/qt7movieviewoutput.mm
deleted file mode 100644
index 4fcf01d39..000000000
--- a/src/plugins/qt7/qt7movieviewoutput.mm
+++ /dev/null
@@ -1,339 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <QTKit/QTKit.h>
-
-#include "qt7backend.h"
-
-#include "qt7playercontrol.h"
-#include "qt7movieviewoutput.h"
-#include "qt7playersession.h"
-#include <QtCore/qdebug.h>
-
-#include <QuartzCore/CIFilter.h>
-#include <QuartzCore/CIVector.h>
-
-QT_USE_NAMESPACE
-
-#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];}
-
-@interface TransparentQTMovieView : QTMovieView
-{
-@private
- QRect *m_drawRect;
- qreal m_brightness, m_contrast, m_saturation, m_hue;
-}
-
-- (TransparentQTMovieView *) init;
-- (void) setDrawRect:(QRect &)rect;
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img;
-- (void) setContrast:(qreal) contrast;
-@end
-
-@implementation TransparentQTMovieView
-
-- (TransparentQTMovieView *) init
-{
- self = [super initWithFrame:NSZeroRect];
- if (self) {
- [self setControllerVisible:NO];
- [self setContrast:1.0];
- [self setDelegate:self];
- }
- return self;
-}
-
-- (void) dealloc
-{
- [super dealloc];
-}
-
-- (void) setContrast:(qreal) contrast
-{
- m_hue = 0.0;
- m_brightness = 0.0;
- m_contrast = contrast;
- m_saturation = 1.0;
-}
-
-
-- (void) setDrawRect:(QRect &)rect
-{
- *m_drawRect = rect;
-
- NSRect nsrect;
- nsrect.origin.x = m_drawRect->x();
- nsrect.origin.y = m_drawRect->y();
- nsrect.size.width = m_drawRect->width();
- nsrect.size.height = m_drawRect->height();
- [self setFrame:nsrect];
-}
-
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img
-{
- // This method is called from QTMovieView just
- // before the image will be drawn.
- Q_UNUSED(view);
-
- if ( !qFuzzyCompare(m_brightness, 0.0) ||
- !qFuzzyCompare(m_contrast, 1.0) ||
- !qFuzzyCompare(m_saturation, 1.0)){
- CIFilter *colorFilter = [CIFilter filterWithName:@"CIColorControls"];
- [colorFilter setValue:[NSNumber numberWithFloat:m_brightness] forKey:@"inputBrightness"];
- [colorFilter setValue:[NSNumber numberWithFloat:(m_contrast < 1) ? m_contrast : 1 + ((m_contrast-1)*3)] forKey:@"inputContrast"];
- [colorFilter setValue:[NSNumber numberWithFloat:m_saturation] forKey:@"inputSaturation"];
- [colorFilter setValue:img forKey:@"inputImage"];
- img = [colorFilter valueForKey:@"outputImage"];
- }
-
- /*if (m_hue){
- CIFilter *colorFilter = [CIFilter filterWithName:@"CIHueAdjust"];
- [colorFilter setValue:[NSNumber numberWithFloat:(m_hue * 3.14)] forKey:@"inputAngle"];
- [colorFilter setValue:img forKey:@"inputImage"];
- img = [colorFilter valueForKey:@"outputImage"];
- }*/
-
- return img;
-}
-
-
-VIDEO_TRANSPARENT(mouseDown);
-VIDEO_TRANSPARENT(mouseDragged);
-VIDEO_TRANSPARENT(mouseUp);
-VIDEO_TRANSPARENT(mouseMoved);
-VIDEO_TRANSPARENT(mouseEntered);
-VIDEO_TRANSPARENT(mouseExited);
-VIDEO_TRANSPARENT(rightMouseDown);
-VIDEO_TRANSPARENT(rightMouseDragged);
-VIDEO_TRANSPARENT(rightMouseUp);
-VIDEO_TRANSPARENT(otherMouseDown);
-VIDEO_TRANSPARENT(otherMouseDragged);
-VIDEO_TRANSPARENT(otherMouseUp);
-VIDEO_TRANSPARENT(keyDown);
-VIDEO_TRANSPARENT(keyUp);
-VIDEO_TRANSPARENT(scrollWheel)
-
-@end
-
-
-QT7MovieViewOutput::QT7MovieViewOutput(QObject *parent)
- :QT7VideoWindowControl(parent),
- m_movie(0),
- m_movieView(0),
- m_layouted(false),
- m_winId(0),
- m_fullscreen(false),
- m_aspectRatioMode(Qt::KeepAspectRatio),
- m_brightness(0),
- m_contrast(0),
- m_hue(0),
- m_saturation(0)
-{
-}
-
-QT7MovieViewOutput::~QT7MovieViewOutput()
-{
- [(QTMovieView*)m_movieView release];
- [(QTMovie*)m_movie release];
-}
-
-void QT7MovieViewOutput::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieViewOutput::setupVideoOutput" << m_movie << m_winId;
-#endif
- if (m_movie == 0 || m_winId <= 0)
- return;
-
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
- m_nativeSize = QSize(size.width, size.height);
-
- if (!m_movieView)
- m_movieView = [[TransparentQTMovieView alloc] init];
-
- [(QTMovieView*)m_movieView setControllerVisible:NO];
- [(QTMovieView*)m_movieView setMovie:(QTMovie*)m_movie];
-
- [(NSView *)m_winId addSubview:(QTMovieView*)m_movieView];
- m_layouted = true;
-
- setDisplayRect(m_displayRect);
-}
-
-void QT7MovieViewOutput::setMovie(void *movie)
-{
- if (m_movie != movie) {
- if (m_movie) {
- if (m_movieView)
- [(QTMovieView*)m_movieView setMovie:nil];
-
- [(QTMovie*)m_movie release];
- }
-
- m_movie = movie;
-
- if (m_movie)
- [(QTMovie*)m_movie retain];
-
- setupVideoOutput();
- }
-}
-
-void QT7MovieViewOutput::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- Q_EMIT nativeSizeChanged();
- }
-}
-
-WId QT7MovieViewOutput::winId() const
-{
- return m_winId;
-}
-
-void QT7MovieViewOutput::setWinId(WId id)
-{
- if (m_winId != id) {
- if (m_movieView && m_layouted) {
- [(QTMovieView*)m_movieView removeFromSuperview];
- m_layouted = false;
- }
-
- m_winId = id;
- setupVideoOutput();
- }
-}
-
-QRect QT7MovieViewOutput::displayRect() const
-{
- return m_displayRect;
-}
-
-void QT7MovieViewOutput::setDisplayRect(const QRect &rect)
-{
- m_displayRect = rect;
-
- if (m_movieView) {
- AutoReleasePool pool;
- [(QTMovieView*)m_movieView setPreservesAspectRatio:(m_aspectRatioMode == Qt::KeepAspectRatio ? YES : NO)];
- [(QTMovieView*)m_movieView setFrame:NSMakeRect(m_displayRect.x(),
- m_displayRect.y(),
- m_displayRect.width(),
- m_displayRect.height())];
- }
-
-}
-
-bool QT7MovieViewOutput::isFullScreen() const
-{
- return m_fullscreen;
-}
-
-void QT7MovieViewOutput::setFullScreen(bool fullScreen)
-{
- m_fullscreen = fullScreen;
- setDisplayRect(m_displayRect);
-}
-
-void QT7MovieViewOutput::repaint()
-{
-}
-
-QSize QT7MovieViewOutput::nativeSize() const
-{
- return m_nativeSize;
-}
-
-Qt::AspectRatioMode QT7MovieViewOutput::aspectRatioMode() const
-{
- return m_aspectRatioMode;
-}
-
-void QT7MovieViewOutput::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_aspectRatioMode = mode;
- setDisplayRect(m_displayRect);
-}
-
-int QT7MovieViewOutput::brightness() const
-{
- return m_brightness;
-}
-
-void QT7MovieViewOutput::setBrightness(int brightness)
-{
- m_brightness = brightness;
-}
-
-int QT7MovieViewOutput::contrast() const
-{
- return m_contrast;
-}
-
-void QT7MovieViewOutput::setContrast(int contrast)
-{
- m_contrast = contrast;
- [(TransparentQTMovieView*)m_movieView setContrast:(contrast/100.0+1.0)];
-}
-
-int QT7MovieViewOutput::hue() const
-{
- return m_hue;
-}
-
-void QT7MovieViewOutput::setHue(int hue)
-{
- m_hue = hue;
-}
-
-int QT7MovieViewOutput::saturation() const
-{
- return m_saturation;
-}
-
-void QT7MovieViewOutput::setSaturation(int saturation)
-{
- m_saturation = saturation;
-}
-
diff --git a/src/plugins/qt7/qt7movieviewrenderer.h b/src/plugins/qt7/qt7movieviewrenderer.h
deleted file mode 100644
index 2416fe7b3..000000000
--- a/src/plugins/qt7/qt7movieviewrenderer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7MOVIEVIEWRENDERER_H
-#define QT7MOVIEVIEWRENDERER_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-
-#include <qvideowindowcontrol.h>
-#include <qmediaplayer.h>
-
-#include "qt7videooutput.h"
-#include <qvideoframe.h>
-
-#include <QuartzCore/CIContext.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVideoFrame;
-
-class QT7PlayerSession;
-class QT7PlayerService;
-class QGLWidget;
-class QGLFramebufferObject;
-class QWindow;
-class QOpenGLContext;
-
-class QT7MovieViewRenderer : public QT7VideoRendererControl
-{
-public:
- QT7MovieViewRenderer(QObject *parent = 0);
- ~QT7MovieViewRenderer();
-
- void setMovie(void *movie);
- void updateNaturalSize(const QSize &newSize);
-
- QAbstractVideoSurface *surface() const;
- void setSurface(QAbstractVideoSurface *surface);
-
- void renderFrame(const QVideoFrame &);
-
-protected:
- bool event(QEvent *event);
-
-private:
- void setupVideoOutput();
- QVideoFrame convertCIImageToGLTexture(const QVideoFrame &frame);
-
- void *m_movie;
- void *m_movieView;
- QSize m_nativeSize;
- QAbstractVideoSurface *m_surface;
- QVideoFrame m_currentFrame;
- QWindow *m_window;
- QOpenGLContext *m_context;
- QGLFramebufferObject *m_fbo;
- CIContext *m_ciContext;
-
- bool m_pendingRenderEvent;
- QMutex m_mutex;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/qt7/qt7movieviewrenderer.mm b/src/plugins/qt7/qt7movieviewrenderer.mm
deleted file mode 100644
index a59031577..000000000
--- a/src/plugins/qt7/qt7movieviewrenderer.mm
+++ /dev/null
@@ -1,509 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <QTKit/QTKit.h>
-
-#include "qt7backend.h"
-
-#include "qt7playercontrol.h"
-#include "qt7movieviewrenderer.h"
-#include "qt7playersession.h"
-#include "qt7ciimagevideobuffer.h"
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtGui/qwindow.h>
-#include <QtGui/qopenglcontext.h>
-#include <QtOpenGL/qgl.h>
-#include <QtOpenGL/qglframebufferobject.h>
-
-#include <QtCore/qreadwritelock.h>
-
-#include <qabstractvideobuffer.h>
-#include <qabstractvideosurface.h>
-#include <qvideosurfaceformat.h>
-
-#include <QuartzCore/CIFilter.h>
-#include <QuartzCore/CIVector.h>
-
-QT_USE_NAMESPACE
-
-class NSBitmapVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- NSBitmapVideoBuffer(NSBitmapImageRep *buffer)
- : QAbstractVideoBuffer(NoHandle)
- , m_buffer(buffer)
- , m_mode(NotMapped)
- {
- [m_buffer retain];
- }
-
- virtual ~NSBitmapVideoBuffer()
- {
- [m_buffer release];
- }
-
- MapMode mapMode() const { return m_mode; }
-
- uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
- if (mode != NotMapped && m_mode == NotMapped) {
- if (numBytes)
- *numBytes = [m_buffer bytesPerPlane];
-
- if (bytesPerLine)
- *bytesPerLine = [m_buffer bytesPerRow];
-
- m_mode = mode;
-
- return [m_buffer bitmapData];
- } else {
- return 0;
- }
- }
-
- void unmap() { m_mode = NotMapped; }
-
-private:
- NSBitmapImageRep *m_buffer;
- MapMode m_mode;
-};
-
-class TextureVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- TextureVideoBuffer(GLuint textureId)
- : QAbstractVideoBuffer(GLTextureHandle)
- , m_textureId(textureId)
- {}
-
- virtual ~TextureVideoBuffer() {}
-
- MapMode mapMode() const { return NotMapped; }
- uchar *map(MapMode, int*, int*) { return 0; }
- void unmap() {}
-
- QVariant handle() const
- {
- return QVariant::fromValue<unsigned int>(m_textureId);
- }
-
-private:
- GLuint m_textureId;
-};
-
-
-#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];}
-
-@interface HiddenQTMovieView : QTMovieView
-{
-@private
- QWindow *m_window;
- QT7MovieViewRenderer *m_renderer;
- QReadWriteLock m_rendererLock;
-}
-
-- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer;
-- (void) setRenderer:(QT7MovieViewRenderer *)renderer;
-- (void) setDrawRect:(const QRect &)rect;
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img;
-@end
-
-@implementation HiddenQTMovieView
-
-- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer
-{
- self = [super initWithFrame:NSZeroRect];
- if (self) {
- [self setControllerVisible:NO];
- [self setDelegate:self];
-
- QWriteLocker lock(&self->m_rendererLock);
- self->m_renderer = renderer;
-
- self->m_window = new QWindow;
- self->m_window->setOpacity(0.0);
- self->m_window->setGeometry(0,0,1,1);
- self->m_window->create();
-
- [(NSView *)(self->m_window->winId()) addSubview:self];
- [self setDrawRect:QRect(0,0,1,1)];
- }
- return self;
-}
-
-- (void) dealloc
-{
- self->m_window->deleteLater();
- [super dealloc];
-}
-
-- (void) setRenderer:(QT7MovieViewRenderer *)renderer
-{
- QWriteLocker lock(&m_rendererLock);
- m_renderer = renderer;
-}
-
-- (void) setDrawRect:(const QRect &)rect
-{
- NSRect nsrect;
- nsrect.origin.x = rect.x();
- nsrect.origin.y = rect.y();
- nsrect.size.width = rect.width();
- nsrect.size.height = rect.height();
- [self setFrame:nsrect];
-}
-
-- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img
-{
- // This method is called from QTMovieView just
- // before the image will be drawn.
- Q_UNUSED(view);
- QReadLocker lock(&m_rendererLock);
- AutoReleasePool pool;
-
- if (m_renderer) {
- CGRect bounds = [img extent];
- int w = bounds.size.width;
- int h = bounds.size.height;
-
- QVideoFrame frame;
-
- QAbstractVideoSurface *surface = m_renderer->surface();
- if (!surface || !surface->isActive())
- return img;
-
- if (surface->surfaceFormat().handleType() == QAbstractVideoBuffer::CoreImageHandle ||
- surface->surfaceFormat().handleType() == QAbstractVideoBuffer::GLTextureHandle) {
- //surface supports rendering of opengl based CIImage
- frame = QVideoFrame(new QT7CIImageVideoBuffer(img), QSize(w,h), QVideoFrame::Format_RGB32 );
- } else {
- //Swap R and B colors
- CIFilter *colorSwapFilter = [CIFilter filterWithName: @"CIColorMatrix" keysAndValues:
- @"inputImage", img,
- @"inputRVector", [CIVector vectorWithX: 0 Y: 0 Z: 1 W: 0],
- @"inputGVector", [CIVector vectorWithX: 0 Y: 1 Z: 0 W: 0],
- @"inputBVector", [CIVector vectorWithX: 1 Y: 0 Z: 0 W: 0],
- @"inputAVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 1],
- @"inputBiasVector", [CIVector vectorWithX: 0 Y: 0 Z: 0 W: 0],
- nil];
- CIImage *img = [colorSwapFilter valueForKey: @"outputImage"];
- NSBitmapImageRep *bitmap =[[NSBitmapImageRep alloc] initWithCIImage:img];
- //requesting the bitmap data is slow,
- //but it's better to do it here to avoid blocking the main thread for a long.
- [bitmap bitmapData];
- frame = QVideoFrame(new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 );
- [bitmap release];
- }
-
- m_renderer->renderFrame(frame);
- }
-
- return img;
-}
-
-// Override this method so that the movie doesn't stop if
-// the window becomes invisible
-- (void)viewWillMoveToWindow:(NSWindow *)newWindow
-{
- Q_UNUSED(newWindow);
-}
-
-
-VIDEO_TRANSPARENT(mouseDown);
-VIDEO_TRANSPARENT(mouseDragged);
-VIDEO_TRANSPARENT(mouseUp);
-VIDEO_TRANSPARENT(mouseMoved);
-VIDEO_TRANSPARENT(mouseEntered);
-VIDEO_TRANSPARENT(mouseExited);
-VIDEO_TRANSPARENT(rightMouseDown);
-VIDEO_TRANSPARENT(rightMouseDragged);
-VIDEO_TRANSPARENT(rightMouseUp);
-VIDEO_TRANSPARENT(otherMouseDown);
-VIDEO_TRANSPARENT(otherMouseDragged);
-VIDEO_TRANSPARENT(otherMouseUp);
-VIDEO_TRANSPARENT(keyDown);
-VIDEO_TRANSPARENT(keyUp);
-VIDEO_TRANSPARENT(scrollWheel)
-
-@end
-
-
-QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent)
- :QT7VideoRendererControl(parent),
- m_movie(0),
- m_movieView(0),
- m_surface(0),
- m_window(0),
- m_context(0),
- m_fbo(0),
- m_ciContext(0),
- m_pendingRenderEvent(false)
-{
-}
-
-QT7MovieViewRenderer::~QT7MovieViewRenderer()
-{
- [(HiddenQTMovieView*)m_movieView setRenderer:0];
-
- QMutexLocker locker(&m_mutex);
- m_currentFrame = QVideoFrame();
- [(HiddenQTMovieView*)m_movieView release];
- [m_ciContext release];
- delete m_fbo;
- delete m_window;
-}
-
-void QT7MovieViewRenderer::setupVideoOutput()
-{
- AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7MovieViewRenderer::setupVideoOutput" << m_movie << m_surface;
-#endif
-
- HiddenQTMovieView *movieView = (HiddenQTMovieView*)m_movieView;
-
- if (movieView && !m_movie) {
- [movieView setMovie:nil];
- }
-
- if (m_movie) {
- NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
-
- m_nativeSize = QSize(size.width, size.height);
-
- if (!movieView) {
- movieView = [[HiddenQTMovieView alloc] initWithRenderer:this];
- m_movieView = movieView;
- [movieView setControllerVisible:NO];
- }
-
- [movieView setMovie:(QTMovie*)m_movie];
- [movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)];
- } else {
- m_nativeSize = QSize();
- }
-
- if (m_surface && !m_nativeSize.isEmpty()) {
- bool coreImageFrameSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::CoreImageHandle).isEmpty();
- bool glTextureSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty();
-
- QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle;
- QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_RGB32;
-
- if (coreImageFrameSupported) {
- handleType = QAbstractVideoBuffer::CoreImageHandle;
- } else if (glTextureSupported) {
- handleType = QAbstractVideoBuffer::GLTextureHandle;
- pixelFormat = QVideoFrame::Format_BGR32;
- }
-
- QVideoSurfaceFormat format(m_nativeSize, pixelFormat, handleType);
-
- if (m_surface->isActive() && m_surface->surfaceFormat() != format) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Surface format was changed, stop the surface.";
-#endif
- m_surface->stop();
- }
-
- if (!m_surface->isActive()) {
-#ifdef QT_DEBUG_QT7
- qDebug() << "Starting the surface with format" << format;
-#endif
- if (!m_surface->start(format))
- qWarning() << "failed to start video surface" << m_surface->error();
- }
- }
-}
-
-/*!
- Render the CIImage based video frame to FBO and return the video frame with resulting texture
-*/
-QVideoFrame QT7MovieViewRenderer::convertCIImageToGLTexture(const QVideoFrame &frame)
-{
- if (frame.handleType() != QAbstractVideoBuffer::CoreImageHandle)
- return QVideoFrame();
-
- if (!m_window) {
- QOpenGLContext *qGlContext = 0;
-
- if (m_surface)
- qGlContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>());
-
- if (qGlContext) {
- m_window = new QWindow();
-
- QSurfaceFormat format(qGlContext->format());
-
- m_context = new QOpenGLContext(m_window);
- m_context->setShareContext(qGlContext);
- m_context->setFormat(format);
- m_context->create();
-
- m_window->setFormat(format);
- m_window->setGeometry(0, 0, 1, 1);
- m_window->setSurfaceType(QWindow::OpenGLSurface);
- m_window->create();
- } else {
- return QVideoFrame();
- }
- }
-
- if (!m_context)
- return QVideoFrame();
-
- m_context->makeCurrent(m_window);
-
- if (!m_fbo || m_fbo->size() != frame.size()) {
- delete m_fbo;
- m_fbo = new QGLFramebufferObject(frame.size());
- }
-
- CIImage *ciImg = (CIImage*)(frame.handle().value<void*>());
- if (ciImg) {
- AutoReleasePool pool;
-
- QPainter p(m_fbo);
- p.beginNativePainting();
- CGLContextObj cglContext = CGLGetCurrentContext();
- if (cglContext) {
- if (!m_ciContext) {
- NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat];
- CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]);
-
- m_ciContext = [CIContext contextWithCGLContext:cglContext
- pixelFormat:cglPixelFormat
- colorSpace:nil
- options:nil];
-
- [m_ciContext retain];
- }
-
- QRect viewport = QRect(0, 0, frame.width(), frame.height());
- CGRect sRect = CGRectMake(viewport.x(), viewport.y(), viewport.width(), viewport.height());
- CGRect dRect = CGRectMake(viewport.x(), viewport.y(), viewport.width(), viewport.height());
-
- [m_ciContext drawImage:ciImg inRect:dRect fromRect:sRect];
- }
-
- p.endNativePainting();
-
- QAbstractVideoBuffer *buffer = new TextureVideoBuffer(m_fbo->texture());
- return QVideoFrame(buffer, frame.size(), QVideoFrame::Format_BGR32);
- }
-
- return QVideoFrame();
-}
-
-void QT7MovieViewRenderer::setMovie(void *movie)
-{
- if (movie == m_movie)
- return;
-
- QMutexLocker locker(&m_mutex);
- m_movie = movie;
- setupVideoOutput();
-}
-
-void QT7MovieViewRenderer::updateNaturalSize(const QSize &newSize)
-{
- if (m_nativeSize != newSize) {
- m_nativeSize = newSize;
- setupVideoOutput();
- }
-}
-
-QAbstractVideoSurface *QT7MovieViewRenderer::surface() const
-{
- return m_surface;
-}
-
-void QT7MovieViewRenderer::setSurface(QAbstractVideoSurface *surface)
-{
- if (surface == m_surface)
- return;
-
- QMutexLocker locker(&m_mutex);
-
- if (m_surface && m_surface->isActive())
- m_surface->stop();
-
- m_surface = surface;
- setupVideoOutput();
-}
-
-void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame)
-{
- QMutexLocker locker(&m_mutex);
- m_currentFrame = frame;
-
- if (!m_pendingRenderEvent)
- qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
-
- m_pendingRenderEvent = true;
-}
-
-bool QT7MovieViewRenderer::event(QEvent *event)
-{
- if (event->type() == QEvent::User) {
- QMutexLocker locker(&m_mutex);
- m_pendingRenderEvent = false;
-
- if (m_surface->isActive()) {
- //For GL texture frames, render in the main thread CIImage based buffers
- //to FBO shared with video surface shared context
- if (m_surface->surfaceFormat().handleType() == QAbstractVideoBuffer::GLTextureHandle) {
- m_currentFrame = convertCIImageToGLTexture(m_currentFrame);
- if (m_currentFrame.isValid())
- m_surface->present(m_currentFrame);
- } else {
- m_surface->present(m_currentFrame);
- }
- }
-
- m_currentFrame = QVideoFrame();
- }
-
- return QT7VideoRendererControl::event(event);
-}
diff --git a/src/plugins/qt7/qt7serviceplugin.h b/src/plugins/qt7/qt7serviceplugin.h
deleted file mode 100644
index 2e04297ff..000000000
--- a/src/plugins/qt7/qt7serviceplugin.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QT7SERVICEPLUGIN_H
-#define QT7SERVICEPLUGIN_H
-
-#include <qmediaserviceproviderplugin.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7ServicePlugin
- : public QMediaServiceProviderPlugin
- , public QMediaServiceSupportedFormatsInterface
- , public QMediaServiceFeaturesInterface
-{
- Q_OBJECT
- Q_INTERFACES(QMediaServiceFeaturesInterface)
- Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "qt7.json")
-
-public:
- QT7ServicePlugin();
-
- QMediaService* create(QString const& key);
- void release(QMediaService *service);
-
- QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
- QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const;
- QStringList supportedMimeTypes() const;
-
-private:
- void buildSupportedTypes();
-
- QStringList m_supportedMimeTypes;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERSERVICEPLUGIN_H
diff --git a/src/plugins/qt7/qt7videooutput.h b/src/plugins/qt7/qt7videooutput.h
deleted file mode 100644
index 86fc273dd..000000000
--- a/src/plugins/qt7/qt7videooutput.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** 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.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7VIDEOOUTPUTCONTROL_H
-#define QT7VIDEOOUTPUTCONTROL_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qsize.h>
-
-#include <qvideowindowcontrol.h>
-#ifndef QT_NO_WIDGETS
-#include <qvideowidgetcontrol.h>
-#endif
-#include <qvideorenderercontrol.h>
-#include <qmediaplayer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-
-class QT7VideoOutput {
-public:
- virtual ~QT7VideoOutput() {}
- virtual void setMovie(void *movie) = 0;
- virtual void updateNaturalSize(const QSize &newSize) = 0;
-};
-
-#define QT7VideoOutput_iid \
- "org.qt-project.qt.QT7VideoOutput/5.0"
-Q_DECLARE_INTERFACE(QT7VideoOutput, QT7VideoOutput_iid)
-
-class QT7VideoWindowControl : public QVideoWindowControl, public QT7VideoOutput
-{
-Q_OBJECT
-Q_INTERFACES(QT7VideoOutput)
-public:
- virtual ~QT7VideoWindowControl() {}
-
-protected:
- QT7VideoWindowControl(QObject *parent)
- :QVideoWindowControl(parent)
- {}
-};
-
-class QT7VideoRendererControl : public QVideoRendererControl, public QT7VideoOutput
-{
-Q_OBJECT
-Q_INTERFACES(QT7VideoOutput)
-public:
- virtual ~QT7VideoRendererControl() {}
-
-protected:
- QT7VideoRendererControl(QObject *parent)
- :QVideoRendererControl(parent)
- {}
-};
-
-#ifndef QT_NO_WIDGETS
-class QT7VideoWidgetControl : public QVideoWidgetControl, public QT7VideoOutput
-{
-Q_OBJECT
-Q_INTERFACES(QT7VideoOutput)
-public:
- virtual ~QT7VideoWidgetControl() {}
-
-protected:
- QT7VideoWidgetControl(QObject *parent)
- :QVideoWidgetControl(parent)
- {}
-};
-#endif
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp
index 59a9f661f..4f8f03836 100644
--- a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp
@@ -404,6 +404,7 @@ QList<QByteArray> QWindowsAudioDeviceInfo::availableDevices(QAudio::Mode mode)
Q_UNUSED(mode)
QList<QByteArray> devices;
+#ifndef Q_OS_WINCE
//enumerate device fullnames through directshow api
CoInitialize(NULL);
ICreateDevEnum *pDevEnum = NULL;
@@ -455,6 +456,35 @@ QList<QByteArray> QWindowsAudioDeviceInfo::availableDevices(QAudio::Mode mode)
}
}
CoUninitialize();
+#else // Q_OS_WINCE
+ if (mode == QAudio::AudioOutput) {
+ WAVEOUTCAPS woc;
+ unsigned long iNumDevs,i;
+ iNumDevs = waveOutGetNumDevs();
+ for (i=0;i<iNumDevs;i++) {
+ if (waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS))
+ == MMSYSERR_NOERROR) {
+ QByteArray device;
+ QDataStream ds(&device, QIODevice::WriteOnly);
+ ds << quint32(i) << QString::fromWCharArray(woc.szPname);
+ devices.append(device);
+ }
+ }
+ } else {
+ WAVEINCAPS woc;
+ unsigned long iNumDevs,i;
+ iNumDevs = waveInGetNumDevs();
+ for (i=0;i<iNumDevs;i++) {
+ if (waveInGetDevCaps(i, &woc, sizeof(WAVEINCAPS))
+ == MMSYSERR_NOERROR) {
+ QByteArray device;
+ QDataStream ds(&device, QIODevice::WriteOnly);
+ ds << quint32(i) << QString::fromWCharArray(woc.szPname);
+ devices.append(device);
+ }
+ }
+ }
+#endif // !Q_OS_WINCE
return devices;
}
diff --git a/src/plugins/windowsaudio/qwindowsaudioinput.cpp b/src/plugins/windowsaudio/qwindowsaudioinput.cpp
index 376854373..2a3d34293 100644
--- a/src/plugins/windowsaudio/qwindowsaudioinput.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudioinput.cpp
@@ -698,7 +698,7 @@ qint64 QWindowsAudioInput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return timeStampOpened.elapsed()*1000;
+ return timeStampOpened.elapsed() * qint64(1000);
}
void QWindowsAudioInput::reset()
diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
index 659ee3a0c..a9230139c 100644
--- a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
+++ b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp
@@ -674,7 +674,7 @@ qint64 QWindowsAudioOutput::elapsedUSecs() const
if (deviceState == QAudio::StoppedState)
return 0;
- return timeStampOpened.elapsed()*1000;
+ return timeStampOpened.elapsed() * qint64(1000);
}
QAudio::Error QWindowsAudioOutput::error() const
diff --git a/src/plugins/windowsaudio/windowsaudio.pro b/src/plugins/windowsaudio/windowsaudio.pro
index a1a327953..ead73251b 100644
--- a/src/plugins/windowsaudio/windowsaudio.pro
+++ b/src/plugins/windowsaudio/windowsaudio.pro
@@ -5,7 +5,8 @@ PLUGIN_TYPE = audio
PLUGIN_CLASS_NAME = QWindowsAudioPlugin
load(qt_plugin)
-LIBS += -lwinmm -lstrmiids -lole32 -loleaut32
+LIBS += -lstrmiids -lole32 -loleaut32
+!wince*:LIBS += -lwinmm
HEADERS += \
qwindowsaudioplugin.h \
diff --git a/src/plugins/winrt/qwinrtcameracontrol.cpp b/src/plugins/winrt/qwinrtcameracontrol.cpp
new file mode 100644
index 000000000..619e97315
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameracontrol.cpp
@@ -0,0 +1,783 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcameracontrol.h"
+#include "qwinrtcameravideorenderercontrol.h"
+#include "qwinrtvideodeviceselectorcontrol.h"
+#include "qwinrtcameraimagecapturecontrol.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QPointer>
+
+#include <mfapi.h>
+#include <mferror.h>
+#include <mfidl.h>
+#include <wrl.h>
+#include <windows.devices.enumeration.h>
+#include <windows.media.capture.h>
+#include <windows.storage.streams.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Devices::Enumeration;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Media;
+using namespace ABI::Windows::Media::Capture;
+using namespace ABI::Windows::Media::Devices;
+using namespace ABI::Windows::Media::MediaProperties;
+using namespace ABI::Windows::Storage::Streams;
+
+QT_USE_NAMESPACE
+
+#define RETURN_VOID_AND_EMIT_ERROR(msg) \
+ if (FAILED(hr)) { \
+ emit error(QCamera::CameraError, qt_error_string(hr)); \
+ RETURN_VOID_IF_FAILED(msg); \
+ }
+
+class CriticalSectionLocker
+{
+public:
+ CriticalSectionLocker(CRITICAL_SECTION *section)
+ : m_section(section)
+ {
+ EnterCriticalSection(m_section);
+ }
+ ~CriticalSectionLocker()
+ {
+ LeaveCriticalSection(m_section);
+ }
+private:
+ CRITICAL_SECTION *m_section;
+};
+
+class MediaStream : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IMFStreamSink, IMFMediaEventGenerator, IMFMediaTypeHandler>
+{
+public:
+ MediaStream(IMFMediaType *type, IMFMediaSink *mediaSink, QWinRTCameraVideoRendererControl *videoRenderer)
+ : m_type(type), m_sink(mediaSink), m_videoRenderer(videoRenderer)
+ {
+ Q_ASSERT(m_videoRenderer);
+
+ InitializeCriticalSectionEx(&m_mutex, 0, 0);
+
+ HRESULT hr;
+ hr = MFCreateEventQueue(&m_eventQueue);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = MFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &m_workQueueId);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ ~MediaStream()
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ m_eventQueue->Shutdown();
+ DeleteCriticalSection(&m_mutex);
+ }
+
+ HRESULT RequestSample()
+ {
+ if (m_pendingSamples.load() < 3) {
+ m_pendingSamples.ref();
+ return QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetEvent(DWORD flags, IMFMediaEvent **event) Q_DECL_OVERRIDE
+ {
+ EnterCriticalSection(&m_mutex);
+ // Create an extra reference to avoid deadlock
+ ComPtr<IMFMediaEventQueue> eventQueue = m_eventQueue;
+ LeaveCriticalSection(&m_mutex);
+
+ return eventQueue->GetEvent(flags, event);
+ }
+
+ HRESULT __stdcall BeginGetEvent(IMFAsyncCallback *callback, IUnknown *state) Q_DECL_OVERRIDE
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ HRESULT hr = m_eventQueue->BeginGetEvent(callback, state);
+ return hr;
+ }
+
+ HRESULT __stdcall EndGetEvent(IMFAsyncResult *result, IMFMediaEvent **event) Q_DECL_OVERRIDE
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ return m_eventQueue->EndGetEvent(result, event);
+ }
+
+ HRESULT __stdcall QueueEvent(MediaEventType eventType, const GUID &extendedType, HRESULT status, const PROPVARIANT *value) Q_DECL_OVERRIDE
+ {
+ CriticalSectionLocker locker(&m_mutex);
+ return m_eventQueue->QueueEventParamVar(eventType, extendedType, status, value);
+ }
+
+ HRESULT __stdcall GetMediaSink(IMFMediaSink **mediaSink) Q_DECL_OVERRIDE
+ {
+ *mediaSink = m_sink;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetIdentifier(DWORD *identifier) Q_DECL_OVERRIDE
+ {
+ *identifier = 0;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetMediaTypeHandler(IMFMediaTypeHandler **handler) Q_DECL_OVERRIDE
+ {
+ return QueryInterface(IID_PPV_ARGS(handler));
+ }
+
+ HRESULT __stdcall ProcessSample(IMFSample *sample) Q_DECL_OVERRIDE
+ {
+ ComPtr<IMFMediaBuffer> buffer;
+ HRESULT hr = sample->GetBufferByIndex(0, &buffer);
+ RETURN_HR_IF_FAILED("Failed to get buffer from camera sample");
+ ComPtr<IMF2DBuffer> buffer2d;
+ hr = buffer.As(&buffer2d);
+ RETURN_HR_IF_FAILED("Failed to cast camera sample buffer to 2D buffer");
+
+ m_pendingSamples.deref();
+ m_videoRenderer->queueBuffer(buffer2d.Get());
+
+ return hr;
+ }
+
+ HRESULT __stdcall PlaceMarker(MFSTREAMSINK_MARKER_TYPE type, const PROPVARIANT *value, const PROPVARIANT *context) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(type);
+ Q_UNUSED(value);
+ QueueEvent(MEStreamSinkMarker, GUID_NULL, S_OK, context);
+ return S_OK;
+ }
+
+ HRESULT __stdcall Flush() Q_DECL_OVERRIDE
+ {
+ m_videoRenderer->discardBuffers();
+ m_pendingSamples.store(0);
+ return S_OK;
+ }
+
+ HRESULT __stdcall IsMediaTypeSupported(IMFMediaType *type, IMFMediaType **) Q_DECL_OVERRIDE
+ {
+ HRESULT hr;
+ GUID majorType;
+ hr = type->GetMajorType(&majorType);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (!IsEqualGUID(majorType, MFMediaType_Video))
+ return MF_E_INVALIDMEDIATYPE;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetMediaTypeCount(DWORD *typeCount) Q_DECL_OVERRIDE
+ {
+ *typeCount = 1;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetMediaTypeByIndex(DWORD index, IMFMediaType **type) Q_DECL_OVERRIDE
+ {
+ if (index == 0)
+ return m_type.CopyTo(type);
+ return E_BOUNDS;
+ }
+
+ HRESULT __stdcall SetCurrentMediaType(IMFMediaType *type) Q_DECL_OVERRIDE
+ {
+ if (FAILED(IsMediaTypeSupported(type, Q_NULLPTR)))
+ return MF_E_INVALIDREQUEST;
+
+ m_type = type;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetCurrentMediaType(IMFMediaType **type) Q_DECL_OVERRIDE
+ {
+ return m_type.CopyTo(type);
+ }
+
+ HRESULT __stdcall GetMajorType(GUID *majorType) Q_DECL_OVERRIDE
+ {
+ return m_type->GetMajorType(majorType);
+ }
+
+private:
+ CRITICAL_SECTION m_mutex;
+ ComPtr<IMFMediaType> m_type;
+ IMFMediaSink *m_sink;
+ ComPtr<IMFMediaEventQueue> m_eventQueue;
+ DWORD m_workQueueId;
+
+ QWinRTCameraVideoRendererControl *m_videoRenderer;
+ QAtomicInt m_pendingSamples;
+};
+
+class MediaSink : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IMediaExtension, IMFMediaSink, IMFClockStateSink>
+{
+public:
+ MediaSink(IMediaEncodingProfile *encodingProfile, QWinRTCameraVideoRendererControl *videoRenderer)
+ : m_videoRenderer(videoRenderer)
+ {
+ HRESULT hr;
+ ComPtr<IVideoEncodingProperties> videoProperties;
+ hr = encodingProfile->get_Video(&videoProperties);
+ RETURN_VOID_IF_FAILED("Failed to get video properties");
+ ComPtr<IMFMediaType> videoType;
+ hr = MFCreateMediaTypeFromProperties(videoProperties.Get(), &videoType);
+ RETURN_VOID_IF_FAILED("Failed to create video type");
+ m_stream = Make<MediaStream>(videoType.Get(), this, videoRenderer);
+ }
+
+ ~MediaSink()
+ {
+ }
+
+ HRESULT RequestSample()
+ {
+ return m_stream->RequestSample();
+ }
+
+ HRESULT __stdcall SetProperties(Collections::IPropertySet *configuration) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(configuration);
+ return E_NOTIMPL;
+ }
+
+ HRESULT __stdcall GetCharacteristics(DWORD *characteristics) Q_DECL_OVERRIDE
+ {
+ *characteristics = MEDIASINK_FIXED_STREAMS | MEDIASINK_RATELESS;
+ return S_OK;
+ }
+
+ HRESULT __stdcall AddStreamSink(DWORD streamSinkIdentifier, IMFMediaType *mediaType, IMFStreamSink **streamSink) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(streamSinkIdentifier);
+ Q_UNUSED(mediaType);
+ Q_UNUSED(streamSink);
+ return E_NOTIMPL;
+ }
+
+ HRESULT __stdcall RemoveStreamSink(DWORD streamSinkIdentifier) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(streamSinkIdentifier);
+ return E_NOTIMPL;
+ }
+
+ HRESULT __stdcall GetStreamSinkCount(DWORD *streamSinkCount) Q_DECL_OVERRIDE
+ {
+ *streamSinkCount = 1;
+ return S_OK;
+ }
+
+ HRESULT __stdcall GetStreamSinkByIndex(DWORD index, IMFStreamSink **streamSink) Q_DECL_OVERRIDE
+ {
+ if (index == 0)
+ return m_stream.CopyTo(streamSink);
+ return MF_E_INVALIDINDEX;
+ }
+
+ HRESULT __stdcall GetStreamSinkById(DWORD streamSinkIdentifier, IMFStreamSink **streamSink) Q_DECL_OVERRIDE
+ {
+ // ID and index are always 0
+ HRESULT hr = GetStreamSinkByIndex(streamSinkIdentifier, streamSink);
+ return hr == MF_E_INVALIDINDEX ? MF_E_INVALIDSTREAMNUMBER : hr;
+ }
+
+ HRESULT __stdcall SetPresentationClock(IMFPresentationClock *presentationClock) Q_DECL_OVERRIDE
+ {
+ HRESULT hr = S_OK;
+ m_presentationClock = presentationClock;
+ if (m_presentationClock)
+ hr = m_presentationClock->AddClockStateSink(this);
+ return hr;
+ }
+
+ HRESULT __stdcall GetPresentationClock(IMFPresentationClock **presentationClock) Q_DECL_OVERRIDE
+ {
+ return m_presentationClock.CopyTo(presentationClock);
+ }
+
+ HRESULT __stdcall Shutdown() Q_DECL_OVERRIDE
+ {
+ m_stream->Flush();
+ m_videoRenderer->setActive(false);
+ return m_presentationClock->Stop();
+ }
+
+ HRESULT __stdcall OnClockStart(MFTIME systemTime, LONGLONG clockStartOffset) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+ Q_UNUSED(clockStartOffset);
+
+ m_videoRenderer->setActive(true);
+
+ return S_OK;
+ }
+
+ HRESULT __stdcall OnClockStop(MFTIME systemTime) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+
+ m_videoRenderer->setActive(false);
+
+ return m_stream->QueueEvent(MEStreamSinkStopped, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+
+ HRESULT __stdcall OnClockPause(MFTIME systemTime) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+
+ m_videoRenderer->setActive(false);
+
+ return m_stream->QueueEvent(MEStreamSinkPaused, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+
+ HRESULT __stdcall OnClockRestart(MFTIME systemTime) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+
+ m_videoRenderer->setActive(true);
+
+ return m_stream->QueueEvent(MEStreamSinkStarted, GUID_NULL, S_OK, Q_NULLPTR);
+ }
+
+ HRESULT __stdcall OnClockSetRate(MFTIME systemTime, float rate) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(systemTime);
+ Q_UNUSED(rate);
+ return E_NOTIMPL;
+ }
+
+private:
+ ComPtr<MediaStream> m_stream;
+ ComPtr<IMFPresentationClock> m_presentationClock;
+
+ QWinRTCameraVideoRendererControl *m_videoRenderer;
+};
+
+class QWinRTCameraControlPrivate
+{
+public:
+ QCamera::State state;
+ QCamera::Status status;
+ QCamera::CaptureModes captureMode;
+
+ ComPtr<IMediaCapture> capture;
+ ComPtr<IMediaCaptureVideoPreview> capturePreview;
+ EventRegistrationToken captureFailedCookie;
+ EventRegistrationToken recordLimitationCookie;
+
+ ComPtr<IMediaEncodingProfileStatics> encodingProfileFactory;
+
+ ComPtr<IMediaEncodingProfile> encodingProfile;
+ ComPtr<MediaSink> mediaSink;
+
+ QSize size;
+ QPointer<QWinRTCameraVideoRendererControl> videoRenderer;
+ QPointer<QWinRTVideoDeviceSelectorControl> videoDeviceSelector;
+ QPointer<QWinRTCameraImageCaptureControl> imageCaptureControl;
+};
+
+QWinRTCameraControl::QWinRTCameraControl(QObject *parent)
+ : QCameraControl(parent), d_ptr(new QWinRTCameraControlPrivate)
+{
+ Q_D(QWinRTCameraControl);
+
+ d->state = QCamera::UnloadedState;
+ d->status = QCamera::UnloadedStatus;
+ d->captureMode = QCamera::CaptureStillImage;
+ d->captureFailedCookie.value = 0;
+ d->recordLimitationCookie.value = 0;
+ d->videoRenderer = new QWinRTCameraVideoRendererControl(d->size, this);
+ connect(d->videoRenderer, &QWinRTCameraVideoRendererControl::bufferRequested,
+ this, &QWinRTCameraControl::onBufferRequested);
+ d->videoDeviceSelector = new QWinRTVideoDeviceSelectorControl(this);
+ d->imageCaptureControl = new QWinRTCameraImageCaptureControl(this);
+}
+
+QWinRTCameraControl::~QWinRTCameraControl()
+{
+ setState(QCamera::UnloadedState);
+}
+
+QCamera::State QWinRTCameraControl::state() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->state;
+}
+
+void QWinRTCameraControl::setState(QCamera::State state)
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->state == state)
+ return;
+
+ HRESULT hr;
+ switch (state) {
+ case QCamera::ActiveState: {
+ // Capture has not been created or initialized
+ if (d->state == QCamera::UnloadedState) {
+ hr = initialize();
+ RETURN_VOID_AND_EMIT_ERROR("Failed to initialize media capture");
+ }
+ Q_ASSERT(d->state == QCamera::LoadedState);
+
+ d->mediaSink = Make<MediaSink>(d->encodingProfile.Get(), d->videoRenderer);
+ ComPtr<IAsyncAction> op;
+ hr = d->capturePreview->StartPreviewToCustomSinkAsync(d->encodingProfile.Get(), d->mediaSink.Get(), &op);
+ RETURN_VOID_AND_EMIT_ERROR("Failed to initiate capture");
+ if (d->status != QCamera::StartingStatus) {
+ d->status = QCamera::StartingStatus;
+ emit statusChanged(d->status);
+ }
+
+ hr = QWinRTFunctions::await(op);
+ if (FAILED(hr)) {
+ emit error(QCamera::CameraError, qt_error_string(hr));
+ setState(QCamera::UnloadedState); // Unload everything, as initialize() will need be called again
+ return;
+ }
+
+ d->state = QCamera::ActiveState;
+ emit stateChanged(d->state);
+ d->status = QCamera::ActiveStatus;
+ emit statusChanged(d->status);
+ break;
+ }
+ case QCamera::LoadedState: {
+ // If moving from unloaded, initialize the camera
+ if (d->state == QCamera::UnloadedState) {
+ hr = initialize();
+ RETURN_VOID_AND_EMIT_ERROR("Failed to initialize media capture");
+ }
+ // fall through
+ }
+ case QCamera::UnloadedState: {
+ // Stop the camera if it is running (transition to LoadedState)
+ if (d->status == QCamera::ActiveStatus) {
+ ComPtr<IAsyncAction> op;
+ hr = d->capturePreview->StopPreviewAsync(&op);
+ RETURN_VOID_AND_EMIT_ERROR("Failed to stop camera preview");
+ if (d->status != QCamera::StoppingStatus) {
+ d->status = QCamera::StoppingStatus;
+ emit statusChanged(d->status);
+ }
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = QWinRTFunctions::await(op); // Synchronize unloading
+ if (FAILED(hr))
+ emit error(QCamera::InvalidRequestError, qt_error_string(hr));
+
+ d->mediaSink->Shutdown();
+ d->mediaSink.Reset();
+
+ d->state = QCamera::LoadedState;
+ emit stateChanged(d->state);
+
+ d->status = QCamera::LoadedStatus;
+ emit statusChanged(d->status);
+ }
+ // Completely unload if needed
+ if (state == QCamera::UnloadedState) {
+ if (!d->capture) // Already unloaded
+ break;
+
+ if (d->status != QCamera::UnloadingStatus) {
+ d->status = QCamera::UnloadingStatus;
+ emit statusChanged(d->status);
+ }
+
+ if (d->capture && d->captureFailedCookie.value) {
+ hr = d->capture->remove_Failed(d->captureFailedCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->captureFailedCookie.value = 0;
+ }
+ if (d->capture && d->recordLimitationCookie.value) {
+ d->capture->remove_RecordLimitationExceeded(d->recordLimitationCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->recordLimitationCookie.value = 0;
+ }
+ ComPtr<IClosable> capture;
+ hr = d->capture.As(&capture);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = capture->Close();
+ RETURN_VOID_AND_EMIT_ERROR("Failed to close the capture manger");
+ d->capture.Reset();
+ if (d->state != QCamera::UnloadedState) {
+ d->state = QCamera::UnloadedState;
+ emit stateChanged(d->state);
+ }
+ if (d->status != QCamera::UnloadedStatus) {
+ d->status = QCamera::UnloadedStatus;
+ emit statusChanged(d->status);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+QCamera::Status QWinRTCameraControl::status() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->status;
+}
+
+QCamera::CaptureModes QWinRTCameraControl::captureMode() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->captureMode;
+}
+
+void QWinRTCameraControl::setCaptureMode(QCamera::CaptureModes mode)
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->captureMode == mode)
+ return;
+
+ if (!isCaptureModeSupported(mode)) {
+ qWarning("Unsupported capture mode: %d", mode);
+ return;
+ }
+
+ d->captureMode = mode;
+ emit captureModeChanged(d->captureMode);
+}
+
+bool QWinRTCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const
+{
+ return mode >= QCamera::CaptureViewfinder && mode <= QCamera::CaptureStillImage;
+}
+
+bool QWinRTCameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const
+{
+ Q_UNUSED(changeType);
+
+ return status == QCamera::UnloadedStatus; // For now, assume shutdown is required for all property changes
+}
+
+QVideoRendererControl *QWinRTCameraControl::videoRenderer() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->videoRenderer;
+}
+
+QVideoDeviceSelectorControl *QWinRTCameraControl::videoDeviceSelector() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->videoDeviceSelector;
+}
+
+QCameraImageCaptureControl *QWinRTCameraControl::imageCaptureControl() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->imageCaptureControl;
+}
+
+IMediaCapture *QWinRTCameraControl::handle() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->capture.Get();
+}
+
+QSize QWinRTCameraControl::imageSize() const
+{
+ Q_D(const QWinRTCameraControl);
+ return d->size;
+}
+
+void QWinRTCameraControl::onBufferRequested()
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->mediaSink)
+ d->mediaSink->RequestSample();
+}
+
+HRESULT QWinRTCameraControl::initialize()
+{
+ Q_D(QWinRTCameraControl);
+
+ if (d->status != QCamera::LoadingStatus) {
+ d->status = QCamera::LoadingStatus;
+ emit statusChanged(d->status);
+ }
+
+ HRESULT hr;
+ ComPtr<IInspectable> capture;
+ hr = RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCapture).Get(),
+ &capture);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = capture.As(&d->capture);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->capture.As(&d->capturePreview);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->capture->add_Failed(Callback<IMediaCaptureFailedEventHandler>(this, &QWinRTCameraControl::onCaptureFailed).Get(),
+ &d->captureFailedCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->capture->add_RecordLimitationExceeded(Callback<IRecordLimitationExceededEventHandler>(this, &QWinRTCameraControl::onRecordLimitationExceeded).Get(),
+ &d->recordLimitationCookie);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(),
+ IID_PPV_ARGS(&d->encodingProfileFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ int deviceIndex = d->videoDeviceSelector->selectedDevice();
+ if (deviceIndex < 0)
+ deviceIndex = d->videoDeviceSelector->defaultDevice();
+
+ const QString deviceName = d->videoDeviceSelector->deviceName(deviceIndex);
+ if (deviceName.isEmpty()) {
+ qWarning("No video device available or selected.");
+ return E_FAIL;
+ }
+
+ ComPtr<IMediaCaptureInitializationSettings> settings;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings).Get(),
+ &settings);
+ Q_ASSERT_SUCCEEDED(hr);
+ HStringReference deviceId(reinterpret_cast<LPCWSTR>(deviceName.utf16()), deviceName.length());
+ hr = settings->put_VideoDeviceId(deviceId.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = settings->put_StreamingCaptureMode(StreamingCaptureMode_Video);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = settings->put_PhotoCaptureSource(PhotoCaptureSource_Auto);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncAction> op;
+ hr = d->capture->InitializeWithSettingsAsync(settings.Get(), &op);
+ RETURN_HR_IF_FAILED("Failed to begin initialization of media capture manager");
+ hr = QWinRTFunctions::await(op, QWinRTFunctions::ProcessThreadEvents);
+ if (hr == E_ACCESSDENIED) {
+ qWarning("Access denied when initializing the media capture manager. "
+ "Check your manifest settings for microphone and webcam access.");
+ }
+ RETURN_HR_IF_FAILED("Failed to initialize media capture manager");
+
+ ComPtr<IVideoDeviceController> videoDeviceController;
+ hr = d->capture->get_VideoDeviceController(&videoDeviceController);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IMediaDeviceController> deviceController;
+ hr = videoDeviceController.As(&deviceController);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<IMediaEncodingProperties *>> encodingPropertiesList;
+ hr = deviceController->GetAvailableMediaStreamProperties(MediaStreamType_Photo, &encodingPropertiesList);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ d->size = QSize();
+ ComPtr<IVideoEncodingProperties> videoEncodingProperties;
+ quint32 encodingPropertiesListSize;
+ hr = encodingPropertiesList->get_Size(&encodingPropertiesListSize);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (quint32 i = 0; i < encodingPropertiesListSize; ++i) {
+ ComPtr<IMediaEncodingProperties> properties;
+ hr = encodingPropertiesList->GetAt(i, &properties);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVideoEncodingProperties> videoProperties;
+ hr = properties.As(&videoEncodingProperties);
+ Q_ASSERT_SUCCEEDED(hr);
+ UINT32 width, height;
+ hr = videoEncodingProperties->get_Width(&width);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = videoEncodingProperties->get_Height(&height);
+ Q_ASSERT_SUCCEEDED(hr);
+ // Choose the highest-quality format
+ if (int(width * height) > d->size.width() * d->size.height()) {
+ d->size = QSize(width, height);
+ videoEncodingProperties = videoProperties;
+ }
+ }
+
+ if (!videoEncodingProperties || d->size.isEmpty()) {
+ hr = MF_E_INVALID_FORMAT;
+ RETURN_HR_IF_FAILED("Failed to find a suitable video format");
+ }
+
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(),
+ &d->encodingProfile);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = d->encodingProfile->put_Video(videoEncodingProperties.Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ if (d->videoRenderer)
+ d->videoRenderer->setSize(d->size);
+
+ if (SUCCEEDED(hr) && d->state != QCamera::LoadedState) {
+ d->state = QCamera::LoadedState;
+ emit stateChanged(d->state);
+ }
+ if (SUCCEEDED(hr) && d->status != QCamera::LoadedStatus) {
+ d->status = QCamera::LoadedStatus;
+ emit statusChanged(d->status);
+ }
+ return hr;
+}
+
+HRESULT QWinRTCameraControl::onCaptureFailed(IMediaCapture *, IMediaCaptureFailedEventArgs *args)
+{
+ HRESULT hr;
+ UINT32 code;
+ hr = args->get_Code(&code);
+ RETURN_HR_IF_FAILED("Failed to get error code");
+ HString message;
+ args->get_Message(message.GetAddressOf());
+ RETURN_HR_IF_FAILED("Failed to get error message");
+ quint32 messageLength;
+ const wchar_t *messageBuffer = message.GetRawBuffer(&messageLength);
+ emit error(QCamera::CameraError, QString::fromWCharArray(messageBuffer, messageLength));
+ setState(QCamera::LoadedState);
+ return S_OK;
+}
+
+HRESULT QWinRTCameraControl::onRecordLimitationExceeded(IMediaCapture *)
+{
+ emit error(QCamera::CameraError, QStringLiteral("Recording limit exceeded."));
+ setState(QCamera::LoadedState);
+ return S_OK;
+}
diff --git a/src/plugins/winrt/qwinrtcameracontrol.h b/src/plugins/winrt/qwinrtcameracontrol.h
new file mode 100644
index 000000000..e75f7e476
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameracontrol.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCAMERACONTROL_H
+#define QWINRTCAMERACONTROL_H
+
+#include <QtMultimedia/QCameraControl>
+#include <QtCore/qt_windows.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace Media {
+ namespace Capture {
+ struct IMediaCapture;
+ struct IMediaCaptureFailedEventArgs;
+ }
+ }
+ namespace Foundation {
+ struct IAsyncAction;
+ enum class AsyncStatus;
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QVideoRendererControl;
+class QVideoDeviceSelectorControl;
+class QCameraImageCaptureControl;
+
+class QWinRTCameraControlPrivate;
+class QWinRTCameraControl : public QCameraControl
+{
+ Q_OBJECT
+public:
+ explicit QWinRTCameraControl(QObject *parent = 0);
+ ~QWinRTCameraControl();
+
+ QCamera::State state() const Q_DECL_OVERRIDE;
+ void setState(QCamera::State state) Q_DECL_OVERRIDE;
+
+ QCamera::Status status() const Q_DECL_OVERRIDE;
+
+ QCamera::CaptureModes captureMode() const Q_DECL_OVERRIDE;
+ void setCaptureMode(QCamera::CaptureModes mode) Q_DECL_OVERRIDE;
+ bool isCaptureModeSupported(QCamera::CaptureModes mode) const Q_DECL_OVERRIDE;
+
+ bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const Q_DECL_OVERRIDE;
+
+ QVideoRendererControl *videoRenderer() const;
+ QVideoDeviceSelectorControl *videoDeviceSelector() const;
+ QCameraImageCaptureControl *imageCaptureControl() const;
+
+ ABI::Windows::Media::Capture::IMediaCapture *handle() const;
+ QSize imageSize() const;
+
+private slots:
+ void onBufferRequested();
+
+private:
+ HRESULT enumerateDevices();
+ HRESULT initialize();
+ HRESULT onCaptureFailed(ABI::Windows::Media::Capture::IMediaCapture *,
+ ABI::Windows::Media::Capture::IMediaCaptureFailedEventArgs *);
+ HRESULT onRecordLimitationExceeded(ABI::Windows::Media::Capture::IMediaCapture *);
+
+ QScopedPointer<QWinRTCameraControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraControl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCAMERACONTROL_H
diff --git a/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp
new file mode 100644
index 000000000..f5151c619
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcameraimagecapturecontrol.h"
+#include "qwinrtcameracontrol.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QGlobalStatic>
+#include <QtCore/QPointer>
+#include <QtCore/QStandardPaths>
+#include <QtCore/QVector>
+#include <QtCore/qfunctions_winrt.h>
+#include <QtMultimedia/private/qmediastoragelocation_p.h>
+
+#include <wrl.h>
+#include <windows.media.capture.h>
+#include <windows.media.devices.h>
+#include <windows.media.mediaproperties.h>
+#include <windows.storage.streams.h>
+#include <windows.graphics.imaging.h>
+#include <robuffer.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Media::Capture;
+using namespace ABI::Windows::Media::Devices;
+using namespace ABI::Windows::Media::MediaProperties;
+using namespace ABI::Windows::Storage::Streams;
+using namespace ABI::Windows::Graphics::Imaging;
+
+QT_USE_NAMESPACE
+
+#define wchar(str) reinterpret_cast<const wchar_t *>(str.utf16())
+
+struct QWinRTCameraImageCaptureControlGlobal
+{
+ QWinRTCameraImageCaptureControlGlobal()
+ {
+ HRESULT hr;
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_ImageEncodingProperties).Get(),
+ &encodingPropertiesFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
+ &bufferFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(),
+ &dataReaderFactory);
+ }
+
+ ComPtr<IImageEncodingPropertiesStatics2> encodingPropertiesFactory;
+ ComPtr<IBufferFactory> bufferFactory;
+ ComPtr<IDataReaderFactory> dataReaderFactory;
+};
+Q_GLOBAL_STATIC(QWinRTCameraImageCaptureControlGlobal, g)
+
+struct CaptureRequest
+{
+ quint16 id;
+ QString fileName;
+ ComPtr<IImageEncodingProperties> imageFormat;
+ ComPtr<IRandomAccessStream> stream;
+ ComPtr<IAsyncAction> op;
+};
+
+class QWinRTCameraImageCaptureControlPrivate
+{
+public:
+ QPointer<QWinRTCameraControl> cameraControl;
+ QHash<IAsyncAction *, CaptureRequest> requests;
+ quint16 currentCaptureId;
+ QMediaStorageLocation location;
+
+ void onCameraStateChanged()
+ {
+
+ }
+};
+
+QWinRTCameraImageCaptureControl::QWinRTCameraImageCaptureControl(QWinRTCameraControl *parent)
+ : QCameraImageCaptureControl(parent), d_ptr(new QWinRTCameraImageCaptureControlPrivate)
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ d->cameraControl = parent;
+ connect(d->cameraControl, &QCameraControl::stateChanged,
+ this, &QWinRTCameraImageCaptureControl::readyForCaptureChanged);
+ d->currentCaptureId = 0;
+}
+
+bool QWinRTCameraImageCaptureControl::isReadyForCapture() const
+{
+ Q_D(const QWinRTCameraImageCaptureControl);
+ return d->cameraControl->state() == QCamera::ActiveState;
+}
+
+QCameraImageCapture::DriveMode QWinRTCameraImageCaptureControl::driveMode() const
+{
+ return QCameraImageCapture::SingleImageCapture;
+}
+
+void QWinRTCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode)
+{
+ Q_UNUSED(mode);
+}
+
+int QWinRTCameraImageCaptureControl::capture(const QString &fileName)
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ ++d->currentCaptureId;
+ IMediaCapture *capture = d->cameraControl->handle();
+ if (!capture) {
+ emit error(d->currentCaptureId, QCameraImageCapture::NotReadyError, tr("Camera not ready"));
+ return -1;
+ }
+
+ CaptureRequest request = {
+ d->currentCaptureId,
+ d->location.generateFileName(fileName, QMediaStorageLocation::Pictures, QStringLiteral("IMG_"),
+ fileName.isEmpty() ? QStringLiteral("jpg") : QFileInfo(fileName).suffix())
+ };
+
+ HRESULT hr;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(),
+ &request.stream);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = g->encodingPropertiesFactory->CreateBmp(&request.imageFormat);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ const QSize imageSize = d->cameraControl->imageSize();
+ hr = request.imageFormat->put_Width(imageSize.width());
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = request.imageFormat->put_Height(imageSize.height());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = capture->CapturePhotoToStreamAsync(request.imageFormat.Get(), request.stream.Get(), &request.op);
+ Q_ASSERT_SUCCEEDED(hr);
+ d->requests.insert(request.op.Get(), request);
+
+ hr = request.op->put_Completed(Callback<IAsyncActionCompletedHandler>(
+ this, &QWinRTCameraImageCaptureControl::onCaptureCompleted).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ return request.id;
+}
+
+void QWinRTCameraImageCaptureControl::cancelCapture()
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ QHash<IAsyncAction *, CaptureRequest>::iterator it = d->requests.begin();
+ while (it != d->requests.end()) {
+ ComPtr<IAsyncInfo> info;
+ it->op.As(&info);
+ info->Cancel();
+ it = d->requests.erase(it);
+ }
+}
+
+HRESULT QWinRTCameraImageCaptureControl::onCaptureCompleted(IAsyncAction *asyncInfo, AsyncStatus status)
+{
+ Q_D(QWinRTCameraImageCaptureControl);
+
+ if (status == Canceled || !d->requests.contains(asyncInfo))
+ return S_OK;
+
+ CaptureRequest request = d->requests.take(asyncInfo);
+
+ HRESULT hr;
+ if (status == Error) {
+ hr = asyncInfo->GetResults();
+ emit error(request.id, QCameraImageCapture::ResourceError, qt_error_string(hr));
+ return S_OK;
+ }
+
+ quint64 dataLength;
+ hr = request.stream->get_Size(&dataLength);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (dataLength == 0 || dataLength > INT_MAX) {
+ emit error(request.id, QCameraImageCapture::FormatError, tr("Invalid photo data length."));
+ return S_OK;
+ }
+
+ ComPtr<IBitmapDecoderStatics> bitmapFactory;
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_BitmapDecoder).Get(),
+ &bitmapFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncOperation<BitmapDecoder *>> op;
+ hr = bitmapFactory->CreateAsync(request.stream.Get(), &op);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IBitmapDecoder> decoder;
+ hr = QWinRTFunctions::await(op, decoder.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncOperation<BitmapFrame *>> op2;
+ hr = decoder->GetFrameAsync(0, &op2);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IBitmapFrame> frame;
+ hr = QWinRTFunctions::await(op2, frame.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IBitmapTransform> transform;
+ hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_BitmapTransform).Get(),
+ &transform);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ ComPtr<IAsyncOperation<PixelDataProvider *>> op3;
+ hr = frame->GetPixelDataTransformedAsync(BitmapPixelFormat_Rgba8, BitmapAlphaMode_Straight,
+ transform.Get(), ExifOrientationMode_IgnoreExifOrientation,
+ ColorManagementMode_DoNotColorManage, &op3);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IPixelDataProvider> pixelDataProvider;
+ hr = QWinRTFunctions::await(op3, pixelDataProvider.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ UINT32 pixelDataSize;
+ BYTE *pixelData;
+ hr = pixelDataProvider->DetachPixelData(&pixelDataSize, &pixelData);
+
+ UINT32 pixelHeight;
+ hr = frame->get_PixelHeight(&pixelHeight);
+ Q_ASSERT_SUCCEEDED(hr);
+ UINT32 pixelWidth;
+ hr = frame->get_PixelWidth(&pixelWidth);
+ Q_ASSERT_SUCCEEDED(hr);
+ const QImage image(pixelData, pixelWidth, pixelHeight, QImage::Format_RGBA8888,
+ reinterpret_cast<QImageCleanupFunction>(&CoTaskMemFree), pixelData);
+ emit imageCaptured(request.id, image);
+ if (image.save(request.fileName))
+ emit imageSaved(request.id, request.fileName);
+ else
+ emit error(request.id, QCameraImageCapture::ResourceError, tr("Image saving failed"));
+
+ return S_OK;
+}
diff --git a/src/plugins/qt7/qt7serviceplugin.mm b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.h
index 731f278a1..5150e4d3a 100644
--- a/src/plugins/qt7/qt7serviceplugin.mm
+++ b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.h
@@ -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.
@@ -39,80 +39,48 @@
**
****************************************************************************/
-#import <Foundation/Foundation.h>
-#import <QTKit/QTKit.h>
+#ifndef QWINRTCAMERAIMAGECAPTURECONTROL_H
+#define QWINRTCAMERAIMAGECAPTURECONTROL_H
-#include <QtCore/qstring.h>
-#include <QtCore/qdebug.h>
+#include <QtMultimedia/QCameraImageCaptureControl>
+#include <QtCore/qt_windows.h>
-#include "qt7backend.h"
-#include "qt7serviceplugin.h"
-#include "qt7playerservice.h"
-
-#include <qmediaserviceproviderplugin.h>
-
-QT_BEGIN_NAMESPACE
-
-
-QT7ServicePlugin::QT7ServicePlugin()
-{
- buildSupportedTypes();
+namespace ABI {
+ namespace Windows {
+ namespace Foundation {
+ struct IAsyncAction;
+ enum class AsyncStatus;
+ }
+ }
}
-QMediaService* QT7ServicePlugin::create(QString const& key)
-{
-#ifdef QT_DEBUG_QT7
- qDebug() << "QT7ServicePlugin::create" << key;
-#endif
-#ifdef QMEDIA_QT7_PLAYER
- if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
- return new QT7PlayerService;
-#endif
- qWarning() << "unsupported key:" << key;
-
- return 0;
-}
+QT_BEGIN_NAMESPACE
-void QT7ServicePlugin::release(QMediaService *service)
-{
- delete service;
-}
+class QWinRTCameraControl;
-QMediaServiceProviderHint::Features QT7ServicePlugin::supportedFeatures(
- const QByteArray &service) const
+class QWinRTCameraImageCaptureControlPrivate;
+class QWinRTCameraImageCaptureControl : public QCameraImageCaptureControl
{
- if (service == Q_MEDIASERVICE_MEDIAPLAYER)
- return QMediaServiceProviderHint::VideoSurface;
- else
- return QMediaServiceProviderHint::Features();
-}
+ Q_OBJECT
+public:
+ explicit QWinRTCameraImageCaptureControl(QWinRTCameraControl *parent);
-QMultimedia::SupportEstimate QT7ServicePlugin::hasSupport(const QString &mimeType, const QStringList& codecs) const
-{
- Q_UNUSED(codecs);
+ bool isReadyForCapture() const Q_DECL_OVERRIDE;
- if (m_supportedMimeTypes.contains(mimeType))
- return QMultimedia::ProbablySupported;
+ QCameraImageCapture::DriveMode driveMode() const Q_DECL_OVERRIDE;
+ void setDriveMode(QCameraImageCapture::DriveMode mode) Q_DECL_OVERRIDE;
- return QMultimedia::MaybeSupported;
-}
+ int capture(const QString &fileName) Q_DECL_OVERRIDE;
+ void cancelCapture() Q_DECL_OVERRIDE;
-QStringList QT7ServicePlugin::supportedMimeTypes() const
-{
- return m_supportedMimeTypes;
-}
+private:
+ HRESULT onCaptureCompleted(ABI::Windows::Foundation::IAsyncAction *,
+ ABI::Windows::Foundation::AsyncStatus);
-void QT7ServicePlugin::buildSupportedTypes()
-{
- AutoReleasePool pool;
- NSArray *utis = [QTMovie movieTypesWithOptions:QTIncludeCommonTypes];
- for (NSString *uti in utis) {
- NSString* mimeType = (NSString*)UTTypeCopyPreferredTagWithClass((CFStringRef)uti, kUTTagClassMIMEType);
- if (mimeType != 0) {
- m_supportedMimeTypes.append(QString::fromUtf8([mimeType UTF8String]));
- [mimeType release];
- }
- }
-}
+ QScopedPointer<QWinRTCameraImageCaptureControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraImageCaptureControl)
+};
QT_END_NAMESPACE
+
+#endif // QWINRTCAMERAIMAGECAPTURECONTROL_H
diff --git a/src/plugins/qt7/qt7videooutput.mm b/src/plugins/winrt/qwinrtcamerainfocontrol.cpp
index 53486c4e4..c16b83be8 100644
--- a/src/plugins/qt7/qt7videooutput.mm
+++ b/src/plugins/winrt/qwinrtcamerainfocontrol.cpp
@@ -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.
@@ -39,53 +39,22 @@
**
****************************************************************************/
-#include "qt7playercontrol.h"
-#include "qt7playersession.h"
-#include <QtCore/qdebug.h>
+#include "qwinrtcamerainfocontrol.h"
+#include "qwinrtvideodeviceselectorcontrol.h"
QT_USE_NAMESPACE
-/*
-QT7VideoOutputControl::QT7VideoOutputControl(QObject *parent)
- :QVideoOutputControl(parent),
- m_session(0),
- m_output(QVideoOutputControl::NoOutput)
+QWinRTCameraInfoControl::QWinRTCameraInfoControl(QObject *parent)
+ : QCameraInfoControl(parent)
{
}
-QT7VideoOutputControl::~QT7VideoOutputControl()
+QCamera::Position QWinRTCameraInfoControl::cameraPosition(const QString &deviceName) const
{
+ return QWinRTVideoDeviceSelectorControl::cameraPosition(deviceName);
}
-void QT7VideoOutputControl::setSession(QT7PlayerSession *session)
+int QWinRTCameraInfoControl::cameraOrientation(const QString &deviceName) const
{
- m_session = session;
+ return QWinRTVideoDeviceSelectorControl::cameraOrientation(deviceName);
}
-
-QList<QVideoOutputControl::Output> QT7VideoOutputControl::availableOutputs() const
-{
- return m_outputs;
-}
-
-void QT7VideoOutputControl::enableOutput(QVideoOutputControl::Output output)
-{
- if (!m_outputs.contains(output))
- m_outputs.append(output);
-}
-
-QVideoOutputControl::Output QT7VideoOutputControl::output() const
-{
- return m_output;
-}
-
-void QT7VideoOutputControl::setOutput(Output output)
-{
- if (m_output != output) {
- m_output = output;
- Q_EMIT videoOutputChanged(m_output);
- }
-}
-
-#include "moc_qt7videooutputcontrol.cpp"
-
-*/
diff --git a/src/plugins/qt7/qt7backend.mm b/src/plugins/winrt/qwinrtcamerainfocontrol.h
index 136220cef..bf430f038 100644
--- a/src/plugins/qt7/qt7backend.mm
+++ b/src/plugins/winrt/qwinrtcamerainfocontrol.h
@@ -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.
@@ -39,22 +39,23 @@
**
****************************************************************************/
-#include "qt7backend.h"
-
-#import <Foundation/NSAutoreleasePool.h>
-#include <CoreFoundation/CFBase.h>
+#ifndef QWINRTCAMERAINFOCONTROL_H
+#define QWINRTCAMERAINFOCONTROL_H
+#include <QtMultimedia/QCameraInfoControl>
QT_BEGIN_NAMESPACE
-AutoReleasePool::AutoReleasePool()
+class QWinRTCameraInfoControl : public QCameraInfoControl
{
- pool = (void*)[[NSAutoreleasePool alloc] init];
-}
+ Q_OBJECT
+public:
+ explicit QWinRTCameraInfoControl(QObject *parent = 0);
-AutoReleasePool::~AutoReleasePool()
-{
- [(NSAutoreleasePool*)pool release];
-}
+ QCamera::Position cameraPosition(const QString &deviceName) const Q_DECL_OVERRIDE;
+ int cameraOrientation(const QString &deviceName) const Q_DECL_OVERRIDE;
+};
QT_END_NAMESPACE
+
+#endif // QWINRTCAMERAINFOCONTROL_H
diff --git a/src/plugins/winrt/qwinrtcameraservice.cpp b/src/plugins/winrt/qwinrtcameraservice.cpp
new file mode 100644
index 000000000..239a1e883
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameraservice.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcameraservice.h"
+#include "qwinrtcameracontrol.h"
+#include "qwinrtcamerainfocontrol.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QPointer>
+#include <QtMultimedia/QCameraImageCaptureControl>
+#include <QtMultimedia/QVideoRendererControl>
+#include <QtMultimedia/QVideoDeviceSelectorControl>
+
+QT_USE_NAMESPACE
+
+class QWinRTCameraServicePrivate
+{
+public:
+ QPointer<QWinRTCameraControl> cameraControl;
+ QPointer<QWinRTCameraInfoControl> cameraInfoControl;
+};
+
+QWinRTCameraService::QWinRTCameraService(QObject *parent)
+ : QMediaService(parent), d_ptr(new QWinRTCameraServicePrivate)
+{
+}
+
+QMediaControl *QWinRTCameraService::requestControl(const char *name)
+{
+ Q_D(QWinRTCameraService);
+
+ if (qstrcmp(name, QCameraControl_iid) == 0) {
+ if (!d->cameraControl)
+ d->cameraControl = new QWinRTCameraControl(this);
+ return d->cameraControl;
+ }
+
+ if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+ if (d->cameraControl)
+ return d->cameraControl->videoRenderer();
+ }
+
+ if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) {
+ if (d->cameraControl)
+ return d->cameraControl->videoDeviceSelector();
+ }
+
+ if (qstrcmp(name, QCameraInfoControl_iid) == 0) {
+ if (!d->cameraInfoControl)
+ d->cameraInfoControl = new QWinRTCameraInfoControl(this);
+ return d->cameraInfoControl;
+ }
+
+ if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) {
+ if (d->cameraControl)
+ return d->cameraControl->imageCaptureControl();
+ }
+
+ return Q_NULLPTR;
+}
+
+void QWinRTCameraService::releaseControl(QMediaControl *control)
+{
+ Q_UNUSED(control);
+}
diff --git a/src/plugins/winrt/qwinrtcameraservice.h b/src/plugins/winrt/qwinrtcameraservice.h
new file mode 100644
index 000000000..19e93a818
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameraservice.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCAMERASERVICE_H
+#define QWINRTCAMERASERVICE_H
+
+#include <QtMultimedia/QMediaService>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCameraServicePrivate;
+class QWinRTCameraService : public QMediaService
+{
+ Q_OBJECT
+public:
+ explicit QWinRTCameraService(QObject *parent = 0);
+
+ QMediaControl *requestControl(const char *name) Q_DECL_OVERRIDE;
+ void releaseControl(QMediaControl *control) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWinRTCameraServicePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraService)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCAMERASERVICE_H
diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp
new file mode 100644
index 000000000..e7e75da27
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcameravideorenderercontrol.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QSize>
+#include <QtCore/QVector>
+
+#include <d3d11.h>
+#include <mfapi.h>
+#include <wrl.h>
+using namespace Microsoft::WRL;
+
+QT_USE_NAMESPACE
+
+class D3DVideoBlitter
+{
+public:
+ D3DVideoBlitter(ID3D11Device *device, ID3D11Texture2D *target)
+ : m_d3dDevice(device), m_target(target)
+ {
+ HRESULT hr;
+ ComPtr<IDXGIResource> targetResource;
+ hr = target->QueryInterface(IID_PPV_ARGS(&targetResource));
+ Q_ASSERT_SUCCEEDED(hr);
+ HANDLE sharedHandle;
+ hr = targetResource->GetSharedHandle(&sharedHandle);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = m_d3dDevice->OpenSharedResource(sharedHandle, IID_PPV_ARGS(&m_targetTexture));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = m_d3dDevice.As(&m_videoDevice);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ ID3D11Device *device() const
+ {
+ return m_d3dDevice.Get();
+ }
+
+ ID3D11Texture2D *target() const
+ {
+ return m_target;
+ }
+
+ void blit(ID3D11Texture2D *texture)
+ {
+ HRESULT hr;
+ D3D11_TEXTURE2D_DESC desc;
+ texture->GetDesc(&desc);
+ if (!m_videoEnumerator) {
+ D3D11_VIDEO_PROCESSOR_CONTENT_DESC videoProcessorDesc = {
+ D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE,
+ { 0 }, desc.Width, desc.Height,
+ { 0 }, desc.Width, desc.Height,
+ D3D11_VIDEO_USAGE_PLAYBACK_NORMAL
+ };
+ hr = m_videoDevice->CreateVideoProcessorEnumerator(&videoProcessorDesc, &m_videoEnumerator);
+ RETURN_VOID_IF_FAILED("Failed to create video enumerator");
+ }
+
+ if (!m_videoProcessor) {
+ hr = m_videoDevice->CreateVideoProcessor(m_videoEnumerator.Get(), 0, &m_videoProcessor);
+ RETURN_VOID_IF_FAILED("Failed to create video processor");
+ }
+
+ if (!m_outputView) {
+ D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D };
+ hr = m_videoDevice->CreateVideoProcessorOutputView(
+ m_targetTexture.Get(), m_videoEnumerator.Get(), &outputDesc, &m_outputView);
+ RETURN_VOID_IF_FAILED("Failed to create video output view");
+ }
+
+ D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = {
+ 0, D3D11_VPIV_DIMENSION_TEXTURE2D, { 0, 0 }
+ };
+ ComPtr<ID3D11VideoProcessorInputView> inputView;
+ hr = m_videoDevice->CreateVideoProcessorInputView(
+ texture, m_videoEnumerator.Get(), &inputViewDesc, &inputView);
+ RETURN_VOID_IF_FAILED("Failed to create video input view");
+
+ ComPtr<ID3D11DeviceContext> context;
+ ComPtr<ID3D11VideoContext> videoContext;
+ m_d3dDevice->GetImmediateContext(&context);
+ hr = context.As(&videoContext);
+ RETURN_VOID_IF_FAILED("Failed to get video context");
+
+ D3D11_VIDEO_PROCESSOR_STREAM stream = { TRUE };
+ stream.pInputSurface = inputView.Get();
+ hr = videoContext->VideoProcessorBlt(
+ m_videoProcessor.Get(), m_outputView.Get(), 0, 1, &stream);
+ RETURN_VOID_IF_FAILED("Failed to get blit video frame");
+ }
+
+private:
+ ComPtr<ID3D11Device> m_d3dDevice;
+ ComPtr<ID3D11Texture2D> m_targetTexture;
+ ID3D11Texture2D *m_target;
+ ComPtr<ID3D11VideoDevice> m_videoDevice;
+ ComPtr<ID3D11VideoProcessorEnumerator> m_videoEnumerator;
+ ComPtr<ID3D11VideoProcessor> m_videoProcessor;
+ ComPtr<ID3D11VideoProcessorOutputView> m_outputView;
+};
+
+class QWinRTCameraVideoRendererControlPrivate
+{
+public:
+ QScopedPointer<D3DVideoBlitter> blitter;
+ QVector<ComPtr<IMF2DBuffer>> buffers;
+};
+
+QWinRTCameraVideoRendererControl::QWinRTCameraVideoRendererControl(const QSize &size, QObject *parent)
+ : QWinRTAbstractVideoRendererControl(size, parent), d_ptr(new QWinRTCameraVideoRendererControlPrivate)
+{
+}
+
+QWinRTCameraVideoRendererControl::~QWinRTCameraVideoRendererControl()
+{
+ shutdown();
+}
+
+bool QWinRTCameraVideoRendererControl::render(ID3D11Texture2D *target)
+{
+ Q_D(QWinRTCameraVideoRendererControl);
+
+ if (d->buffers.isEmpty()) {
+ emit bufferRequested();
+ return false;
+ }
+
+ HRESULT hr;
+ ComPtr<IMF2DBuffer> buffer = d->buffers.takeFirst();
+
+ ComPtr<ID3D11Texture2D> sourceTexture;
+ ComPtr<IMFDXGIBuffer> dxgiBuffer;
+ hr = buffer.As(&dxgiBuffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = dxgiBuffer->GetResource(IID_PPV_ARGS(&sourceTexture));
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "The video frame does not support texture output; aborting rendering.");
+ return false;
+ }
+
+ ComPtr<ID3D11Device> device;
+ sourceTexture->GetDevice(&device);
+ if (!d->blitter || d->blitter->device() != device.Get() || d->blitter->target() != target)
+ d->blitter.reset(new D3DVideoBlitter(device.Get(), target));
+
+ d->blitter->blit(sourceTexture.Get());
+
+ emit bufferRequested();
+ return true;
+}
+
+void QWinRTCameraVideoRendererControl::queueBuffer(IMF2DBuffer *buffer)
+{
+ Q_D(QWinRTCameraVideoRendererControl);
+ Q_ASSERT(buffer);
+ d->buffers.append(buffer);
+}
+
+void QWinRTCameraVideoRendererControl::discardBuffers()
+{
+ Q_D(QWinRTCameraVideoRendererControl);
+ d->buffers.clear();
+}
diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.h b/src/plugins/winrt/qwinrtcameravideorenderercontrol.h
new file mode 100644
index 000000000..ed8b3388d
--- /dev/null
+++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCAMERAVIDEORENDERERCONTROL_H
+#define QWINRTCAMERAVIDEORENDERERCONTROL_H
+
+#include "qwinrtabstractvideorenderercontrol.h"
+
+struct IMF2DBuffer;
+
+QT_BEGIN_NAMESPACE
+
+class QVideoSurfaceFormat;
+class QWinRTCameraVideoRendererControlPrivate;
+class QWinRTCameraVideoRendererControl : public QWinRTAbstractVideoRendererControl
+{
+ Q_OBJECT
+public:
+ explicit QWinRTCameraVideoRendererControl(const QSize &size, QObject *parent);
+ ~QWinRTCameraVideoRendererControl();
+
+ bool render(ID3D11Texture2D *texture) Q_DECL_OVERRIDE;
+ void queueBuffer(IMF2DBuffer *buffer);
+ void discardBuffers();
+
+signals:
+ void bufferRequested();
+
+private:
+ QScopedPointer<QWinRTCameraVideoRendererControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTCameraVideoRendererControl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCAMERAVIDEORENDERERCONTROL_H
diff --git a/src/plugins/winrt/qwinrtserviceplugin.cpp b/src/plugins/winrt/qwinrtserviceplugin.cpp
index 5d49b44a4..036d63e39 100644
--- a/src/plugins/winrt/qwinrtserviceplugin.cpp
+++ b/src/plugins/winrt/qwinrtserviceplugin.cpp
@@ -44,6 +44,8 @@
#include "qwinrtserviceplugin.h"
#include "qwinrtmediaplayerservice.h"
+#include "qwinrtcameraservice.h"
+#include "qwinrtvideodeviceselectorcontrol.h"
QT_USE_NAMESPACE
@@ -52,6 +54,9 @@ QMediaService *QWinRTServicePlugin::create(QString const &key)
if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
return new QWinRTMediaPlayerService(this);
+ if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
+ return new QWinRTCameraService(this);
+
return Q_NULLPTR;
}
@@ -68,3 +73,37 @@ QMediaServiceProviderHint::Features QWinRTServicePlugin::supportedFeatures(
return QMediaServiceProviderHint::Features();
}
+
+QCamera::Position QWinRTServicePlugin::cameraPosition(const QByteArray &device) const
+{
+ return QWinRTVideoDeviceSelectorControl::cameraPosition(device);
+}
+
+int QWinRTServicePlugin::cameraOrientation(const QByteArray &device) const
+{
+ return QWinRTVideoDeviceSelectorControl::cameraOrientation(device);
+}
+
+QList<QByteArray> QWinRTServicePlugin::devices(const QByteArray &service) const
+{
+ if (service == Q_MEDIASERVICE_CAMERA)
+ return QWinRTVideoDeviceSelectorControl::deviceNames();
+
+ return QList<QByteArray>();
+}
+
+QString QWinRTServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
+{
+ if (service == Q_MEDIASERVICE_CAMERA)
+ return QWinRTVideoDeviceSelectorControl::deviceDescription(device);
+
+ return QString();
+}
+
+QByteArray QWinRTServicePlugin::defaultDevice(const QByteArray &service) const
+{
+ if (service == Q_MEDIASERVICE_CAMERA)
+ return QWinRTVideoDeviceSelectorControl::defaultDeviceName();
+
+ return QByteArray();
+}
diff --git a/src/plugins/winrt/qwinrtserviceplugin.h b/src/plugins/winrt/qwinrtserviceplugin.h
index aaac79c7b..9fabadb4f 100644
--- a/src/plugins/winrt/qwinrtserviceplugin.h
+++ b/src/plugins/winrt/qwinrtserviceplugin.h
@@ -48,15 +48,29 @@ QT_USE_NAMESPACE
class QWinRTServicePlugin : public QMediaServiceProviderPlugin
, public QMediaServiceFeaturesInterface
+ , public QMediaServiceCameraInfoInterface
+ , public QMediaServiceSupportedDevicesInterface
+ , public QMediaServiceDefaultDeviceInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceFeaturesInterface)
+ Q_INTERFACES(QMediaServiceCameraInfoInterface)
+ Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
+ Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "winrt.json")
public:
QMediaService *create(QString const &key);
void release(QMediaService *service);
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
+
+ QCamera::Position cameraPosition(const QByteArray &device) const Q_DECL_OVERRIDE;
+ int cameraOrientation(const QByteArray &device) const Q_DECL_OVERRIDE;
+
+ QList<QByteArray> devices(const QByteArray &service) const Q_DECL_OVERRIDE;
+ QString deviceDescription(const QByteArray &service, const QByteArray &device) Q_DECL_OVERRIDE;
+
+ QByteArray defaultDevice(const QByteArray &service) const Q_DECL_OVERRIDE;
};
#endif // QWINRTSERVICEPLUGIN_H
diff --git a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp
new file mode 100644
index 000000000..8058c3dad
--- /dev/null
+++ b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.cpp
@@ -0,0 +1,383 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtvideodeviceselectorcontrol.h"
+
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/QVector>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QEventLoop>
+#include <QtCore/QGlobalStatic>
+
+#include <wrl.h>
+#include <windows.devices.enumeration.h>
+
+using namespace ABI::Windows::Devices::Enumeration;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+typedef ITypedEventHandler<DeviceWatcher *, DeviceInformation *> DeviceInformationHandler;
+typedef ITypedEventHandler<DeviceWatcher *, DeviceInformationUpdate *> DeviceInformationUpdateHandler;
+typedef ITypedEventHandler<DeviceWatcher *, IInspectable *> DeviceEnumerationCompletedHandler;
+
+QT_USE_NAMESPACE
+
+static QString deviceName(IDeviceInformation *device)
+{
+ HRESULT hr;
+ HString id;
+ hr = device->get_Id(id.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 length;
+ const wchar_t *buffer = id.GetRawBuffer(&length);
+ return QString::fromWCharArray(buffer, length);
+}
+
+static QString deviceDescription(IDeviceInformation *device)
+{
+ HRESULT hr;
+ HString name;
+ hr = device->get_Name(name.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 length;
+ const wchar_t *buffer = name.GetRawBuffer(&length);
+ return QString::fromWCharArray(buffer, length);
+}
+
+struct QWinRTVideoDeviceSelectorControlGlobal
+{
+ QWinRTVideoDeviceSelectorControlGlobal()
+ : defaultDeviceIndex(-1)
+ {
+ HRESULT hr;
+ ComPtr<IDeviceInformationStatics> deviceWatcherFactory;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(),
+ IID_PPV_ARGS(&deviceWatcherFactory));
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = deviceWatcherFactory->CreateWatcherDeviceClass(DeviceClass_VideoCapture, &deviceWatcher);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = deviceWatcher->add_Added(
+ Callback<DeviceInformationHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceAdded).Get(),
+ &deviceAddedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = deviceWatcher->add_Removed(
+ Callback<DeviceInformationUpdateHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceRemoved).Get(),
+ &deviceRemovedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = deviceWatcher->add_Updated(
+ Callback<DeviceInformationUpdateHandler>(this, &QWinRTVideoDeviceSelectorControlGlobal::onDeviceUpdated).Get(),
+ &deviceUpdatedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // Synchronously populate the devices on construction
+ ComPtr<IAsyncOperation<DeviceInformationCollection *>> op;
+ hr = deviceWatcherFactory->FindAllAsyncDeviceClass(DeviceClass_VideoCapture, &op);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IVectorView<DeviceInformation *>> deviceList;
+ hr = QWinRTFunctions::await(op, deviceList.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 deviceCount;
+ hr = deviceList->get_Size(&deviceCount);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (quint32 i = 0; i < deviceCount; ++i) {
+ IDeviceInformation *device;
+ hr = deviceList->GetAt(i, &device);
+ Q_ASSERT_SUCCEEDED(hr);
+ onDeviceAdded(Q_NULLPTR, device);
+ }
+
+ // If there is no default device provided by the API, choose the first one
+ if (!devices.isEmpty() && defaultDeviceIndex < 0)
+ defaultDeviceIndex = 0;
+ }
+
+ ~QWinRTVideoDeviceSelectorControlGlobal()
+ {
+ HRESULT hr;
+ hr = deviceWatcher->remove_Added(deviceAddedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = deviceWatcher->remove_Removed(deviceRemovedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = deviceWatcher->remove_Updated(deviceUpdatedToken);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+private:
+ HRESULT onDeviceAdded(IDeviceWatcher *, IDeviceInformation *device)
+ {
+ const QString name = deviceName(device);
+ if (deviceIndex.contains(name))
+ return S_OK;
+
+ devices.append(device);
+ const int index = devices.size() - 1;
+ deviceIndex.insert(name, index);
+
+ HRESULT hr;
+ boolean isDefault;
+ hr = device->get_IsDefault(&isDefault);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (isDefault)
+ defaultDeviceIndex = index;
+
+ foreach (QWinRTVideoDeviceSelectorControl *watcher, watchers)
+ emit watcher->devicesChanged();
+
+ return S_OK;
+ }
+
+ HRESULT onDeviceRemoved(IDeviceWatcher *, IDeviceInformationUpdate *device)
+ {
+ HRESULT hr;
+ HString id;
+ hr = device->get_Id(id.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+
+ HString name;
+ hr = device->get_Id(name.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ quint32 nameLength;
+ const wchar_t *nameString = name.GetRawBuffer(&nameLength);
+ const int index = deviceIndex.take(QString::fromWCharArray(nameString, nameLength));
+ if (index >= 0)
+ devices.remove(index);
+
+ foreach (QWinRTVideoDeviceSelectorControl *watcher, watchers)
+ emit watcher->devicesChanged();
+
+ return S_OK;
+ }
+
+ HRESULT onDeviceUpdated(IDeviceWatcher *, IDeviceInformationUpdate *)
+ {
+ // A name or description may have changed, so emit devicesChanged
+ foreach (QWinRTVideoDeviceSelectorControl *watcher, watchers)
+ emit watcher->devicesChanged();
+
+ return S_OK;
+ }
+
+public:
+ void addWatcher(QWinRTVideoDeviceSelectorControl *control)
+ {
+ watchers.append(control);
+
+ HRESULT hr;
+ DeviceWatcherStatus status;
+ hr = deviceWatcher->get_Status(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (status != DeviceWatcherStatus_Started) {
+ // We can't immediately Start() if we have just called Stop()
+ while (status == DeviceWatcherStatus_Stopping) {
+ QThread::yieldCurrentThread();
+ hr = deviceWatcher->get_Status(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ hr = deviceWatcher->Start();
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ }
+
+ void removeWatcher(QWinRTVideoDeviceSelectorControl *control)
+ {
+ watchers.removeAll(control);
+
+ if (!watchers.isEmpty())
+ return;
+
+ HRESULT hr;
+ DeviceWatcherStatus status;
+ hr = deviceWatcher->get_Status(&status);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (status == DeviceWatcherStatus_Stopped || status == DeviceWatcherStatus_Stopping)
+ return;
+
+ hr = deviceWatcher->Stop();
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ QVector<ComPtr<IDeviceInformation>> devices;
+ QHash<QString, int> deviceIndex;
+ int defaultDeviceIndex;
+
+private:
+ ComPtr<IDeviceWatcher> deviceWatcher;
+ QList<QWinRTVideoDeviceSelectorControl *> watchers;
+ EventRegistrationToken deviceAddedToken;
+ EventRegistrationToken deviceRemovedToken;
+ EventRegistrationToken deviceUpdatedToken;
+};
+Q_GLOBAL_STATIC(QWinRTVideoDeviceSelectorControlGlobal, g)
+
+class QWinRTVideoDeviceSelectorControlPrivate
+{
+public:
+ int selectedDevice;
+};
+
+QWinRTVideoDeviceSelectorControl::QWinRTVideoDeviceSelectorControl(QObject *parent)
+ : QVideoDeviceSelectorControl(parent), d_ptr(new QWinRTVideoDeviceSelectorControlPrivate)
+{
+ Q_D(QWinRTVideoDeviceSelectorControl);
+ d->selectedDevice = -1;
+ g->addWatcher(this);
+}
+
+QWinRTVideoDeviceSelectorControl::~QWinRTVideoDeviceSelectorControl()
+{
+ if (g.isDestroyed())
+ return;
+
+ g->removeWatcher(this);
+}
+
+int QWinRTVideoDeviceSelectorControl::deviceCount() const
+{
+ return g->devices.size();
+}
+
+QString QWinRTVideoDeviceSelectorControl::deviceName(int index) const
+{
+ if (index < 0 || index >= g->devices.size())
+ return QString();
+
+ return ::deviceName(g->devices.at(index).Get());
+}
+
+QString QWinRTVideoDeviceSelectorControl::deviceDescription(int index) const
+{
+ if (index < 0 || index >= g->devices.size())
+ return QString();
+
+ return ::deviceDescription(g->devices.at(index).Get());
+}
+
+int QWinRTVideoDeviceSelectorControl::defaultDevice() const
+{
+ return g->defaultDeviceIndex;
+}
+
+int QWinRTVideoDeviceSelectorControl::selectedDevice() const
+{
+ Q_D(const QWinRTVideoDeviceSelectorControl);
+ return d->selectedDevice;
+}
+
+QCamera::Position QWinRTVideoDeviceSelectorControl::cameraPosition(const QString &deviceName)
+{
+ int deviceIndex = g->deviceIndex.value(deviceName);
+ IDeviceInformation *deviceInfo = g->devices.value(deviceIndex).Get();
+ if (!deviceInfo)
+ return QCamera::UnspecifiedPosition;
+
+ ComPtr<IEnclosureLocation> enclosureLocation;
+ HRESULT hr;
+ hr = deviceInfo->get_EnclosureLocation(&enclosureLocation);
+ RETURN_IF_FAILED("Failed to get camera enclosure location", return QCamera::UnspecifiedPosition);
+ if (!enclosureLocation)
+ return QCamera::UnspecifiedPosition;
+
+ Panel panel;
+ hr = enclosureLocation->get_Panel(&panel);
+ RETURN_IF_FAILED("Failed to get camera panel location", return QCamera::UnspecifiedPosition);
+
+ switch (panel) {
+ case Panel_Front:
+ return QCamera::FrontFace;
+ case Panel_Back:
+ return QCamera::BackFace;
+ default:
+ break;
+ }
+ return QCamera::UnspecifiedPosition;
+}
+
+int QWinRTVideoDeviceSelectorControl::cameraOrientation(const QString &deviceName)
+{
+ Q_UNUSED(deviceName);
+ return 0;
+}
+
+QList<QByteArray> QWinRTVideoDeviceSelectorControl::deviceNames()
+{
+ QList<QByteArray> devices;
+ foreach (const QString &device, g->deviceIndex.keys())
+ devices.append(device.toUtf8());
+
+ return devices;
+}
+
+QByteArray QWinRTVideoDeviceSelectorControl::deviceDescription(const QByteArray &deviceName)
+{
+ int deviceIndex = g->deviceIndex.value(QString::fromUtf8(deviceName), -1);
+ if (deviceIndex < 0)
+ return QByteArray();
+
+ return ::deviceDescription(g->devices.value(deviceIndex).Get()).toUtf8();
+}
+
+QByteArray QWinRTVideoDeviceSelectorControl::defaultDeviceName()
+{
+ if (g->defaultDeviceIndex < 0)
+ return QByteArray();
+
+ return ::deviceName(g->devices.value(g->defaultDeviceIndex).Get()).toUtf8();
+}
+
+void QWinRTVideoDeviceSelectorControl::setSelectedDevice(int index)
+{
+ Q_D(QWinRTVideoDeviceSelectorControl);
+
+ int selectedDevice = index;
+ if (index < 0 || index >= g->devices.size())
+ selectedDevice = -1;
+
+ if (d->selectedDevice != selectedDevice) {
+ d->selectedDevice = selectedDevice;
+ emit selectedDeviceChanged(d->selectedDevice);
+ emit selectedDeviceChanged(deviceName(d->selectedDevice));
+ }
+}
diff --git a/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h
new file mode 100644
index 000000000..2143b3ea8
--- /dev/null
+++ b/src/plugins/winrt/qwinrtvideodeviceselectorcontrol.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTVIDEODEVICESELECTORCONTROL_H
+#define QWINRTVIDEODEVICESELECTORCONTROL_H
+
+#include <QtMultimedia/QVideoDeviceSelectorControl>
+#include <QtMultimedia/QCameraInfoControl>
+#include <QtCore/qt_windows.h>
+
+struct IInspectable;
+namespace ABI {
+ namespace Windows {
+ namespace Devices {
+ namespace Enumeration {
+ struct IDeviceInformation;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTVideoDeviceSelectorControlPrivate;
+class QWinRTVideoDeviceSelectorControl : public QVideoDeviceSelectorControl
+{
+ Q_OBJECT
+public:
+ explicit QWinRTVideoDeviceSelectorControl(QObject *parent = 0);
+ ~QWinRTVideoDeviceSelectorControl();
+
+ int deviceCount() const Q_DECL_OVERRIDE;
+
+ QString deviceName(int index) const Q_DECL_OVERRIDE;
+ QString deviceDescription(int index) const Q_DECL_OVERRIDE;
+
+ int defaultDevice() const Q_DECL_OVERRIDE;
+ int selectedDevice() const Q_DECL_OVERRIDE;
+
+ static QCamera::Position cameraPosition(const QString &deviceName);
+ static int cameraOrientation(const QString &deviceName);
+ static QList<QByteArray> deviceNames();
+ static QByteArray deviceDescription(const QByteArray &deviceName);
+ static QByteArray defaultDeviceName();
+
+public slots:
+ void setSelectedDevice(int index) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWinRTVideoDeviceSelectorControlPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QWinRTVideoDeviceSelectorControl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTVIDEODEVICESELECTORCONTROL_H
diff --git a/src/plugins/winrt/winrt.json b/src/plugins/winrt/winrt.json
index b85cfeb12..9af79cc37 100644
--- a/src/plugins/winrt/winrt.json
+++ b/src/plugins/winrt/winrt.json
@@ -1,4 +1,4 @@
{
"Keys": ["winrt"],
- "Services": ["org.qt-project.qt.mediaplayer"]
+ "Services": ["org.qt-project.qt.mediaplayer", "org.qt-project.qt.camera"]
}
diff --git a/src/plugins/winrt/winrt.pro b/src/plugins/winrt/winrt.pro
index 0ea90d22e..04db71e75 100644
--- a/src/plugins/winrt/winrt.pro
+++ b/src/plugins/winrt/winrt.pro
@@ -5,21 +5,33 @@ PLUGIN_TYPE=mediaservice
PLUGIN_CLASS_NAME = WinRTServicePlugin
load(qt_plugin)
-LIBS += -lmfplat -lmfuuid -loleaut32 -ld3d11
+LIBS += -lmfplat -lmfuuid -loleaut32 -ld3d11 -lruntimeobject
HEADERS += \
qwinrtabstractvideorenderercontrol.h \
+ qwinrtcameracontrol.h \
+ qwinrtcamerainfocontrol.h \
+ qwinrtcameraimagecapturecontrol.h \
+ qwinrtcameraservice.h \
+ qwinrtcameravideorenderercontrol.h \
qwinrtmediaplayercontrol.h \
qwinrtmediaplayerservice.h \
qwinrtplayerrenderercontrol.h \
- qwinrtserviceplugin.h
+ qwinrtserviceplugin.h \
+ qwinrtvideodeviceselectorcontrol.h
SOURCES += \
qwinrtabstractvideorenderercontrol.cpp \
+ qwinrtcameracontrol.cpp \
+ qwinrtcamerainfocontrol.cpp \
+ qwinrtcameraimagecapturecontrol.cpp \
+ qwinrtcameraservice.cpp \
+ qwinrtcameravideorenderercontrol.cpp \
qwinrtmediaplayercontrol.cpp \
qwinrtmediaplayerservice.cpp \
qwinrtplayerrenderercontrol.cpp \
- qwinrtserviceplugin.cpp
+ qwinrtserviceplugin.cpp \
+ qwinrtvideodeviceselectorcontrol.cpp
OTHER_FILES += \
winrt.json
diff --git a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
index 93c1841bc..da69f926f 100644
--- a/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
+++ b/src/plugins/wmf/decoder/mfaudiodecodercontrol.cpp
@@ -236,7 +236,6 @@ void MFAudioDecoderControl::handleMediaSourceReady()
}
if (m_sourceResolver->mediaSource()) {
- IMFPresentationDescriptor *pd = 0;
if (mediaType && m_resampler) {
HRESULT hr = S_OK;
hr = m_resampler->SetInputType(m_mfInputStreamID, mediaType, 0);
@@ -246,9 +245,11 @@ void MFAudioDecoderControl::handleMediaSourceReady()
qWarning() << "MFAudioDecoderControl: failed to SetInputType of resampler" << hr;
}
}
+ IMFPresentationDescriptor *pd;
if (SUCCEEDED(m_sourceResolver->mediaSource()->CreatePresentationDescriptor(&pd))) {
UINT64 duration = 0;
pd->GetUINT64(MF_PD_DURATION, &duration);
+ pd->Release();
duration /= 10000;
if (m_duration != qint64(duration)) {
m_duration = qint64(duration);
diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp
index a1b63321c..42d0dea4e 100644
--- a/src/plugins/wmf/evrd3dpresentengine.cpp
+++ b/src/plugins/wmf/evrd3dpresentengine.cpp
@@ -48,7 +48,6 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
#include <d3d9.h>
#include <dxva2api.h>
#include <WinUser.h>
@@ -331,34 +330,36 @@ void D3DPresentEngine::presentSample(void *opaque, qint64)
IMFMediaBuffer* buffer = NULL;
IDirect3DSurface9* surface = NULL;
- if (sample) {
- // Get the buffer from the sample.
- hr = sample->GetBufferByIndex(0, &buffer);
- if (FAILED(hr))
- goto done;
+ if (m_surface && m_surface->isActive()) {
+ if (sample) {
+ // Get the buffer from the sample.
+ hr = sample->GetBufferByIndex(0, &buffer);
+ if (FAILED(hr))
+ goto done;
+
+ // Get the surface from the buffer.
+ hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
+ if (FAILED(hr))
+ goto done;
+ }
- // Get the surface from the buffer.
- hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
- if (FAILED(hr))
- goto done;
- }
+ if (surface && updateTexture(surface)) {
+ QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture),
+ m_surfaceFormat.frameSize(),
+ m_surfaceFormat.pixelFormat());
- if (surface && updateTexture(surface)) {
- QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat());
+ // WMF uses 100-nanosecond units, Qt uses microseconds
+ LONGLONG startTime = -1;
+ if (SUCCEEDED(sample->GetSampleTime(&startTime))) {
+ frame.setStartTime(startTime * 0.1);
- // WMF uses 100-nanosecond units, Qt uses microseconds
- LONGLONG startTime = -1;
- if (SUCCEEDED(sample->GetSampleTime(&startTime))) {
- frame.setStartTime(startTime * 0.1);
+ LONGLONG duration = -1;
+ if (SUCCEEDED(sample->GetSampleDuration(&duration)))
+ frame.setEndTime((startTime + duration) * 0.1);
+ }
- LONGLONG duration = -1;
- if (SUCCEEDED(sample->GetSampleDuration(&duration)))
- frame.setEndTime((startTime + duration) * 0.1);
+ m_surface->present(frame);
}
-
- m_surface->present(frame);
}
done:
@@ -420,18 +421,19 @@ void D3DPresentEngine::createOffscreenTexture()
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
m_eglDisplay = static_cast<EGLDisplay*>(
nativeInterface->nativeResourceForContext("eglDisplay", currentContext));
- m_eglConfig = static_cast<EGLDisplay*>(
+ m_eglConfig = static_cast<EGLConfig*>(
nativeInterface->nativeResourceForContext("eglConfig", currentContext));
currentContext->functions()->glGenTextures(1, &m_glTexture);
int w = m_surfaceFormat.frameWidth();
int h = m_surfaceFormat.frameHeight();
+ bool hasAlpha = currentContext->format().hasAlpha();
EGLint attribs[] = {
EGL_WIDTH, w,
EGL_HEIGHT, h,
- EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
+ EGL_TEXTURE_FORMAT, hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
EGL_NONE
};
@@ -450,7 +452,7 @@ void D3DPresentEngine::createOffscreenTexture()
m_device->CreateTexture(w, h, 1,
D3DUSAGE_RENDERTARGET,
- D3DFMT_X8R8G8B8,
+ hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&m_texture,
&share_handle);
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index 77b19f1b0..08baa779a 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -258,6 +258,7 @@ void MFPlayerSession::handleMediaSourceReady()
//convert from 100 nanosecond to milisecond
emit durationUpdate(qint64(m_duration / 10000));
setupPlaybackTopology(mediaSource, sourcePD);
+ sourcePD->Release();
} else {
changeStatus(QMediaPlayer::InvalidMedia);
emit error(QMediaPlayer::ResourceError, tr("Cannot create presentation descriptor."), true);
@@ -415,12 +416,15 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc,
if (SUCCEEDED(hr)) {
hr = node->SetUINT32(MF_TOPONODE_STREAMID, sinkID);
if (SUCCEEDED(hr)) {
- if (SUCCEEDED(topology->AddNode(node)))
+ if (SUCCEEDED(topology->AddNode(node))) {
+ handler->Release();
return node;
+ }
}
}
}
}
+ handler->Release();
}
node->Release();
return NULL;
@@ -609,42 +613,39 @@ HRESULT BindOutputNode(IMFTopologyNode *pNode)
// Sets the IMFStreamSink pointers on all of the output nodes in a topology.
HRESULT BindOutputNodes(IMFTopology *pTopology)
{
- DWORD cNodes = 0;
-
- IMFCollection *collection = NULL;
- IUnknown *element = NULL;
- IMFTopologyNode *node = NULL;
+ IMFCollection *collection;
// Get the collection of output nodes.
HRESULT hr = pTopology->GetOutputNodeCollection(&collection);
// Enumerate all of the nodes in the collection.
- if (SUCCEEDED(hr))
+ if (SUCCEEDED(hr)) {
+ DWORD cNodes;
hr = collection->GetElementCount(&cNodes);
- if (SUCCEEDED(hr)) {
- for (DWORD i = 0; i < cNodes; i++) {
- hr = collection->GetElement(i, &element);
- if (FAILED(hr))
- break;
+ if (SUCCEEDED(hr)) {
+ for (DWORD i = 0; i < cNodes; i++) {
+ IUnknown *element;
+ hr = collection->GetElement(i, &element);
+ if (FAILED(hr))
+ break;
- hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
- if (FAILED(hr))
- break;
+ IMFTopologyNode *node;
+ hr = element->QueryInterface(IID_IMFTopologyNode, (void**)&node);
+ element->Release();
+ if (FAILED(hr))
+ break;
- // Bind this node.
- hr = BindOutputNode(node);
- if (FAILED(hr))
- break;
+ // Bind this node.
+ hr = BindOutputNode(node);
+ node->Release();
+ if (FAILED(hr))
+ break;
+ }
}
+ collection->Release();
}
- if (collection)
- collection->Release();
- if (element)
- element->Release();
- if (node)
- node->Release();
return hr;
}
@@ -1395,14 +1396,17 @@ int MFPlayerSession::bufferStatus()
if (!m_netsourceStatistics)
return 0;
PROPVARIANT var;
+ PropVariantInit(&var);
PROPERTYKEY key;
key.fmtid = MFNETSOURCE_STATISTICS;
key.pid = MFNETSOURCE_BUFFERPROGRESS_ID;
int progress = -1;
- if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) {
+ // GetValue returns S_FALSE if the property is not available, which has
+ // a value > 0. We therefore can't use the SUCCEEDED macro here.
+ if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
progress = var.lVal;
+ PropVariantClear(&var);
}
- PropVariantClear(&var);
#ifdef DEBUG_MEDIAFOUNDATION
qDebug() << "bufferStatus: progress = " << progress;
@@ -1413,22 +1417,30 @@ int MFPlayerSession::bufferStatus()
QMediaTimeRange MFPlayerSession::availablePlaybackRanges()
{
- if (!m_netsourceStatistics)
- return QMediaTimeRange();
+ // defaults to the whole media
+ qint64 start = 0;
+ qint64 end = qint64(m_duration / 10000);
- qint64 start = 0, end = 0;
- PROPVARIANT var;
- PROPERTYKEY key;
- key.fmtid = MFNETSOURCE_STATISTICS;
- key.pid = MFNETSOURCE_SEEKRANGESTART_ID;
- if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) {
- start = qint64(var.uhVal.QuadPart / 10000);
- key.pid = MFNETSOURCE_SEEKRANGEEND_ID;
- if (SUCCEEDED(m_netsourceStatistics->GetValue(key, &var))) {
- end = qint64(var.uhVal.QuadPart / 10000);
+ if (m_netsourceStatistics) {
+ PROPVARIANT var;
+ PropVariantInit(&var);
+ PROPERTYKEY key;
+ key.fmtid = MFNETSOURCE_STATISTICS;
+ key.pid = MFNETSOURCE_SEEKRANGESTART_ID;
+ // GetValue returns S_FALSE if the property is not available, which has
+ // a value > 0. We therefore can't use the SUCCEEDED macro here.
+ if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
+ start = qint64(var.uhVal.QuadPart / 10000);
+ PropVariantClear(&var);
+ PropVariantInit(&var);
+ key.pid = MFNETSOURCE_SEEKRANGEEND_ID;
+ if (m_netsourceStatistics->GetValue(key, &var) == S_OK) {
+ end = qint64(var.uhVal.QuadPart / 10000);
+ PropVariantClear(&var);
+ }
}
}
- PropVariantClear(&var);
+
return QMediaTimeRange(start, end);
}
@@ -1491,8 +1503,11 @@ HRESULT MFPlayerSession::Invoke(IMFAsyncResult *pResult)
}
}
- if (!m_closing)
+ if (!m_closing) {
emit sessionEvent(pEvent);
+ } else {
+ pEvent->Release();
+ }
return S_OK;
}
@@ -1615,9 +1630,6 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
}
}
- if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
- setVolumeInternal(m_muted ? 0 : m_volume);
-
DWORD dwCharacteristics = 0;
m_sourceResolver->mediaSource()->GetCharacteristics(&dwCharacteristics);
emit seekableUpdate(MFMEDIASOURCE_CAN_SEEK & dwCharacteristics);
@@ -1688,6 +1700,9 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent)
}
}
MFGetService(m_session, MFNETSOURCE_STATISTICS_SERVICE, IID_PPV_ARGS(&m_netsourceStatistics));
+
+ if (SUCCEEDED(MFGetService(m_session, MR_STREAM_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl))))
+ setVolumeInternal(m_muted ? 0 : m_volume);
}
}
}
diff --git a/src/plugins/wmf/samplegrabber.cpp b/src/plugins/wmf/samplegrabber.cpp
index 016482e5d..0a11d8bb8 100644
--- a/src/plugins/wmf/samplegrabber.cpp
+++ b/src/plugins/wmf/samplegrabber.cpp
@@ -155,6 +155,9 @@ STDMETHODIMP AudioSampleGrabberCallback::OnProcessSample(REFGUID guidMajorMediaT
if (llSampleTime == _I64_MAX) {
// Set default QAudioBuffer start time
llSampleTime = -1;
+ } else {
+ // WMF uses 100-nanosecond units, Qt uses microseconds
+ llSampleTime /= 10;
}
foreach (MFAudioProbeControl* probe, m_audioProbes)
diff --git a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp
index e993609ad..72cbc9614 100644
--- a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp
+++ b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp
@@ -212,7 +212,7 @@ public:
stride /= 4;
}
- m_width = qreal(m_frame.width() / stride);
+ m_width = qreal(m_frame.width()) / stride;
textureSize.setWidth(stride);
if (m_textureSize != textureSize) {