play: Introducing the new playback library

This aims to be a replacement for the GstPlayer library. In GstPlay, notifications are
sent as application messages through a dedicated GstBus. The GMainContext-based
signal dispatcher was replaced by a GObject signal adapter, now relying on the
bus to emit its signals. The signal dispatcher is now optional and fully
decoupled from the GstPlay object.

Co-authored with: Philippe Normand <philn@igalia.com>

Fixes #394

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2061>
This commit is contained in:
Stephan Hesse 2019-11-02 16:14:13 +01:00 committed by Philippe Normand
parent 80c1722cba
commit a74651ddc1
23 changed files with 8087 additions and 0 deletions

3
docs/libs/play/index.md Normal file
View file

@ -0,0 +1,3 @@
# Play Library
> NOTE: This library API is considered *unstable*

View file

@ -0,0 +1 @@
gi-index

View file

@ -107,6 +107,7 @@ libs = []
if build_gir if build_gir
libs = [ libs = [
{'name': 'mpegts', 'gir': mpegts_gir, 'lib': gstmpegts_dep}, {'name': 'mpegts', 'gir': mpegts_gir, 'lib': gstmpegts_dep},
{'name': 'play', 'gir': play_gir, 'lib': gstplay_dep},
{'name': 'player', 'gir': player_gir, 'lib': gstplayer_dep}, {'name': 'player', 'gir': player_gir, 'lib': gstplayer_dep},
{'name': 'insertbin', 'gir': insertbin_gir, 'lib': gstinsertbin_dep}, {'name': 'insertbin', 'gir': insertbin_gir, 'lib': gstinsertbin_dep},
{'name': 'codecparsers', 'lib': gstcodecparsers_dep}, {'name': 'codecparsers', 'lib': gstcodecparsers_dep},

View file

@ -11,6 +11,7 @@ subdir('interfaces')
subdir('isoff') subdir('isoff')
subdir('mpegts') subdir('mpegts')
subdir('opencv') subdir('opencv')
subdir('play')
subdir('player') subdir('player')
subdir('sctp') subdir('sctp')
subdir('transcoder') subdir('transcoder')

View file

@ -0,0 +1,126 @@
/* GStreamer
*
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@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 "gstplay-media-info.h"
#ifndef __GST_PLAY_MEDIA_INFO_PRIVATE_H__
#define __GST_PLAY_MEDIA_INFO_PRIVATE_H__
struct _GstPlayStreamInfo
{
GObject parent;
gchar *codec;
GstCaps *caps;
gint stream_index;
GstTagList *tags;
gchar *stream_id;
};
struct _GstPlayStreamInfoClass
{
GObjectClass parent_class;
};
struct _GstPlaySubtitleInfo
{
GstPlayStreamInfo parent;
gchar *language;
};
struct _GstPlaySubtitleInfoClass
{
GstPlayStreamInfoClass parent_class;
};
struct _GstPlayAudioInfo
{
GstPlayStreamInfo parent;
gint channels;
gint sample_rate;
guint bitrate;
guint max_bitrate;
gchar *language;
};
struct _GstPlayAudioInfoClass
{
GstPlayStreamInfoClass parent_class;
};
struct _GstPlayVideoInfo
{
GstPlayStreamInfo parent;
gint width;
gint height;
gint framerate_num;
gint framerate_denom;
gint par_num;
gint par_denom;
guint bitrate;
guint max_bitrate;
};
struct _GstPlayVideoInfoClass
{
GstPlayStreamInfoClass parent_class;
};
struct _GstPlayMediaInfo
{
GObject parent;
gchar *uri;
gchar *title;
gchar *container;
gboolean seekable, is_live;
GstTagList *tags;
GstSample *image_sample;
GList *stream_list;
GList *audio_stream_list;
GList *video_stream_list;
GList *subtitle_stream_list;
GstClockTime duration;
};
struct _GstPlayMediaInfoClass
{
GObjectClass parent_class;
};
G_GNUC_INTERNAL GstPlayMediaInfo* gst_play_media_info_new
(const gchar *uri);
G_GNUC_INTERNAL GstPlayMediaInfo* gst_play_media_info_copy
(GstPlayMediaInfo *ref);
G_GNUC_INTERNAL GstPlayStreamInfo* gst_play_stream_info_new
(gint stream_index, GType type);
G_GNUC_INTERNAL GstPlayStreamInfo* gst_play_stream_info_copy
(GstPlayStreamInfo *ref);
#endif /* __GST_PLAY_MEDIA_INFO_PRIVATE_H__ */

View file

@ -0,0 +1,933 @@
/* GStreamer
*
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@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.
*/
/**
* SECTION:gstplay-mediainfo
* @title: GstPlayMediaInfo
* @short_description: Play Media Information
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstplay-media-info.h"
#include "gstplay-media-info-private.h"
/* Per-stream information */
G_DEFINE_ABSTRACT_TYPE (GstPlayStreamInfo, gst_play_stream_info, G_TYPE_OBJECT);
static void
gst_play_stream_info_init (GstPlayStreamInfo * sinfo)
{
sinfo->stream_index = -1;
}
static void
gst_play_stream_info_finalize (GObject * object)
{
GstPlayStreamInfo *sinfo = GST_PLAY_STREAM_INFO (object);
g_free (sinfo->codec);
g_free (sinfo->stream_id);
if (sinfo->caps)
gst_caps_unref (sinfo->caps);
if (sinfo->tags)
gst_tag_list_unref (sinfo->tags);
G_OBJECT_CLASS (gst_play_stream_info_parent_class)->finalize (object);
}
static void
gst_play_stream_info_class_init (GstPlayStreamInfoClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->finalize = gst_play_stream_info_finalize;
}
/**
* gst_play_stream_info_get_index:
* @info: a #GstPlayStreamInfo
*
* Function to get stream index from #GstPlayStreamInfo instance.
*
* Returns: the stream index of this stream.
* Since: 1.20
*/
gint
gst_play_stream_info_get_index (const GstPlayStreamInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_STREAM_INFO (info), -1);
return info->stream_index;
}
/**
* gst_play_stream_info_get_stream_type:
* @info: a #GstPlayStreamInfo
*
* Function to return human readable name for the stream type
* of the given @info (ex: "audio", "video", "subtitle")
*
* Returns: a human readable name
* Since: 1.20
*/
const gchar *
gst_play_stream_info_get_stream_type (const GstPlayStreamInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_STREAM_INFO (info), NULL);
if (GST_IS_PLAY_VIDEO_INFO (info))
return "video";
else if (GST_IS_PLAY_AUDIO_INFO (info))
return "audio";
else
return "subtitle";
}
/**
* gst_play_stream_info_get_tags:
* @info: a #GstPlayStreamInfo
*
* Returns: (transfer none): the tags contained in this stream.
* Since: 1.20
*/
GstTagList *
gst_play_stream_info_get_tags (const GstPlayStreamInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_STREAM_INFO (info), NULL);
return info->tags;
}
/**
* gst_play_stream_info_get_codec:
* @info: a #GstPlayStreamInfo
*
* A string describing codec used in #GstPlayStreamInfo.
*
* Returns: codec string or NULL on unknown.
* Since: 1.20
*/
const gchar *
gst_play_stream_info_get_codec (const GstPlayStreamInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_STREAM_INFO (info), NULL);
return info->codec;
}
/**
* gst_play_stream_info_get_caps:
* @info: a #GstPlayStreamInfo
*
* Returns: (transfer none): the #GstCaps of the stream.
* Since: 1.20
*/
GstCaps *
gst_play_stream_info_get_caps (const GstPlayStreamInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_STREAM_INFO (info), NULL);
return info->caps;
}
/* Video information */
G_DEFINE_TYPE (GstPlayVideoInfo, gst_play_video_info,
GST_TYPE_PLAY_STREAM_INFO);
static void
gst_play_video_info_init (GstPlayVideoInfo * info)
{
info->width = -1;
info->height = -1;
info->framerate_num = 0;
info->framerate_denom = 1;
info->par_num = 1;
info->par_denom = 1;
}
static void
gst_play_video_info_class_init (G_GNUC_UNUSED GstPlayVideoInfoClass * klass)
{
/* nothing to do here */
}
/**
* gst_play_video_info_get_width:
* @info: a #GstPlayVideoInfo
*
* Returns: the width of video in #GstPlayVideoInfo.
* Since: 1.20
*/
gint
gst_play_video_info_get_width (const GstPlayVideoInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_VIDEO_INFO (info), -1);
return info->width;
}
/**
* gst_play_video_info_get_height:
* @info: a #GstPlayVideoInfo
*
* Returns: the height of video in #GstPlayVideoInfo.
* Since: 1.20
*/
gint
gst_play_video_info_get_height (const GstPlayVideoInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_VIDEO_INFO (info), -1);
return info->height;
}
/**
* gst_play_video_info_get_framerate:
* @info: a #GstPlayVideoInfo
* @fps_n: (out): Numerator of frame rate
* @fps_d: (out): Denominator of frame rate
*
* Since: 1.20
*/
void
gst_play_video_info_get_framerate (const GstPlayVideoInfo * info,
gint * fps_n, gint * fps_d)
{
g_return_if_fail (GST_IS_PLAY_VIDEO_INFO (info));
*fps_n = info->framerate_num;
*fps_d = info->framerate_denom;
}
/**
* gst_play_video_info_get_pixel_aspect_ratio:
* @info: a #GstPlayVideoInfo
* @par_n: (out): numerator
* @par_d: (out): denominator
*
* Returns the pixel aspect ratio in @par_n and @par_d
*
* Since: 1.20
*/
void
gst_play_video_info_get_pixel_aspect_ratio (const GstPlayVideoInfo * info,
guint * par_n, guint * par_d)
{
g_return_if_fail (GST_IS_PLAY_VIDEO_INFO (info));
*par_n = info->par_num;
*par_d = info->par_denom;
}
/**
* gst_play_video_info_get_bitrate:
* @info: a #GstPlayVideoInfo
*
* Returns: the current bitrate of video in #GstPlayVideoInfo.
* Since: 1.20
*/
gint
gst_play_video_info_get_bitrate (const GstPlayVideoInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_VIDEO_INFO (info), -1);
return info->bitrate;
}
/**
* gst_play_video_info_get_max_bitrate:
* @info: a #GstPlayVideoInfo
*
* Returns: the maximum bitrate of video in #GstPlayVideoInfo.
* Since: 1.20
*/
gint
gst_play_video_info_get_max_bitrate (const GstPlayVideoInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_VIDEO_INFO (info), -1);
return info->max_bitrate;
}
/* Audio information */
G_DEFINE_TYPE (GstPlayAudioInfo, gst_play_audio_info,
GST_TYPE_PLAY_STREAM_INFO);
static void
gst_play_audio_info_init (GstPlayAudioInfo * info)
{
info->channels = 0;
info->sample_rate = 0;
info->bitrate = -1;
info->max_bitrate = -1;
}
static void
gst_play_audio_info_finalize (GObject * object)
{
GstPlayAudioInfo *info = GST_PLAY_AUDIO_INFO (object);
g_free (info->language);
G_OBJECT_CLASS (gst_play_audio_info_parent_class)->finalize (object);
}
static void
gst_play_audio_info_class_init (GstPlayAudioInfoClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->finalize = gst_play_audio_info_finalize;
}
/**
* gst_play_audio_info_get_language:
* @info: a #GstPlayAudioInfo
*
* Returns: the language of the stream, or NULL if unknown.
* Since: 1.20
*/
const gchar *
gst_play_audio_info_get_language (const GstPlayAudioInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_AUDIO_INFO (info), NULL);
return info->language;
}
/**
* gst_play_audio_info_get_channels:
* @info: a #GstPlayAudioInfo
*
* Returns: the number of audio channels in #GstPlayAudioInfo.
* Since: 1.20
*/
gint
gst_play_audio_info_get_channels (const GstPlayAudioInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_AUDIO_INFO (info), 0);
return info->channels;
}
/**
* gst_play_audio_info_get_sample_rate:
* @info: a #GstPlayAudioInfo
*
* Returns: the audio sample rate in #GstPlayAudioInfo.
* Since: 1.20
*/
gint
gst_play_audio_info_get_sample_rate (const GstPlayAudioInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_AUDIO_INFO (info), 0);
return info->sample_rate;
}
/**
* gst_play_audio_info_get_bitrate:
* @info: a #GstPlayAudioInfo
*
* Returns: the audio bitrate in #GstPlayAudioInfo.
* Since: 1.20
*/
gint
gst_play_audio_info_get_bitrate (const GstPlayAudioInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_AUDIO_INFO (info), -1);
return info->bitrate;
}
/**
* gst_play_audio_info_get_max_bitrate:
* @info: a #GstPlayAudioInfo
*
* Returns: the audio maximum bitrate in #GstPlayAudioInfo.
* Since: 1.20
*/
gint
gst_play_audio_info_get_max_bitrate (const GstPlayAudioInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_AUDIO_INFO (info), -1);
return info->max_bitrate;
}
/* Subtitle information */
G_DEFINE_TYPE (GstPlaySubtitleInfo, gst_play_subtitle_info,
GST_TYPE_PLAY_STREAM_INFO);
static void
gst_play_subtitle_info_init (G_GNUC_UNUSED GstPlaySubtitleInfo * info)
{
/* nothing to do */
}
static void
gst_play_subtitle_info_finalize (GObject * object)
{
GstPlaySubtitleInfo *info = GST_PLAY_SUBTITLE_INFO (object);
g_free (info->language);
G_OBJECT_CLASS (gst_play_subtitle_info_parent_class)->finalize (object);
}
static void
gst_play_subtitle_info_class_init (GstPlaySubtitleInfoClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->finalize = gst_play_subtitle_info_finalize;
}
/**
* gst_play_subtitle_info_get_language:
* @info: a #GstPlaySubtitleInfo
*
* Returns: the language of the stream, or NULL if unknown.
* Since: 1.20
*/
const gchar *
gst_play_subtitle_info_get_language (const GstPlaySubtitleInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_SUBTITLE_INFO (info), NULL);
return info->language;
}
/* Global media information */
G_DEFINE_TYPE (GstPlayMediaInfo, gst_play_media_info, G_TYPE_OBJECT);
static void
gst_play_media_info_init (GstPlayMediaInfo * info)
{
info->duration = -1;
info->is_live = FALSE;
info->seekable = FALSE;
}
static void
gst_play_media_info_finalize (GObject * object)
{
GstPlayMediaInfo *info = GST_PLAY_MEDIA_INFO (object);
g_free (info->uri);
if (info->tags)
gst_tag_list_unref (info->tags);
g_free (info->title);
g_free (info->container);
if (info->image_sample)
gst_sample_unref (info->image_sample);
if (info->audio_stream_list)
g_list_free (info->audio_stream_list);
if (info->video_stream_list)
g_list_free (info->video_stream_list);
if (info->subtitle_stream_list)
g_list_free (info->subtitle_stream_list);
if (info->stream_list)
g_list_free_full (info->stream_list, g_object_unref);
G_OBJECT_CLASS (gst_play_media_info_parent_class)->finalize (object);
}
static void
gst_play_media_info_class_init (GstPlayMediaInfoClass * klass)
{
GObjectClass *oclass = (GObjectClass *) klass;
oclass->finalize = gst_play_media_info_finalize;
}
static GstPlayVideoInfo *
gst_play_video_info_new (void)
{
return g_object_new (GST_TYPE_PLAY_VIDEO_INFO, NULL);
}
static GstPlayAudioInfo *
gst_play_audio_info_new (void)
{
return g_object_new (GST_TYPE_PLAY_AUDIO_INFO, NULL);
}
static GstPlaySubtitleInfo *
gst_play_subtitle_info_new (void)
{
return g_object_new (GST_TYPE_PLAY_SUBTITLE_INFO, NULL);
}
static GstPlayStreamInfo *
gst_play_video_info_copy (GstPlayVideoInfo * ref)
{
GstPlayVideoInfo *ret;
ret = gst_play_video_info_new ();
ret->width = ref->width;
ret->height = ref->height;
ret->framerate_num = ref->framerate_num;
ret->framerate_denom = ref->framerate_denom;
ret->par_num = ref->par_num;
ret->par_denom = ref->par_denom;
ret->bitrate = ref->bitrate;
ret->max_bitrate = ref->max_bitrate;
return (GstPlayStreamInfo *) ret;
}
static GstPlayStreamInfo *
gst_play_audio_info_copy (GstPlayAudioInfo * ref)
{
GstPlayAudioInfo *ret;
ret = gst_play_audio_info_new ();
ret->sample_rate = ref->sample_rate;
ret->channels = ref->channels;
ret->bitrate = ref->bitrate;
ret->max_bitrate = ref->max_bitrate;
if (ref->language)
ret->language = g_strdup (ref->language);
return (GstPlayStreamInfo *) ret;
}
static GstPlayStreamInfo *
gst_play_subtitle_info_copy (GstPlaySubtitleInfo * ref)
{
GstPlaySubtitleInfo *ret;
ret = gst_play_subtitle_info_new ();
if (ref->language)
ret->language = g_strdup (ref->language);
return (GstPlayStreamInfo *) ret;
}
GstPlayStreamInfo *
gst_play_stream_info_copy (GstPlayStreamInfo * ref)
{
GstPlayStreamInfo *info = NULL;
if (!ref)
return NULL;
if (GST_IS_PLAY_VIDEO_INFO (ref))
info = gst_play_video_info_copy ((GstPlayVideoInfo *) ref);
else if (GST_IS_PLAY_AUDIO_INFO (ref))
info = gst_play_audio_info_copy ((GstPlayAudioInfo *) ref);
else
info = gst_play_subtitle_info_copy ((GstPlaySubtitleInfo *) ref);
info->stream_index = ref->stream_index;
if (ref->tags)
info->tags = gst_tag_list_ref (ref->tags);
if (ref->caps)
info->caps = gst_caps_copy (ref->caps);
if (ref->codec)
info->codec = g_strdup (ref->codec);
if (ref->stream_id)
info->stream_id = g_strdup (ref->stream_id);
return info;
}
GstPlayMediaInfo *
gst_play_media_info_copy (GstPlayMediaInfo * ref)
{
GList *l;
GstPlayMediaInfo *info;
if (!ref)
return NULL;
info = gst_play_media_info_new (ref->uri);
info->duration = ref->duration;
info->seekable = ref->seekable;
info->is_live = ref->is_live;
if (ref->tags)
info->tags = gst_tag_list_ref (ref->tags);
if (ref->title)
info->title = g_strdup (ref->title);
if (ref->container)
info->container = g_strdup (ref->container);
if (ref->image_sample)
info->image_sample = gst_sample_ref (ref->image_sample);
for (l = ref->stream_list; l != NULL; l = l->next) {
GstPlayStreamInfo *s;
s = gst_play_stream_info_copy ((GstPlayStreamInfo *) l->data);
info->stream_list = g_list_append (info->stream_list, s);
if (GST_IS_PLAY_AUDIO_INFO (s))
info->audio_stream_list = g_list_append (info->audio_stream_list, s);
else if (GST_IS_PLAY_VIDEO_INFO (s))
info->video_stream_list = g_list_append (info->video_stream_list, s);
else
info->subtitle_stream_list =
g_list_append (info->subtitle_stream_list, s);
}
return info;
}
GstPlayStreamInfo *
gst_play_stream_info_new (gint stream_index, GType type)
{
GstPlayStreamInfo *info = NULL;
if (type == GST_TYPE_PLAY_AUDIO_INFO)
info = (GstPlayStreamInfo *) gst_play_audio_info_new ();
else if (type == GST_TYPE_PLAY_VIDEO_INFO)
info = (GstPlayStreamInfo *) gst_play_video_info_new ();
else
info = (GstPlayStreamInfo *) gst_play_subtitle_info_new ();
info->stream_index = stream_index;
return info;
}
GstPlayMediaInfo *
gst_play_media_info_new (const gchar * uri)
{
GstPlayMediaInfo *info;
g_return_val_if_fail (uri != NULL, NULL);
info = g_object_new (GST_TYPE_PLAY_MEDIA_INFO, NULL);
info->uri = g_strdup (uri);
return info;
}
/**
* gst_play_media_info_get_uri:
* @info: a #GstPlayMediaInfo
*
* Returns: the URI associated with #GstPlayMediaInfo.
* Since: 1.20
*/
const gchar *
gst_play_media_info_get_uri (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->uri;
}
/**
* gst_play_media_info_is_seekable:
* @info: a #GstPlayMediaInfo
*
* Returns: %TRUE if the media is seekable.
* Since: 1.20
*/
gboolean
gst_play_media_info_is_seekable (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), FALSE);
return info->seekable;
}
/**
* gst_play_media_info_is_live:
* @info: a #GstPlayMediaInfo
*
* Returns: %TRUE if the media is live.
* Since: 1.20
*/
gboolean
gst_play_media_info_is_live (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), FALSE);
return info->is_live;
}
/**
* gst_play_media_info_get_stream_list:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none) (element-type GstPlayStreamInfo): A #GList of
* matching #GstPlayStreamInfo.
* Since: 1.20
*/
GList *
gst_play_media_info_get_stream_list (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->stream_list;
}
/**
* gst_play_media_info_get_video_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none) (element-type GstPlayVideoInfo): A #GList of
* matching #GstPlayVideoInfo.
* Since: 1.20
*/
GList *
gst_play_media_info_get_video_streams (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->video_stream_list;
}
/**
* gst_play_media_info_get_subtitle_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none) (element-type GstPlaySubtitleInfo): A #GList of
* matching #GstPlaySubtitleInfo.
* Since: 1.20
*/
GList *
gst_play_media_info_get_subtitle_streams (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->subtitle_stream_list;
}
/**
* gst_play_media_info_get_audio_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none) (element-type GstPlayAudioInfo): A #GList of
* matching #GstPlayAudioInfo.
* Since: 1.20
*/
GList *
gst_play_media_info_get_audio_streams (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->audio_stream_list;
}
/**
* gst_play_media_info_get_duration:
* @info: a #GstPlayMediaInfo
*
* Returns: duration of the media.
* Since: 1.20
*/
GstClockTime
gst_play_media_info_get_duration (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), -1);
return info->duration;
}
/**
* gst_play_media_info_get_tags:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none): the tags contained in media info.
* Since: 1.20
*/
GstTagList *
gst_play_media_info_get_tags (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->tags;
}
/**
* gst_play_media_info_get_title:
* @info: a #GstPlayMediaInfo
*
* Returns: the media title.
* Since: 1.20
*/
const gchar *
gst_play_media_info_get_title (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->title;
}
/**
* gst_play_media_info_get_container_format:
* @info: a #GstPlayMediaInfo
*
* Returns: the container format.
* Since: 1.20
*/
const gchar *
gst_play_media_info_get_container_format (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->container;
}
/**
* gst_play_media_info_get_image_sample:
* @info: a #GstPlayMediaInfo
*
* Function to get the image (or preview-image) stored in taglist.
* Application can use `gst_sample_*_()` API's to get caps, buffer etc.
*
* Returns: (transfer none): GstSample or NULL.
* Since: 1.20
*/
GstSample *
gst_play_media_info_get_image_sample (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), NULL);
return info->image_sample;
}
/**
* gst_play_media_info_get_number_of_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: number of total streams.
* Since: 1.20
*/
guint
gst_play_media_info_get_number_of_streams (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), 0);
return g_list_length (info->stream_list);
}
/**
* gst_play_media_info_get_number_of_video_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: number of video streams.
* Since: 1.20
*/
guint
gst_play_media_info_get_number_of_video_streams (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), 0);
return g_list_length (info->video_stream_list);
}
/**
* gst_play_media_info_get_number_of_audio_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: number of audio streams.
* Since: 1.20
*/
guint
gst_play_media_info_get_number_of_audio_streams (const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), 0);
return g_list_length (info->audio_stream_list);
}
/**
* gst_play_media_info_get_number_of_subtitle_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: number of subtitle streams.
* Since: 1.20
*/
guint gst_play_media_info_get_number_of_subtitle_streams
(const GstPlayMediaInfo * info)
{
g_return_val_if_fail (GST_IS_PLAY_MEDIA_INFO (info), 0);
return g_list_length (info->subtitle_stream_list);
}
/**
* gst_play_get_video_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none) (element-type GstPlayVideoInfo): A #GList of
* matching #GstPlayVideoInfo.
* Since: 1.20
*/
#ifndef GST_REMOVE_DEPRECATED
GList *
gst_play_get_video_streams (const GstPlayMediaInfo * info)
{
return gst_play_media_info_get_video_streams (info);
}
#endif
/**
* gst_play_get_audio_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none) (element-type GstPlayAudioInfo): A #GList of
* matching #GstPlayAudioInfo.
* Since: 1.20
*/
#ifndef GST_REMOVE_DEPRECATED
GList *
gst_play_get_audio_streams (const GstPlayMediaInfo * info)
{
return gst_play_media_info_get_audio_streams (info);
}
#endif
/**
* gst_play_get_subtitle_streams:
* @info: a #GstPlayMediaInfo
*
* Returns: (transfer none) (element-type GstPlaySubtitleInfo): A #GList of
* matching #GstPlaySubtitleInfo.
* Since: 1.20
*/
#ifndef GST_REMOVE_DEPRECATED
GList *
gst_play_get_subtitle_streams (const GstPlayMediaInfo * info)
{
return gst_play_media_info_get_subtitle_streams (info);
}
#endif

