gst/playback/gstplaybasebin.c: Don't remove our mute-probe if someone else already did so.

Original commit message from CVS:
* gst/playback/gstplaybasebin.c: (mute_stream), (setup_substreams):
Don't remove our mute-probe if someone else already did so.
Don't set a 2nd one if there is already one pending on the pad.
* gst/playback/gstplaybin.c: (gst_play_bin_send_event_to_sink),
(do_playbin_seek):
When a seek fails, ensure that playbin is still set back to playing.
* gst/typefind/gsttypefindfunctions.c: (mpeg_ts_probe_headers),
(mpeg_ts_type_find), (plugin_init):
Add a typefind function for mpeg-ts streams.
This commit is contained in:
Jan Schmidt 2006-04-07 09:51:35 +00:00
parent a8e9a6d7a1
commit 67dac71e6c
5 changed files with 127 additions and 8 deletions

View file

@ -1,3 +1,17 @@
2006-04-07 Jan Schmidt <thaytan@mad.scientist.com>
* gst/playback/gstplaybasebin.c: (mute_stream), (setup_substreams):
Don't remove our mute-probe if someone else already did so.
Don't set a 2nd one if there is already one pending on the pad.
* gst/playback/gstplaybin.c: (gst_play_bin_send_event_to_sink),
(do_playbin_seek):
When a seek fails, ensure that playbin is still set back to playing.
* gst/typefind/gsttypefindfunctions.c: (mpeg_ts_probe_headers),
(mpeg_ts_type_find), (plugin_init):
Add a typefind function for mpeg-ts streams.
2006-04-06 Andy Wingo <wingo@pobox.com>
* gst/videorate/gstvideorate.c (gst_video_rate_reset)

2
common

@ -1 +1 @@
Subproject commit 623fe1c2cce45bc30d5823c05716349874ae994e
Subproject commit 1783855e983a5294434673694e8a57e44980b6f1

View file

@ -30,8 +30,13 @@
GST_DEBUG_CATEGORY_STATIC (gst_play_base_bin_debug);
#define GST_CAT_DEFAULT gst_play_base_bin_debug
#if 0
#define DEFAULT_QUEUE_THRESHOLD ((2 * GST_SECOND) / 3)
#define DEFAULT_QUEUE_SIZE (GST_SECOND / 2)
#else
#define DEFAULT_QUEUE_THRESHOLD (2 * GST_SECOND)
#define DEFAULT_QUEUE_SIZE (3 * GST_SECOND)
#endif
#define GROUP_LOCK(pbb) g_mutex_lock (pbb->group_lock)
#define GROUP_UNLOCK(pbb) g_mutex_unlock (pbb->group_lock)
@ -928,7 +933,8 @@ mute_stream (GstPad * pad, GstBuffer * buf, gpointer data)
g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe"));
g_object_set_data (G_OBJECT (info), "mute_probe", NULL);
gst_pad_remove_buffer_probe (GST_PAD_CAST (info->object), id);
if (id > 0)
gst_pad_remove_buffer_probe (GST_PAD_CAST (info->object), id);
/* no data */
return FALSE;
@ -1137,9 +1143,12 @@ setup_substreams (GstPlayBaseBin * play_base_bin)
if (info->type == GST_STREAM_TYPE_UNKNOWN) {
guint id;
id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
G_CALLBACK (mute_stream), info);
g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id));
id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe"));
if (id == 0) {
id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
G_CALLBACK (mute_stream), info);
g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id));
}
}
}

View file

