promoting gstreamer-0.10 branch to trunk
This commit is contained in:
parent
666c9d0d0f
commit
c9026785f9
|
@ -424,7 +424,7 @@ export LD_LIBRARY_PATH=$install_lib # is this needed here?
|
|||
export GST_REGISTRY=$install_etc/gst-registry.xml
|
||||
export GST_PLUGIN_PATH=$install_lib:$gstreamer_dir
|
||||
rm -f ${GST_REGISTRY}
|
||||
rm -f $install_var/cache/gstreamer-0.8/registry.xml
|
||||
rm -f $install_var/cache/gstreamer-0.10/registry.xml
|
||||
$install_bin/gst-register
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
MD5 230cec8bdd27a33315b67c3eb5cd59f7 gst-plugins-0.8.10-r1.ebuild 2151
|
||||
MD5 14463cc56953050a6161f55a1abb9228 files/adder-query.patch 1754
|
||||
MD5 d05851db15053a9e5b1c114dfecabbf4 files/adder-duration-fix.patch 1102
|
||||
MD5 36f4a0bacb3d1f85c78525f4a1e46fe5 files/switch-fix.patch 1434
|
||||
MD5 9f833bb88c0c1d6b9c2b0bdf20f47e4e files/adder-caps-property.patch 9086
|
||||
MD5 e5a6b80e2dfc0bf36559f4663fb90e25 files/digest-gst-plugins-0.8.10-r1 72
|
||||
MD5 0fd59e0dd0c56f118ccc1a5309cb69b8 files/typefind-smil.patch 2783
|
|
@ -1,290 +0,0 @@
|
|||
--- gst-plugins-0.8.10/gst/adder/gstadder.h 2005-05-17 10:41:43.000000000 +0200
|
||||
+++ gst-plugins-0.8.10-livesupport/gst/adder/gstadder.h 2005-08-26 10:58:46.000000000 +0200
|
||||
@@ -65,6 +65,8 @@
|
||||
|
||||
GstPad *srcpad;
|
||||
|
||||
+ GstCaps *caps;
|
||||
+
|
||||
/* keep track of the sinkpads */
|
||||
guint numsinkpads;
|
||||
GSList *input_channels;
|
||||
--- gst-plugins-0.8.10/gst/adder/gstadder.c 2005-06-14 18:38:01.000000000 +0200
|
||||
+++ gst-plugins-0.8.10-livesupport/gst/adder/gstadder.c 2005-08-26 12:07:30.000000000 +0200
|
||||
@@ -64,7 +64,8 @@
|
||||
{
|
||||
ARG_0,
|
||||
ARG_NUM_PADS,
|
||||
- ARG_EOS
|
||||
+ ARG_EOS,
|
||||
+ ARG_CAPS
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
@@ -86,6 +87,7 @@
|
||||
|
||||
static void gst_adder_class_init (GstAdderClass * klass);
|
||||
static void gst_adder_init (GstAdder * adder);
|
||||
+static void gst_adder_dispose (GObject * object);
|
||||
|
||||
static void gst_adder_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
@@ -101,6 +103,8 @@
|
||||
/* we do need a loop function */
|
||||
static void gst_adder_loop (GstElement * element);
|
||||
|
||||
+static void gst_adder_set_caps(GstAdder * adder,
|
||||
+ const GstCaps * caps);
|
||||
static GstCaps *gst_adder_get_caps (GstPad * pad);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
@@ -131,13 +135,11 @@
|
||||
static GstPadLinkReturn
|
||||
gst_adder_link (GstPad * pad, const GstCaps * caps)
|
||||
{
|
||||
- GstAdder *adder;
|
||||
- const char *media_type;
|
||||
- const GList *pads;
|
||||
- GstStructure *structure;
|
||||
- GstPadLinkReturn ret;
|
||||
- GstElement *element;
|
||||
- const GSList *links;
|
||||
+ GstAdder * adder;
|
||||
+ const GList * pads;
|
||||
+ GstPadLinkReturn ret;
|
||||
+ GstElement * element;
|
||||
+ GSList * links;
|
||||
|
||||
g_return_val_if_fail (caps != NULL, GST_PAD_LINK_REFUSED);
|
||||
g_return_val_if_fail (pad != NULL, GST_PAD_LINK_REFUSED);
|
||||
@@ -145,41 +147,42 @@
|
||||
element = GST_PAD_PARENT (pad);
|
||||
adder = GST_ADDER (element);
|
||||
|
||||
- pads = gst_element_get_pad_list (element);
|
||||
- while (pads) {
|
||||
- GstPad *otherpad = GST_PAD (pads->data);
|
||||
-
|
||||
- if (otherpad != pad) {
|
||||
- ret = gst_pad_try_set_caps (otherpad, caps);
|
||||
- if (ret == GST_PAD_LINK_REFUSED ||
|
||||
- (otherpad == adder->srcpad && GST_PAD_LINK_FAILED (ret))) {
|
||||
- return ret;
|
||||
+ if (adder->caps != NULL) {
|
||||
+ pads = gst_element_get_pad_list (element);
|
||||
+ while (pads) {
|
||||
+ GstPad *otherpad = GST_PAD (pads->data);
|
||||
+
|
||||
+ if (otherpad != pad) {
|
||||
+ ret = gst_pad_try_set_caps (otherpad, adder->caps);
|
||||
+ if (ret == GST_PAD_LINK_REFUSED ||
|
||||
+ (otherpad == adder->srcpad && GST_PAD_LINK_FAILED (ret))) {
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
+ pads = g_list_next (pads);
|
||||
+ }
|
||||
+ } else {
|
||||
+ pads = gst_element_get_pad_list (element);
|
||||
+ while (pads) {
|
||||
+ GstPad *otherpad = GST_PAD (pads->data);
|
||||
+
|
||||
+ if (otherpad != pad) {
|
||||
+ ret = gst_pad_try_set_caps (otherpad, caps);
|
||||
+ if (ret == GST_PAD_LINK_REFUSED ||
|
||||
+ (otherpad == adder->srcpad && GST_PAD_LINK_FAILED (ret))) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ pads = g_list_next (pads);
|
||||
}
|
||||
- pads = g_list_next (pads);
|
||||
- }
|
||||
|
||||
- structure = gst_caps_get_structure (caps, 0);
|
||||
- media_type = gst_structure_get_name (structure);
|
||||
- if (strcmp (media_type, "audio/x-raw-int") == 0) {
|
||||
- GST_DEBUG ("parse_caps sets adder to format int");
|
||||
- adder->format = GST_ADDER_FORMAT_INT;
|
||||
- gst_structure_get_int (structure, "width", &adder->width);
|
||||
- gst_structure_get_int (structure, "depth", &adder->depth);
|
||||
- gst_structure_get_int (structure, "endianness", &adder->endianness);
|
||||
- gst_structure_get_boolean (structure, "signed", &adder->is_signed);
|
||||
- gst_structure_get_int (structure, "channels", &adder->channels);
|
||||
- gst_structure_get_int (structure, "rate", &adder->rate);
|
||||
- } else if (strcmp (media_type, "audio/x-raw-float") == 0) {
|
||||
- GST_DEBUG ("parse_caps sets adder to format float");
|
||||
- adder->format = GST_ADDER_FORMAT_FLOAT;
|
||||
- gst_structure_get_int (structure, "width", &adder->width);
|
||||
- gst_structure_get_int (structure, "channels", &adder->channels);
|
||||
- gst_structure_get_int (structure, "rate", &adder->rate);
|
||||
+ /* set our caps, if all try_set_caps succeeded */
|
||||
+ gst_adder_set_caps(adder, caps);
|
||||
+
|
||||
}
|
||||
|
||||
for (links = adder->input_channels;
|
||||
- links != NULL; links = g_slist_next (links)) {
|
||||
+ links != NULL; links = g_slist_next (links)) {
|
||||
GstAdderInputChannel *input = (GstAdderInputChannel *) links->data;
|
||||
|
||||
if (input->sinkpad == pad) {
|
||||
@@ -200,6 +203,8 @@
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
+ gobject_class->dispose = gst_adder_dispose;
|
||||
+
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_adder_src_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
@@ -217,6 +222,11 @@
|
||||
"generate an EOS when all input channels did", FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CAPS,
|
||||
+ g_param_spec_pointer ("caps", "pad capabilities",
|
||||
+ "fix all adder capabilities to supplied value",
|
||||
+ G_PARAM_READWRITE));
|
||||
+
|
||||
gobject_class->get_property = gst_adder_get_property;
|
||||
gobject_class->set_property = gst_adder_set_property;
|
||||
|
||||
@@ -226,6 +236,44 @@
|
||||
}
|
||||
|
||||
static void
|
||||
+gst_adder_set_caps(GstAdder * adder,
|
||||
+ const GstCaps * caps)
|
||||
+{
|
||||
+ GstStructure * structure;
|
||||
+ const char * media_type;
|
||||
+
|
||||
+ if (adder == NULL || !GST_IS_ADDER(adder)
|
||||
+ || caps == NULL || !GST_IS_CAPS(caps)) {
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ if (adder->caps != NULL) {
|
||||
+ gst_caps_free(adder->caps);
|
||||
+ }
|
||||
+
|
||||
+ adder->caps = gst_caps_copy(caps);
|
||||
+
|
||||
+ structure = gst_caps_get_structure (adder->caps, 0);
|
||||
+ media_type = gst_structure_get_name (structure);
|
||||
+ if (strcmp (media_type, "audio/x-raw-int") == 0) {
|
||||
+ GST_DEBUG ("parse_caps sets adder to format int");
|
||||
+ adder->format = GST_ADDER_FORMAT_INT;
|
||||
+ gst_structure_get_int (structure, "width", &adder->width);
|
||||
+ gst_structure_get_int (structure, "depth", &adder->depth);
|
||||
+ gst_structure_get_int (structure, "endianness", &adder->endianness);
|
||||
+ gst_structure_get_boolean (structure, "signed", &adder->is_signed);
|
||||
+ gst_structure_get_int (structure, "channels", &adder->channels);
|
||||
+ gst_structure_get_int (structure, "rate", &adder->rate);
|
||||
+ } else if (strcmp (media_type, "audio/x-raw-float") == 0) {
|
||||
+ GST_DEBUG ("parse_caps sets adder to format float");
|
||||
+ adder->format = GST_ADDER_FORMAT_FLOAT;
|
||||
+ gst_structure_get_int (structure, "width", &adder->width);
|
||||
+ gst_structure_get_int (structure, "channels", &adder->channels);
|
||||
+ gst_structure_get_int (structure, "rate", &adder->rate);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
gst_adder_init (GstAdder * adder)
|
||||
{
|
||||
adder->srcpad =
|
||||
@@ -238,6 +286,8 @@
|
||||
|
||||
adder->format = GST_ADDER_FORMAT_UNSET;
|
||||
|
||||
+ adder->caps = NULL;
|
||||
+
|
||||
/* keep track of the sinkpads requested */
|
||||
|
||||
adder->numsinkpads = 0;
|
||||
@@ -246,6 +296,18 @@
|
||||
adder->eos = FALSE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+gst_adder_dispose(GObject * object)
|
||||
+{
|
||||
+ GstAdder * adder = GST_ADDER(object);
|
||||
+
|
||||
+ g_return_if_fail(GST_IS_ADDER(adder));
|
||||
+ if (adder->caps) {
|
||||
+ gst_caps_free(adder->caps);
|
||||
+ }
|
||||
+ G_OBJECT_CLASS(parent_class)->dispose(object);
|
||||
+}
|
||||
+
|
||||
static GstPad *
|
||||
gst_adder_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||
const gchar * unused)
|
||||
@@ -339,6 +401,9 @@
|
||||
case ARG_EOS:
|
||||
g_value_set_boolean (value, adder->eos);
|
||||
break;
|
||||
+ case ARG_CAPS:
|
||||
+ g_value_set_pointer (value, adder->caps);
|
||||
+ break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -360,6 +425,9 @@
|
||||
case ARG_EOS:
|
||||
adder->eos = g_value_get_boolean (value);
|
||||
break;
|
||||
+ case ARG_CAPS:
|
||||
+ gst_adder_set_caps(adder, g_value_get_pointer(value));
|
||||
+ break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -613,23 +681,28 @@
|
||||
gst_adder_get_caps (GstPad * pad)
|
||||
{
|
||||
GstAdder *adder = GST_ADDER (gst_pad_get_parent (pad));
|
||||
- GstCaps *caps = gst_caps_new_any ();
|
||||
- GstCaps *tmp, *res;
|
||||
- GstPad *otherpad;
|
||||
- const GList *pads;
|
||||
-
|
||||
- for (pads = gst_element_get_pad_list (GST_ELEMENT (adder));
|
||||
- pads != NULL; pads = pads->next) {
|
||||
- otherpad = GST_PAD (pads->data);
|
||||
-
|
||||
- tmp = gst_pad_get_allowed_caps (otherpad);
|
||||
- res = gst_caps_intersect (caps, tmp);
|
||||
- gst_caps_free (tmp);
|
||||
- gst_caps_free (caps);
|
||||
- caps = res;
|
||||
- }
|
||||
|
||||
- return caps;
|
||||
+ if (adder->caps != NULL) {
|
||||
+ return gst_caps_copy(adder->caps);
|
||||
+ } else {
|
||||
+ GstCaps *caps = gst_caps_new_any ();
|
||||
+ GstCaps *tmp, *res;
|
||||
+ GstPad *otherpad;
|
||||
+ const GList *pads;
|
||||
+
|
||||
+ for (pads = gst_element_get_pad_list (GST_ELEMENT (adder));
|
||||
+ pads != NULL; pads = pads->next) {
|
||||
+ otherpad = GST_PAD (pads->data);
|
||||
+
|
||||
+ tmp = gst_pad_get_allowed_caps (otherpad);
|
||||
+ res = gst_caps_intersect (caps, tmp);
|
||||
+ gst_caps_free (tmp);
|
||||
+ gst_caps_free (caps);
|
||||
+ caps = res;
|
||||
+ }
|
||||
+
|
||||
+ return caps;
|
||||
+ }
|
||||
}
|
||||
|
||||
static gboolean
|
|
@ -1,29 +0,0 @@
|
|||
--- gst-plugins-0.8.9/gst/adder/gstadder.c 2005-06-29 14:45:17.000000000 +0200
|
||||
+++ gst-plugins-0.8.9-livesupport/gst/adder/gstadder.c 2005-06-29 14:42:05.000000000 +0200
|
||||
@@ -558,14 +558,19 @@
|
||||
}
|
||||
|
||||
if (valid_inputs > 0 || adder->eos == FALSE) {
|
||||
+ gint64 delta;
|
||||
+ gint64 duration;
|
||||
+
|
||||
+ delta = (adder->format == GST_ADDER_FORMAT_FLOAT)
|
||||
+ ? GST_BUFFER_SIZE (buf_out) / adder->width / adder->channels
|
||||
+ : GST_BUFFER_SIZE (buf_out) * 8 / adder->width / adder->channels;
|
||||
+ duration = delta * GST_SECOND / adder->rate;
|
||||
+
|
||||
GST_BUFFER_TIMESTAMP (buf_out) = adder->timestamp;
|
||||
- if (adder->format == GST_ADDER_FORMAT_FLOAT)
|
||||
- adder->offset +=
|
||||
- GST_BUFFER_SIZE (buf_out) / adder->width / adder->channels;
|
||||
- else
|
||||
- adder->offset +=
|
||||
- GST_BUFFER_SIZE (buf_out) * 8 / adder->width / adder->channels;
|
||||
- adder->timestamp = adder->offset * GST_SECOND / adder->rate;
|
||||
+ GST_BUFFER_DURATION (buf_out) = duration;
|
||||
+
|
||||
+ adder->offset += delta;
|
||||
+ adder->timestamp += duration;
|
||||
|
||||
/* send it out */
|
||||
GST_LOG ("pushing buf_out");
|
|
@ -1,54 +0,0 @@
|
|||
--- gst-plugins-0.8.10/gst/adder/gstadder.c 2005-09-07 16:24:18.000000000 +0200
|
||||
+++ gst-plugins-0.8.10-livesupport/gst/adder/gstadder.c 2005-09-07 16:22:40.000000000 +0200
|
||||
@@ -107,6 +107,11 @@
|
||||
const GstCaps * caps);
|
||||
static GstCaps *gst_adder_get_caps (GstPad * pad);
|
||||
|
||||
+static gboolean gst_adder_query(GstPad * pad,
|
||||
+ GstQueryType type,
|
||||
+ GstFormat * format,
|
||||
+ gint64 * value);
|
||||
+
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
/* static guint gst_adder_signals[LAST_SIGNAL] = { 0 }; */
|
||||
@@ -283,6 +288,7 @@
|
||||
gst_element_set_loop_function (GST_ELEMENT (adder), gst_adder_loop);
|
||||
gst_pad_set_getcaps_function (adder->srcpad, gst_adder_get_caps);
|
||||
gst_pad_set_link_function (adder->srcpad, gst_adder_link);
|
||||
+ gst_pad_set_query_function (adder->srcpad, gst_adder_query);
|
||||
|
||||
adder->format = GST_ADDER_FORMAT_UNSET;
|
||||
|
||||
@@ -654,6 +660,31 @@
|
||||
}
|
||||
|
||||
|
||||
+static gboolean gst_adder_query(GstPad * pad,
|
||||
+ GstQueryType type,
|
||||
+ GstFormat * format,
|
||||
+ gint64 * value)
|
||||
+{
|
||||
+ GstAdder * adder;
|
||||
+
|
||||
+ adder = GST_ADDER(gst_pad_get_parent(pad));
|
||||
+ if (!GST_IS_ADDER(adder)) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (pad != adder->srcpad) {
|
||||
+ return gst_pad_query_default(pad, type, format, value);
|
||||
+ }
|
||||
+
|
||||
+ if (type != GST_QUERY_POSITION || *format != GST_FORMAT_TIME) {
|
||||
+ return gst_pad_query_default(pad, type, format, value);
|
||||
+ }
|
||||
+
|
||||
+ *value = adder->timestamp;
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static GstElementStateReturn
|
||||
gst_adder_change_state (GstElement * element)
|
||||
{
|
|
@ -1 +0,0 @@
|
|||
MD5 99f36ba2b91015a23d3c20a8f424b232 gst-plugins-0.8.10.tar.bz2 2397528
|
|
@ -1,32 +0,0 @@
|
|||
--- gst-plugins-0.8.9/gst/switch/gstswitch.c 2005-04-14 18:26:47.000000000 +0200
|
||||
+++ gst-plugins-0.8.9-livesupport/gst/switch/gstswitch.c 2005-06-18 11:26:19.000000000 +0200
|
||||
@@ -241,15 +241,23 @@
|
||||
GstEvent *event = GST_EVENT (data);
|
||||
|
||||
GST_LOG_OBJECT (gstswitch,
|
||||
- "handling event from active pad %p", switchpad->sinkpad);
|
||||
+ "handling event of type %d from active pad %p",
|
||||
+ GST_EVENT_TYPE(GST_EVENT(data)),
|
||||
+ switchpad->sinkpad);
|
||||
/* Handling event */
|
||||
gst_pad_event_default (switchpad->sinkpad, event);
|
||||
} else {
|
||||
- /* Pushing active sinkpad data to srcpad */
|
||||
- GST_LOG_OBJECT (gstswitch,
|
||||
- "pushing data from active pad %p to %p",
|
||||
- switchpad->sinkpad, gstswitch->srcpad);
|
||||
- gst_pad_push (gstswitch->srcpad, data);
|
||||
+ if (GST_PAD_IS_ACTIVE(GST_PAD_PEER(gstswitch->srcpad))) {
|
||||
+ /* Pushing active sinkpad data to srcpad */
|
||||
+ GST_LOG_OBJECT (gstswitch,
|
||||
+ "pushing data from active pad %p to %p",
|
||||
+ switchpad->sinkpad, gstswitch->srcpad);
|
||||
+ gst_pad_push (gstswitch->srcpad, data);
|
||||
+ } else {
|
||||
+ /* the peer has become inactive, put us into EOS state */
|
||||
+ GST_LOG_OBJECT(gstswitch, "peer pad inactivated, going to eos");
|
||||
+ gst_element_set_eos(GST_ELEMENT(gstswitch));
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Mark this data as forwarded so that it won't get unrefed on next poll */
|
|
@ -1,86 +0,0 @@
|
|||
--- gst-plugins-0.8.9/gst/typefind/gsttypefindfunctions.c 2005-05-17 10:41:47.000000000 +0200
|
||||
+++ gst-plugins-0.8.9-livesupport/gst/typefind/gsttypefindfunctions.c 2005-06-22 18:46:33.000000000 +0200
|
||||
@@ -132,6 +132,66 @@
|
||||
}
|
||||
}
|
||||
|
||||
+/*** application/smil *********************************************************/
|
||||
+
|
||||
+static GstStaticCaps smil_caps = GST_STATIC_CAPS ("application/smil");
|
||||
+
|
||||
+#define SMIL_CAPS (gst_static_caps_get(&smil_caps))
|
||||
+static void
|
||||
+smil_type_find (GstTypeFind * tf, gpointer unused)
|
||||
+{
|
||||
+ guint8 *data = gst_type_find_peek (tf, 0, BUFFER_SIZE);
|
||||
+ guint pos = 0;
|
||||
+ guint offset = 0;
|
||||
+
|
||||
+ if (data) {
|
||||
+ /* look for the XMLDec,
|
||||
+ * see XML spec 2.8, Prolog and Document Type Declaration
|
||||
+ * http://www.w3.org/TR/2004/REC-xml-20040204/#sec-prolog-dtd
|
||||
+ */
|
||||
+ /* we know that BUFFER_SIZE > strlen("<?xml") */
|
||||
+ if (!(data[0] == '<'
|
||||
+ && data[1] == '?'
|
||||
+ && data[2] == 'x'
|
||||
+ && data[3] == 'm'
|
||||
+ && data[4] == 'l')) {
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ data += 5;
|
||||
+ pos += 5;
|
||||
+
|
||||
+ /* look for the first element, it has to be a <smil> element */
|
||||
+ while (data) {
|
||||
+ while (*data != '<') {
|
||||
+ INC_BUFFER;
|
||||
+ }
|
||||
+
|
||||
+ INC_BUFFER;
|
||||
+ if (!g_ascii_isalpha(*data)) {
|
||||
+ /* if not alphabetic, it's a PI or an element / attribute declaration
|
||||
+ * like <?xxx or <!xxx */
|
||||
+ INC_BUFFER;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* the first normal element
|
||||
+ * get the next 4 bytes, and look if it's smil */
|
||||
+ data = gst_type_find_peek(tf, offset + pos, 5);
|
||||
+ if (!(data[0] == 's'
|
||||
+ && data[1] == 'm'
|
||||
+ && data[2] == 'i'
|
||||
+ && data[3] == 'l')) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ gst_type_find_suggest(tf, GST_TYPE_FIND_MAXIMUM, SMIL_CAPS);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*** video/x-fli **************************************************************/
|
||||
|
||||
static GstStaticCaps flx_caps = GST_STATIC_CAPS ("video/x-fli");
|
||||
@@ -1789,6 +1849,7 @@
|
||||
static gchar *shn_exts[] = { "shn", NULL };
|
||||
static gchar *ape_exts[] = { "ape", NULL };
|
||||
static gchar *uri_exts[] = { "ram", NULL };
|
||||
+ static gchar *smil_exts[] = { "smil", NULL };
|
||||
static gchar *jpeg_exts[] = { "jpg", "jpe", "jpeg", NULL };
|
||||
static gchar *gif_exts[] = { "gif", NULL };
|
||||
static gchar *png_exts[] = { "png", NULL };
|
||||
@@ -1871,6 +1932,8 @@
|
||||
utf8_exts, UTF8_CAPS, NULL);
|
||||
TYPE_FIND_REGISTER (plugin, "text/uri-list", GST_RANK_MARGINAL, uri_type_find,
|
||||
uri_exts, URI_CAPS, NULL);
|
||||
+ TYPE_FIND_REGISTER (plugin, "application/smil", GST_RANK_PRIMARY, smil_type_find,
|
||||
+ smil_exts, SMIL_CAPS, NULL);
|
||||
TYPE_FIND_REGISTER_RIFF (plugin, "audio/x-wav", GST_RANK_PRIMARY, wav_exts,
|
||||
"WAVE");
|
||||
TYPE_FIND_REGISTER (plugin, "audio/x-aiff", GST_RANK_SECONDARY,
|
|
@ -1,89 +0,0 @@
|
|||
# Copyright 1999-2005 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header: /var/cvsroot/gentoo-x86/media-libs/gst-plugins/gst-plugins-0.8.10.ebuild,v 1.10 2005/09/15 11:39:17 agriffis Exp $
|
||||
|
||||
# order is important, gnome2 after gst-plugins
|
||||
inherit gst-plugins gnome2 eutils flag-o-matic libtool
|
||||
|
||||
DESCRIPTION="Basepack of plugins for gstreamer"
|
||||
HOMEPAGE="http://gstreamer.net/"
|
||||
SRC_URI="http://gstreamer.freedesktop.org/src/${PN}/${P}.tar.bz2"
|
||||
|
||||
LICENSE="GPL-2"
|
||||
KEYWORDS="alpha amd64 ~arm hppa ia64 ~mips ppc ppc64 sparc x86"
|
||||
IUSE="esd alsa oss"
|
||||
|
||||
RDEPEND=">=media-libs/gstreamer-0.8.10
|
||||
>=gnome-base/gconf-2"
|
||||
|
||||
DEPEND="${RDEPEND}
|
||||
>=sys-devel/gettext-0.11.5
|
||||
>=dev-util/pkgconfig-0.9"
|
||||
|
||||
PDEPEND="oss? ( >=media-plugins/gst-plugins-oss-${PV} )
|
||||
alsa? ( >=media-plugins/gst-plugins-alsa-${PV} )
|
||||
esd? ( >=media-plugins/gst-plugins-esd-${PV} )"
|
||||
|
||||
# we need x for the x overlay to get linked
|
||||
GST_PLUGINS_BUILD="x xshm"
|
||||
|
||||
# overrides the eclass
|
||||
src_unpack() {
|
||||
|
||||
unpack ${A}
|
||||
cd ${S}
|
||||
epatch ${FILESDIR}/adder-caps-property.patch
|
||||
epatch ${FILESDIR}/adder-duration-fix.patch
|
||||
epatch ${FILESDIR}/adder-query.patch
|
||||
epatch ${FILESDIR}/switch-fix.patch
|
||||
epatch ${FILESDIR}/typefind-smil.patch
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
|
||||
elibtoolize
|
||||
|
||||
# gst doesnt handle optimisations well
|
||||
strip-flags
|
||||
replace-flags "-O3" "-O2"
|
||||
filter-flags "-fprefetch-loop-arrays" # see bug 22249
|
||||
if use alpha || use amd64 || use ia64 || use hppa; then
|
||||
append-flags -fPIC
|
||||
fi
|
||||
|
||||
gst-plugins_src_configure
|
||||
|
||||
emake || die
|
||||
|
||||
}
|
||||
|
||||
# override eclass
|
||||
src_install() {
|
||||
|
||||
gnome2_src_install
|
||||
|
||||
}
|
||||
|
||||
DOCS="AUTHORS INSTALL README RELEASE TODO"
|
||||
|
||||
pkg_postinst () {
|
||||
|
||||
gnome2_pkg_postinst
|
||||
gst-plugins_pkg_postinst
|
||||
|
||||
echo ""
|
||||
einfo "The Gstreamer plugins setup has changed quite a bit on Gentoo,"
|
||||
einfo "applications now should provide the basic plugins needed."
|
||||
echo ""
|
||||
einfo "The new seperate plugins are all named 'gst-plugins-<plugin>'."
|
||||
einfo "To get a listing of currently available plugins execute 'emerge -s gst-plugins-'."
|
||||
einfo "In most cases it shouldn't be needed though to emerge extra plugins."
|
||||
|
||||
}
|
||||
|
||||
pkg_postrm() {
|
||||
|
||||
gnome2_pkg_postrm
|
||||
gst-plugins_pkg_postrm
|
||||
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
MD5 5675251f4f6bd25fbf54f809816140ac gst-plugins-mad-0.8.10-r1.ebuild 421
|
||||
MD5 e5a6b80e2dfc0bf36559f4663fb90e25 files/digest-gst-plugins-mad-0.8.10-r1 72
|
||||
MD5 9b4b87c7c0e1bf243ebc6def2f62c971 files/id3demuxbin-pad-free-fix.patch 551
|
|
@ -1 +0,0 @@
|
|||
MD5 99f36ba2b91015a23d3c20a8f424b232 gst-plugins-0.8.10.tar.bz2 2397528
|
|
@ -1,15 +0,0 @@
|
|||
--- gst-plugins-0.8.9/ext/mad/gstid3demuxbin.c 2005-04-10 22:24:17.000000000 +0200
|
||||
+++ gst-plugins-0.8.9-livesupport/ext/mad/gstid3demuxbin.c 2005-06-22 10:45:31.000000000 +0200
|
||||
@@ -188,7 +188,11 @@
|
||||
gst_id3demux_bin_remove_pad (GstId3DemuxBin * id3)
|
||||
{
|
||||
if (id3->srcpad) {
|
||||
- gst_element_remove_pad (GST_ELEMENT (id3), id3->srcpad);
|
||||
+ GstPad * pad = gst_element_get_pad(GST_ELEMENT(id3), "src");
|
||||
+
|
||||
+ if (pad && pad == id3->srcpad) {
|
||||
+ gst_element_remove_pad (GST_ELEMENT (id3), id3->srcpad);
|
||||
+ }
|
||||
id3->srcpad = NULL;
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
# Copyright 1999-2005 Gentoo Foundation
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
# $Header$
|
||||
|
||||
inherit gst-plugins eutils
|
||||
|
||||
KEYWORDS="alpha amd64 ~arm hppa ia64 -mips ppc ppc64 sparc x86"
|
||||
IUSE=""
|
||||
|
||||
RDEPEND=">=media-libs/libmad-0.15.1b
|
||||
>=media-libs/libid3tag-0.15"
|
||||
|
||||
DEPEND="${RDEPEND}
|
||||
dev-util/pkgconfig"
|
||||
|
||||
src_unpack() {
|
||||
|
||||
unpack ${A}
|
||||
cd ${S}
|
||||
epatch ${FILESDIR}/id3demuxbin-pad-free-fix.patch
|
||||
}
|
||||
|
|
@ -96,20 +96,6 @@ diff -Naur livesupport-1.0/modules/getid3/etc/Makefile.in livesupport-1.0-gentoo
|
|||
USR_INCLUDE_DIR = ${USR_DIR}/include
|
||||
USR_VAR_DIR = ${USR_DIR}/var
|
||||
|
||||
diff -Naur livesupport-1.0/modules/gstreamerElements/etc/Makefile.in livesupport-1.0-gentoo/modules/gstreamerElements/etc/Makefile.in
|
||||
--- livesupport-1.0/modules/gstreamerElements/etc/Makefile.in 2005-09-21 11:57:28.000000000 +0200
|
||||
+++ livesupport-1.0-gentoo/modules/gstreamerElements/etc/Makefile.in 2005-09-21 11:56:57.000000000 +0200
|
||||
@@ -56,7 +56,9 @@
|
||||
REAL_BASE_DIR=$(shell cd ${BASE_DIR}; pwd)
|
||||
|
||||
|
||||
-USR_DIR = @prefix@
|
||||
+prefix = @prefix@
|
||||
+
|
||||
+USR_DIR = ${prefix}
|
||||
USR_INCLUDE_DIR = ${USR_DIR}/include
|
||||
USR_BIN_DIR = ${USR_DIR}/bin
|
||||
USR_LIB_DIR = ${USR_DIR}/lib
|
||||
diff -Naur livesupport-1.0/modules/htmlUI/etc/Makefile.in livesupport-1.0-gentoo/modules/htmlUI/etc/Makefile.in
|
||||
--- livesupport-1.0/modules/htmlUI/etc/Makefile.in 2005-08-10 00:03:11.000000000 +0200
|
||||
+++ livesupport-1.0-gentoo/modules/htmlUI/etc/Makefile.in 2005-09-21 11:56:57.000000000 +0200
|
||||
|
|
|
@ -185,31 +185,6 @@ diff -Naur --exclude=.svn --exclude=tmp --exclude=lib --exclude=Makefile --exclu
|
|||
${TAGLIB_CFLAGS} \
|
||||
${LIBXMLPP_CFLAGS} \
|
||||
-I${USR_INCLUDE_DIR} \
|
||||
diff -Naur --exclude=.svn --exclude=tmp --exclude=lib --exclude=Makefile --exclude=var --exclude=doc --exclude=src livesupport/modules/gstreamerElements/etc/configure.ac livesupport-x/modules/gstreamerElements/etc/configure.ac
|
||||
--- livesupport/modules/gstreamerElements/etc/configure.ac 2005-09-20 12:46:18.000000000 +0200
|
||||
+++ livesupport-x/modules/gstreamerElements/etc/configure.ac 2005-09-19 17:11:47.000000000 +0200
|
||||
@@ -63,6 +63,9 @@
|
||||
AC_SUBST(GSTREAMER_CFLAGS)
|
||||
AC_SUBST(GSTREAMER_LIBS)
|
||||
|
||||
+AC_PATH_PROG(GST_REGISTER, gst-register-0.8)
|
||||
+AC_SUBST(GST_REGISTER)
|
||||
+
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl enable compilaton for code coverage data
|
||||
diff -Naur --exclude=.svn --exclude=tmp --exclude=lib --exclude=Makefile --exclude=var --exclude=doc --exclude=src livesupport/modules/gstreamerElements/etc/Makefile.in livesupport-x/modules/gstreamerElements/etc/Makefile.in
|
||||
--- livesupport/modules/gstreamerElements/etc/Makefile.in 2005-09-20 12:46:18.000000000 +0200
|
||||
+++ livesupport-x/modules/gstreamerElements/etc/Makefile.in 2005-09-19 17:06:03.000000000 +0200
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
GSTREAMER_CFLAGS=@GSTREAMER_CFLAGS@
|
||||
GSTREAMER_LIBS=@GSTREAMER_LIBS@
|
||||
-GST_REGISTER=${USR_BIN_DIR}/gst-register
|
||||
+GST_REGISTER=@GST_REGISTER@
|
||||
|
||||
TEST_RESULTS = ${DOC_DIR}/testResults.xml
|
||||
# the text result XSLT has to be relative to the test result file, e.g. TMP_DIR
|
||||
diff -Naur --exclude=.svn --exclude=tmp --exclude=lib --exclude=Makefile --exclude=var --exclude=doc --exclude=src livesupport/modules/playlistExecutor/etc/acinclude.m4 livesupport-x/modules/playlistExecutor/etc/acinclude.m4
|
||||
--- livesupport/modules/playlistExecutor/etc/acinclude.m4 2005-09-20 12:45:15.000000000 +0200
|
||||
+++ livesupport-x/modules/playlistExecutor/etc/acinclude.m4 2005-09-19 17:25:54.000000000 +0200
|
||||
|
|
|
@ -53,11 +53,7 @@ DEPEND=">=dev-db/unixODBC-2.2
|
|||
>=dev-cpp/libxmlpp-2.8.1
|
||||
=dev-db/libodbc++-0.2.3-r2
|
||||
=dev-libs/xmlrpc++-0.7
|
||||
=media-libs/gst-plugins-0.8.10-r1
|
||||
=media-libs/taglib-1.3.1-r3
|
||||
=media-plugins/gst-plugins-mad-0.8.10-r1
|
||||
=media-plugins/gst-plugins-ogg-0.8.10
|
||||
=media-libs/gstreamer-0.8.10"
|
||||
|
||||
src_unpack() {
|
||||
unpack ${A}
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
#!/bin/bash
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2004 Media Development Loan Fund
|
||||
#
|
||||
# This file is part of the Campcaster project.
|
||||
# http://campcaster.campware.org/
|
||||
# To report bugs, send an e-mail to bugs@campware.org
|
||||
#
|
||||
# Campcaster is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Campcaster 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Campcaster; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
#
|
||||
# Author : $Author$
|
||||
# Version : $Revision$
|
||||
# Location : $URL$
|
||||
#-------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# This script generates code coverage data for the module
|
||||
#-------------------------------------------------------------------------------
|
||||
module="Campcaster GstreamerElements"
|
||||
|
||||
reldir=`dirname $0`/..
|
||||
basedir=`cd $reldir; pwd;`
|
||||
bindir=$basedir/bin
|
||||
docdir=$basedir/doc
|
||||
tmpdir=$basedir/tmp
|
||||
|
||||
usrdir=`cd $basedir/../../../usr; pwd;`
|
||||
|
||||
coverage_report_dir=$docdir/coverage
|
||||
|
||||
raw_coverage_file=$tmpdir/raw_coverage.info
|
||||
coverage_file=$tmpdir/coverage.info
|
||||
|
||||
lcov=$usrdir/bin/lcov
|
||||
genhtml=$usrdir/bin/genhtml
|
||||
|
||||
|
||||
cd $basedir
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Re-configure with covarege collection enabled, compile and run the tests
|
||||
#-------------------------------------------------------------------------------
|
||||
$bindir/autogen.sh --enable-coverage
|
||||
make clean
|
||||
make check
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Generate some symlinks so that the sources are visible from tmpdir
|
||||
#-------------------------------------------------------------------------------
|
||||
ln -s $basedir/include $tmpdir/include
|
||||
ln -s $basedir/src $tmpdir/src
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Use lcov to generate an HTML report on the coverage data
|
||||
#-------------------------------------------------------------------------------
|
||||
$lcov -d $tmpdir -c > $raw_coverage_file
|
||||
$lcov -e $raw_coverage_file "$tmpdir/*" > $coverage_file
|
||||
rm -rf $coverage_report_dir
|
||||
mkdir -p $coverage_report_dir
|
||||
$genhtml -t "$module" -o $coverage_report_dir $coverage_file
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Clean up
|
||||
#-------------------------------------------------------------------------------
|
||||
rm -f $tmpdir/include
|
||||
rm -f $tmpdir/src
|
|
@ -1,64 +0,0 @@
|
|||
#!/bin/bash
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2004 Media Development Loan Fund
|
||||
#
|
||||
# This file is part of the Campcaster project.
|
||||
# http://campcaster.campware.org/
|
||||
# To report bugs, send an e-mail to bugs@campware.org
|
||||
#
|
||||
# Campcaster is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Campcaster 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Campcaster; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
#
|
||||
# Author : $Author$
|
||||
# Version : $Revision$
|
||||
# Location : $URL$
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Play an audio file by using gstreamer and autoplugging.
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# assume we're in $basedir/bin
|
||||
reldir=`dirname $0`/..
|
||||
basedir=`cd $reldir; pwd;`
|
||||
test -z "$basedir" && basedir=.
|
||||
usrdir=`cd $basedir/../../../usr; pwd;`
|
||||
|
||||
bindir=$basedir/bin
|
||||
etcdir=$basedir/etc
|
||||
libdir=$basedir/lib
|
||||
tmpdir=$basedir/tmp
|
||||
|
||||
play=$tmpdir/play
|
||||
|
||||
|
||||
export CPPFLAGS="-I$usrdir/include"
|
||||
export LDFLAGS="-L$usrdir/lib"
|
||||
export PKG_CONFIG_PATH="$usrdir/lib/pkgconfig"
|
||||
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$usrdir/lib"
|
||||
export GST_PLUGIN_PATH="$libdir"
|
||||
|
||||
|
||||
if [ ! -f $play ]; then
|
||||
echo "first build the play executable by issuing the following command:";
|
||||
echo "";
|
||||
echo "make all";
|
||||
|
||||
exit -1;
|
||||
fi
|
||||
|
||||
|
||||
$play "$*"
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2004 Media Development Loan Fund
|
||||
#
|
||||
# This file is part of the Campcaster project.
|
||||
# http://campcaster.campware.org/
|
||||
# To report bugs, send an e-mail to bugs@campware.org
|
||||
#
|
||||
# Campcaster is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Campcaster 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Campcaster; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
#
|
||||
# Author : $Author$
|
||||
# Version : $Revision$
|
||||
# Location : $URL$
|
||||
#
|
||||
# @configure_input@
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# General command definitions
|
||||
#-------------------------------------------------------------------------------
|
||||
MKDIR = mkdir -p
|
||||
RM = rm -f
|
||||
RMDIR = rm -rf
|
||||
DOXYGEN = doxygen
|
||||
CP = cp -f
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Basic directory and file definitions
|
||||
#-------------------------------------------------------------------------------
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
|
||||
BASE_DIR = @builddir@
|
||||
DOC_DIR = ${BASE_DIR}/doc
|
||||
DOXYGEN_DIR = ${DOC_DIR}/doxygen
|
||||
COVERAGE_DIR = ${DOC_DIR}/coverage
|
||||
ETC_DIR = ${BASE_DIR}/etc
|
||||
INCLUDE_DIR = ${BASE_DIR}/include
|
||||
LIB_DIR = ${BASE_DIR}/lib
|
||||
SRC_DIR = ${BASE_DIR}/src
|
||||
TMP_DIR = ${BASE_DIR}/tmp
|
||||
VAR_DIR = ${BASE_DIR}/var
|
||||
|
||||
REAL_BASE_DIR=$(shell cd ${BASE_DIR}; pwd)
|
||||
|
||||
|
||||
prefix = @prefix@
|
||||
|
||||
USR_DIR = ${prefix}
|
||||
USR_INCLUDE_DIR = ${USR_DIR}/include
|
||||
USR_BIN_DIR = ${USR_DIR}/bin
|
||||
USR_LIB_DIR = ${USR_DIR}/lib
|
||||
|
||||
MODULES_DIR = ${BASE_DIR}/..
|
||||
|
||||
CORE_DIR = ${MODULES_DIR}/core
|
||||
CORE_INCLUDE_DIR = ${CORE_DIR}/include
|
||||
CORE_LIB_DIR = ${CORE_DIR}/lib
|
||||
CORE_LIB = livesupport_core
|
||||
CORE_LIB_FILE = ${CORE_LIB_DIR}/lib${CORE_LIB}.a
|
||||
|
||||
VPATH = ${SRC_DIR}
|
||||
|
||||
BOOST_CFLAGS=@BOOST_CPPFLAGS@
|
||||
BOOST_LIBS=@BOOST_LDFLAGS@
|
||||
BOOST_DATE_TIME_LIB=@BOOST_DATE_TIME_LIB@
|
||||
|
||||
GSTREAMER_CFLAGS=@GSTREAMER_CFLAGS@
|
||||
GSTREAMER_LIBS=@GSTREAMER_LIBS@
|
||||
GST_REGISTER=@GST_REGISTER@
|
||||
|
||||
TEST_RESULTS = ${DOC_DIR}/testResults.xml
|
||||
# the text result XSLT has to be relative to the test result file, e.g. TMP_DIR
|
||||
TEST_XSLT = ../etc/testResultToHtml.xsl
|
||||
|
||||
GSTREAMER_ELEMENTS_LIB = livesupport_gstreamerelements
|
||||
GSTREAMER_ELEMENTS_LIB_FILE = ${LIB_DIR}/lib${GSTREAMER_ELEMENTS_LIB}.a
|
||||
|
||||
ONESHOT_READER_LIB = livesupport_oneshotreader
|
||||
ONESHOT_READER_LIB_FILE = ${LIB_DIR}/lib${ONESHOT_READER_LIB}.so
|
||||
MINIMAL_AUDIO_SMIL_LIB = livesupport_minimalaudiosmil
|
||||
MINIMAL_AUDIO_SMIL_LIB_FILE = ${LIB_DIR}/lib${MINIMAL_AUDIO_SMIL_LIB}.so
|
||||
PARTIAL_PLAY_LIB = livesupport_partialplay
|
||||
PARTIAL_PLAY_LIB_FILE = ${LIB_DIR}/lib${PARTIAL_PLAY_LIB}.so
|
||||
SWITCHER_LIB = livesupport_switcher
|
||||
SWITCHER_LIB_FILE = ${LIB_DIR}/lib${SWITCHER_LIB}.so
|
||||
|
||||
TEST_RUNNER = ${TMP_DIR}/testRunner
|
||||
PLAY = ${TMP_DIR}/play
|
||||
|
||||
DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
|
||||
|
||||
export LD_LIBRARY_PATH:=${USR_LIB_DIR}:${LD_LIBRARY_PATH}
|
||||
export GST_PLUGIN_PATH=${REAL_BASE_DIR}/lib
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configuration parameters
|
||||
#-------------------------------------------------------------------------------
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@ @DEFS@ @COVERAGE_CXXFLAGS@ -pthread \
|
||||
-pedantic -Wall -std=c99 -Wno-long-long \
|
||||
-fPIC -DPIC \
|
||||
${GSTREAMER_CFLAGS} \
|
||||
-I${USR_INCLUDE_DIR} \
|
||||
-I${INCLUDE_DIR} -I${TMP_DIR}
|
||||
CXXFLAGS = @CXXFLAGS@ @DEFS@ @COVERAGE_CXXFLAGS@ -pthread \
|
||||
-Wall -Wno-long-long \
|
||||
${BOOST_CFLAGS} \
|
||||
${GSTREAMER_CFLAGS} \
|
||||
-I${USR_INCLUDE_DIR} \
|
||||
-I${CORE_INCLUDE_DIR} \
|
||||
-I${INCLUDE_DIR} -I${TMP_DIR}
|
||||
GST_LDFLAGS = @LDFLAGS@ ${GSTREAMER_LIBS} \
|
||||
-L${USR_LIB_DIR} \
|
||||
-L${LIB_DIR}
|
||||
LDFLAGS = @LDFLAGS@ ${GSTREAMER_LIBS} \
|
||||
${BOOST_LIBS} \
|
||||
-L${USR_LIB_DIR} \
|
||||
-L${CORE_LIB_DIR} \
|
||||
-L${LIB_DIR}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Dependencies
|
||||
#-------------------------------------------------------------------------------
|
||||
GSTREAMER_ELEMENTS_LIB_OBJS = ${TMP_DIR}/seek.o \
|
||||
${TMP_DIR}/util.o \
|
||||
${TMP_DIR}/seek-pack.o \
|
||||
${TMP_DIR}/autoplug.o \
|
||||
${TMP_DIR}/smil-util.o
|
||||
|
||||
ONESHOT_READER_LIB_OBJS = ${TMP_DIR}/oneshot-reader.o
|
||||
|
||||
MINIMAL_AUDIO_SMIL_LIB_OBJS = ${TMP_DIR}/minimal-audio-smil.o
|
||||
|
||||
PARTIAL_PLAY_LIB_OBJS = ${TMP_DIR}/partial-play.o
|
||||
|
||||
SWITCHER_LIB_OBJS = ${TMP_DIR}/switcher.o
|
||||
|
||||
TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
|
||||
${TMP_DIR}/AutoplugTest.o
|
||||
DONT_TEST= ${TMP_DIR}/AutoplugTest.o \
|
||||
${TMP_DIR}/SeekTest.o \
|
||||
${TMP_DIR}/SwitcherTest.o \
|
||||
${TMP_DIR}/SeekPackTest.o \
|
||||
${TMP_DIR}/PartialPlayTest.o \
|
||||
${TMP_DIR}/OneshotReaderTest.o \
|
||||
${TMP_DIR}/MinimalAudioSmilTest.o
|
||||
|
||||
TEST_RUNNER_LIBS = -l${GSTREAMER_ELEMENTS_LIB} -l${CORE_LIB} \
|
||||
${BOOST_DATE_TIME_LIB} \
|
||||
-lcppunit -ldl -lxmlrpc++
|
||||
|
||||
PLAY_OBJS = ${TMP_DIR}/play.o
|
||||
|
||||
PLAY_LIBS = -l${GSTREAMER_ELEMENTS_LIB} -l${CORE_LIB}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Targets
|
||||
#-------------------------------------------------------------------------------
|
||||
.PHONY: all dir_setup doc clean docclean depclean distclean check install
|
||||
|
||||
all: dir_setup ${GSTREAMER_ELEMENTS_LIB_FILE} \
|
||||
${ONESHOT_READER_LIB_FILE} \
|
||||
${MINIMAL_AUDIO_SMIL_LIB_FILE} \
|
||||
${PARTIAL_PLAY_LIB_FILE} \
|
||||
${SWITCHER_LIB_FILE} \
|
||||
${PLAY} \
|
||||
gst_register
|
||||
|
||||
dir_setup: ${TMP_DIR} ${DOXYGEN_DIR}
|
||||
|
||||
|
||||
gst_register:
|
||||
${GST_REGISTER} > /dev/null 2>&1
|
||||
|
||||
doc:
|
||||
${DOXYGEN} ${DOXYGEN_CONFIG}
|
||||
|
||||
clean:
|
||||
${RM} ${GSTREAMER_ELEMENTS_LIB_OBJS} ${GSTREAMER_ELEMENTS_LIB_FILE}
|
||||
${RM} ${ONESHOT_READER_LIB_OBJS} ${ONESHOT_READER_LIB_FILE}
|
||||
${RM} ${MINIMAL_AUDIO_SMIL_LIB_OBJS} ${MINIMAL_AUDIO_SMIL_LIB_FILE}
|
||||
${RM} ${PARTIAL_PLAY_LIB_OBJS} ${PARTIAL_PLAY_LIB_FILE}
|
||||
${RM} ${SWITCHER_LIB_OBJS} ${SWITCHER_LIB_FILE}
|
||||
${RM} ${TEST_RUNNER_OBJS} ${TEST_RUNNER_RES} ${TEST_RUNNER}
|
||||
${RM} ${PLAY_OBJS} ${PLAY}
|
||||
${RM} ${TMP_DIR}/*.bb ${TMP_DIR}/*.bbg ${TMP_DIR}/*.da ${TMP_DIR}/*.info
|
||||
|
||||
docclean:
|
||||
${RMDIR} ${DOXYGEN_DIR}/html
|
||||
${RMDIR} ${COVERAGE_DIR}/*
|
||||
${RM} ${TEST_RESULTS}
|
||||
|
||||
depclean: clean
|
||||
|
||||
distclean: clean docclean
|
||||
${RMDIR} ${TMP_DIR}/config* ${TMP_DIR}/autom4te* ${TMP_DIR}/ac*.m4
|
||||
|
||||
check: all ${TEST_RUNNER}
|
||||
${TEST_RUNNER} -o ${TEST_RESULTS} -s ${TEST_XSLT}
|
||||
|
||||
install: all
|
||||
${MKDIR} ${USR_INCLUDE_DIR}/LiveSupport/GstreamerElements
|
||||
${CP} ${INCLUDE_DIR}/LiveSupport/GstreamerElements/*.h \
|
||||
${USR_INCLUDE_DIR}/LiveSupport/GstreamerElements
|
||||
${CP} ${GSTREAMER_ELEMENTS_LIB_FILE} \
|
||||
${ONESHOT_READER_LIB_FILE} \
|
||||
${MINIMAL_AUDIO_SMIL_LIB_FILE} \
|
||||
${PARTIAL_PLAY_LIB_FILE} \
|
||||
${SWITCHER_LIB_FILE} \
|
||||
${USR_LIB_DIR}
|
||||
-GST_PLUGIN_PATH=${USR_LIB_DIR} ${GST_REGISTER}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Specific targets
|
||||
#-------------------------------------------------------------------------------
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}: ${GSTREAMER_ELEMENTS_LIB_OBJS}
|
||||
${AR} crus $@ $^
|
||||
|
||||
${ONESHOT_READER_LIB_FILE}: ${ONESHOT_READER_LIB_OBJS} \
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}
|
||||
${CC} -shared -o $@ $^ ${GST_LDFLAGS}
|
||||
|
||||
${MINIMAL_AUDIO_SMIL_LIB_FILE}: ${MINIMAL_AUDIO_SMIL_LIB_OBJS} \
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}
|
||||
${CC} -shared -o $@ $^ ${GST_LDFLAGS}
|
||||
|
||||
${PARTIAL_PLAY_LIB_FILE}: ${PARTIAL_PLAY_LIB_OBJS} \
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}
|
||||
${CC} -shared -o $@ $^ ${GST_LDFLAGS}
|
||||
|
||||
${SWITCHER_LIB_FILE}: ${SWITCHER_LIB_OBJS} \
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}
|
||||
${CC} -shared -o $@ $^ ${GST_LDFLAGS}
|
||||
|
||||
${TMP_DIR}:
|
||||
${MKDIR} ${TMP_DIR}
|
||||
|
||||
${DOXYGEN_DIR}:
|
||||
${MKDIR} ${DOXYGEN_DIR}
|
||||
|
||||
${TEST_RUNNER}: ${CORE_LIB_FILE} ${GSTREAMER_ELEMENTS_LIB_FILE} \
|
||||
${TEST_RUNNER_OBJS}
|
||||
${CXX} ${LDFLAGS} -o $@ ${TEST_RUNNER_OBJS} ${TEST_RUNNER_LIBS}
|
||||
|
||||
${PLAY}: ${CORE_LIB_FILE} ${GSTREAMER_ELEMENTS_LIB_FILE} ${PLAY_OBJS}
|
||||
${CXX} ${LDFLAGS} -o $@ ${PLAY_OBJS} ${PLAY_LIBS}
|
||||
|
||||
${CORE_LIB_FILE}:
|
||||
${MAKE} -C ${CORE_DIR}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Pattern rules
|
||||
#-------------------------------------------------------------------------------
|
||||
${TMP_DIR}/%.o : ${SRC_DIR}/%.c
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} -c -o $@ $<
|
||||
|
||||
${TMP_DIR}/%.o : ${SRC_DIR}/%.cxx
|
||||
${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $<
|
||||
|
|
@ -1,407 +0,0 @@
|
|||
dnl-----------------------------------------------------------------------------
|
||||
dnl Copyright (c) 2004 Media Development Loan Fund
|
||||
dnl
|
||||
dnl This file is part of the Campcaster project.
|
||||
dnl http://campcaster.campware.org/
|
||||
dnl To report bugs, send an e-mail to bugs@campware.org
|
||||
dnl
|
||||
dnl Campcaster is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl Campcaster is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with Campcaster; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
dnl
|
||||
dnl
|
||||
dnl Author : $Author$
|
||||
dnl Version : $Revision$
|
||||
dnl Location : $URL$
|
||||
dnl-----------------------------------------------------------------------------
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl Macro to check for available modules using pkg-conf
|
||||
dnl
|
||||
dnl usage:
|
||||
dnl PKG_CHECK_MODULES(GSTUFF,[gtk+-2.0 >= 1.3], action-if, action-not)
|
||||
dnl
|
||||
dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
|
||||
dnl also defines GSTUFF_PKG_ERRORS on error
|
||||
dnl
|
||||
dnl This function was taken from the glade-- project
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_MODULES], [
|
||||
succeeded=no
|
||||
|
||||
if test -z "$PKG_CONFIG"; then
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||
fi
|
||||
|
||||
if test "$PKG_CONFIG" = "no" ; then
|
||||
echo "*** The pkg-config script could not be found. Make sure it is"
|
||||
echo "*** in your path, or set the PKG_CONFIG environment variable"
|
||||
echo "*** to the full path to pkg-config."
|
||||
echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
|
||||
else
|
||||
PKG_CONFIG_MIN_VERSION=0.9.0
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
|
||||
AC_MSG_CHECKING(for $2)
|
||||
|
||||
if $PKG_CONFIG --exists "$2" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
succeeded=yes
|
||||
|
||||
AC_MSG_CHECKING($1_CFLAGS)
|
||||
$1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
|
||||
AC_MSG_RESULT($$1_CFLAGS)
|
||||
|
||||
AC_MSG_CHECKING($1_LIBS)
|
||||
$1_LIBS=`$PKG_CONFIG --libs "$2"`
|
||||
AC_MSG_RESULT($$1_LIBS)
|
||||
else
|
||||
$1_CFLAGS=""
|
||||
$1_LIBS=""
|
||||
## If we have a custom action on failure, don't print errors, but
|
||||
## do set a variable so people can do so.
|
||||
$1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
|
||||
ifelse([$4], ,echo $$1_PKG_ERRORS,)
|
||||
fi
|
||||
|
||||
AC_SUBST($1_CFLAGS)
|
||||
AC_SUBST($1_LIBS)
|
||||
else
|
||||
echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
|
||||
echo "*** See http://www.freedesktop.org/software/pkgconfig"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $succeeded = yes; then
|
||||
ifelse([$3], , :, [$3])
|
||||
else
|
||||
ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl Macro to check for C++ namespaces
|
||||
dnl for more information on this macro, see
|
||||
dnl http://autoconf-archive.cryp.to/ac_cxx_namespaces.html
|
||||
dnl
|
||||
dnl usage:
|
||||
dnl If the compiler can prevent names clashes using namespaces,
|
||||
dnl define HAVE_NAMESPACES.
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_DEFUN([AC_CXX_NAMESPACES],
|
||||
[AC_CACHE_CHECK(whether the compiler implements namespaces,
|
||||
ac_cv_cxx_namespaces,
|
||||
[AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}],
|
||||
[using namespace Outer::Inner; return i;],
|
||||
ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no)
|
||||
AC_LANG_RESTORE
|
||||
])
|
||||
if test "$ac_cv_cxx_namespaces" = yes; then
|
||||
AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl Test for the Boost C++ libraries of a particular version (or newer).
|
||||
dnl for more information on boost, see http://www.boost.org/
|
||||
dnl for more information on this macro, see
|
||||
dnl http://autoconf-archive.cryp.to/ax_boost_base.html
|
||||
dnl
|
||||
dnl usage:
|
||||
dnl If no path to the installed boost library is given the macro searches
|
||||
dnl under ${prefix}, /usr, /usr/local, and /opt, and evaluates the $BOOST_ROOT
|
||||
dnl environment variable. Further documentation is available at
|
||||
dnl http://randspringer.de/boost/index.html
|
||||
dnl
|
||||
dnl This macro calls: AC_SUBST(BOOST_CPPFLAGS) and AC_SUBST(BOOST_LDFLAGS)
|
||||
dnl and sets: HAVE_BOOST
|
||||
dnl
|
||||
dnl Modified for Campcaster:
|
||||
dnl * --with-boost default changed to Yes;
|
||||
dnl * if the library is not found, it does not die, just prints "no", leaves
|
||||
dnl HAVE_BOOST undefined, and sets the BOOST_CPPFLAGS and BOOST_LDFLAGS
|
||||
dnl variables to "";
|
||||
dnl * ${prefix} is prepended to the search path.
|
||||
dnl
|
||||
dnl Author: Thomas Porschberg <thomas@randspringer.de>
|
||||
dnl
|
||||
dnl License:
|
||||
dnl Copyright © 2006 Thomas Porschberg <thomas@randspringer.de>
|
||||
dnl Copying and distribution of this file, with or without modification,
|
||||
dnl are permitted in any medium without royalty provided the copyright notice
|
||||
dnl and this notice are preserved.
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_DEFUN([AX_BOOST_BASE],
|
||||
[
|
||||
AC_ARG_WITH([boost],
|
||||
AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is Yes) - it is possible to specify the root directory for boost (optional)]),
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
want_boost="no"
|
||||
elif test "$withval" = "yes"; then
|
||||
want_boost="yes"
|
||||
ac_boost_path=""
|
||||
else
|
||||
want_boost="yes"
|
||||
ac_boost_path="$withval"
|
||||
fi
|
||||
],
|
||||
[want_boost="yes"])
|
||||
|
||||
if test "x$want_boost" = "xyes"; then
|
||||
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
|
||||
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
|
||||
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
|
||||
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
|
||||
boost_lib_version_req_sub_minor="0"
|
||||
fi
|
||||
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
|
||||
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
|
||||
succeeded=no
|
||||
|
||||
dnl first we check the system location for boost libraries
|
||||
dnl this location ist chosen if boost libraries are installed with the --layout=system option
|
||||
dnl or if you install boost with RPM
|
||||
if test "$ac_boost_path" != ""; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_path/lib"
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path/include"
|
||||
else
|
||||
for ac_boost_path_tmp in ${prefix} /usr /usr/local /opt ; do
|
||||
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
CPPFLAGS_SAVED="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
|
||||
LDFLAGS_SAVED="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <boost/version.hpp>
|
||||
]], [[
|
||||
#if BOOST_VERSION >= $WANT_BOOST_VERSION
|
||||
// Everything is okay
|
||||
#else
|
||||
# error Boost version is too old
|
||||
#endif
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
succeeded=yes
|
||||
found_system=yes
|
||||
],[
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
|
||||
|
||||
dnl if we found no boost with system layout we search for boost libraries
|
||||
dnl built and installed without the --layout=system option or for a staged(not installed) version
|
||||
if test "x$succeeded" != "xyes"; then
|
||||
_version=0
|
||||
if test "$ac_boost_path" != ""; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_path/lib"
|
||||
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
|
||||
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
|
||||
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
|
||||
V_CHECK=`expr $_version_tmp \> $_version`
|
||||
if test "$V_CHECK" = "1" ; then
|
||||
_version=$_version_tmp
|
||||
fi
|
||||
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
|
||||
done
|
||||
fi
|
||||
else
|
||||
for ac_boost_path in /usr /usr/local /opt ; do
|
||||
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
|
||||
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
|
||||
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
|
||||
V_CHECK=`expr $_version_tmp \> $_version`
|
||||
if test "$V_CHECK" = "1" ; then
|
||||
_version=$_version_tmp
|
||||
best_path=$ac_boost_path
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
|
||||
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
|
||||
BOOST_LDFLAGS="-L$best_path/lib"
|
||||
|
||||
if test "x$BOOST_ROOT" != "x"; then
|
||||
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
|
||||
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
|
||||
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
|
||||
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
|
||||
V_CHECK=`expr $stage_version_shorten \>\= $_version`
|
||||
if test "$V_CHECK" = "1" ; then
|
||||
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
|
||||
BOOST_CPPFLAGS="-I$BOOST_ROOT"
|
||||
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <boost/version.hpp>
|
||||
]], [[
|
||||
#if BOOST_VERSION >= $WANT_BOOST_VERSION
|
||||
// Everything is okay
|
||||
#else
|
||||
# error Boost version is too old
|
||||
#endif
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
succeeded=yes
|
||||
found_system=yes
|
||||
],[
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
|
||||
if test "$succeeded" != "yes" ; then
|
||||
BOOST_CPPFLAGS=""
|
||||
BOOST_LDFLAGS=""
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_SUBST(BOOST_CPPFLAGS)
|
||||
AC_SUBST(BOOST_LDFLAGS)
|
||||
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS_SAVED"
|
||||
LDFLAGS="$LDFLAGS_SAVED"
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl Test for Date_Time library from the Boost C++ libraries.
|
||||
dnl for more information on boost, see http://www.boost.org/
|
||||
dnl for more information on this macro, see
|
||||
dnl http://autoconf-archive.cryp.to/ax_boost_date_time.html
|
||||
dnl
|
||||
dnl usage:
|
||||
dnl The macro requires a preceding call to AX_BOOST_BASE.
|
||||
dnl Further documentation is available at
|
||||
dnl <http://randspringer.de/boost/index.html>.
|
||||
dnl
|
||||
dnl This macro calls: AC_SUBST(BOOST_DATE_TIME_LIB)
|
||||
dnl and sets: HAVE_BOOST_DATE_TIME
|
||||
dnl
|
||||
dnl Modified for Campcaster:
|
||||
dnl * --with-boost-date-time default changed to Yes.
|
||||
dnl * added some more recognized suffixes to the library's name, incl. "-st".
|
||||
dnl
|
||||
dnl Authors:
|
||||
dnl Thomas Porschberg <thomas@randspringer.de>
|
||||
dnl Michael Tindal <mtindal@paradoxpoint.com>
|
||||
dnl
|
||||
dnl License:
|
||||
dnl Copyright © 2006 Thomas Porschberg <thomas@randspringer.de>
|
||||
dnl Copying and distribution of this file, with or without modification,
|
||||
dnl are permitted in any medium without royalty provided the copyright notice
|
||||
dnl and this notice are preserved.
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_DEFUN([AX_BOOST_DATE_TIME],
|
||||
[
|
||||
AC_ARG_WITH([boost-date-time],
|
||||
AS_HELP_STRING([--with-boost-date-time@<:@=special-lib@:>@],
|
||||
[use the Date_Time library from boost - it is possible to specify a certain library for the linker
|
||||
e.g. --with-boost-date-time=boost_date_time-gcc-mt-d-1_33_1 ]),
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
want_boost="no"
|
||||
elif test "$withval" = "yes"; then
|
||||
want_boost="yes"
|
||||
ax_boost_user_date_time_lib=""
|
||||
else
|
||||
want_boost="yes"
|
||||
ax_boost_user_date_time_lib="$withval"
|
||||
fi
|
||||
],
|
||||
[want_boost="yes"]
|
||||
)
|
||||
|
||||
if test "x$want_boost" = "xyes"; then
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
CPPFLAGS_SAVED="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
|
||||
LDFLAGS_SAVED="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_CACHE_CHECK(whether the Boost::Date_Time library is available,
|
||||
ax_cv_boost_date_time,
|
||||
[AC_LANG_PUSH([C++])
|
||||
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include <boost/date_time/gregorian/gregorian_types.hpp>]],
|
||||
[[using namespace boost::gregorian; date d(2002,Jan,10);
|
||||
return 0;
|
||||
]]),
|
||||
ax_cv_boost_date_time=yes, ax_cv_boost_date_time=no)
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
if test "x$ax_cv_boost_date_time" = "xyes"; then
|
||||
AC_DEFINE(HAVE_BOOST_DATE_TIME,,[define if the Boost::Date_Time library is available])
|
||||
BN=boost_date_time
|
||||
if test "x$ax_boost_user_date_time_lib" = "x"; then
|
||||
for ax_lib in $BN $BN-st $BN-mt $BN-mt-s $BN-s \
|
||||
$BN-$CC $BN-$CC-st $BN-$CC-mt $BN-$CC-mt-s $BN-$CC-s \
|
||||
lib$BN lib$BN-st lib$BN-mt lib$BN-mt-s lib$BN-s \
|
||||
lib$BN-$CC lib$BN-$CC-st lib$BN-$CC-mt lib$BN-$CC-mt-s lib$BN-$CC-s \
|
||||
$BN-mgw $BN-mgw $BN-mgw-st $BN-mgw-mt $BN-mgw-mt-s $BN-mgw-s ; do
|
||||
AC_CHECK_LIB($ax_lib, main, [BOOST_DATE_TIME_LIB="-l$ax_lib" AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes" break],
|
||||
[link_date_time="no"])
|
||||
done
|
||||
else
|
||||
for ax_lib in $ax_boost_user_date_time_lib $BN-$ax_boost_user_date_time_lib; do
|
||||
AC_CHECK_LIB($ax_lib, main,
|
||||
[BOOST_DATE_TIME_LIB="-l$ax_lib" AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes" break],
|
||||
[link_date_time="no"])
|
||||
done
|
||||
|
||||
fi
|
||||
if test "x$link_date_time" = "xno"; then
|
||||
AC_MSG_ERROR(Could not link against $ax_lib !)
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS_SAVED"
|
||||
LDFLAGS="$LDFLAGS_SAVED"
|
||||
fi
|
||||
])
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
dnl-----------------------------------------------------------------------------
|
||||
dnl Copyright (c) 2004 Media Development Loan Fund
|
||||
dnl
|
||||
dnl This file is part of the Campcaster project.
|
||||
dnl http://campcaster.campware.org/
|
||||
dnl To report bugs, send an e-mail to bugs@campware.org
|
||||
dnl
|
||||
dnl Campcaster is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl Campcaster is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with Campcaster; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
dnl
|
||||
dnl
|
||||
dnl Author : $Author$
|
||||
dnl Version : $Revision$
|
||||
dnl Location : $URL$
|
||||
dnl-----------------------------------------------------------------------------
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl NOTE: Run all configure related scripts from the tmp directory of the
|
||||
dnl project.
|
||||
dnl This is due to the fact that configure spreads a lot of trash around,
|
||||
dnl like atom4te cache directories, config.* files, etc. into the directory
|
||||
dnl it is being run from. We clearly don't want these in our base directory.
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_INIT(GstreamerElements, 0.0, bugs@campware.org)
|
||||
AC_PREREQ(2.59)
|
||||
AC_COPYRIGHT([Copyright (c) 2004 Media Development Loan Fund under the GNU GPL])
|
||||
AC_REVISION($Revision$)
|
||||
|
||||
AC_CONFIG_SRCDIR(../src/oneshot-reader.c)
|
||||
|
||||
AC_CONFIG_HEADERS(configure.h)
|
||||
AC_PROG_CC()
|
||||
AC_PROG_CXX()
|
||||
|
||||
AC_CHECK_HEADERS(string.h getopt.h sys/time.h)
|
||||
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl specify whether debug info should be compiled into the executable
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_SUBST(CXXFLAGS)
|
||||
|
||||
AC_ARG_ENABLE([debug],
|
||||
AC_HELP_STRING([--enable-debug], [compile with debug info (no)]),
|
||||
[],
|
||||
[enable_debug=no])
|
||||
|
||||
if test "x${enable_debug}" = "xyes"; then
|
||||
CXXFLAGS="-g -O0"
|
||||
AC_DEFINE( YDEBUG, 1, [Debug is on] )
|
||||
else
|
||||
CXXFLAGS="-O3"
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_RESULT([using compiler options: ${CXXFLAGS}])
|
||||
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl specify the pkg-config path
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_ARG_WITH([pkg-config-path],
|
||||
AC_HELP_STRING([--with-pkg-config-path],
|
||||
[use the pkg-config path (prefix/lib/pkgconfig)]),
|
||||
[PKG_CONFIG_PATH=${withval}],
|
||||
[PKG_CONFIG_PATH=${prefix}/lib/pkgconfig:$PKG_CONFIG_PATH])
|
||||
|
||||
AC_MSG_RESULT([using pkg-config path: ${PKG_CONFIG_PATH}])
|
||||
|
||||
export PKG_CONFIG_PATH
|
||||
|
||||
export PATH=${prefix}/bin:${PATH}
|
||||
|
||||
AX_BOOST_BASE([1.33.1])
|
||||
if test "x${BOOST_CPPFLAGS}" != "x"; then
|
||||
AX_BOOST_DATE_TIME
|
||||
if test "x${BOOST_DATE_TIME_LIB}" = "x"; then
|
||||
AC_MSG_ERROR([Boost date-time library not found])
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([Boost library >= 1.33.1 not found])
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(GSTREAMER,[gstreamer-0.8 >= 0.8])
|
||||
AC_SUBST(GSTREAMER_CFLAGS)
|
||||
AC_SUBST(GSTREAMER_LIBS)
|
||||
|
||||
AC_PATH_PROG(GST_REGISTER, gst-register-0.8)
|
||||
AC_SUBST(GST_REGISTER)
|
||||
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl enable compilaton for code coverage data
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_SUBST(COVERAGE_CXXFLAGS)
|
||||
|
||||
AC_ARG_ENABLE( coverage,
|
||||
[ --enable-coverage enable code coverage data generaton (no) ],
|
||||
ENABLE_COVERAGE=${enableval}, ENABLE_COVERAGE="no" )
|
||||
|
||||
if test "x${ENABLE_COVERAGE}" == "xyes" ; then
|
||||
COVERAGE_CXXFLAGS="-fprofile-arcs -ftest-coverage"
|
||||
AC_MSG_RESULT([compiling in code coverage mode])
|
||||
else
|
||||
AC_MSG_RESULT([not compiling in code coverage mode])
|
||||
fi
|
||||
|
||||
|
||||
AC_CONFIG_FILES(../Makefile:../etc/Makefile.in)
|
||||
|
||||
AC_OUTPUT()
|
File diff suppressed because it is too large
Load Diff
|
@ -1,98 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef LiveSupport_GstreamerElements_Autoplug_h
|
||||
#define LiveSupport_GstreamerElements_Autoplug_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functions for autoplugging gstreamer elements based on their MIME types.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Autoplug a source element, that contains some form of audio.
|
||||
* The result will be a gstreamer element, that is linked with
|
||||
* source, and produces raw audio on its src pad as it output.
|
||||
*
|
||||
* @param source the source to autoplug.
|
||||
* @param name the name of the new element.
|
||||
* @param caps the capabilities expected from the returned element,
|
||||
* on its src pad.
|
||||
* @return a gstreamer element already linked to source, that produces
|
||||
* the audio provided by source in audio/x-raw-int or
|
||||
* audio/x-raw-float format, as needed.
|
||||
*/
|
||||
GstElement *
|
||||
ls_gst_autoplug_plug_source(GstElement * source,
|
||||
const gchar * name,
|
||||
const GstCaps * caps);
|
||||
|
||||
/**
|
||||
* Return the current position in a previously autoplugged element.
|
||||
* This is a workaround function, as querying the element returned by
|
||||
* ls_gst_autoplug_plug_source() with the standard gstreamer calls
|
||||
* will not give satisfactory results.
|
||||
*
|
||||
* @param element a GstElement that was returned by a previous call to
|
||||
* ls_gst_autoplug_plug_source()
|
||||
* @return the current position, in nanoseconds
|
||||
*/
|
||||
gint64
|
||||
ls_gst_autoplug_get_position(GstElement * element);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LiveSupport_GstreamerElements_Autoplug_h */
|
||||
|
|
@ -1 +0,0 @@
|
|||
keep me
|
|
@ -1,540 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "LiveSupport/GstreamerElements/autoplug.h"
|
||||
#include "AutoplugTest.h"
|
||||
|
||||
|
||||
using namespace boost::posix_time;
|
||||
using namespace LiveSupport::Core;
|
||||
using namespace LiveSupport::GstreamerElements;
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(AutoplugTest);
|
||||
|
||||
/**
|
||||
* Define this if time statistics should be printed while running tests.
|
||||
*/
|
||||
#undef PRINT_TIMES
|
||||
|
||||
/**
|
||||
* Define this if time statistics should be printed for each iteration.
|
||||
*/
|
||||
#undef PRINT_ITERATION_TIMES
|
||||
|
||||
|
||||
/**
|
||||
* An mp3 test file.
|
||||
*/
|
||||
static const char * mp3TestFile = "var/5seccounter.mp3";
|
||||
|
||||
/**
|
||||
* A 48 kHz mp3 test file.
|
||||
*/
|
||||
static const char * mp3_48kHzTestFile = "var/48kHz.mp3";
|
||||
|
||||
/**
|
||||
* An ogg vorbis test file.
|
||||
*/
|
||||
static const char * oggTestFile = "var/5seccounter.ogg";
|
||||
|
||||
/**
|
||||
* A 160kb/s ogg vorbis test file.
|
||||
*/
|
||||
static const char * ogg160kbpsTestFile = "var/d160.ogg";
|
||||
|
||||
/**
|
||||
* A SMIL test file.
|
||||
*/
|
||||
static const char * smilTestFile = "var/simple.smil";
|
||||
|
||||
/**
|
||||
* A SMIL test file, containing an ogg vorbis file.
|
||||
*/
|
||||
static const char * oggSmilFile = "var/simple-ogg.smil";
|
||||
|
||||
/**
|
||||
* A file we can't plug.
|
||||
*/
|
||||
static const char * badFile = "src/AutoplugTest.cxx";
|
||||
|
||||
/**
|
||||
* A very short file.
|
||||
*/
|
||||
static const char * shortFile = "var/test-short.mp3";
|
||||
|
||||
/**
|
||||
* A SMIL file referring to a very short file.
|
||||
*/
|
||||
static const char * shortSmilFile = "var/short.smil";
|
||||
|
||||
/**
|
||||
* An embedded SMIL file.
|
||||
*/
|
||||
static const char * embeddedSmilFile = "var/embedded.smil";
|
||||
|
||||
/**
|
||||
* A sequentially looking SMIL file.
|
||||
*/
|
||||
static const char * sequentialSmilFile = "var/sequentialSmil.smil";
|
||||
|
||||
/**
|
||||
* A long (in time) playlist
|
||||
*/
|
||||
static const char * longSmilFile = "var/bach.smil";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Signal handler for the eos event of the autoplug element.
|
||||
*
|
||||
* @param element the element emitting the eos signal
|
||||
* @param userData pointer to the container bin of the switcher.
|
||||
*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData);
|
||||
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: setUp(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clean up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: tearDown(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play an audio file
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
AutoplugTest :: playFile(const char * audioFile)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * source;
|
||||
GstElement * decoder;
|
||||
GstElement * sink;
|
||||
GstCaps * caps;
|
||||
gint64 timePlayed;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(0, 0);
|
||||
|
||||
caps = gst_caps_new_simple("audio/x-raw-int",
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"channels", G_TYPE_INT, 2,
|
||||
"rate", G_TYPE_INT, 44100,
|
||||
NULL);
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new("audio-player");
|
||||
source = gst_element_factory_make("filesrc", "source");
|
||||
sink = gst_element_factory_make("alsasink", "alsa-output");
|
||||
|
||||
g_object_set(G_OBJECT(source), "location", audioFile, NULL);
|
||||
|
||||
decoder = ls_gst_autoplug_plug_source(source, "decoder", caps);
|
||||
|
||||
if (!decoder) {
|
||||
gst_object_unref(GST_OBJECT(sink));
|
||||
gst_object_unref(GST_OBJECT(source));
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
g_signal_connect(decoder, "eos", G_CALLBACK(eos_signal_handler), pipeline);
|
||||
|
||||
gst_element_link(decoder, sink);
|
||||
gst_bin_add_many(GST_BIN(pipeline), source, decoder, sink, NULL);
|
||||
|
||||
gst_element_set_state(source, GST_STATE_PAUSED);
|
||||
gst_element_set_state(decoder, GST_STATE_PAUSED);
|
||||
gst_element_set_state(sink, GST_STATE_PAUSED);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
while (gst_bin_iterate(GST_BIN(pipeline))) {
|
||||
#ifdef PRINT_ITERATION_TIMES
|
||||
timePlayed = ls_gst_autoplug_get_position(decoder);
|
||||
std::cerr << "iteration time: " << timePlayed << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
timePlayed = ls_gst_autoplug_get_position(decoder);
|
||||
|
||||
/* clean up nicely */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return timePlayed;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* eos signal handler for the switcher element
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData)
|
||||
{
|
||||
GstElement * container = GST_ELEMENT(userData);
|
||||
|
||||
g_return_if_fail(container != NULL);
|
||||
g_return_if_fail(GST_IS_ELEMENT(container));
|
||||
|
||||
// set the container into eos state
|
||||
gst_element_set_eos(container);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Open an audio file
|
||||
*----------------------------------------------------------------------------*/
|
||||
Ptr<time_duration>::Ref
|
||||
AutoplugTest :: openFile(const char * audioFile)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * source;
|
||||
GstElement * decoder;
|
||||
GstElement * sink;
|
||||
GstCaps * caps;
|
||||
Ptr<ptime>::Ref start;
|
||||
Ptr<ptime>::Ref end;
|
||||
Ptr<time_duration>::Ref duration;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(0, 0);
|
||||
|
||||
caps = gst_caps_new_simple("audio/x-raw-int",
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"channels", G_TYPE_INT, 2,
|
||||
"rate", G_TYPE_INT, 44100,
|
||||
NULL);
|
||||
|
||||
start = TimeConversion::now();
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new("audio-player");
|
||||
source = gst_element_factory_make("filesrc", "source");
|
||||
sink = gst_element_factory_make("alsasink", "alsa-output");
|
||||
|
||||
g_object_set(G_OBJECT(source), "location", audioFile, NULL);
|
||||
|
||||
decoder = ls_gst_autoplug_plug_source(source, "decoder", caps);
|
||||
|
||||
if (!decoder) {
|
||||
gst_object_unref(GST_OBJECT(sink));
|
||||
gst_object_unref(GST_OBJECT(source));
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
gst_element_link(decoder, sink);
|
||||
gst_bin_add_many(GST_BIN(pipeline), source, decoder, sink, NULL);
|
||||
|
||||
gst_element_set_state(source, GST_STATE_PAUSED);
|
||||
gst_element_set_state(decoder, GST_STATE_PAUSED);
|
||||
gst_element_set_state(sink, GST_STATE_PAUSED);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
gst_bin_iterate(GST_BIN(pipeline));
|
||||
|
||||
end = TimeConversion::now();
|
||||
|
||||
/* clean up nicely */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
duration.reset(new time_duration(*end - *start));
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: firstTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3TestFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test a 48kHz mp3 file
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: mp3_48kHzTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3_48kHzTestFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 12.1 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 12.3 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* An ogg vorbis test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: oggVorbisTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(oggTestFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* An ogg vorbis test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: oggVorbis160kbpsTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(ogg160kbpsTestFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.1 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 2.4 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A SMIL test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: smilTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(smilTestFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test somethign we can't plug.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: negativeTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(badFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed == 0LL);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test on a very short file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: shortTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(shortFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 1.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 2.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test on a SMIL file referring to a very short file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: shortSmilTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(shortSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 1.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 2.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* See how long it takes to open some playlists
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: playlistOpenTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
Ptr<time_duration>::Ref duration;
|
||||
|
||||
duration = openFile(mp3TestFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << mp3TestFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = openFile(oggTestFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << oggTestFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = openFile(smilTestFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << smilTestFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = openFile(oggSmilFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << oggSmilFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = openFile(shortSmilFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << shortSmilFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = openFile(embeddedSmilFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << embeddedSmilFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = openFile(sequentialSmilFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << sequentialSmilFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = openFile(longSmilFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << longSmilFile << ": "
|
||||
<< *duration << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A test to see if play duration is reported properly.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
AutoplugTest :: playDurationTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 duration;
|
||||
|
||||
duration = playFile(mp3TestFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << mp3TestFile << ": "
|
||||
<< duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = playFile(sequentialSmilFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << sequentialSmilFile << ": "
|
||||
<< duration << std::endl;
|
||||
#endif
|
||||
|
||||
duration = playFile(embeddedSmilFile);
|
||||
#ifdef PRINT_TIMES
|
||||
std::cerr << "duration for " << embeddedSmilFile << ": "
|
||||
<< duration << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef AutoplugTest_h
|
||||
#define AutoplugTest_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
#include <LiveSupport/Core/Ptr.h>
|
||||
#include <LiveSupport/Core/TimeConversion.h>
|
||||
|
||||
|
||||
namespace LiveSupport {
|
||||
namespace GstreamerElements {
|
||||
|
||||
using namespace LiveSupport::Core;
|
||||
using namespace boost::posix_time;
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* Unit test for the partialplay gstreamer element.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class AutoplugTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(AutoplugTest);
|
||||
CPPUNIT_TEST(firstTest);
|
||||
CPPUNIT_TEST(mp3_48kHzTest);
|
||||
CPPUNIT_TEST(oggVorbisTest);
|
||||
CPPUNIT_TEST(oggVorbis160kbpsTest);
|
||||
CPPUNIT_TEST(smilTest);
|
||||
CPPUNIT_TEST(negativeTest);
|
||||
CPPUNIT_TEST(shortTest);
|
||||
CPPUNIT_TEST(shortSmilTest);
|
||||
CPPUNIT_TEST(playlistOpenTest);
|
||||
CPPUNIT_TEST(playDurationTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Play a specific file.
|
||||
*
|
||||
* @param audioFile the audio file to play.
|
||||
* @return the number of milliseconds played.
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
gint64
|
||||
playFile(const char * audioFile)
|
||||
throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Open a specific file. Used to measure the time it takes to
|
||||
* open files.
|
||||
*
|
||||
* @param audioFile the audio file to play.
|
||||
* @return the amount of time it took to open the file.
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
Ptr<time_duration>::Ref
|
||||
openFile(const char * audioFile)
|
||||
throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A simple smoke test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
firstTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test a 48kHz mp3 file
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3_48kHzTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test an Ogg Vorbis file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test a 160 kb/s Ogg Vorbis file.
|
||||
* See http://bugs.campware.org/view.php?id=1421 for details.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbis160kbpsTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test a SMIL file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A negative test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
negativeTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test on a very short file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
shortTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test on a SMIL file referring to a very short file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
shortSmilTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test to open playlists, for seeing how long it takes to open
|
||||
* them.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
playlistOpenTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test to see if play duration is reported properly.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
playDurationTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set up the environment for the test case.
|
||||
*/
|
||||
void
|
||||
setUp(void) throw ();
|
||||
|
||||
/**
|
||||
* Clean up the environment after the test case.
|
||||
*/
|
||||
void
|
||||
tearDown(void) throw ();
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
} // namespace GstreamerElements
|
||||
} // namespace LiveSupport
|
||||
|
||||
#endif // AutoplugTest_h
|
||||
|
|
@ -1,402 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#error need string.h
|
||||
#endif
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "MinimalAudioSmilTest.h"
|
||||
|
||||
|
||||
using namespace LiveSupport::GstreamerElements;
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(MinimalAudioSmilTest);
|
||||
|
||||
/**
|
||||
* A simple smil file.
|
||||
*/
|
||||
static const char * simpleFile = "var/simple.smil";
|
||||
|
||||
/**
|
||||
* A simple smil file with clipBegin and clipEnd attributes
|
||||
*/
|
||||
static const char * simpleClipBeginFile =
|
||||
"var/simple-clipBegin.smil";
|
||||
|
||||
/**
|
||||
* A simple smil file with clipBegin and clipEnd attributes
|
||||
*/
|
||||
static const char * simpleClipBeginEndFile =
|
||||
"var/simple-clipBegin-clipEnd.smil";
|
||||
|
||||
/**
|
||||
* A parallel smil file.
|
||||
*/
|
||||
static const char * parallelFile = "var/parallel.smil";
|
||||
|
||||
|
||||
/**
|
||||
* A parallel smil file with clipBegin and clipEnd attributes.
|
||||
*/
|
||||
static const char * parallelClipBeginEndFile =
|
||||
"var/parallel-clipBegin-clipEnd.smil";
|
||||
|
||||
/**
|
||||
* A SMIL file containing an Ogg Vorbis file.
|
||||
*/
|
||||
static const char * oggVorbisSmilFile = "var/simple-ogg.smil";
|
||||
|
||||
/**
|
||||
* A SMIL file containing another SMIL file.
|
||||
*/
|
||||
static const char * embeddedSmilFile = "var/embedded.smil";
|
||||
|
||||
/**
|
||||
* A SMIL file containing sound animation.
|
||||
*/
|
||||
static const char * soundAnimationSmilFile = "var/animateSound.smil";
|
||||
|
||||
/**
|
||||
* A SMIL file containing sound animation with two parallel files.
|
||||
*/
|
||||
static const char * soundAnimationParallelSmilFile =
|
||||
"var/animateSoundParallel.smil";
|
||||
|
||||
/**
|
||||
* A SMIL file containing sound animation in effect of a fade in / out.
|
||||
*/
|
||||
static const char * fadeInOutSmilFile = "var/fadeInOut.smil";
|
||||
|
||||
/**
|
||||
* A SMIL file containing sound animation in effect of a fade in / out,
|
||||
* with two overlapping audio files.
|
||||
*/
|
||||
static const char * fadeInOutParallelSmilFile =
|
||||
"var/fadeInOutParallel.smil";
|
||||
|
||||
/**
|
||||
* A SMIL file containing several audio elements in a par, that in effect
|
||||
* play sequentially.
|
||||
*/
|
||||
static const char * sequentialSmilFile =
|
||||
"var/sequentialSmil.smil";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: setUp(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clean up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: tearDown(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a SMIL file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
MinimalAudioSmilTest :: playSmilFile(const char * smilFile)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * filesrc;
|
||||
GstElement * smil;
|
||||
GstElement * sink;
|
||||
GstFormat format;
|
||||
gint64 timePlayed;
|
||||
|
||||
/* initialization */
|
||||
gst_init(0, 0);
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new("pipeline");
|
||||
filesrc = gst_element_factory_make("filesrc", "filesource");
|
||||
smil = gst_element_factory_make("minimalaudiosmil", "smil");
|
||||
sink = gst_element_factory_make("alsasink", "audiosink");
|
||||
|
||||
g_object_set(G_OBJECT(filesrc), "location", smilFile, NULL);
|
||||
|
||||
/* link everything together */
|
||||
gst_element_link_many(filesrc, smil, sink, NULL);
|
||||
gst_bin_add_many(GST_BIN(pipeline), filesrc, smil, sink, NULL);
|
||||
|
||||
/* run */
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
while (gst_bin_iterate(GST_BIN(pipeline)));
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_element_query(sink, GST_QUERY_POSITION, &format, &timePlayed);
|
||||
|
||||
/* clean up */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return timePlayed;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: firstTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(simpleFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple test with clipBegin attribute
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: simpleClipBeginTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(simpleClipBeginFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple test with clipBegin and clipEnd attributes
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: simpleClipBeginEndTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(simpleClipBeginEndFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test <par> SMIL elements
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: parallelTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(parallelFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 7.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 8.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test <par> SMIL elements with clipBegin and clipEnd attributes
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: parallelClipBeginEndTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(parallelClipBeginEndFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 7.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 8.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test a SMIL file pointing to an Ogg Vorbis file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: oggVorbisTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(oggVorbisSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test a SMIL file pointing to another SMIL file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: embeddedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(embeddedSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 9.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 10.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test a SMIL file containing sound level animation.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: soundAnimationTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(soundAnimationSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test a SMIL file containing sound level animation with two files in
|
||||
* parallel.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: soundAnimationParallelTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(soundAnimationParallelSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test a SMIL file containing sound level animation resulting in a fade
|
||||
* in / fade out effect.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: fadeInOutTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(fadeInOutSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Test a SMIL file containing sound level animation resulting in a fade
|
||||
* in / fade out effect, with two parallel files
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: fadeInOutParallelTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(fadeInOutParallelSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A sequential par element test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
MinimalAudioSmilTest :: sequentialSmilTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playSmilFile(sequentialSmilFile);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 34.7 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 35.0 * GST_SECOND);
|
||||
}
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef MinimalAudioSmilTest_h
|
||||
#define MinimalAudioSmilTest_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
|
||||
namespace LiveSupport {
|
||||
namespace GstreamerElements {
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* Unit test for the partialplay gstreamer element.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class MinimalAudioSmilTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(MinimalAudioSmilTest);
|
||||
CPPUNIT_TEST(firstTest);
|
||||
CPPUNIT_TEST(simpleClipBeginTest);
|
||||
CPPUNIT_TEST(simpleClipBeginEndTest);
|
||||
CPPUNIT_TEST(parallelTest);
|
||||
CPPUNIT_TEST(parallelClipBeginEndTest);
|
||||
CPPUNIT_TEST(oggVorbisTest);
|
||||
// disabled because this test hangs on some systems
|
||||
// CPPUNIT_TEST(embeddedTest);
|
||||
CPPUNIT_TEST(soundAnimationTest);
|
||||
CPPUNIT_TEST(soundAnimationParallelTest);
|
||||
CPPUNIT_TEST(fadeInOutTest);
|
||||
CPPUNIT_TEST(fadeInOutParallelTest);
|
||||
CPPUNIT_TEST(sequentialSmilTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Play a smil file.
|
||||
*
|
||||
* @param smilFile the name of the smil file to play.
|
||||
* @return the number of milliseconds played.
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
gint64
|
||||
playSmilFile(const char * smilFile)
|
||||
throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A simple smoke test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
firstTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple test with clipBegin attribute.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
simpleClipBeginTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple test with clipBegin and clipEnd attributes.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
simpleClipBeginEndTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test on <par> elements in a SMIL file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
parallelTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test on <par> elements in a SMIL file, with clipBegin and
|
||||
* clipEnd attributes.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
parallelClipBeginEndTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple test with a SMIL file referring to an Ogg Vorbis file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test looking at an embedded SMIL file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
embeddedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test sound level animation.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
soundAnimationTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test sound level animation with two parallel elements.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
soundAnimationParallelTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test fade in / fade out using sound level animation.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
fadeInOutTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test fade in / fade out using sound level animation,
|
||||
* with two parallel audio files.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
fadeInOutParallelTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A sequential par element test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
sequentialSmilTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set up the environment for the test case.
|
||||
*/
|
||||
void
|
||||
setUp(void) throw ();
|
||||
|
||||
/**
|
||||
* Clean up the environment after the test case.
|
||||
*/
|
||||
void
|
||||
tearDown(void) throw ();
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
} // namespace GstreamerElements
|
||||
} // namespace LiveSupport
|
||||
|
||||
#endif // MinimalAudioSmilTest_h
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#error need string.h
|
||||
#endif
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "OneshotReaderTest.h"
|
||||
|
||||
|
||||
using namespace LiveSupport::GstreamerElements;
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(OneshotReaderTest);
|
||||
|
||||
static const char * testFile = "var/oneshotReader.input";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
OneshotReaderTest :: setUp(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clean up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
OneshotReaderTest :: tearDown(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
OneshotReaderTest :: firstTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * filesrc;
|
||||
GstElement * oneshot;
|
||||
GstElement * bin;
|
||||
guint8 * contents;
|
||||
guint length;
|
||||
char * verifyContents;
|
||||
std::ifstream ifs;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(0, 0);
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new ("my_pipeline");
|
||||
|
||||
filesrc = gst_element_factory_make("filesrc", "my_filesource");
|
||||
oneshot = gst_element_factory_make("oneshotreader", "oneshot");
|
||||
bin = gst_bin_new("bin");
|
||||
|
||||
g_object_set(G_OBJECT(filesrc), "location", testFile, NULL);
|
||||
|
||||
gst_bin_add(GST_BIN(bin), oneshot);
|
||||
gst_element_add_ghost_pad(bin,
|
||||
gst_element_get_pad(oneshot, "sink"),
|
||||
"sink");
|
||||
|
||||
/* link everything together */
|
||||
gst_element_link_many(filesrc, bin, NULL);
|
||||
gst_bin_add_many(GST_BIN(pipeline), filesrc, bin, NULL);
|
||||
|
||||
/* run */
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
// well, actually don't run, by setting to state PLAYING,
|
||||
// we already have what we're looking for.
|
||||
while (gst_bin_iterate(GST_BIN(pipeline)));
|
||||
|
||||
g_object_get(G_OBJECT(oneshot), "contents", &contents, NULL);
|
||||
g_object_get(G_OBJECT(oneshot), "length", &length, NULL);
|
||||
|
||||
// read in the file contents with an ifstream, and see if
|
||||
// we get the same
|
||||
verifyContents = new char[length];
|
||||
ifs.open(testFile);
|
||||
CPPUNIT_ASSERT(ifs.good());
|
||||
ifs.read(verifyContents, length);
|
||||
CPPUNIT_ASSERT(!memcmp(contents, verifyContents, length));
|
||||
|
||||
/* clean up */
|
||||
delete[] verifyContents;
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef OneshotReaderTest_h
|
||||
#define OneshotReaderTest_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
|
||||
namespace LiveSupport {
|
||||
namespace GstreamerElements {
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* Unit test for the partialplay gstreamer element.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class OneshotReaderTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(OneshotReaderTest);
|
||||
CPPUNIT_TEST(firstTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A simple smoke test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
firstTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set up the environment for the test case.
|
||||
*/
|
||||
void
|
||||
setUp(void) throw ();
|
||||
|
||||
/**
|
||||
* Clean up the environment after the test case.
|
||||
*/
|
||||
void
|
||||
tearDown(void) throw ();
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
} // namespace GstreamerElements
|
||||
} // namespace LiveSupport
|
||||
|
||||
#endif // OneshotReaderTest_h
|
||||
|
|
@ -1,267 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "PartialPlayTest.h"
|
||||
|
||||
|
||||
using namespace LiveSupport::GstreamerElements;
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(PartialPlayTest);
|
||||
|
||||
/**
|
||||
* An mp3 test file.
|
||||
*/
|
||||
static const char * mp3File = "var/5seccounter.mp3";
|
||||
|
||||
/**
|
||||
* An ogg vorbis test file.
|
||||
*/
|
||||
static const char * oggVorbisFile = "var/5seccounter.ogg";
|
||||
|
||||
/**
|
||||
* A SMIL test file.
|
||||
*/
|
||||
static const char * smilFile = "var/simple.smil";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Signal handler for the eos event of the switcher element.
|
||||
*
|
||||
* @param element the element emitting the eos signal
|
||||
* @param userData pointer to the container bin of the switcher.
|
||||
*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: setUp(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clean up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: tearDown(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
PartialPlayTest :: playFile(const char * audioFile,
|
||||
const char * config)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * filter;
|
||||
GstElement * sink;
|
||||
GstFormat format;
|
||||
gint64 timePlayed;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(0, 0);
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new("audio-player");
|
||||
filter = gst_element_factory_make("partialplay", "partialplay");
|
||||
sink = gst_element_factory_make("alsasink", "alsa-output");
|
||||
|
||||
/* set filename property on the file source */
|
||||
g_object_set(G_OBJECT(filter), "location", audioFile, NULL);
|
||||
g_object_set(G_OBJECT(filter), "config", config, NULL);
|
||||
g_signal_connect(filter, "eos", G_CALLBACK(eos_signal_handler), pipeline);
|
||||
|
||||
gst_element_link(filter, sink);
|
||||
|
||||
gst_bin_add_many(GST_BIN(pipeline), filter, sink, NULL);
|
||||
|
||||
gst_element_set_state(filter, GST_STATE_READY);
|
||||
gst_element_set_state(sink, GST_STATE_READY);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
while (gst_bin_iterate(GST_BIN(pipeline)));
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_element_query(sink, GST_QUERY_POSITION, &format, &timePlayed);
|
||||
|
||||
/* clean up nicely */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT (pipeline));
|
||||
|
||||
return timePlayed;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* eos signal handler for the switcher element
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData)
|
||||
{
|
||||
GstElement * container = GST_ELEMENT(userData);
|
||||
|
||||
g_return_if_fail(container != NULL);
|
||||
g_return_if_fail(GST_IS_ELEMENT(container));
|
||||
|
||||
// set the container into eos state
|
||||
gst_element_set_eos(container);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: mp3Test(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3File, "2s;1s-4s");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Open ended test
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: mp3OpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3File, "2s;2s-");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: oggVorbisTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(oggVorbisFile, "2s;1s-4s");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Open ended test
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: oggVorbisOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(oggVorbisFile, "2s;2s-");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: smilTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(smilFile, "2s;1s-4s");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Open ended test
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
PartialPlayTest :: smilOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(smilFile, "2s;2s-");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef PartialPlayTest_h
|
||||
#define PartialPlayTest_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
|
||||
namespace LiveSupport {
|
||||
namespace GstreamerElements {
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* Unit test for the partialplay gstreamer element.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class PartialPlayTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(PartialPlayTest);
|
||||
CPPUNIT_TEST(mp3Test);
|
||||
CPPUNIT_TEST(mp3OpenEndedTest);
|
||||
CPPUNIT_TEST(oggVorbisTest);
|
||||
CPPUNIT_TEST(oggVorbisOpenEndedTest);
|
||||
CPPUNIT_TEST(smilTest);
|
||||
CPPUNIT_TEST(smilOpenEndedTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Play a file, with a specific partial play config.
|
||||
*
|
||||
* @param audioFile the file to play
|
||||
* @param config the partial play config to use when playing the file
|
||||
* @return the number of milliseconds played.
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
gint64
|
||||
playFile(const char * audioFile,
|
||||
const char * config)
|
||||
throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A simple mp3 smoke test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3Test(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* An open ended mp3 play test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3OpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple ogg vorbis smoke test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* An open ended ogg vorbis play test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple SMIL smoke test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* An open ended SMIL play test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set up the environment for the test case.
|
||||
*/
|
||||
void
|
||||
setUp(void) throw ();
|
||||
|
||||
/**
|
||||
* Clean up the environment after the test case.
|
||||
*/
|
||||
void
|
||||
tearDown(void) throw ();
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
} // namespace GstreamerElements
|
||||
} // namespace LiveSupport
|
||||
|
||||
#endif // PartialPlayTest_h
|
||||
|
|
@ -1,370 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "seek-pack.h"
|
||||
#include "SeekPackTest.h"
|
||||
|
||||
|
||||
using namespace LiveSupport::GstreamerElements;
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(SeekPackTest);
|
||||
|
||||
/**
|
||||
* An mp3 test file.
|
||||
*/
|
||||
static const char * mp3File = "var/5seccounter.mp3";
|
||||
|
||||
/**
|
||||
* An ogg vorbis test file.
|
||||
*/
|
||||
static const char * oggVorbisFile = "var/5seccounter.ogg";
|
||||
|
||||
/**
|
||||
* A smil test file.
|
||||
*/
|
||||
static const char * smilFile = "var/simple.smil";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Signal handler for the eos event of the switcher element.
|
||||
*
|
||||
* @param element the element emitting the eos signal
|
||||
* @param userData pointer to the container bin of the switcher.
|
||||
*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: setUp(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clean up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: tearDown(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
SeekPackTest :: playFile(const char * audioFile,
|
||||
gint64 silenceDuration,
|
||||
gint64 playFrom,
|
||||
gint64 playTo)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * source;
|
||||
LivesupportSeekPack * seekPack;
|
||||
GstCaps * caps;
|
||||
GstElement * sink;
|
||||
GstFormat format;
|
||||
gint64 timePlayed;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(0, 0);
|
||||
|
||||
caps = gst_caps_new_simple("audio/x-raw-int",
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"channels", G_TYPE_INT, 2,
|
||||
"rate", G_TYPE_INT, 44100,
|
||||
NULL);
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new("audio-player");
|
||||
source = gst_element_factory_make("filesrc", "filesource");
|
||||
seekPack = livesupport_seek_pack_new("seekPack", caps);
|
||||
sink = gst_element_factory_make("alsasink", "alsaoutput");
|
||||
|
||||
/* set filename property on the file source */
|
||||
g_object_set(G_OBJECT (source), "location", audioFile, NULL);
|
||||
|
||||
livesupport_seek_pack_init(seekPack,
|
||||
source,
|
||||
silenceDuration,
|
||||
playFrom,
|
||||
playTo);
|
||||
g_signal_connect(seekPack->bin,
|
||||
"eos",
|
||||
G_CALLBACK(eos_signal_handler),
|
||||
pipeline);
|
||||
|
||||
livesupport_seek_pack_link(seekPack, sink);
|
||||
|
||||
livesupport_seek_pack_add_to_bin(seekPack, GST_BIN(pipeline));
|
||||
gst_bin_add(GST_BIN(pipeline), sink);
|
||||
|
||||
gst_element_set_state(sink, GST_STATE_READY);
|
||||
livesupport_seek_pack_set_state(seekPack, GST_STATE_PLAYING);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
while (gst_bin_iterate(GST_BIN(pipeline)));
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_element_query(sink, GST_QUERY_POSITION, &format, &timePlayed);
|
||||
|
||||
/* clean up nicely */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
livesupport_seek_pack_destroy(seekPack);
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return timePlayed;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* eos signal handler for the switcher element
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData)
|
||||
{
|
||||
GstElement * container = GST_ELEMENT(userData);
|
||||
|
||||
g_return_if_fail(container != NULL);
|
||||
g_return_if_fail(GST_IS_ELEMENT(container));
|
||||
|
||||
// set the container into eos state
|
||||
gst_element_set_eos(container);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: mp3Test(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3File,
|
||||
2LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
3LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A test with no silence.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: mp3NoSilenceTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3File,
|
||||
0LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
3LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 1.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 2.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Open ended test
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: mp3OpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3File,
|
||||
2LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
-1LL);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 5.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 6.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple test with an ogg vorbis file
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: oggVorbisTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(oggVorbisFile,
|
||||
2LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
3LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A no silence test with an ogg vorbis file
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: oggVorbisNoSilenceTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(oggVorbisFile,
|
||||
0LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
3LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 1.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 2.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* An open ended test with an ogg vorbis file
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: oggVorbisOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(oggVorbisFile,
|
||||
2LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
-1LL);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple test with a SMIL file
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: smilTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(smilFile,
|
||||
2LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
3LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple test with a SMIL file, without silence
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: smilNoSilenceTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(smilFile,
|
||||
0LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
3LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 1.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 2.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple test with a SMIL file, playing until EOS
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekPackTest :: smilOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(smilFile,
|
||||
2LL * GST_SECOND,
|
||||
1LL * GST_SECOND,
|
||||
-1LL);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
|
@ -1,199 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef SeekPackTest_h
|
||||
#define SeekPackTest_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
|
||||
namespace LiveSupport {
|
||||
namespace GstreamerElements {
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* Unit test for the SeekPack structure.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class SeekPackTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(SeekPackTest);
|
||||
CPPUNIT_TEST(mp3Test);
|
||||
CPPUNIT_TEST(mp3NoSilenceTest);
|
||||
CPPUNIT_TEST(mp3OpenEndedTest);
|
||||
CPPUNIT_TEST(oggVorbisTest);
|
||||
CPPUNIT_TEST(oggVorbisNoSilenceTest);
|
||||
CPPUNIT_TEST(oggVorbisOpenEndedTest);
|
||||
CPPUNIT_TEST(smilTest);
|
||||
CPPUNIT_TEST(smilNoSilenceTest);
|
||||
CPPUNIT_TEST(smilOpenEndedTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Play a file, with a specific partial play config.
|
||||
*
|
||||
* @param audioFile the file to play
|
||||
* @param silenceDuration the amount of silence before playing
|
||||
* @param playFrom play the audio file from this offset
|
||||
* @param playTo play the audio file until this offset,
|
||||
* or -1LL if until the end.
|
||||
* @return the number of milliseconds played.
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
gint64
|
||||
playFile(const char * audioFile,
|
||||
gint64 silenceDuration,
|
||||
gint64 playFrom,
|
||||
gint64 playTo)
|
||||
throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A simple mp3 smoke test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3Test(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* An mp3 test with no silence.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3NoSilenceTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* An open ended mp3 play test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3OpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Try SeekPack on an ogg vorbis file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Try SeekPack on an ogg vorbis file, without playing silence.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisNoSilenceTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Try SeekPack on an ogg vorbis file, playing until EOS.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Try SeekPack on a SMIL file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Try SeekPack on a SMIL file, with no silence in the front.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilNoSilenceTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Try SeekPack on a SMIL file, playing until EOS.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set up the environment for the test case.
|
||||
*/
|
||||
void
|
||||
setUp(void) throw ();
|
||||
|
||||
/**
|
||||
* Clean up the environment after the test case.
|
||||
*/
|
||||
void
|
||||
tearDown(void) throw ();
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
} // namespace GstreamerElements
|
||||
} // namespace LiveSupport
|
||||
|
||||
#endif // SeekPackTest_h
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "LiveSupport/GstreamerElements/autoplug.h"
|
||||
#include "seek.h"
|
||||
#include "SeekTest.h"
|
||||
|
||||
|
||||
using namespace LiveSupport::GstreamerElements;
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(SeekTest);
|
||||
|
||||
/**
|
||||
* An mp3 test file.
|
||||
*/
|
||||
static const char * mp3File = "var/5seccounter.mp3";
|
||||
|
||||
/**
|
||||
* An Ogg Vorbis test file.
|
||||
*/
|
||||
static const char * oggVorbisFile = "var/5seccounter.ogg";
|
||||
|
||||
/**
|
||||
* An smil test file.
|
||||
*/
|
||||
static const char * smilFile = "var/simple.smil";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: setUp(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clean up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: tearDown(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play an audio file
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
SeekTest :: playFile(const char * audioFile,
|
||||
gint64 seekTo,
|
||||
gint64 playTo)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * source;
|
||||
GstElement * decoder;
|
||||
GstElement * sink;
|
||||
GstSeekType seekType;
|
||||
GstCaps * caps;
|
||||
GstFormat format;
|
||||
gint64 timePlayed;
|
||||
gint64 timeAfterSeek;
|
||||
gboolean ret;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(0, 0);
|
||||
|
||||
caps = gst_caps_new_simple("audio/x-raw-int",
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"channels", G_TYPE_INT, 2,
|
||||
"rate", G_TYPE_INT, 44100,
|
||||
NULL);
|
||||
|
||||
/* create elements */
|
||||
seekType = (GstSeekType) (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH);
|
||||
|
||||
pipeline = gst_pipeline_new("audio-player");
|
||||
source = gst_element_factory_make("filesrc", "source");
|
||||
sink = gst_element_factory_make("alsasink", "alsa-output");
|
||||
|
||||
g_object_set(G_OBJECT(source), "location", audioFile, NULL);
|
||||
|
||||
decoder = ls_gst_autoplug_plug_source(source, "decoder", caps);
|
||||
|
||||
if (!decoder) {
|
||||
gst_object_unref(GST_OBJECT(sink));
|
||||
gst_object_unref(GST_OBJECT(source));
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
gst_element_link(decoder, sink);
|
||||
gst_bin_add_many(GST_BIN(pipeline), source, decoder, sink, NULL);
|
||||
|
||||
gst_element_set_state(source, GST_STATE_PLAYING);
|
||||
gst_element_set_state(decoder, GST_STATE_PAUSED);
|
||||
gst_element_set_state(sink, GST_STATE_PAUSED);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
// iterate on the pipline until the played time becomes more than 0
|
||||
// as the seek even will only be taken into consideration after that
|
||||
// by gstreamer
|
||||
for (timePlayed = 0;
|
||||
timePlayed == 0 && gst_bin_iterate(GST_BIN(pipeline)); ) {
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_element_query(sink, GST_QUERY_POSITION, &format, &timePlayed);
|
||||
}
|
||||
|
||||
// so, seek now
|
||||
timeAfterSeek = -1LL;
|
||||
ret = livesupport_seek(decoder, seekType, seekTo);
|
||||
CPPUNIT_ASSERT(ret);
|
||||
|
||||
// iterate until playTo is reached
|
||||
while (gst_bin_iterate(GST_BIN(pipeline))) {
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_element_query(sink, GST_QUERY_POSITION, &format, &timePlayed);
|
||||
|
||||
if (timeAfterSeek == -1LL && timePlayed > seekTo) {
|
||||
timeAfterSeek = timePlayed;
|
||||
}
|
||||
|
||||
if (playTo > 0 && timePlayed > playTo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up nicely */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT (pipeline));
|
||||
|
||||
return timePlayed - timeAfterSeek;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: mp3Test(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(mp3File, 1LL * GST_SECOND, 4LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Seek and play until the end of the auido file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: mp3OpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
// see http://bugzilla.gnome.org/show_bug.cgi?id=308312
|
||||
// as why this seek is not precise
|
||||
timePlayed = playFile(mp3File, 2LL * GST_SECOND, -1LL);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test on an Ogg Vorbis file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: oggVorbisTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(oggVorbisFile, 1LL * GST_SECOND, 4LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Seek and play an ogg vorbis file until the end of the auido file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: oggVorbisOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
// see http://bugzilla.gnome.org/show_bug.cgi?id=308312
|
||||
// as why this seek is not precise
|
||||
timePlayed = playFile(oggVorbisFile, 2LL * GST_SECOND, -1LL);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test on a SMIL file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: smilTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFile(smilFile, 1LL * GST_SECOND, 4LL * GST_SECOND);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Seek and play a SMIL file until the end of the auido file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SeekTest :: smilOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
// see http://bugzilla.gnome.org/show_bug.cgi?id=308312
|
||||
// as why this seek is not precise
|
||||
timePlayed = playFile(oggVorbisFile, 2LL * GST_SECOND, -1LL);
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef SeekTest_h
|
||||
#define SeekTest_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
|
||||
namespace LiveSupport {
|
||||
namespace GstreamerElements {
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* Unit test for the partialplay gstreamer element.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class SeekTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(SeekTest);
|
||||
CPPUNIT_TEST(mp3Test);
|
||||
CPPUNIT_TEST(mp3OpenEndedTest);
|
||||
CPPUNIT_TEST(oggVorbisTest);
|
||||
CPPUNIT_TEST(oggVorbisOpenEndedTest);
|
||||
CPPUNIT_TEST(smilTest);
|
||||
CPPUNIT_TEST(smilOpenEndedTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Play a specific file, from and until a specific timepoint.
|
||||
*
|
||||
* @param audioFile the audio file to play.
|
||||
* @param seekTo before playing, seek to this position.
|
||||
* @param playTo play until this position, or -1LL if play until
|
||||
* the end.
|
||||
* @return the number of milliseconds played.
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
gint64
|
||||
playFile(const char * audioFile,
|
||||
gint64 seekTo,
|
||||
gint64 playTo)
|
||||
throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A simple mp3 test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3Test(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test where an mp3 file is played until its end.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3OpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple ogg vorbis test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test where an ogg vorbis file is played until its end.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple SMIL test.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test where an SMIL file is played until its end.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set up the environment for the test case.
|
||||
*/
|
||||
void
|
||||
setUp(void) throw ();
|
||||
|
||||
/**
|
||||
* Clean up the environment after the test case.
|
||||
*/
|
||||
void
|
||||
tearDown(void) throw ();
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
} // namespace GstreamerElements
|
||||
} // namespace LiveSupport
|
||||
|
||||
#endif // SeekTest_h
|
||||
|
|
@ -1,415 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "LiveSupport/GstreamerElements/autoplug.h"
|
||||
#include "SwitcherTest.h"
|
||||
|
||||
|
||||
using namespace LiveSupport::GstreamerElements;
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(SwitcherTest);
|
||||
|
||||
/**
|
||||
* An mp3 test file.
|
||||
*/
|
||||
static const char * mp3File = "var/5seccounter.mp3";
|
||||
|
||||
/**
|
||||
* An ogg vorbis test file.
|
||||
*/
|
||||
static const char * oggVorbisFile = "var/5seccounter.ogg";
|
||||
|
||||
/**
|
||||
* A SMIL test file.
|
||||
*/
|
||||
static const char * smilFile = "var/simple.smil";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Signal handler for the eos event of the switcher element.
|
||||
*
|
||||
* @param element the element emitting the eos signal
|
||||
* @param userData pointer to the container bin of the switcher.
|
||||
*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: setUp(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clean up the test environment
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: tearDown(void) throw ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play an audio file
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
SwitcherTest :: playFiles(const char ** audioFiles,
|
||||
unsigned int noFiles,
|
||||
const char * sourceConfig)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * switcher;
|
||||
GstElement * sink;
|
||||
GstCaps * caps;
|
||||
unsigned int i;
|
||||
GstFormat format;
|
||||
gint64 timePlayed;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(0, 0);
|
||||
|
||||
caps = gst_caps_new_simple("audio/x-raw-int",
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"channels", G_TYPE_INT, 2,
|
||||
"rate", G_TYPE_INT, 44100,
|
||||
NULL);
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new("audio-player");
|
||||
switcher = gst_element_factory_make("switcher", "switcher");
|
||||
sink = gst_element_factory_make("alsasink", "alsa-output");
|
||||
|
||||
for (i = 0; i < noFiles; ++i) {
|
||||
GstElement * source;
|
||||
GstElement * decoder;
|
||||
char str[256];
|
||||
gboolean ret;
|
||||
|
||||
g_snprintf(str, 256, "source_%d", i);
|
||||
source = gst_element_factory_make("filesrc", str);
|
||||
CPPUNIT_ASSERT(source);
|
||||
g_object_set(G_OBJECT(source), "location", audioFiles[i], NULL);
|
||||
|
||||
g_snprintf(str, 256, "decoder_%d", i);
|
||||
decoder = ls_gst_autoplug_plug_source(source, str, caps);
|
||||
CPPUNIT_ASSERT(decoder);
|
||||
|
||||
ret = gst_element_link(decoder, switcher);
|
||||
CPPUNIT_ASSERT(ret);
|
||||
gst_bin_add_many(GST_BIN(pipeline), source, decoder, NULL);
|
||||
}
|
||||
|
||||
/* link and add the switcher & sink _after_ the decoders above
|
||||
* otherwise we'll get a:
|
||||
* "assertion failed: (group->group_links == NULL)"
|
||||
* error later on when trying to free up the pipeline
|
||||
* see http://bugzilla.gnome.org/show_bug.cgi?id=309122
|
||||
*/
|
||||
gst_element_link_many(switcher, sink, NULL);
|
||||
gst_bin_add_many(GST_BIN(pipeline), switcher, sink, NULL);
|
||||
|
||||
g_object_set(G_OBJECT(switcher), "source-config", sourceConfig, NULL);
|
||||
/* listen for the eos event on switcher, so the pipeline can be stopped */
|
||||
g_signal_connect(switcher, "eos", G_CALLBACK(eos_signal_handler), pipeline);
|
||||
|
||||
gst_element_set_state(sink, GST_STATE_PAUSED);
|
||||
/* set the switcher to PAUSED, as it will give
|
||||
* "trying to push on unnegotiaded pad" warnings otherwise */
|
||||
gst_element_set_state(switcher, GST_STATE_PAUSED);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
while (gst_bin_iterate(GST_BIN(pipeline)));
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_element_query(sink, GST_QUERY_POSITION, &format, &timePlayed);
|
||||
|
||||
/* clean up nicely */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT (pipeline));
|
||||
|
||||
return timePlayed;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* eos signal handler for the switcher element
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
eos_signal_handler(GstElement * element,
|
||||
gpointer userData)
|
||||
{
|
||||
GstElement * container = GST_ELEMENT(userData);
|
||||
|
||||
g_return_if_fail(container != NULL);
|
||||
g_return_if_fail(GST_IS_ELEMENT(container));
|
||||
|
||||
// set the container into eos state
|
||||
gst_element_set_eos(container);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: mp3Test(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(&mp3File, 1, "0[3s]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: mp3OpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(&mp3File, 1, "0[]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: mp3MultipleTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
const char * testFiles[] = { mp3File, mp3File };
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(testFiles, 2, "0[2s];1[2s]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: mp3MultipleOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
const char * testFiles[] = { mp3File, mp3File };
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(testFiles, 2, "0[2s];1[]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 6.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 7.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: oggVorbisTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(&oggVorbisFile, 1, "0[3s]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: oggVorbisOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(&oggVorbisFile, 1, "0[]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: oggVorbisMultipleTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
const char * testFiles[] = { oggVorbisFile, oggVorbisFile };
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(testFiles, 2, "0[2s];1[2s]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: oggVorbisMultipleOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
const char * testFiles[] = { oggVorbisFile, oggVorbisFile };
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(testFiles, 2, "0[2s];1[]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 6.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 7.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* A simple smoke test.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: smilTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(&smilFile, 1, "0[3s]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 2.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 3.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: smilOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(&smilFile, 1, "0[]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 4.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: smilMultipleTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
const char * testFiles[] = { smilFile, smilFile };
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(testFiles, 2, "0[2s];1[2s]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 3.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 4.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Play a file until its end.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
SwitcherTest :: smilMultipleOpenEndedTest(void)
|
||||
throw (CPPUNIT_NS::Exception)
|
||||
{
|
||||
const char * testFiles[] = { smilFile, smilFile };
|
||||
gint64 timePlayed;
|
||||
char str[256];
|
||||
|
||||
timePlayed = playFiles(testFiles, 2, "0[2s];1[]");
|
||||
g_snprintf(str, 256, "time played: %" G_GINT64_FORMAT, timePlayed);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed > 6.9 * GST_SECOND);
|
||||
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 7.1 * GST_SECOND);
|
||||
}
|
||||
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef SwitcherTest_h
|
||||
#define SwitcherTest_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
|
||||
namespace LiveSupport {
|
||||
namespace GstreamerElements {
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* Unit test for the partialplay gstreamer element.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class SwitcherTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(SwitcherTest);
|
||||
CPPUNIT_TEST(mp3Test);
|
||||
CPPUNIT_TEST(mp3OpenEndedTest);
|
||||
CPPUNIT_TEST(mp3MultipleTest);
|
||||
CPPUNIT_TEST(mp3MultipleOpenEndedTest);
|
||||
CPPUNIT_TEST(oggVorbisTest);
|
||||
CPPUNIT_TEST(oggVorbisOpenEndedTest);
|
||||
CPPUNIT_TEST(oggVorbisMultipleTest);
|
||||
CPPUNIT_TEST(oggVorbisMultipleOpenEndedTest);
|
||||
CPPUNIT_TEST(smilTest);
|
||||
CPPUNIT_TEST(smilOpenEndedTest);
|
||||
CPPUNIT_TEST(smilMultipleTest);
|
||||
CPPUNIT_TEST(smilMultipleOpenEndedTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Play audio files, with a specific switcher configuration.
|
||||
*
|
||||
* @param audioFiles an array of file names to play
|
||||
* @param noFiles the size of the audioFiles array.
|
||||
* @param sourceConfig the source config to use.
|
||||
* @return the number of milliseconds played.
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
gint64
|
||||
playFiles(const char ** audioFiles,
|
||||
unsigned int noFiles,
|
||||
const char * sourceConfig)
|
||||
throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* A simple smoke test with an mp3 file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3Test(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test to play an mp3 file until its end.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3OpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test the switcher with multiple mp3 inputs.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3MultipleTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test the switcher with multiple mp3 inputs,
|
||||
* including open-ended ones.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
mp3MultipleOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple smoke test with an ogg vorbis file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test to play an ogg vorbis file until its end.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test the switcher with multiple ogg vorbis inputs.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisMultipleTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test the switcher with multiple ogg vorbis inputs,
|
||||
* including open-ended ones.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
oggVorbisMultipleOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A simple smoke test with a SMIL file.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* A test to play a SMIL file until its end.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test the switcher with multiple SMIL inputs.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilMultipleTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
/**
|
||||
* Test the switcher with multiple SMIL inputs,
|
||||
* including open-ended ones.
|
||||
*
|
||||
* @exception CPPUNIT_NS::Exception on test failures.
|
||||
*/
|
||||
void
|
||||
smilMultipleOpenEndedTest(void) throw (CPPUNIT_NS::Exception);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set up the environment for the test case.
|
||||
*/
|
||||
void
|
||||
setUp(void) throw ();
|
||||
|
||||
/**
|
||||
* Clean up the environment after the test case.
|
||||
*/
|
||||
void
|
||||
tearDown(void) throw ();
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
} // namespace GstreamerElements
|
||||
} // namespace LiveSupport
|
||||
|
||||
#endif // SwitcherTest_h
|
||||
|
|
@ -1,286 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error "Need unistd.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#else
|
||||
#error "Need getopt.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <cppunit/BriefTestProgressListener.h>
|
||||
#include <cppunit/CompilerOutputter.h>
|
||||
#include <cppunit/XmlOutputter.h>
|
||||
#include <cppunit/extensions/TestFactoryRegistry.h>
|
||||
#include <cppunit/TestResult.h>
|
||||
#include <cppunit/TestResultCollector.h>
|
||||
#include <cppunit/TestRunner.h>
|
||||
|
||||
#include "LiveSupport/Core/Ptr.h"
|
||||
|
||||
|
||||
using namespace LiveSupport::Core;
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
/**
|
||||
* Our copyright notice, should be at most 80 columns
|
||||
*/
|
||||
static const char copyrightNotice[] =
|
||||
"Copyright (c) 2004 Media Development Loan Fund under the GNU GPL";
|
||||
|
||||
/**
|
||||
* String describing the short options.
|
||||
*/
|
||||
static const char options[] = "ho:s:v";
|
||||
|
||||
/**
|
||||
* Structure describing the long options
|
||||
*/
|
||||
static const struct option longOptions[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "output", required_argument, 0, 'o' },
|
||||
{ "stylesheet", required_argument, 0, 's' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/**
|
||||
* The encoding to use for the output file.
|
||||
*/
|
||||
static const std::string encoding = "utf-8";
|
||||
|
||||
/**
|
||||
* The output XML file name.
|
||||
*/
|
||||
static Ptr<std::string>::Ref xmlOutFileName;
|
||||
|
||||
/**
|
||||
* The XSLT attached to the output file.
|
||||
*/
|
||||
static Ptr<std::string>::Ref xsltFileName;
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Print program version.
|
||||
*
|
||||
* @param os the std::ostream to print to.
|
||||
*/
|
||||
static void
|
||||
printVersion ( std::ostream & os );
|
||||
|
||||
/**
|
||||
* Print program usage information.
|
||||
*
|
||||
* @param invocation the command line command used to invoke this program.
|
||||
* @param os the std::ostream to print to.
|
||||
*/
|
||||
static void
|
||||
printUsage ( const char invocation[],
|
||||
std::ostream & os );
|
||||
|
||||
/**
|
||||
* Process command line arguments.
|
||||
*
|
||||
* @param argc the number of arguments.
|
||||
* @param argv the arguments themselves.
|
||||
* @return true of all went well, false in case the program should exit
|
||||
* after this call.
|
||||
*/
|
||||
static bool
|
||||
processArguments(int argc, char *argv[]);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Run all tests
|
||||
*----------------------------------------------------------------------------*/
|
||||
int
|
||||
main( int argc,
|
||||
char * argv[] ) throw ()
|
||||
{
|
||||
// initialize the gst parameters
|
||||
gst_init(&argc, &argv);
|
||||
|
||||
if (!processArguments(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create the event manager and test controller
|
||||
CPPUNIT_NS::TestResult controller;
|
||||
|
||||
// Add a listener that colllects test result
|
||||
CPPUNIT_NS::TestResultCollector result;
|
||||
controller.addListener( &result );
|
||||
|
||||
// Add a listener that print dots as test run.
|
||||
CPPUNIT_NS::BriefTestProgressListener progress;
|
||||
controller.addListener( &progress );
|
||||
|
||||
// Add the top suite to the test runner
|
||||
CPPUNIT_NS::TestRunner runner;
|
||||
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
|
||||
runner.run( controller );
|
||||
|
||||
// Print test in a compiler compatible format.
|
||||
CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr );
|
||||
outputter.setLocationFormat("%p:%l:");
|
||||
outputter.write();
|
||||
|
||||
// also generate an XML document as an output
|
||||
std::ofstream xmlOutFile(xmlOutFileName->c_str());
|
||||
CPPUNIT_NS::XmlOutputter xmlOutputter(&result, xmlOutFile, encoding);
|
||||
xmlOutputter.setStandalone(false);
|
||||
if (xsltFileName) {
|
||||
xmlOutputter.setStyleSheet(*xsltFileName);
|
||||
}
|
||||
xmlOutputter.write();
|
||||
xmlOutFile.flush();
|
||||
xmlOutFile.close();
|
||||
|
||||
return result.wasSuccessful() ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Process command line arguments.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static bool
|
||||
processArguments(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
while ((i = getopt_long(argc, argv, options, longOptions, 0)) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
printUsage(argv[0], std::cout);
|
||||
return false;
|
||||
|
||||
case 'o':
|
||||
xmlOutFileName.reset(new std::string(optarg));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
xsltFileName.reset(new std::string(optarg));
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
printVersion(std::cout);
|
||||
return false;
|
||||
|
||||
default:
|
||||
printUsage(argv[0], std::cout);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
std::cerr << "error processing command line arguments" << std::endl;
|
||||
printUsage(argv[0], std::cout);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!xmlOutFileName) {
|
||||
std::cerr << "mandatory option output file name not specified"
|
||||
<< std::endl;
|
||||
printUsage(argv[0], std::cout);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cerr << "writing output to '" << *xmlOutFileName << '\'' << std::endl;
|
||||
if (xsltFileName) {
|
||||
std::cerr << "using XSLT file '" << *xsltFileName << '\'' << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Print program version.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
printVersion ( std::ostream & os )
|
||||
{
|
||||
os << PACKAGE_NAME << ' ' << PACKAGE_VERSION << std::endl
|
||||
<< "Unit test runner" << std::endl
|
||||
<< copyrightNotice << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Print program usage.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
printUsage ( const char invocation[],
|
||||
std::ostream & os )
|
||||
{
|
||||
os << PACKAGE_NAME << ' ' << PACKAGE_VERSION << std::endl
|
||||
<< "Unit test runner" << std::endl
|
||||
<< std::endl
|
||||
<< "Usage: " << invocation << " [OPTION]"
|
||||
<< std::endl
|
||||
<< " mandatory options:" << std::endl
|
||||
<< " -o, --output=file.name write test results into this XML file"
|
||||
<< std::endl
|
||||
<< " optional options:" << std::endl
|
||||
<< " -s, --stylesheet specify this XSLT for the output file"
|
||||
<< std::endl
|
||||
<< " this is either an absolute URI, or a"
|
||||
<< std::endl
|
||||
<< " relative path for the output document"
|
||||
<< std::endl
|
||||
<< " -h, --help display this help and exit" << std::endl
|
||||
<< " -v, --version display version information and exit"
|
||||
<< std::endl
|
||||
<< std::endl
|
||||
<< "Report bugs to " << PACKAGE_BUGREPORT << std::endl;
|
||||
}
|
||||
|
|
@ -1,826 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
This code is based on the examples/manual/dynamic.c sample file
|
||||
provided in the gstreamer-0.8.10 source tarball, which is published
|
||||
under the GNU LGPL license.
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "LiveSupport/GstreamerElements/autoplug.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
typedef struct _Typefind Typefind;
|
||||
|
||||
/**
|
||||
* Data structure to hold information related to typefindinf.
|
||||
*/
|
||||
struct _Typefind {
|
||||
GstElement * pipeline;
|
||||
GstElement * bin;
|
||||
GstElement * source;
|
||||
GstElement * typefind;
|
||||
GstElement * audiosink;
|
||||
GstElement * sink;
|
||||
|
||||
const GstCaps * caps;
|
||||
|
||||
gulong typefindSignal;
|
||||
|
||||
gboolean done;
|
||||
};
|
||||
|
||||
/**
|
||||
* The list of factories this autoplugger is interested in.
|
||||
*/
|
||||
static GList * factories = 0;
|
||||
|
||||
/**
|
||||
* The reference count for the autoplugger, used to determine if static
|
||||
* (shared) resources should be freed.
|
||||
*/
|
||||
static unsigned int refCount = 0;
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Handle typefinding error.
|
||||
*
|
||||
* @param pipeline the pipeline generating the error.
|
||||
* @param source the source element with the error
|
||||
* @param error the error itself.
|
||||
* @param message the error message.
|
||||
* @param userData user-specific data.
|
||||
*/
|
||||
static void
|
||||
autoplug_error_handler(GstElement * pipeline,
|
||||
GstElement * source,
|
||||
GError * error,
|
||||
gchar * message,
|
||||
gpointer userData);
|
||||
|
||||
/**
|
||||
* Handle event of the typefinder finding a type.
|
||||
*
|
||||
* @param typefind the typefind element that found the type.
|
||||
* @param probability the probability of the find.
|
||||
* @param caps the found capabilities.
|
||||
* @param userData user-specific data, a pointer to a related Typefind
|
||||
* structure.
|
||||
*/
|
||||
static void
|
||||
autoplug_typefound_handler(GstElement * typefind,
|
||||
gint probability,
|
||||
GstCaps * caps,
|
||||
gpointer userData);
|
||||
|
||||
/**
|
||||
* Initialize a typefind object.
|
||||
*
|
||||
* @param typefind the Typefind structure to init.
|
||||
* @param name the name of the topmost bin element, that will
|
||||
* be returned at the end of autoplugging.
|
||||
* @param caps the capabilities expected from the returned element,
|
||||
* on its src pad.
|
||||
*/
|
||||
static void
|
||||
autoplug_init(Typefind * typefind,
|
||||
const gchar * name,
|
||||
const GstCaps * caps);
|
||||
|
||||
/**
|
||||
* De-initialize a typefind object.
|
||||
*
|
||||
* @param typefind the Typefind structure to de-init.
|
||||
*/
|
||||
static void
|
||||
autoplug_deinit(Typefind * typefind);
|
||||
|
||||
/**
|
||||
* A filter specifying the kind of factories we're interested in.
|
||||
*
|
||||
* @param feature the feature to test
|
||||
* @param userData user-specific data
|
||||
* @return TRUE if we're interested in the supplied feature, FALSE otherwise
|
||||
*/
|
||||
static gboolean
|
||||
autoplug_feature_filter(GstPluginFeature * feature,
|
||||
gpointer userData);
|
||||
|
||||
/**
|
||||
* A comparison function based on the ranks of two features.
|
||||
*
|
||||
* @param feature1 one of the features to compare.
|
||||
* @param feature2 the other feature to compare.
|
||||
* @return 0 if the two features match in terms of their ranks,
|
||||
* <0 if feature1 is higher, >0 if feature2 is higher in
|
||||
* their ranks.
|
||||
*/
|
||||
static gint
|
||||
autoplug_compare_ranks(GstPluginFeature * feature1,
|
||||
GstPluginFeature * feature2);
|
||||
|
||||
/**
|
||||
* Type to plug an appropriate element to a pad, according to the specified
|
||||
* capabilities.
|
||||
*
|
||||
* @param typefind the Typefind structure to do the plugging for
|
||||
* @param pad the pad to plug.
|
||||
* @param caps the capabilities to plug with.
|
||||
*/
|
||||
static void
|
||||
autoplug_try_to_plug(Typefind * typefind,
|
||||
GstPad * pad,
|
||||
const GstCaps * caps);
|
||||
|
||||
/**
|
||||
* Close a found link.
|
||||
*
|
||||
* @param typefind the Typefind structure to do close the link for.
|
||||
* @param srcpad the source pad to close linking for.
|
||||
* @param sinkelement the sink element to link the src pad to.
|
||||
* @param padname the name of sink pad in sinkelement to link srcpad to.
|
||||
* @param templlist a pad template list (TODO: what's this for?)
|
||||
*/
|
||||
static void
|
||||
autoplug_close_link(Typefind * typefind,
|
||||
GstPad * srcpad,
|
||||
GstElement * sinkelement,
|
||||
const gchar * padname,
|
||||
const GList * templlist);
|
||||
|
||||
/**
|
||||
* Handle the event of new pads created on elements with dynamic pads.
|
||||
*
|
||||
* @param element the element that the new pad was created on.
|
||||
* @param pad the new pad.
|
||||
* @param userData user-specific data.
|
||||
*/
|
||||
static void
|
||||
autoplug_newpad(GstElement * element,
|
||||
GstPad * pad,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/**
|
||||
* Remove all typefind elements inside the bin, traversing to lower binds
|
||||
* if necessary. The pads linked through the removed typefind elements are
|
||||
* linked directly instead.
|
||||
* The typefind member of the supplied Typefind object is also removed,
|
||||
* and changed to NULL.
|
||||
*
|
||||
* @param typefind the typefind object to work on.
|
||||
* @param bin the bin to remove the typefind elements from.
|
||||
*/
|
||||
static void
|
||||
autoplug_remove_typefind_elements(Typefind * typefind,
|
||||
GstBin * bin);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Filter the features that we're interested in.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gboolean
|
||||
autoplug_feature_filter(GstPluginFeature * feature,
|
||||
gpointer userData)
|
||||
{
|
||||
GstElementFactory * factory;
|
||||
const gchar * klass;
|
||||
guint rank;
|
||||
const GList * pads;
|
||||
gboolean good;
|
||||
|
||||
/* we only care about element factories */
|
||||
if (!GST_IS_ELEMENT_FACTORY(feature)) {
|
||||
return FALSE;
|
||||
}
|
||||
factory = GST_ELEMENT_FACTORY(feature);
|
||||
|
||||
/* only parsers, demuxers and decoders */
|
||||
klass = gst_element_factory_get_klass(factory);
|
||||
if (g_strrstr(klass, "Demux") == NULL &&
|
||||
g_strrstr(klass, "Decoder") == NULL &&
|
||||
g_strrstr(klass, "Parse") == NULL) {
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* select only the factories we care about, which are enough to
|
||||
* open and plug mp3, ogg vorbis and SMIL */
|
||||
good = FALSE;
|
||||
for (pads = gst_element_factory_get_pad_templates(factory);
|
||||
pads != NULL;
|
||||
pads = pads->next) {
|
||||
|
||||
GstPadTemplate * templ = GST_PAD_TEMPLATE(pads->data);
|
||||
const char * mime;
|
||||
|
||||
if (!GST_IS_PAD_TEMPLATE(templ)) {
|
||||
continue;
|
||||
}
|
||||
/* find the sink template - need an always pad*/
|
||||
if (templ->direction != GST_PAD_SINK ||
|
||||
templ->presence != GST_PAD_ALWAYS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gst_caps_get_size(templ->caps) <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mime = gst_structure_get_name(gst_caps_get_structure(templ->caps, 0));
|
||||
|
||||
if (g_strrstr(mime, "application/x-id3")
|
||||
|| g_strrstr(mime, "audio/mpeg")
|
||||
|| g_strrstr(mime, "application/ogg")
|
||||
|| g_strrstr(mime, "audio/x-vorbis")
|
||||
|| g_strrstr(mime, "application/smil")) {
|
||||
|
||||
good = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!good) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* only select elements with autoplugging rank */
|
||||
rank = gst_plugin_feature_get_rank(feature);
|
||||
if (rank < GST_RANK_MARGINAL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Compare the ranks of two features.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gint
|
||||
autoplug_compare_ranks(GstPluginFeature * feature1,
|
||||
GstPluginFeature * feature2)
|
||||
{
|
||||
return gst_plugin_feature_get_rank(feature2)
|
||||
- gst_plugin_feature_get_rank(feature1);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize a Typefind object, like the factories that we care about.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_init(Typefind * typefind,
|
||||
const gchar * name,
|
||||
const GstCaps * caps)
|
||||
{
|
||||
/* first filter out the interesting element factories */
|
||||
if (!factories) {
|
||||
/* FIXME: this is not thread safe!
|
||||
* but set factoires to non-zero ASAP to avoid race conditions */
|
||||
factories = (GList *) -1;
|
||||
|
||||
factories = gst_registry_pool_feature_filter(
|
||||
(GstPluginFeatureFilter) autoplug_feature_filter,
|
||||
FALSE, NULL);
|
||||
|
||||
/* sort them according to their ranks */
|
||||
factories = g_list_sort(factories,
|
||||
(GCompareFunc) autoplug_compare_ranks);
|
||||
}
|
||||
|
||||
typefind->pipeline = gst_pipeline_new("pipeline");
|
||||
typefind->bin = gst_bin_new(name);
|
||||
typefind->typefind = gst_element_factory_make("typefind", "tf");
|
||||
typefind->audiosink = gst_element_factory_make("audioconvert", "audiosink");
|
||||
typefind->sink = gst_element_factory_make("fakesink", "fakesink");
|
||||
|
||||
typefind->caps = caps;
|
||||
|
||||
gst_element_add_ghost_pad(typefind->bin,
|
||||
gst_element_get_pad(typefind->typefind, "sink"),
|
||||
"sink");
|
||||
gst_bin_add_many(GST_BIN(typefind->bin),
|
||||
typefind->typefind,
|
||||
NULL);
|
||||
|
||||
g_signal_connect(typefind->bin,
|
||||
"error",
|
||||
G_CALLBACK(autoplug_error_handler),
|
||||
NULL);
|
||||
typefind->typefindSignal = g_signal_connect(typefind->typefind,
|
||||
"have-type",
|
||||
G_CALLBACK(autoplug_typefound_handler),
|
||||
typefind);
|
||||
|
||||
gst_element_link(typefind->source, typefind->bin);
|
||||
gst_bin_add_many(GST_BIN(typefind->pipeline),
|
||||
typefind->source,
|
||||
typefind->bin,
|
||||
NULL);
|
||||
|
||||
typefind->done = FALSE;
|
||||
|
||||
++refCount;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* De-initialize a Typefind object.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_deinit(Typefind * typefind)
|
||||
{
|
||||
--refCount;
|
||||
|
||||
if (refCount == 0) {
|
||||
g_list_free(factories);
|
||||
factories = 0;
|
||||
}
|
||||
|
||||
gst_element_set_state(typefind->pipeline, GST_STATE_NULL);
|
||||
if (typefind->typefind) {
|
||||
g_signal_handler_disconnect(typefind->typefind,
|
||||
typefind->typefindSignal);
|
||||
}
|
||||
|
||||
if (typefind->audiosink && !gst_element_get_parent(typefind->audiosink)) {
|
||||
gst_object_unref(GST_OBJECT(typefind->audiosink));
|
||||
}
|
||||
if (typefind->sink && !gst_element_get_parent(typefind->sink)) {
|
||||
gst_object_unref(GST_OBJECT(typefind->sink));
|
||||
}
|
||||
gst_object_unref(GST_OBJECT(typefind->pipeline));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Handle the event of a new pad being created on an element with
|
||||
* request pads.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_newpad(GstElement * element,
|
||||
GstPad * pad,
|
||||
gpointer userData)
|
||||
{
|
||||
GstCaps * caps;
|
||||
Typefind * typefind = (Typefind*) userData;
|
||||
|
||||
g_return_if_fail(typefind != NULL);
|
||||
|
||||
GST_DEBUG("created new pad %s for element %s",
|
||||
gst_pad_get_name(pad), gst_element_get_name(element));
|
||||
caps = gst_pad_get_caps(pad);
|
||||
autoplug_try_to_plug(typefind, pad, caps);
|
||||
gst_caps_free(caps);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Close the link.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_close_link(Typefind * typefind,
|
||||
GstPad * srcpad,
|
||||
GstElement * sinkelement,
|
||||
const gchar * padname,
|
||||
const GList * templlist)
|
||||
{
|
||||
GstPad * pad;
|
||||
gboolean has_dynamic_pads = FALSE;
|
||||
GstElement * srcelement;
|
||||
|
||||
srcelement = GST_ELEMENT(gst_pad_get_parent(srcpad));
|
||||
|
||||
GST_DEBUG("Plugging pad %s:%s to newly created %s:%s",
|
||||
gst_object_get_name(GST_OBJECT(srcelement)),
|
||||
gst_pad_get_name(srcpad),
|
||||
gst_object_get_name(GST_OBJECT(sinkelement)), padname);
|
||||
|
||||
/* add the element to the pipeline and set correct state */
|
||||
gst_bin_add(GST_BIN(typefind->bin), sinkelement);
|
||||
pad = gst_element_get_pad(sinkelement, padname);
|
||||
|
||||
gst_pad_link(srcpad, pad);
|
||||
|
||||
/* FIXME: this is a nasty workaround for lack of time
|
||||
* the minimalaudiosmil will try to read the input immediately
|
||||
* from it sink pad as its set to PLAYING state,
|
||||
* but that will result in a zillion such gstreamer warnings:
|
||||
* "deadlock detected, disabling group 0xXXXXXX"
|
||||
* but for example the vorbis demuxer needs to be in PLAYING
|
||||
* state so that it can dynamically connect its request pads.
|
||||
* fix this as soon as possible!
|
||||
*/
|
||||
if (!(g_strrstr(gst_object_get_name(GST_OBJECT(srcelement)),
|
||||
"minimalaudiosmil")
|
||||
|| g_strrstr(gst_object_get_name(GST_OBJECT(sinkelement)),
|
||||
"minimalaudiosmil"))) {
|
||||
|
||||
gst_bin_sync_children_state(GST_BIN(typefind->bin));
|
||||
}
|
||||
|
||||
/* if we have static source pads, link those. If we have dynamic
|
||||
* source pads, listen for new-pad signals on the element */
|
||||
for ( ; templlist != NULL; templlist = templlist->next) {
|
||||
GstPadTemplate *templ = GST_PAD_TEMPLATE (templlist->data);
|
||||
|
||||
/* only sourcepads, no request pads */
|
||||
if (templ->direction != GST_PAD_SRC ||
|
||||
templ->presence == GST_PAD_REQUEST) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (templ->presence) {
|
||||
case GST_PAD_ALWAYS: {
|
||||
GstPad * pad = gst_element_get_pad(sinkelement,
|
||||
templ->name_template);
|
||||
GstCaps * caps = gst_pad_get_caps(pad);
|
||||
|
||||
/* link */
|
||||
autoplug_try_to_plug(typefind, pad, caps);
|
||||
gst_caps_free(caps);
|
||||
} break;
|
||||
|
||||
case GST_PAD_SOMETIMES:
|
||||
has_dynamic_pads = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* listen for newly created pads if this element supports that */
|
||||
if (has_dynamic_pads) {
|
||||
g_signal_connect(sinkelement,
|
||||
"new-pad",
|
||||
G_CALLBACK(autoplug_newpad),
|
||||
typefind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Try to plug a pad with the specified capabilities.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_try_to_plug(Typefind * typefind,
|
||||
GstPad * pad,
|
||||
const GstCaps * caps)
|
||||
{
|
||||
GstObject * parent = GST_OBJECT(gst_pad_get_parent(pad));
|
||||
const gchar * mime;
|
||||
const GList * item;
|
||||
|
||||
g_return_if_fail(typefind != NULL);
|
||||
|
||||
/* don't plug if we're already plugged */
|
||||
if (GST_PAD_IS_LINKED(gst_element_get_pad(typefind->audiosink, "sink"))) {
|
||||
GST_DEBUG("Omitting link for pad %s:%s because we're already linked",
|
||||
gst_object_get_name(parent), gst_pad_get_name(pad));
|
||||
return;
|
||||
}
|
||||
|
||||
/* as said above, we only try to plug audio... Omit video */
|
||||
mime = gst_structure_get_name(gst_caps_get_structure(caps, 0));
|
||||
if (g_strrstr(mime, "video")) {
|
||||
GST_DEBUG("Omitting link for pad %s:%s because "
|
||||
"mimetype %s is non-audio\n",
|
||||
gst_object_get_name(parent), gst_pad_get_name(pad), mime);
|
||||
return;
|
||||
}
|
||||
|
||||
/* can it link to the audiopad? */
|
||||
/* instead of doing a gst_caps_intersect between caps and the sink
|
||||
* pad caps of typefind->audiosink, just look at the mime type of caps.
|
||||
* this is sufficient, as we know that we're linking to an audioconvert
|
||||
* element, that accepts audio/x-raw-int and audio/x-raw-float */
|
||||
if (g_strrstr(mime, "audio/x-raw-int")
|
||||
|| g_strrstr(mime, "audio/x-raw-float")) {
|
||||
|
||||
GST_DEBUG("Found pad to link to audiosink - plugging is now done");
|
||||
typefind->done = TRUE;
|
||||
|
||||
autoplug_close_link(typefind, pad, typefind->audiosink, "sink", NULL);
|
||||
|
||||
gst_element_add_ghost_pad(typefind->bin,
|
||||
gst_element_get_pad(typefind->audiosink, "src"),
|
||||
"src");
|
||||
gst_element_link_filtered(typefind->bin, typefind->sink,
|
||||
typefind->caps);
|
||||
gst_bin_add(GST_BIN(typefind->pipeline), typefind->sink);
|
||||
gst_bin_sync_children_state(GST_BIN(typefind->pipeline));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to plug from our list */
|
||||
for (item = factories; item != NULL; item = item->next) {
|
||||
GstElementFactory * factory = GST_ELEMENT_FACTORY(item->data);
|
||||
const GList * pads;
|
||||
GstCaps * res;
|
||||
|
||||
for (pads = gst_element_factory_get_pad_templates(factory);
|
||||
pads != NULL;
|
||||
pads = pads->next) {
|
||||
GstPadTemplate * templ = GST_PAD_TEMPLATE(pads->data);
|
||||
const gchar * templMime;
|
||||
|
||||
if (!GST_IS_PAD_TEMPLATE(templ)) {
|
||||
continue;
|
||||
}
|
||||
/* find the sink template - need an always pad*/
|
||||
if (templ->direction != GST_PAD_SINK ||
|
||||
templ->presence != GST_PAD_ALWAYS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* first check if mime types match */
|
||||
templMime = gst_structure_get_name(
|
||||
gst_caps_get_structure(templ->caps, 0));
|
||||
if (!g_strrstr(mime, templMime)) {
|
||||
continue;
|
||||
}
|
||||
/* can it link? */
|
||||
res = gst_caps_intersect(caps, templ->caps);
|
||||
if (res && !gst_caps_is_empty(res)) {
|
||||
GstElement * element;
|
||||
const GList * padTemplates;
|
||||
gchar * templateName;
|
||||
|
||||
/* close link and return */
|
||||
gst_caps_free(res);
|
||||
templateName = g_strdup(templ->name_template);
|
||||
element = gst_element_factory_create(factory, NULL);
|
||||
padTemplates = gst_element_factory_get_pad_templates(factory);
|
||||
autoplug_close_link(typefind,
|
||||
pad,
|
||||
element,
|
||||
templateName,
|
||||
padTemplates);
|
||||
g_free(templateName);
|
||||
return;
|
||||
}
|
||||
gst_caps_free(res);
|
||||
|
||||
/* we only check one sink template per factory, so move on to the
|
||||
* next factory now */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we get here, no item was found */
|
||||
GST_DEBUG("No compatible pad found to decode %s on %s:%s",
|
||||
mime, gst_object_get_name(parent), gst_pad_get_name(pad));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Handle the event when a new type was found.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_typefound_handler(GstElement * typefind,
|
||||
gint probability,
|
||||
GstCaps * caps,
|
||||
gpointer userData)
|
||||
{
|
||||
gchar * str;
|
||||
Typefind * tf = (Typefind*) userData;
|
||||
|
||||
g_return_if_fail(tf != NULL);
|
||||
|
||||
str = gst_caps_to_string(caps);
|
||||
GST_DEBUG("Detected media type %s", str);
|
||||
g_free(str);
|
||||
|
||||
/* actually plug now */
|
||||
autoplug_try_to_plug(tf, gst_element_get_pad(typefind, "src"), caps);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Filter the features that we're interested in.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_error_handler(GstElement * pipeline,
|
||||
GstElement * source,
|
||||
GError * error,
|
||||
gchar * message,
|
||||
gpointer userData)
|
||||
{
|
||||
/* TODO: handle error somehow */
|
||||
GST_DEBUG("error: %s", message);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Remove all typefind elements inside the bin, traversing to lower binds
|
||||
* if necessary. The pads linked to the removed typefind elements are
|
||||
* linked directly instead.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
autoplug_remove_typefind_elements(Typefind * typefind,
|
||||
GstBin * bin)
|
||||
{
|
||||
GstElement * element;
|
||||
const GList * elements;
|
||||
|
||||
elements = gst_bin_get_list(GST_BIN(bin));
|
||||
while (elements) {
|
||||
GstElementFactory * factory;
|
||||
GType type;
|
||||
|
||||
element = (GstElement*) elements->data;
|
||||
factory = gst_element_get_factory(element);
|
||||
type = gst_element_factory_get_element_type(factory);
|
||||
|
||||
GST_DEBUG("found factory: %s of type %s, is bin: %d",
|
||||
gst_element_factory_get_longname(factory),
|
||||
g_type_name(type),
|
||||
g_type_is_a(type, GST_TYPE_BIN));
|
||||
|
||||
if (GST_IS_BIN(element)) {
|
||||
autoplug_remove_typefind_elements(typefind, GST_BIN(element));
|
||||
} else if (g_strrstr(gst_element_factory_get_longname(factory),
|
||||
"TypeFind")) {
|
||||
GstPad * tfSinkPad;
|
||||
GstPad * tfSrcPad;
|
||||
GstPad * sinkPad;
|
||||
GstElement * sinkElement;
|
||||
GstPad * srcPad;
|
||||
GstElement * srcElement;
|
||||
GstElement * parent;
|
||||
GstPad * parentSrcPad;
|
||||
GstPad * parentSinkPad;
|
||||
|
||||
tfSinkPad = gst_element_get_pad(element, "sink");
|
||||
tfSrcPad = gst_element_get_pad(element, "src");
|
||||
sinkPad = gst_pad_get_peer(tfSrcPad);
|
||||
sinkElement = gst_pad_get_parent(sinkPad);
|
||||
srcPad = gst_pad_get_peer(tfSinkPad);
|
||||
srcElement = gst_pad_get_parent(srcPad);
|
||||
parent = (GstElement*) gst_element_get_parent(element);
|
||||
parentSrcPad = gst_element_get_pad(parent, "src");
|
||||
parentSinkPad = gst_element_get_pad(parent, "sink");
|
||||
|
||||
gst_element_unlink(srcElement, element);
|
||||
gst_element_unlink(element, sinkElement);
|
||||
|
||||
if (GST_PAD_REALIZE(parentSrcPad) == (GstRealPad*) tfSrcPad) {
|
||||
/* if the pad we want to relink is ghosted by the container */
|
||||
gst_element_remove_pad(parent, parentSrcPad);
|
||||
gst_element_add_ghost_pad(parent, srcPad, "src");
|
||||
gst_element_link(parent, sinkElement);
|
||||
} else if (GST_PAD_REALIZE(parentSinkPad) ==
|
||||
(GstRealPad*) tfSinkPad) {
|
||||
/* if the pad we want to relink is ghosted by the container */
|
||||
gst_element_remove_pad(parent, parentSinkPad);
|
||||
gst_element_add_ghost_pad(parent, sinkPad, "sink");
|
||||
gst_element_link(srcElement, parent);
|
||||
} else {
|
||||
gst_element_link(srcElement, sinkElement);
|
||||
}
|
||||
|
||||
gst_bin_remove(bin, element);
|
||||
|
||||
if (element == typefind->typefind) {
|
||||
typefind->typefind = NULL;
|
||||
}
|
||||
|
||||
/* start iteration from the beginning, as probably the element
|
||||
* list is invalidated with us removing the typefind element */
|
||||
elements = gst_bin_get_list(GST_BIN(bin));
|
||||
continue;
|
||||
}
|
||||
|
||||
elements = elements->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Filter the features that we're interested in.
|
||||
*----------------------------------------------------------------------------*/
|
||||
GstElement *
|
||||
ls_gst_autoplug_plug_source(GstElement * source,
|
||||
const gchar * name,
|
||||
const GstCaps * caps)
|
||||
{
|
||||
Typefind typefind;
|
||||
GstElement * bin;
|
||||
GValue gvalue = { 0 };
|
||||
|
||||
/* add an additional ref on the source, as we'll put it in a bin
|
||||
* and remove it from the bin later, which will decrease the ref by one */
|
||||
g_object_ref(source);
|
||||
|
||||
typefind.source = source;
|
||||
autoplug_init(&typefind, name, caps);
|
||||
|
||||
gst_element_set_state(typefind.audiosink, GST_STATE_PAUSED);
|
||||
gst_element_set_state(typefind.sink, GST_STATE_PAUSED);
|
||||
gst_element_set_state(typefind.bin, GST_STATE_PLAYING);
|
||||
gst_element_set_state(typefind.pipeline, GST_STATE_PLAYING);
|
||||
|
||||
/* run */
|
||||
while (!typefind.done && gst_bin_iterate(GST_BIN(typefind.pipeline)));
|
||||
|
||||
/* do an extra iteration, otherwise some gstreamer elements don't get
|
||||
* properly initialized, like the vorbis element.
|
||||
* see http://bugs.campware.org/view.php?id=1421 for details */
|
||||
g_value_init(&gvalue, G_TYPE_STRING);
|
||||
gst_element_get_property(typefind.typefind, "caps", &gvalue);
|
||||
if (g_strrstr("application/ogg", g_value_get_string(&gvalue))) {
|
||||
gst_bin_iterate(GST_BIN(typefind.pipeline));
|
||||
}
|
||||
|
||||
if (!typefind.done) {
|
||||
autoplug_deinit(&typefind);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* remove the sink element */
|
||||
gst_element_unlink(typefind.bin, typefind.sink);
|
||||
gst_bin_remove(GST_BIN(typefind.pipeline), typefind.sink);
|
||||
typefind.sink = NULL;
|
||||
|
||||
/* remove the typefind elements, and re-link with the source */
|
||||
autoplug_remove_typefind_elements(&typefind, GST_BIN(typefind.bin));
|
||||
gst_element_link(typefind.source, typefind.bin);
|
||||
|
||||
/* destory the pipeline, but keep source and bin */
|
||||
g_object_ref(typefind.bin);
|
||||
gst_bin_remove(GST_BIN(typefind.pipeline), typefind.bin);
|
||||
|
||||
bin = typefind.bin;
|
||||
|
||||
autoplug_deinit(&typefind);
|
||||
|
||||
gst_element_set_state(bin, GST_STATE_PAUSED);
|
||||
gst_bin_sync_children_state(GST_BIN(bin));
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Return the current position of an autoplugged element
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
ls_gst_autoplug_get_position(GstElement * element)
|
||||
{
|
||||
GstFormat format;
|
||||
gint64 position;
|
||||
|
||||
if (!element || !GST_IS_BIN(element)) {
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
if (!gst_element_query(element, GST_QUERY_POSITION, &format, &position)
|
||||
|| format != GST_FORMAT_TIME) {
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,135 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef LivesSupport_GstreamerElements_MinimalAudioSmil_h
|
||||
#define LivesSupport_GstreamerElements_MinimalAudioSmil_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* A gstreamer element that plays SMIL files referencing audio content.
|
||||
* Only a small subset of SMIL is supported.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
* @see http://www.w3.org/TR/SMIL2/
|
||||
*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define LIVESUPPORT_TYPE_MINIMAL_AUDIO_SMIL \
|
||||
(livesupport_minimal_audio_smil_get_type())
|
||||
|
||||
#define LIVESUPPORT_MINIMAL_AUDIO_SMIL(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
LIVESUPPORT_TYPE_MINIMAL_AUDIO_SMIL, \
|
||||
LivesupportMinimalAudioSmil))
|
||||
|
||||
#define LIVESUPPORT_MINIMAL_AUDIO_SMIL_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
LIVESUPPORT_TYPE_MINIMAL_AUDIO_SMIL, \
|
||||
LivesupportMinimalAudioSmil))
|
||||
|
||||
#define LIVESUPPORT_IS_MINIMAL_AUDIO_SMIL(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), \
|
||||
LIVESUPPORT_TYPE_MINIMAL_AUDIO_SMIL))
|
||||
|
||||
#define LIVESUPPORT_IS_MINIMAL_AUDIO_SMIL_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), \
|
||||
LIVESUPPORT_TYPE_MINIMAL_AUDIO_SMIL))
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
typedef struct _LivesupportMinimalAudioSmil LivesupportMinimalAudioSmil;
|
||||
typedef struct _LivesupportMinimalAudioSmilClass
|
||||
LivesupportMinimalAudioSmilClass;
|
||||
|
||||
/**
|
||||
* The MinimalAudioSmil object structure.
|
||||
*/
|
||||
struct _LivesupportMinimalAudioSmil {
|
||||
LivesupportMinimalAudioSmilClass* myclass;
|
||||
GstBin parent;
|
||||
|
||||
GstPad * sinkpad;
|
||||
GstPad * srcpad;
|
||||
|
||||
GstCaps * caps;
|
||||
|
||||
GstElement * oneshotReader;
|
||||
gboolean fileProcessed;
|
||||
|
||||
GstBin * bin;
|
||||
GstElement * finalAdder;
|
||||
};
|
||||
|
||||
/**
|
||||
* The MinimalAudioSmil class.
|
||||
*/
|
||||
struct _LivesupportMinimalAudioSmilClass {
|
||||
GstBinClass parent_class;
|
||||
|
||||
gboolean abort_initial;
|
||||
gboolean * abort;
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Return the appropriate type for the element.
|
||||
*
|
||||
* @return the type structure of the element.
|
||||
*/
|
||||
GType
|
||||
livesupport_minimal_audio_smil_get_type(void);
|
||||
|
||||
/**
|
||||
* The plugin initialization function.
|
||||
*
|
||||
* @param plugin the plugin itself.
|
||||
* @return TRUE if initialization was successful, FALSE otherwise.
|
||||
*/
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* LivesSupport_GstreamerElements_MinimalAudioSmil_h */
|
||||
|
|
@ -1,528 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#error need string.h
|
||||
#endif
|
||||
|
||||
|
||||
#include "oneshot-reader.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
/**
|
||||
* The arguments this element supports.
|
||||
*/
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_CONTENTS,
|
||||
ARG_LENGTH
|
||||
};
|
||||
|
||||
/**
|
||||
* Element details.
|
||||
*/
|
||||
static GstElementDetails livesupport_one_shot_reader_details =
|
||||
GST_ELEMENT_DETAILS("OneShotReader",
|
||||
"Generic",
|
||||
"A reader, reading the contents in one shot",
|
||||
"Akos Maroy <maroy@campware.org>");
|
||||
|
||||
/**
|
||||
* The parent class.
|
||||
*/
|
||||
static GstElementClass * parent_class = NULL;
|
||||
|
||||
/**
|
||||
* The sink factory template.
|
||||
*/
|
||||
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE (
|
||||
"sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
/**
|
||||
* Debug category definition.
|
||||
*/
|
||||
GST_DEBUG_CATEGORY_STATIC(one_shot_reader_debug);
|
||||
|
||||
/**
|
||||
* The plugin definition.
|
||||
*/
|
||||
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"oneshotreaderplugin",
|
||||
"A reader that reads all of the input on one go",
|
||||
plugin_init,
|
||||
"$Revision$",
|
||||
"GPL",
|
||||
"LiveSupport",
|
||||
"http://campcaster.campware.org/")
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Get a specific property.
|
||||
*
|
||||
* @param object the object to get the property from (a oneshotreader)
|
||||
* @param propId the ID of the property
|
||||
* @param value the value to return the property in (out parameter)
|
||||
* @param pspec the parameter spec
|
||||
*/
|
||||
static void
|
||||
get_property(GObject * object,
|
||||
guint propId,
|
||||
GValue * value,
|
||||
GParamSpec * pspec);
|
||||
|
||||
/**
|
||||
* Read a stream into memory.
|
||||
*
|
||||
* @param read the OneShotReader to read from.
|
||||
* @param outbuffer the buffer to return the whole stream in, plus
|
||||
* an extra terminating NULL character.
|
||||
* must be freed after it's not needed.
|
||||
* @param outlength the length of the returned buffer.
|
||||
*/
|
||||
static void
|
||||
read_stream_into_memory(LivesupportOneShotReader * reader,
|
||||
guint8 ** outbuffer,
|
||||
guint32 * outlength);
|
||||
|
||||
/**
|
||||
* The main loop function of the element.
|
||||
*
|
||||
* @param element a OneShotReader element to loop on.
|
||||
*/
|
||||
static void
|
||||
livesupport_one_shot_reader_loop(GstElement * element);
|
||||
|
||||
/**
|
||||
* The state change function of the element.
|
||||
*
|
||||
* @param element a OneShotReader element to change the state for.
|
||||
*/
|
||||
static GstElementStateReturn
|
||||
livesupport_one_shot_reader_change_state(GstElement * element);
|
||||
|
||||
/**
|
||||
* The dispose function of the element.
|
||||
*
|
||||
* @param object a OneShotReader element to dispose of.
|
||||
*/
|
||||
static void
|
||||
livesupport_one_shot_reader_dispose(GObject * object);
|
||||
|
||||
/**
|
||||
* Initialize a OneShotReader element.
|
||||
*
|
||||
* @param reader the OneShotReader element to initialzie.
|
||||
*/
|
||||
static void
|
||||
livesupport_one_shot_reader_init(LivesupportOneShotReader * reader);
|
||||
|
||||
/**
|
||||
* Do base initialization on the element's class.
|
||||
*
|
||||
* @param g_class the element's class.
|
||||
*/
|
||||
static void
|
||||
livesupport_one_shot_reader_base_init(gpointer g_class);
|
||||
|
||||
/**
|
||||
* Initialize the element's class.
|
||||
*
|
||||
* @param klass the element's class.
|
||||
*/
|
||||
static void
|
||||
livesupport_one_shot_reader_class_init(LivesupportOneShotReaderClass * klass);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Get a specific property.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
get_property(GObject * object,
|
||||
guint propId,
|
||||
GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
LivesupportOneShotReader * reader = LIVESUPPORT_ONE_SHOT_READER(object);
|
||||
|
||||
switch (propId) {
|
||||
case ARG_CONTENTS:
|
||||
g_value_set_pointer(value, reader->contents);
|
||||
break;
|
||||
|
||||
case ARG_LENGTH:
|
||||
g_value_set_uint(value, reader->length);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Read the whole stream into memory.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
read_stream_into_memory(LivesupportOneShotReader * reader,
|
||||
guint8 ** outbuffer,
|
||||
guint32 * outlength)
|
||||
{
|
||||
guint32 length;
|
||||
guint32 read;
|
||||
guint8 * buffer;
|
||||
|
||||
*outbuffer = 0;
|
||||
*outlength = 0;
|
||||
|
||||
if (!reader->bytestream) {
|
||||
GST_ELEMENT_ERROR(GST_ELEMENT(reader),
|
||||
CORE,
|
||||
PAD,
|
||||
("missing bytestream"),
|
||||
(NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
/* seek to the beginning, to make sure... */
|
||||
gst_bytestream_seek(reader->bytestream, 0LL, GST_SEEK_METHOD_SET);
|
||||
|
||||
length = (guint32) gst_bytestream_length(reader->bytestream);
|
||||
buffer = g_malloc(length + 1);
|
||||
read = 0;
|
||||
while (read < length) {
|
||||
guint32 r;
|
||||
guint8 * buf;
|
||||
GstEvent * event;
|
||||
|
||||
/* look if we've reached eos, and exit the loop if so */
|
||||
gst_bytestream_get_status(reader->bytestream, &r, &event);
|
||||
if (event) {
|
||||
if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
|
||||
gst_event_unref(event);
|
||||
break;
|
||||
}
|
||||
gst_event_unref(event);
|
||||
}
|
||||
|
||||
r = gst_bytestream_peek_bytes(reader->bytestream, &buf, length - read);
|
||||
memcpy(buffer + read, buf, r);
|
||||
read += r;
|
||||
}
|
||||
|
||||
/* check if we could read everything */
|
||||
if (read < length) {
|
||||
g_free(buffer);
|
||||
GST_ELEMENT_ERROR(GST_ELEMENT(reader),
|
||||
RESOURCE,
|
||||
READ,
|
||||
("couldn't read the whole of the input"),
|
||||
(NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
/* flush the bytestream, as we've read all from it anyway */
|
||||
gst_bytestream_flush_fast(reader->bytestream, length);
|
||||
|
||||
/* re-seek to the beginning, to make sure it can be set to PLAYING again */
|
||||
gst_bytestream_seek(reader->bytestream, 0LL, GST_SEEK_METHOD_SET);
|
||||
|
||||
/* put a 0 character at the end of the buffer */
|
||||
buffer[length] = '\0';
|
||||
|
||||
*outbuffer = buffer;
|
||||
*outlength = length;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* The loop function of the reader.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_one_shot_reader_loop(GstElement * element)
|
||||
{
|
||||
LivesupportOneShotReader * reader;
|
||||
GstData * data;
|
||||
|
||||
g_return_if_fail(element != NULL);
|
||||
g_return_if_fail(GST_IS_ONE_SHOT_READER(element));
|
||||
|
||||
reader = LIVESUPPORT_ONE_SHOT_READER(element);
|
||||
|
||||
if (!reader->processed) {
|
||||
/* read the source document into memory */
|
||||
read_stream_into_memory(reader, &reader->contents, &reader->length);
|
||||
if (!reader->contents) {
|
||||
GST_ELEMENT_ERROR(GST_ELEMENT(reader),
|
||||
STREAM,
|
||||
WRONG_TYPE,
|
||||
("unable to process input"),
|
||||
(NULL));
|
||||
}
|
||||
reader->processed = TRUE;
|
||||
}
|
||||
|
||||
/* just pull the data from the source and don't care about it */
|
||||
data = gst_pad_pull(reader->sinkpad);
|
||||
|
||||
gst_element_set_eos(element);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* The state change function of the element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static GstElementStateReturn
|
||||
livesupport_one_shot_reader_change_state(GstElement * element)
|
||||
{
|
||||
LivesupportOneShotReader * reader;
|
||||
|
||||
reader = LIVESUPPORT_ONE_SHOT_READER(element);
|
||||
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_NULL_TO_READY:
|
||||
break;
|
||||
|
||||
case GST_STATE_READY_TO_PAUSED:
|
||||
reader->bytestream = gst_bytestream_new(reader->sinkpad);
|
||||
break;
|
||||
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
if (!reader->processed) {
|
||||
/* read the source document into memory */
|
||||
read_stream_into_memory(reader,
|
||||
&reader->contents,
|
||||
&reader->length);
|
||||
if (!reader->contents) {
|
||||
GST_ELEMENT_ERROR(GST_ELEMENT(reader),
|
||||
STREAM,
|
||||
WRONG_TYPE,
|
||||
("unable to process input"),
|
||||
(NULL));
|
||||
}
|
||||
reader->processed = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case GST_STATE_PLAYING_TO_PAUSED:
|
||||
break;
|
||||
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
if (reader->bytestream) {
|
||||
gst_bytestream_destroy(reader->bytestream);
|
||||
reader->bytestream = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GST_STATE_READY_TO_NULL:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CLASS(parent_class)->change_state) {
|
||||
return GST_ELEMENT_CLASS(parent_class)->change_state(element);
|
||||
}
|
||||
|
||||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* The dispose function.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_one_shot_reader_dispose(GObject * object)
|
||||
{
|
||||
LivesupportOneShotReader * reader = LIVESUPPORT_ONE_SHOT_READER(object);
|
||||
|
||||
if (reader->bytestream) {
|
||||
gst_bytestream_destroy(reader->bytestream);
|
||||
reader->bytestream = 0;
|
||||
}
|
||||
if (reader->contents) {
|
||||
g_free(reader->contents);
|
||||
reader->contents = 0;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize a OneShotReader element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_one_shot_reader_init(LivesupportOneShotReader * reader)
|
||||
{
|
||||
reader->sinkpad = gst_pad_new("sink", GST_PAD_SINK);
|
||||
gst_element_add_pad(GST_ELEMENT(reader), reader->sinkpad);
|
||||
gst_pad_set_link_function(reader->sinkpad,
|
||||
GST_DEBUG_FUNCPTR(gst_pad_proxy_pad_link));
|
||||
gst_pad_set_getcaps_function(reader->sinkpad,
|
||||
GST_DEBUG_FUNCPTR(gst_pad_proxy_getcaps));
|
||||
|
||||
gst_element_set_loop_function(GST_ELEMENT(reader),
|
||||
livesupport_one_shot_reader_loop);
|
||||
|
||||
reader->bytestream = 0;
|
||||
reader->contents = 0;
|
||||
reader->length = 0L;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Do base initialization on the element's class.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_one_shot_reader_base_init(gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);
|
||||
|
||||
gst_element_class_set_details(element_class,
|
||||
&livesupport_one_shot_reader_details);
|
||||
|
||||
gst_element_class_add_pad_template(element_class,
|
||||
gst_static_pad_template_get(&sink_factory));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize the element's class.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_one_shot_reader_class_init(LivesupportOneShotReaderClass * klass)
|
||||
{
|
||||
GObjectClass * gobject_class;
|
||||
GstElementClass * gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->dispose = livesupport_one_shot_reader_dispose;
|
||||
gstelement_class->change_state = livesupport_one_shot_reader_change_state;
|
||||
|
||||
g_object_class_install_property(gobject_class,
|
||||
ARG_CONTENTS,
|
||||
g_param_spec_pointer("contents",
|
||||
"contents",
|
||||
"the contents read "
|
||||
", a 0-terminated array",
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property(gobject_class,
|
||||
ARG_LENGTH,
|
||||
g_param_spec_uint("length",
|
||||
"length",
|
||||
"the length of the contents read",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
gobject_class->get_property = get_property;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Return the appropriate type for the element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
GType
|
||||
livesupport_one_shot_reader_get_type(void)
|
||||
{
|
||||
static GType one_shot_reader_type = 0;
|
||||
|
||||
if (!one_shot_reader_type) {
|
||||
static const GTypeInfo one_shot_reader_info = {
|
||||
sizeof (LivesupportOneShotReaderClass),
|
||||
livesupport_one_shot_reader_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) livesupport_one_shot_reader_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (LivesupportOneShotReader),
|
||||
0,
|
||||
(GInstanceInitFunc) livesupport_one_shot_reader_init,
|
||||
};
|
||||
|
||||
one_shot_reader_type = g_type_register_static(GST_TYPE_ELEMENT,
|
||||
"LivesupportOneShotReader",
|
||||
&one_shot_reader_info,
|
||||
0);
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT(one_shot_reader_debug,
|
||||
"oneshotreader",
|
||||
0,
|
||||
"a one-shot reader");
|
||||
}
|
||||
|
||||
return one_shot_reader_type;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* The plugin initialization function.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gboolean
|
||||
plugin_init(GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_library_load("gstbytestream")) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gst_element_register(plugin,
|
||||
"oneshotreader",
|
||||
GST_RANK_NONE,
|
||||
LIVESUPPORT_TYPE_ONE_SHOT_READER);
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef LivesSupport_GstreamerElements_OneShotReader_h
|
||||
#define LivesSupport_GstreamerElements_OneShotReader_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* A gstreamer element that reads all input from it's sink pad, and
|
||||
* returns it in one byte array.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/bytestream/bytestream.h>
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define LIVESUPPORT_TYPE_ONE_SHOT_READER \
|
||||
(livesupport_one_shot_reader_get_type())
|
||||
|
||||
#define LIVESUPPORT_ONE_SHOT_READER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
LIVESUPPORT_TYPE_ONE_SHOT_READER, \
|
||||
LivesupportOneShotReader))
|
||||
|
||||
#define LIVESUPPORT_ONE_SHOT_READER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
LIVESUPPORT_TYPE_ONE_SHOT_READER, \
|
||||
LivesupportOneShotReader))
|
||||
|
||||
#define GST_IS_ONE_SHOT_READER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), LIVESUPPORT_TYPE_ONE_SHOT_READER))
|
||||
|
||||
#define GST_IS_ONE_SHOT_READER_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), LIVESUPPORT_TYPE_ONE_SHOT_READER))
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
typedef struct _LivesupportOneShotReader LivesupportOneShotReader;
|
||||
typedef struct _LivesupportOneShotReaderClass LivesupportOneShotReaderClass;
|
||||
|
||||
/**
|
||||
* The OneShotReader structure.
|
||||
*/
|
||||
struct _LivesupportOneShotReader {
|
||||
GstElement parent;
|
||||
|
||||
GstPad * sinkpad;
|
||||
|
||||
GstByteStream * bytestream;
|
||||
gboolean processed;
|
||||
guint8 * contents;
|
||||
guint32 length;
|
||||
};
|
||||
|
||||
/**
|
||||
* The class of the OneShotReader.
|
||||
*/
|
||||
struct _LivesupportOneShotReaderClass {
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* The plugin initialization function.
|
||||
*
|
||||
* @param plugin the plugin itself.
|
||||
* @return TRUE if initialization was successful, FALSE otherwise.
|
||||
*/
|
||||
static gboolean
|
||||
plugin_init(GstPlugin * plugin);
|
||||
|
||||
/**
|
||||
* Return the appropriate type for the element.
|
||||
*
|
||||
* @return the type structure of the element.
|
||||
*/
|
||||
GType
|
||||
livesupport_one_shot_reader_get_type(void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* LivesSupport_GstreamerElements_OneShotReader_h */
|
|
@ -1,539 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#error need string.h
|
||||
#endif
|
||||
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "partial-play.h"
|
||||
#include "smil-util.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
/**
|
||||
* The arguments this element supports.
|
||||
*/
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_LOCATION,
|
||||
ARG_CONFIG
|
||||
};
|
||||
|
||||
/**
|
||||
* The factory for the source pad.
|
||||
*/
|
||||
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE (
|
||||
"src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS("audio/x-raw-int, "
|
||||
"width = (int) 16, "
|
||||
"depth = (int) 16, "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"channels = (int) { 1, 2 }, "
|
||||
"rate = (int) [ 8000, 96000 ]")
|
||||
);
|
||||
|
||||
/**
|
||||
* The parent class of PartialPlay.
|
||||
*/
|
||||
static GstBinClass * parent_class = NULL;
|
||||
|
||||
/**
|
||||
* The plugin definition structure.
|
||||
*/
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"partialplay",
|
||||
"Partial play",
|
||||
plugin_init,
|
||||
"$Revision$",
|
||||
"GPL",
|
||||
"LiveSupport",
|
||||
"http://campcaster.campware.org/"
|
||||
)
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Initializer function for the PartialPlay class.
|
||||
*
|
||||
* @para klass the class to initialize.
|
||||
*/
|
||||
static void
|
||||
livesupport_partial_play_class_init(LivesupportPartialPlayClass * klass);
|
||||
|
||||
/**
|
||||
* Base initializer for the PartialPlay plugin.
|
||||
*
|
||||
* @param klass the PartialPlay class.
|
||||
*/
|
||||
static void
|
||||
livesupport_partial_play_base_init(LivesupportPartialPlayClass * klass);
|
||||
|
||||
/**
|
||||
* Signal handler for the eos event of the SeekPack->bin element.
|
||||
*
|
||||
* @param element the element emitting the eos signal
|
||||
* @param userData pointer to the container bin of the switcher,
|
||||
* which is this PartialPlay element
|
||||
*/
|
||||
static void
|
||||
seek_pack_eos_signal_handler(GstElement * element,
|
||||
gpointer userData);
|
||||
|
||||
/**
|
||||
* PartialPlay instance initializer.
|
||||
*
|
||||
* @param pplay the PartialPlay object to initialize.
|
||||
*/
|
||||
static void
|
||||
livesupport_partial_play_init(LivesupportPartialPlay * pplay);
|
||||
|
||||
/**
|
||||
* Destroy a PartialPlay object.
|
||||
*
|
||||
* @param object the PartialPlay object to destroy.
|
||||
*/
|
||||
static void
|
||||
livesupport_partial_play_dispose(GObject * object);
|
||||
|
||||
/**
|
||||
* Set a property for a PartialPlay object.
|
||||
*
|
||||
* @param object the PartialPlay object.
|
||||
* @param prop_id the property id.
|
||||
* @param value the value to set.
|
||||
* @param pspec the property specification
|
||||
*/
|
||||
static void
|
||||
livesupport_partial_play_set_property(GObject * object,
|
||||
guint prop_id,
|
||||
const GValue * value,
|
||||
GParamSpec * pspec);
|
||||
|
||||
/**
|
||||
* Get a property from a PartialPlay object.
|
||||
*
|
||||
* @param object the PartialPlay object.
|
||||
* @param prop_id the property id.
|
||||
* @param value the value to return the property in (out parameter).
|
||||
* @param pspec the property specification.
|
||||
*/
|
||||
static void
|
||||
livesupport_partial_play_get_property(GObject * object,
|
||||
guint prop_id,
|
||||
GValue * value,
|
||||
GParamSpec * pspec);
|
||||
|
||||
/**
|
||||
* Return the type structure for the PartialPlay plugin.
|
||||
*
|
||||
* @return the type structure for the PartialPlay plugin.
|
||||
*/
|
||||
GType
|
||||
livesupport_partial_play_get_type(void);
|
||||
|
||||
/**
|
||||
* Handle the state change on a PartialPlay object.
|
||||
*
|
||||
* @param element the PartialPlay object.
|
||||
* @return GST_STATE_SUCCES if the state change was successful,
|
||||
* GST_STATE_FAILURE on failure.
|
||||
*/
|
||||
static GstElementStateReturn
|
||||
livesupport_partial_play_change_state(GstElement * element);
|
||||
|
||||
/**
|
||||
* Update the source configration for a PartialPlay object.
|
||||
* This should be called after each update to the config string.
|
||||
*
|
||||
* @param pplay the partial play object.
|
||||
*/
|
||||
static void
|
||||
update_source_config(LivesupportPartialPlay * pplay);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Return the type structure for the PartialPlay plugin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
GType
|
||||
livesupport_partial_play_get_type(void)
|
||||
{
|
||||
static GType plugin_type = 0;
|
||||
|
||||
if (!plugin_type) {
|
||||
static const GTypeInfo plugin_info = {
|
||||
sizeof (LivesupportPartialPlayClass),
|
||||
(GBaseInitFunc) livesupport_partial_play_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) livesupport_partial_play_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (LivesupportPartialPlay),
|
||||
0,
|
||||
(GInstanceInitFunc) livesupport_partial_play_init,
|
||||
};
|
||||
|
||||
plugin_type = g_type_register_static(GST_TYPE_BIN,
|
||||
"LivesupportPartialPlay",
|
||||
&plugin_info, 0);
|
||||
}
|
||||
|
||||
return plugin_type;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Handle the state change for a partial play object.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static GstElementStateReturn
|
||||
livesupport_partial_play_change_state(GstElement * element)
|
||||
{
|
||||
LivesupportPartialPlay * pplay;
|
||||
|
||||
pplay = LIVESUPPORT_PARTIAL_PLAY(element);
|
||||
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_NULL_TO_READY:
|
||||
livesupport_seek_pack_set_state(pplay->seekPack, GST_STATE_READY);
|
||||
break;
|
||||
|
||||
case GST_STATE_READY_TO_PAUSED:
|
||||
livesupport_seek_pack_set_state(pplay->seekPack, GST_STATE_PAUSED);
|
||||
break;
|
||||
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
if (!pplay->seekPackInited) {
|
||||
pplay->seekPackInited = TRUE;
|
||||
if (pplay->source) {
|
||||
g_object_unref(pplay->source);
|
||||
}
|
||||
/* TODO: check for NULL returns here */
|
||||
pplay->source = gst_element_factory_make("filesrc", "source");
|
||||
g_object_set(G_OBJECT(pplay->source),
|
||||
"location",
|
||||
pplay->location,
|
||||
NULL);
|
||||
|
||||
livesupport_seek_pack_init(pplay->seekPack,
|
||||
pplay->source,
|
||||
pplay->silenceDuration,
|
||||
pplay->playFrom,
|
||||
pplay->playTo);
|
||||
}
|
||||
livesupport_seek_pack_set_state(pplay->seekPack, GST_STATE_PLAYING);
|
||||
break;
|
||||
|
||||
case GST_STATE_PLAYING_TO_PAUSED:
|
||||
livesupport_seek_pack_set_state(pplay->seekPack, GST_STATE_PAUSED);
|
||||
break;
|
||||
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
livesupport_seek_pack_set_state(pplay->seekPack, GST_STATE_READY);
|
||||
/* TODO: maybe de-init seekPack somehow? */
|
||||
break;
|
||||
|
||||
case GST_STATE_READY_TO_NULL:
|
||||
livesupport_seek_pack_set_state(pplay->seekPack, GST_STATE_NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CLASS(parent_class)->change_state) {
|
||||
return GST_ELEMENT_CLASS(parent_class)->change_state(element);
|
||||
}
|
||||
|
||||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Do base initialization.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_partial_play_base_init(LivesupportPartialPlayClass * klass)
|
||||
{
|
||||
static GstElementDetails plugin_details = {
|
||||
"PartialPlay",
|
||||
"Audio/PartialPlay",
|
||||
"A filter that plays an audio source partially",
|
||||
"Akos Maroy <maroy@campware.org>"
|
||||
};
|
||||
GstElementClass * element_class = GST_ELEMENT_CLASS(klass);
|
||||
|
||||
gst_element_class_add_pad_template(element_class,
|
||||
gst_static_pad_template_get(&src_factory));
|
||||
gst_element_class_set_details(element_class, &plugin_details);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize the plugin's class
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_partial_play_class_init(LivesupportPartialPlayClass * klass)
|
||||
{
|
||||
GObjectClass * gobject_class;
|
||||
GstElementClass * gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass*) klass;
|
||||
gstelement_class = (GstElementClass*) klass;
|
||||
|
||||
parent_class = g_type_class_ref(GST_TYPE_BIN);
|
||||
|
||||
gobject_class->dispose = livesupport_partial_play_dispose;
|
||||
|
||||
g_object_class_install_property(gobject_class,
|
||||
ARG_LOCATION,
|
||||
g_param_spec_string("location",
|
||||
"Location",
|
||||
"Location of the file to read",
|
||||
"",
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(gobject_class,
|
||||
ARG_CONFIG,
|
||||
g_param_spec_string("config",
|
||||
"Play configuration",
|
||||
"specify the silence and play details",
|
||||
"",
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
gobject_class->set_property = livesupport_partial_play_set_property;
|
||||
gobject_class->get_property = livesupport_partial_play_get_property;
|
||||
|
||||
gstelement_class->change_state = livesupport_partial_play_change_state;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* eos signal handler for the seekPack->bin element
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
seek_pack_eos_signal_handler(GstElement * element,
|
||||
gpointer userData)
|
||||
{
|
||||
GstElement * container = GST_ELEMENT(userData);
|
||||
|
||||
g_return_if_fail(container != NULL);
|
||||
g_return_if_fail(GST_IS_ELEMENT(container));
|
||||
|
||||
/* set the container into eos state */
|
||||
|
||||
GST_DEBUG("SeekPack.bin setting PartialPlay to eos");
|
||||
gst_element_set_eos(container);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize a new PartialPlay element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_partial_play_init(LivesupportPartialPlay * pplay)
|
||||
{
|
||||
pplay->caps = gst_caps_new_simple("audio/x-raw-int",
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"channels", G_TYPE_INT, 2,
|
||||
"rate", G_TYPE_INT, 44100,
|
||||
NULL);
|
||||
|
||||
pplay->seekPack = livesupport_seek_pack_new("seekPack", pplay->caps);
|
||||
pplay->seekPackInited = FALSE;
|
||||
|
||||
livesupport_seek_pack_add_to_bin(pplay->seekPack, GST_BIN(pplay));
|
||||
pplay->srcpad = gst_element_add_ghost_pad(GST_ELEMENT(pplay),
|
||||
gst_element_get_pad(pplay->seekPack->bin, "src"),
|
||||
"src");
|
||||
|
||||
g_signal_connect(pplay->seekPack->bin,
|
||||
"eos",
|
||||
G_CALLBACK(seek_pack_eos_signal_handler),
|
||||
pplay);
|
||||
|
||||
pplay->location = g_strdup("");
|
||||
pplay->config = g_strdup("");
|
||||
pplay->silenceDuration = 0LL;
|
||||
pplay->playFrom = 0LL;
|
||||
pplay->playTo = 0LL;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Destroy a PartialPlay object.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_partial_play_dispose(GObject * object)
|
||||
{
|
||||
LivesupportPartialPlay * pplay;
|
||||
|
||||
g_return_if_fail(LIVESUPPORT_IS_PARTIAL_PLAY(object));
|
||||
pplay = LIVESUPPORT_PARTIAL_PLAY(object);
|
||||
|
||||
gst_caps_free(pplay->caps);
|
||||
g_free(pplay->location);
|
||||
g_free(pplay->config);
|
||||
G_OBJECT_CLASS(parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Update the source config.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
update_source_config(LivesupportPartialPlay * pplay)
|
||||
{
|
||||
gchar ** tokens;
|
||||
gchar * token;
|
||||
guint i = 0;
|
||||
|
||||
tokens = g_strsplit(pplay->config, ";", 0);
|
||||
if ((token = tokens[i++])) {
|
||||
pplay->silenceDuration = smil_clock_value_to_nanosec(token);
|
||||
}
|
||||
if ((token = tokens[i++])) {
|
||||
gint len = strlen(token);
|
||||
gchar * from = g_malloc(sizeof(gchar) * len + 1);
|
||||
gchar * to = g_malloc(sizeof(gchar) * len + 1);
|
||||
|
||||
if (sscanf(token, "%[^-]-%s", from, to) == 2) {
|
||||
pplay->playFrom = smil_clock_value_to_nanosec(from);
|
||||
pplay->playTo = smil_clock_value_to_nanosec(to);
|
||||
} else if (sscanf(token, "%[^-]-", from) == 1) {
|
||||
pplay->playFrom = smil_clock_value_to_nanosec(from);
|
||||
pplay->playTo = -1LL;
|
||||
}
|
||||
|
||||
g_free(to);
|
||||
g_free(from);
|
||||
}
|
||||
|
||||
g_strfreev(tokens);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set a property.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_partial_play_set_property(GObject * object,
|
||||
guint prop_id,
|
||||
const GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
LivesupportPartialPlay * pplay;
|
||||
|
||||
g_return_if_fail(LIVESUPPORT_IS_PARTIAL_PLAY(object));
|
||||
pplay = LIVESUPPORT_PARTIAL_PLAY(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_LOCATION:
|
||||
if (pplay->location) {
|
||||
g_free(pplay->location);
|
||||
}
|
||||
pplay->location = g_strdup(g_value_get_string(value));
|
||||
break;
|
||||
|
||||
case ARG_CONFIG:
|
||||
if (pplay->config) {
|
||||
g_free(pplay->config);
|
||||
}
|
||||
pplay->config = g_strdup(g_value_get_string(value));
|
||||
update_source_config(pplay);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Get a property.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_partial_play_get_property(GObject * object,
|
||||
guint prop_id,
|
||||
GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
LivesupportPartialPlay * pplay;
|
||||
|
||||
g_return_if_fail(LIVESUPPORT_IS_PARTIAL_PLAY(object));
|
||||
pplay = LIVESUPPORT_PARTIAL_PLAY(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_LOCATION:
|
||||
g_value_set_string(value, pplay->location);
|
||||
break;
|
||||
|
||||
case ARG_CONFIG:
|
||||
g_value_set_string(value, pplay->config);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize the plugin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gboolean
|
||||
plugin_init(GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register(plugin,
|
||||
"partialplay",
|
||||
GST_RANK_NONE,
|
||||
LIVESUPPORT_TYPE_PARTIAL_PLAY);
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef LivesSupport_GstreamerElements_PartialPlay_h
|
||||
#define LivesSupport_GstreamerElements_PartialPlay_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* A gstreamer element that plays its source partially, first by playing
|
||||
* some specified silence, then playing the source from a specified
|
||||
* offset until a specified offset.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "seek-pack.h"
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define LIVESUPPORT_TYPE_PARTIAL_PLAY \
|
||||
(livesupport_partial_play_get_type())
|
||||
|
||||
#define LIVESUPPORT_PARTIAL_PLAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
LIVESUPPORT_TYPE_PARTIAL_PLAY, \
|
||||
LivesupportPartialPlay))
|
||||
|
||||
#define LIVESUPPORT_PARTIAL_PLAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
LIVESUPPORT_TYPE_PARTIAL_PLAY, \
|
||||
LivesupportPartialPlay))
|
||||
|
||||
#define LIVESUPPORT_IS_PARTIAL_PLAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), \
|
||||
LIVESUPPORT_TYPE_PARTIAL_PLAY))
|
||||
|
||||
#define LIVESUPPORT_IS_PARTIAL_PLAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),LIVESUPPORT_TYPE_PARTIAL_PLAY))
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
typedef struct _LivesupportPartialPlay LivesupportPartialPlay;
|
||||
typedef struct _LivesupportPartialPlayClass LivesupportPartialPlayClass;
|
||||
|
||||
/**
|
||||
* The PartialPlay structure.
|
||||
*/
|
||||
struct _LivesupportPartialPlay
|
||||
{
|
||||
GstBin parent;
|
||||
|
||||
GstCaps * caps;
|
||||
|
||||
GstPad * srcpad;
|
||||
GstElement * source;
|
||||
LivesupportSeekPack * seekPack;
|
||||
gboolean seekPackInited;
|
||||
|
||||
gchar * location;
|
||||
gchar * config;
|
||||
gint64 silenceDuration;
|
||||
gint64 playFrom;
|
||||
gint64 playTo;
|
||||
};
|
||||
|
||||
/**
|
||||
* The PartialPlay class.
|
||||
*/
|
||||
struct _LivesupportPartialPlayClass
|
||||
{
|
||||
GstBinClass parent_class;
|
||||
};
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Initilize (register, etc.) the plugin.
|
||||
*
|
||||
* @param plugin the plugin itself.
|
||||
* @return TRUE if initialization was successful, FALSE otherwise.
|
||||
*/
|
||||
static gboolean
|
||||
plugin_init(GstPlugin * plugin);
|
||||
|
||||
/**
|
||||
* Return the appropriate type for the element.
|
||||
*
|
||||
* @return the type structure of the element.
|
||||
*/
|
||||
GType livesupport_partial_play_get_type(void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* LivesSupport_GstreamerElements_PartialPlay_h */
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "LiveSupport/GstreamerElements/autoplug.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param argc the number of command line arguments.
|
||||
* @param argv the command line argument array.
|
||||
* @return 0 on success, non-0 on failure.
|
||||
*/
|
||||
int
|
||||
main(int argc,
|
||||
char ** argv);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Program entry point.
|
||||
*----------------------------------------------------------------------------*/
|
||||
int
|
||||
main(int argc,
|
||||
char ** argv)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * source;
|
||||
GstElement * decoder;
|
||||
GstElement * sink;
|
||||
GstCaps * caps;
|
||||
GstFormat format;
|
||||
gint64 timePlayed;
|
||||
|
||||
/* initialize GStreamer */
|
||||
gst_init(&argc, &argv);
|
||||
|
||||
caps = gst_caps_new_simple("audio/x-raw-int",
|
||||
"width", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
"channels", G_TYPE_INT, 2,
|
||||
"rate", G_TYPE_INT, 44100,
|
||||
NULL);
|
||||
|
||||
if (argc != 2) {
|
||||
g_print("Usage: %s <audio filename>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new("audio-player");
|
||||
source = gst_element_factory_make("filesrc", "source");
|
||||
sink = gst_element_factory_make("alsasink", "alsa-output");
|
||||
|
||||
g_object_set(G_OBJECT(source), "location", argv[1], NULL);
|
||||
|
||||
decoder = ls_gst_autoplug_plug_source(source, "decoder", caps);
|
||||
|
||||
if (!decoder) {
|
||||
gst_object_unref(GST_OBJECT(sink));
|
||||
gst_object_unref(GST_OBJECT(source));
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
gst_element_link(decoder, sink);
|
||||
gst_bin_add_many(GST_BIN(pipeline), source, decoder, sink, NULL);
|
||||
|
||||
gst_element_set_state(source, GST_STATE_PAUSED);
|
||||
gst_element_set_state(decoder, GST_STATE_PAUSED);
|
||||
gst_element_set_state(sink, GST_STATE_PAUSED);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
// iterate until playTo is reached
|
||||
while (gst_bin_iterate(GST_BIN(pipeline)));
|
||||
|
||||
format = GST_FORMAT_TIME;
|
||||
gst_element_query(sink, GST_QUERY_POSITION, &format, &timePlayed);
|
||||
|
||||
g_print("time played: %" G_GINT64_FORMAT " ns\n", timePlayed);
|
||||
|
||||
/* clean up nicely */
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,375 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#error need string.h
|
||||
#endif
|
||||
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "LiveSupport/GstreamerElements/autoplug.h"
|
||||
#include "util.h"
|
||||
#include "seek.h"
|
||||
#include "seek-pack.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
#define NSEC_PER_SEC 1000000000LL
|
||||
#define SEC_PER_MIN 60
|
||||
#define SEC_PER_HOUR 3600
|
||||
#define NSEC_PER_SEC_FLOAT 1000000000.0
|
||||
#define SEC_PER_MIN_FLOAT 60.0
|
||||
#define SEC_PER_HOUR_FLOAT 3600.0
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Signal handler for the eos event of the switcher element.
|
||||
*
|
||||
* @param element the element emitting the eos signal
|
||||
* @param userData pointer to the container bin of the switcher.
|
||||
*/
|
||||
static void
|
||||
switcher_eos_signal_handler(GstElement * element,
|
||||
gpointer userData);
|
||||
|
||||
/**
|
||||
* Perform the seeks on the SeekPack, set by the initialization function.
|
||||
*
|
||||
* @param seekPack the SeekPack to perform the seek on.
|
||||
* @see #livesupport_seek_pack_init
|
||||
*/
|
||||
static void
|
||||
livesupport_seek_pack_seek(LivesupportSeekPack * seekPack);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* eos signal handler for the switcher element
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
switcher_eos_signal_handler(GstElement * element,
|
||||
gpointer userData)
|
||||
{
|
||||
GstElement * container = GST_ELEMENT(userData);
|
||||
|
||||
g_return_if_fail(container != NULL);
|
||||
g_return_if_fail(GST_IS_ELEMENT(container));
|
||||
|
||||
/* set the container into eos state */
|
||||
GST_DEBUG("SeekPack.switcher setting SeekPack.bin to eos");
|
||||
gst_element_set_eos(container);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Create a new SeekPack.
|
||||
*----------------------------------------------------------------------------*/
|
||||
LivesupportSeekPack *
|
||||
livesupport_seek_pack_new(const gchar * uniqueName,
|
||||
const GstCaps * caps)
|
||||
{
|
||||
unsigned int len = strlen(uniqueName) + 64;
|
||||
gchar * str = g_malloc(len);
|
||||
LivesupportSeekPack * seekPack = g_malloc(sizeof(LivesupportSeekPack));
|
||||
GValue gvalue = { 0 };
|
||||
|
||||
seekPack->name = g_strdup(uniqueName);
|
||||
|
||||
seekPack->caps = gst_caps_copy(caps);
|
||||
|
||||
g_snprintf(str, len, "%s_seekPackSilence", uniqueName);
|
||||
seekPack->silence = gst_element_factory_make("silence", str);
|
||||
|
||||
seekPack->source = NULL;
|
||||
|
||||
/* generate decoder later, by autoplugging */
|
||||
seekPack->decoder = 0;
|
||||
seekPack->decoderScale = 0;
|
||||
g_snprintf(str, len, "%s_seekPackSwitcher", uniqueName);
|
||||
seekPack->switcher = gst_element_factory_make("switcher", str);
|
||||
g_snprintf(str, len, "%s_seekPackBin", uniqueName);
|
||||
seekPack->bin = gst_bin_new(str);
|
||||
g_free(str);
|
||||
|
||||
g_value_init(&gvalue, G_TYPE_POINTER);
|
||||
g_value_set_pointer(&gvalue, seekPack->caps);
|
||||
gst_element_set_property(seekPack->switcher, "caps", &gvalue);
|
||||
g_value_unset(&gvalue);
|
||||
|
||||
g_signal_connect(seekPack->switcher,
|
||||
"eos",
|
||||
G_CALLBACK(switcher_eos_signal_handler),
|
||||
seekPack->bin);
|
||||
|
||||
seekPack->silenceDuration = 0LL;
|
||||
seekPack->startTime = 0LL;
|
||||
seekPack->endTime = 0LL;
|
||||
seekPack->duration = 0LL;
|
||||
seekPack->positionAfterSeek = 0LL;
|
||||
seekPack->realEndTime = 0LL;
|
||||
|
||||
seekPack->sendingSilence = TRUE;
|
||||
|
||||
gst_element_add_ghost_pad(seekPack->bin,
|
||||
gst_element_get_pad(seekPack->switcher, "src"),
|
||||
"src");
|
||||
|
||||
return seekPack;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize a SeekPack.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
livesupport_seek_pack_init(LivesupportSeekPack * seekPack,
|
||||
GstElement * source,
|
||||
gint64 silenceDuration,
|
||||
gint64 startTime,
|
||||
gint64 endTime)
|
||||
{
|
||||
GValue gvalue = { 0 };
|
||||
gchar str[256];
|
||||
unsigned int len = strlen(seekPack->name) + 64;
|
||||
gchar * name = g_malloc(len);
|
||||
|
||||
seekPack->source = source;
|
||||
|
||||
seekPack->silenceDuration = silenceDuration;
|
||||
seekPack->startTime = startTime;
|
||||
seekPack->endTime = endTime;
|
||||
seekPack->duration = endTime - startTime;
|
||||
seekPack->positionAfterSeek = 0LL;
|
||||
seekPack->realEndTime = 0LL;
|
||||
|
||||
g_value_init(&gvalue, G_TYPE_STRING);
|
||||
if (seekPack->endTime >= 0) {
|
||||
g_snprintf(str, 256, "0[%lfs];1[%lfs]",
|
||||
seekPack->silenceDuration / NSEC_PER_SEC_FLOAT,
|
||||
seekPack->duration / NSEC_PER_SEC_FLOAT);
|
||||
} else {
|
||||
g_snprintf(str, 256, "0[%lfs];1[]",
|
||||
seekPack->silenceDuration / NSEC_PER_SEC_FLOAT);
|
||||
}
|
||||
g_value_set_string(&gvalue, str);
|
||||
gst_element_set_property(seekPack->switcher, "source-config", &gvalue);
|
||||
g_value_unset(&gvalue);
|
||||
|
||||
g_snprintf(name, len, "%s_seekPackDecoder", seekPack->name);
|
||||
seekPack->decoder = ls_gst_autoplug_plug_source(seekPack->source,
|
||||
name,
|
||||
seekPack->caps);
|
||||
/* TODO: only add scale element if needed */
|
||||
g_snprintf(name, len, "%s_seekPackDecoderScale", seekPack->name);
|
||||
seekPack->decoderScale = gst_element_factory_make("audioscale", name);
|
||||
g_free(name);
|
||||
|
||||
/* link up the silence element with the switcher first */
|
||||
gst_element_link_filtered(seekPack->silence,
|
||||
seekPack->switcher,
|
||||
seekPack->caps);
|
||||
|
||||
if (seekPack->decoder) {
|
||||
/* seek on the decoder, and link it up with the switcher */
|
||||
gst_element_link(seekPack->source, seekPack->decoder);
|
||||
livesupport_seek_pack_seek(seekPack);
|
||||
} else {
|
||||
/* just fake the content with silence,
|
||||
* if it could not be auto-plugged */
|
||||
seekPack->decoder = gst_element_factory_make("silence", "decoder");
|
||||
}
|
||||
gst_element_link_many(seekPack->decoder,
|
||||
seekPack->decoderScale,
|
||||
NULL);
|
||||
gst_element_link_filtered(seekPack->decoderScale,
|
||||
seekPack->switcher,
|
||||
seekPack->caps);
|
||||
|
||||
/* put all inside the bin, and link up a ghost pad to switch's src pad */
|
||||
gst_bin_add_many(GST_BIN(seekPack->bin),
|
||||
seekPack->silence,
|
||||
seekPack->source,
|
||||
seekPack->decoder,
|
||||
seekPack->decoderScale,
|
||||
NULL);
|
||||
|
||||
/* put the switcher last into the bin, and also link it as last
|
||||
* otherwise we'll get a:
|
||||
* "assertion failed: (group->group_links == NULL)"
|
||||
* error later on when trying to free up the pipeline
|
||||
* see http://bugzilla.gnome.org/show_bug.cgi?id=309122
|
||||
*/
|
||||
gst_bin_add(GST_BIN(seekPack->bin), seekPack->switcher);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Destroy a SeekPack.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
livesupport_seek_pack_destroy(LivesupportSeekPack * seekPack)
|
||||
{
|
||||
gst_element_set_state(seekPack->bin, GST_STATE_NULL);
|
||||
g_object_unref(seekPack->bin);
|
||||
gst_caps_free(seekPack->caps);
|
||||
g_free(seekPack->name);
|
||||
g_free(seekPack);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Link a SeekPack to another element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gboolean
|
||||
livesupport_seek_pack_link(LivesupportSeekPack * seekPack,
|
||||
GstElement * element)
|
||||
{
|
||||
return gst_element_link_filtered(seekPack->bin, element, seekPack->caps);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Add a SeekPack to a bin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
livesupport_seek_pack_add_to_bin(LivesupportSeekPack * seekPack,
|
||||
GstBin * bin)
|
||||
{
|
||||
/* put an extra ref on our elements, as the bin will decrease the
|
||||
* ref when they are removed from there */
|
||||
g_object_ref(seekPack->bin);
|
||||
gst_bin_add(bin, seekPack->bin);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Remove a SeekPack from a bin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
livesupport_seek_pack_remove_from_bin(LivesupportSeekPack * seekPack,
|
||||
GstBin * bin)
|
||||
{
|
||||
gst_bin_remove(bin, seekPack->bin);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set the state of a SeekPack.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
livesupport_seek_pack_set_state(LivesupportSeekPack * seekPack,
|
||||
GstElementState state)
|
||||
{
|
||||
/* FIXME: resetting the source from PLAYING state would make it lose
|
||||
* it's seek position */
|
||||
if (seekPack->silence) {
|
||||
gst_element_set_state(seekPack->silence, state);
|
||||
}
|
||||
if (seekPack->decoder) {
|
||||
gst_element_set_state(seekPack->decoder, state);
|
||||
}
|
||||
if (seekPack->decoderScale) {
|
||||
gst_element_set_state(seekPack->decoderScale, state);
|
||||
}
|
||||
if (seekPack->switcher) {
|
||||
gst_element_set_state(seekPack->switcher, state);
|
||||
}
|
||||
if (seekPack->bin) {
|
||||
gst_element_set_state(seekPack->bin, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Do the seeking on a SeekPack.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_seek_pack_seek(LivesupportSeekPack * seekPack)
|
||||
{
|
||||
GstElement * pipeline;
|
||||
GstElement * fakesink;
|
||||
gboolean ret;
|
||||
gint64 value;
|
||||
GstSeekType seekType;
|
||||
|
||||
seekType = (GstSeekType) (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH);
|
||||
pipeline = gst_pipeline_new("seek_pipeline");
|
||||
fakesink = gst_element_factory_make("fakesink", "seek_fakesink");
|
||||
|
||||
gst_element_link_filtered(seekPack->decoder, fakesink, seekPack->caps);
|
||||
/* ref the objects we want to keep after pipeline, as it will unref them */
|
||||
g_object_ref(seekPack->source);
|
||||
g_object_ref(seekPack->decoder);
|
||||
gst_bin_add_many(GST_BIN(pipeline),
|
||||
seekPack->source,
|
||||
seekPack->decoder,
|
||||
fakesink,
|
||||
NULL);
|
||||
|
||||
GST_DEBUG("setting seek pipeline to PLAYING state");
|
||||
gst_element_set_state(seekPack->decoder, GST_STATE_PAUSED);
|
||||
gst_element_set_state(fakesink, GST_STATE_PAUSED);
|
||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||
|
||||
GST_DEBUG("starting to iterate...");
|
||||
for (value = 0; value == 0 && gst_bin_iterate(GST_BIN(pipeline)); ) {
|
||||
GstFormat format = GST_FORMAT_DEFAULT;
|
||||
gst_element_query(fakesink, GST_QUERY_POSITION, &format, &value);
|
||||
GST_DEBUG("position value: %" G_GINT64_FORMAT, value);
|
||||
}
|
||||
GST_DEBUG("seeking on element");
|
||||
ret = livesupport_seek(seekPack->decoder, seekType, seekPack->startTime);
|
||||
GST_DEBUG("seek result: %d", ret);
|
||||
|
||||
gst_bin_remove_many(GST_BIN(pipeline),
|
||||
seekPack->source,
|
||||
seekPack->decoder,
|
||||
NULL);
|
||||
gst_element_unlink(seekPack->decoder, fakesink);
|
||||
gst_object_unref(GST_OBJECT(pipeline));
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef SeekPack_h
|
||||
#define SeekPack_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* A SeekPack - a structure that plays a gstreamer source by playing
|
||||
* some silence and then some specified part of the source.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "seek.h"
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
typedef struct _LivesupportSeekPack LivesupportSeekPack;
|
||||
|
||||
/**
|
||||
* A SeekPack structure.
|
||||
*/
|
||||
struct _LivesupportSeekPack {
|
||||
gchar * name;
|
||||
|
||||
GstCaps * caps;
|
||||
|
||||
GstElement * silence;
|
||||
|
||||
GstElement * source;
|
||||
GstElement * decoder;
|
||||
GstElement * decoderScale;
|
||||
|
||||
GstElement * switcher;
|
||||
GstElement * bin;
|
||||
|
||||
gint64 silenceDuration;
|
||||
gint64 startTime;
|
||||
gint64 endTime;
|
||||
gint64 duration;
|
||||
gint64 positionAfterSeek;
|
||||
gint64 realEndTime;
|
||||
|
||||
gboolean sendingSilence;
|
||||
};
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Create a new SeekPack.
|
||||
* Initialize the SeekPack before using it, and destroy after it's not
|
||||
* needed anymore.
|
||||
*
|
||||
* @param uniqueName a name unique in the SeekPack's context.
|
||||
* @param caps the desired capabilites on the src of the SeekPack
|
||||
* @return a new SeekPack.
|
||||
* @see #livesupport_seek_pack_init
|
||||
* @see #livesupport_seek_pack_destroy
|
||||
*/
|
||||
LivesupportSeekPack *
|
||||
livesupport_seek_pack_new(const gchar * uniqueName,
|
||||
const GstCaps * caps);
|
||||
|
||||
/**
|
||||
* Initialize a SeekPack.
|
||||
*
|
||||
* @param seekPack the SeekPack to initialize.
|
||||
* @param source the source the SeekPack will play.
|
||||
* @param silenceDuration the number of nanoseconds the SeekPack will
|
||||
* play only silence in the beginning.
|
||||
* @param startTime the offset at which source will start to play after
|
||||
* the silence.
|
||||
* @param endTime the offset until which source will play.
|
||||
*/
|
||||
void
|
||||
livesupport_seek_pack_init(LivesupportSeekPack * seekPack,
|
||||
GstElement * source,
|
||||
gint64 silenceDuration,
|
||||
gint64 startTime,
|
||||
gint64 endTime);
|
||||
|
||||
/**
|
||||
* Destory a SeekPack.
|
||||
*
|
||||
* @param seekPack the SeekPack to destroy.
|
||||
*/
|
||||
void
|
||||
livesupport_seek_pack_destroy(LivesupportSeekPack * seekPack);
|
||||
|
||||
/**
|
||||
* Link a SeekPack to an element.
|
||||
*
|
||||
* @param seekPack the SeekPack to link.
|
||||
* @param element the element to link to.
|
||||
* @return TRUE if linking was successful, FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
livesupport_seek_pack_link(LivesupportSeekPack * seekPack,
|
||||
GstElement * element);
|
||||
|
||||
/**
|
||||
* Add a SeekPack to a bin.
|
||||
*
|
||||
* @param seekPack the SeekPack to add.
|
||||
* @param bin the bin to add to.
|
||||
*/
|
||||
void
|
||||
livesupport_seek_pack_add_to_bin(LivesupportSeekPack * seekPack,
|
||||
GstBin * bin);
|
||||
|
||||
/**
|
||||
* Remove a SeekPack from a bin.
|
||||
*
|
||||
* @param seekPack the SeekPack to remove.
|
||||
* @param bin the bin to remove from.
|
||||
*/
|
||||
void
|
||||
livesupport_seek_pack_remove_from_bin(LivesupportSeekPack * seekPack,
|
||||
GstBin * bin);
|
||||
|
||||
/**
|
||||
* Set the state of a SeekPack.
|
||||
*
|
||||
* @param seekPack the SeekPack to set the state for.
|
||||
* @param state the new state of the SeekPack.
|
||||
*/
|
||||
void
|
||||
livesupport_seek_pack_set_state(LivesupportSeekPack * seekPack,
|
||||
GstElementState state);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SeekPack_h */
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include "util.h"
|
||||
#include "seek.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
/**
|
||||
* Define PAD_PUSH if seeking on an src pad should be done with
|
||||
* pushin a new seek event down the pad.
|
||||
* Otherwise, the event will be sent normally.
|
||||
*/
|
||||
#undef PAD_PUSH
|
||||
|
||||
/**
|
||||
* Define SEEK_ELEMENT if seeking should be done by seeking on an element
|
||||
* itself. Otherwise, the seek will be done on the first src pad of
|
||||
* the element.
|
||||
*/
|
||||
#undef SEEK_ELEMENT
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
#ifdef SEEK_ELEMENT
|
||||
/**
|
||||
* Seek on an element.
|
||||
*
|
||||
* @param element the element to seek on.
|
||||
* @param seekType the type of seek.
|
||||
* @param seekTime the seek time in nanoseconds.
|
||||
* @return TRUE if seeking was successfult, FALSE otherwise.
|
||||
*/
|
||||
static gboolean
|
||||
seek_element(GstElement * element,
|
||||
GstSeekType seekType,
|
||||
gint64 seekTime);
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_ELEMENT
|
||||
/**
|
||||
* Seek on the first src pad of an element.
|
||||
*
|
||||
* @param element the element to seek on.
|
||||
* @param seekType the type of seek.
|
||||
* @param seekTime the time of seek, in nanoseconds.
|
||||
* @return TRUE if seeking was successfult, FALSE otherwise.
|
||||
*/
|
||||
static gboolean
|
||||
seek_src_pad(GstElement * element,
|
||||
GstSeekType seekType,
|
||||
gint64 seekTime);
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
#ifdef SEEK_ELEMENT
|
||||
/*------------------------------------------------------------------------------
|
||||
* Seek on an element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gboolean
|
||||
seek_element(GstElement * element,
|
||||
GstSeekType seekType,
|
||||
gint64 seekTime)
|
||||
{
|
||||
return gst_element_seek(element, seekType, seekTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SEEK_ELEMENT
|
||||
/*------------------------------------------------------------------------------
|
||||
* Seek on the first src pad of an element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gboolean
|
||||
seek_src_pad(GstElement * element,
|
||||
GstSeekType seekType,
|
||||
gint64 seekTime)
|
||||
{
|
||||
GstPad * pad;
|
||||
GstEvent * seek;
|
||||
|
||||
if ((pad = get_src_pad(element))) {
|
||||
seek = gst_event_new_seek(seekType, seekTime);
|
||||
#ifdef PAD_PUSH
|
||||
gst_pad_push(pad, GST_DATA(seek));
|
||||
return TRUE;
|
||||
#else
|
||||
return gst_pad_send_event(pad, seek);
|
||||
#endif
|
||||
}
|
||||
|
||||
GST_WARNING("element doesn't have a src pad");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Seek on an element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gboolean
|
||||
livesupport_seek(GstElement * element,
|
||||
GstSeekType seekType,
|
||||
gint64 seekTime)
|
||||
{
|
||||
#ifdef SEEK_ELEMENT
|
||||
return seek_element(element, seekType, seekTime);
|
||||
#else
|
||||
return seek_src_pad(element, seekType, seekTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Helper function to make it easy to seek for a number of seconds.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gboolean
|
||||
livesupport_seek_seconds(GstElement * element,
|
||||
gint64 seconds)
|
||||
{
|
||||
GstSeekType seekType;
|
||||
gint64 seekTime;
|
||||
|
||||
seekType = (GstSeekType) (GST_FORMAT_TIME |
|
||||
GST_SEEK_METHOD_SET |
|
||||
GST_SEEK_FLAG_FLUSH);
|
||||
seekTime = seconds * GST_SECOND;
|
||||
|
||||
return livesupport_seek(element, seekType, seekTime);
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef Seek_h
|
||||
#define Seek_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Utility functions to help seeking in gstreamer elements.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Seek on an element.
|
||||
*
|
||||
* @param element the element to seek on.
|
||||
* @param seekType the type of seek.
|
||||
* @param seekTime the time of seek, in nanoseconds.
|
||||
* @return TRUE if the seek was successful, FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
livesupport_seek(GstElement * element,
|
||||
GstSeekType seekType,
|
||||
gint64 seekTime);
|
||||
|
||||
/**
|
||||
* Seek a number of seconds on an element.
|
||||
*
|
||||
* @param element the element to seek on.
|
||||
* @param seconds the number of seconds to seek.
|
||||
* @return TRUE if the seek was successful, FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
livesupport_seek_seconds(GstElement * element,
|
||||
gint64 seconds);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* Seek_h */
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include "smil-util.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
#define NSEC_PER_SEC 1000000000LL
|
||||
#define SEC_PER_MIN 60
|
||||
#define SEC_PER_HOUR 3600
|
||||
#define NSEC_PER_SEC_FLOAT 1000000000.0
|
||||
#define SEC_PER_MIN_FLOAT 60.0
|
||||
#define SEC_PER_HOUR_FLOAT 3600.0
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Convert an hour - minute - second triplet into a nanosecond value.
|
||||
*
|
||||
* @param hours the number of hours
|
||||
* @param minutes the number of minutes (may be more than 59)
|
||||
* @param seconds the number of seconds (may be mora than 59)
|
||||
* @return the supplied time in nanoseconds
|
||||
*/
|
||||
static gint64
|
||||
hms_to_nanosec(int hours,
|
||||
int minutes,
|
||||
double seconds);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Convert a hour-minute-second triplet to nanoseconds
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gint64
|
||||
hms_to_nanosec(int hours,
|
||||
int minutes,
|
||||
double seconds)
|
||||
{
|
||||
gint64 nanosec;
|
||||
double nsec;
|
||||
|
||||
nsec = seconds * NSEC_PER_SEC_FLOAT;
|
||||
|
||||
nanosec = (gint64) nsec;
|
||||
nanosec += ((gint64) hours) * NSEC_PER_SEC;
|
||||
nanosec += ((gint64) minutes) * SEC_PER_MIN * NSEC_PER_SEC;
|
||||
|
||||
return nanosec;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Parse the clock value according to the SMIL clock spec
|
||||
*
|
||||
* see http://www.w3.org/TR/2005/REC-SMIL2-20050107/smil-timing.html#Timing-ClockValueSyntax
|
||||
*
|
||||
* the BNF for the value is:
|
||||
*
|
||||
* Clock-value ::= ( Full-clock-value | Partial-clock-value
|
||||
* | Timecount-value )
|
||||
* Full-clock-value ::= Hours ":" Minutes ":" Seconds ("." Fraction)?
|
||||
* Partial-clock-value ::= Minutes ":" Seconds ("." Fraction)?
|
||||
* Timecount-value ::= Timecount ("." Fraction)? (Metric)?
|
||||
* Metric ::= "h" | "min" | "s" | "ms"
|
||||
* Hours ::= DIGIT+; any positive number
|
||||
* Minutes ::= 2DIGIT; range from 00 to 59
|
||||
* Seconds ::= 2DIGIT; range from 00 to 59
|
||||
* Fraction ::= DIGIT+
|
||||
* Timecount ::= DIGIT+
|
||||
* 2DIGIT ::= DIGIT DIGIT
|
||||
* DIGIT ::= [0-9]
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64
|
||||
smil_clock_value_to_nanosec(const gchar * value)
|
||||
{
|
||||
int hours;
|
||||
int minutes;
|
||||
double seconds;
|
||||
|
||||
/* see if it's a full-clock-value */
|
||||
if (sscanf(value, "%2d:%2d:%lf", &hours, &minutes, &seconds) == 3) {
|
||||
return hms_to_nanosec(hours, minutes, seconds);
|
||||
}
|
||||
|
||||
/* see if it's a partial-clock-value */
|
||||
if (sscanf(value, "%2d:%lf", &minutes, &seconds) == 2) {
|
||||
return hms_to_nanosec(0, minutes, seconds);
|
||||
}
|
||||
|
||||
/* see if it's a timecount-value, in hours */
|
||||
if (g_str_has_suffix(value, "h")
|
||||
&& sscanf(value, "%lfh", &seconds) == 1) {
|
||||
return hms_to_nanosec(0, 0, seconds * SEC_PER_HOUR_FLOAT);
|
||||
}
|
||||
|
||||
/* see if it's a timecount-value, in minutes */
|
||||
if (g_str_has_suffix(value, "min")
|
||||
&& sscanf(value, "%lfmin", &seconds) == 1) {
|
||||
return hms_to_nanosec(0, 0, seconds * SEC_PER_MIN_FLOAT);
|
||||
}
|
||||
|
||||
/* see if it's a timecount-value, in millisecs */
|
||||
if (g_str_has_suffix(value, "ms")
|
||||
&& sscanf(value, "%lfms", &seconds) == 1) {
|
||||
return hms_to_nanosec(0, 0, seconds / 100.0);
|
||||
}
|
||||
|
||||
/* it's a timecount-value, either with no metric, or explicit seconds */
|
||||
if (sscanf(value, "%lfs", &seconds) == 1) {
|
||||
return hms_to_nanosec(0, 0, seconds);
|
||||
}
|
||||
|
||||
return -1LL;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Convert a percent value to a double.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gboolean
|
||||
smil_parse_percent(const gchar * str,
|
||||
double * value)
|
||||
{
|
||||
double val;
|
||||
|
||||
if (g_str_has_suffix(str, "%")
|
||||
&& sscanf(str, "%lf%%", &val) == 1) {
|
||||
*value = val / 100.0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef SmilUtil_h
|
||||
#define SmilUtil_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Utility functions helping to work with SMIL-related data structures.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Parse the clock value according to the SMIL clock spec
|
||||
*
|
||||
* see http://www.w3.org/TR/2005/REC-SMIL2-20050107/smil-timing.html#Timing-ClockValueSyntax
|
||||
*
|
||||
* the BNF for the value is:
|
||||
*
|
||||
* <pre><code>
|
||||
* Clock-value ::= ( Full-clock-value | Partial-clock-value
|
||||
* | Timecount-value )
|
||||
* Full-clock-value ::= Hours ":" Minutes ":" Seconds ("." Fraction)?
|
||||
* Partial-clock-value ::= Minutes ":" Seconds ("." Fraction)?
|
||||
* Timecount-value ::= Timecount ("." Fraction)? (Metric)?
|
||||
* Metric ::= "h" | "min" | "s" | "ms"
|
||||
* Hours ::= DIGIT+; any positive number
|
||||
* Minutes ::= 2DIGIT; range from 00 to 59
|
||||
* Seconds ::= 2DIGIT; range from 00 to 59
|
||||
* Fraction ::= DIGIT+
|
||||
* Timecount ::= DIGIT+
|
||||
* 2DIGIT ::= DIGIT DIGIT
|
||||
* DIGIT ::= [0-9]
|
||||
* </code></pre>
|
||||
*
|
||||
* @param value the SMIL clock value in string form
|
||||
* @return the clock value in nanoseconds
|
||||
*/
|
||||
gint64
|
||||
smil_clock_value_to_nanosec(const gchar * value);
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string as a percentage value, and return the result as a
|
||||
* float. Indicate parse error.
|
||||
*
|
||||
* @param str the string to parse.
|
||||
* @param value the parsed value (out parameter).
|
||||
* @return TRUE if parsing went OK, FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
smil_parse_percent(const gchar * str,
|
||||
double * value);
|
||||
|
||||
|
||||
#endif /* SmilUtil_h */
|
||||
|
|
@ -1,775 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#error need string.h
|
||||
#endif
|
||||
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "switcher.h"
|
||||
#include "smil-util.h"
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
/**
|
||||
* The properties of the Switcher element.
|
||||
*/
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_SOURCE_CONFIG,
|
||||
ARG_CAPS
|
||||
};
|
||||
|
||||
/**
|
||||
* The plugin registry definition.
|
||||
*/
|
||||
GST_PLUGIN_DEFINE (
|
||||
GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"switcher",
|
||||
"A filter that connects to a swtich, and changes its source",
|
||||
plugin_init,
|
||||
"$Revision$",
|
||||
"GPL",
|
||||
"LiveSupport",
|
||||
"http://campcaster.campware.org/"
|
||||
)
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
/**
|
||||
* The parent class of the Switcher class.
|
||||
*/
|
||||
static GstElementClass * parent_class = NULL;
|
||||
|
||||
/**
|
||||
* The sink pad factory.
|
||||
*/
|
||||
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE(
|
||||
"sink_%d",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_REQUEST,
|
||||
GST_STATIC_CAPS("ANY"));
|
||||
|
||||
/**
|
||||
* The source pad factory.
|
||||
*/
|
||||
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE(
|
||||
"src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS("ANY"));
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
/**
|
||||
* Initialize the Switcher class.
|
||||
*
|
||||
* @param klass the class to initialize
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_class_init(LivesupportSwitcherClass * klass);
|
||||
|
||||
/**
|
||||
* Base initialization for Switcher objects.
|
||||
*
|
||||
* @param klass a Switcher class
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_base_init(LivesupportSwitcherClass * klass);
|
||||
|
||||
/**
|
||||
* Initialize a Switcher object.
|
||||
*
|
||||
* @param switcher the Switcher object to initialize.
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_init(LivesupportSwitcher * switcher);
|
||||
|
||||
/**
|
||||
* Destroy a Switcher object.
|
||||
*
|
||||
* @param object the Switcher object to destroy.
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_dispose(GObject * object);
|
||||
|
||||
/**
|
||||
* Return the capabilities of a pad.
|
||||
*
|
||||
* @pad the pad to return the capabilities for.
|
||||
* @return the capabilities of pad.
|
||||
*/
|
||||
static GstCaps *
|
||||
livesupport_switcher_get_caps(GstPad * pad);
|
||||
|
||||
/**
|
||||
* Set the capabilities for this switcher element.
|
||||
*
|
||||
* @param switcher the switcher to set the capabilities for.
|
||||
* @param caps the capabilities to set.
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_set_caps(LivesupportSwitcher * switcher,
|
||||
const GstCaps * caps);
|
||||
|
||||
/**
|
||||
* Set a property on a Switcher object.
|
||||
*
|
||||
* @param object a Switcher object
|
||||
* @param prop_id the property id
|
||||
* @param value the value to set
|
||||
* @param pspec the property specification
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_set_property(GObject * object,
|
||||
guint prop_id,
|
||||
const GValue * value,
|
||||
GParamSpec * pspec);
|
||||
|
||||
/**
|
||||
* Get a property from a Switcher object.
|
||||
*
|
||||
* @param object a Switcher object.
|
||||
* @param prop_id the property id
|
||||
* @param value the requested property (an out parameter)
|
||||
* @param pspec the property specification
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_get_property(GObject * object,
|
||||
guint prop_id,
|
||||
GValue * value,
|
||||
GParamSpec * pspec);
|
||||
|
||||
/**
|
||||
* The main loop function of the Switcher element.
|
||||
*
|
||||
* @param element the Switcher element to loop on.
|
||||
* @param in the data recieved.
|
||||
*/
|
||||
static void
|
||||
livesupport_switcher_loop(GstElement * element);
|
||||
|
||||
/**
|
||||
* Switch to the source next in line.
|
||||
* Call this function if it's time to switch to the next source.
|
||||
*
|
||||
* @param switcher a Switcher object to swtich on.
|
||||
*/
|
||||
static void
|
||||
switch_to_next_source(LivesupportSwitcher * switcher);
|
||||
|
||||
/**
|
||||
* Update the source configuration.
|
||||
* Call this function when the sourceConfigList string has been updated.
|
||||
*
|
||||
* @param switcher a Switcher object to perform the update on.
|
||||
*/
|
||||
static void
|
||||
update_source_config(LivesupportSwitcher * switcher);
|
||||
|
||||
/**
|
||||
* Create a new pad upon request.
|
||||
*
|
||||
* @param element a Switcher element, for which to create the new pas.
|
||||
* @param template the pad template to use for the new pad.
|
||||
* @param name the requested name of the new pad.
|
||||
* @return the new, requested pad.
|
||||
*/
|
||||
static GstPad *
|
||||
request_new_pad(GstElement * element,
|
||||
GstPadTemplate * template,
|
||||
const gchar * name);
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Return the type structure for the Switcher plugin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
GType
|
||||
livesupport_switcher_get_type(void)
|
||||
{
|
||||
static GType plugin_type = 0;
|
||||
|
||||
if (!plugin_type) {
|
||||
static const GTypeInfo plugin_info = {
|
||||
sizeof (LivesupportSwitcherClass),
|
||||
(GBaseInitFunc) livesupport_switcher_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) livesupport_switcher_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (LivesupportSwitcher),
|
||||
0,
|
||||
(GInstanceInitFunc) livesupport_switcher_init,
|
||||
};
|
||||
|
||||
plugin_type = g_type_register_static(GST_TYPE_ELEMENT,
|
||||
"LivesupportSwitcher",
|
||||
&plugin_info, 0);
|
||||
}
|
||||
|
||||
return plugin_type;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Do base initialization for the Switcher class.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_base_init(LivesupportSwitcherClass * klass)
|
||||
{
|
||||
static GstElementDetails plugin_details = {
|
||||
"Switcher",
|
||||
"Generic/Switcher",
|
||||
"A plugin that is connected to a switch element, and changes its source",
|
||||
"Akos Maroy <maroy@campware.org>"
|
||||
};
|
||||
GstElementClass * element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template(element_class,
|
||||
gst_static_pad_template_get(&src_factory));
|
||||
gst_element_class_add_pad_template(element_class,
|
||||
gst_static_pad_template_get(&sink_factory));
|
||||
gst_element_class_set_details(element_class, &plugin_details);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize the plugin's class.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_class_init(LivesupportSwitcherClass * klass)
|
||||
{
|
||||
GObjectClass * gobject_class;
|
||||
GstElementClass * element_class;
|
||||
|
||||
gobject_class = (GObjectClass*) klass;
|
||||
element_class = (GstElementClass*) klass;
|
||||
|
||||
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
|
||||
|
||||
g_object_class_install_property(gobject_class,
|
||||
ARG_SOURCE_CONFIG,
|
||||
g_param_spec_string("source_config",
|
||||
"source config",
|
||||
"source config",
|
||||
"",
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(gobject_class,
|
||||
ARG_CAPS,
|
||||
g_param_spec_pointer("caps",
|
||||
"pad capabilites",
|
||||
"fix all switcher capabilities to supplied value",
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
gobject_class->dispose = livesupport_switcher_dispose;
|
||||
gobject_class->set_property = livesupport_switcher_set_property;
|
||||
gobject_class->get_property = livesupport_switcher_get_property;
|
||||
|
||||
element_class->request_new_pad = request_new_pad;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Create a new request pad.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static GstPad *
|
||||
request_new_pad(GstElement * element,
|
||||
GstPadTemplate * template,
|
||||
const gchar * name)
|
||||
{
|
||||
LivesupportSwitcher * switcher;
|
||||
GstPad * pad;
|
||||
|
||||
g_return_val_if_fail(element != NULL, NULL);
|
||||
g_return_val_if_fail(LIVESUPPORT_IS_SWITCHER(element), NULL);
|
||||
|
||||
switcher = LIVESUPPORT_SWITCHER(element);
|
||||
|
||||
if (template->direction != GST_PAD_SINK) {
|
||||
GST_DEBUG("only sink pads are created on request");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pad = gst_pad_new_from_template(template, name);
|
||||
gst_pad_set_link_function(pad, gst_pad_proxy_pad_link);
|
||||
gst_pad_set_getcaps_function(pad, livesupport_switcher_get_caps);
|
||||
|
||||
gst_element_add_pad(element, pad);
|
||||
/* TODO: catch the pad remove event, and remove the pad from this
|
||||
* list as well */
|
||||
switcher->sinkpadList = g_list_append(switcher->sinkpadList, pad);
|
||||
|
||||
if (GST_PAD_CAPS(switcher->srcpad)) {
|
||||
gst_pad_try_set_caps(pad, GST_PAD_CAPS(switcher->srcpad));
|
||||
}
|
||||
|
||||
return pad;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize a Switcher object.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_init(LivesupportSwitcher * switcher)
|
||||
{
|
||||
GstElementClass * klass = GST_ELEMENT_GET_CLASS(switcher);
|
||||
|
||||
switcher->srcpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template(klass, "src"),
|
||||
"src");
|
||||
gst_pad_set_link_function(switcher->srcpad, gst_pad_proxy_pad_link);
|
||||
gst_pad_set_getcaps_function(switcher->srcpad,
|
||||
livesupport_switcher_get_caps);
|
||||
|
||||
gst_element_add_pad(GST_ELEMENT(switcher), switcher->srcpad);
|
||||
gst_element_set_loop_function(GST_ELEMENT(switcher),
|
||||
livesupport_switcher_loop);
|
||||
|
||||
switcher->caps = NULL;
|
||||
switcher->sinkpadList = NULL;
|
||||
switcher->elapsedTime = 0LL;
|
||||
switcher->offset = 0LL;
|
||||
switcher->switchTime = 0LL;
|
||||
switcher->eos = FALSE;
|
||||
switcher->sourceConfig = 0;
|
||||
switcher->sourceConfigList = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Destroy a Switcher object.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_dispose(GObject * object)
|
||||
{
|
||||
LivesupportSwitcher * switcher = LIVESUPPORT_SWITCHER(object);
|
||||
|
||||
g_return_if_fail(LIVESUPPORT_IS_SWITCHER(switcher));
|
||||
|
||||
if (switcher->sinkpadList) {
|
||||
g_list_free(switcher->sinkpadList);
|
||||
}
|
||||
if (switcher->sourceConfig) {
|
||||
g_free(switcher->sourceConfig);
|
||||
}
|
||||
if (switcher->sourceConfigList) {
|
||||
GList * element;
|
||||
|
||||
for (element = g_list_first(switcher->sourceConfigList);
|
||||
element;
|
||||
element = g_list_next(element)) {
|
||||
|
||||
g_free(element->data);
|
||||
}
|
||||
g_list_free(switcher->sourceConfigList);
|
||||
}
|
||||
|
||||
if (switcher->caps) {
|
||||
gst_caps_free(switcher->caps);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Return the capabilities of the switcher element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static GstCaps *
|
||||
livesupport_switcher_get_caps(GstPad * pad)
|
||||
{
|
||||
LivesupportSwitcher * switcher =
|
||||
LIVESUPPORT_SWITCHER(gst_pad_get_parent(pad));
|
||||
|
||||
return switcher->caps != NULL
|
||||
? gst_caps_copy(switcher->caps)
|
||||
: gst_pad_proxy_getcaps(pad);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Switch to the source next in line.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
switch_to_next_source(LivesupportSwitcher * switcher)
|
||||
{
|
||||
LivesupportSwitcherSourceConfig * oldConfig;
|
||||
LivesupportSwitcherSourceConfig * newConfig;
|
||||
|
||||
oldConfig = (LivesupportSwitcherSourceConfig*)
|
||||
switcher->currentConfig->data;
|
||||
|
||||
if ((switcher->currentConfig = g_list_next(switcher->currentConfig))) {
|
||||
|
||||
GST_INFO("switching from source %d, duration: %" G_GINT64_FORMAT,
|
||||
oldConfig->sourceId, oldConfig->duration);
|
||||
|
||||
newConfig = (LivesupportSwitcherSourceConfig*)
|
||||
switcher->currentConfig->data;
|
||||
|
||||
if (!newConfig->sinkPad) {
|
||||
if (!(newConfig->sinkPad = g_list_nth_data(switcher->sinkpadList,
|
||||
newConfig->sourceId))) {
|
||||
GST_ELEMENT_ERROR(GST_ELEMENT(switcher),
|
||||
RESOURCE,
|
||||
NOT_FOUND,
|
||||
("can't find sinkpad for next sink"),
|
||||
(NULL));
|
||||
}
|
||||
}
|
||||
|
||||
switcher->switchTime = oldConfig->duration >= 0
|
||||
? switcher->switchTime + newConfig->duration
|
||||
: switcher->elapsedTime + newConfig->duration;
|
||||
} else {
|
||||
/* mark EOS, as there are no more sources to switch to */
|
||||
GST_INFO("no more sources after source %d, duration: %" G_GINT64_FORMAT,
|
||||
oldConfig->sourceId, oldConfig->duration);
|
||||
switcher->eos = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* The main loop function.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_loop(GstElement * element)
|
||||
{
|
||||
LivesupportSwitcher * switcher;
|
||||
GstData * data;
|
||||
GstBuffer * buf;
|
||||
LivesupportSwitcherSourceConfig * config = NULL;
|
||||
|
||||
g_return_if_fail(element != NULL);
|
||||
g_return_if_fail(LIVESUPPORT_IS_SWITCHER(element));
|
||||
|
||||
switcher = LIVESUPPORT_SWITCHER(element);
|
||||
|
||||
if (switcher->eos) {
|
||||
GstEvent * event;
|
||||
|
||||
GST_INFO("switcher_loop: eos");
|
||||
/* push an EOS event down the srcpad, just to make sure */
|
||||
event = gst_event_new(GST_EVENT_EOS);
|
||||
gst_pad_send_event(switcher->srcpad, event);
|
||||
gst_element_set_eos(GST_ELEMENT(switcher));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (switcher->currentConfig == NULL) {
|
||||
/* if this is the very first call to the loop function */
|
||||
switcher->currentConfig = g_list_first(switcher->sourceConfigList);
|
||||
config = (LivesupportSwitcherSourceConfig*)
|
||||
switcher->currentConfig->data;
|
||||
switcher->switchTime = config->duration;
|
||||
if (!config->sinkPad) {
|
||||
if (!(config->sinkPad = g_list_nth_data(switcher->sinkpadList,
|
||||
config->sourceId))) {
|
||||
GST_ELEMENT_ERROR(GST_ELEMENT(switcher),
|
||||
RESOURCE,
|
||||
NOT_FOUND,
|
||||
("can't find sinkpad for first sink"),
|
||||
(NULL));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
config = (LivesupportSwitcherSourceConfig*)
|
||||
switcher->currentConfig->data;
|
||||
}
|
||||
|
||||
data = gst_pad_pull(config->sinkPad);
|
||||
|
||||
if (config->duration < 0LL) {
|
||||
/* handle config->duration == -1LL (play until EOS) */
|
||||
if (GST_IS_EVENT(data)) {
|
||||
GstEvent * event = GST_EVENT(data);
|
||||
|
||||
GST_INFO("handling event type %d", GST_EVENT_TYPE(event));
|
||||
|
||||
switch (GST_EVENT_TYPE(event)) {
|
||||
case GST_EVENT_EOS:
|
||||
switch_to_next_source(switcher);
|
||||
break;
|
||||
|
||||
case GST_EVENT_FLUSH:
|
||||
/* silently discard flush events
|
||||
* this is because when having an Ogg Vorbis source
|
||||
* as the second source, the flush event will indefinately
|
||||
* bounce back and forward, and the filesrc will regenerate
|
||||
* new flush events ad infinitum */
|
||||
break;
|
||||
|
||||
default:
|
||||
gst_pad_event_default(switcher->srcpad, event);
|
||||
}
|
||||
} else {
|
||||
buf = GST_BUFFER(data);
|
||||
|
||||
if (GST_BUFFER_DURATION(buf) != GST_CLOCK_TIME_NONE) {
|
||||
switcher->elapsedTime += GST_BUFFER_DURATION(buf);
|
||||
GST_BUFFER_TIMESTAMP(buf) = switcher->elapsedTime;
|
||||
}
|
||||
switcher->offset += GST_BUFFER_SIZE(buf);
|
||||
GST_INFO("elapsed time: %" G_GINT64_FORMAT, switcher->elapsedTime);
|
||||
|
||||
GST_BUFFER_OFFSET(buf) = switcher->offset;
|
||||
|
||||
/* just push out the incoming buffer without touching it */
|
||||
gst_pad_push(switcher->srcpad, GST_DATA(buf));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (GST_IS_EVENT(data)) {
|
||||
/* handle events */
|
||||
GstEvent * event = GST_EVENT(data);
|
||||
|
||||
GST_INFO("handling event type %d", GST_EVENT_TYPE(event));
|
||||
|
||||
switch (GST_EVENT_TYPE(event)) {
|
||||
case GST_EVENT_FLUSH:
|
||||
/* silently discard flush events
|
||||
* this is because when having an Ogg Vorbis source
|
||||
* as the second source, the flush event will indefinately
|
||||
* bounce back and forward, and the filesrc will regenerate
|
||||
* new flush events ad infinitum */
|
||||
break;
|
||||
|
||||
default:
|
||||
gst_pad_event_default(switcher->srcpad, event);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
buf = GST_BUFFER(data);
|
||||
if (GST_BUFFER_DURATION(buf) != GST_CLOCK_TIME_NONE) {
|
||||
switcher->elapsedTime += GST_BUFFER_DURATION(buf);
|
||||
}
|
||||
switcher->offset += GST_BUFFER_SIZE(buf);
|
||||
GST_INFO("elapsed time: %" G_GINT64_FORMAT, switcher->elapsedTime);
|
||||
|
||||
if (switcher->elapsedTime >= switcher->switchTime) {
|
||||
/* time to switch to the next source */
|
||||
switch_to_next_source(switcher);
|
||||
}
|
||||
|
||||
GST_INFO("pushing data size: %d, duration: %" G_GINT64_FORMAT,
|
||||
GST_BUFFER_SIZE(buf), GST_BUFFER_DURATION(buf));
|
||||
|
||||
GST_BUFFER_TIMESTAMP(buf) = switcher->elapsedTime;
|
||||
GST_BUFFER_OFFSET(buf) = switcher->offset;
|
||||
|
||||
/* just push out the incoming buffer without touching it */
|
||||
gst_pad_push(switcher->srcpad, GST_DATA(buf));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Update the source config.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
update_source_config(LivesupportSwitcher * switcher)
|
||||
{
|
||||
gchar ** tokens;
|
||||
gchar * token;
|
||||
guint i = 0;
|
||||
GList * listElem;
|
||||
|
||||
/* first free the config list */
|
||||
for (listElem = g_list_first(switcher->sourceConfigList);
|
||||
listElem;
|
||||
listElem = g_list_next(listElem)) {
|
||||
g_free(listElem->data);
|
||||
}
|
||||
g_list_free(switcher->sourceConfigList);
|
||||
switcher->sourceConfigList = NULL;
|
||||
switcher->currentConfig = NULL;
|
||||
listElem = NULL;
|
||||
|
||||
tokens = g_strsplit(switcher->sourceConfig, ";", 0);
|
||||
while ((token = tokens[i++])) {
|
||||
gchar * durationStr;
|
||||
gint len;
|
||||
LivesupportSwitcherSourceConfig * config;
|
||||
gboolean found;
|
||||
|
||||
len = strlen(token);
|
||||
durationStr = g_malloc(sizeof(gchar) * len + 1);
|
||||
config = g_malloc(sizeof(LivesupportSwitcherSourceConfig));
|
||||
found = FALSE;
|
||||
|
||||
/* token formats can be:
|
||||
*
|
||||
* id[] play the whole thing, until EOS
|
||||
* id[duration] play from begin for duration time
|
||||
*/
|
||||
if (g_str_has_suffix(token, "[]")
|
||||
&& sscanf(token, "%d[]", &config->sourceId) == 1) {
|
||||
config->duration = -1LL;
|
||||
found = TRUE;
|
||||
} else if (sscanf(token, "%d[%[^]]]",
|
||||
&config->sourceId, durationStr) == 2) {
|
||||
config->duration = smil_clock_value_to_nanosec(durationStr);
|
||||
found = config->duration >= 0;
|
||||
}
|
||||
/* don't fill in the sinkPad yet, as it may be added later */
|
||||
config->sinkPad = NULL;
|
||||
|
||||
g_free(durationStr);
|
||||
|
||||
if (!found) {
|
||||
g_free(config);
|
||||
continue;
|
||||
}
|
||||
|
||||
switcher->sourceConfigList = g_list_append(switcher->sourceConfigList,
|
||||
config);
|
||||
listElem = g_list_last(switcher->sourceConfigList);
|
||||
}
|
||||
|
||||
g_strfreev(tokens);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set the capabilities of this switcher element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_set_caps(LivesupportSwitcher * switcher,
|
||||
const GstCaps * caps)
|
||||
{
|
||||
if (!switcher || !LIVESUPPORT_IS_SWITCHER(switcher)
|
||||
|| !caps || !GST_IS_CAPS(caps)) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (switcher->caps) {
|
||||
gst_caps_free(switcher->caps);
|
||||
}
|
||||
|
||||
switcher->caps = gst_caps_copy(caps);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set a property.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_set_property(GObject * object,
|
||||
guint prop_id,
|
||||
const GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
LivesupportSwitcher * switcher;
|
||||
|
||||
g_return_if_fail(LIVESUPPORT_IS_SWITCHER(object));
|
||||
switcher = LIVESUPPORT_SWITCHER(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SOURCE_CONFIG:
|
||||
if (switcher->sourceConfig) {
|
||||
g_free(switcher->sourceConfig);
|
||||
}
|
||||
switcher->sourceConfig = g_value_dup_string(value);
|
||||
update_source_config(switcher);
|
||||
break;
|
||||
|
||||
case ARG_CAPS:
|
||||
livesupport_switcher_set_caps(switcher, g_value_get_pointer(value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Get a property.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
livesupport_switcher_get_property(GObject * object,
|
||||
guint prop_id,
|
||||
GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
LivesupportSwitcher * switcher;
|
||||
|
||||
g_return_if_fail(LIVESUPPORT_IS_SWITCHER(object));
|
||||
switcher = LIVESUPPORT_SWITCHER(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SOURCE_CONFIG:
|
||||
g_value_set_string(value, switcher->sourceConfig);
|
||||
break;
|
||||
|
||||
case ARG_CAPS:
|
||||
g_value_set_pointer(value, switcher->caps);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize the plugin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gboolean
|
||||
plugin_init(GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register(plugin,
|
||||
"switcher",
|
||||
GST_RANK_NONE,
|
||||
LIVESUPPORT_TYPE_SWITCHER);
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef LiveSupport_GstreamerElements_Switcher_h
|
||||
#define LiveSupport_GstreamerElements_Switcher_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* A gstreamer element that expects to be linked after a switch
|
||||
* element. The element will switch the active source on the attached
|
||||
* switcher according to the time positions it is configured with.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define LIVESUPPORT_TYPE_SWITCHER \
|
||||
(livesupport_switcher_get_type())
|
||||
|
||||
#define LIVESUPPORT_SWITCHER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
LIVESUPPORT_TYPE_SWITCHER, \
|
||||
LivesupportSwitcher))
|
||||
|
||||
#define LIVESUPPORT_SWITCHER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
LIVESUPPORT_TYPE_SWITCHER, \
|
||||
LivesupportSwitcher))
|
||||
|
||||
#define LIVESUPPORT_IS_SWITCHER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), \
|
||||
LIVESUPPORT_TYPE_SWITCHER))
|
||||
|
||||
#define LIVESUPPORT_IS_SWITCHER_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), \
|
||||
LIVESUPPORT_TYPE_SWITCHER))
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
typedef struct _LivesupportSwitcherSourceConfig LivesupportSwitcherSourceConfig;
|
||||
typedef struct _LivesupportSwitcher LivesupportSwitcher;
|
||||
typedef struct _LivesupportSwitcherClass LivesupportSwitcherClass;
|
||||
|
||||
/**
|
||||
* A source configuration, describing how long a source should be played
|
||||
* before switching to the next.
|
||||
*/
|
||||
struct _LivesupportSwitcherSourceConfig {
|
||||
gint sourceId;
|
||||
gint64 duration;
|
||||
GstPad * sinkPad;
|
||||
};
|
||||
|
||||
/**
|
||||
* The Switcher object.
|
||||
*/
|
||||
struct _LivesupportSwitcher
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad * srcpad;
|
||||
GList * sinkpadList;
|
||||
|
||||
GstCaps * caps;
|
||||
|
||||
gint64 elapsedTime;
|
||||
gint64 offset;
|
||||
gint64 switchTime;
|
||||
gboolean eos;
|
||||
|
||||
gchar * sourceConfig;
|
||||
GList * sourceConfigList;
|
||||
GList * currentConfig;
|
||||
};
|
||||
|
||||
/**
|
||||
* The Switcher class.
|
||||
*/
|
||||
struct _LivesupportSwitcherClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Return the type structure for the Switcher class.
|
||||
*
|
||||
* @return the type structure for the Switcher class.
|
||||
*/
|
||||
GType
|
||||
livesupport_switcher_get_type(void);
|
||||
|
||||
/**
|
||||
* Initialize the plugin.
|
||||
*
|
||||
* @param plugin the plugin to initialize.
|
||||
*/
|
||||
static gboolean
|
||||
plugin_init(GstPlugin * plugin);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* LiveSupport_GstreamerElements_Switcher_h */
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Return the first src pad for an element.
|
||||
*----------------------------------------------------------------------------*/
|
||||
GstPad *
|
||||
get_src_pad(GstElement * element)
|
||||
{
|
||||
const GList * pads;
|
||||
|
||||
g_return_val_if_fail(element != NULL, NULL);
|
||||
|
||||
for (pads = gst_element_get_pad_list(element);
|
||||
pads;
|
||||
pads = g_list_next(pads)) {
|
||||
GstPad * pad = pads->data;
|
||||
|
||||
if (GST_PAD_IS_SRC(pad)) {
|
||||
return pad;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef Util_h
|
||||
#define Util_h
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Utility functions helping to work with SMIL-related data structures.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
/**
|
||||
* Return the first src pad for an element.
|
||||
*
|
||||
* @param element the element to return the pad from.
|
||||
* @return the first src pad for element, or NULL.
|
||||
*/
|
||||
GstPad *
|
||||
get_src_pad(GstElement * element);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* Util_h */
|
||||
|
|
@ -1 +0,0 @@
|
|||
keep me
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/5seccounter.mp3">
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "100%"
|
||||
to = "0%"
|
||||
calcMode = "linear"
|
||||
begin = "1s"
|
||||
end = "5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/5seccounter.mp3">
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "100%"
|
||||
to = "0%"
|
||||
calcMode = "linear"
|
||||
begin = "1s"
|
||||
end = "5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
<audio src = "file:var/5seccounter.mp3"
|
||||
begin = "3s">
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "100%"
|
||||
to = "0%"
|
||||
calcMode = "linear"
|
||||
begin = "1s"
|
||||
end = "5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
Binary file not shown.
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/simple.smil"
|
||||
/>
|
||||
<audio src = "file:var/5seccounter.mp3"
|
||||
begin = "5s"
|
||||
/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,26 +0,0 @@
|
|||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/5seccounter.mp3">
|
||||
<!-- fade in -->
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "0%"
|
||||
to = "100%"
|
||||
calcMode = "linear"
|
||||
begin = "0s"
|
||||
end = "1.5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
<!-- fade out -->
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "100%"
|
||||
to = "0%"
|
||||
calcMode = "linear"
|
||||
begin = "3.5s"
|
||||
end = "5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,48 +0,0 @@
|
|||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/5seccounter.mp3">
|
||||
<!-- fade in -->
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "0%"
|
||||
to = "100%"
|
||||
calcMode = "linear"
|
||||
begin = "0s"
|
||||
end = "1.5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
<!-- fade out -->
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "100%"
|
||||
to = "0%"
|
||||
calcMode = "linear"
|
||||
begin = "3.5s"
|
||||
end = "5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
|
||||
<audio src = "file:var/5seccounter.ogg"
|
||||
begin = "3s">
|
||||
<!-- fade in -->
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "0%"
|
||||
to = "100%"
|
||||
calcMode = "linear"
|
||||
begin = "0s"
|
||||
end = "1.5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
<!-- fade out -->
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "100%"
|
||||
to = "0%"
|
||||
calcMode = "linear"
|
||||
begin = "3.5s"
|
||||
end = "5s"
|
||||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1 +0,0 @@
|
|||
She sells seashells by the seashore.
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/1minutecounter.mp3"
|
||||
clipBegin = "10s"
|
||||
clipEnd = "15s"
|
||||
/>
|
||||
<audio src = "file:var/1minutecounter.mp3"
|
||||
begin = "3s"
|
||||
clipBegin = "10s"
|
||||
clipEnd = "15s"
|
||||
/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/5seccounter.mp3"
|
||||
/>
|
||||
<audio src = "file:var/5seccounter.mp3"
|
||||
begin = "3s"
|
||||
/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns = "http://www.w3.org/2001/SMIL20/Language">
|
||||
<body>
|
||||
<par>
|
||||
<audio src="file:var/test10001.mp3" begin="0s"/>
|
||||
<audio src="file:var/test10002.mp3" begin="11.23s"/>
|
||||
<audio src="file:var/test10003.mp3" begin="23.45s"/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/test-short.mp3" />
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/1minutecounter.mp3"
|
||||
begin = "2s"
|
||||
clipBegin = "10s"
|
||||
clipEnd = "13s"
|
||||
/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/1minutecounter.mp3"
|
||||
begin = "2s"
|
||||
clipBegin = "57s"
|
||||
/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/5seccounter.ogg"
|
||||
/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<smil xmlns="http://www.w3.org/2001/SMIL20/Language" >
|
||||
<body>
|
||||
<par>
|
||||
<audio src = "file:var/5seccounter.mp3"
|
||||
/>
|
||||
</par>
|
||||
</body>
|
||||
</smil>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -68,12 +68,6 @@ CORE_LIB_DIR = ${CORE_DIR}/lib
|
|||
CORE_LIB = livesupport_core
|
||||
CORE_LIB_FILE = ${CORE_LIB_DIR}/lib${CORE_LIB}.a
|
||||
|
||||
GSTREAMER_ELEMENTS_DIR = ${MODULES_DIR}/gstreamerElements
|
||||
GSTREAMER_ELEMENTS_INCLUDE_DIR = ${GSTREAMER_ELEMENTS_DIR}/include
|
||||
GSTREAMER_ELEMENTS_LIB_DIR = ${GSTREAMER_ELEMENTS_DIR}/lib
|
||||
GSTREAMER_ELEMENTS_LIB = livesupport_gstreamerelements
|
||||
GSTREAMER_ELEMENTS_LIB_FILE = ${GSTREAMER_ELEMENTS_LIB_DIR}/lib${GSTREAMER_ELEMENTS_LIB}.a
|
||||
GST_REAL_LIB_DIR=${REAL_BASE_DIR}/modules/gstreamerElements/lib
|
||||
|
||||
VPATH = ${SRC_DIR}
|
||||
|
||||
|
@ -91,6 +85,9 @@ ICU_LIBS=@ICU_LIBS@
|
|||
GSTREAMER_CFLAGS=@GSTREAMER_CFLAGS@
|
||||
GSTREAMER_LIBS=@GSTREAMER_LIBS@
|
||||
|
||||
GSTCONTROLLER_CFLAGS=@GSTCONTROLLER_CFLAGS@
|
||||
GSTCONTROLLER_LIBS=@GSTCONTROLLER_LIBS@
|
||||
|
||||
TAGLIB_CFLAGS=@TAGLIB_CFLAGS@
|
||||
TAGLIB_LIBS=@TAGLIB_LIBS@
|
||||
|
||||
|
@ -106,7 +103,6 @@ TWOTEST_RUNNER = ${TMP_DIR}/twoTestRunner
|
|||
DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
|
||||
|
||||
export LD_LIBRARY_PATH:=${USR_LIB_DIR}:${LD_LIBRARY_PATH}
|
||||
export GST_PLUGIN_PATH=${GST_REAL_LIB_DIR}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
@ -118,8 +114,8 @@ CXXFLAGS = @CXXFLAGS@ @DEFS@ @COVERAGE_CXXFLAGS@ -pthread \
|
|||
${BOOST_CFLAGS} \
|
||||
${LIBXMLPP_CFLAGS} \
|
||||
${GSTREAMER_CFLAGS} \
|
||||
${GSTCONTROLLER_CFLAGS} \
|
||||
-I${USR_INCLUDE_DIR} \
|
||||
-I${GSTREAMER_ELEMENTS_INCLUDE_DIR} \
|
||||
-I${CORE_INCLUDE_DIR} \
|
||||
-I${INCLUDE_DIR} -I${TMP_DIR}
|
||||
LDFLAGS = @LDFLAGS@ -pthread \
|
||||
|
@ -127,10 +123,10 @@ LDFLAGS = @LDFLAGS@ -pthread \
|
|||
${LIBXMLPP_LIBS} \
|
||||
${ICU_LIBS} \
|
||||
${GSTREAMER_LIBS} \
|
||||
${GSTCONTROLLER_LIBS} \
|
||||
${TAGLIB_LIBS} \
|
||||
-L${USR_LIB_DIR} \
|
||||
-L${CORE_LIB_DIR} \
|
||||
-L${GSTREAMER_ELEMENTS_LIB_DIR} \
|
||||
-L${LIB_DIR}
|
||||
|
||||
|
||||
|
@ -140,10 +136,9 @@ LDFLAGS = @LDFLAGS@ -pthread \
|
|||
PLAYLIST_EXECUTOR_LIB_OBJS = ${TMP_DIR}/AudioPlayerFactory.o \
|
||||
${TMP_DIR}/GstreamerPlayer.o
|
||||
TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
|
||||
${TMP_DIR}/AudioPlayerFactoryGstreamerTest.o \
|
||||
${TMP_DIR}/GstreamerPlayerTest.o
|
||||
${TMP_DIR}/AudioPlayerFactoryGstreamerTest.o
|
||||
# ${TMP_DIR}/GstreamerPlayerTest.o
|
||||
TEST_RUNNER_LIBS = -l${PLAYLIST_EXECUTOR_LIB} -l${CORE_LIB} \
|
||||
-l${GSTREAMER_ELEMENTS_LIB} \
|
||||
${TAGLIB_LIBS} \
|
||||
${BOOST_DATE_TIME_LIB} -lcppunit -ldl -lm -lxmlrpc++
|
||||
|
||||
|
@ -203,20 +198,17 @@ ${TMP_DIR}:
|
|||
${DOXYGEN_DIR}:
|
||||
${MKDIR} ${DOXYGEN_DIR}
|
||||
|
||||
${TEST_RUNNER}: ${CORE_LIB_FILE} ${GSTREAMER_ELEMENTS_LIB_FILE} \
|
||||
${TEST_RUNNER}: ${CORE_LIB_FILE} \
|
||||
${TEST_RUNNER_OBJS} ${PLAYLIST_EXECUTOR_LIB_FILE}
|
||||
${CXX} ${LDFLAGS} -o $@ ${TEST_RUNNER_OBJS} ${TEST_RUNNER_LIBS}
|
||||
|
||||
${TWOTEST_RUNNER}: ${CORE_LIB_FILE} ${GSTREAMER_ELEMENTS_LIB_FILE} \
|
||||
${TWOTEST_RUNNER}: ${CORE_LIB_FILE} \
|
||||
${TWOTEST_RUNNER_OBJS} ${PLAYLIST_EXECUTOR_LIB_FILE}
|
||||
${CXX} ${LDFLAGS} -o $@ ${TWOTEST_RUNNER_OBJS} ${TEST_RUNNER_LIBS}
|
||||
|
||||
${CORE_LIB_FILE}:
|
||||
${MAKE} -C ${CORE_DIR}
|
||||
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}:
|
||||
${MAKE} -C ${GSTREAMER_ELEMENTS_DIR}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Pattern rules
|
||||
|
|
|
@ -99,6 +99,10 @@ PKG_CHECK_MODULES(GSTREAMER,[gstreamer-0.8 >= 0.8])
|
|||
AC_SUBST(GSTREAMER_CFLAGS)
|
||||
AC_SUBST(GSTREAMER_LIBS)
|
||||
|
||||
PKG_CHECK_MODULES(GSTCONTROLLER,[gstreamer-controller-0.10 >= 0.10])
|
||||
AC_SUBST(GSTCONTROLLER_CFLAGS)
|
||||
AC_SUBST(GSTCONTROLLER_LIBS)
|
||||
|
||||
AC_CHECK_TAGLIB(1.3.1)
|
||||
AC_SUBST(TAGLIB_CFLAGS)
|
||||
AC_SUBST(TAGLIB_LIBS)
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#error "Need unistd.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -149,18 +149,28 @@ AudioPlayerFactoryGstreamerTest :: simplePlayTest(void)
|
|||
Ptr<AudioPlayerInterface>::Ref audioPlayer;
|
||||
Ptr<time_duration>::Ref sleepT;
|
||||
|
||||
|
||||
GMainLoop *loop=g_main_loop_new(NULL, FALSE);
|
||||
|
||||
audioPlayerFactory = AudioPlayerFactory::getInstance();
|
||||
audioPlayer = audioPlayerFactory->getAudioPlayer();
|
||||
|
||||
CPPUNIT_ASSERT_NO_THROW(
|
||||
audioPlayer->open("file:var/test.mp3");
|
||||
);
|
||||
CPPUNIT_ASSERT(!audioPlayer->isPlaying());
|
||||
CPPUNIT_ASSERT_NO_THROW(
|
||||
// CPPUNIT_ASSERT_NO_THROW(
|
||||
audioPlayer->open("file:///home/nebojsa/testFiles/simple.smil");
|
||||
// );
|
||||
// CPPUNIT_ASSERT(!audioPlayer->isPlaying());
|
||||
// CPPUNIT_ASSERT_NO_THROW(
|
||||
audioPlayer->start();
|
||||
);
|
||||
CPPUNIT_ASSERT(audioPlayer->isPlaying());
|
||||
|
||||
|
||||
g_main_loop_run(loop);
|
||||
|
||||
|
||||
// );
|
||||
// CPPUNIT_ASSERT(
|
||||
audioPlayer->isPlaying();
|
||||
// );
|
||||
/*
|
||||
sleepT.reset(new time_duration(seconds(5)));
|
||||
TimeConversion::sleep(sleepT);
|
||||
CPPUNIT_ASSERT_NO_THROW(
|
||||
|
@ -187,6 +197,6 @@ AudioPlayerFactoryGstreamerTest :: simplePlayTest(void)
|
|||
TimeConversion::sleep(sleepT);
|
||||
}
|
||||
CPPUNIT_ASSERT(!audioPlayer->isPlaying());
|
||||
audioPlayer->close();
|
||||
*/ audioPlayer->close();
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace PlaylistExecutor {
|
|||
class AudioPlayerFactoryGstreamerTest : public CPPUNIT_NS::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(AudioPlayerFactoryGstreamerTest);
|
||||
CPPUNIT_TEST(firstTest);
|
||||
// CPPUNIT_TEST(firstTest);
|
||||
CPPUNIT_TEST(simplePlayTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef GstreamerPlayContext_h
|
||||
#define GstreamerPlayContext_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/controller/gstcontroller.h>
|
||||
#include <gst/controller/gstinterpolationcontrolsource.h>
|
||||
|
||||
#include "SmilHandler.h"
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* User of this class must implement my_bus_callback function to receive bus callbacks.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gboolean
|
||||
my_bus_callback (GstBus *bus,
|
||||
GstMessage *message,
|
||||
gpointer data);
|
||||
|
||||
/**
|
||||
* A class to play audio files using Gstreamer library.
|
||||
*
|
||||
* Usage sequence:
|
||||
*
|
||||
* create an instance of GstreamerPlayContext object
|
||||
* call setParentData to provide data to be returned by my_bus_callback
|
||||
* call setAudioDevice on it
|
||||
* call openSource on it
|
||||
* call playContext on it
|
||||
*
|
||||
* when done, call closeContext on it
|
||||
* destroy instance
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class GstreamerPlayContext
|
||||
{
|
||||
GstElement *m_pipeline;
|
||||
GstElement *m_source;
|
||||
GstElement *m_decoder;
|
||||
GstElement *m_sink;
|
||||
GstController *m_ctrl;
|
||||
GstElement *m_volume;
|
||||
GstInterpolationControlSource *m_ics;
|
||||
gpointer m_data;
|
||||
AudioDescription *m_audioDescription;
|
||||
std::string m_audioDevice;
|
||||
|
||||
public:
|
||||
|
||||
GstreamerPlayContext(){
|
||||
m_pipeline = NULL;
|
||||
m_source = NULL;
|
||||
m_decoder = NULL;
|
||||
m_sink = NULL;
|
||||
m_ctrl = NULL;
|
||||
m_volume = NULL;
|
||||
m_ics = NULL;
|
||||
m_data = NULL;
|
||||
m_audioDescription = NULL;
|
||||
m_audioDevice = "default";
|
||||
}
|
||||
|
||||
~GstreamerPlayContext(){
|
||||
}
|
||||
|
||||
void closeContext(){
|
||||
stopContext();
|
||||
if(m_ctrl != NULL){
|
||||
g_object_unref(G_OBJECT(m_ctrl));
|
||||
m_ctrl = NULL;
|
||||
}
|
||||
if(m_ics != NULL){
|
||||
g_object_unref(G_OBJECT(m_ics));
|
||||
m_ics = NULL;
|
||||
}
|
||||
if(m_pipeline != NULL){
|
||||
gst_element_set_state (m_pipeline, GST_STATE_NULL);
|
||||
gst_bin_remove (GST_BIN (m_pipeline), m_sink);
|
||||
m_sink=NULL;
|
||||
gst_object_unref(GST_OBJECT(m_pipeline));
|
||||
m_source = NULL;
|
||||
m_decoder = NULL;
|
||||
m_volume = NULL;
|
||||
m_pipeline = NULL;
|
||||
}
|
||||
if(m_sink != NULL){
|
||||
gst_object_unref(GST_OBJECT(m_sink));
|
||||
m_sink=NULL;
|
||||
}
|
||||
if(m_audioDescription != NULL){
|
||||
m_audioDescription->release();
|
||||
delete m_audioDescription;
|
||||
m_audioDescription = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void playContext(){
|
||||
gst_element_set_state (m_pipeline, GST_STATE_PLAYING);
|
||||
g_object_set(G_OBJECT(m_volume), "volume", 1.0, NULL);
|
||||
}
|
||||
|
||||
void pauseContext(){
|
||||
g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
|
||||
gst_element_set_state (m_pipeline, GST_STATE_PAUSED);
|
||||
}
|
||||
|
||||
void stopContext(){
|
||||
if(GST_IS_ELEMENT(m_volume)) g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
|
||||
if(GST_IS_ELEMENT(m_volume)) gst_element_set_state (m_pipeline, GST_STATE_READY);
|
||||
}
|
||||
|
||||
void setParentData(gpointer data){
|
||||
m_data = data;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set the audio device.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void setAudioDevice(const std::string &deviceName) {
|
||||
m_audioDevice = deviceName;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set the audio device.
|
||||
*----------------------------------------------------------------------------*/
|
||||
GstElement* getAudioBin() {
|
||||
return m_sink;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Opens source element for the file name given.
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool openSource(const gchar *fileUri) throw() {
|
||||
m_source = gst_element_make_from_uri (GST_URI_SRC, fileUri, NULL);
|
||||
if(m_source == NULL){
|
||||
return false;
|
||||
}
|
||||
|
||||
prepareAudioDevice();
|
||||
|
||||
if(m_sink==NULL){
|
||||
std::cerr << "openSource: Failed to create sink!" << std::endl;
|
||||
gst_object_unref (m_source);
|
||||
m_source = NULL;
|
||||
return false;
|
||||
}
|
||||
if(!prepareDecodebin()){
|
||||
std::cerr << "openSource: Failed to create decodebin!" << std::endl;
|
||||
if(m_sink){
|
||||
gst_object_unref (m_sink);
|
||||
m_sink = NULL;
|
||||
}
|
||||
gst_object_unref (m_source);
|
||||
m_source = NULL;
|
||||
return false;
|
||||
}
|
||||
if(!preparePipeline()){
|
||||
std::cerr << "openSource: Failed to create pipeline!" << std::endl;
|
||||
if(m_sink){
|
||||
gst_object_unref (m_sink);
|
||||
m_sink = NULL;
|
||||
}
|
||||
gst_object_unref (m_decoder);
|
||||
m_decoder = NULL;
|
||||
gst_object_unref (m_source);
|
||||
m_source = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Opens source element for the file name given.
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool openSource(AudioDescription *audioDescription) throw() {
|
||||
if(audioDescription == NULL) return false;
|
||||
m_audioDescription = audioDescription;
|
||||
return openSource(m_audioDescription->m_src);
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Returns current stream's duration.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64 getPlayLength() throw() {
|
||||
gint64 ns = 0LL;
|
||||
if(m_pipeline!=NULL){
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
gst_element_query_duration(m_pipeline, &format, &ns);
|
||||
if(format != GST_FORMAT_TIME){
|
||||
ns = 0LL;
|
||||
}
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Returns current stream's position.
|
||||
*----------------------------------------------------------------------------*/
|
||||
gint64 getPosition() throw() {
|
||||
gint64 ns = 0LL;
|
||||
if(m_pipeline!=NULL){
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
gst_element_query_position(m_pipeline, &format, &ns);
|
||||
if(format != GST_FORMAT_TIME){
|
||||
ns = 0LL;
|
||||
}
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Checks if the stream is currently playing.
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool isPlaying() throw() {
|
||||
GstState state;
|
||||
GstState pending;
|
||||
gst_element_get_state(m_pipeline, &state, &pending, 50000000);
|
||||
return state == GST_STATE_PLAYING;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Prepare audio device from the name provided previously.
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool prepareAudioDevice() throw() {
|
||||
if(m_sink != NULL){
|
||||
gst_object_unref(GST_OBJECT(m_sink));
|
||||
m_sink=NULL;
|
||||
}
|
||||
|
||||
GstPad *audiopad;
|
||||
|
||||
const bool oss = m_audioDevice.find("/dev") == 0;
|
||||
|
||||
m_sink = gst_bin_new ("audiobin");
|
||||
if(m_sink == NULL){
|
||||
return false;
|
||||
}
|
||||
GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
|
||||
audiopad = gst_element_get_pad (conv, "sink");
|
||||
|
||||
GstElement *sink = (oss ? gst_element_factory_make("osssink", NULL) : gst_element_factory_make("alsasink", NULL));
|
||||
if(sink == NULL){
|
||||
return false;
|
||||
}
|
||||
g_object_set(G_OBJECT(sink), "device", m_audioDevice.c_str(), NULL);
|
||||
|
||||
m_volume = gst_element_factory_make("volume", NULL);
|
||||
g_object_set(G_OBJECT(m_volume), "volume", 0.0, NULL);
|
||||
|
||||
gst_bin_add_many (GST_BIN (m_sink), conv, m_volume, sink, NULL);
|
||||
gst_element_link (conv, m_volume);
|
||||
gst_element_link (m_volume, sink);
|
||||
gst_element_add_pad (m_sink, gst_ghost_pad_new ("sink", audiopad));
|
||||
gst_object_unref (audiopad);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Prepare empty pipeline.
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool preparePipeline(){
|
||||
if(m_pipeline!=NULL){
|
||||
return false;//pipeline can only be created once per instance
|
||||
}
|
||||
m_pipeline = gst_pipeline_new ("pipeline");
|
||||
if(m_pipeline==NULL){
|
||||
return false;
|
||||
}
|
||||
|
||||
GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
|
||||
gst_bus_add_watch (bus, my_bus_callback, m_data);
|
||||
gst_object_unref (bus);
|
||||
|
||||
//link up all elements in the pipeline
|
||||
gst_bin_add_many (GST_BIN (m_pipeline), m_source, m_decoder, NULL);
|
||||
gst_element_link (m_source, m_decoder);
|
||||
gst_bin_add (GST_BIN (m_pipeline), m_sink);
|
||||
//lastly prepare animations if desired
|
||||
prepareAnimations();
|
||||
return true;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Prepare decode bin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool prepareDecodebin(){
|
||||
if(m_pipeline!=NULL){
|
||||
return false;//pipeline can only be created once per instance
|
||||
}
|
||||
m_decoder = gst_element_factory_make ("decodebin", NULL);
|
||||
g_signal_connect (m_decoder, "new-decoded-pad", G_CALLBACK (cb_newpad), this);
|
||||
return true;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Prepare animations bin.
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool prepareAnimations(){
|
||||
if(m_audioDescription && m_audioDescription->m_animations.size() > 0){
|
||||
m_ctrl = gst_controller_new (G_OBJECT (m_volume), "volume", NULL);
|
||||
if (m_ctrl == NULL) {
|
||||
std::cout << "prepareAnimations: element not controllable!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
GValue vol = { 0, };
|
||||
m_ics = gst_interpolation_control_source_new ();
|
||||
gst_controller_set_control_source (m_ctrl, "volume", GST_CONTROL_SOURCE (m_ics));
|
||||
// Set interpolation mode
|
||||
gst_interpolation_control_source_set_interpolation_mode (m_ics, GST_INTERPOLATE_LINEAR);//GST_INTERPOLATE_CUBIC);
|
||||
// set control values, first fade in
|
||||
g_value_init (&vol, G_TYPE_DOUBLE);
|
||||
if(m_audioDescription->m_animations[0] != NULL){
|
||||
g_value_set_double (&vol, m_audioDescription->m_animations[0]->m_from);
|
||||
gst_interpolation_control_source_set (m_ics, m_audioDescription->m_animations[0]->m_begin, &vol);
|
||||
g_value_set_double (&vol, m_audioDescription->m_animations[0]->m_to);
|
||||
gst_interpolation_control_source_set (m_ics, m_audioDescription->m_animations[0]->m_end, &vol);
|
||||
g_print("prepareAnimations: animation set begin=%d, end=%d, from=%f, to=%f\n",
|
||||
m_audioDescription->m_animations[0]->m_begin,
|
||||
m_audioDescription->m_animations[0]->m_end,
|
||||
m_audioDescription->m_animations[0]->m_from,
|
||||
m_audioDescription->m_animations[0]->m_to);
|
||||
}
|
||||
if(m_audioDescription->m_animations.size() > 1){
|
||||
if(m_audioDescription->m_animations[1] != NULL){
|
||||
//set fade out, between fadein and fadeout we have a hold period
|
||||
g_value_set_double (&vol, m_audioDescription->m_animations[1]->m_from);
|
||||
gst_interpolation_control_source_set (m_ics, m_audioDescription->m_animations[1]->m_begin, &vol);
|
||||
g_value_set_double (&vol, m_audioDescription->m_animations[1]->m_to);
|
||||
gst_interpolation_control_source_set (m_ics, m_audioDescription->m_animations[1]->m_end, &vol);
|
||||
g_print("prepareAnimations: animation set begin=%d, end=%d, from=%f, to=%f\n",
|
||||
m_audioDescription->m_animations[1]->m_begin,
|
||||
m_audioDescription->m_animations[1]->m_end,
|
||||
m_audioDescription->m_animations[1]->m_from,
|
||||
m_audioDescription->m_animations[1]->m_to);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* New pad signal callback.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static void cb_newpad (GstElement *decodebin, GstPad *pad, gboolean last, gpointer data)
|
||||
{
|
||||
GstCaps *caps;
|
||||
GstStructure *str;
|
||||
GstPad *audiopad;
|
||||
audiopad = gst_element_get_pad (((GstreamerPlayContext*)data)->getAudioBin(), "sink");
|
||||
if (GST_PAD_IS_LINKED (audiopad)) {
|
||||
g_object_unref (audiopad);
|
||||
return;
|
||||
}
|
||||
caps = gst_pad_get_caps (pad);
|
||||
str = gst_caps_get_structure (caps, 0);
|
||||
if (!g_strrstr (gst_structure_get_name (str), "audio")) {
|
||||
gst_caps_unref (caps);
|
||||
gst_object_unref (audiopad);
|
||||
return;
|
||||
}
|
||||
gst_caps_unref (caps);
|
||||
gst_pad_link (pad, audiopad);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // GstreamerPlayContext_h
|
|
@ -64,7 +64,7 @@ namespace PlaylistExecutor {
|
|||
class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture,
|
||||
public AudioPlayerEventListener
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(GstreamerPlayerTest);
|
||||
/* CPPUNIT_TEST_SUITE(GstreamerPlayerTest);
|
||||
CPPUNIT_TEST(firstTest);
|
||||
CPPUNIT_TEST(simplePlayTest);
|
||||
CPPUNIT_TEST(getPositionTest);
|
||||
|
@ -80,7 +80,7 @@ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture,
|
|||
CPPUNIT_TEST(pauseResumeTest);
|
||||
CPPUNIT_TEST(openSoundcardTwiceTest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
*/
|
||||
private:
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,576 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2004 Media Development Loan Fund
|
||||
|
||||
This file is part of the Campcaster project.
|
||||
http://campcaster.campware.org/
|
||||
To report bugs, send an e-mail to bugs@campware.org
|
||||
|
||||
Campcaster is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Campcaster 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Campcaster; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Author : $Author$
|
||||
Version : $Revision$
|
||||
Location : $URL$
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef SmilHandler_h
|
||||
#define SmilHandler_h
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "configure.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#error need string.h
|
||||
#endif
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
#define NSEC_PER_SEC 1000000000LL
|
||||
#define SEC_PER_MIN 60
|
||||
#define SEC_PER_HOUR 3600
|
||||
#define NSEC_PER_SEC_FLOAT 1000000000.0
|
||||
#define SEC_PER_MIN_FLOAT 60.0
|
||||
#define SEC_PER_HOUR_FLOAT 3600.0
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
/**
|
||||
* The AnimationDescription class.
|
||||
*
|
||||
* It is assumed that thic class supports only animations that have
|
||||
*
|
||||
* attributeName="soundLevel",
|
||||
* calcMode="linear" and
|
||||
* fill="freeze"
|
||||
*
|
||||
* If these conditions are not met, the entire animate entry in xml will
|
||||
* be ignored and this object will never be created.
|
||||
*/
|
||||
class AnimationDescription {
|
||||
public:
|
||||
double m_from;
|
||||
double m_to;
|
||||
guint64 m_begin;
|
||||
guint64 m_end;
|
||||
|
||||
AnimationDescription():
|
||||
m_from(0.0),
|
||||
m_to(0.0),
|
||||
m_begin(0),
|
||||
m_end(0)
|
||||
{
|
||||
// std::cout << "AnimationDescription created!" << std::endl;
|
||||
}
|
||||
~AnimationDescription()
|
||||
{
|
||||
// std::cout << "AnimationDescription destroyed!" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The AudioDescription class.
|
||||
*/
|
||||
class AudioDescription {
|
||||
public:
|
||||
gchar *m_src;
|
||||
gint64 m_begin;
|
||||
gint64 m_clipBegin;
|
||||
gint64 m_clipEnd;
|
||||
std::vector<AnimationDescription*> m_animations;
|
||||
|
||||
AudioDescription():
|
||||
m_src(NULL),
|
||||
m_begin(0),
|
||||
m_clipBegin(0),
|
||||
m_clipEnd(0)
|
||||
{
|
||||
// std::cout << "AudioDescription created!" << std::endl;
|
||||
}
|
||||
~AudioDescription()
|
||||
{
|
||||
// std::cout << "AudioDescription destroyed!" << std::endl;
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
for(int i = m_animations.size(); i > 0; i--){
|
||||
delete m_animations[i-1];
|
||||
}
|
||||
m_animations.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A class to parse SMIL file and return playback info in sequence.
|
||||
*
|
||||
* Usage sequence:
|
||||
*
|
||||
* create an instance of GstreamerPlayContext object
|
||||
* call setParentData to provide data to be returned by my_bus_callback
|
||||
* call setAudioDevice on it
|
||||
* call openSource on it
|
||||
* call playContext on it
|
||||
*
|
||||
* when done, call closeContext on it
|
||||
* destroy instance
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class SmilHandler
|
||||
{
|
||||
xmlDocPtr m_document;
|
||||
xmlNode *m_bodyChildren;
|
||||
xmlNode *m_parChildren;
|
||||
SmilHandler *m_subSmil;
|
||||
|
||||
public:
|
||||
|
||||
SmilHandler(){
|
||||
m_document = NULL;
|
||||
m_bodyChildren = NULL;
|
||||
m_parChildren = NULL;
|
||||
m_subSmil = NULL;
|
||||
}
|
||||
|
||||
~SmilHandler(){
|
||||
xmlCleanupParser();
|
||||
if(m_document != NULL){
|
||||
xmlFreeDoc(m_document);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the sink input as a SMIL file.
|
||||
* The bin container inside the MinimalAudioSmil object will be filled
|
||||
* with gstreamer elements, playing audio as described by the SMIL file.
|
||||
*
|
||||
* @para smil a MinimalAudioSmil object.
|
||||
* @return TRUE if processing was successful, FALSE otherwise.
|
||||
*/
|
||||
gboolean openSmilFile(const gchar *xmlFile){
|
||||
xmlNode *node;
|
||||
|
||||
/* parse the XML files */
|
||||
m_document = xmlReadFile(xmlFile, NULL, XML_PARSE_RECOVER);
|
||||
if (!m_document || !(node = getBodyElement(m_document))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bodyChildren = node->children;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch next audio entry in sequence.
|
||||
* @return AudioDescription object if processing was successful, NULL otherwise.
|
||||
*/
|
||||
AudioDescription *getNext(){
|
||||
emptysmilrecovery:
|
||||
AudioDescription *audioDescription = NULL;
|
||||
|
||||
if(m_subSmil != NULL){
|
||||
audioDescription = m_subSmil->getNext();
|
||||
if(audioDescription == NULL){
|
||||
delete m_subSmil;
|
||||
m_subSmil = NULL;
|
||||
}else{
|
||||
return audioDescription;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_parChildren){//we are currently traversing par segment
|
||||
audioDescription = getNextPar();
|
||||
}
|
||||
|
||||
if(audioDescription == NULL && m_bodyChildren){//par exaused, see if there is more in the body segment
|
||||
for (; m_bodyChildren; m_bodyChildren = m_bodyChildren->next) {
|
||||
if (m_bodyChildren->type == XML_ELEMENT_NODE) {
|
||||
if (!strcmp((const char*)m_bodyChildren->name, "par")) {
|
||||
m_parChildren = m_bodyChildren->children;
|
||||
audioDescription = getNextPar();
|
||||
if(audioDescription != NULL){
|
||||
m_bodyChildren = m_bodyChildren->next;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GST_WARNING("unsupported SMIL element %s found", m_bodyChildren->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(audioDescription != NULL && std::string(audioDescription->m_src).find(".smil") != std::string::npos){//we have a sub smil
|
||||
m_subSmil = new SmilHandler();
|
||||
m_subSmil->openSmilFile(audioDescription->m_src);
|
||||
delete audioDescription;
|
||||
audioDescription = m_subSmil->getNext();
|
||||
if(audioDescription == NULL){
|
||||
delete m_subSmil;
|
||||
m_subSmil = NULL;
|
||||
goto emptysmilrecovery;
|
||||
}
|
||||
}
|
||||
|
||||
return audioDescription;
|
||||
}
|
||||
|
||||
gint64 getPlayLength() throw() {
|
||||
gint64 ns = 0LL;
|
||||
//TODO: calculate proper playlist length
|
||||
return ns;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Fetch next audio entry from "<par>" SMIL segment.
|
||||
*
|
||||
* @return AudioDescription object if processing was successful, NULL otherwise..
|
||||
*/
|
||||
AudioDescription *getNextPar(){
|
||||
AudioDescription *audioDescription = NULL;
|
||||
for (; m_parChildren; m_parChildren = m_parChildren->next) {
|
||||
if (m_parChildren->type == XML_ELEMENT_NODE) {
|
||||
if (!strcmp((const char*)m_parChildren->name, "audio")) {
|
||||
audioDescription = getNextAudio(m_parChildren);
|
||||
if(audioDescription != NULL){
|
||||
m_parChildren = m_parChildren->next;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GST_WARNING("unsupported SMIL element %s found inside a par", m_parChildren->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return audioDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch next audio entry from "<audio>" SMIL segment.
|
||||
*
|
||||
* @param audio an "<audio>" SMIL element.
|
||||
* @return AudioDescription object if processing was successful, NULL otherwise..
|
||||
*/
|
||||
AudioDescription *getNextAudio(xmlNode *audio){
|
||||
AudioDescription *audioDescription = NULL;
|
||||
|
||||
xmlNode * node;
|
||||
xmlAttribute * attr;
|
||||
gchar * src = 0;
|
||||
gchar * begin = 0;
|
||||
gchar * clipBegin = 0;
|
||||
gchar * clipEnd = 0;
|
||||
|
||||
/* handle the attributes */
|
||||
for (attr = ((xmlElement*)audio)->attributes; attr; attr = (xmlAttribute*) attr->next) {
|
||||
/* TODO: support attribute values that are represented with
|
||||
* more than one text node, in all content assignments below */
|
||||
if (!strcmp((const char*)attr->name, "src")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
src = (gchar*) node->content;
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "begin")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
begin = (gchar*) node->content;
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "clipBegin")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
clipBegin = (gchar*) node->content;
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "clipEnd")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
clipEnd = (gchar*) node->content;
|
||||
}
|
||||
} else {
|
||||
GST_WARNING("unsupported SMIL audio element attribute: %s",
|
||||
attr->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!begin) {
|
||||
begin = "0s";
|
||||
}
|
||||
if (!clipBegin) {
|
||||
clipBegin = "0s";
|
||||
}
|
||||
if (!clipEnd) {
|
||||
clipEnd = "0s";
|
||||
}
|
||||
audioDescription = new AudioDescription();
|
||||
audioDescription->m_src = src;
|
||||
audioDescription->m_begin = su_smil_clock_value_to_nanosec(begin);
|
||||
audioDescription->m_clipBegin = su_smil_clock_value_to_nanosec(clipBegin);
|
||||
audioDescription->m_clipEnd = su_smil_clock_value_to_nanosec(clipEnd);
|
||||
// now handle the possible animate elements inside this audio element
|
||||
for (node = audio->children; node; node = node->next) {
|
||||
if (node->type == XML_ELEMENT_NODE) {
|
||||
if (!strcmp((const char*)node->name, "animate")) {
|
||||
AnimationDescription *anim = getNextAnimate(audioDescription->m_begin, node);
|
||||
if(anim != NULL){
|
||||
audioDescription->m_animations.push_back(anim);
|
||||
}
|
||||
} else {
|
||||
GST_WARNING("unsupported SMIL element %s found inside a audio", node->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return audioDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an "<animate>" element.
|
||||
*
|
||||
* @param offset the offset in nanoseconds that the animation should
|
||||
* begin at. this is usually the begin="xx" attribute value
|
||||
* of the containing element.
|
||||
* @param animate the "<animate>" element to handle.
|
||||
* @return AnimationDescription object if processing was successful, NULL otherwise..
|
||||
*/
|
||||
AnimationDescription *getNextAnimate(gint64 offset, xmlNode *animate){
|
||||
xmlAttribute * attr;
|
||||
double from = 0.0;
|
||||
double to = 0.0;
|
||||
guint64 begin = 0;
|
||||
guint64 end = 0;
|
||||
|
||||
/* handle the attributes */
|
||||
for (attr = ((xmlElement*)animate)->attributes; attr; attr = (xmlAttribute*) attr->next) {
|
||||
|
||||
xmlNode * node;
|
||||
|
||||
/* TODO: support attribute values that are represented with
|
||||
* more than one text node, in all content assignments below */
|
||||
if (!strcmp((const char*)attr->name, "attributeName")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
gchar* cstr = (gchar*) node->content;
|
||||
/* we only support soundLevel animation at the moment */
|
||||
if (strcmp(cstr, "soundLevel")) {
|
||||
GST_WARNING("unsupported animate attribute: %s", cstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "calcMode")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
gchar* cstr = (gchar*) node->content;
|
||||
/* we only support linear calc mode at the moment */
|
||||
if (strcmp(cstr, "linear")) {
|
||||
GST_WARNING("unsupported animate calcMode: %s", cstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "fill")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
gchar* cstr = (gchar*) node->content;
|
||||
/* we only support freeze fill at the moment */
|
||||
if (strcmp(cstr, "freeze")) {
|
||||
GST_WARNING("unsupported animate fill: %s", cstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "from")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
gchar* cstr = (gchar*) node->content;
|
||||
if (!su_smil_parse_percent(cstr, &from)) {
|
||||
GST_WARNING("bad from value: %s", cstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "to")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
gchar* cstr = (gchar*) node->content;
|
||||
if (!su_smil_parse_percent(cstr, &to)) {
|
||||
GST_WARNING("bad to value: %s", cstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "begin")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
gint64 i;
|
||||
gchar* cstr = (gchar*) node->content;
|
||||
begin = su_smil_clock_value_to_nanosec(cstr);// + offset;
|
||||
// begin = ((double) i) / NSEC_PER_SEC_FLOAT;
|
||||
}
|
||||
} else if (!strcmp((const char*)attr->name, "end")) {
|
||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||
gint64 i;
|
||||
gchar* cstr = (gchar*) node->content;
|
||||
end = su_smil_clock_value_to_nanosec(cstr);// + offset;
|
||||
// end = ((double) i) / NSEC_PER_SEC_FLOAT;
|
||||
}
|
||||
} else {
|
||||
GST_WARNING("unsupported SMIL audio element attribute: %s",
|
||||
attr->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (from == 0.0 && to == 0.0 && begin == 0.0 && end == 0.0) {
|
||||
GST_WARNING("some required animate attribute missing");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (begin >= end) {
|
||||
GST_WARNING("begin value in animate greater than end value");
|
||||
return 0;
|
||||
}
|
||||
AnimationDescription *animDesc = new AnimationDescription();
|
||||
animDesc->m_from = from;
|
||||
animDesc->m_to = to;
|
||||
animDesc->m_begin = begin;
|
||||
animDesc->m_end = end;
|
||||
return animDesc;
|
||||
}
|
||||
|
||||
xmlNode *getBodyElement(xmlDocPtr document){
|
||||
xmlNode * node = document->children;
|
||||
if (!node || strcmp((const char*)node->name, "smil")) {
|
||||
return 0;
|
||||
}
|
||||
for (node = node->children; node; node = node->next) {
|
||||
if (node->type == XML_ELEMENT_NODE
|
||||
&& !strcmp((const char*)node->name, "body")) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Convert a hour-minute-second triplet to nanoseconds
|
||||
*----------------------------------------------------------------------------*/
|
||||
static gint64
|
||||
su_hms_to_nanosec(int hours,
|
||||
int minutes,
|
||||
double seconds)
|
||||
{
|
||||
gint64 nanosec;
|
||||
double nsec;
|
||||
|
||||
nsec = seconds * NSEC_PER_SEC_FLOAT;
|
||||
|
||||
nanosec = (gint64) nsec;
|
||||
nanosec += ((gint64) hours) * NSEC_PER_SEC;
|
||||
nanosec += ((gint64) minutes) * SEC_PER_MIN * NSEC_PER_SEC;
|
||||
|
||||
return nanosec;
|
||||
}
|
||||
/**
|
||||
* Parse the clock value according to the SMIL clock spec
|
||||
*
|
||||
* see http://www.w3.org/TR/2005/REC-SMIL2-20050107/smil-timing.html#Timing-ClockValueSyntax
|
||||
*
|
||||
* the BNF for the value is:
|
||||
*
|
||||
* <pre><code>
|
||||
* Clock-value ::= ( Full-clock-value | Partial-clock-value
|
||||
* | Timecount-value )
|
||||
* Full-clock-value ::= Hours ":" Minutes ":" Seconds ("." Fraction)?
|
||||
* Partial-clock-value ::= Minutes ":" Seconds ("." Fraction)?
|
||||
* Timecount-value ::= Timecount ("." Fraction)? (Metric)?
|
||||
* Metric ::= "h" | "min" | "s" | "ms"
|
||||
* Hours ::= DIGIT+; any positive number
|
||||
* Minutes ::= 2DIGIT; range from 00 to 59
|
||||
* Seconds ::= 2DIGIT; range from 00 to 59
|
||||
* Fraction ::= DIGIT+
|
||||
* Timecount ::= DIGIT+
|
||||
* 2DIGIT ::= DIGIT DIGIT
|
||||
* DIGIT ::= [0-9]
|
||||
* </code></pre>
|
||||
*
|
||||
* @param value the SMIL clock value in string form
|
||||
* @return the clock value in nanoseconds
|
||||
*/
|
||||
guint64
|
||||
su_smil_clock_value_to_nanosec(const gchar * value)
|
||||
{
|
||||
int hours;
|
||||
int minutes;
|
||||
double seconds;
|
||||
|
||||
/* see if it's a full-clock-value */
|
||||
if (sscanf(value, "%2d:%2d:%lf", &hours, &minutes, &seconds) == 3) {
|
||||
return su_hms_to_nanosec(hours, minutes, seconds);
|
||||
}
|
||||
|
||||
/* see if it's a partial-clock-value */
|
||||
if (sscanf(value, "%2d:%lf", &minutes, &seconds) == 2) {
|
||||
return su_hms_to_nanosec(0, minutes, seconds);
|
||||
}
|
||||
|
||||
/* see if it's a timecount-value, in hours */
|
||||
if (g_str_has_suffix(value, "h")
|
||||
&& sscanf(value, "%lfh", &seconds) == 1) {
|
||||
return su_hms_to_nanosec(0, 0, seconds * SEC_PER_HOUR_FLOAT);
|
||||
}
|
||||
|
||||
/* see if it's a timecount-value, in minutes */
|
||||
if (g_str_has_suffix(value, "min")
|
||||
&& sscanf(value, "%lfmin", &seconds) == 1) {
|
||||
return su_hms_to_nanosec(0, 0, seconds * SEC_PER_MIN_FLOAT);
|
||||
}
|
||||
|
||||
/* see if it's a timecount-value, in millisecs */
|
||||
if (g_str_has_suffix(value, "ms")
|
||||
&& sscanf(value, "%lfms", &seconds) == 1) {
|
||||
return su_hms_to_nanosec(0, 0, seconds / 100.0);
|
||||
}
|
||||
|
||||
/* it's a timecount-value, either with no metric, or explicit seconds */
|
||||
if (sscanf(value, "%lfs", &seconds) == 1) {
|
||||
return su_hms_to_nanosec(0, 0, seconds);
|
||||
}
|
||||
|
||||
return -1LL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string as a percentage value, and return the result as a
|
||||
* float. Indicate parse error.
|
||||
*
|
||||
* @param str the string to parse.
|
||||
* @param value the parsed value (out parameter).
|
||||
* @return TRUE if parsing went OK, FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
su_smil_parse_percent(const gchar * str,
|
||||
double * value)
|
||||
{
|
||||
double val;
|
||||
|
||||
if (g_str_has_suffix(str, "%")
|
||||
&& sscanf(str, "%lf%%", &val) == 1) {
|
||||
*value = val / 100.0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SmilHandler_h
|
|
@ -48,6 +48,9 @@
|
|||
#include <fstream>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/controller/gstcontroller.h>
|
||||
#include <gst/controller/gstinterpolationcontrolsource.h>
|
||||
|
||||
|
||||
#include <cppunit/BriefTestProgressListener.h>
|
||||
#include <cppunit/CompilerOutputter.h>
|
||||
|
@ -59,6 +62,8 @@
|
|||
|
||||
#include "LiveSupport/Core/Ptr.h"
|
||||
|
||||
#include "GstreamerPlayContext.h"
|
||||
#include "SmilHandler.h"
|
||||
|
||||
using namespace LiveSupport::Core;
|
||||
|
||||
|
@ -139,14 +144,304 @@ processArguments(int argc, char *argv[]);
|
|||
|
||||
/* ============================================================= module code */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Run all tests
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
static GMainLoop *loop;
|
||||
static GstElement *play=NULL;
|
||||
|
||||
|
||||
static GstreamerPlayContext *pContext=NULL;
|
||||
static GstreamerPlayContext *pContextNext=NULL;
|
||||
|
||||
static SmilHandler *smil = NULL;
|
||||
|
||||
|
||||
static int cnt=0;
|
||||
|
||||
static gboolean
|
||||
my_bus_callback (GstBus *bus,
|
||||
GstMessage *message,
|
||||
gpointer data)
|
||||
{
|
||||
g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
|
||||
|
||||
switch (GST_MESSAGE_TYPE (message)) {
|
||||
case GST_MESSAGE_ERROR: {
|
||||
GError *err;
|
||||
gchar *debug;
|
||||
|
||||
gst_message_parse_error (message, &err, &debug);
|
||||
g_print ("Error: %s\n", err->message);
|
||||
g_error_free (err);
|
||||
g_free (debug);
|
||||
|
||||
g_main_loop_quit (loop);
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_EOS:
|
||||
if(cnt<0){
|
||||
// if(cnt<5){
|
||||
char tmp[255]={0};
|
||||
sprintf(tmp, "file:///home/nebojsa/testFiles/%d.ogg", cnt+1);//use when file name needed
|
||||
if(pContext){
|
||||
pContext->closeContext();
|
||||
delete pContext;
|
||||
pContext = NULL;
|
||||
}
|
||||
|
||||
/* if(pContextNext){
|
||||
pContext=pContextNext;
|
||||
pContextNext=new GstreamerPlayContext(tmp);
|
||||
}
|
||||
*/
|
||||
|
||||
pContext=new GstreamerPlayContext();
|
||||
// pContext->setAudioDevice("default");
|
||||
pContext->openSource(tmp);
|
||||
|
||||
|
||||
|
||||
if(pContext){
|
||||
pContext->playContext();
|
||||
}
|
||||
|
||||
cnt++;
|
||||
}else if(smil != NULL){
|
||||
pContext->closeContext();
|
||||
AudioDescription *audioDescription = smil->getNext();
|
||||
if(audioDescription == NULL){//no more audio entries to play
|
||||
delete smil;
|
||||
smil = NULL;
|
||||
delete pContext;
|
||||
g_main_loop_quit (loop);
|
||||
break;
|
||||
}
|
||||
pContext->openSource(audioDescription);
|
||||
pContext->playContext();
|
||||
}else{
|
||||
if(pContext){
|
||||
pContext->closeContext();
|
||||
delete pContext;
|
||||
pContext = NULL;
|
||||
}
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//we want to be notified again the next time there is a message
|
||||
//on the bus, so returning TRUE (FALSE means we want to stop watching
|
||||
//for messages on the bus and our callback should not be called again)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main( int argc,
|
||||
char * argv[] ) throw ()
|
||||
{
|
||||
// initialize the gst parameters
|
||||
// sleep(10);//hook for debugging, allows time to attach kdbg
|
||||
|
||||
/*
|
||||
gint res = 1;
|
||||
GstElement *src, *sink;
|
||||
GstElement *bin;
|
||||
GstController *ctrl;
|
||||
GstInterpolationControlSource *csource1;//, *csource2;
|
||||
GstClock *clock;
|
||||
GstClockID clock_id;
|
||||
GstClockReturn wait_ret;
|
||||
GValue vol = { 0, };
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
gst_controller_init (&argc, &argv);
|
||||
|
||||
// build pipeline
|
||||
bin = gst_pipeline_new ("pipeline");
|
||||
clock = gst_pipeline_get_clock (GST_PIPELINE (bin));
|
||||
src = gst_element_factory_make ("audiotestsrc", "gen_audio");
|
||||
// src = gst_element_make_from_uri (GST_URI_SRC, "file:///usr/share/sounds/kubuntu-login.ogg", NULL);
|
||||
sink = gst_element_factory_make ("alsasink", "play_audio");
|
||||
gst_bin_add_many (GST_BIN (bin), src, sink, NULL);
|
||||
if (!gst_element_link (src, sink)) {
|
||||
GST_WARNING ("can't link elements");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// square wave
|
||||
// g_object_set (G_OBJECT(src), "wave", 1, NULL);
|
||||
|
||||
// add a controller to the source
|
||||
// if (!(ctrl = gst_controller_new (G_OBJECT (src), "freq", "volume", NULL))) {
|
||||
if (!(ctrl = gst_controller_new (G_OBJECT (src), "volume", NULL))) {
|
||||
GST_WARNING ("can't control source element");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
csource1 = gst_interpolation_control_source_new ();
|
||||
// csource2 = gst_interpolation_control_source_new ();
|
||||
|
||||
gst_controller_set_control_source (ctrl, "volume", GST_CONTROL_SOURCE (csource1));
|
||||
// gst_controller_set_control_source (ctrl, "freq", GST_CONTROL_SOURCE (csource2));
|
||||
|
||||
// Set interpolation mode
|
||||
|
||||
gst_interpolation_control_source_set_interpolation_mode (csource1, GST_INTERPOLATE_LINEAR);
|
||||
// gst_interpolation_control_source_set_interpolation_mode (csource2, GST_INTERPOLATE_LINEAR);
|
||||
|
||||
// set control values
|
||||
g_value_init (&vol, G_TYPE_DOUBLE);
|
||||
|
||||
g_value_set_double (&vol, 0.0);
|
||||
gst_interpolation_control_source_set (csource1, 0 * GST_SECOND, &vol);
|
||||
g_value_set_double (&vol, 1.0);
|
||||
gst_interpolation_control_source_set (csource1, 1 * GST_SECOND, &vol);
|
||||
|
||||
g_value_set_double (&vol, 1.0);
|
||||
gst_interpolation_control_source_set (csource1, 2 * GST_SECOND, &vol);
|
||||
g_value_set_double (&vol, 0.0);
|
||||
gst_interpolation_control_source_set (csource1, 3 * GST_SECOND, &vol);
|
||||
|
||||
g_object_unref (csource1);
|
||||
|
||||
// g_value_set_double (&vol, 220.0);
|
||||
// gst_interpolation_control_source_set (csource2, 0 * GST_SECOND, &vol);
|
||||
// g_value_set_double (&vol, 3520.0);
|
||||
// gst_interpolation_control_source_set (csource2, 3 * GST_SECOND, &vol);
|
||||
// g_value_set_double (&vol, 440.0);
|
||||
// gst_interpolation_control_source_set (csource2, 6 * GST_SECOND, &vol);
|
||||
//
|
||||
// g_object_unref (csource2);
|
||||
|
||||
clock_id =
|
||||
gst_clock_new_single_shot_id (clock,
|
||||
gst_clock_get_time (clock) + (6 * GST_SECOND));
|
||||
|
||||
// run for 7 seconds
|
||||
if (gst_element_set_state (bin, GST_STATE_PLAYING)) {
|
||||
if ((wait_ret = gst_clock_id_wait (clock_id, NULL)) != GST_CLOCK_OK) {
|
||||
GST_WARNING ("clock_id_wait returned: %d", wait_ret);
|
||||
}
|
||||
gst_element_set_state (bin, GST_STATE_NULL);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
g_object_unref (G_OBJECT (ctrl));
|
||||
gst_object_unref (G_OBJECT (clock));
|
||||
gst_object_unref (G_OBJECT (bin));
|
||||
res = 0;
|
||||
Error:
|
||||
return (res);
|
||||
*/
|
||||
/*
|
||||
//quick gnonlin playback test
|
||||
gst_init (NULL, NULL);
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
|
||||
GstElement *composition = gst_element_factory_make("gnlcomposition", NULL);
|
||||
// GstElement *silentGnlSource = gst_element_factory_make("gnlsource", NULL);
|
||||
// GstElement *silenceAudioSource = gst_element_factory_make("audiotestsrc", NULL);
|
||||
|
||||
GstElement *volumeFadeBin = gst_element_factory_make("bin", "Volume_fades_bin");
|
||||
GstElement *volumeFadeElement = gst_element_factory_make("volume", "Volume_Fade_Element");
|
||||
GstElement *volumeFadeStartConvert = gst_element_factory_make("audioconvert", "Start_fadebin_converter");
|
||||
GstElement *volumeFadeEndConvert = gst_element_factory_make("audioconvert", "End_fadebin_converter");
|
||||
GstElement *volumeFadeOperation = gst_element_factory_make("gnloperation", "gnloperation");
|
||||
GstController *volumeFadeController = gst_controller_new(G_OBJECT(volumeFadeElement), "volume");
|
||||
|
||||
gst_bin_add(GST_BIN(volumeFadeBin), volumeFadeElement);
|
||||
gst_bin_add(GST_BIN(volumeFadeBin), volumeFadeStartConvert);
|
||||
gst_bin_add(GST_BIN(volumeFadeBin), volumeFadeEndConvert);
|
||||
GstPad *volumeFadeBinSink = gst_ghost_pad_new("sink", gst_element_get_pad(volumeFadeStartConvert, "sink"));
|
||||
gst_element_add_pad(volumeFadeBin, volumeFadeBinSink);
|
||||
GstPad *volumeFadeBinSrc = gst_ghost_pad_new("src", gst_element_get_pad(volumeFadeEndConvert, "src"));
|
||||
gst_element_add_pad(volumeFadeBin, volumeFadeBinSrc);
|
||||
|
||||
// g_object_set(G_OBJECT(silenceAudioSource), "wave", 4, NULL); //4 is silence
|
||||
|
||||
// g_object_set(G_OBJECT(silentGnlSource), "priority", (2 ^ 32 - 1), NULL);
|
||||
// g_object_set(G_OBJECT(silentGnlSource), "start", 0, NULL);
|
||||
// g_object_set(G_OBJECT(silentGnlSource), "duration", 1000 * GST_SECOND, NULL);
|
||||
// g_object_set(G_OBJECT(silentGnlSource), "media-start", 0, NULL);
|
||||
// g_object_set(G_OBJECT(silentGnlSource), "media-duration", 1000 * GST_SECOND, NULL);
|
||||
|
||||
g_object_set(G_OBJECT(volumeFadeOperation), "start", long(0) * GST_SECOND, NULL);
|
||||
g_object_set(G_OBJECT(volumeFadeOperation), "duration", long(20) * GST_SECOND, NULL);
|
||||
g_object_set(G_OBJECT(volumeFadeOperation), "priority", 1, NULL);
|
||||
|
||||
gst_controller_set_interpolation_mode(volumeFadeController, "volume", GST_INTERPOLATE_LINEAR);
|
||||
|
||||
gst_bin_add(GST_BIN(volumeFadeOperation), volumeFadeBin);
|
||||
// gst_bin_add(GST_BIN(silentGnlSource), silenceAudioSource);
|
||||
// gst_bin_add(GST_BIN(composition), silentGnlSource);
|
||||
gst_bin_add(GST_BIN(composition), volumeFadeOperation);//this is where we hook up to the rest of the pipeline
|
||||
|
||||
gst_element_link(volumeFadeStartConvert, volumeFadeElement);
|
||||
gst_element_link(volumeFadeElement, volumeFadeEndConvert);
|
||||
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
return 0;
|
||||
*/
|
||||
|
||||
//quick smil playback test
|
||||
gst_init (NULL, NULL);
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
//quick test for smil parser
|
||||
smil = new SmilHandler();
|
||||
smil->openSmilFile("file:///home/nebojsa/src/campcaster/src/modules/playlistExecutor/var/animatedSmil.smil");
|
||||
|
||||
pContext=new GstreamerPlayContext();
|
||||
pContext->setParentData((gpointer)pContext);
|
||||
|
||||
AudioDescription *audDesc = smil->getNext();
|
||||
pContext->openSource(audDesc);
|
||||
pContext->playContext();
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
return 0;
|
||||
|
||||
/*
|
||||
//quick test for play context
|
||||
gst_init (NULL, NULL);
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
pContext=new GstreamerPlayContext();
|
||||
pContext->setParentData((gpointer)pContext);
|
||||
// pContext->setAudioDevice("default");
|
||||
// pContext->openSource("/usr/share/sounds/kubuntu-login.ogg");
|
||||
// pContext->openSource("file:///usr/share/sounds/kubuntu-login.ogg");
|
||||
pContext->openSource("file:///home/nebojsa/src/campcaster/var/jingles/B92 - Brian Eno.ogg");
|
||||
// pContext->openSource("file:///home/nebojsa/src/campcaster/var/jingles/LS Live FEED.ogg");
|
||||
|
||||
// pContext->openSource("http://www.sicksiteradio.com/contents/radio_shows/sicksiteradio57.mp3");
|
||||
|
||||
// pContext->openSource("file:///home/nebojsa/testFiles/3n.mp3");
|
||||
// pContextNext=new GstreamerPlayContext("file:///home/nebojsa/testFiles/1.ogg");
|
||||
// cnt++;
|
||||
pContext->playContext();
|
||||
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
if(pContext){
|
||||
pContext->closeContext();
|
||||
delete pContext;
|
||||
}
|
||||
|
||||
return 0; // initialize the gst parameters
|
||||
*/
|
||||
/*
|
||||
gst_init(&argc, &argv);
|
||||
|
||||
if (!processArguments(argc, argv)) {
|
||||
|
@ -186,6 +481,7 @@ main( int argc,
|
|||
xmlOutFile.close();
|
||||
|
||||
return result.wasSuccessful() ? 0 : 1;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<smil xmlns = "http://www.w3.org/2001/SMIL20/Language">
|
||||
<body>
|
||||
<par>
|
||||
<audio src="file:var/test10001.mp3" begin="0s">
|
||||
<audio src="file:///home/nebojsa/src/campcaster/src/modules/playlistExecutor/var/test10001.mp3" begin="0s">
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "100%"
|
||||
to = "0%"
|
||||
|
@ -12,7 +12,7 @@
|
|||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
<audio src="file:var/test10002.mp3" begin="6.23s">
|
||||
<audio src="file:///home/nebojsa/src/campcaster/src/modules/playlistExecutor/var/test10002.mp3" begin="6.23s">
|
||||
<animate attributeName = "soundLevel"
|
||||
from = "0%"
|
||||
to = "100%"
|
||||
|
@ -22,7 +22,7 @@
|
|||
fill = "freeze"
|
||||
/>
|
||||
</audio>
|
||||
<audio src="file:var/test10003.mp3" begin="18.45s">
|
||||
<audio src="file:///home/nebojsa/src/campcaster/src/modules/playlistExecutor/var/test10003.mp3" begin="18.45s">
|
||||
</audio>
|
||||
</par>
|
||||
</body>
|
||||
|
|
|
@ -1807,7 +1807,7 @@ class BasicStor {
|
|||
}
|
||||
if (is_null($parid)) {
|
||||
return PEAR::raiseError("BasicStor::_getHomeDirId: ".
|
||||
"homedir not found ($subjid)", GBERR_NOTF);
|
||||
"homedir not found ($subjid) ($login)", GBERR_NOTF);
|
||||
}
|
||||
return $parid;
|
||||
}
|
||||
|
|
|
@ -152,13 +152,6 @@ SCHEDULER_CLIENT_LIB_DIR = ${SCHEDULER_CLIENT_DIR}/lib
|
|||
SCHEDULER_CLIENT_LIB = livesupport_scheduler_client
|
||||
SCHEDULER_CLIENT_LIB_FILE = ${SCHEDULER_CLIENT_LIB_DIR}/lib${SCHEDULER_CLIENT_LIB}.a
|
||||
|
||||
GSTREAMER_ELEMENTS_DIR = ${MODULES_DIR}/gstreamerElements
|
||||
GSTREAMER_ELEMENTS_INCLUDE_DIR = ${GSTREAMER_ELEMENTS_DIR}/include
|
||||
GSTREAMER_ELEMENTS_LIB_DIR = ${GSTREAMER_ELEMENTS_DIR}/lib
|
||||
GSTREAMER_ELEMENTS_LIB = livesupport_gstreamerelements
|
||||
GSTREAMER_ELEMENTS_LIB_FILE = ${GSTREAMER_ELEMENTS_LIB_DIR}/lib${GSTREAMER_ELEMENTS_LIB}.a
|
||||
GST_REAL_LIB_DIR=${REAL_BASE_DIR}/modules/gstreamerElements/lib
|
||||
|
||||
PLAYLIST_EXECUTOR_DIR = ${MODULES_DIR}/playlistExecutor
|
||||
PLAYLIST_EXECUTOR_INCLUDE_DIR = ${PLAYLIST_EXECUTOR_DIR}/include
|
||||
PLAYLIST_EXECUTOR_LIB_DIR = ${PLAYLIST_EXECUTOR_DIR}/lib
|
||||
|
@ -190,6 +183,9 @@ LIBGLADEMM_LIBS=@LIBGLADEMM_LIBS@
|
|||
GSTREAMER_CFLAGS=@GSTREAMER_CFLAGS@
|
||||
GSTREAMER_LIBS=@GSTREAMER_LIBS@
|
||||
|
||||
GSTCONTROLLER_CFLAGS=@GSTCONTROLLER_CFLAGS@
|
||||
GSTCONTROLLER_LIBS=@GSTCONTROLLER_LIBS@
|
||||
|
||||
ICU_CFLAGS=@ICU_CFLAGS@
|
||||
ICU_CXXFLAGS=@ICU_CXXFLAGS@
|
||||
ICU_LIBS=@ICU_LIBS@
|
||||
|
@ -209,7 +205,6 @@ TEST_RUNNER = ${TMP_DIR}/testRunner
|
|||
DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
|
||||
|
||||
export LD_LIBRARY_PATH:=${USR_LIB_DIR}:${LD_LIBRARY_PATH}
|
||||
export GST_PLUGIN_PATH=${GST_REAL_LIB_DIR}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
@ -224,13 +219,13 @@ CXXFLAGS = @CXXFLAGS@ @DEFS@ @COVERAGE_CXXFLAGS@ -pthread \
|
|||
${GTKMM_CFLAGS} \
|
||||
${LIBGLADEMM_CFLAGS} \
|
||||
${GSTREAMER_CFLAGS} \
|
||||
${GSTCONTROLLER_CFLAGS} \
|
||||
-I${USR_INCLUDE_DIR} \
|
||||
-I${CORE_INCLUDE_DIR} \
|
||||
-I${AUTHENTICATION_INCLUDE_DIR} \
|
||||
-I${STORAGE_CLIENT_INCLUDE_DIR} \
|
||||
-I${WIDGETS_INCLUDE_DIR} \
|
||||
-I${SCHEDULER_CLIENT_INCLUDE_DIR} \
|
||||
-I${GSTREAMER_ELEMENTS_INCLUDE_DIR} \
|
||||
-I${PLAYLIST_EXECUTOR_INCLUDE_DIR} \
|
||||
-I${TMP_DIR}
|
||||
LDFLAGS = @LDFLAGS@ -pthread \
|
||||
|
@ -241,6 +236,7 @@ LDFLAGS = @LDFLAGS@ -pthread \
|
|||
${GTKMM_LIBS} \
|
||||
${LIBGLADEMM_LIBS} \
|
||||
${GSTREAMER_LIBS} \
|
||||
${GSTCONTROLLER_LIBS} \
|
||||
${TAGLIB_LIBS} \
|
||||
-L${USR_LIB_DIR} \
|
||||
-L${CORE_LIB_DIR} \
|
||||
|
@ -248,7 +244,6 @@ LDFLAGS = @LDFLAGS@ -pthread \
|
|||
-L${STORAGE_CLIENT_LIB_DIR} \
|
||||
-L${WIDGETS_LIB_DIR} \
|
||||
-L${SCHEDULER_CLIENT_LIB_DIR} \
|
||||
-L${GSTREAMER_ELEMENTS_LIB_DIR} \
|
||||
-L${PLAYLIST_EXECUTOR_LIB_DIR}
|
||||
|
||||
|
||||
|
@ -306,7 +301,6 @@ G_LIVESUPPORT_EXE_OBJS = ${TMP_DIR}/main.o
|
|||
FSDF = ${G_LIVESUPPORT_OBJS} \
|
||||
${TMP_DIR}/main.o
|
||||
G_LIVESUPPORT_EXE_LIBS = -l${PLAYLIST_EXECUTOR_LIB} \
|
||||
-l${GSTREAMER_ELEMENTS_LIB} \
|
||||
-l${AUTHENTICATION_LIB} \
|
||||
-l${STORAGE_CLIENT_LIB} \
|
||||
-l${WIDGETS_LIB} \
|
||||
|
@ -460,9 +454,6 @@ ${WIDGETS_LIB_FILE}:
|
|||
${SCHEDULER_CLIENT_LIB_FILE}:
|
||||
${MAKE} -C ${SCHEDULER_CLIENT_DIR}
|
||||
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}:
|
||||
${MAKE} -C ${GSTREAMER_ELEMENTS_DIR}
|
||||
|
||||
${PLAYLIST_EXECUTOR_LIB_FILE}:
|
||||
${MAKE} -C ${PLAYLIST_EXECUTOR_DIR}
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ LIBODBCXX_LIBS=@LIBODBCXX_LIBS@
|
|||
GSTREAMER_CFLAGS=@GSTREAMER_CFLAGS@
|
||||
GSTREAMER_LIBS=@GSTREAMER_LIBS@
|
||||
|
||||
GSTCONTROLLER_CFLAGS=@GSTCONTROLLER_CFLAGS@
|
||||
GSTCONTROLLER_LIBS=@GSTCONTROLLER_LIBS@
|
||||
|
||||
CURL_CFLAGS=@CURL_CFLAGS@
|
||||
CURL_LIBS=@CURL_LIBS@
|
||||
|
@ -159,13 +161,6 @@ STORAGE_CLIENT_LIB_FILE = ${STORAGE_CLIENT_LIB_DIR}/lib${STORAGE_CLIENT_LIB}.
|
|||
|
||||
STORAGE_SERVER_DIR = ${MODULES_DIR}/storageServer
|
||||
|
||||
GSTREAMER_ELEMENTS_DIR = ${MODULES_DIR}/gstreamerElements
|
||||
GSTREAMER_ELEMENTS_INCLUDE_DIR = ${GSTREAMER_ELEMENTS_DIR}/include
|
||||
GSTREAMER_ELEMENTS_LIB_DIR = ${GSTREAMER_ELEMENTS_DIR}/lib
|
||||
GSTREAMER_ELEMENTS_LIB = livesupport_gstreamerelements
|
||||
GSTREAMER_ELEMENTS_LIB_FILE = ${GSTREAMER_ELEMENTS_LIB_DIR}/lib${GSTREAMER_ELEMENTS_LIB}.a
|
||||
GST_REAL_LIB_DIR=${REAL_BASE_DIR}/modules/gstreamerElements/lib
|
||||
|
||||
PLAYLIST_EXECUTOR_DIR = ${MODULES_DIR}/playlistExecutor
|
||||
PLAYLIST_EXECUTOR_INCLUDE_DIR = ${PLAYLIST_EXECUTOR_DIR}/include
|
||||
PLAYLIST_EXECUTOR_LIB_DIR = ${PLAYLIST_EXECUTOR_DIR}/lib
|
||||
|
@ -192,7 +187,6 @@ TEST_RUNNER_SH = ${BIN_DIR}/run_tests.sh
|
|||
DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
|
||||
|
||||
export LD_LIBRARY_PATH:=${USR_LIB_DIR}:${LD_LIBRARY_PATH}
|
||||
export GST_PLUGIN_PATH=${GST_REAL_LIB_DIR}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
@ -205,6 +199,7 @@ CXXFLAGS = @CXXFLAGS@ @DEFS@ @COVERAGE_CXXFLAGS@ -pthread \
|
|||
${LIBXMLPP_CFLAGS} \
|
||||
${LIBODBCXX_CFLAGS} \
|
||||
${GSTREAMER_CFLAGS} \
|
||||
${GSTCONTROLLER_CFLAGS} \
|
||||
${TAGLIB_CFLAGS} \
|
||||
${LIBTAR_CFLAGS} \
|
||||
-I${USR_INCLUDE_DIR} \
|
||||
|
@ -212,7 +207,6 @@ CXXFLAGS = @CXXFLAGS@ @DEFS@ @COVERAGE_CXXFLAGS@ -pthread \
|
|||
-I${AUTHENTICATION_INCLUDE_DIR} \
|
||||
-I${DB_INCLUDE_DIR} \
|
||||
-I${STORAGE_CLIENT_INCLUDE_DIR} \
|
||||
-I${GSTREAMER_ELEMENTS_INCLUDE_DIR} \
|
||||
-I${PLAYLIST_EXECUTOR_INCLUDE_DIR} \
|
||||
-I${EVENT_SCHEDULER_INCLUDE_DIR} \
|
||||
-I${TMP_DIR}
|
||||
|
@ -221,6 +215,7 @@ LDFLAGS = @LDFLAGS@ -pthread \
|
|||
${LIBXMLPP_LIBS} \
|
||||
${LIBODBCXX_LIBS} \
|
||||
${GSTREAMER_LIBS} \
|
||||
${GSTCONTROLLER_LIBS} \
|
||||
${CURL_LIBS} \
|
||||
${ICU_LIBS} \
|
||||
${TAGLIB_LIBS} \
|
||||
|
@ -230,7 +225,6 @@ LDFLAGS = @LDFLAGS@ -pthread \
|
|||
-L${AUTHENTICATION_LIB_DIR} \
|
||||
-L${DB_LIB_DIR} \
|
||||
-L${STORAGE_CLIENT_LIB_DIR} \
|
||||
-L${GSTREAMER_ELEMENTS_LIB_DIR} \
|
||||
-L${PLAYLIST_EXECUTOR_LIB_DIR} \
|
||||
-L${EVENT_SCHEDULER_LIB_DIR}
|
||||
|
||||
|
@ -269,7 +263,6 @@ SCHEDULER_OBJS = ${TMP_DIR}/SignalDispatcher.o \
|
|||
SCHEDULER_EXE_OBJS = ${SCHEDULER_OBJS} \
|
||||
${TMP_DIR}/main.o
|
||||
SCHEDULER_EXE_LIBS = -l${EVENT_SCHEDULER_LIB} -l${PLAYLIST_EXECUTOR_LIB} \
|
||||
-l${GSTREAMER_ELEMENTS_LIB} \
|
||||
-l${STORAGE_CLIENT_LIB} -l${DB_LIB} \
|
||||
-l${AUTHENTICATION_LIB} \
|
||||
-l${CORE_LIB} \
|
||||
|
@ -480,9 +473,6 @@ ${DB_LIB_FILE}:
|
|||
${STORAGE_CLIENT_LIB_FILE}:
|
||||
${MAKE} -C ${STORAGE_CLIENT_DIR}
|
||||
|
||||
${GSTREAMER_ELEMENTS_LIB_FILE}:
|
||||
${MAKE} -C ${GSTREAMER_ELEMENTS_DIR}
|
||||
|
||||
${PLAYLIST_EXECUTOR_LIB_FILE}:
|
||||
${MAKE} -C ${PLAYLIST_EXECUTOR_DIR}
|
||||
|
||||
|
|
|
@ -104,6 +104,10 @@ PKG_CHECK_MODULES(GSTREAMER,[gstreamer-0.8 >= 0.8])
|
|||
AC_SUBST(GSTREAMER_CFLAGS)
|
||||
AC_SUBST(GSTREAMER_LIBS)
|
||||
|
||||
PKG_CHECK_MODULES(GSTCONTROLLER,[gstreamer-controller-0.10 >= 0.10])
|
||||
AC_SUBST(GSTCONTROLLER_CFLAGS)
|
||||
AC_SUBST(GSTCONTROLLER_LIBS)
|
||||
|
||||
AC_CHECK_CURL(7.12.3)
|
||||
AC_SUBST(CURL_CFLAGS)
|
||||
AC_SUBST(CURL_LIBS)
|
||||
|
|
|
@ -31,13 +31,13 @@
|
|||
# (based on the version in enlightenment's cvs)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
package="GstreamerElements"
|
||||
package="gstreamer"
|
||||
|
||||
# assume we're in $basedir/bin
|
||||
reldir=`dirname $0`/..
|
||||
basedir=`cd $reldir; pwd;`
|
||||
test -z "$basedir" && basedir=.
|
||||
usrdir=`cd $basedir/../../../usr; pwd;`
|
||||
usrdir=`cd $basedir/../../../../usr; pwd;`
|
||||
|
||||
bindir=$basedir/bin
|
||||
etcdir=$basedir/etc
|
||||
|
@ -81,14 +81,14 @@ aclocal_m4=${tmpdir}/aclocal.m4
|
|||
# as aclocal >= 1.8 is sooo unbelivably stupid that it will simply try to
|
||||
# look for configure.ac in the current directory, and include acinclude.m4
|
||||
# in aclocal.m4 it without a directory path in front
|
||||
ACLOCAL_FLAGS="-I ${tmpdir} --acdir=${tmpdir} --output=${aclocal_m4}"
|
||||
echo " aclocal $ACLOCAL_FLAGS"
|
||||
cp -f ${configure_ac} ${tmpdir}
|
||||
cp -f ${etcdir}/acinclude.m4 ${tmpdir}
|
||||
aclocal $ACLOCAL_FLAGS
|
||||
#ACLOCAL_FLAGS="-I ${tmpdir} --acdir=${tmpdir} --output=${aclocal_m4}"
|
||||
#echo " aclocal $ACLOCAL_FLAGS"
|
||||
#cp -f ${configure_ac} ${tmpdir}
|
||||
#cp -f ${etcdir}/acinclude.m4 ${tmpdir}
|
||||
#aclocal $ACLOCAL_FLAGS
|
||||
|
||||
echo " autoheader ${configure_ac}"
|
||||
autoheader ${configure_ac}
|
||||
#echo " autoheader ${configure_ac}"
|
||||
#autoheader ${configure_ac}
|
||||
|
||||
echo " autoconf -I ${tmpdir} -o ${configure} ${configure_ac}"
|
||||
autoconf -I ${tmpdir} -o ${configure} ${configure_ac}
|
|
@ -0,0 +1,323 @@
|
|||
#!/bin/bash
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2005-02-02.21
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=
|
||||
chgrpcmd=
|
||||
stripcmd=
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dstarg=
|
||||
no_target_directory=
|
||||
|
||||
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
-c (ignored)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test -n "$1"; do
|
||||
case $1 in
|
||||
-c) shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd=$stripprog
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t) dstarg=$2
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-T) no_target_directory=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
*) # When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
test -n "$dir_arg$dstarg" && break
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dstarg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dstarg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dstarg=$arg
|
||||
done
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$1"; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src ;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
src=
|
||||
|
||||
if test -d "$dst"; then
|
||||
mkdircmd=:
|
||||
chmodcmd=
|
||||
else
|
||||
mkdircmd=$mkdirprog
|
||||
fi
|
||||
else
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dstarg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dstarg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst ;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dstarg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst/`basename "$src"`
|
||||
fi
|
||||
fi
|
||||
|
||||
# This sed command emulates the dirname command.
|
||||
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if test ! -d "$dstdir"; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-$defaultIFS}"
|
||||
|
||||
oIFS=$IFS
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
shift
|
||||
IFS=$oIFS
|
||||
|
||||
pathcomp=
|
||||
|
||||
while test $# -ne 0 ; do
|
||||
pathcomp=$pathcomp$1
|
||||
shift
|
||||
if test ! -d "$pathcomp"; then
|
||||
$mkdirprog "$pathcomp"
|
||||
# mkdir can fail with a `File exist' error in case several
|
||||
# install-sh are creating the directory concurrently. This
|
||||
# is OK.
|
||||
test -d "$pathcomp" || exit
|
||||
fi
|
||||
pathcomp=$pathcomp/
|
||||
done
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
$doit $mkdircmd "$dst" \
|
||||
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||
|
||||
else
|
||||
dstfile=`basename "$dst"`
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
$doit $cpprog "$src" "$dsttmp" &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| {
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
if test -f "$dstdir/$dstfile"; then
|
||||
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||
|| {
|
||||
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
else
|
||||
:
|
||||
fi
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||
}
|
||||
}
|
||||
fi || { (exit 1); exit 1; }
|
||||
done
|
||||
|
||||
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||
{
|
||||
(exit 0); exit 0
|
||||
}
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
|
@ -0,0 +1,99 @@
|
|||
#!/bin/bash
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2004 Media Development Loan Fund
|
||||
#
|
||||
# This file is part of the Campcaster project.
|
||||
# http://campcaster.campware.org/
|
||||
# To report bugs, send an e-mail to bugs@campware.org
|
||||
#
|
||||
# Campcaster is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Campcaster 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Campcaster; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
#
|
||||
# Author : $Author$
|
||||
# Version : $Revision$
|
||||
# Location : $URL$
|
||||
#-------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Run this script to prepare gstreamer to be configured and compiled.
|
||||
# To read more about gstreamer, see http://gstreamer.freedesktop.org/
|
||||
#-------------------------------------------------------------------------------
|
||||
liboil=liboil-0.3.10
|
||||
gstreamer=gstreamer-0.10.15
|
||||
plugins_base=gst-plugins-base-0.10.15
|
||||
plugins_good=gst-plugins-good-0.10.5
|
||||
plugins_bad=gst-plugins-bad-0.10.5
|
||||
plugins_ugly=gst-plugins-ugly-0.10.6
|
||||
|
||||
reldir=`dirname $0`/..
|
||||
basedir=`cd ${reldir}; pwd;`
|
||||
bindir=${basedir}/bin
|
||||
etcdir=${basedir}/etc
|
||||
tmpdir=${basedir}/tmp
|
||||
|
||||
liboil_tar=${basedir}/src/${liboil}.tar.gz
|
||||
gstreamer_tar=${basedir}/src/${gstreamer}.tar.bz2
|
||||
plugins_base_tar=${basedir}/src/${plugins_base}.tar.bz2
|
||||
plugins_good_tar=${basedir}/src/${plugins_good}.tar.bz2
|
||||
plugins_bad_tar=${basedir}/src/${plugins_bad}.tar.bz2
|
||||
plugins_ugly_tar=${basedir}/src/${plugins_ugly}.tar.bz2
|
||||
|
||||
mkdir -p ${tmpdir}
|
||||
|
||||
# copy over install-sh, as AC_CONFIG_SUBDIRS will be looking for it
|
||||
cp -r $bindir/install-sh $tmpdir
|
||||
|
||||
cd ${tmpdir}
|
||||
if [ ! -d $liboil ]; then
|
||||
tar xfz ${liboil_tar}
|
||||
cd ${liboil}
|
||||
# patch here
|
||||
fi
|
||||
|
||||
cd ${tmpdir}
|
||||
if [ ! -d $gstreamer ]; then
|
||||
tar xfj ${gstreamer_tar}
|
||||
cd ${gstreamer}
|
||||
# patch here
|
||||
fi
|
||||
|
||||
cd ${tmpdir}
|
||||
if [ ! -d $plugins_base ]; then
|
||||
tar xfj ${plugins_base_tar}
|
||||
cd ${plugins_base}
|
||||
# patch here
|
||||
fi
|
||||
|
||||
cd ${tmpdir}
|
||||
if [ ! -d $plugins_good ]; then
|
||||
tar xfj ${plugins_good_tar}
|
||||
cd ${plugins_good}
|
||||
# patch here
|
||||
fi
|
||||
|
||||
cd ${tmpdir}
|
||||
if [ ! -d $plugins_bad ]; then
|
||||
tar xfj ${plugins_bad_tar}
|
||||
cd ${plugins_bad}
|
||||
# patch here
|
||||
fi
|
||||
|
||||
cd ${tmpdir}
|
||||
if [ ! -d $plugins_ugly ]; then
|
||||
tar xfj ${plugins_ugly_tar}
|
||||
cd ${plugins_ugly}
|
||||
# patch here
|
||||
fi
|
||||
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2004 Media Development Loan Fund
|
||||
#
|
||||
# This file is part of the Campcaster project.
|
||||
# http://campcaster.campware.org/
|
||||
# To report bugs, send an e-mail to bugs@campware.org
|
||||
#
|
||||
# Campcaster is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Campcaster 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Campcaster; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
#
|
||||
# Author : $Author$
|
||||
# Version : $Revision$
|
||||
# Location : $URL$
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# General command definitions
|
||||
#-------------------------------------------------------------------------------
|
||||
MKDIR = mkdir -p
|
||||
RM = rm -f
|
||||
RMDIR = rm -rf
|
||||
DOXYGEN = doxygen
|
||||
DOXYTAG = doxytag
|
||||
XSLTPROC = xsltproc
|
||||
ECHO = @echo
|
||||
FLAWFINDER = flawfinder
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Basic directory and file definitions
|
||||
#-------------------------------------------------------------------------------
|
||||
BASE_DIR = .
|
||||
BIN_DIR = ${BASE_DIR}/bin
|
||||
DOC_DIR = ${BASE_DIR}/doc
|
||||
DOXYGEN_DIR = ${DOC_DIR}/doxygen
|
||||
COVERAGE_DIR = ${DOC_DIR}/coverage
|
||||
ETC_DIR = ${BASE_DIR}/etc
|
||||
TMP_DIR = ${BASE_DIR}/tmp
|
||||
|
||||
LIBOIL_VERSION = liboil-0.3.10
|
||||
LIBOIL_DIR = ${TMP_DIR}/${LIBOIL_VERSION}
|
||||
GSTREAMER_VERSION = gstreamer-0.10.15
|
||||
GSTREAMER_DIR = ${TMP_DIR}/${GSTREAMER_VERSION}
|
||||
GST_PLUGINS_BASE_VERSION = gst-plugins-base-0.10.15
|
||||
GST_PLUGINS_BASE_DIR = ${TMP_DIR}/${GST_PLUGINS_BASE_VERSION}
|
||||
GST_PLUGINS_GOOD_VERSION = gst-plugins-good-0.10.5
|
||||
GST_PLUGINS_GOOD_DIR = ${TMP_DIR}/${GST_PLUGINS_GOOD_VERSION}
|
||||
GST_PLUGINS_BAD_VERSION = gst-plugins-bad-0.10.5
|
||||
GST_PLUGINS_BAD_DIR = ${TMP_DIR}/${GST_PLUGINS_BAD_VERSION}
|
||||
GST_PLUGINS_UGLY_VERSION = gst-plugins-ugly-0.10.6
|
||||
GST_PLUGINS_UGLY_DIR = ${TMP_DIR}/${GST_PLUGINS_UGLY_VERSION}
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
# libdir will look literally like ${exec_prefix}/lib
|
||||
# thus we need exec_prefix defined as well above
|
||||
libdir=@libdir@
|
||||
pkg_config_path=${libdir}/pkgconfig
|
||||
|
||||
|
||||
USR_DIR=${prefix}
|
||||
USR_BIN_DIR=${USR_DIR}/bin
|
||||
USR_LIB_DIR=${libdir}
|
||||
|
||||
export PATH:=${USR_BIN_DIR}:${PATH}
|
||||
export CPPFLAGS=-I${USR_DIR}/include
|
||||
export LDFLAGS=-L${USR_LIB_DIR}
|
||||
export LD_LIBRARY_PATH:=${USR_LIB_DIR}:${LD_LIBRARY_PATH}
|
||||
export PKG_CONFIG_PATH=${USR_LIB_DIR}/pkgconfig
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Targets
|
||||
#-------------------------------------------------------------------------------
|
||||
all: ${TMP_DIR}/all.stamp
|
||||
${TMP_DIR}/all.stamp:
|
||||
cd ${LIBOIL_DIR} && \
|
||||
./configure --prefix=${prefix} --with-pkg-config-path=${pkg_config_path}
|
||||
${MAKE} -C ${LIBOIL_DIR}
|
||||
${MAKE} -C ${LIBOIL_DIR} install
|
||||
cd ${GSTREAMER_DIR} && \
|
||||
./configure --prefix=${prefix} --with-pkg-config-path=${pkg_config_path}
|
||||
${MAKE} -C ${GSTREAMER_DIR}
|
||||
${MAKE} -C ${GSTREAMER_DIR} install
|
||||
cd ${GST_PLUGINS_BASE_DIR} && \
|
||||
./configure --prefix=${prefix} --with-pkg-config-path=${pkg_config_path}
|
||||
${MAKE} -C ${GST_PLUGINS_BASE_DIR}
|
||||
${MAKE} -C ${GST_PLUGINS_BASE_DIR} install
|
||||
cd ${GST_PLUGINS_GOOD_DIR} && \
|
||||
./configure --prefix=${prefix} --with-pkg-config-path=${pkg_config_path}
|
||||
${MAKE} -C ${GST_PLUGINS_GOOD_DIR}
|
||||
${MAKE} -C ${GST_PLUGINS_GOOD_DIR} install
|
||||
cd ${GST_PLUGINS_BAD_DIR} && \
|
||||
./configure --prefix=${prefix} --with-pkg-config-path=${pkg_config_path}
|
||||
${MAKE} -C ${GST_PLUGINS_BAD_DIR}
|
||||
${MAKE} -C ${GST_PLUGINS_BAD_DIR} install
|
||||
cd ${GST_PLUGINS_UGLY_DIR} && \
|
||||
./configure --prefix=${prefix} --with-pkg-config-path=${pkg_config_path}
|
||||
${MAKE} -C ${GST_PLUGINS_UGLY_DIR}
|
||||
${MAKE} -C ${GST_PLUGINS_UGLY_DIR} install
|
||||
|
||||
install: all
|
||||
|
||||
clean:
|
||||
${MAKE} -C ${LIBOIL_DIR} clean
|
||||
${MAKE} -C ${GSTREAMER_DIR} clean
|
||||
${MAKE} -C ${GST_PLUGINS_BASE_DIR} clean
|
||||
${MAKE} -C ${GST_PLUGINS_GOOD_DIR} clean
|
||||
${MAKE} -C ${GST_PLUGINS_BAD_DIR} clean
|
||||
${MAKE} -C ${GST_PLUGINS_UGLY_DIR} clean
|
||||
rm ${TMP_DIR}/all.stamp
|
||||
|
||||
distclean:
|
||||
${RMDIR} ${LIBOIL_DIR}
|
||||
${RMDIR} ${GSTREAMER_DIR}
|
||||
${RMDIR} ${GST_PLUGINS_BASE_DIR}
|
||||
${RMDIR} ${GST_PLUGINS_GOOD_DIR}
|
||||
${RMDIR} ${GST_PLUGINS_BAD_DIR}
|
||||
${RMDIR} ${GST_PLUGINS_UGLY_DIR}
|
||||
${RMDIR} ${TMP_DIR}/auto* ${TMP_DIR}/config* ${TMP_DIR}/install-sh
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
dnl-----------------------------------------------------------------------------
|
||||
dnl Copyright (c) 2004 Media Development Loan Fund
|
||||
dnl
|
||||
dnl This file is part of the Campcaster project.
|
||||
dnl http://campcaster.campware.org/
|
||||
dnl To report bugs, send an e-mail to bugs@campware.org
|
||||
dnl
|
||||
dnl Campcaster is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl Campcaster is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with Campcaster; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
dnl
|
||||
dnl
|
||||
dnl Author : $Author$
|
||||
dnl Version : $Revision$
|
||||
dnl Location : $URL$
|
||||
dnl-----------------------------------------------------------------------------
|
||||
|
||||
dnl-----------------------------------------------------------------------------
|
||||
dnl NOTE: Run all configure related scripts from the tmp directory of the
|
||||
dnl project.
|
||||
dnl This is due to the fact that configure spreads a lot of trash around,
|
||||
dnl like atom4te cache directories, config.* files, etc. into the directory
|
||||
dnl it is being run from. We clearly don't want these in our base directory.
|
||||
dnl-----------------------------------------------------------------------------
|
||||
AC_INIT(gstreamer, 0.10.15, bugs@campware.org)
|
||||
AC_PREREQ(2.59)
|
||||
AC_COPYRIGHT([Copyright (c) 2004 Media Development Loan Fund under the GNU GPL])
|
||||
AC_REVISION($Revision$)
|
||||
|
||||
AC_CONFIG_SRCDIR(../src/gstreamer-0.10.15.tar.bz2)
|
||||
|
||||
|
||||
dnl untar the sources before anything happens
|
||||
../bin/prepare.sh
|
||||
|
||||
|
||||
AC_CONFIG_FILES(../Makefile:../etc/Makefile.in)
|
||||
|
||||
AC_OUTPUT()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue