diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/resindvd/gstmpegdemux.c | 89 | ||||
-rw-r--r-- | ext/resindvd/gstmpegdemux.h | 3 | ||||
-rw-r--r-- | ext/resindvd/resindvdsrc.c | 176 | ||||
-rw-r--r-- | ext/resindvd/rsnstreamselector.c | 67 |
4 files changed, 281 insertions, 54 deletions
diff --git a/ext/resindvd/gstmpegdemux.c b/ext/resindvd/gstmpegdemux.c index 4e2cc291..99049cea 100644 --- a/ext/resindvd/gstmpegdemux.c +++ b/ext/resindvd/gstmpegdemux.c @@ -28,9 +28,6 @@ #include "gstmpegdefs.h" #include "gstmpegdemux.h" -#define MAX_DVD_AUDIO_STREAMS 8 -#define MAX_DVD_SUBPICTURE_STREAMS 32 - #define SEGMENT_THRESHOLD (GST_SECOND/2) /* The SCR_MUNGE value is used to offset the scr_adjust value, to avoid @@ -581,6 +578,7 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) gint i; gchar cur_stream_name[32]; GstFluPSStream *temp; + gboolean ret = TRUE; if (strcmp (type, "dvd-lang-codes") == 0) { GstEvent **p_ev; @@ -624,6 +622,8 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) if (!gst_structure_get_int (structure, cur_stream_name, &stream_format)) continue; + demux->audio_stream_types[i] = stream_format; + switch (stream_format) { case 0x0: /* AC3 */ @@ -678,10 +678,89 @@ gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event) gst_element_no_more_pads (GST_ELEMENT (demux)); demux->need_no_more_pads = FALSE; gst_event_unref (event); + } else if (strcmp (type, "dvd-set-subpicture-track") == 0) { + gint stream_id; + gboolean forced_only; + + gst_structure_get_boolean (structure, "forced-only", &forced_only); + + if (gst_structure_get_int (structure, "physical-id", &stream_id)) { + temp = demux->streams[0x20 + stream_id]; + if (temp != NULL && temp->pad != NULL) { + /* Send event to the selector to activate the desired pad */ + GstStructure *s = gst_structure_new ("application/x-gst-dvd", + "event", G_TYPE_STRING, "select-pad", NULL); + GstEvent *sel_event = + gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s); + gst_pad_push_event (temp->pad, sel_event); + + gst_event_ref (event); + ret = gst_pad_push_event (temp->pad, event); + g_print ("Subpicture physical ID change to %d, forced %d\n", stream_id, + forced_only); + } + } + gst_event_unref (event); + } else if (strcmp (type, "dvd-set-audio-track") == 0) { + gint stream_id; + + if (gst_structure_get_int (structure, "physical-id", &stream_id)) { + gint aud_type; + + stream_id %= MAX_DVD_AUDIO_STREAMS; + + aud_type = demux->audio_stream_types[stream_id % MAX_DVD_AUDIO_STREAMS]; + + switch (aud_type) { + case 0x0: + /* AC3 */ + stream_id += 0x80; + temp = demux->streams[stream_id]; + break; +#if 0 /* FIXME: Ignore non AC-3 requests until the decoder bin can handle them */ + case 0x2: + case 0x3: + /* MPEG audio without and with extension stream are + * treated the same */ + stream_id = 0xC0 + i; + temp = demux->streams[stream_id]; + break; + case 0x4: + /* LPCM */ + stream_id = 0xA0 + i; + temp = demux->streams[stream_id]; + break; + case 0x6: + /* DTS */ + stream_id = 0x88 + i; + temp = demux->streams[stream_id]; + break; + case 0x7: + /* FIXME: What range is SDDS? */ + break; +#endif + default: + temp = NULL; + break; + } + if (temp != NULL && temp->pad != NULL) { + /* Send event to the selector to activate the desired pad */ + GstStructure *s = gst_structure_new ("application/x-gst-dvd", + "event", G_TYPE_STRING, "select-pad", NULL); + GstEvent *sel_event = + gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s); + gst_pad_push_event (temp->pad, sel_event); + g_print ("Audio physical ID change to %d\n", stream_id); + + gst_event_ref (event); + ret = gst_pad_push_event (temp->pad, event); + } + } + ret = gst_flups_demux_send_event (demux, event); } else { - gst_flups_demux_send_event (demux, event); + ret = gst_flups_demux_send_event (demux, event); } - return TRUE; + return ret; } static gboolean diff --git a/ext/resindvd/gstmpegdemux.h b/ext/resindvd/gstmpegdemux.h index fd566afa..3f38b088 100644 --- a/ext/resindvd/gstmpegdemux.h +++ b/ext/resindvd/gstmpegdemux.h @@ -42,6 +42,8 @@ typedef struct _GstFluPSDemuxClass GstFluPSDemuxClass; #define GST_FLUPS_DEMUX_MAX_STREAMS 256 #define GST_FLUPS_DEMUX_MAX_PSM 256 +#define MAX_DVD_AUDIO_STREAMS 8 +#define MAX_DVD_SUBPICTURE_STREAMS 32 typedef enum { STATE_FLUPS_DEMUX_NEED_SYNC, @@ -106,6 +108,7 @@ struct _GstFluPSDemux { /* Language codes event is stored when a dvd-lang-codes * custom event arrives from upstream */ GstEvent * lang_codes; + gint audio_stream_types[MAX_DVD_AUDIO_STREAMS]; }; struct _GstFluPSDemuxClass { diff --git a/ext/resindvd/resindvdsrc.c b/ext/resindvd/resindvdsrc.c index bf4d033d..371624e9 100644 --- a/ext/resindvd/resindvdsrc.c +++ b/ext/resindvd/resindvdsrc.c @@ -84,6 +84,9 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", /* Private seek format for private flushing */ static GstFormat rsndvd_format; +/* Title/chapter formats */ +static GstFormat title_format; +static GstFormat chapter_format; static void rsn_dvdsrc_register_extra (GType rsn_dvdsrc_type); @@ -104,6 +107,7 @@ static gboolean rsn_dvdsrc_stop (RsnBaseSrc * bsrc); static gboolean rsn_dvdsrc_unlock (RsnBaseSrc * bsrc); static gboolean rsn_dvdsrc_unlock_stop (RsnBaseSrc * bsrc); +static gboolean rsn_dvdsrc_is_seekable (RsnBaseSrc * bsrc); static gboolean rsn_dvdsrc_prepare_seek (RsnBaseSrc * bsrc, GstEvent * event, GstSegment * segment); static gboolean rsn_dvdsrc_do_seek (RsnBaseSrc * bsrc, GstSegment * segment); @@ -163,6 +167,9 @@ rsn_dvdsrc_register_extra (GType rsn_dvdsrc_type) rsndvd_format = gst_format_register ("rsndvdsrc-internal", "private Resin DVD src format"); + + title_format = gst_format_register ("title", "DVD title format"); + chapter_format = gst_format_register ("chapter", "DVD chapter format"); } static void @@ -206,6 +213,7 @@ rsn_dvdsrc_class_init (resinDvdSrcClass * klass) gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (rsn_dvdsrc_unlock_stop); gstbasesrc_class->event = GST_DEBUG_FUNCPTR (rsn_dvdsrc_src_event); gstbasesrc_class->query = GST_DEBUG_FUNCPTR (rsn_dvdsrc_src_query); + gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (rsn_dvdsrc_is_seekable); gstbasesrc_class->prepare_seek_segment = GST_DEBUG_FUNCPTR (rsn_dvdsrc_prepare_seek); gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (rsn_dvdsrc_do_seek); @@ -284,7 +292,6 @@ rsn_dvdsrc_set_property (GObject * object, guint prop_id, else src->device = g_value_dup_string (value); GST_OBJECT_UNLOCK (src); - g_print ("Device is now %s\n", src->device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -756,7 +763,6 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock) case DVDNAV_VTS_CHANGE:{ dvdnav_vts_change_event_t *event = (dvdnav_vts_change_event_t *) data; - g_print ("VTS change\n"); if (dvdnav_is_domain_vmgm (src->dvdnav)) src->vts_n = 0; else @@ -772,7 +778,7 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock) case DVDNAV_AUDIO_STREAM_CHANGE:{ dvdnav_audio_stream_change_event_t *event = (dvdnav_audio_stream_change_event_t *) data; - g_print ("cur audio stream change\n"); + GST_DEBUG_OBJECT (src, " physical: %d", event->physical); GST_DEBUG_OBJECT (src, " logical: %d", event->logical); @@ -782,9 +788,10 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock) case DVDNAV_SPU_STREAM_CHANGE:{ dvdnav_spu_stream_change_event_t *event = (dvdnav_spu_stream_change_event_t *) data; + gint phys_track = event->physical_wide & 0x1f; + gboolean forced_only = (event->physical_wide & 0x80) ? TRUE : FALSE; - rsn_dvdsrc_prepare_spu_stream_event (src, event->physical_wide & 0x1f, - (event->physical_wide & 0x80) ? TRUE : FALSE); + rsn_dvdsrc_prepare_spu_stream_event (src, phys_track, forced_only); GST_DEBUG_OBJECT (src, " physical_wide: %d", event->physical_wide); GST_DEBUG_OBJECT (src, " physical_letterbox: %d", @@ -1200,6 +1207,8 @@ rsn_dvdsrc_prepare_audio_stream_event (resinDvdSrc * src, guint8 phys_stream) return; src->cur_audio_phys_stream = phys_stream; + g_print ("Preparing audio change, phys %d\n", phys_stream); + s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING, "dvd-set-audio-track", "physical-id", G_TYPE_INT, (gint) phys_stream, NULL); @@ -1220,12 +1229,14 @@ rsn_dvdsrc_prepare_spu_stream_event (resinDvdSrc * src, guint8 phys_stream, if (phys_stream == src->cur_spu_phys_stream && forced_only == src->cur_spu_forced_only) { - g_print ("Not preparing SPU change\n"); return; } src->cur_spu_phys_stream = phys_stream; src->cur_spu_forced_only = forced_only; + g_print ("Preparing SPU change, phys %d forced %d\n", + phys_stream, forced_only); + s = gst_structure_new ("application/x-gst-dvd", "event", G_TYPE_STRING, "dvd-set-subpicture-track", "physical-id", G_TYPE_INT, (gint) phys_stream, @@ -1252,6 +1263,7 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) gchar lang_code[3] = { '\0', '\0', '\0' }; gchar *t; gboolean is_widescreen; + gboolean have_audio; if (src->vts_attrs == NULL || src->vts_n >= src->vts_attrs->len) { if (src->vts_attrs) @@ -1301,13 +1313,21 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) NULL); /* audio */ - if (n_audio == 0) { - /* Always create at least one audio stream */ - gst_structure_set (s, "audio-0-format", G_TYPE_INT, (int) 0, NULL); - } + have_audio = FALSE; for (i = 0; i < n_audio; i++) { const audio_attr_t *a = a_attrs + i; +#if 1 + /* FIXME: Only output A52 streams for now, until the decoder switching + * is ready */ + if (a->audio_format != 0) { + GST_DEBUG_OBJECT (src, "Ignoring non-A52 stream %d, format %d", i, + (int) a->audio_format); + continue; + } +#endif + have_audio = TRUE; + t = g_strdup_printf ("audio-%d-format", i); gst_structure_set (s, t, G_TYPE_INT, (int) a->audio_format, NULL); g_free (t); @@ -1327,6 +1347,11 @@ rsn_dvdsrc_prepare_streamsinfo_event (resinDvdSrc * src) GST_DEBUG_OBJECT (src, "Audio stream %d - no language", i, lang_code); } + if (have_audio == FALSE) { + /* Always create at least one audio stream */ + gst_structure_set (s, "audio-0-format", G_TYPE_INT, (int) 0, NULL); + } + /* subpictures */ if (n_subp == 0) { /* Always create at least one subpicture stream */ @@ -1447,7 +1472,15 @@ rsn_dvdsrc_update_highlight (resinDvdSrc * src) /* Check if we have a new button number, or a new highlight region. */ if (button != src->active_button || - memcmp (&area, &(src->area), sizeof (dvdnav_highlight_area_t)) != 0) { + area.sx != src->area.sx || area.sy != src->area.sy || + area.ex != src->area.ex || area.ey != src->area.ey || + area.palette != src->area.palette) { + + g_print ("Setting highlight. Button %d @ %d,%d active %d palette 0x%x " + "(from button %d @ %d,%d palette 0x%x)\n", + button, src->area.sx, src->area.sy, mode, src->area.palette, + src->active_button, area.sx, area.sy, area.palette); + memcpy (&(src->area), &area, sizeof (dvdnav_highlight_area_t)); s = gst_structure_new ("application/x-gst-dvd", "event", @@ -1469,9 +1502,6 @@ rsn_dvdsrc_update_highlight (resinDvdSrc * src) src->active_button = button; - g_print ("Setting highlight. Button %d @ %d,%d active %d" - " palette 0x%x\n", button, area.sx, area.sy, mode, area.palette); - if (src->highlight_event) gst_event_unref (src->highlight_event); src->highlight_event = event; @@ -1708,11 +1738,70 @@ rsn_dvdsrc_src_query (RsnBaseSrc * basesrc, GstQuery * query) switch (GST_QUERY_TYPE (query)) { case GST_QUERY_DURATION: gst_query_parse_duration (query, &format, NULL); - if (format == GST_FORMAT_TIME && src->pgc_duration != GST_CLOCK_TIME_NONE) { - val = src->pgc_duration; - gst_query_set_duration (query, format, val); - res = TRUE; + g_mutex_lock (src->dvd_lock); + if (!src->running) { + g_mutex_unlock (src->dvd_lock); + break; + } + + if (format == GST_FORMAT_TIME) { + if (src->pgc_duration != GST_CLOCK_TIME_NONE) { + val = src->pgc_duration; + gst_query_set_duration (query, format, val); + res = TRUE; + } + } else if (format == title_format) { + gint32 titles; + + if (dvdnav_get_number_of_titles (src->dvdnav, + &titles) == DVDNAV_STATUS_OK) { + val = titles; + gst_query_set_duration (query, format, val); + res = TRUE; + } + } else if (format == chapter_format) { + gint32 title, chapters, x; + + if (dvdnav_current_title_info (src->dvdnav, &title, + &x) == DVDNAV_STATUS_OK) { + if (dvdnav_get_number_of_parts (src->dvdnav, title, + &chapters) == DVDNAV_STATUS_OK) { + val = chapters; + gst_query_set_duration (query, format, val); + res = TRUE; + } + } } + g_mutex_unlock (src->dvd_lock); + break; + case GST_QUERY_POSITION: + gst_query_parse_position (query, &format, NULL); + + g_mutex_lock (src->dvd_lock); + if (!src->running) { + g_mutex_unlock (src->dvd_lock); + break; + } + if (format == title_format) { + gint32 title, chapter; + + if (dvdnav_current_title_info (src->dvdnav, &title, + &chapter) == DVDNAV_STATUS_OK) { + val = title; + gst_query_set_position (query, format, val); + res = TRUE; + } + } else if (format == chapter_format) { + gint32 title, chapter = -1; + + if (dvdnav_current_title_info (src->dvdnav, &title, + &chapter) == DVDNAV_STATUS_OK) { + val = chapter; + gst_query_set_position (query, format, val); + res = TRUE; + } + } + g_mutex_unlock (src->dvd_lock); break; default: res = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); @@ -1723,6 +1812,12 @@ rsn_dvdsrc_src_query (RsnBaseSrc * basesrc, GstQuery * query) } static gboolean +rsn_dvdsrc_is_seekable (RsnBaseSrc * bsrc) +{ + return TRUE; +} + +static gboolean rsn_dvdsrc_prepare_seek (RsnBaseSrc * bsrc, GstEvent * event, GstSegment * segment) { @@ -1737,8 +1832,9 @@ rsn_dvdsrc_prepare_seek (RsnBaseSrc * bsrc, GstEvent * event, gst_event_parse_seek (event, &rate, &seek_format, &flags, &cur_type, &cur, &stop_type, &stop); - if (seek_format == rsndvd_format) { - /* Seeks in our internal format are passed directly through to the do_seek + if (seek_format == rsndvd_format || seek_format == title_format || + seek_format == chapter_format) { + /* Seeks in our internal formats are passed directly through to the do_seek * method. */ gst_segment_init (segment, seek_format); gst_segment_set_seek (segment, rate, seek_format, flags, cur_type, cur, @@ -1753,8 +1849,7 @@ rsn_dvdsrc_prepare_seek (RsnBaseSrc * bsrc, GstEvent * event, if (seek_format == GST_FORMAT_BYTES) return FALSE; - /* Let basesrc handle other formats for now. FIXME: Implement angle, - * chapter etc */ + /* Let basesrc handle other formats for now. FIXME: Implement angle */ return GST_BASE_SRC_CLASS (parent_class)->prepare_seek_segment (bsrc, event, segment); } @@ -1766,6 +1861,9 @@ rsn_dvdsrc_do_seek (RsnBaseSrc * bsrc, GstSegment * segment) gboolean ret = FALSE; if (segment->format == rsndvd_format) { + /* The internal format has alread served its purpose of waking + * everything up and flushing, we just need to step to the next + * data block (below) so we know our new position */ ret = TRUE; } else { /* FIXME: Handle other formats: Time, title, chapter, angle */ @@ -1773,13 +1871,41 @@ rsn_dvdsrc_do_seek (RsnBaseSrc * bsrc, GstSegment * segment) if (segment->format == GST_FORMAT_TIME) { ret = TRUE; src->discont = TRUE; + } else if (segment->format == title_format) { + gint titles; + + g_mutex_lock (src->dvd_lock); + if (src->running && + dvdnav_get_number_of_titles (src->dvdnav, + &titles) == DVDNAV_STATUS_OK) { + if (segment->start > 0 && segment->start <= titles) { + dvdnav_title_play (src->dvdnav, segment->start); + ret = TRUE; + src->discont = TRUE; + } + } + g_mutex_unlock (src->dvd_lock); + } else if (segment->format == chapter_format) { + g_mutex_lock (src->dvd_lock); + if (src->running) { + gint32 title, chapters, x; + if (dvdnav_current_title_info (src->dvdnav, &title, &x) == + DVDNAV_STATUS_OK) { + if (dvdnav_get_number_of_parts (src->dvdnav, title, &chapters) == + DVDNAV_STATUS_OK) { + if (segment->start > 0 && segment->start <= chapters) { + dvdnav_part_play (src->dvdnav, title, segment->start); + ret = TRUE; + src->discont = TRUE; + } + } + } + } + g_mutex_unlock (src->dvd_lock); } } if (ret) { - /* The internal format has served its purpose of waking everything - * up and flushing, now step to the next data block so we know our - * position */ /* Force a highlight update */ src->active_button = -1; diff --git a/ext/resindvd/rsnstreamselector.c b/ext/resindvd/rsnstreamselector.c index b422ac38..2c7e58e2 100644 --- a/ext/resindvd/rsnstreamselector.c +++ b/ext/resindvd/rsnstreamselector.c @@ -63,7 +63,9 @@ enum static gboolean rsn_stream_selector_is_active_sinkpad (RsnStreamSelector * sel, GstPad * pad); -static GstPad *rsn_stream_selector_activate_sinkpad (RsnStreamSelector * sel, +static GstPad *rsn_stream_selector_get_active (RsnStreamSelector * sel, + GstPad * pad); +static void rsn_stream_selector_set_active (RsnStreamSelector * sel, GstPad * pad); static GstPad *rsn_stream_selector_get_linked_pad (GstPad * pad, gboolean strict); @@ -261,7 +263,7 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event) selpad = GST_SELECTOR_PAD_CAST (pad); /* only forward if we are dealing with the active sinkpad */ - active_sinkpad = rsn_stream_selector_activate_sinkpad (sel, pad); + active_sinkpad = rsn_stream_selector_get_active (sel, pad); forward = (active_sinkpad == pad); switch (GST_EVENT_TYPE (event)) { @@ -307,6 +309,18 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event) GST_OBJECT_UNLOCK (selpad); break; } + case GST_EVENT_CUSTOM_DOWNSTREAM: + { + const GstStructure *structure = gst_event_get_structure (event); + if (structure != NULL && + gst_structure_has_name (structure, "application/x-gst-dvd")) { + const char *type = gst_structure_get_string (structure, "event"); + if (strcmp (type, "select-pad") == 0) { + rsn_stream_selector_set_active (sel, pad); + forward = FALSE; + } + } + } case GST_EVENT_EOS: selpad->eos = TRUE; break; @@ -351,7 +365,7 @@ gst_selector_pad_bufferalloc (GstPad * pad, guint64 offset, sel = RSN_STREAM_SELECTOR (gst_pad_get_parent (pad)); - active_sinkpad = rsn_stream_selector_activate_sinkpad (sel, pad); + active_sinkpad = rsn_stream_selector_get_active (sel, pad); /* Fallback allocation for buffers from pads except the selected one */ if (pad != active_sinkpad) { @@ -397,7 +411,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf) selpad = GST_SELECTOR_PAD_CAST (pad); seg = &selpad->segment; - active_sinkpad = rsn_stream_selector_activate_sinkpad (sel, pad); + active_sinkpad = rsn_stream_selector_get_active (sel, pad); timestamp = GST_BUFFER_TIMESTAMP (buf); if (GST_CLOCK_TIME_IS_VALID (timestamp)) { @@ -574,28 +588,10 @@ rsn_stream_selector_set_property (GObject * object, guint prop_id, case PROP_ACTIVE_PAD: { GstPad *pad = NULL; - GstPad **active_pad_p; pad = g_value_get_object (value); + rsn_stream_selector_set_active (sel, pad); - GST_OBJECT_LOCK (object); - if (pad != sel->active_sinkpad) { - RsnSelectorPad *selpad; - - selpad = GST_SELECTOR_PAD_CAST (pad); - /* we can only activate pads that have data received */ - if (selpad && !selpad->active) { - GST_DEBUG_OBJECT (sel, "No data received on pad %" GST_PTR_FORMAT, - pad); - } else { - active_pad_p = &sel->active_sinkpad; - gst_object_replace ((GstObject **) active_pad_p, - GST_OBJECT_CAST (pad)); - GST_DEBUG_OBJECT (sel, "New active pad is %" GST_PTR_FORMAT, - sel->active_sinkpad); - } - } - GST_OBJECT_UNLOCK (object); break; } default: @@ -694,7 +690,7 @@ rsn_stream_selector_is_active_sinkpad (RsnStreamSelector * sel, GstPad * pad) /* Get or create the active sinkpad */ static GstPad * -rsn_stream_selector_activate_sinkpad (RsnStreamSelector * sel, GstPad * pad) +rsn_stream_selector_get_active (RsnStreamSelector * sel, GstPad * pad) { GstPad *active_sinkpad; RsnSelectorPad *selpad; @@ -714,6 +710,29 @@ rsn_stream_selector_activate_sinkpad (RsnStreamSelector * sel, GstPad * pad) return active_sinkpad; } +static void +rsn_stream_selector_set_active (RsnStreamSelector * sel, GstPad * pad) +{ + GstPad **active_pad_p; + + GST_OBJECT_LOCK (GST_OBJECT_CAST (sel)); + if (pad != sel->active_sinkpad) { + RsnSelectorPad *selpad; + + selpad = GST_SELECTOR_PAD_CAST (pad); + /* we can only activate pads that have data received */ + if (selpad && !selpad->active) { + GST_DEBUG_OBJECT (sel, "No data received on pad %" GST_PTR_FORMAT, pad); + } else { + active_pad_p = &sel->active_sinkpad; + gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad)); + GST_DEBUG_OBJECT (sel, "New active pad is %" GST_PTR_FORMAT, + sel->active_sinkpad); + } + } + GST_OBJECT_UNLOCK (GST_OBJECT_CAST (sel)); +} + static GList * rsn_stream_selector_get_linked_pads (GstPad * pad) { |