gstreamer/gst/playback/gststreaminfo.c
Sebastian Dröge 49deb0c05d Use G_PARAM_STATIC_STRINGS everywhere for GParamSpecs that use static strings (i.e. all). This gives us less memory u...
Original commit message from CVS:
* configure.ac:
* ext/alsa/gstalsamixerelement.c:
(gst_alsa_mixer_element_class_init):
* ext/alsa/gstalsasink.c: (gst_alsasink_class_init):
* ext/alsa/gstalsasrc.c: (gst_alsasrc_class_init):
* ext/cdparanoia/gstcdparanoiasrc.c:
(gst_cd_paranoia_src_class_init):
* ext/gio/gstgiosink.c: (gst_gio_sink_class_init):
* ext/gio/gstgiosrc.c: (gst_gio_src_class_init):
* ext/gio/gstgiostreamsink.c: (gst_gio_stream_sink_class_init):
* ext/gio/gstgiostreamsrc.c: (gst_gio_stream_src_class_init):
* ext/gnomevfs/gstgnomevfssink.c: (gst_gnome_vfs_sink_class_init):
* ext/gnomevfs/gstgnomevfssrc.c: (gst_gnome_vfs_src_class_init):
* ext/ogg/gstoggmux.c: (gst_ogg_mux_class_init):
* ext/pango/gsttextoverlay.c: (gst_text_overlay_class_init):
* ext/pango/gsttextrender.c: (gst_text_render_class_init):
* ext/theora/theoradec.c: (gst_theora_dec_class_init):
* ext/theora/theoraenc.c: (gst_theora_enc_class_init):
* ext/theora/theoraparse.c: (gst_theora_parse_class_init):
* ext/vorbis/vorbisenc.c: (gst_vorbis_enc_class_init):
* gst-libs/gst/audio/gstaudiofiltertemplate.c:
(gst_audio_filter_template_class_init):
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_class_init):
* gst-libs/gst/audio/gstbaseaudiosrc.c:
(gst_base_audio_src_class_init):
* gst-libs/gst/cdda/gstcddabasesrc.c:
(gst_cdda_base_src_class_init):
* gst-libs/gst/interfaces/mixertrack.c:
(gst_mixer_track_class_init):
* gst-libs/gst/rtp/gstbasertpdepayload.c:
(gst_base_rtp_depayload_class_init):
* gst-libs/gst/rtp/gstbasertppayload.c:
(gst_basertppayload_class_init):
* gst/audioconvert/gstaudioconvert.c:
(gst_audio_convert_class_init):
* gst/audiorate/gstaudiorate.c: (gst_audio_rate_class_init):
* gst/audioresample/gstaudioresample.c:
(gst_audioresample_class_init):
* gst/audiotestsrc/gstaudiotestsrc.c:
(gst_audio_test_src_class_init):
* gst/gdp/gstgdppay.c: (gst_gdp_pay_class_init):
* gst/playback/gstdecodebin2.c: (gst_decode_bin_class_init):
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
(preroll_unlinked):
* gst/playback/gstplaybin.c: (gst_play_bin_class_init):
* gst/playback/gstplaybin2.c: (gst_play_bin_class_init):
* gst/playback/gstplaysink.c: (gst_play_sink_class_init):
* gst/playback/gstqueue2.c: (gst_queue_class_init):
* gst/playback/gststreaminfo.c: (gst_stream_info_class_init):
* gst/playback/gststreamselector.c: (gst_selector_pad_class_init),
(gst_stream_selector_class_init):
* gst/playback/gsturidecodebin.c: (gst_uri_decode_bin_class_init):
* gst/subparse/gstsubparse.c: (gst_sub_parse_class_init):
* gst/tcp/gstmultifdsink.c: (gst_multi_fd_sink_class_init):
* gst/tcp/gsttcpclientsink.c: (gst_tcp_client_sink_class_init):
* gst/tcp/gsttcpclientsrc.c: (gst_tcp_client_src_class_init):
* gst/tcp/gsttcpserversink.c: (gst_tcp_server_sink_class_init):
* gst/tcp/gsttcpserversrc.c: (gst_tcp_server_src_class_init):
* gst/videorate/gstvideorate.c: (gst_video_rate_class_init):
* gst/videoscale/gstvideoscale.c: (gst_video_scale_class_init):
* gst/videotestsrc/gstvideotestsrc.c:
(gst_video_test_src_class_init):
* gst/volume/gstvolume.c: (gst_volume_class_init):
* sys/v4l/gstv4lelement.c: (gst_v4lelement_class_init):
* sys/v4l/gstv4lmjpegsink.c: (gst_v4lmjpegsink_class_init):
* sys/v4l/gstv4lmjpegsrc.c: (gst_v4lmjpegsrc_class_init):
* sys/v4l/gstv4lsrc.c: (gst_v4lsrc_class_init):
* sys/ximage/ximagesink.c: (gst_ximagesink_class_init):
* sys/xvimage/xvimagesink.c: (gst_xvimagesink_class_init):
Use G_PARAM_STATIC_STRINGS everywhere for GParamSpecs that use
static strings (i.e. all). This gives us less memory usage,
fewer allocations and thus less memory defragmentation. Depend
on core CVS for this. Fixes bug #523806.
2008-03-22 15:00:53 +00:00

