mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +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_sources = gstplay-marshal.c
|
||||||
built_headers = gstplay-marshal.h
|
built_headers = gstplay-marshal.h
|
||||||
|
|
||||||
plugin_LTLIBRARIES = libgstplaybin.la libgstdecodebin.la libgstdecodebin2.la
|
plugin_LTLIBRARIES = libgstplaybin.la libgstdecodebin2.la
|
||||||
|
|
||||||
libgstplaybin_la_SOURCES = \
|
libgstplaybin_la_SOURCES = \
|
||||||
gstplayback.c \
|
gstplayback.c \
|
||||||
gstplaybin.c \
|
|
||||||
gstplaybin2.c \
|
gstplaybin2.c \
|
||||||
gstplaysink.c \
|
gstplaysink.c \
|
||||||
gstplaybasebin.c \
|
|
||||||
gstplay-enum.c \
|
gstplay-enum.c \
|
||||||
gststreaminfo.c \
|
|
||||||
gststreamselector.c \
|
gststreamselector.c \
|
||||||
gstsubtitleoverlay.c \
|
gstsubtitleoverlay.c \
|
||||||
gstplaysinkvideoconvert.c \
|
gstplaysinkvideoconvert.c \
|
||||||
|
@ -32,15 +29,6 @@ libgstplaybin_la_LIBADD = \
|
||||||
$(GST_LIBS)
|
$(GST_LIBS)
|
||||||
libgstplaybin_la_LIBTOOLFLAGS = --tag=disable-static
|
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
|
libgstdecodebin2_la_SOURCES = gstdecodebin2.c gsturidecodebin.c gstplay-enum.c
|
||||||
nodist_libgstdecodebin2_la_SOURCES = $(built_sources)
|
nodist_libgstdecodebin2_la_SOURCES = $(built_sources)
|
||||||
libgstdecodebin2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
libgstdecodebin2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||||
|
@ -52,9 +40,7 @@ libgstdecodebin2_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
gstplayback.h \
|
gstplayback.h \
|
||||||
gstplaybasebin.h \
|
|
||||||
gstplaysink.h \
|
gstplaysink.h \
|
||||||
gststreaminfo.h \
|
|
||||||
gstplay-enum.h \
|
gstplay-enum.h \
|
||||||
gststreamselector.h \
|
gststreamselector.h \
|
||||||
gstrawcaps.h \
|
gstrawcaps.h \
|
||||||
|
@ -73,18 +59,6 @@ include $(top_srcdir)/common/gst-glib-gen.mak
|
||||||
|
|
||||||
Android.mk: Makefile.am $(BUILT_SOURCES)
|
Android.mk: Makefile.am $(BUILT_SOURCES)
|
||||||
androgenizer \
|
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 \
|
-:PROJECT libgstdecodebin2 -:SHARED libgstdecodebin2 \
|
||||||
-:TAGS eng debug \
|
-:TAGS eng debug \
|
||||||
-:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
|
-: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 "gstplayback.h"
|
||||||
#include "gstplaysink.h"
|
#include "gstplaysink.h"
|
||||||
#include "gststreamselector.h"
|
#include "gststreamselector.h"
|
||||||
#include "gststreaminfo.h"
|
|
||||||
#include "gstsubtitleoverlay.h"
|
#include "gstsubtitleoverlay.h"
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -49,11 +48,9 @@ plugin_init (GstPlugin * plugin)
|
||||||
|
|
||||||
/* ref class from a thread-safe context to work around missing bit of
|
/* ref class from a thread-safe context to work around missing bit of
|
||||||
* thread-safety in GObject */
|
* thread-safety in GObject */
|
||||||
g_type_class_ref (GST_TYPE_STREAM_INFO);
|
|
||||||
g_type_class_ref (GST_TYPE_STREAM_SELECTOR);
|
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_play_sink_plugin_init (plugin);
|
||||||
res &= gst_subtitle_overlay_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