View file

@ -0,0 +1,280 @@
/* GStreamer
*
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@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 __GST_PLAY_MEDIA_INFO_H__
#define __GST_PLAY_MEDIA_INFO_H__
#include <gst/gst.h>
#include <gst/play/play-prelude.h>
G_BEGIN_DECLS
/**
* GST_TYPE_PLAY_STREAM_INFO:
* Since: 1.20
*/
#define GST_TYPE_PLAY_STREAM_INFO \
(gst_play_stream_info_get_type ())
#define GST_PLAY_STREAM_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAY_STREAM_INFO,GstPlayStreamInfo))
#define GST_PLAY_STREAM_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLAY_STREAM_INFO,GstPlayStreamInfo))
#define GST_IS_PLAY_STREAM_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAY_STREAM_INFO))
#define GST_IS_PLAY_STREAM_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAY_STREAM_INFO))
/**
* GstPlayStreamInfo:
*
* Base structure for information concerning a media stream. Depending on
* the stream type, one can find more media-specific information in
* #GstPlayVideoInfo, #GstPlayAudioInfo, #GstPlaySubtitleInfo.
* Since: 1.20
*/
typedef struct _GstPlayStreamInfo GstPlayStreamInfo;
typedef struct _GstPlayStreamInfoClass GstPlayStreamInfoClass;
GST_PLAY_API
GType gst_play_stream_info_get_type (void);
GST_PLAY_API
gint gst_play_stream_info_get_index (const GstPlayStreamInfo *info);
GST_PLAY_API
const gchar* gst_play_stream_info_get_stream_type (const GstPlayStreamInfo *info);
GST_PLAY_API
GstTagList* gst_play_stream_info_get_tags (const GstPlayStreamInfo *info);
GST_PLAY_API
GstCaps* gst_play_stream_info_get_caps (const GstPlayStreamInfo *info);
GST_PLAY_API
const gchar* gst_play_stream_info_get_codec (const GstPlayStreamInfo *info);
/**
* GST_TYPE_PLAY_VIDEO_INFO:
* Since: 1.20
*/
#define GST_TYPE_PLAY_VIDEO_INFO \
(gst_play_video_info_get_type ())
#define GST_PLAY_VIDEO_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAY_VIDEO_INFO, GstPlayVideoInfo))
#define GST_PLAY_VIDEO_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((obj),GST_TYPE_PLAY_VIDEO_INFO, GstPlayVideoInfoClass))
#define GST_IS_PLAY_VIDEO_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAY_VIDEO_INFO))
#define GST_IS_PLAY_VIDEO_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((obj),GST_TYPE_PLAY_VIDEO_INFO))
/**
* GstPlayVideoInfo:
*
* #GstPlayStreamInfo specific to video streams.
* Since: 1.20
*/
typedef struct _GstPlayVideoInfo GstPlayVideoInfo;
typedef struct _GstPlayVideoInfoClass GstPlayVideoInfoClass;
GST_PLAY_API
GType gst_play_video_info_get_type (void);
GST_PLAY_API
gint gst_play_video_info_get_bitrate (const GstPlayVideoInfo * info);
GST_PLAY_API
gint gst_play_video_info_get_max_bitrate (const GstPlayVideoInfo * info);
GST_PLAY_API
gint gst_play_video_info_get_width (const GstPlayVideoInfo * info);
GST_PLAY_API
gint gst_play_video_info_get_height (const GstPlayVideoInfo * info);
GST_PLAY_API
void gst_play_video_info_get_framerate (const GstPlayVideoInfo * info,
gint * fps_n,
gint * fps_d);
GST_PLAY_API
void gst_play_video_info_get_pixel_aspect_ratio (const GstPlayVideoInfo * info,
guint * par_n,
guint * par_d);
/**
* GST_TYPE_PLAY_AUDIO_INFO:
* Since: 1.20
*/
#define GST_TYPE_PLAY_AUDIO_INFO \
(gst_play_audio_info_get_type ())
#define GST_PLAY_AUDIO_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAY_AUDIO_INFO, GstPlayAudioInfo))
#define GST_PLAY_AUDIO_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLAY_AUDIO_INFO, GstPlayAudioInfoClass))
#define GST_IS_PLAY_AUDIO_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAY_AUDIO_INFO))
#define GST_IS_PLAY_AUDIO_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAY_AUDIO_INFO))
/**
* GstPlayAudioInfo:
*
* #GstPlayStreamInfo specific to audio streams.
* Since: 1.20
*/
typedef struct _GstPlayAudioInfo GstPlayAudioInfo;
typedef struct _GstPlayAudioInfoClass GstPlayAudioInfoClass;
GST_PLAY_API
GType gst_play_audio_info_get_type (void);
GST_PLAY_API
gint gst_play_audio_info_get_channels (const GstPlayAudioInfo* info);
GST_PLAY_API
gint gst_play_audio_info_get_sample_rate (const GstPlayAudioInfo* info);
GST_PLAY_API
gint gst_play_audio_info_get_bitrate (const GstPlayAudioInfo* info);
GST_PLAY_API
gint gst_play_audio_info_get_max_bitrate (const GstPlayAudioInfo* info);
GST_PLAY_API
const gchar* gst_play_audio_info_get_language (const GstPlayAudioInfo* info);
/**
* GST_TYPE_PLAY_SUBTITLE_INFO:
* Since: 1.20
*/
#define GST_TYPE_PLAY_SUBTITLE_INFO \
(gst_play_subtitle_info_get_type ())
#define GST_PLAY_SUBTITLE_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAY_SUBTITLE_INFO, GstPlaySubtitleInfo))
#define GST_PLAY_SUBTITLE_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLAY_SUBTITLE_INFO,GstPlaySubtitleInfoClass))
#define GST_IS_PLAY_SUBTITLE_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAY_SUBTITLE_INFO))
#define GST_IS_PLAY_SUBTITLE_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAY_SUBTITLE_INFO))
/**
* GstPlaySubtitleInfo:
*
* #GstPlayStreamInfo specific to subtitle streams.
* Since: 1.20
*/
typedef struct _GstPlaySubtitleInfo GstPlaySubtitleInfo;
typedef struct _GstPlaySubtitleInfoClass GstPlaySubtitleInfoClass;
GST_PLAY_API
GType gst_play_subtitle_info_get_type (void);
GST_PLAY_API
const gchar * gst_play_subtitle_info_get_language (const GstPlaySubtitleInfo* info);
/**
* GST_TYPE_PLAY_MEDIA_INFO:
* Since: 1.20
*/
#define GST_TYPE_PLAY_MEDIA_INFO \
(gst_play_media_info_get_type())
#define GST_PLAY_MEDIA_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAY_MEDIA_INFO,GstPlayMediaInfo))
#define GST_PLAY_MEDIA_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLAY_MEDIA_INFO,GstPlayMediaInfoClass))
#define GST_IS_PLAY_MEDIA_INFO(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAY_MEDIA_INFO))
#define GST_IS_PLAY_MEDIA_INFO_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAY_MEDIA_INFO))
/**
* GstPlayMediaInfo:
*
* Structure containing the media information of a URI.
* Since: 1.20
*/
typedef struct _GstPlayMediaInfo GstPlayMediaInfo;
typedef struct _GstPlayMediaInfoClass GstPlayMediaInfoClass;
GST_PLAY_API
GType gst_play_media_info_get_type (void);
GST_PLAY_API
const gchar * gst_play_media_info_get_uri (const GstPlayMediaInfo *info);
GST_PLAY_API
gboolean gst_play_media_info_is_seekable (const GstPlayMediaInfo *info);
GST_PLAY_API
gboolean gst_play_media_info_is_live (const GstPlayMediaInfo *info);
GST_PLAY_API
GstClockTime gst_play_media_info_get_duration (const GstPlayMediaInfo *info);
GST_PLAY_API
GList* gst_play_media_info_get_stream_list (const GstPlayMediaInfo *info);
GST_PLAY_API
guint gst_play_media_info_get_number_of_streams (const GstPlayMediaInfo *info);
GST_PLAY_API
GList* gst_play_media_info_get_video_streams (const GstPlayMediaInfo *info);
GST_PLAY_API
guint gst_play_media_info_get_number_of_video_streams (const GstPlayMediaInfo *info);
GST_PLAY_API
GList* gst_play_media_info_get_audio_streams (const GstPlayMediaInfo *info);
GST_PLAY_API
guint gst_play_media_info_get_number_of_audio_streams (const GstPlayMediaInfo *info);
GST_PLAY_API
GList* gst_play_media_info_get_subtitle_streams (const GstPlayMediaInfo *info);
GST_PLAY_API
guint gst_play_media_info_get_number_of_subtitle_streams (const GstPlayMediaInfo *info);
GST_PLAY_API
GstTagList* gst_play_media_info_get_tags (const GstPlayMediaInfo *info);
GST_PLAY_API
const gchar* gst_play_media_info_get_title (const GstPlayMediaInfo *info);
GST_PLAY_API
const gchar* gst_play_media_info_get_container_format (const GstPlayMediaInfo *info);
GST_PLAY_API
GstSample* gst_play_media_info_get_image_sample (const GstPlayMediaInfo *info);
GST_PLAY_DEPRECATED_FOR(gst_play_media_info_get_video_streams)
GList* gst_play_get_video_streams (const GstPlayMediaInfo *info);
GST_PLAY_DEPRECATED_FOR(gst_play_media_info_get_audio_streams)
GList* gst_play_get_audio_streams (const GstPlayMediaInfo *info);
GST_PLAY_DEPRECATED_FOR(gst_play_media_info_get_subtitle_streams)
GList* gst_play_get_subtitle_streams (const GstPlayMediaInfo *info);
G_END_DECLS
#endif /* __GST_PLAY_MEDIA_INFO_H */

