playback/player: qt: add new qml item to render media info sample
authorAlexandre Moreno <alexmorenocano@gmail.com>
Sun, 1 Nov 2015 17:48:08 +0000 (01:48 +0800)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 2 Nov 2015 07:28:51 +0000 (09:28 +0200)
when video is not available it will try to display the sample image
returned by media info object.

playback/player/qt/imagesample.cpp [new file with mode: 0644]
playback/player/qt/imagesample.h [new file with mode: 0644]
playback/player/qt/main.cpp
playback/player/qt/main.qml
playback/player/qt/play.pro
playback/player/qt/qgstplayer.cpp
playback/player/qt/qgstplayer.h

diff --git a/playback/player/qt/imagesample.cpp b/playback/player/qt/imagesample.cpp
new file mode 100644 (file)
index 0000000..94c07d4
--- /dev/null
@@ -0,0 +1,61 @@
+/* GStreamer
+ *
+ * Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <QPainter>
+#include "imagesample.h"
+
+ImageSample::ImageSample()
+    : QQuickPaintedItem()
+    , sample_()
+{
+
+}
+
+ImageSample::~ImageSample()
+{
+
+}
+
+void ImageSample::paint(QPainter *painter)
+{
+    if (sample_.size().isEmpty())
+        return;
+
+    float aspect_ratio = sample_.width() / sample_.height();
+    int w  = height() * aspect_ratio;
+    int x = (width() - w) / 2;
+
+    painter->setViewport(x, 0, w, height());
+    painter->drawImage(QRectF(0, 0, width(), height()), sample_);
+}
+
+const QImage &ImageSample::sample() const
+{
+    return sample_;
+}
+
+void ImageSample::setSample(const QImage &sample)
+{
+    sample_ = sample;
+    update();
+}
+
+
+
diff --git a/playback/player/qt/imagesample.h b/playback/player/qt/imagesample.h
new file mode 100644 (file)
index 0000000..917bb24
--- /dev/null
@@ -0,0 +1,46 @@
+/* GStreamer
+ *
+ * Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef IMAGESAMPLE_H
+#define IMAGESAMPLE_H
+
+#include <QObject>
+#include <QQuickPaintedItem>
+#include <QImage>
+#include <QPainter>
+#include "player.h"
+
+class ImageSample : public QQuickPaintedItem
+{
+    Q_OBJECT
+    Q_PROPERTY(QImage sample READ sample WRITE setSample)
+public:
+    ImageSample();
+    ~ImageSample();
+    void paint(QPainter *painter);
+
+    const QImage &sample() const;
+    void setSample(const QImage &sample);
+
+private:
+    QImage sample_;
+};
+
+#endif // IMAGESAMPLE_H
index 999ddcb..4ef6b64 100644 (file)
@@ -25,6 +25,7 @@
 #include <QUrl>
 
 #include "player.h"
+#include "imagesample.h"
 
 int main(int argc, char *argv[])
 {
@@ -45,6 +46,7 @@ int main(int argc, char *argv[])
     }
 
     qmlRegisterType<Player>("Player", 1, 0, "Player");
+    qmlRegisterType<ImageSample>("ImageSample", 1, 0, "ImageSample");
 
     /* the plugin must be loaded before loading the qml file to register the
      * GstGLVideoItem qml item
index 15a8292..ce1cf8f 100644 (file)
@@ -25,6 +25,7 @@ import QtQuick.Dialogs 1.2
 import QtQuick.Window 2.1
 import Player 1.0
 import org.freedesktop.gstreamer.GLVideoItem 1.0
+import ImageSample 1.0
 
 import "fontawesome.js" as FontAwesome
 
@@ -50,6 +51,7 @@ ApplicationWindow {
                 playbutton.state = "play"
             }
         }
+
         onResolutionChanged: {
             if (player.videoAvailable) {
                 window.width = resolution.width
@@ -64,6 +66,16 @@ ApplicationWindow {
         anchors.centerIn: parent
         width: parent.width
         height: parent.height
+        visible: player.videoAvailable
+    }
+
+    ImageSample {
+        id: sample
+        anchors.centerIn: parent
+        sample: player.mediaInfo.sample
+        width: parent.width
+        height: parent.height
+        visible: !player.videoAvailable
     }
 
     MouseArea {
index c8b2954..d16440c 100644 (file)
@@ -41,13 +41,15 @@ macx {
 HEADERS += \
     qgstplayer.h \
     player.h \
-    quickrenderer.h
+    quickrenderer.h \
+    imagesample.h
 
 SOURCES += main.cpp \
     qgstplayer.cpp \
     ../lib/gst/player/gstplayer.c \
     ../lib/gst/player/gstplayer-media-info.c \
     player.cpp \
-    quickrenderer.cpp
+    quickrenderer.cpp \
+    imagesample.cpp
 
 DISTFILES +=
index 8c350d5..b15347f 100644 (file)
 #include <functional>
 #include <QThread>
 #include <QtAlgorithms>
+#include <QImage>
+
+#include <gst/gst.h>
+#include <gst/tag/tag.h>
 
 namespace QGstPlayer {
 
@@ -43,6 +47,10 @@ MediaInfo::MediaInfo(Player *player)
     , uri_()
     , title_()
     , isSeekable_(false)
+    , videoStreams_()
+    , audioStreams_()
+    , subtitleStreams_()
+    , sample_()
 {
 
 }
@@ -77,6 +85,11 @@ const QList<QObject*> &MediaInfo::subtitleStreams() const
     return subtitleStreams_;
 }
 
+const QImage &MediaInfo::sample()
+{
+    return sample_;
+}
+
 void MediaInfo::update(GstPlayerMediaInfo *info)
 {
     Q_ASSERT(info != 0);
@@ -146,6 +159,47 @@ void MediaInfo::update(GstPlayerMediaInfo *info)
 
         audios->append(new AudioInfo(info));
     }, &audioStreams_);
+
+    GstSample *sample;
+    GstMapInfo map_info;
+    GstBuffer *buffer;
+    const GstStructure *caps_struct;
+    GstTagImageType type = GST_TAG_IMAGE_TYPE_UNDEFINED;
+
+    /* get image sample buffer from media */
+    sample = gst_player_media_info_get_image_sample (info);
+    if (!sample)
+      return;
+
+    buffer = gst_sample_get_buffer (sample);
+    caps_struct = gst_sample_get_info (sample);
+
+    /* if sample is retrieved from preview-image tag then caps struct
+     * will not be defined. */
+    if (caps_struct)
+      gst_structure_get_enum (caps_struct, "image-type",
+          GST_TYPE_TAG_IMAGE_TYPE, reinterpret_cast<gint*>(&type));
+
+    /* FIXME: Should we check more type ?? */
+    if ((type != GST_TAG_IMAGE_TYPE_FRONT_COVER) &&
+        (type != GST_TAG_IMAGE_TYPE_UNDEFINED) &&
+        (type != GST_TAG_IMAGE_TYPE_NONE)) {
+      g_print ("unsupport type ... %d \n", type);
+      return;
+    }
+
+    if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
+      g_print ("failed to map gst buffer \n");
+      return;
+    }
+
+    sample_ = QImage::fromData(map_info.data, map_info.size);
+    if (sample_.isNull())
+        qWarning() << "failed to load media info sample image";
+
+    emit sampleChanged();
+
+    gst_buffer_unmap (buffer, &map_info);
 }
 
 VideoInfo::VideoInfo(GstPlayerVideoInfo *info)
