mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-13 12:51:16 +00:00
436 lines
10 KiB
C++
436 lines
10 KiB
C++
|
/* 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 "qgstplayer.h"
|
||
|
#include <QDebug>
|
||
|
#include <QSize>
|
||
|
|
||
|
#include <QMetaObject>
|
||
|
|
||
|
class QGstPlayerRegisterMetaTypes
|
||
|
{
|
||
|
public:
|
||
|
QGstPlayerRegisterMetaTypes()
|
||
|
{
|
||
|
qRegisterMetaType<QGstPlayer::State>("State");
|
||
|
}
|
||
|
|
||
|
} _register;
|
||
|
|
||
|
QGstPlayer::MediaInfo::MediaInfo(GstPlayerMediaInfo *media_info)
|
||
|
: mediaInfo_(media_info)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
QString QGstPlayer::MediaInfo::title() const
|
||
|
{
|
||
|
QString title = QString::fromLocal8Bit
|
||
|
(gst_player_media_info_get_title(mediaInfo_));
|
||
|
|
||
|
// if media has no title, return the file name
|
||
|
if (title.isEmpty()) {
|
||
|
QUrl url(gst_player_media_info_get_uri(mediaInfo_));
|
||
|
title = url.fileName();
|
||
|
}
|
||
|
|
||
|
return title;
|
||
|
}
|
||
|
|
||
|
bool QGstPlayer::MediaInfo::isSeekable() const
|
||
|
{
|
||
|
return gst_player_media_info_is_seekable(mediaInfo_);
|
||
|
}
|
||
|
|
||
|
bool QGstPlayer::isVideoAvailable() const
|
||
|
{
|
||
|
GstPlayerVideoInfo *video_info;
|
||
|
|
||
|
video_info = gst_player_get_current_video_track (player_);
|
||
|
if (video_info) {
|
||
|
g_object_unref (video_info);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
QQmlPropertyMap *QGstPlayer::mediaInfo() const
|
||
|
{
|
||
|
return mediaInfoMap_;
|
||
|
}
|
||
|
|
||
|
QGstPlayer::QGstPlayer(QObject *parent, QGstPlayer::VideoRenderer *renderer)
|
||
|
: QObject(parent)
|
||
|
, player_()
|
||
|
, state_(STOPPED)
|
||
|
, videoDimensions_(QSize())
|
||
|
, mediaInfoMap_()
|
||
|
, videoAvailable_(false)
|
||
|
{
|
||
|
|
||
|
player_ = gst_player_new_full(renderer ? renderer->renderer() : 0, 0);
|
||
|
|
||
|
g_object_connect(player_,
|
||
|
"swapped-signal::state-changed", G_CALLBACK (QGstPlayer::onStateChanged), this,
|
||
|
"swapped-signal::position-updated", G_CALLBACK (QGstPlayer::onPositionUpdated), this,
|
||
|
"swapped-signal::duration-changed", G_CALLBACK (QGstPlayer::onDurationChanged), this,
|
||
|
"swapped-signal::buffering", G_CALLBACK (QGstPlayer::onBufferingChanged), this,
|
||
|
"swapped-signal::video-dimensions-changed", G_CALLBACK (QGstPlayer::onVideoDimensionsChanged), this,
|
||
|
"swapped-signal::volume-changed", G_CALLBACK (QGstPlayer::onVolumeChanged), this,
|
||
|
"swapped-signal::mute-changed", G_CALLBACK (QGstPlayer::onMuteChanged), this,
|
||
|
"swapped-signal::media-info-updated", G_CALLBACK (QGstPlayer::onMediaInfoUpdated), this, NULL);
|
||
|
|
||
|
mediaInfoMap_ = new QQmlPropertyMap(this);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onStateChanged(QGstPlayer * player, GstPlayerState state)
|
||
|
{
|
||
|
player->state_ = static_cast<QGstPlayer::State>(state);
|
||
|
|
||
|
emit player->stateChanged(player->state_);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onPositionUpdated(QGstPlayer * player, GstClockTime position)
|
||
|
{
|
||
|
emit player->positionChanged(position);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onDurationChanged(QGstPlayer * player, GstClockTime duration)
|
||
|
{
|
||
|
emit player->durationChanged(duration);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onBufferingChanged(QGstPlayer * player, int percent)
|
||
|
{
|
||
|
emit player->bufferingChanged(percent);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onVideoDimensionsChanged(QGstPlayer * player, int w, int h)
|
||
|
{
|
||
|
QSize res(w,h);
|
||
|
|
||
|
player->setResolution(res);
|
||
|
|
||
|
emit player->resolutionChanged(res);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onVolumeChanged(QGstPlayer *player)
|
||
|
{
|
||
|
qreal new_val;
|
||
|
|
||
|
new_val = gst_player_get_volume (player->player_);
|
||
|
|
||
|
emit player->volumeChanged(new_val);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onMuteChanged(QGstPlayer *player)
|
||
|
{
|
||
|
bool new_val;
|
||
|
|
||
|
new_val = gst_player_get_mute (player->player_);
|
||
|
|
||
|
emit player->mutedChanged(new_val);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
QGstPlayer::onMediaInfoUpdated(QGstPlayer *player, GstPlayerMediaInfo *media_info)
|
||
|
{
|
||
|
MediaInfo mediaInfo(media_info);
|
||
|
|
||
|
player->mediaInfoMap_->insert(QLatin1String("title"),
|
||
|
QVariant(mediaInfo.title()));
|
||
|
player->mediaInfoMap_->insert(QLatin1String("isSeekable"),
|
||
|
QVariant(mediaInfo.isSeekable()));
|
||
|
|
||
|
bool val = player->isVideoAvailable();
|
||
|
|
||
|
if (player->videoAvailable_ != val) {
|
||
|
player->videoAvailable_ = val;
|
||
|
emit player->videoAvailableChanged(val);
|
||
|
}
|
||
|
|
||
|
emit player->mediaInfoChanged();
|
||
|
}
|
||
|
|
||
|
QUrl QGstPlayer::source() const
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
QString url = QString::fromLocal8Bit(gst_player_get_uri(player_));
|
||
|
|
||
|
return QUrl(url);
|
||
|
}
|
||
|
|
||
|
qint64 QGstPlayer::duration() const
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
return gst_player_get_duration(player_);
|
||
|
}
|
||
|
|
||
|
qint64 QGstPlayer::position() const
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
return gst_player_get_position(player_);
|
||
|
}
|
||
|
|
||
|
qreal QGstPlayer::volume() const
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
return gst_player_get_volume(player_);
|
||
|
}
|
||
|
|
||
|
bool QGstPlayer::isMuted() const
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
return gst_player_get_mute(player_);
|
||
|
}
|
||
|
|
||
|
int QGstPlayer::buffering() const
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
QSize QGstPlayer::resolution() const
|
||
|
{
|
||
|
return videoDimensions_;
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::setResolution(QSize size)
|
||
|
{
|
||
|
videoDimensions_ = size;
|
||
|
}
|
||
|
|
||
|
QGstPlayer::State QGstPlayer::state() const
|
||
|
{
|
||
|
return state_;
|
||
|
}
|
||
|
|
||
|
GstElement *QGstPlayer::pipeline() const
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
return gst_player_get_pipeline(player_);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::play()
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
gst_player_play(player_);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::pause()
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
gst_player_pause(player_);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::stop()
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
gst_player_stop(player_);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::seek(qint64 position)
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
gst_player_seek(player_, position);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::setSource(QUrl const& url)
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
QByteArray uri = url.toString().toLocal8Bit();
|
||
|
|
||
|
gst_player_set_uri(player_, uri.data());
|
||
|
|
||
|
emit sourceChanged(url);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::setVolume(qreal val)
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
gst_player_set_volume(player_, val);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::setMuted(bool val)
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
gst_player_set_mute(player_, val);
|
||
|
}
|
||
|
|
||
|
void QGstPlayer::setPosition(qint64 pos)
|
||
|
{
|
||
|
Q_ASSERT(player_ != 0);
|
||
|
|
||
|
gst_player_seek(player_, pos);
|
||
|
}
|
||
|
|
||
|
GstPlayerVideoRenderer *QGstPlayer::VideoRenderer::renderer()
|
||
|
{
|
||
|
return renderer_;
|
||
|
}
|
||
|
|
||
|
QGstPlayer::VideoRenderer::VideoRenderer()
|
||
|
{
|
||
|
renderer_ = static_cast<GstPlayerVideoRenderer*>
|
||
|
(g_object_new (GST_TYPE_PLAYER_QT_VIDEO_RENDERER, "renderer", this, NULL));
|
||
|
}
|
||
|
|
||
|
QGstPlayer::VideoRenderer::~VideoRenderer()
|
||
|
{
|
||
|
if (renderer_) gst_object_unref(renderer_);
|
||
|
}
|
||
|
|
||
|
struct _GstPlayerQtVideoRenderer
|
||
|
{
|
||
|
GObject parent;
|
||
|
|
||
|
gpointer renderer;
|
||
|
};
|
||
|
|
||
|
struct _GstPlayerQtVideoRendererClass
|
||
|
{
|
||
|
GObjectClass parent_class;
|
||
|
};
|
||
|
|
||
|
static void
|
||
|
gst_player_qt_video_renderer_interface_init
|
||
|
(GstPlayerVideoRendererInterface * iface);
|
||
|
|
||
|
G_DEFINE_TYPE_WITH_CODE (GstPlayerQtVideoRenderer,
|
||
|
gst_player_qt_video_renderer, G_TYPE_OBJECT,
|
||
|
G_IMPLEMENT_INTERFACE (GST_TYPE_PLAYER_VIDEO_RENDERER,
|
||
|
gst_player_qt_video_renderer_interface_init))
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
QT_VIDEO_RENDERER_PROP_0,
|
||
|
QT_VIDEO_RENDERER_PROP_RENDERER,
|
||
|
QT_VIDEO_RENDERER_PROP_LAST
|
||
|
};
|
||
|
|
||
|
static GParamSpec * qt_video_renderer_param_specs
|
||
|
[QT_VIDEO_RENDERER_PROP_LAST] = { NULL, };
|
||
|
|
||
|
static void
|
||
|
gst_player_qt_video_renderer_set_property (GObject * object,
|
||
|
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||
|
{
|
||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (object);
|
||
|
|
||
|
switch (prop_id) {
|
||
|
case QT_VIDEO_RENDERER_PROP_RENDERER:
|
||
|
qDebug() << "setting renderer";
|
||
|
self->renderer = g_value_get_pointer (value);
|
||
|
break;
|
||
|
default:
|
||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gst_player_qt_video_renderer_get_property (GObject * object,
|
||
|
guint prop_id, GValue * value, GParamSpec * pspec)
|
||
|
{
|
||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (object);
|
||
|
|
||
|
switch (prop_id) {
|
||
|
case QT_VIDEO_RENDERER_PROP_RENDERER:
|
||
|
g_value_set_pointer (value, self->renderer);
|
||
|
break;
|
||
|
default:
|
||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gst_player_qt_video_renderer_finalize (GObject * object)
|
||
|
{
|
||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (object);
|
||
|
|
||
|
G_OBJECT_CLASS
|
||
|
(gst_player_qt_video_renderer_parent_class)->finalize(object);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gst_player_qt_video_renderer_class_init
|
||
|
(GstPlayerQtVideoRendererClass * klass)
|
||
|
{
|
||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||
|
|
||
|
gobject_class->set_property =
|
||
|
gst_player_qt_video_renderer_set_property;
|
||
|
gobject_class->get_property =
|
||
|
gst_player_qt_video_renderer_get_property;
|
||
|
gobject_class->finalize = gst_player_qt_video_renderer_finalize;
|
||
|
|
||
|
qt_video_renderer_param_specs
|
||
|
[QT_VIDEO_RENDERER_PROP_RENDERER] =
|
||
|
g_param_spec_pointer ("renderer", "Qt Renderer", "",
|
||
|
static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
|
||
|
g_object_class_install_properties (gobject_class,
|
||
|
QT_VIDEO_RENDERER_PROP_LAST,
|
||
|
qt_video_renderer_param_specs);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gst_player_qt_video_renderer_init (GstPlayerQtVideoRenderer * self)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
static GstElement *
|
||
|
gst_player_qt_video_renderer_create_video_sink
|
||
|
(GstPlayerVideoRenderer * iface, GstPlayer *player)
|
||
|
{
|
||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (iface);
|
||
|
|
||
|
g_assert(self->renderer != NULL);
|
||
|
|
||
|
return static_cast<QGstPlayer::VideoRenderer*>(self->renderer)->createVideoSink();
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gst_player_qt_video_renderer_interface_init
|
||
|
(GstPlayerVideoRendererInterface * iface)
|
||
|
{
|
||
|
iface->create_video_sink = gst_player_qt_video_renderer_create_video_sink;
|
||
|
}
|