From 67dac71e6ce2d33f8207784c76460d3607947de7 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 7 Apr 2006 09:51:35 +0000 Subject: [PATCH] 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. --- ChangeLog | 14 +++++ common | 2 +- gst/playback/gstplaybasebin.c | 17 ++++-- gst/playback/gstplaybin.c | 15 ++++- gst/typefind/gsttypefindfunctions.c | 87 +++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb7a19ee64..28546b9b8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-04-07 Jan Schmidt + + * 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 * gst/videorate/gstvideorate.c (gst_video_rate_reset) diff --git a/common b/common index 623fe1c2cc..1783855e98 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 623fe1c2cce45bc30d5823c05716349874ae994e +Subproject commit 1783855e983a5294434673694e8a57e44980b6f1 diff --git a/gst/playback/gstplaybasebin.c b/gst/playback/gstplaybasebin.c index 9f9c81f3a7..c69a3a4721 100644 --- a/gst/playback/gstplaybasebin.c +++ b/gst/playback/gstplaybasebin.c @@ -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)); + } } } diff --git a/gst/playback/gstplaybin.c b/gst/playback/gstplaybin.c index b6eb48f15d..f28379e14f 100644 --- a/gst/playback/gstplaybin.c +++ b/gst/playback/gstplaybin.c @@ -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); diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 5ab91cb251..eec4c49958 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -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,