index c41f66c..8ff87d1 100644 (file)
@@ -27,6 +27,7 @@
 //#include <QtGui/qwindowdefs.h>
 #include <QVariant>
 #include <QList>
+#include <QImage>
 #include <gst/player/player.h>
 
 namespace QGstPlayer {
@@ -174,6 +175,7 @@ class MediaInfo : public QObject
     Q_PROPERTY(QList<QObject*> videoStreams READ videoStreams CONSTANT)
     Q_PROPERTY(QList<QObject*> audioStreams READ audioStreams CONSTANT)
     Q_PROPERTY(QList<QObject*> subtitleStreams READ subtitleStreams CONSTANT)
+    Q_PROPERTY(QImage sample READ sample NOTIFY sampleChanged)
 
 public:
     explicit MediaInfo(Player *player = 0);
@@ -183,11 +185,13 @@ public:
     const QList<QObject*> &videoStreams() const;
     const QList<QObject*> &audioStreams() const;
     const QList<QObject*> &subtitleStreams() const;
+    const QImage &sample();
 
 signals:
     void uriChanged();
     void seekableChanged();
     void titleChanged();
+    void sampleChanged();
 
 public Q_SLOTS:
     void update(GstPlayerMediaInfo *info);
@@ -198,6 +202,7 @@ private:
     QList<QObject*> videoStreams_;
     QList<QObject*> audioStreams_;
     QList<QObject*> subtitleStreams_;
+    QImage sample_;
 };
 
 class StreamInfo : public QObject
@@ -267,6 +272,7 @@ private:
 
 Q_DECLARE_METATYPE(QGstPlayer::Player*)
 Q_DECLARE_METATYPE(QGstPlayer::Player::State)
+Q_DECLARE_METATYPE(QGstPlayer::MediaInfo*)
 
 extern "C" {