View file

@ -0,0 +1,42 @@
/* GStreamer
*
* Copyright (C) 2020 Stephan Hesse <stephan@emliri.com>
* Copyright (C) 2020 Philippe Normand <philn@igalia.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 __GST_PLAY_MESSAGE_PRIVATE_H__
#define __GST_PLAY_MESSAGE_PRIVATE_H__
#define GST_PLAY_MESSAGE_DATA "gst-play-message-data"
#define GST_PLAY_MESSAGE_DATA_TYPE "play-message-type"
#define GST_PLAY_MESSAGE_DATA_URI "uri"
#define GST_PLAY_MESSAGE_DATA_POSITION "position"
#define GST_PLAY_MESSAGE_DATA_DURATION "duration"
#define GST_PLAY_MESSAGE_DATA_PLAY_STATE "play-state"
#define GST_PLAY_MESSAGE_DATA_BUFFERING_PERCENT "bufferring-percent"
#define GST_PLAY_MESSAGE_DATA_ERROR "error"
#define GST_PLAY_MESSAGE_DATA_ERROR_DETAILS "error-details"
#define GST_PLAY_MESSAGE_DATA_WARNING "warning"
#define GST_PLAY_MESSAGE_DATA_WARNING_DETAILS "warning-details"
#define GST_PLAY_MESSAGE_DATA_VIDEO_WIDTH "video-width"
#define GST_PLAY_MESSAGE_DATA_VIDEO_HEIGHT "video-height"
#define GST_PLAY_MESSAGE_DATA_MEDIA_INFO "media-info"
#define GST_PLAY_MESSAGE_DATA_VOLUME "volume"
#define GST_PLAY_MESSAGE_DATA_IS_MUTED "is-muted"
#endif

View file

@ -0,0 +1,460 @@
/* GStreamer
*
* Copyright (C) 2019-2020 Stephan Hesse <stephan@emliri.com>
* Copyright (C) 2020 Philippe Normand <philn@igalia.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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstplay.h"
#include "gstplay-signal-adapter.h"
#include "gstplay-message-private.h"
GST_DEBUG_CATEGORY_STATIC (gst_play_signal_adapter_debug);
#define GST_CAT_DEFAULT gst_play_signal_adapter_debug
enum
{
SIGNAL_URI_LOADED,
SIGNAL_POSITION_UPDATED,
SIGNAL_DURATION_CHANGED,
SIGNAL_STATE_CHANGED,
SIGNAL_BUFFERING,
SIGNAL_END_OF_STREAM,
SIGNAL_ERROR,
SIGNAL_WARNING,
SIGNAL_VIDEO_DIMENSIONS_CHANGED,
SIGNAL_MEDIA_INFO_UPDATED,
SIGNAL_VOLUME_CHANGED,
SIGNAL_MUTE_CHANGED,
SIGNAL_SEEK_DONE,
SIGNAL_LAST
};
enum
{
PROP_0,
PROP_PLAY,
PROP_LAST
};
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
struct _GstPlaySignalAdapter
{
GObject parent;
GstBus *bus;
GstPlay *play;
GSource *source;
};
struct _GstPlaySignalAdapterClass
{
GObjectClass parent_class;
};
#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_play_signal_adapter_debug, "gst-play-signal-adapter", \
0, "GstPlay signal adapter")
#define parent_class gst_play_signal_adapter_parent_class
G_DEFINE_TYPE_WITH_CODE (GstPlaySignalAdapter, gst_play_signal_adapter,
G_TYPE_OBJECT, _do_init);
static guint signals[SIGNAL_LAST] = { 0, };
static void
gst_play_signal_adapter_emit (GstPlaySignalAdapter * self,
const GstStructure * message_data)
{
GstPlayMessage play_message_type;
g_return_if_fail (g_str_equal (gst_structure_get_name (message_data),
GST_PLAY_MESSAGE_DATA));
GST_LOG ("Emitting message %" GST_PTR_FORMAT, message_data);
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_TYPE,
GST_TYPE_PLAY_MESSAGE, &play_message_type, NULL);
switch (play_message_type) {
case GST_PLAY_MESSAGE_URI_LOADED:{
const gchar *uri =
gst_structure_get_string (message_data, GST_PLAY_MESSAGE_DATA_URI);
g_signal_emit (self, signals[SIGNAL_URI_LOADED], 0, uri);
break;
}
case GST_PLAY_MESSAGE_POSITION_UPDATED:{
GstClockTime pos = GST_CLOCK_TIME_NONE;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_POSITION,
GST_TYPE_CLOCK_TIME, &pos, NULL);
g_signal_emit (self, signals[SIGNAL_POSITION_UPDATED], 0, pos);
break;
}
case GST_PLAY_MESSAGE_DURATION_CHANGED:{
GstClockTime duration = GST_CLOCK_TIME_NONE;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_DURATION,
GST_TYPE_CLOCK_TIME, &duration, NULL);
g_signal_emit (self, signals[SIGNAL_DURATION_CHANGED], 0, duration);
break;
}
case GST_PLAY_MESSAGE_STATE_CHANGED:{
GstPlayState state = 0;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_PLAY_STATE,
GST_TYPE_PLAY_STATE, &state, NULL);
g_signal_emit (self, signals[SIGNAL_STATE_CHANGED], 0, state);
break;
}
case GST_PLAY_MESSAGE_BUFFERING:{
guint percent = 0;
gst_structure_get (message_data,
GST_PLAY_MESSAGE_DATA_BUFFERING_PERCENT, G_TYPE_UINT, &percent, NULL);
g_signal_emit (self, signals[SIGNAL_BUFFERING], 0, percent);
break;
}
case GST_PLAY_MESSAGE_END_OF_STREAM:
g_signal_emit (self, signals[SIGNAL_END_OF_STREAM], 0);
break;
case GST_PLAY_MESSAGE_ERROR:{
GError *error = NULL;
GstStructure *details = NULL;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_ERROR,
G_TYPE_ERROR, &error, GST_PLAY_MESSAGE_DATA_ERROR_DETAILS,
GST_TYPE_STRUCTURE, &details, NULL);
g_signal_emit (self, signals[SIGNAL_ERROR], 0, error, details);
g_error_free (error);
if (details)
gst_structure_free (details);
break;
}
case GST_PLAY_MESSAGE_WARNING:{
GError *error = NULL;
GstStructure *details = NULL;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_WARNING,
G_TYPE_ERROR, &error, GST_PLAY_MESSAGE_DATA_WARNING_DETAILS,
GST_TYPE_STRUCTURE, &details, NULL);
g_signal_emit (self, signals[SIGNAL_WARNING], 0, error, details);
g_error_free (error);
if (details)
gst_structure_free (details);
break;
}
case GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED:{
guint width = 0;
guint height = 0;
gst_structure_get (message_data,
GST_PLAY_MESSAGE_DATA_VIDEO_WIDTH, G_TYPE_UINT, &width,
GST_PLAY_MESSAGE_DATA_VIDEO_HEIGHT, G_TYPE_UINT, &height, NULL);
g_signal_emit (self, signals[SIGNAL_VIDEO_DIMENSIONS_CHANGED], 0,
width, height);
break;
}
case GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED:{
GstPlayMediaInfo *media_info;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_MEDIA_INFO,
GST_TYPE_PLAY_MEDIA_INFO, &media_info, NULL);
g_signal_emit (self, signals[SIGNAL_VIDEO_DIMENSIONS_CHANGED], 0,
media_info);
g_object_unref (media_info);
break;
}
case GST_PLAY_MESSAGE_VOLUME_CHANGED:{
gdouble volume;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_VOLUME,
G_TYPE_DOUBLE, &volume, NULL);
g_signal_emit (self, signals[SIGNAL_VOLUME_CHANGED], 0, volume);
break;
}
case GST_PLAY_MESSAGE_MUTE_CHANGED:{
gboolean is_muted;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_IS_MUTED,
G_TYPE_BOOLEAN, &is_muted, NULL);
g_signal_emit (self, signals[SIGNAL_MUTE_CHANGED], 0, is_muted);
break;
}
case GST_PLAY_MESSAGE_SEEK_DONE:{
GstClockTime pos;
gst_structure_get (message_data, GST_PLAY_MESSAGE_DATA_POSITION,
GST_TYPE_CLOCK_TIME, &pos, NULL);
g_signal_emit (self, signals[SIGNAL_SEEK_DONE], 0, pos);
break;
}
default:
g_assert_not_reached ();
break;
}
}
/*
* callback for the bus-message in-sync handling
*/
static GstBusSyncReply
gst_play_signal_adapter_bus_sync_handler
(GstBus * bus, GstMessage * message, gpointer user_data)
{
GstPlaySignalAdapter *self = GST_PLAY_SIGNAL_ADAPTER (user_data);
const GstStructure *message_data = gst_message_get_structure (message);
gst_play_signal_adapter_emit (self, message_data);
gst_message_unref (message);
return GST_BUS_DROP;
}
/*
* callback for the bus-watch
* pre: there is a message on the bus
*/
static gboolean
gst_play_signal_adapter_on_message (GstBus * bus,
GstMessage * message, gpointer user_data)
{
GstPlaySignalAdapter *self = GST_PLAY_SIGNAL_ADAPTER (user_data);
const GstStructure *message_data = gst_message_get_structure (message);
gst_play_signal_adapter_emit (self, message_data);
return TRUE;
}
/**
* gst_play_signal_adapter_new:
* @play: (transfer none): #GstPlay instance to emit signals for.
*
* A bus-watching #GSource will be created and attached to the the
* thread-default #GMainContext. The attached callback will emit the
* corresponding signal for the message received. Matching signals for play
* messages from the bus will be emitted by it on the created adapter object.
*
* Returns: (transfer full): A new #GstPlaySignalAdapter to connect signal handlers to.
*
* Since: 1.20
*/
GstPlaySignalAdapter *
gst_play_signal_adapter_new (GstPlay * play)
{
GstPlaySignalAdapter *self = NULL;
GMainContext *context = NULL;
g_return_val_if_fail (GST_IS_PLAY (play), NULL);
self = g_object_new (GST_TYPE_PLAY_SIGNAL_ADAPTER, NULL);
self->play = play;
self->bus = gst_play_get_message_bus (play);
self->source = gst_bus_create_watch (self->bus);
context = g_main_context_get_thread_default ();
g_source_attach (self->source, context);
g_source_set_callback (self->source,
(GSourceFunc) gst_play_signal_adapter_on_message, self, NULL);
return self;
}
/**
* gst_play_signal_adapter_new_with_main_context:
* @play: (transfer none): #GstPlay instance to emit signals for.
* @context: A #GMainContext on which the main-loop will process play bus messages on.
*
* A bus-watching #GSource will be created and attached to the @context. The
* attached callback will emit the corresponding signal for the message
* received. Matching signals for play messages from the bus will be emitted by
* it on the created adapter object.
*
* Returns: (transfer full): A new #GstPlaySignalAdapter to connect signal handlers to.
*
* Since: 1.20
*/
GstPlaySignalAdapter *
gst_play_signal_adapter_new_with_main_context (GstPlay * play,
GMainContext * context)
{
GstPlaySignalAdapter *self = NULL;
g_return_val_if_fail (GST_IS_PLAY (play), NULL);
g_return_val_if_fail (context != NULL, NULL);
self = g_object_new (GST_TYPE_PLAY_SIGNAL_ADAPTER, NULL);
self->play = play;
self->bus = gst_play_get_message_bus (play);
self->source = gst_bus_create_watch (self->bus);
g_source_attach (self->source, context);
g_source_set_callback (self->source,
(GSourceFunc) gst_play_signal_adapter_on_message, self, NULL);
return self;
}
/**
* gst_play_signal_adapter_new_sync_emit:
* @play: (transfer none): #GstPlay instance to emit signals for.
*
* Create an adapter that synchronously emits its signals, from the thread in
* which the messages have been posted.
*
* Returns: (transfer full): A new #GstPlaySignalAdapter to connect signal handlers to.
*
* Since: 1.20
*/
GstPlaySignalAdapter *
gst_play_signal_adapter_new_sync_emit (GstPlay * play)
{
GstBus *bus = NULL;
GstPlaySignalAdapter *self = NULL;
g_return_val_if_fail (GST_IS_PLAY (play), NULL);
bus = gst_play_get_message_bus (play);
self = g_object_new (GST_TYPE_PLAY_SIGNAL_ADAPTER, NULL);
self->play = play;
self->bus = bus;
gst_bus_set_sync_handler (self->bus,
gst_play_signal_adapter_bus_sync_handler, self, NULL);
return self;
}
/**
* gst_play_signal_adapter_get_play:
* @adapter: #GstPlaySignalAdapter instance
*
* Returns: (transfer none): The #GstPlay owning this signal adapter.
*
* Since: 1.20
*/
GstPlay *
gst_play_signal_adapter_get_play (GstPlaySignalAdapter * adapter)
{
g_return_val_if_fail (GST_IS_PLAY_SIGNAL_ADAPTER (adapter), NULL);
return adapter->play;
}
static void
gst_play_signal_adapter_init (GstPlaySignalAdapter * self)
{
self->source = NULL;
}
static void
gst_play_signal_adapter_dispose (GObject * object)
{
GstPlaySignalAdapter *self = GST_PLAY_SIGNAL_ADAPTER (object);
if (self->source) {
g_source_destroy (self->source);
g_source_unref (self->source);
self->source = NULL;
}
gst_clear_object (&self->bus);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_play_signal_adapter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstPlaySignalAdapter *self = GST_PLAY_SIGNAL_ADAPTER (object);
switch (prop_id) {
case PROP_PLAY:
g_value_set_object (value, self->play);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_play_signal_adapter_class_init (GstPlaySignalAdapterClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->dispose = gst_play_signal_adapter_dispose;
gobject_class->get_property = gst_play_signal_adapter_get_property;
param_specs[PROP_PLAY] =
g_param_spec_object ("play", "Play",
"GstPlay owning this adapter",
GST_TYPE_PLAY, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
signals[SIGNAL_URI_LOADED] =
g_signal_new ("uri-loaded", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
signals[SIGNAL_POSITION_UPDATED] =
g_signal_new ("position-updated", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_CLOCK_TIME);
signals[SIGNAL_DURATION_CHANGED] =
g_signal_new ("duration-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_CLOCK_TIME);
signals[SIGNAL_STATE_CHANGED] =
g_signal_new ("state-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_PLAY_STATE);
signals[SIGNAL_BUFFERING] =
g_signal_new ("buffering", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 1, G_TYPE_INT);
signals[SIGNAL_END_OF_STREAM] =
g_signal_new ("end-of-stream", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 0, G_TYPE_INVALID);
signals[SIGNAL_ERROR] =
g_signal_new ("error", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 2, G_TYPE_ERROR, GST_TYPE_STRUCTURE);
signals[SIGNAL_VIDEO_DIMENSIONS_CHANGED] =
g_signal_new ("video-dimensions-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
signals[SIGNAL_MEDIA_INFO_UPDATED] =
g_signal_new ("media-info-updated", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_PLAY_MEDIA_INFO);
signals[SIGNAL_VOLUME_CHANGED] =
g_signal_new ("volume-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 0, G_TYPE_INVALID);
signals[SIGNAL_MUTE_CHANGED] =
g_signal_new ("mute-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 0, G_TYPE_INVALID);
signals[SIGNAL_WARNING] =
g_signal_new ("warning", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 2, G_TYPE_ERROR, GST_TYPE_STRUCTURE);
signals[SIGNAL_SEEK_DONE] =
g_signal_new ("seek-done", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, NULL,
NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_CLOCK_TIME);
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
}

View file

@ -0,0 +1,59 @@
/* GStreamer
*
* Copyright (C) 2019-2020 Stephan Hesse <stephan@emliri.com>
* Copyright (C) 2020 Philippe Normand <philn@igalia.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 __GST_PLAY_SIGNAL_ADAPTER_H__
#define __GST_PLAY_SIGNAL_ADAPTER_H__
#include <gst/play/gstplay-types.h>
G_BEGIN_DECLS
#define GST_TYPE_PLAY_SIGNAL_ADAPTER (gst_play_signal_adapter_get_type ())
#define GST_IS_PLAY_SIGNAL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAY_SIGNAL_ADAPTER))
#define GST_IS_PLAY_SIGNAL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY_SIGNAL_ADAPTER))
#define GST_PLAY_SIGNAL_ADAPTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLAY_SIGNAL_ADAPTER, GstPlaySignalAdapterClass))
#define GST_PLAY_SIGNAL_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAY_SIGNAL_ADAPTER, GstPlaySignalAdapter))
#define GST_PLAY_SIGNAL_ADAPTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLAY_SIGNAL_ADAPTER, GstPlaySignalAdapterClass))
/**
* GST_PLAY_SIGNAL_ADAPTER_CAST:
* Since: 1.20
*/
#define GST_PLAY_SIGNAL_ADAPTER_CAST(obj) ((GstPlaySignalAdapter*)(obj))
GST_PLAY_API
GType gst_play_signal_adapter_get_type (void);
GST_PLAY_API
GstPlaySignalAdapter * gst_play_signal_adapter_new (GstPlay * play);
GST_PLAY_API
GstPlaySignalAdapter * gst_play_signal_adapter_new_with_main_context (GstPlay * play, GMainContext * context);
GST_PLAY_API
GstPlaySignalAdapter * gst_play_signal_adapter_new_sync_emit (GstPlay * play);
GST_PLAY_API
GstPlay * gst_play_signal_adapter_get_play (GstPlaySignalAdapter * adapter);
G_END_DECLS
#endif /* __GST_PLAY_SIGNAL_ADAPTER_H__ */

View file

@ -0,0 +1,47 @@
/* GStreamer
*
* Copyright (C) 2015 Sebastian Dröge <sebastian@centricular.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 __GST_PLAY_TYPES_H__
#define __GST_PLAY_TYPES_H__
#include <gst/gst.h>
#include <gst/play/play-prelude.h>
G_BEGIN_DECLS
/**
* GstPlay:
* Since: 1.20
*/
typedef struct _GstPlay GstPlay;
typedef struct _GstPlayClass GstPlayClass;
/**
* GstPlaySignalAdapter:
* Since: 1.20
*/
typedef struct _GstPlaySignalAdapter GstPlaySignalAdapter;
typedef struct _GstPlaySignalAdapterClass GstPlaySignalAdapterClass;
G_END_DECLS
#endif /* __GST_PLAY_TYPES_H__ */

View file

@ -0,0 +1,351 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.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.
*/
/**
* SECTION:gstplay-videooverlayvideorenderer
* @title: GstPlayVideoOverlayVideoRenderer
* @short_description: Play Video Overlay Video Renderer
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstplay-video-overlay-video-renderer.h"
#include "gstplay.h"
#include <gst/video/video.h>
struct _GstPlayVideoOverlayVideoRenderer
{
GObject parent;
GstVideoOverlay *video_overlay;
gpointer window_handle;
gint x, y, width, height;
GstElement *video_sink; /* configured video sink, or NULL */
};
struct _GstPlayVideoOverlayVideoRendererClass
{
GObjectClass parent_class;
};
static void
gst_play_video_overlay_video_renderer_interface_init
(GstPlayVideoRendererInterface * iface);
enum
{
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_0,
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE,
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK,
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST
};
G_DEFINE_TYPE_WITH_CODE (GstPlayVideoOverlayVideoRenderer,
gst_play_video_overlay_video_renderer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GST_TYPE_PLAY_VIDEO_RENDERER,
gst_play_video_overlay_video_renderer_interface_init));
static GParamSpec
* video_overlay_video_renderer_param_specs
[VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST] = { NULL, };
static void
gst_play_video_overlay_video_renderer_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
{
GstPlayVideoOverlayVideoRenderer *self =
GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (object);
switch (prop_id) {
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE:
self->window_handle = g_value_get_pointer (value);
if (self->video_overlay)
gst_video_overlay_set_window_handle (self->video_overlay,
(guintptr) self->window_handle);
break;
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK:
self->video_sink = gst_object_ref_sink (g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_play_video_overlay_video_renderer_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
GstPlayVideoOverlayVideoRenderer *self =
GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (object);
switch (prop_id) {
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE:
g_value_set_pointer (value, self->window_handle);
break;
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK:
g_value_set_object (value, self->video_sink);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_play_video_overlay_video_renderer_finalize (GObject * object)
{
GstPlayVideoOverlayVideoRenderer *self =
GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (object);
if (self->video_overlay)
gst_object_unref (self->video_overlay);
if (self->video_sink)
gst_object_unref (self->video_sink);
G_OBJECT_CLASS
(gst_play_video_overlay_video_renderer_parent_class)->finalize (object);
}
static void
gst_play_video_overlay_video_renderer_class_init
(GstPlayVideoOverlayVideoRendererClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property =
gst_play_video_overlay_video_renderer_set_property;
gobject_class->get_property =
gst_play_video_overlay_video_renderer_get_property;
gobject_class->finalize = gst_play_video_overlay_video_renderer_finalize;
video_overlay_video_renderer_param_specs
[VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE] =
g_param_spec_pointer ("window-handle", "Window Handle",
"Window handle to embed the video into",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
video_overlay_video_renderer_param_specs
[VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK] =
g_param_spec_object ("video-sink", "Video Sink",
"the video output element to use (NULL = default sink)",
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class,
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST,
video_overlay_video_renderer_param_specs);
}
static void
gst_play_video_overlay_video_renderer_init
(GstPlayVideoOverlayVideoRenderer * self)
{
self->x = self->y = self->width = self->height = -1;
self->video_sink = NULL;
}
static GstElement *gst_play_video_overlay_video_renderer_create_video_sink
(GstPlayVideoRenderer * iface, GstPlay * play)
{
GstElement *video_overlay;
GstPlayVideoOverlayVideoRenderer *self =
GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (iface);
if (self->video_overlay)
gst_object_unref (self->video_overlay);
video_overlay = gst_play_get_pipeline (play);
g_return_val_if_fail (GST_IS_VIDEO_OVERLAY (video_overlay), NULL);
self->video_overlay = GST_VIDEO_OVERLAY (video_overlay);
gst_video_overlay_set_window_handle (self->video_overlay,
(guintptr) self->window_handle);
if (self->width != -1 || self->height != -1)
gst_video_overlay_set_render_rectangle (self->video_overlay, self->x,
self->y, self->width, self->height);
return self->video_sink;
}
static void
gst_play_video_overlay_video_renderer_interface_init
(GstPlayVideoRendererInterface * iface)
{
iface->create_video_sink =
gst_play_video_overlay_video_renderer_create_video_sink;
}
/**
* gst_play_video_overlay_video_renderer_new:
* @window_handle: (allow-none): Window handle to use or %NULL
*
* Returns: (transfer full):
* Since: 1.20
*/
GstPlayVideoRenderer *
gst_play_video_overlay_video_renderer_new (gpointer window_handle)
{
return g_object_new (GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER,
"window-handle", window_handle, NULL);
}
/**
* gst_play_video_overlay_video_renderer_new_with_sink:
* @window_handle: (allow-none): Window handle to use or %NULL
* @video_sink: (transfer floating): the custom video_sink element to be set for the video renderer
*
* Returns: (transfer full):
*
* Since: 1.20
*/
GstPlayVideoRenderer *
gst_play_video_overlay_video_renderer_new_with_sink (gpointer window_handle,
GstElement * video_sink)
{
return g_object_new (GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER,
"window-handle", window_handle, "video-sink", video_sink, NULL);
}
/**
* gst_play_video_overlay_video_renderer_set_window_handle:
* @self: #GstPlayVideoRenderer instance
* @window_handle: handle referencing to the platform specific window
*
* Sets the platform specific window handle into which the video
* should be rendered
* Since: 1.20
**/
void gst_play_video_overlay_video_renderer_set_window_handle
(GstPlayVideoOverlayVideoRenderer * self, gpointer window_handle)
{
g_return_if_fail (GST_IS_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (self));
g_object_set (self, "window-handle", window_handle, NULL);
}
/**
* gst_play_video_overlay_video_renderer_get_window_handle:
* @self: #GstPlayVideoRenderer instance
*
* Returns: (transfer none): The currently set, platform specific window
* handle
* Since: 1.20
*/
gpointer
gst_play_video_overlay_video_renderer_get_window_handle
(GstPlayVideoOverlayVideoRenderer * self) {
gpointer window_handle;
g_return_val_if_fail (GST_IS_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (self), NULL);
g_object_get (self, "window-handle", &window_handle, NULL);
return window_handle;
}
/**
* gst_play_video_overlay_video_renderer_expose:
* @self: a #GstPlayVideoOverlayVideoRenderer instance.
*
* Tell an overlay that it has been exposed. This will redraw the current frame
* in the drawable even if the pipeline is PAUSED.
* Since: 1.20
*/
void gst_play_video_overlay_video_renderer_expose
(GstPlayVideoOverlayVideoRenderer * self)
{
g_return_if_fail (GST_IS_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (self));
if (self->video_overlay)
gst_video_overlay_expose (self->video_overlay);
}
/**
* gst_play_video_overlay_video_renderer_set_render_rectangle:
* @self: a #GstPlayVideoOverlayVideoRenderer instance
* @x: the horizontal offset of the render area inside the window
* @y: the vertical offset of the render area inside the window
* @width: the width of the render area inside the window
* @height: the height of the render area inside the window
*
* Configure a subregion as a video target within the window set by
* gst_play_video_overlay_video_renderer_set_window_handle(). If this is not
* used or not supported the video will fill the area of the window set as the
* overlay to 100%. By specifying the rectangle, the video can be overlaid to
* a specific region of that window only. After setting the new rectangle one
* should call gst_play_video_overlay_video_renderer_expose() to force a
* redraw. To unset the region pass -1 for the @width and @height parameters.
*
* This method is needed for non fullscreen video overlay in UI toolkits that
* do not support subwindows.
*
* Since: 1.20
*/
void gst_play_video_overlay_video_renderer_set_render_rectangle
(GstPlayVideoOverlayVideoRenderer * self, gint x, gint y, gint width,
gint height)
{
g_return_if_fail (GST_IS_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (self));
self->x = x;
self->y = y;
self->width = width;
self->height = height;
if (self->video_overlay)
gst_video_overlay_set_render_rectangle (self->video_overlay,
x, y, width, height);
}
/**
* gst_play_video_overlay_video_renderer_get_render_rectangle:
* @self: a #GstPlayVideoOverlayVideoRenderer instance
* @x: (out) (allow-none): the horizontal offset of the render area inside the window
* @y: (out) (allow-none): the vertical offset of the render area inside the window
* @width: (out) (allow-none): the width of the render area inside the window
* @height: (out) (allow-none): the height of the render area inside the window
*
* Return the currently configured render rectangle. See gst_play_video_overlay_video_renderer_set_render_rectangle()
* for details.
*
* Since: 1.20
*/
void gst_play_video_overlay_video_renderer_get_render_rectangle
(GstPlayVideoOverlayVideoRenderer * self, gint * x, gint * y,
gint * width, gint * height)
{
g_return_if_fail (GST_IS_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (self));
if (x)
*x = self->x;
if (y)
*y = self->y;
if (width)
*width = self->width;
if (height)
*height = self->height;
}

View file

@ -0,0 +1,77 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.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 __GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_H__
#define __GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_H__
#include <gst/play/gstplay-types.h>
#include <gst/play/gstplay-video-renderer.h>
G_BEGIN_DECLS
/**
* GstPlayVideoOverlayVideoRenderer:
* Since: 1.20
*/
typedef struct _GstPlayVideoOverlayVideoRenderer
GstPlayVideoOverlayVideoRenderer;
typedef struct _GstPlayVideoOverlayVideoRendererClass
GstPlayVideoOverlayVideoRendererClass;
#define GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER (gst_play_video_overlay_video_renderer_get_type ())
#define GST_IS_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER))
#define GST_IS_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER))
#define GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER, GstPlayVideoOverlayVideoRendererClass))
#define GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER, GstPlayVideoOverlayVideoRenderer))
#define GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER, GstPlayVideoOverlayVideoRendererClass))
/**
* GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_CAST:
* Since: 1.20
*/
#define GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_CAST(obj) ((GstPlayVideoOverlayVideoRenderer*)(obj))
GST_PLAY_API
GType gst_play_video_overlay_video_renderer_get_type (void);
GST_PLAY_API
GstPlayVideoRenderer * gst_play_video_overlay_video_renderer_new (gpointer window_handle);
GST_PLAY_API
GstPlayVideoRenderer * gst_play_video_overlay_video_renderer_new_with_sink (gpointer window_handle, GstElement * video_sink);
GST_PLAY_API
void gst_play_video_overlay_video_renderer_set_window_handle (GstPlayVideoOverlayVideoRenderer * self, gpointer window_handle);
GST_PLAY_API
gpointer gst_play_video_overlay_video_renderer_get_window_handle (GstPlayVideoOverlayVideoRenderer * self);
GST_PLAY_API
void gst_play_video_overlay_video_renderer_expose (GstPlayVideoOverlayVideoRenderer * self);
GST_PLAY_API
void gst_play_video_overlay_video_renderer_set_render_rectangle (GstPlayVideoOverlayVideoRenderer * self, gint x, gint y, gint width, gint height);
GST_PLAY_API
void gst_play_video_overlay_video_renderer_get_render_rectangle (GstPlayVideoOverlayVideoRenderer * self, gint *x, gint *y, gint *width, gint *height);
G_END_DECLS
#endif /* __GST_PLAY_VIDEO_OVERLAY_VIDEO_RENDERER_H__ */

View file

@ -0,0 +1,33 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.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 __GST_PLAY_VIDEO_RENDERER_PRIVATE_H__
#define __GST_PLAY_VIDEO_RENDERER_PRIVATE_H__
#include <gst/play/gstplay-video-renderer.h>
G_BEGIN_DECLS
G_GNUC_INTERNAL GstElement * gst_play_video_renderer_create_video_sink (GstPlayVideoRenderer *
self, GstPlay * play);
G_END_DECLS
#endif /* __GST_PLAY_VIDEO_RENDERER_PRIVATE_H__ */

View file

@ -0,0 +1,49 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstplay-video-renderer.h"
#include "gstplay-video-renderer-private.h"
G_DEFINE_INTERFACE (GstPlayVideoRenderer, gst_play_video_renderer,
G_TYPE_OBJECT);
static void
gst_play_video_renderer_default_init (G_GNUC_UNUSED
GstPlayVideoRendererInterface * iface)
{
}
GstElement *
gst_play_video_renderer_create_video_sink (GstPlayVideoRenderer * self,
GstPlay * play)
{
GstPlayVideoRendererInterface *iface;
g_return_val_if_fail (GST_IS_PLAY_VIDEO_RENDERER (self), NULL);
iface = GST_PLAY_VIDEO_RENDERER_GET_INTERFACE (self);
g_return_val_if_fail (iface->create_video_sink != NULL, NULL);
return iface->create_video_sink (self, play);
}

View file

@ -0,0 +1,57 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.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 __GST_PLAY_VIDEO_RENDERER_H__
#define __GST_PLAY_VIDEO_RENDERER_H__
#include <gst/gst.h>
#include <gst/play/gstplay-types.h>
G_BEGIN_DECLS
/**
* GstPlayVideoRenderer:
* Since: 1.20
*/
typedef struct _GstPlayVideoRenderer GstPlayVideoRenderer;
typedef struct _GstPlayVideoRendererInterface GstPlayVideoRendererInterface;
#define GST_TYPE_PLAY_VIDEO_RENDERER (gst_play_video_renderer_get_type ())
#define GST_PLAY_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAY_VIDEO_RENDERER, GstPlayVideoRenderer))
#define GST_IS_PLAY_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAY_VIDEO_RENDERER))
/**
* GST_PLAY_VIDEO_RENDERER_GET_INTERFACE:
* Since: 1.20
*/
#define GST_PLAY_VIDEO_RENDERER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_PLAY_VIDEO_RENDERER, GstPlayVideoRendererInterface))
struct _GstPlayVideoRendererInterface {
GTypeInterface parent_iface;
GstElement * (*create_video_sink) (GstPlayVideoRenderer * self, GstPlay * play);
};
GST_PLAY_API
GType gst_play_video_renderer_get_type (void);
G_END_DECLS
#endif /* __GST_PLAY_VIDEO_RENDERER_H__ */

View file

@ -0,0 +1,183 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@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.
*/
/**
* SECTION:gstplay-visualization
* @title: GstPlayVisualization
* @short_description: Play Visualization
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstplay-visualization.h"
#include <string.h>
static GMutex vis_lock;
static GQueue vis_list = G_QUEUE_INIT;
static guint32 vis_cookie;
G_DEFINE_BOXED_TYPE (GstPlayVisualization, gst_play_visualization,
(GBoxedCopyFunc) gst_play_visualization_copy,
(GBoxedFreeFunc) gst_play_visualization_free);
/**
* gst_play_visualization_free:
* @vis: #GstPlayVisualization instance
*
* Frees a #GstPlayVisualization.
* Since: 1.20
*/
void
gst_play_visualization_free (GstPlayVisualization * vis)
{
g_return_if_fail (vis != NULL);
g_free (vis->name);
g_free (vis->description);
g_free (vis);
}
/**
* gst_play_visualization_copy:
* @vis: #GstPlayVisualization instance
*
* Makes a copy of the #GstPlayVisualization. The result must be
* freed using gst_play_visualization_free().
*
* Returns: (transfer full): an allocated copy of @vis.
* Since: 1.20
*/
GstPlayVisualization *
gst_play_visualization_copy (const GstPlayVisualization * vis)
{
GstPlayVisualization *ret;
g_return_val_if_fail (vis != NULL, NULL);
ret = g_new0 (GstPlayVisualization, 1);
ret->name = vis->name ? g_strdup (vis->name) : NULL;
ret->description = vis->description ? g_strdup (vis->description) : NULL;
return ret;
}
/**
* gst_play_visualizations_free:
* @viss: a %NULL terminated array of #GstPlayVisualization to free
*
* Frees a %NULL terminated array of #GstPlayVisualization.
* Since: 1.20
*/
void
gst_play_visualizations_free (GstPlayVisualization ** viss)
{
GstPlayVisualization **p;
g_return_if_fail (viss != NULL);
p = viss;
while (*p) {
g_free ((*p)->name);
g_free ((*p)->description);
g_free (*p);
p++;
}
g_free (viss);
}
static void
gst_play_update_visualization_list (void)
{
GList *features;
GList *l;
guint32 cookie;
GstPlayVisualization *vis;
g_mutex_lock (&vis_lock);
/* check if we need to update the list */
cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
if (vis_cookie == cookie) {
g_mutex_unlock (&vis_lock);
return;
}
/* if update is needed then first free the existing list */
while ((vis = g_queue_pop_head (&vis_list)))
gst_play_visualization_free (vis);
features = gst_registry_get_feature_list (gst_registry_get (),
GST_TYPE_ELEMENT_FACTORY);
for (l = features; l; l = l->next) {
GstPluginFeature *feature = l->data;
const gchar *klass;
klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY (feature),
GST_ELEMENT_METADATA_KLASS);
if (strstr (klass, "Visualization")) {
vis = g_new0 (GstPlayVisualization, 1);
vis->name = g_strdup (gst_plugin_feature_get_name (feature));
vis->description =
g_strdup (gst_element_factory_get_metadata (GST_ELEMENT_FACTORY
(feature), GST_ELEMENT_METADATA_DESCRIPTION));
g_queue_push_tail (&vis_list, vis);
}
}
gst_plugin_feature_list_free (features);
vis_cookie = cookie;
g_mutex_unlock (&vis_lock);
}
/**
* gst_play_visualizations_get:
*
* Returns: (transfer full) (array zero-terminated=1) (element-type GstPlayVisualization):
* a %NULL terminated array containing all available
* visualizations. Use gst_play_visualizations_free() after
* usage.
* Since: 1.20
*/
GstPlayVisualization **
gst_play_visualizations_get (void)
{
gint i = 0;
GList *l;
GstPlayVisualization **ret;
gst_play_update_visualization_list ();
g_mutex_lock (&vis_lock);
ret = g_new0 (GstPlayVisualization *, g_queue_get_length (&vis_list) + 1);
for (l = vis_list.head; l; l = l->next)
ret[i++] = gst_play_visualization_copy (l->data);
g_mutex_unlock (&vis_lock);
return ret;
}

View file

@ -0,0 +1,61 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@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 __GST_PLAY_VISUALIZATION_H__
#define __GST_PLAY_VISUALIZATION_H__
#include <gst/gst.h>
#include <gst/play/play-prelude.h>
G_BEGIN_DECLS
typedef struct _GstPlayVisualization GstPlayVisualization;
/**
* GstPlayVisualization:
* @name: name of the visualization.
* @description: description of the visualization.
*
* A #GstPlayVisualization descriptor.
* Since: 1.20
*/
struct _GstPlayVisualization {
gchar *name;
gchar *description;
};
GST_PLAY_API
GType gst_play_visualization_get_type (void);
GST_PLAY_API
GstPlayVisualization * gst_play_visualization_copy (const GstPlayVisualization *vis);
GST_PLAY_API
void gst_play_visualization_free (GstPlayVisualization *vis);
GST_PLAY_API
GstPlayVisualization ** gst_play_visualizations_get (void);
GST_PLAY_API
void gst_play_visualizations_free (GstPlayVisualization **viss);
G_END_DECLS
#endif /* __GST_PLAY_VISUALIZATION_H__ */

4738
gst-libs/gst/play/gstplay.c Normal file

File diff suppressed because it is too large Load diff

442
gst-libs/gst/play/gstplay.h Normal file
View file

@ -0,0 +1,442 @@
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
* Copyright (C) 2019-2020 Stephan Hesse <stephan@emliri.com>
* Copyright (C) 2020 Philippe Normand <philn@igalia.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 __GST_PLAY_H__
#define __GST_PLAY_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/play/play-prelude.h>
#include <gst/play/gstplay-types.h>
#include <gst/play/gstplay-video-renderer.h>
#include <gst/play/gstplay-media-info.h>
G_BEGIN_DECLS
GST_PLAY_API
GType gst_play_state_get_type (void);
/**
* GST_TYPE_PLAY_STATE:
* Since: 1.20
*/
#define GST_TYPE_PLAY_STATE (gst_play_state_get_type ())
GST_PLAY_API
GType gst_play_message_get_type (void);
/**
* GST_TYPE_PLAY_MESSAGE:
* Since: 1.20
*/
#define GST_TYPE_PLAY_MESSAGE (gst_play_message_get_type ())
/**
* GstPlayState:
* @GST_PLAY_STATE_STOPPED: the play is stopped.
* @GST_PLAY_STATE_BUFFERING: the play is buffering.
* @GST_PLAY_STATE_PAUSED: the play is paused.
* @GST_PLAY_STATE_PLAYING: the play is currently playing a
* stream.
*
* Since: 1.20
*/
typedef enum
{
GST_PLAY_STATE_STOPPED,
GST_PLAY_STATE_BUFFERING,
GST_PLAY_STATE_PAUSED,
GST_PLAY_STATE_PLAYING
} GstPlayState;
/**
* GstPlayMessage:
* @GST_PLAY_MESSAGE_URI_LOADED: Source element was initalized for set URI
* @GST_PLAY_MESSAGE_POSITION_UPDATED: Sink position changed
* @GST_PLAY_MESSAGE_DURATION_CHANGED: Duration of stream changed
* @GST_PLAY_MESSAGE_STATE_CHANGED: State changed, see #GstPlayState
* @GST_PLAY_MESSAGE_BUFFERING: Pipeline is in buffering state, message contains the percentage value of the decoding buffer
* @GST_PLAY_MESSAGE_END_OF_STREAM: Sink has received EOS
* @GST_PLAY_MESSAGE_ERROR: Message contains an error
* @GST_PLAY_MESSAGE_WARNING: Message contains an error
* @GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED: Video sink received format in different dimensions than before
* @GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED: A media-info property has changed, message contains current #GstPlayMediaInfo
* @GST_PLAY_MESSAGE_VOLUME_CHANGED: The volume of the audio ouput has changed
* @GST_PLAY_MESSAGE_MUTE_CHANGED: Audio muting flag has been toggled
* @GST_PLAY_MESSAGE_SEEK_DONE: Any pending seeking operation has been completed
*
* Since: 1.20
*
* Types of messages that will be posted on the play API bus.
*
* See also #gst_play_get_message_bus()
*
*/
typedef enum
{
GST_PLAY_MESSAGE_URI_LOADED,
GST_PLAY_MESSAGE_POSITION_UPDATED,
GST_PLAY_MESSAGE_DURATION_CHANGED,
GST_PLAY_MESSAGE_STATE_CHANGED,
GST_PLAY_MESSAGE_BUFFERING,
GST_PLAY_MESSAGE_END_OF_STREAM,
GST_PLAY_MESSAGE_ERROR,
GST_PLAY_MESSAGE_WARNING,
GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED,
GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED,
GST_PLAY_MESSAGE_VOLUME_CHANGED,
GST_PLAY_MESSAGE_MUTE_CHANGED,
GST_PLAY_MESSAGE_SEEK_DONE
} GstPlayMessage;
GST_PLAY_API
const gchar *gst_play_state_get_name (GstPlayState state);
GST_PLAY_API
const gchar *gst_play_message_get_name (GstPlayMessage message_type);
GST_PLAY_API
GQuark gst_play_error_quark (void);
GST_PLAY_API
GType gst_play_error_get_type (void);
/**
* GST_PLAY_ERROR:
*
* Since: 1.20
*/
#define GST_PLAY_ERROR (gst_play_error_quark ())
/**
* GST_TYPE_PLAY_ERROR:
*
* Since: 1.20
*/
#define GST_TYPE_PLAY_ERROR (gst_play_error_get_type ())
/**
* GstPlayError:
* @GST_PLAY_ERROR_FAILED: generic error.
*
* Since: 1.20
*/
typedef enum {
GST_PLAY_ERROR_FAILED = 0
} GstPlayError;
GST_PLAY_API
const gchar *gst_play_error_get_name (GstPlayError error);
GST_PLAY_API
GType gst_play_color_balance_type_get_type (void);
/**
* GST_TYPE_PLAY_COLOR_BALANCE_TYPE:
*
* Since: 1.20
*/
#define GST_TYPE_PLAY_COLOR_BALANCE_TYPE (gst_play_color_balance_type_get_type ())
/**
* GstPlayColorBalanceType:
* @GST_PLAY_COLOR_BALANCE_BRIGHTNESS: brightness or black level.
* @GST_PLAY_COLOR_BALANCE_CONTRAST: contrast or luma gain.
* @GST_PLAY_COLOR_BALANCE_SATURATION: color saturation or chroma
* gain.
* @GST_PLAY_COLOR_BALANCE_HUE: hue or color balance.
*
* Since: 1.20
*/
typedef enum
{
GST_PLAY_COLOR_BALANCE_BRIGHTNESS,
GST_PLAY_COLOR_BALANCE_CONTRAST,
GST_PLAY_COLOR_BALANCE_SATURATION,
GST_PLAY_COLOR_BALANCE_HUE,
} GstPlayColorBalanceType;
GST_PLAY_API
const gchar *gst_play_color_balance_type_get_name (GstPlayColorBalanceType type);
#define GST_TYPE_PLAY (gst_play_get_type ())
#define GST_IS_PLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAY))
#define GST_IS_PLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY))
#define GST_PLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLAY, GstPlayClass))
#define GST_PLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAY, GstPlay))
#define GST_PLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLAY, GstPlayClass))
/**
* GST_PLAY_CAST:
* Since: 1.20
*/
#define GST_PLAY_CAST(obj) ((GstPlay*)(obj))
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstPlay, gst_object_unref)
#endif
GST_PLAY_API
GType gst_play_get_type (void);
GST_PLAY_API
GstPlay * gst_play_new (GstPlayVideoRenderer * video_renderer);
GST_PLAY_API
GstBus * gst_play_get_message_bus (GstPlay * play);
GST_PLAY_API
void gst_play_play (GstPlay * play);
GST_PLAY_API
void gst_play_pause (GstPlay * play);
GST_PLAY_API
void gst_play_stop (GstPlay * play);
GST_PLAY_API
void gst_play_seek (GstPlay * play,
GstClockTime position);
GST_PLAY_API
void gst_play_set_rate (GstPlay * play,
gdouble rate);
GST_PLAY_API
gdouble gst_play_get_rate (GstPlay * play);
GST_PLAY_API
gchar * gst_play_get_uri (GstPlay * play);
GST_PLAY_API
void gst_play_set_uri (GstPlay * play,
const gchar * uri);
GST_PLAY_API
gchar * gst_play_get_subtitle_uri (GstPlay * play);
GST_PLAY_API
void gst_play_set_subtitle_uri (GstPlay * play,
const gchar *uri);
GST_PLAY_API
GstClockTime gst_play_get_position (GstPlay * play);
GST_PLAY_API
GstClockTime gst_play_get_duration (GstPlay * play);
GST_PLAY_API
gdouble gst_play_get_volume (GstPlay * play);
GST_PLAY_API
void gst_play_set_volume (GstPlay * play,
gdouble val);
GST_PLAY_API
gboolean gst_play_get_mute (GstPlay * play);
GST_PLAY_API
void gst_play_set_mute (GstPlay * play,
gboolean val);
GST_PLAY_API
GstElement * gst_play_get_pipeline (GstPlay * play);
GST_PLAY_API
void gst_play_set_video_track_enabled (GstPlay * play,
gboolean enabled);
GST_PLAY_API
void gst_play_set_audio_track_enabled (GstPlay * play,
gboolean enabled);
GST_PLAY_API
void gst_play_set_subtitle_track_enabled (GstPlay * play,
gboolean enabled);
GST_PLAY_API
gboolean gst_play_set_audio_track (GstPlay *play,
gint stream_index);
GST_PLAY_API
gboolean gst_play_set_video_track (GstPlay *play,
gint stream_index);
GST_PLAY_API
gboolean gst_play_set_subtitle_track (GstPlay *play,
gint stream_index);
GST_PLAY_API
GstPlayMediaInfo * gst_play_get_media_info (GstPlay * play);
GST_PLAY_API
GstPlayAudioInfo * gst_play_get_current_audio_track (GstPlay * play);
GST_PLAY_API
GstPlayVideoInfo * gst_play_get_current_video_track (GstPlay * play);
GST_PLAY_API
GstPlaySubtitleInfo * gst_play_get_current_subtitle_track (GstPlay * play);
GST_PLAY_API
gboolean gst_play_set_visualization (GstPlay * play,
const gchar *name);
GST_PLAY_API
void gst_play_set_visualization_enabled (GstPlay * play,
gboolean enabled);
GST_PLAY_API
gchar * gst_play_get_current_visualization (GstPlay * play);
GST_PLAY_API
gboolean gst_play_has_color_balance (GstPlay * play);
GST_PLAY_API
void gst_play_set_color_balance (GstPlay * play,
GstPlayColorBalanceType type,
gdouble value);
GST_PLAY_API
gdouble gst_play_get_color_balance (GstPlay * play,
GstPlayColorBalanceType type);
GST_PLAY_API
GstVideoMultiviewFramePacking gst_play_get_multiview_mode (GstPlay * play);
GST_PLAY_API
void gst_play_set_multiview_mode (GstPlay * play,
GstVideoMultiviewFramePacking mode);
GST_PLAY_API
GstVideoMultiviewFlags gst_play_get_multiview_flags (GstPlay * play);
GST_PLAY_API
void gst_play_set_multiview_flags (GstPlay * play,
GstVideoMultiviewFlags flags);
GST_PLAY_API
gint64 gst_play_get_audio_video_offset (GstPlay * play);
GST_PLAY_API
void gst_play_set_audio_video_offset (GstPlay * play,
gint64 offset);
GST_PLAY_API
gint64 gst_play_get_subtitle_video_offset (GstPlay * play);
GST_PLAY_API
void gst_play_set_subtitle_video_offset (GstPlay * play,
gint64 offset);
GST_PLAY_API
gboolean gst_play_set_config (GstPlay * play,
GstStructure * config);
GST_PLAY_API
GstStructure * gst_play_get_config (GstPlay * play);
/* helpers for configuring the config structure */
GST_PLAY_API
void gst_play_config_set_user_agent (GstStructure * config,
const gchar * agent);
GST_PLAY_API
gchar * gst_play_config_get_user_agent (const GstStructure * config);
GST_PLAY_API
void gst_play_config_set_position_update_interval (GstStructure * config,
guint interval);
GST_PLAY_API
guint gst_play_config_get_position_update_interval (const GstStructure * config);
GST_PLAY_API
void gst_play_config_set_seek_accurate (GstStructure * config, gboolean accurate);
GST_PLAY_API
gboolean gst_play_config_get_seek_accurate (const GstStructure * config);
/**
* GstPlaySnapshotFormat:
* @GST_PLAY_THUMBNAIL_RAW_NATIVE: raw native format.
* @GST_PLAY_THUMBNAIL_RAW_xRGB: raw xRGB format.
* @GST_PLAY_THUMBNAIL_RAW_BGRx: raw BGRx format.
* @GST_PLAY_THUMBNAIL_JPG: jpeg format.
* @GST_PLAY_THUMBNAIL_PNG: png format.
*
* Since: 1.20
*/
typedef enum
{
GST_PLAY_THUMBNAIL_RAW_NATIVE = 0,
GST_PLAY_THUMBNAIL_RAW_xRGB,
GST_PLAY_THUMBNAIL_RAW_BGRx,
GST_PLAY_THUMBNAIL_JPG,
GST_PLAY_THUMBNAIL_PNG
} GstPlaySnapshotFormat;
GST_PLAY_API
GstSample * gst_play_get_video_snapshot (GstPlay * play,
GstPlaySnapshotFormat format, const GstStructure * config);
GST_PLAY_API
gboolean gst_play_is_play_message (GstMessage *msg);
GST_PLAY_API
void gst_play_message_parse_type (GstMessage *msg, GstPlayMessage *type);
GST_PLAY_API
void gst_play_message_parse_duration_updated (GstMessage *msg, GstClockTime *duration);
GST_PLAY_API
void gst_play_message_parse_position_updated (GstMessage *msg, GstClockTime *position);
GST_PLAY_API
void gst_play_message_parse_state_changed (GstMessage *msg, GstPlayState *state);
GST_PLAY_API
void gst_play_message_parse_buffering_percent (GstMessage *msg, guint *percent);
GST_PLAY_API
void gst_play_message_parse_error (GstMessage *msg, GError *error, GstStructure **details);
GST_PLAY_API
void gst_play_message_parse_warning (GstMessage *msg, GError *error, GstStructure **details);
GST_PLAY_API
void gst_play_message_parse_video_dimensions_changed (GstMessage *msg, guint *width, guint *height);
GST_PLAY_API
void gst_play_message_parse_media_info_updated (GstMessage *msg, GstPlayMediaInfo **info);
GST_PLAY_API
void gst_play_message_parse_volume_changed (GstMessage *msg, gdouble *volume);
GST_PLAY_API
void gst_play_message_parse_muted_changed (GstMessage *msg, gboolean *muted);
G_END_DECLS
#endif /* __GST_PLAY_H__ */

View file

@ -0,0 +1,69 @@
gstplay_sources = [
'gstplay.c',
'gstplay-signal-adapter.c',
'gstplay-video-renderer.c',
'gstplay-media-info.c',
'gstplay-video-overlay-video-renderer.c',
'gstplay-visualization.c',
]
gstplay_headers = [
'play.h',
'play-prelude.h',
'gstplay.h',
'gstplay-types.h',
'gstplay-signal-adapter.h',
'gstplay-video-renderer.h',
'gstplay-media-info.h',
'gstplay-video-overlay-video-renderer.h',
'gstplay-visualization.h',
]
install_headers(gstplay_headers, subdir : 'gstreamer-' + api_version + '/gst/play/')
gstplay = library('gstplay-' + api_version,
gstplay_sources,
c_args : gst_plugins_bad_args + ['-DBUILDING_GST_PLAY'],
include_directories : [configinc, libsinc],
version : libversion,
soversion : soversion,
darwin_versions : osxversion,
install : true,
dependencies : [gstbase_dep, gstvideo_dep, gstaudio_dep,
gsttag_dep, gstpbutils_dep],
)
pkgconfig.generate(gstplay,
libraries : [gst_dep, gstvideo_dep],
variables : pkgconfig_variables,
subdirs : pkgconfig_subdirs,
name : 'gstreamer-play-1.0',
description : 'GStreamer Player convenience library',
)
gen_sources = []
if build_gir
play_gir = gnome.generate_gir(gstplay,
sources : gstplay_sources + gstplay_headers,
namespace : 'GstPlay',
nsversion : api_version,
identifier_prefix : 'Gst',
symbol_prefix : 'gst',
export_packages : 'gstreamer-play-1.0',
includes : ['Gst-1.0', 'GstPbutils-1.0', 'GstBase-1.0', 'GstVideo-1.0',
'GstAudio-1.0', 'GstTag-1.0'],
install : true,
extra_args : gir_init_section + ['-DGST_USE_UNSTABLE_API'] + ['--c-include=gst/play/play.h'],
dependencies : [gstbase_dep, gstvideo_dep, gstaudio_dep,
gsttag_dep, gstpbutils_dep]
)
gen_sources += play_gir
endif
gstplay_dep = declare_dependency(link_with : gstplay,
include_directories : [libsinc],
sources: gen_sources,
dependencies : [gstbase_dep, gstvideo_dep, gstaudio_dep,
gsttag_dep, gstpbutils_dep])
meson.override_dependency('gstreamer-play-1.0', gstplay_dep)

View file

@ -0,0 +1,43 @@
/* GStreamer Play Library
* Copyright (C) 2018 GStreamer developers
*
* play-prelude.h: prelude include header for gst-play library
*
* 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 __GST_PLAY_PRELUDE_H__
#define __GST_PLAY_PRELUDE_H__
#include <gst/gst.h>
#ifndef GST_PLAY_API
# ifdef BUILDING_GST_PLAY
# define GST_PLAY_API GST_API_EXPORT /* from config.h */
# else
# define GST_PLAY_API GST_API_IMPORT
# endif
#endif
#ifndef GST_DISABLE_DEPRECATED
#define GST_PLAY_DEPRECATED GST_PLAY_API
#define GST_PLAY_DEPRECATED_FOR(f) GST_PLAY_API
#else
#define GST_PLAY_DEPRECATED G_DEPRECATED GST_PLAY_API
#define GST_PLAY_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) GST_PLAY_API
#endif
#endif /* __GST_PLAY_PRELUDE_H__ */

31
gst-libs/gst/play/play.h Normal file
View file

@ -0,0 +1,31 @@
/* GStreamer
*
* Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.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 __PLAY_H__
#define __PLAY_H__
#include <gst/play/play-prelude.h>
#include <gst/play/gstplay.h>
#include <gst/play/gstplay-media-info.h>
#include <gst/play/gstplay-video-overlay-video-renderer.h>
#include <gst/play/gstplay-visualization.h>
#include <gst/play/gstplay-signal-adapter.h>
#endif /* __PLAY_H__ */