From e4ae2c3c7bfe14e58e2b73f0c20743dd7ba4bbc2 Mon Sep 17 00:00:00 2001 From: Alexandre Moreno Date: Mon, 2 Nov 2015 01:48:08 +0800 Subject: [PATCH] playback/player: qt: add new qml item to render media info sample when video is not available it will try to display the sample image returned by media info object. --- playback/player/qt/imagesample.cpp | 61 ++++++++++++++++++++++++++++++ playback/player/qt/imagesample.h | 46 ++++++++++++++++++++++ playback/player/qt/main.cpp | 2 + playback/player/qt/main.qml | 12 ++++++ playback/player/qt/play.pro | 6 ++- playback/player/qt/qgstplayer.cpp | 54 ++++++++++++++++++++++++++ playback/player/qt/qgstplayer.h | 6 +++ 7 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 playback/player/qt/imagesample.cpp create mode 100644 playback/player/qt/imagesample.h diff --git a/playback/player/qt/imagesample.cpp b/playback/player/qt/imagesample.cpp new file mode 100644 index 0000000000..94c07d4e85 --- /dev/null +++ b/playback/player/qt/imagesample.cpp @@ -0,0 +1,61 @@ +/* GStreamer + * + * Copyright (C) 2015 Alexandre Moreno + * + * 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 +#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 index 0000000000..917bb24722 --- /dev/null +++ b/playback/player/qt/imagesample.h @@ -0,0 +1,46 @@ +/* GStreamer + * + * Copyright (C) 2015 Alexandre Moreno + * + * 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 +#include +#include +#include +#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 diff --git a/playback/player/qt/main.cpp b/playback/player/qt/main.cpp index 999ddcba5e..4ef6b64f79 100644 --- a/playback/player/qt/main.cpp +++ b/playback/player/qt/main.cpp @@ -25,6 +25,7 @@ #include #include "player.h" +#include "imagesample.h" int main(int argc, char *argv[]) { @@ -45,6 +46,7 @@ int main(int argc, char *argv[]) } qmlRegisterType("Player", 1, 0, "Player"); + qmlRegisterType("ImageSample", 1, 0, "ImageSample"); /* the plugin must be loaded before loading the qml file to register the * GstGLVideoItem qml item diff --git a/playback/player/qt/main.qml b/playback/player/qt/main.qml index 15a8292b2f..ce1cf8fb34 100644 --- a/playback/player/qt/main.qml +++ b/playback/player/qt/main.qml @@ -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 { diff --git a/playback/player/qt/play.pro b/playback/player/qt/play.pro index c8b29549b3..d16440c284 100644 --- a/playback/player/qt/play.pro +++ b/playback/player/qt/play.pro @@ -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 += diff --git a/playback/player/qt/qgstplayer.cpp b/playback/player/qt/qgstplayer.cpp index 8c350d55d3..b15347ff19 100644 --- a/playback/player/qt/qgstplayer.cpp +++ b/playback/player/qt/qgstplayer.cpp @@ -25,6 +25,10 @@ #include #include #include +#include + +#include +#include namespace QGstPlayer { @@ -43,6 +47,10 @@ MediaInfo::MediaInfo(Player *player) , uri_() , title_() , isSeekable_(false) + , videoStreams_() + , audioStreams_() + , subtitleStreams_() + , sample_() { } @@ -77,6 +85,11 @@ const QList &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(&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) diff --git a/playback/player/qt/qgstplayer.h b/playback/player/qt/qgstplayer.h index c41f66c3bb..8ff87d1e8f 100644 --- a/playback/player/qt/qgstplayer.h +++ b/playback/player/qt/qgstplayer.h @@ -27,6 +27,7 @@ //#include #include #include +#include #include namespace QGstPlayer { @@ -174,6 +175,7 @@ class MediaInfo : public QObject Q_PROPERTY(QList videoStreams READ videoStreams CONSTANT) Q_PROPERTY(QList audioStreams READ audioStreams CONSTANT) Q_PROPERTY(QList 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 &videoStreams() const; const QList &audioStreams() const; const QList &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 videoStreams_; QList audioStreams_; QList 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" {