402 lines
12 KiB
C

/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <gst/gst.h>
#include "gststreaminfo.h"
GST_DEBUG_CATEGORY_STATIC (gst_streaminfo_debug);
#define GST_CAT_DEFAULT gst_streaminfo_debug
/* props */
enum
{
ARG_0,
ARG_PAD,
ARG_TYPE,
ARG_DECODER,
ARG_MUTE,
ARG_CAPS,
ARG_LANG_CODE,
ARG_CODEC
};
/* signals */
enum
{
SIGNAL_MUTED,
LAST_SIGNAL
};
static guint gst_stream_info_signals[LAST_SIGNAL] = { 0 };
#define GST_TYPE_STREAM_TYPE (gst_stream_type_get_type())
static GType
gst_stream_type_get_type (void)
{
static GType stream_type_type = 0;
static const GEnumValue stream_type[] = {
{GST_STREAM_TYPE_UNKNOWN, "Unknown stream", "unknown"},
{GST_STREAM_TYPE_AUDIO, "Audio stream", "audio"},
{GST_STREAM_TYPE_VIDEO, "Video stream", "video"},
{GST_STREAM_TYPE_TEXT, "Text stream", "text"},
{GST_STREAM_TYPE_SUBPICTURE, "Subpicture stream", "subpicture"},
{GST_STREAM_TYPE_ELEMENT,
"Stream handled by element", "element"},
{0, NULL, NULL},
};
if (!stream_type_type) {
stream_type_type = g_enum_register_static ("GstStreamType", stream_type);
}
return stream_type_type;
}
static void gst_stream_info_class_init (GstStreamInfoClass * klass);
static void gst_stream_info_init (GstStreamInfo * stream_info);
static void gst_stream_info_dispose (GObject * object);
static void stream_info_change_state (GstElement * element,
gint old_state, gint new_state, gpointer data);
static void gst_stream_info_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * spec);
static void gst_stream_info_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * spec);
static GObjectClass *parent_class;
//static guint gst_stream_info_signals[LAST_SIGNAL] = { 0 };
GType
gst_stream_info_get_type (void)
{
static GType gst_stream_info_type = 0;
if (!gst_stream_info_type) {
static const GTypeInfo gst_stream_info_info = {
sizeof (GstStreamInfoClass),
NULL,
NULL,
(GClassInitFunc) gst_stream_info_class_init,
NULL,
NULL,
sizeof (GstStreamInfo),
0,
(GInstanceInitFunc) gst_stream_info_init,
NULL
};
gst_stream_info_type = g_type_register_static (G_TYPE_OBJECT,
"GstStreamInfo", &gst_stream_info_info, 0);
}
return gst_stream_info_type;
}
static void
gst_stream_info_class_init (GstStreamInfoClass * klass)
{
GObjectClass *gobject_klass;
gobject_klass = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
gobject_klass->set_property = gst_stream_info_set_property;
gobject_klass->get_property = gst_stream_info_get_property;
g_object_class_install_property (gobject_klass, ARG_PAD,
g_param_spec_object ("object", "object",
"Source Pad or object of the stream", GST_TYPE_OBJECT,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, ARG_TYPE,
g_param_spec_enum ("type", "Type", "Type of the stream",
GST_TYPE_STREAM_TYPE, GST_STREAM_TYPE_UNKNOWN,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, ARG_DECODER,
g_param_spec_string ("decoder", "Decoder",
"The decoder used to decode the stream", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, ARG_MUTE,
g_param_spec_boolean ("mute", "Mute", "Mute or unmute this stream", FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, ARG_CAPS,
g_param_spec_boxed ("caps", "Capabilities",
"Capabilities (or type) of this stream", GST_TYPE_CAPS,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, ARG_LANG_CODE,
g_param_spec_string ("language-code", "Language code",
"Language code for this stream, conforming to ISO-639-1", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, ARG_CODEC,
g_param_spec_string ("codec", "Codec", "Codec used to encode the stream",
NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
gst_stream_info_signals[SIGNAL_MUTED] =
g_signal_new ("muted", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstStreamInfoClass, muted), NULL, NULL,
gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_stream_info_dispose);
GST_DEBUG_CATEGORY_INIT (gst_streaminfo_debug, "streaminfo", 0,
"Playbin Stream Info");
}
static void
gst_stream_info_init (GstStreamInfo * stream_info)
{
stream_info->object = NULL;
stream_info->origin = NULL;
stream_info->type = GST_STREAM_TYPE_UNKNOWN;
stream_info->decoder = NULL;
stream_info->mute = FALSE;
stream_info->caps = NULL;
}
static gboolean
cb_probe (GstPad * pad, GstEvent * e, gpointer user_data)
{
GstStreamInfo *info = user_data;
if (GST_EVENT_TYPE (e) == GST_EVENT_TAG) {
gchar *codec, *lang;
GstTagList *list;
gst_event_parse_tag (e, &list);
if (info->type != GST_STREAM_TYPE_AUDIO &&
gst_tag_list_get_string (list, GST_TAG_VIDEO_CODEC, &codec)) {
g_free (info->codec);
info->codec = codec;
GST_LOG_OBJECT (pad, "codec = %s (video)", codec);
g_object_notify (G_OBJECT (info), "codec");
} else if (info->type != GST_STREAM_TYPE_VIDEO &&
gst_tag_list_get_string (list, GST_TAG_AUDIO_CODEC, &codec)) {
g_free (info->codec);
info->codec = codec;
GST_LOG_OBJECT (pad, "codec = %s (audio)", codec);
g_object_notify (G_OBJECT (info), "codec");
} else if (gst_tag_list_get_string (list, GST_TAG_CODEC, &codec)) {
g_free (info->codec);
info->codec = codec;
GST_LOG_OBJECT (pad, "codec = %s (generic)", codec);
g_object_notify (G_OBJECT (info), "codec");
}
if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) {
g_free (info->langcode);
info->langcode = lang;
GST_LOG_OBJECT (pad, "language-code = %s", lang);
g_object_notify (G_OBJECT (info), "language-code");
}
}
return TRUE;
}
GstStreamInfo *
gst_stream_info_new (GstObject * object,
GstStreamType type, const gchar * decoder, const GstCaps * caps)
{
GstStreamInfo *info;
info = g_object_new (GST_TYPE_STREAM_INFO, NULL);
gst_object_ref (object);
if (GST_IS_PAD (object)) {
gst_pad_add_event_probe (GST_PAD_CAST (object),
G_CALLBACK (cb_probe), info);
}
info->object = object;
info->type = type;
info->decoder = g_strdup (decoder);
info->origin = object;
if (caps) {
info->caps = gst_caps_copy (caps);
}
return info;
}
static void
gst_stream_info_dispose (GObject * object)
{
GstStreamInfo *stream_info;
stream_info = GST_STREAM_INFO (object);
if (stream_info->object) {
GstElement *parent;
parent = gst_pad_get_parent_element ((GstPad *)
GST_PAD_CAST (stream_info->object));
if (parent != NULL) {
g_signal_handlers_disconnect_by_func (parent,
(gpointer) stream_info_change_state, stream_info);
gst_object_unref (parent);
}
gst_object_unref (stream_info->object);
stream_info->object = NULL;
}
stream_info->origin = NULL;
stream_info->type = GST_STREAM_TYPE_UNKNOWN;
g_free (stream_info->decoder);
stream_info->decoder = NULL;
g_free (stream_info->langcode);
stream_info->langcode = NULL;
g_free (stream_info->codec);
stream_info->codec = NULL;
if (stream_info->caps) {
gst_caps_unref (stream_info->caps);
stream_info->caps = NULL;
}
if (G_OBJECT_CLASS (parent_class)->dispose) {
G_OBJECT_CLASS (parent_class)->dispose (object);
}
}
static void
stream_info_change_state (GstElement * element,
gint old_state, gint new_state, gpointer data)
{
GstStreamInfo *stream_info = data;
if (new_state == GST_STATE_PLAYING) {
/* state change will annoy us */
g_return_if_fail (stream_info->mute == TRUE);
GST_DEBUG_OBJECT (stream_info, "Re-muting pads after state-change");
//gst_pad_set_active_recursive (GST_PAD (stream_info->object), FALSE);
g_warning ("FIXME");
}
}
gboolean
gst_stream_info_set_mute (GstStreamInfo * stream_info, gboolean mute)
{
g_return_val_if_fail (GST_IS_STREAM_INFO (stream_info), FALSE);
if (stream_info->type == GST_STREAM_TYPE_ELEMENT) {
g_warning ("cannot mute element stream");
return FALSE;
}
if (mute != stream_info->mute) {
/* nothing really happens here. it looks like gstplaybasebin installs a
* buffer probe hat drops buffers when muting. but the this removes it self
* after first call.
*/
stream_info->mute = mute;
#if 0
gst_pad_set_active ((GstPad *) GST_PAD_CAST (stream_info->object), !mute);
#endif
#if 0
{
GstElement *element;
element = gst_pad_get_parent_element ((GstPad *)
GST_PAD_CAST (stream_info->object));
if (element) {
if (mute) {
g_signal_connect (element, "state-changed",
G_CALLBACK (stream_info_change_state), stream_info);
} else {
g_signal_handlers_disconnect_by_func (element,
G_CALLBACK (stream_info_change_state), stream_info);
}
gst_object_unref (element);
}
}
#endif
}
return TRUE;
}
gboolean
gst_stream_info_is_mute (GstStreamInfo * stream_info)
{
g_return_val_if_fail (GST_IS_STREAM_INFO (stream_info), TRUE);
return stream_info->mute;
}
static void
gst_stream_info_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstStreamInfo *stream_info;
g_return_if_fail (GST_IS_STREAM_INFO (object));
stream_info = GST_STREAM_INFO (object);
switch (prop_id) {
case ARG_MUTE:
gst_stream_info_set_mute (stream_info, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_stream_info_get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
GstStreamInfo *stream_info;
g_return_if_fail (GST_IS_STREAM_INFO (object));
stream_info = GST_STREAM_INFO (object);
switch (prop_id) {
case ARG_PAD:
g_value_set_object (value, stream_info->object);
break;
case ARG_TYPE:
g_value_set_enum (value, stream_info->type);
break;
case ARG_DECODER:
g_value_set_string (value, stream_info->decoder);
break;
case ARG_MUTE:
g_value_set_boolean (value, stream_info->mute);
break;
case ARG_CAPS:
g_value_set_boxed (value, stream_info->caps);
break;
case ARG_LANG_CODE:
g_value_set_string (value, stream_info->langcode);
break;
case ARG_CODEC:
g_value_set_string (value, stream_info->codec);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}