From d19bede8adf9d9219ade62a873d294b6b5f76fe5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Jan 2014 12:57:56 -0800 Subject: [PATCH 1/8] Update changelog for 5.2.1 Change-Id: Id1df662afb2ec0e7eb7055bbc2c5c523a5bda125 Reviewed-by: Lars Knoll Reviewed-by: Yoann Lopes --- dist/changes-5.2.1 | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 dist/changes-5.2.1 diff --git a/dist/changes-5.2.1 b/dist/changes-5.2.1 new file mode 100644 index 00000000..17a39e61 --- /dev/null +++ b/dist/changes-5.2.1 @@ -0,0 +1,35 @@ +Qt 5.2.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.2.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.2 + +The Qt version 5.2 series is binary compatible with the 5.1.x series. +Applications compiled for 5.1 will continue to run with 5.2. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Library * +**************************************************************************** + +QtMultimedia +------------ + + - Android: + * [QTBUG-31422] The mediaplayer can now read files from the Qt + Resource system. + * [QTBUG-35416] QVideoProbe is now functional when used with a camera + source + * [QTBUG-35086] Fixed VideoOutput not showing video frames in the + correct orientation when used with a Camera. + * [QTBUG-35868] Multiple MediaPlayer elements now show correct video + frames when playing simultaneously. From 8fd3a5a198acaf32243617d46e269991284e8e13 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 30 Jan 2014 14:01:55 +0100 Subject: [PATCH 2/8] Android: add missing information in frames retrieved with QVideoProbe. The number of bytes per line was missing. Change-Id: I0afbdcfd6d7195b7beb3fd09f4ed262f756be848 Reviewed-by: Denis Kormalev Reviewed-by: Christian Stromme --- .../src/mediacapture/qandroidcamerasession.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 86c5e312..2b540dc8 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -57,15 +57,16 @@ QT_BEGIN_NAMESPACE class DataVideoBuffer : public QAbstractVideoBuffer { public: - DataVideoBuffer(const QByteArray &d) + DataVideoBuffer(const QByteArray &d, int bpl = -1) : QAbstractVideoBuffer(NoHandle) , data(d) , mode(NotMapped) + , bytesPerLine(bpl) { } MapMode mapMode() const { return mode; } - uchar *map(MapMode m, int *numBytes, int *bytesPerLine) + uchar *map(MapMode m, int *numBytes, int *bpl) { if (mode != NotMapped || m == NotMapped) return 0; @@ -75,8 +76,8 @@ public: if (numBytes) *numBytes = data.size(); - if (bytesPerLine) - *bytesPerLine = -1; + if (bpl) + *bpl = bytesPerLine; return reinterpret_cast(data.data()); } @@ -86,6 +87,7 @@ public: private: QByteArray data; MapMode mode; + int bytesPerLine; }; @@ -543,8 +545,11 @@ void QAndroidCameraSession::onCameraFrameFetched(const QByteArray &frame) { m_videoProbesMutex.lock(); if (frame.size() && m_videoProbes.count()) { - QVideoFrame videoFrame(new DataVideoBuffer(frame), - m_camera->previewSize(), + const QSize frameSize = m_camera->previewSize(); + // Bytes per line should be only for the first plane. For NV21, the Y plane has 8 bits + // per sample, so bpl == width + QVideoFrame videoFrame(new DataVideoBuffer(frame, frameSize.width()), + frameSize, QVideoFrame::Format_NV21); foreach (QAndroidMediaVideoProbeControl *probe, m_videoProbes) probe->newFrameProbed(videoFrame); From 9a16423610405c0329fe40235313212946f08b05 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 31 Jan 2014 08:23:47 +0100 Subject: [PATCH 3/8] Don't mirror the image from the camera unless it has been flipped The camera itself can have a mode set that causes the image to be flipped so instead of always mirroring the image that is taken from the camera we check for the supported modes first and then check the mode and only mirror if it is set. Otherwise we assume that it does not need horizontally flipping but that it needs vertically flipping which seems to be the standard for cameras on Windows. [ChangeLog][QtMultimedia][Windows] Fixed the incorrect mirroring of the image from the camera Task-number: QTBUG-30365 Change-Id: I166b1f354e8d91c9a6c64f64164d782b52df98d8 Reviewed-by: Yoann Lopes --- .../directshow/camera/dscamerasession.cpp | 40 +++++++++++++++++-- .../directshow/camera/dscamerasession.h | 2 + 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index cc1594fe..801367f6 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -173,6 +173,8 @@ public: DSCameraSession::DSCameraSession(QObject *parent) : QObject(parent) ,m_currentImageId(0) + , needsHorizontalMirroring(false) + , needsVerticalMirroring(true) { pBuild = NULL; pGraph = NULL; @@ -581,7 +583,7 @@ void DSCameraSession::captureFrame() mutex.lock(); image = QImage(frames.at(0)->buffer,m_windowSize.width(),m_windowSize.height(), - QImage::Format_RGB888).rgbSwapped().mirrored(true); + QImage::Format_RGB888).rgbSwapped().mirrored(needsHorizontalMirroring, needsVerticalMirroring); QVideoFrame frame(image); frame.setStartTime(frames.at(0)->time); @@ -595,7 +597,7 @@ void DSCameraSession::captureFrame() mutex.lock(); image = QImage(frames.at(0)->buffer,m_windowSize.width(),m_windowSize.height(), - QImage::Format_RGB32).mirrored(true); + QImage::Format_RGB32).mirrored(needsHorizontalMirroring, needsVerticalMirroring); QVideoFrame frame(image); frame.setStartTime(frames.at(0)->time); @@ -805,7 +807,39 @@ void DSCameraSession::updateProperties() types.clear(); resolutions.clear(); - + IAMVideoControl *pVideoControl = 0; + hr = pBuild->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,pCap, + IID_IAMVideoControl, (void**)&pVideoControl); + if (FAILED(hr)) { + qWarning() << "Failed to get the video control"; + } else { + IPin *pPin = 0; + if (pCap) { + hr = getPin(pCap, PINDIR_OUTPUT, &pPin); + if (FAILED(hr)) { + qWarning() << "Failed to get the pin for the video control"; + } else { + long supportedModes; + hr = pVideoControl->GetCaps(pPin, &supportedModes); + if (FAILED(hr)) { + qWarning() << "Failed to get the supported modes of the video control"; + } else if (supportedModes & VideoControlFlag_FlipHorizontal || supportedModes & VideoControlFlag_FlipVertical) { + long mode; + hr = pVideoControl->GetMode(pPin, &mode); + if (FAILED(hr)) { + qWarning() << "Failed to get the mode of the video control"; + } else { + if (supportedModes & VideoControlFlag_FlipHorizontal) + needsHorizontalMirroring = (mode & VideoControlFlag_FlipHorizontal); + if (supportedModes & VideoControlFlag_FlipVertical) + needsVerticalMirroring = (mode & VideoControlFlag_FlipVertical); + } + } + pPin->Release(); + } + } + pVideoControl->Release(); + } for (int iIndex = 0; iIndex < iCount; iIndex++) { hr = pConfig->GetStreamCaps(iIndex, &pmt, reinterpret_cast(&scc)); if (hr == S_OK) { diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index e78358a5..0fe12dec 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -188,6 +188,8 @@ private: QString m_snapshot; int m_currentImageId; + bool needsHorizontalMirroring; + bool needsVerticalMirroring; protected: HRESULT getPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin); bool createFilterGraph(); From 1e23440457d64e6dec53b6b465d783673b6e9956 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Thu, 16 Jan 2014 15:28:02 +0100 Subject: [PATCH 4/8] QSoundEffect: Don't try guess a media role if one has not been provided. Trying to heuristically guess this kind of thing is almost always a bad idea. Expect the creator of the output to explicitly tell us the category instead of guessing. Change-Id: I5f2988e2456685f3622e0ab136951b1742215f71 Reviewed-by: Yoann Lopes --- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index 23e8d727..ef09cd90 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -928,12 +928,8 @@ void QSoundEffectPrivate::createPulseStream() return; pa_proplist *propList = pa_proplist_new(); - if (m_category.isNull()) { - // Meant to be one of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" - pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, "game"); - } else { + if (!m_category.isNull()) pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, m_category.toLatin1().constData()); - } pa_stream *stream = pa_stream_new_with_proplist(pulseDaemon()->context(), m_name.constData(), &m_pulseSpec, 0, propList); pa_proplist_free(propList); From 87b8b4489a96983a7e98e74ee656e6225ff982f3 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Thu, 16 Jan 2014 15:28:06 +0100 Subject: [PATCH 5/8] QAudioOutput: Don't guess media role if one has not been provided in setCategory. Trying to heuristically guess this kind of thing is almost always a bad idea. Expect the creator of the output to explicitly tell us the category instead of guessing. This fixes QAudioOutput not respecting system volume on Sailfish. Change-Id: If1d05192f513eb54fdfbd1df217286f329b2bfe8 Reviewed-by: Yoann Lopes --- src/plugins/pulseaudio/qaudiooutput_pulse.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp index cd326581..2b482ba4 100644 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp +++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp @@ -277,16 +277,8 @@ bool QPulseAudioOutput::open() qint64 bytesPerSecond = m_format.sampleRate() * m_format.channelCount() * m_format.sampleSize() / 8; pa_proplist *propList = pa_proplist_new(); - if (m_category.isNull()) { - // Meant to be one of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" - // We choose music unless the buffer size is small, where we choose game.. - if (m_bufferSize > 0 && bytesPerSecond > 0 && (m_bufferSize * 1000LL / bytesPerSecond <= LowLatencyBufferSizeMs)) { - m_category = LOW_LATENCY_CATEGORY_NAME; - } else { - m_category = "music"; - } - } - pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, m_category.toLatin1().constData()); + if (!m_category.isNull()) + pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, m_category.toLatin1().constData()); m_stream = pa_stream_new_with_proplist(pulseEngine->context(), m_streamName.constData(), &spec, 0, propList); pa_proplist_free(propList); From c949a98c422d80234f7776e33a92a21732edbaee Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 28 Jan 2014 11:28:19 +1000 Subject: [PATCH 6/8] Fix gstreamer crash when meta-data is of incorrect type. GStreamer tags are typed and the correct type must be used when inserting a value into a GstTagList or subsequent merges or data accesses can crash because of invalid casts. Found while adding additional mappings for GPS values. Change-Id: I95ab40a480a4685bf4e69064315557faa9de288e Reviewed-by: Yoann Lopes --- .../gstreamer/camerabin/camerabinmetadata.cpp | 118 ++++++++++-------- 1 file changed, 64 insertions(+), 54 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp index 1e55e9e8..4dd4c750 100644 --- a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp @@ -46,12 +46,15 @@ #include #include +#include + QT_BEGIN_NAMESPACE struct QGstreamerMetaDataKeyLookup { QString key; const char *token; + QVariant::Type type; }; static QVariant fromGStreamerOrientation(const QVariant &value) @@ -86,74 +89,77 @@ static QVariant toGStreamerOrientation(const QVariant &value) static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = { - { QMediaMetaData::Title, GST_TAG_TITLE }, - //{ QMediaMetaData::SubTitle, 0 }, - //{ QMediaMetaData::Author, 0 }, - { QMediaMetaData::Comment, GST_TAG_COMMENT }, - { QMediaMetaData::Date, GST_TAG_DATE_TIME }, - { QMediaMetaData::Description, GST_TAG_DESCRIPTION }, - //{ QMediaMetaData::Category, 0 }, - { QMediaMetaData::Genre, GST_TAG_GENRE }, - //{ QMediaMetaData::Year, 0 }, - //{ QMediaMetaData::UserRating, 0 }, + { QMediaMetaData::Title, GST_TAG_TITLE, QVariant::String }, + //{ QMediaMetaData::SubTitle, 0, QVariant::String }, + //{ QMediaMetaData::Author, 0, QVariant::String }, + { QMediaMetaData::Comment, GST_TAG_COMMENT, QVariant::String }, + { QMediaMetaData::Date, GST_TAG_DATE_TIME, QVariant::DateTime }, + { QMediaMetaData::Description, GST_TAG_DESCRIPTION, QVariant::String }, + //{ QMediaMetaData::Category, 0, QVariant::String }, + { QMediaMetaData::Genre, GST_TAG_GENRE, QVariant::String }, + //{ QMediaMetaData::Year, 0, QVariant::Int }, + //{ QMediaMetaData::UserRating, , QVariant::Int }, - { QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE }, + { QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE, QVariant::String }, - { QMediaMetaData::Publisher, GST_TAG_ORGANIZATION }, - { QMediaMetaData::Copyright, GST_TAG_COPYRIGHT }, - //{ QMediaMetaData::ParentalRating, 0 }, - //{ QMediaMetaData::RatingOrganisation, 0 }, + { QMediaMetaData::Publisher, GST_TAG_ORGANIZATION, QVariant::String }, + { QMediaMetaData::Copyright, GST_TAG_COPYRIGHT, QVariant::String }, + //{ QMediaMetaData::ParentalRating, 0, QVariant::String }, + //{ QMediaMetaData::RatingOrganisation, 0, QVariant::String }, // Media - //{ QMediaMetaData::Size, 0 }, - //{ QMediaMetaData::MediaType, 0 }, - { QMediaMetaData::Duration, GST_TAG_DURATION }, + //{ QMediaMetaData::Size, 0, QVariant::Int }, + //{ QMediaMetaData::MediaType, 0, QVariant::String }, + { QMediaMetaData::Duration, GST_TAG_DURATION, QVariant::Int }, // Audio - { QMediaMetaData::AudioBitRate, GST_TAG_BITRATE }, - { QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC }, - //{ QMediaMetaData::ChannelCount, 0 }, - //{ QMediaMetaData::SampleRate, 0 }, + { QMediaMetaData::AudioBitRate, GST_TAG_BITRATE, QVariant::Int }, + { QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC, QVariant::String }, + //{ QMediaMetaData::ChannelCount, 0, QVariant::Int }, + //{ QMediaMetaData::SampleRate, 0, QVariant::Int }, // Music - { QMediaMetaData::AlbumTitle, GST_TAG_ALBUM }, - { QMediaMetaData::AlbumArtist, GST_TAG_ARTIST}, - { QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER }, + { QMediaMetaData::AlbumTitle, GST_TAG_ALBUM, QVariant::String }, + { QMediaMetaData::AlbumArtist, GST_TAG_ARTIST, QVariant::String}, + { QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER, QVariant::String }, #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19) - { QMediaMetaData::Composer, GST_TAG_COMPOSER }, + { QMediaMetaData::Composer, GST_TAG_COMPOSER, QVariant::String }, #endif - //{ QMediaMetaData::Conductor, 0 }, - //{ QMediaMetaData::Lyrics, 0 }, - //{ QMediaMetaData::Mood, 0 }, - { QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER }, + //{ QMediaMetaData::Conductor, 0, QVariant::String }, + //{ QMediaMetaData::Lyrics, 0, QVariant::String }, + //{ QMediaMetaData::Mood, 0, QVariant::String }, + { QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER, QVariant::Int }, - //{ QMediaMetaData::CoverArtUrlSmall, 0 }, - //{ QMediaMetaData::CoverArtUrlLarge, 0 }, + //{ QMediaMetaData::CoverArtUrlSmall, 0, QVariant::String }, + //{ QMediaMetaData::CoverArtUrlLarge, 0, QVariant::String }, // Image/Video - //{ QMediaMetaData::Resolution, 0 }, - //{ QMediaMetaData::PixelAspectRatio, 0 }, + //{ QMediaMetaData::Resolution, 0, QVariant::Size }, + //{ QMediaMetaData::PixelAspectRatio, 0, QVariant::Size }, // Video - //{ QMediaMetaData::VideoFrameRate, 0 }, - //{ QMediaMetaData::VideoBitRate, 0 }, - { QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC }, + //{ QMediaMetaData::VideoFrameRate, 0, QVariant::String }, + //{ QMediaMetaData::VideoBitRate, 0, QVariant::Double }, + { QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC, QVariant::String }, - //{ QMediaMetaData::PosterUrl, 0 }, + //{ QMediaMetaData::PosterUrl, 0, QVariant::String }, // Movie - //{ QMediaMetaData::ChapterNumber, 0 }, - //{ QMediaMetaData::Director, 0 }, - { QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER }, - //{ QMediaMetaData::Writer, 0 }, + //{ QMediaMetaData::ChapterNumber, 0, QVariant::Int }, + //{ QMediaMetaData::Director, 0, QVariant::String }, + { QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER, QVariant::String }, + //{ QMediaMetaData::Writer, 0, QVariant::String }, +#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 30) // Photos - //{ QMediaMetaData::CameraManufacturer, 0 }, - //{ QMediaMetaData::CameraModel, 0 }, - //{ QMediaMetaData::Event, 0 }, - //{ QMediaMetaData::Subject, 0 }, + { QMediaMetaData::CameraManufacturer, 0, QVariant::String }, + { QMediaMetaData::CameraModel, 0, QVariant::String }, + //{ QMediaMetaData::Event, 0, QVariant::String }, + //{ QMediaMetaData::Subject, 0, QVariant::String }, - { QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION } + { QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION, QVariant::String }, + +#endif }; CameraBinMetaData::CameraBinMetaData(QObject *parent) @@ -165,6 +171,9 @@ QVariant CameraBinMetaData::metaData(const QString &key) const { if (key == QMediaMetaData::Orientation) { return fromGStreamerOrientation(m_values.value(QByteArray(GST_TAG_IMAGE_ORIENTATION))); + } else if (key == QMediaMetaData::GPSSpeed) { + const double metersPerSec = m_values.value(QByteArray(GST_TAG_GEO_LOCATION_MOVEMENT_SPEED)).toDouble(); + return (metersPerSec * 3600) / 1000; } static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); @@ -181,13 +190,12 @@ QVariant CameraBinMetaData::metaData(const QString &key) const void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value) { + QVariant correctedValue = value; if (key == QMediaMetaData::Orientation) { - m_values.insert(QByteArray(GST_TAG_IMAGE_ORIENTATION), toGStreamerOrientation(value)); - - emit QMetaDataWriterControl::metaDataChanged(); - emit metaDataChanged(m_values); - - return; + correctedValue = toGStreamerOrientation(value); + } else if (key == QMediaMetaData::GPSSpeed) { + // kilometers per hour to meters per second. + correctedValue = (value.toDouble() * 1000) / 3600; } static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); @@ -196,7 +204,9 @@ void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value) if (qt_gstreamerMetaDataKeys[i].key == key) { const char *name = qt_gstreamerMetaDataKeys[i].token; - m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), value); + correctedValue.convert(qt_gstreamerMetaDataKeys[i].type); + + m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), correctedValue); emit QMetaDataWriterControl::metaDataChanged(); emit metaDataChanged(m_values); From 72b995ad79ba4e59347e6d6b2b95aa4a2e548bd3 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Fri, 7 Feb 2014 13:17:03 +1000 Subject: [PATCH 7/8] Add meta-data mappings for GPS and camera make and model to camerabin. This enables writing gps positioning information to captured images. Change-Id: I663f7b94b5e6040865358df1ae45d67b73c54f92 Reviewed-by: Yoann Lopes --- src/plugins/gstreamer/camerabin/camerabinmetadata.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp index 4dd4c750..b265fc2a 100644 --- a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp @@ -152,13 +152,20 @@ static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 30) // Photos - { QMediaMetaData::CameraManufacturer, 0, QVariant::String }, - { QMediaMetaData::CameraModel, 0, QVariant::String }, + { QMediaMetaData::CameraManufacturer, GST_TAG_DEVICE_MANUFACTURER, QVariant::String }, + { QMediaMetaData::CameraModel, GST_TAG_DEVICE_MODEL, QVariant::String }, //{ QMediaMetaData::Event, 0, QVariant::String }, //{ QMediaMetaData::Subject, 0, QVariant::String }, { QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION, QVariant::String }, + // GPS + { QMediaMetaData::GPSLatitude, GST_TAG_GEO_LOCATION_LATITUDE, QVariant::Double }, + { QMediaMetaData::GPSLongitude, GST_TAG_GEO_LOCATION_LONGITUDE, QVariant::Double }, + { QMediaMetaData::GPSAltitude, GST_TAG_GEO_LOCATION_ELEVATION, QVariant::Double }, + { QMediaMetaData::GPSTrack, GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, QVariant::Double }, + { QMediaMetaData::GPSSpeed, GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, QVariant::Double }, + { QMediaMetaData::GPSImgDirection, GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, QVariant::Double } #endif }; From db7f7cc5654ddec60297259bc9f86f5f777749cd Mon Sep 17 00:00:00 2001 From: Thomas Senyk Date: Tue, 28 Jan 2014 14:49:32 +0100 Subject: [PATCH 8/8] adding zero-copy-QSGVideoNode for imx6 On imx6 there is a platform-specific API to implement memory-mapping from gstreamer-buffer to opengl-texture. This plugin uses this API to avoid CPU-based-memory-copy. This allows fluid video-playback up to 1080p with very little CPU load. Before even 720p used one cpu-core completely and wasn't fluid. Change-Id: I0c33eb5d475393a65459291ce9290fa0753de4a5 Reviewed-by: Andy Nichols --- src/plugins/plugins.pro | 2 +- src/plugins/videonode/imx6/imx6.json | 3 + src/plugins/videonode/imx6/imx6.pro | 21 ++ .../imx6/qsgvivantevideomaterial.cpp | 196 ++++++++++++++++++ .../videonode/imx6/qsgvivantevideomaterial.h | 80 +++++++ .../imx6/qsgvivantevideomaterialshader.cpp | 104 ++++++++++ .../imx6/qsgvivantevideomaterialshader.h | 64 ++++++ .../videonode/imx6/qsgvivantevideonode.cpp | 90 ++++++++ .../videonode/imx6/qsgvivantevideonode.h | 67 ++++++ .../imx6/qsgvivantevideonodefactory.cpp | 60 ++++++ .../imx6/qsgvivantevideonodefactory.h | 58 ++++++ src/plugins/videonode/videonode.pro | 5 + 12 files changed, 749 insertions(+), 1 deletion(-) create mode 100644 src/plugins/videonode/imx6/imx6.json create mode 100644 src/plugins/videonode/imx6/imx6.pro create mode 100644 src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp create mode 100644 src/plugins/videonode/imx6/qsgvivantevideomaterial.h create mode 100644 src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp create mode 100644 src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h create mode 100644 src/plugins/videonode/imx6/qsgvivantevideonode.cpp create mode 100644 src/plugins/videonode/imx6/qsgvivantevideonode.h create mode 100644 src/plugins/videonode/imx6/qsgvivantevideonodefactory.cpp create mode 100644 src/plugins/videonode/imx6/qsgvivantevideonodefactory.h create mode 100644 src/plugins/videonode/videonode.pro diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index d947f3b2..c1075995 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -6,7 +6,7 @@ TEMPLATE = subdirs -SUBDIRS += m3u +SUBDIRS += m3u videonode android { SUBDIRS += android opensles diff --git a/src/plugins/videonode/imx6/imx6.json b/src/plugins/videonode/imx6/imx6.json new file mode 100644 index 00000000..08bb12c3 --- /dev/null +++ b/src/plugins/videonode/imx6/imx6.json @@ -0,0 +1,3 @@ +{ + "Keys": ["sgvideonodes"] +} diff --git a/src/plugins/videonode/imx6/imx6.pro b/src/plugins/videonode/imx6/imx6.pro new file mode 100644 index 00000000..a2e6798e --- /dev/null +++ b/src/plugins/videonode/imx6/imx6.pro @@ -0,0 +1,21 @@ +TARGET = imx6vivantevideonode +QT += multimedia-private qtmultimediaquicktools-private + +PLUGIN_TYPE=video/videonode +PLUGIN_CLASS_NAME = QSGVivanteVideoNodeFactory +load(qt_plugin) + +HEADERS += \ + qsgvivantevideonode.h \ + qsgvivantevideomaterialshader.h \ + qsgvivantevideomaterial.h \ + qsgvivantevideonodefactory.h + +SOURCES += \ + qsgvivantevideonode.cpp \ + qsgvivantevideomaterialshader.cpp \ + qsgvivantevideomaterial.cpp \ + qsgvivantevideonodefactory.cpp + +OTHER_FILES += \ + imx6.json diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp new file mode 100644 index 00000000..0ed4e1ad --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 +#include + +#include "qsgvivantevideomaterial.h" +#include "qsgvivantevideomaterialshader.h" +#include "qsgvivantevideonode.h" + +#include +#include + +#include + + +//#define QT_VIVANTE_VIDEO_DEBUG + +QSGVivanteVideoMaterial::QSGVivanteVideoMaterial() : + mOpacity(1.0), + mCurrentTexture(0) +{ +#ifdef QT_VIVANTE_VIDEO_DEBUG + qDebug() << Q_FUNC_INFO; +#endif + + setFlag(Blending, false); +} + +QSGVivanteVideoMaterial::~QSGVivanteVideoMaterial() +{ + for (GLuint id : mBitsToTextureMap.values()) { +#ifdef QT_VIVANTE_VIDEO_DEBUG + qDebug() << "delete texture: " << id; +#endif + glDeleteTextures(1, &id); + } +} + +QSGMaterialType *QSGVivanteVideoMaterial::type() const { + static QSGMaterialType theType; + return &theType; +} + +QSGMaterialShader *QSGVivanteVideoMaterial::createShader() const { + return new QSGVivanteVideoMaterialShader; +} + +int QSGVivanteVideoMaterial::compare(const QSGMaterial *other) const { + if (this->type() == other->type()) { + const QSGVivanteVideoMaterial *m = static_cast(other); + if (this->mBitsToTextureMap == m->mBitsToTextureMap) + return 0; + else + return 1; + } + return 1; +} + +void QSGVivanteVideoMaterial::updateBlending() { + setFlag(Blending, qFuzzyCompare(mOpacity, qreal(1.0)) ? false : true); +} + +void QSGVivanteVideoMaterial::setCurrentFrame(const QVideoFrame &frame) { + QMutexLocker lock(&mFrameMutex); + mNextFrame = frame; + +#ifdef QT_VIVANTE_VIDEO_DEBUG + qDebug() << Q_FUNC_INFO << " new frame: " << frame; +#endif +} + +void QSGVivanteVideoMaterial::bind() +{ + QOpenGLContext *glcontext = QOpenGLContext::currentContext(); + if (glcontext == 0) { + qWarning() << Q_FUNC_INFO << "no QOpenGLContext::currentContext() => return"; + return; + } + + QMutexLocker lock(&mFrameMutex); + if (mNextFrame.isValid()) { + mCurrentFrame.unmap(); + + mCurrentFrame = mNextFrame; + mCurrentTexture = vivanteMapping(mNextFrame); + } + else + glBindTexture(GL_TEXTURE_2D, mCurrentTexture); +} + +GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF) +{ + QOpenGLContext *glcontext = QOpenGLContext::currentContext(); + if (glcontext == 0) { + qWarning() << Q_FUNC_INFO << "no QOpenGLContext::currentContext() => return 0"; + return 0; + } + + static PFNGLTEXDIRECTVIVMAPPROC glTexDirectVIVMap_LOCAL = 0; + static PFNGLTEXDIRECTINVALIDATEVIVPROC glTexDirectInvalidateVIV_LOCAL = 0; + + if (glTexDirectVIVMap_LOCAL == 0 || glTexDirectInvalidateVIV_LOCAL == 0) { + glTexDirectVIVMap_LOCAL = reinterpret_cast(glcontext->getProcAddress("glTexDirectVIVMap")); + glTexDirectInvalidateVIV_LOCAL = reinterpret_cast(glcontext->getProcAddress("glTexDirectInvalidateVIV")); + } + if (glTexDirectVIVMap_LOCAL == 0 || glTexDirectInvalidateVIV_LOCAL == 0) { + qWarning() << Q_FUNC_INFO << "couldn't find \"glTexDirectVIVMap\" and/or \"glTexDirectInvalidateVIV\" => do nothing and return"; + return 0; + } + + + if (vF.map(QAbstractVideoBuffer::ReadOnly)) { + + if (!mBitsToTextureMap.contains(vF.bits())) { + GLuint tmpTexId; + glGenTextures(1, &tmpTexId); + mBitsToTextureMap.insert(vF.bits(), tmpTexId); + + const uchar *constBits = vF.bits(); + void *bits = (void*)constBits; + +#ifdef QT_VIVANTE_VIDEO_DEBUG + qDebug() << Q_FUNC_INFO << "new texture, texId: " << tmpTexId << "; constBits: " << constBits; +#endif + + GLuint physical = ~0U; + + glBindTexture(GL_TEXTURE_2D, tmpTexId); + glTexDirectVIVMap_LOCAL(GL_TEXTURE_2D, + vF.width(), vF.height(), + QSGVivanteVideoNode::getVideoFormat2GLFormatMap().value(vF.pixelFormat()), + &bits, &physical); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D); + + return tmpTexId; + } + else { + glBindTexture(GL_TEXTURE_2D, mBitsToTextureMap.value(vF.bits())); + glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D); + return mBitsToTextureMap.value(vF.bits()); + } + } + else { +#ifdef QT_VIVANTE_VIDEO_DEBUG + qWarning() << " couldn't map the QVideoFrame vF: " << vF; +#endif + return 0; + } + + Q_ASSERT(false); // should never reach this line!; + return 0; +} diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.h b/src/plugins/videonode/imx6/qsgvivantevideomaterial.h new file mode 100644 index 00000000..9d792b78 --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 QSGVIDEOMATERIAL_VIVMAP_H +#define QSGVIDEOMATERIAL_VIVMAP_H + +#include +#include + +#include +#include +#include + + +class QSGVivanteVideoMaterial : public QSGMaterial +{ +public: + QSGVivanteVideoMaterial(); + ~QSGVivanteVideoMaterial(); + + virtual QSGMaterialType *type() const; + virtual QSGMaterialShader *createShader() const; + virtual int compare(const QSGMaterial *other) const; + void updateBlending(); + void setCurrentFrame(const QVideoFrame &frame); + + void bind(); + GLuint vivanteMapping(QVideoFrame texIdVideoFramePair); + + void setOpacity(float o) { mOpacity = o; } + +private: + qreal mOpacity; + + QMap mBitsToTextureMap; + QVideoFrame mCurrentFrame, mNextFrame; + GLuint mCurrentTexture; + + QMutex mFrameMutex; +}; + +#endif // QSGVIDEOMATERIAL_VIVMAP_H diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp new file mode 100644 index 00000000..7b5e5e58 --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 "qsgvivantevideomaterialshader.h" +#include "qsgvivantevideonode.h" +#include "qsgvivantevideomaterial.h" + +void QSGVivanteVideoMaterialShader::updateState(const RenderState &state, + QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + + QSGVivanteVideoMaterial *mat = static_cast(newMaterial); + program()->setUniformValue(mIdTexture, 0); + mat->bind(); + if (state.isOpacityDirty()) { + mat->setOpacity(state.opacity()); + program()->setUniformValue(mIdOpacity, state.opacity()); + } + if (state.isMatrixDirty()) + program()->setUniformValue(mIdMatrix, state.combinedMatrix()); +} + +const char * const *QSGVivanteVideoMaterialShader::attributeNames() const { + static const char *names[] = { + "qt_VertexPosition", + "qt_VertexTexCoord", + 0 + }; + return names; +} + +const char *QSGVivanteVideoMaterialShader::vertexShader() const { + static const char *shader = + "uniform highp mat4 qt_Matrix; \n" + "attribute highp vec4 qt_VertexPosition; \n" + "attribute highp vec2 qt_VertexTexCoord; \n" + "varying highp vec2 qt_TexCoord; \n" + "void main() { \n" + " qt_TexCoord = qt_VertexTexCoord; \n" + " gl_Position = qt_Matrix * qt_VertexPosition; \n" + "}"; + return shader; +} + +const char *QSGVivanteVideoMaterialShader::fragmentShader() const { + static const char *shader = + "uniform sampler2D texture;" + "uniform lowp float opacity;" + "" + "varying highp vec2 qt_TexCoord;" + "" + "void main()" + "{" + " gl_FragColor = texture2D( texture, qt_TexCoord ) * opacity;\n" + "}"; + return shader; +} + + +void QSGVivanteVideoMaterialShader::initialize() { + mIdMatrix = program()->uniformLocation("qt_Matrix"); + mIdTexture = program()->uniformLocation("texture"); + mIdOpacity = program()->uniformLocation("opacity"); +} diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h new file mode 100644 index 00000000..570be256 --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 QSGVIDEOMATERIALSHADER_VIVANTE_H +#define QSGVIDEOMATERIALSHADER_VIVANTE_H + +#include + +class QSGVivanteVideoMaterialShader : public QSGMaterialShader +{ +public: + void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial); + virtual char const *const *attributeNames() const; + +protected: + virtual const char *vertexShader() const; + virtual const char *fragmentShader() const; + virtual void initialize(); + +private: + int mIdMatrix; + int mIdTexture; + int mIdOpacity; +}; + +#endif // QSGVIDEOMATERIALSHADER_VIVANTE_H diff --git a/src/plugins/videonode/imx6/qsgvivantevideonode.cpp b/src/plugins/videonode/imx6/qsgvivantevideonode.cpp new file mode 100644 index 00000000..d5f1e618 --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideonode.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 +#include + +#include "qsgvivantevideonode.h" +#include "qsgvivantevideomaterialshader.h" +#include "qsgvivantevideomaterial.h" + +QMap QSGVivanteVideoNode::static_VideoFormat2GLFormatMap = QMap(); + +QSGVivanteVideoNode::QSGVivanteVideoNode(const QVideoSurfaceFormat &format) : + mFormat(format) +{ + setFlag(QSGNode::OwnsMaterial, true); + mMaterial = new QSGVivanteVideoMaterial(); + setMaterial(mMaterial); +} + +QSGVivanteVideoNode::~QSGVivanteVideoNode() +{ +} + +void QSGVivanteVideoNode::setCurrentFrame(const QVideoFrame &frame) +{ + mMaterial->setCurrentFrame(frame); + markDirty(DirtyMaterial); +} + +const QMap& QSGVivanteVideoNode::getVideoFormat2GLFormatMap() +{ + if (static_VideoFormat2GLFormatMap.isEmpty()) { + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_YV12, GL_VIV_YV12); + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_NV12, GL_VIV_NV12); + + + // The following formats should work but are untested! + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_NV21, GL_VIV_NV21); + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_UYVY, GL_VIV_UYVY); + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_YUYV, GL_VIV_YUY2); + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB32, GL_RGBA); + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB24, GL_RGB); + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_RGB565, GL_RGB565); + static_VideoFormat2GLFormatMap.insert(QVideoFrame::Format_BGRA32, GL_BGRA_EXT); + } + + return static_VideoFormat2GLFormatMap; +} + + + diff --git a/src/plugins/videonode/imx6/qsgvivantevideonode.h b/src/plugins/videonode/imx6/qsgvivantevideonode.h new file mode 100644 index 00000000..ae2120ae --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideonode.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 QSGVIDEONODE_VIVANTE_H +#define QSGVIDEONODE_VIVANTE_H + +#include +#include + +class QSGVivanteVideoMaterial; +class QSGVivanteVideoNode : public QSGVideoNode +{ +public: + QSGVivanteVideoNode(const QVideoSurfaceFormat &format); + ~QSGVivanteVideoNode(); + + virtual QVideoFrame::PixelFormat pixelFormat() const { return mFormat.pixelFormat(); } + void setCurrentFrame(const QVideoFrame &frame); + + static const QMap& getVideoFormat2GLFormatMap(); + +private: + QVideoSurfaceFormat mFormat; + QSGVivanteVideoMaterial *mMaterial; + + static QMap static_VideoFormat2GLFormatMap; +}; + +#endif // QSGVIDEONODE_VIVANTE_H diff --git a/src/plugins/videonode/imx6/qsgvivantevideonodefactory.cpp b/src/plugins/videonode/imx6/qsgvivantevideonodefactory.cpp new file mode 100644 index 00000000..e0711e18 --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideonodefactory.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 "qsgvivantevideonodefactory.h" +#include "qsgvivantevideonode.h" + +QList QSGVivanteVideoNodeFactory::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + if (handleType == QAbstractVideoBuffer::NoHandle) + return QSGVivanteVideoNode::getVideoFormat2GLFormatMap().keys(); + else + return QList(); +} + +QSGVideoNode *QSGVivanteVideoNodeFactory::createNode(const QVideoSurfaceFormat &format) +{ + if (supportedPixelFormats(format.handleType()).contains(format.pixelFormat())) { + return new QSGVivanteVideoNode(format); + } + return 0; +} diff --git a/src/plugins/videonode/imx6/qsgvivantevideonodefactory.h b/src/plugins/videonode/imx6/qsgvivantevideonodefactory.h new file mode 100644 index 00000000..6fda61b1 --- /dev/null +++ b/src/plugins/videonode/imx6/qsgvivantevideonodefactory.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Pelagicore AG +** 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 QSGVIDEONODEFACTORY_VIVANTE_H +#define QSGVIDEONODEFACTORY_VIVANTE_H + +#include +#include + +class QSGVivanteVideoNodeFactory : public QObject, public QSGVideoNodeFactoryInterface +{ +public: + Q_OBJECT + Q_PLUGIN_METADATA(IID QSGVideoNodeFactoryInterface_iid FILE "imx6.json") + Q_INTERFACES(QSGVideoNodeFactoryInterface) + + QList supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const; + QSGVideoNode *createNode(const QVideoSurfaceFormat &format); +}; +#endif // QSGVIDEONODEFACTORY_VIVANTE_H diff --git a/src/plugins/videonode/videonode.pro b/src/plugins/videonode/videonode.pro new file mode 100644 index 00000000..ecc1c0cf --- /dev/null +++ b/src/plugins/videonode/videonode.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +*imx6* { + SUBDIRS += imx6 +}