summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@mad.scientist.com>2008-09-27 01:12:30 +0000
committerJan Schmidt <thaytan@mad.scientist.com>2008-09-27 01:12:30 +0000
commita8736df9b53a190f21d6c2e132a04f296797782a (patch)
tree2660b8fa6089eabe0faae2ffe879715412d0b815 /ext
parenta51c4c16b25416ca55ddca56a14c89be63782a90 (diff)
downloadgstreamer-plugins-bad-a8736df9b53a190f21d6c2e132a04f296797782a.tar.gz
ext/resindvd/: Add in Title/Chapter seeking, and simple but buggy audio and subtitle stream selection.
Original commit message from CVS: * ext/resindvd/gstmpegdemux.c: * ext/resindvd/gstmpegdemux.h: * ext/resindvd/resindvdbin.c: * ext/resindvd/resindvdsrc.c: * ext/resindvd/rsnstreamselector.c: Add in Title/Chapter seeking, and simple but buggy audio and subtitle stream selection.
Diffstat (limited to 'ext')
-rw-r--r--ext/resindvd/gstmpegdemux.c89
-rw-r--r--ext/resindvd/gstmpegdemux.h3
-rw-r--r--ext/resindvd/resindvdsrc.c176
-rw-r--r--ext/resindvd/rsnstreamselector.c67
4 files changed, 281 insertions, 54 deletions
diff --git a/ext/resindvd/gstmpegdemux.c b/ext/resindvd/gstmpegdemux.c
index 4e2cc2911..99049cea4 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 fd566afa9..3f38b088d 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 bf4d033d1..371624e97 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 b422ac383..2c7e58e2b 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)
{