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.
This commit is contained in:
Alexandre Moreno 2015-11-02 01:48:08 +08:00 committed by Sebastian Dröge
parent 8853575547
commit e4ae2c3c7b
7 changed files with 185 additions and 2 deletions

View file

@ -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();
}

View file

@ -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

View 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

View 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 {

View 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 +=

View file

@ -25,6 +25,10 @@
#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)

View 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" {