mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
playback: remove old playbin and decodebin elements
This commit is contained in:
parent
2c6dbae423
commit
24f28cfdb0
9 changed files with 2 additions and 7624 deletions
|
@ -6,16 +6,13 @@ glib_gen_basename = gstplay
|
|||
built_sources = gstplay-marshal.c
|
||||
built_headers = gstplay-marshal.h
|
||||
|
||||
plugin_LTLIBRARIES = libgstplaybin.la libgstdecodebin.la libgstdecodebin2.la
|
||||
plugin_LTLIBRARIES = libgstplaybin.la libgstdecodebin2.la
|
||||
|
||||
libgstplaybin_la_SOURCES = \
|
||||
gstplayback.c \
|
||||
gstplaybin.c \
|
||||
gstplaybin2.c \
|
||||
gstplaysink.c \
|
||||
gstplaybasebin.c \
|
||||
gstplay-enum.c \
|
||||
gststreaminfo.c \
|
||||
gststreamselector.c \
|
||||
gstsubtitleoverlay.c \
|
||||
gstplaysinkvideoconvert.c \
|
||||
|
@ -32,15 +29,6 @@ libgstplaybin_la_LIBADD = \
|
|||
$(GST_LIBS)
|
||||
libgstplaybin_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
libgstdecodebin_la_SOURCES = gstdecodebin.c
|
||||
nodist_libgstdecodebin_la_SOURCES = $(built_sources)
|
||||
libgstdecodebin_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
libgstdecodebin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
libgstdecodebin_la_LIBADD = \
|
||||
$(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \
|
||||
$(GST_LIBS)
|
||||
libgstdecodebin_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
libgstdecodebin2_la_SOURCES = gstdecodebin2.c gsturidecodebin.c gstplay-enum.c
|
||||
nodist_libgstdecodebin2_la_SOURCES = $(built_sources)
|
||||
libgstdecodebin2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
|
@ -52,9 +40,7 @@ libgstdecodebin2_la_LIBTOOLFLAGS = --tag=disable-static
|
|||
|
||||
noinst_HEADERS = \
|
||||
gstplayback.h \
|
||||
gstplaybasebin.h \
|
||||
gstplaysink.h \
|
||||
gststreaminfo.h \
|
||||
gstplay-enum.h \
|
||||
gststreamselector.h \
|
||||
gstrawcaps.h \
|
||||
|
@ -73,18 +59,6 @@ include $(top_srcdir)/common/gst-glib-gen.mak
|
|||
|
||||
Android.mk: Makefile.am $(BUILT_SOURCES)
|
||||
androgenizer \
|
||||
-:PROJECT libgstdecodebin -:SHARED libgstdecodebin \
|
||||
-:TAGS eng debug \
|
||||
-:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
|
||||
-:SOURCES $(libgstdecodebin_la_SOURCES) \
|
||||
$(nodist_libgstdecodebin_la_SOURCES) \
|
||||
-:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdecodebin_la_CFLAGS) \
|
||||
-:LDFLAGS $(libgstdecodebin_la_LDFLAGS) \
|
||||
$(libgstdecodebin_la_LIBADD) \
|
||||
-ldl \
|
||||
-:PASSTHROUGH LOCAL_ARM_MODE:=arm \
|
||||
LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
|
||||
\
|
||||
-:PROJECT libgstdecodebin2 -:SHARED libgstdecodebin2 \
|
||||
-:TAGS eng debug \
|
||||
-:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
decodebin:
|
||||
|
||||
A bin with a sinkpad that decodes the data into raw formats. It works by sending
|
||||
the input data through a typefind element and then recursively autoplugs elements
|
||||
from the registry until a raw format is obtained. It will then create a new ghostpad
|
||||
on itself to signal the app of the new pad.
|
||||
|
||||
Decodebin will also remove pads when they are removed from the stream.
|
||||
|
||||
TODO
|
||||
- reuse of decoderbin, cleanup in READY state
|
||||
- threading after demuxing?
|
||||
- new_media events should be handled.
|
||||
- caching of elements.
|
||||
- abstract more elements, pads (typefind, ...);
|
||||
|
||||
The autoplugging happens as follows:
|
||||
|
||||
1) typefind is added internally to the bin.
|
||||
2) the have_type signal is connected to typefind.
|
||||
3) in the have_type callback the close_pad_link function is called
|
||||
4) close_pad_link checks the type on the pad, if it is raw, a ghostpad
|
||||
is created and autoplugging for that pad stops.
|
||||
5) if the type of the pad is not raw, a list of possible elements that
|
||||
can connect to this type is generated in find_compatibles.
|
||||
6) try_to_link_1 with the element list is called. The function will loop
|
||||
over the element list and will try to connect one of the elements to
|
||||
the pad. If the link works, a call is made to close_link.
|
||||
7) close_link loops over all the source pads of the element and
|
||||
recursively calls 4) for any ALWAYS pad. For elements with
|
||||
a SOMETIMES pad, a structure is set up and is passed to the callback
|
||||
of the new_pad signal.
|
||||
8) in the new_pad callback, 4) is called to try to autoplug the
|
||||
new pad.
|
||||
|
||||
|
||||
playbasebin:
|
||||
|
||||
A bin with an uri property. It will find the right source element from the registry
|
||||
and connect a decoderbin to it. When going to the PAUSED state, it will iterate the
|
||||
decoderbin and listen for new pad signals from it. It will connect a queue to each
|
||||
new pad and will iterate the decoderbin until one of the queues is filled. It is
|
||||
assumed that by that time all the streams will be found so that when leaving the
|
||||
PAUSED state, one can query the number of streams in the media file with the given
|
||||
uri.
|
||||
|
||||
Playbasebin internally groups related streams together in a GstPlayBaseGroup. This
|
||||
is particulary important for chained oggs. Initially, a new group is created in
|
||||
the 'building' state. All new streams will be added to the building group until
|
||||
no-more-pads is signaled or one of the preroll queues overflows. When this happens,
|
||||
the group is commited to a list of groups ready for playback. PlaybaseBin will then
|
||||
attach a padprobe to each stream to figure out when it finished. It will remove
|
||||
the current group and install the next playable group, then.
|
||||
|
||||
Before going to the PLAYING state, it is possible to connect a custom element to
|
||||
each of the streams. To do that, you have to add the element to the bin and then
|
||||
connect the pad(s) from the stream(s). You do not have to add the elements in
|
||||
a thread, the bin will take care of then when it's needed. You are allowed to use
|
||||
threads inside the elements, of course.
|
||||
The bin tries to be smart and doesn't add a queue when there is only one possible
|
||||
stream.
|
||||
|
||||
|
||||
TODO
|
||||
- reuse, cleanup in ready state
|
||||
- when the first pad is closed, it's possible that another dynamic element is
|
||||
added somewhere so that we need a queue for the first pad as well.
|
||||
|
||||
|
||||
playbin:
|
||||
|
||||
Extends playbasebin, sets up default audiosink and videosink for first audio/video
|
||||
stream detected. implements seeking and querying on the configured sinks.
|
||||
|
||||
It also waits for new notifications from playbasebin about any new groups that are
|
||||
becomming active. It then disconnects the sinks and reconnects them to the new
|
||||
pads in the group.
|
||||
|
||||
TODO
|
||||
- reuse, refcounting, cleanup in READY state
|
||||
- be smarter about replugging the sinks instead of removing them and readding them.
|
||||
- Do not crap out when the audio device is in use.
|
||||
|
||||
|
||||
general
|
||||
|
||||
TODO
|
||||
- playlist support. maybe use a playlist bin that streams the contents of the
|
||||
playlist on a pad, interleaved with new_media events. Also add a tuner
|
||||
interface while we're at it.
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -30,7 +30,6 @@
|
|||
#include "gstplayback.h"
|
||||
#include "gstplaysink.h"
|
||||
#include "gststreamselector.h"
|
||||
#include "gststreaminfo.h"
|
||||
#include "gstsubtitleoverlay.h"
|
||||
|
||||
static gboolean
|
||||
|
@ -49,11 +48,9 @@ plugin_init (GstPlugin * plugin)
|
|||
|
||||
/* ref class from a thread-safe context to work around missing bit of
|
||||
* thread-safety in GObject */
|
||||
g_type_class_ref (GST_TYPE_STREAM_INFO);
|
||||
g_type_class_ref (GST_TYPE_STREAM_SELECTOR);
|
||||
|
||||
res = gst_play_bin_plugin_init (plugin);
|
||||
res &= gst_play_bin2_plugin_init (plugin);
|
||||
res = gst_play_bin2_plugin_init (plugin);
|
||||
res &= gst_play_sink_plugin_init (plugin);
|
||||
res &= gst_subtitle_overlay_plugin_init (plugin);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,126 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_PLAYBASEBIN_H__
|
||||
#define __GST_PLAYBASEBIN_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "gststreaminfo.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_PLAY_BASE_BIN (gst_play_base_bin_get_type())
|
||||
#define GST_PLAY_BASE_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAY_BASE_BIN,GstPlayBaseBin))
|
||||
#define GST_PLAY_BASE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLAY_BASE_BIN,GstPlayBaseBinClass))
|
||||
#define GST_IS_PLAY_BASE_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAY_BASE_BIN))
|
||||
#define GST_IS_PLAY_BASE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAY_BASE_BIN))
|
||||
#define GST_PLAY_BASE_BIN_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLAY_BASE_BIN, \
|
||||
GstPlayBaseBinClass))
|
||||
|
||||
typedef struct _GstPlayBaseBin GstPlayBaseBin;
|
||||
typedef struct _GstPlayBaseBinClass GstPlayBaseBinClass;
|
||||
|
||||
/* a GstPlayBaseGroup is a group of pads and streaminfo that together
|
||||
* make up a playable stream. A new group is created from the current
|
||||
* set of pads that are alive when the preroll elements are filled or
|
||||
* when the no-more-pads signal is fired.
|
||||
*
|
||||
* We have to queue the groups as they can be created while the preroll
|
||||
* queues are still playing the old group. We monitor the EOS signals
|
||||
* on the preroll queues and when all the streams in the current group
|
||||
* have EOSed, we switch to the next queued group.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GstPlayBaseBin *bin; /* ref to the owner */
|
||||
|
||||
gint nstreams;
|
||||
GList *streaminfo;
|
||||
GValueArray *streaminfo_value_array;
|
||||
|
||||
/* contained decoded elementary streams */
|
||||
struct {
|
||||
gint npads;
|
||||
GstBin *bin;
|
||||
GstElement *preroll;
|
||||
GstElement *selector;
|
||||
gboolean done;
|
||||
#define NUM_TYPES 4
|
||||
} type[NUM_TYPES]; /* AUDIO, VIDEO, TEXT, SUBPIC */
|
||||
} GstPlayBaseGroup;
|
||||
|
||||
struct _GstPlayBaseBin {
|
||||
GstPipeline pipeline;
|
||||
|
||||
/* properties */
|
||||
guint64 queue_size;
|
||||
guint64 queue_threshold;
|
||||
guint64 queue_min_threshold;
|
||||
/* connection speed in bits/sec (0 = unknown) */
|
||||
guint connection_speed;
|
||||
|
||||
|
||||
/* currently loaded media */
|
||||
gint current[NUM_TYPES];
|
||||
gchar *uri, *suburi;
|
||||
gboolean is_stream;
|
||||
GstElement *source;
|
||||
GSList *decoders;
|
||||
GstElement *subtitle; /* additional filesrc ! subparse bin */
|
||||
gboolean subtitle_done;
|
||||
gboolean need_rebuild;
|
||||
gboolean raw_decoding_mode; /* Use smaller queues when source outputs raw data */
|
||||
|
||||
GSList *subtitle_elements; /* subtitle elements that have 'subtitle-encoding' property */
|
||||
gchar *subencoding; /* encoding to propagate to the above subtitle elements */
|
||||
GMutex *sub_lock; /* protecting subtitle_elements and subencoding members */
|
||||
|
||||
/* group management - using own lock */
|
||||
GMutex *group_lock; /* lock and mutex to signal availability of new group */
|
||||
GCond *group_cond;
|
||||
GstPlayBaseGroup *building_group; /* the group that we are constructing */
|
||||
GList *queued_groups; /* the constructed groups, head is the active one */
|
||||
|
||||
/* for dynamic sources */
|
||||
guint src_np_sig_id; /* new-pad signal id */
|
||||
guint src_nmp_sig_id; /* no-more-pads signal id */
|
||||
gint pending;
|
||||
};
|
||||
|
||||
struct _GstPlayBaseBinClass {
|
||||
GstPipelineClass parent_class;
|
||||
|
||||
/* virtual fuctions */
|
||||
gboolean (*setup_output_pads) (GstPlayBaseBin *play_base_bin,
|
||||
GstPlayBaseGroup *group);
|
||||
|
||||
void (*set_subtitles_visible) (GstPlayBaseBin *play_base_bin,
|
||||
gboolean visible);
|
||||
void (*set_audio_mute) (GstPlayBaseBin *play_base_bin,
|
||||
gboolean mute);
|
||||
};
|
||||
|
||||
GType gst_play_base_bin_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_PLAYBASEBIN_H__ */
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,404 +0,0 @@
|
|||
/* 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_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 GstProbeReturn
|
||||
cb_probe (GstPad * pad, GstProbeType type, gpointer type_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstEvent *e = type_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_probe (GST_PAD_CAST (object), GST_PROBE_TYPE_EVENT,
|
||||
cb_probe, info, NULL);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* <2007> Wim Taymans <wim.taymans@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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_STREAMINFO_H__
|
||||
#define __GST_STREAMINFO_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_STREAM_INFO (gst_stream_info_get_type())
|
||||
#define GST_STREAM_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_STREAM_INFO,GstStreamInfo))
|
||||
#define GST_STREAM_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_STREAM_INFO,GstStreamInfoClass))
|
||||
#define GST_IS_STREAM_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_STREAM_INFO))
|
||||
#define GST_IS_STREAM_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_STREAM_INFO))
|
||||
|
||||
typedef struct _GstStreamInfo GstStreamInfo;
|
||||
typedef struct _GstStreamInfoClass GstStreamInfoClass;
|
||||
|
||||
typedef enum {
|
||||
GST_STREAM_TYPE_UNKNOWN = 0,
|
||||
GST_STREAM_TYPE_AUDIO = 1, /* an audio stream */
|
||||
GST_STREAM_TYPE_VIDEO = 2, /* a video stream */
|
||||
GST_STREAM_TYPE_TEXT = 3, /* a subtitle/text stream */
|
||||
GST_STREAM_TYPE_SUBPICTURE = 4, /* a subtitle in picture-form */
|
||||
GST_STREAM_TYPE_ELEMENT = 5 /* stream handled by an element */
|
||||
} GstStreamType;
|
||||
|
||||
struct _GstStreamInfo {
|
||||
GObject parent;
|
||||
|
||||
GstObject *object; /* pad/element providing/handling this stream */
|
||||
GstStreamType type; /* the type of the provided stream */
|
||||
gchar *decoder; /* string describing the decoder */
|
||||
gboolean mute; /* is the stream muted or not */
|
||||
GstObject *origin; /* the real object providing this stream, this can
|
||||
be different from the object as the object can be
|
||||
a queue pad, inserted for preroll. */
|
||||
GstCaps *caps; /* the caps of the stream */
|
||||
|
||||
/* this is tream information cached here because the streaminfo may be
|
||||
* created before the app can know about it. */
|
||||
gchar *langcode,
|
||||
*codec;
|
||||
};
|
||||
|
||||
struct _GstStreamInfoClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*muted) (GstStreamInfo *info, gboolean mute);
|
||||
};
|
||||
|
||||
GType gst_stream_info_get_type (void);
|
||||
|
||||
GstStreamInfo* gst_stream_info_new (GstObject *object,
|
||||
GstStreamType type,
|
||||
const gchar *decoder,
|
||||
const GstCaps *caps);
|
||||
|
||||
gboolean gst_stream_info_set_mute (GstStreamInfo *stream_info,
|
||||
gboolean mute);
|
||||
gboolean gst_stream_info_is_mute (GstStreamInfo *stream_info);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_STREAMINFO_H__ */
|
Loading…
Reference in a new issue