@ -1286,8 +1286,13 @@ gst_play_bin_send_event_to_sink (GstPlayBin * play_bin, GstEvent * event)
GstElement *sink = GST_ELEMENT_CAST (sinks->data);
gst_event_ref (event);
if ((res = gst_element_send_event (sink, event)))
if ((res = gst_element_send_event (sink, event))) {
GST_DEBUG_OBJECT (play_bin,
"Sent event succesfully to sink %" GST_PTR_FORMAT, sink);
break;
}
GST_DEBUG_OBJECT (play_bin,
"Event failed when sent to sink %" GST_PTR_FORMAT, sink);
sinks = g_list_next (sinks);
}
@ -1320,14 +1325,18 @@ do_playbin_seek (GstElement * element, GstEvent * event)
if (was_playing) {
gst_element_set_state (element, GST_STATE_PAUSED);
gst_element_get_state (element, NULL, NULL, 50 * GST_MSECOND);
}
}
GST_DEBUG_OBJECT (element, "Sending seek event to a sink");
res = gst_play_bin_send_event_to_sink (GST_PLAY_BIN (element), event);
if (flush && res) {
if (flush) {
/* need to reset the stream time to 0 after a flushing seek */
gst_pipeline_set_new_stream_time (GST_PIPELINE (element), 0);
if (res)
gst_pipeline_set_new_stream_time (GST_PIPELINE (element), 0);
if (was_playing)
/* and continue playing */
gst_element_set_state (element, GST_STATE_PLAYING);

View file

@ -1073,6 +1073,90 @@ mpeg1_sys_type_find (GstTypeFind * tf, gpointer unused)
}
}
/** video/mpegts Transport Stream **/
static GstStaticCaps mpegts_caps = GST_STATIC_CAPS ("video/mpegts, "
"systemstream = (boolean) true, packetsize = (int) [ 188, 208 ]");
#define MPEGTS_CAPS gst_static_caps_get(&mpegts_caps)
#define GST_MPEGTS_TYPEFIND_TRY_HEADERS 4
#define GST_MPEGTS_MAX_PACKET_SIZE 204
#define GST_MPEGTS_TYPEFIND_MAX_SYNC (10 * GST_MPEGTS_MAX_PACKET_SIZE)
#define GST_MPEGTS_TYPEFIND_SYNC_SIZE \
(GST_MPEGTS_TYPEFIND_TRY_HEADERS * GST_MPEGTS_MAX_PACKET_SIZE)
#define MPEGTS_HDR_SIZE 4
#define IS_MPEGTS_HEADER(data) (((data)[0] == 0x47) && \
(((data)[1] & 0x80) == 0x00) && \
(((data)[3] & 0x10) == 0x10))
/* Helper function to search ahead at intervals of packet_size for mpegts
* headers */
gint
mpeg_ts_probe_headers (GstTypeFind * tf, guint64 offset, gint packet_size)
{
/* We always enter this function having found at least one header already */
gint found = 1;
guint8 *data = NULL;
while (found < GST_MPEGTS_TYPEFIND_TRY_HEADERS) {
offset += packet_size;
data = gst_type_find_peek (tf, offset, MPEGTS_HDR_SIZE);
if (data == NULL || !IS_MPEGTS_HEADER (data))
return found;
found++;
}
return found;
}
/* Try and detect at least 4 packets in at most 10 packets worth of
* data. Need to try several possible packet sizes */
static void
mpeg_ts_type_find (GstTypeFind * tf, gpointer unused)
{
/* TS packet sizes to test: normal, DVHS packet size and
* FEC with 16 or 20 byte codes packet size. */
const gint pack_sizes[] = { 188, 192, 204, 208 };
const gint n_pack_sizes = sizeof (pack_sizes) / sizeof (gint);
guint8 *data = NULL;
guint size = 0;
guint64 skipped = 0;
while (skipped < GST_MPEGTS_TYPEFIND_MAX_SYNC) {
if (size < MPEGTS_HDR_SIZE) {
data = gst_type_find_peek (tf, skipped, GST_MPEGTS_TYPEFIND_SYNC_SIZE);
if (!data)
break;
size = GST_MPEGTS_TYPEFIND_SYNC_SIZE;
}
/* Have at least MPEGTS_HDR_SIZE bytes at this point */
if (IS_MPEGTS_HEADER (data)) {
gint p;
for (p = 0; p < n_pack_sizes; p++) {
/* Probe ahead at size pack_sizes[p] */
if (mpeg_ts_probe_headers (tf, skipped, pack_sizes[p]) >=
GST_MPEGTS_TYPEFIND_TRY_HEADERS) {
GstCaps *caps = gst_caps_copy (MPEGTS_CAPS);
gst_structure_set (gst_caps_get_structure (caps, 0), "packetsize",
G_TYPE_INT, pack_sizes[p], NULL);
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 1, caps);
gst_caps_unref (caps);
return;
}
}
}
data++;
skipped++;
size--;
}
}
/*** video/mpeg MPEG-4 elementary video stream ***/
static GstStaticCaps mpeg4_video_caps = GST_STATIC_CAPS ("video/mpeg, "
@ -2195,6 +2279,7 @@ plugin_init (GstPlugin * plugin)
static gchar *musepack_exts[] = { "mpc", NULL };
static gchar *mpeg_sys_exts[] = { "mpe", "mpeg", "mpg", NULL };
static gchar *mpeg_video_exts[] = { "mpv", "mpeg", "mpg", NULL };
static gchar *mpeg_ts_exts[] = { "ts", NULL };
static gchar *ogg_exts[] = { "anx", "ogg", "ogm", NULL };
static gchar *qt_exts[] = { "mov", NULL };
static gchar *rm_exts[] = { "ra", "ram", "rm", "rmvb", NULL };
@ -2290,6 +2375,8 @@ plugin_init (GstPlugin * plugin)
mpeg1_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL, NULL);
TYPE_FIND_REGISTER (plugin, "video/mpeg2", GST_RANK_SECONDARY,
mpeg2_sys_type_find, mpeg_sys_exts, MPEG_SYS_CAPS, NULL, NULL);
TYPE_FIND_REGISTER (plugin, "video/mpegts", GST_RANK_PRIMARY,
mpeg_ts_type_find, mpeg_ts_exts, MPEGTS_CAPS, NULL, NULL);
TYPE_FIND_REGISTER (plugin, "application/ogg", GST_RANK_PRIMARY,
ogganx_type_find, ogg_exts, OGGANX_CAPS, NULL, NULL);
TYPE_FIND_REGISTER (plugin, "video/mpeg", GST_RANK_SECONDARY,