added sound level animation SMIL support

This commit is contained in:
maroy 2005-06-30 07:18:23 +00:00
parent 5ec6a76d74
commit f890fe79b8
10 changed files with 561 additions and 31 deletions

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ Author : $Author: maroy $
Version : $Revision: 1.5 $ Version : $Revision: 1.6 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/MinimalAudioSmilTest.cxx,v $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/MinimalAudioSmilTest.cxx,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -96,6 +96,29 @@ static const char * oggVorbisSmilFile = "var/simple-ogg.smil";
*/ */
static const char * embeddedSmilFile = "var/embedded.smil"; 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";
/* =============================================== local function prototypes */ /* =============================================== local function prototypes */
@ -282,3 +305,74 @@ MinimalAudioSmilTest :: embeddedTest(void)
CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.1 * GST_SECOND); CPPUNIT_ASSERT_MESSAGE(str, timePlayed < 5.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);
}

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ Author : $Author: maroy $
Version : $Revision: 1.5 $ Version : $Revision: 1.6 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/MinimalAudioSmilTest.h,v $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/MinimalAudioSmilTest.h,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -58,20 +58,22 @@ namespace GstreamerElements {
* Unit test for the partialplay gstreamer element. * Unit test for the partialplay gstreamer element.
* *
* @author $Author: maroy $ * @author $Author: maroy $
* @version $Revision: 1.5 $ * @version $Revision: 1.6 $
*/ */
class MinimalAudioSmilTest : public CPPUNIT_NS::TestFixture class MinimalAudioSmilTest : public CPPUNIT_NS::TestFixture
{ {
CPPUNIT_TEST_SUITE(MinimalAudioSmilTest); CPPUNIT_TEST_SUITE(MinimalAudioSmilTest);
#if 0
CPPUNIT_TEST(firstTest); CPPUNIT_TEST(firstTest);
CPPUNIT_TEST(simpleClipBeginTest); CPPUNIT_TEST(simpleClipBeginTest);
CPPUNIT_TEST(simpleClipBeginEndTest); CPPUNIT_TEST(simpleClipBeginEndTest);
CPPUNIT_TEST(parallelTest); CPPUNIT_TEST(parallelTest);
CPPUNIT_TEST(parallelClipBeginEndTest); CPPUNIT_TEST(parallelClipBeginEndTest);
#endif
CPPUNIT_TEST(oggVorbisTest); CPPUNIT_TEST(oggVorbisTest);
CPPUNIT_TEST(embeddedTest); CPPUNIT_TEST(embeddedTest);
CPPUNIT_TEST(soundAnimationTest);
CPPUNIT_TEST(soundAnimationParallelTest);
CPPUNIT_TEST(fadeInOutTest);
CPPUNIT_TEST(fadeInOutParallelTest);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -147,6 +149,39 @@ class MinimalAudioSmilTest : public CPPUNIT_NS::TestFixture
void void
embeddedTest(void) throw (CPPUNIT_NS::Exception); 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);
public: public:

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ Author : $Author: maroy $
Version : $Revision: 1.4 $ Version : $Revision: 1.5 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/minimal-audio-smil.c,v $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/minimal-audio-smil.c,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -45,6 +45,7 @@
#include <libxml/parser.h> #include <libxml/parser.h>
#include <libxml/tree.h> #include <libxml/tree.h>
#include "smil-util.h"
#include "minimal-audio-smil.h" #include "minimal-audio-smil.h"
@ -90,6 +91,9 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE (
/* ================================================ local constants & macros */ /* ================================================ local constants & macros */
#define NSEC_PER_SEC_FLOAT 1000000000.0
#define UNREF_IF_NOT_NULL(gst_object) \ #define UNREF_IF_NOT_NULL(gst_object) \
{ \ { \
if ((gst_object)) { \ if ((gst_object)) { \
@ -110,7 +114,7 @@ GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
"minimalaudiosmil", "minimalaudiosmil",
"Minimal Audio-only SMIL", "Minimal Audio-only SMIL",
plugin_init, plugin_init,
"$Revision: 1.4 $", "$Revision: 1.5 $",
"GPL", "GPL",
"LiveSupport", "LiveSupport",
"http://livesupport.campware.org/") "http://livesupport.campware.org/")
@ -142,19 +146,61 @@ static xmlNode *
get_body_element(xmlDocPtr document); get_body_element(xmlDocPtr document);
/** /**
* Handle an "<audio>" SMIL element. * Handle an "<animate>" element.
* *
* @param smil a MinimalAudioSmil object. * @param smil a MinimalAudioSmil object.
* @param bin the container to put all the generated elements in.
* @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.
* @param namePrefix name prefix to use for generated gstreamer element
* names
* @param index the index of the "<animate>" element with respect to it's
* containing element.
* @return a gstreamer element, that if linked after the containing SMIL
* element, performs the animation described by the "<animate>"
* SMIL element
*/
static GstElement *
handle_animate_element(LivesupportMinimalAudioSmil * smil,
GstBin * bin,
gint64 offset,
xmlNode * animate,
const gchar * namePrefix,
int index);
/**
* Signal handler for the eos event of a gstreamer element.
* The handler will set the gstreamer element pointed to by userData
* to eos as well.
*
* @param element the element emitting the eos signal
* @param userData pointer to a gstreamer element to put into eos state.
*/
static void
element_eos_signal_handler(GstElement * element,
gpointer userData);
/**
* Handle an "<audio>" SMIL element.
* A series of elements will be generated, all linked and added to the
* supplied bin container. The last element in the series will be returned,
* that can be linked further to produce the desired output.
*
* @param smil a MinimalAudioSmil object.
* @param bin the container to put all the generated elements in.
* @param audio an "<audio>" SMIL element. * @param audio an "<audio>" SMIL element.
* @param index the index of the "<audio>" element with respect to it's * @param index the index of the "<audio>" element with respect to it's
* containing element. * containing element.
* @return a gstreamer element that will play audio as described by the * @return a gstreamer element that will play audio as described by the
* "<audio>" SMIL element. the element will be named using the * "<audio>" SMIL element. the element will be named using the
* supplied index, thus is will be uniquely named with respect * supplied indexes, thus is will be uniquely named with respect
* to it's parent. * to it's parent.
*/ */
static GstElement * static GstElement *
handle_audio_element(LivesupportMinimalAudioSmil * smil, handle_audio_element(LivesupportMinimalAudioSmil * smil,
GstBin * bin,
xmlNode * audio, xmlNode * audio,
int index); int index);
@ -281,11 +327,169 @@ get_body_element(xmlDocPtr document)
} }
/*------------------------------------------------------------------------------
* Handle an "<animate>" SMIL element, which is supposedly inside
* an "<audio>" element
*----------------------------------------------------------------------------*/
static GstElement *
handle_animate_element(LivesupportMinimalAudioSmil * smil,
GstBin * bin,
gint64 offset,
xmlNode * animate,
const gchar * namePrefix,
int index)
{
GstElement * volenv;
xmlAttribute * attr;
double from = 0.0;
double to = 0.0;
double begin = 0.0;
double end = 0.0;
const gchar * cstr;
gchar * str;
guint len;
/* 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(attr->name, "attributeName")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
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(attr->name, "calcMode")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
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(attr->name, "fill")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
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(attr->name, "from")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
cstr = (gchar*) node->content;
if (!smil_parse_percent(cstr, &from)) {
GST_WARNING("bad from value: %s", cstr);
return 0;
}
}
} else if (!strcmp(attr->name, "to")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
cstr = (gchar*) node->content;
if (!smil_parse_percent(cstr, &to)) {
GST_WARNING("bad to value: %s", cstr);
return 0;
}
}
} else if (!strcmp(attr->name, "begin")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
gint64 i;
cstr = (gchar*) node->content;
i = smil_clock_value_to_nanosec(cstr) + offset;
begin = ((double) i) / NSEC_PER_SEC_FLOAT;
}
} else if (!strcmp(attr->name, "end")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
gint64 i;
cstr = (gchar*) node->content;
i = 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;
}
/* now create a volenv element */
len = strlen(namePrefix) + strlen("_volenv_XXXXXXXXXX") + 1;
str = g_malloc(len);
g_snprintf(str, len, "%s_volenv_%d", namePrefix, index);
if (!(volenv = gst_element_factory_make("volenv", str))) {
GST_WARNING("can't create a required gstreamer element");
g_free(str);
return 0;
}
g_free(str);
/* insert the control points */
str = g_malloc(64);
/* insert an initial volume level at 0.0 */
if (begin <= 0.0) {
g_snprintf(str, 64, "0.0:%lf", from);
g_object_set(G_OBJECT(volenv), "controlpoint", str, NULL);
g_snprintf(str, 64, "0.01:%lf", from);
g_object_set(G_OBJECT(volenv), "controlpoint", str, NULL);
} else {
g_object_set(G_OBJECT(volenv), "controlpoint", "0.0:1.0", NULL);
g_snprintf(str, 64, "%lf:%lf", begin, from);
g_object_set(G_OBJECT(volenv), "controlpoint", str, NULL);
}
g_snprintf(str, 64, "%lf:%lf", end, to);
g_object_set(G_OBJECT(volenv), "controlpoint", str, NULL);
g_free(str);
return volenv;
}
/*------------------------------------------------------------------------------
* eos signal handler for the partial play element
*----------------------------------------------------------------------------*/
static void
element_eos_signal_handler(GstElement * element,
gpointer userData)
{
GstElement * elem= GST_ELEMENT(userData);
g_return_if_fail(elem!= NULL);
g_return_if_fail(GST_IS_ELEMENT(elem));
/* set the element into eos state */
GST_INFO("setting element %p to eos", elem);
gst_element_set_eos(elem);
}
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Handle an "<audio>" SMIL element. * Handle an "<audio>" SMIL element.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
static GstElement * static GstElement *
handle_audio_element(LivesupportMinimalAudioSmil * smil, handle_audio_element(LivesupportMinimalAudioSmil * smil,
GstBin * bin,
xmlNode * audio, xmlNode * audio,
int index) int index)
{ {
@ -294,10 +498,16 @@ handle_audio_element(LivesupportMinimalAudioSmil * smil,
gchar * begin = 0; gchar * begin = 0;
gchar * clipBegin = 0; gchar * clipBegin = 0;
gchar * clipEnd = 0; gchar * clipEnd = 0;
gint64 nsBegin;
gchar * name;
gchar * str; gchar * str;
guint len; guint len;
GstElement * pplay; GstElement * pplay;
GstElement * element;
xmlNode * node;
int ix;
/* handle the attributes */
for (attr = ((xmlElement*)audio)->attributes; for (attr = ((xmlElement*)audio)->attributes;
attr; attr;
attr = (xmlAttribute*) attr->next) { attr = (xmlAttribute*) attr->next) {
@ -336,6 +546,7 @@ handle_audio_element(LivesupportMinimalAudioSmil * smil,
if (!begin) { if (!begin) {
begin = "0s"; begin = "0s";
} }
nsBegin = smil_clock_value_to_nanosec(begin);
if (!clipBegin) { if (!clipBegin) {
clipBegin = "0s"; clipBegin = "0s";
} }
@ -350,14 +561,13 @@ handle_audio_element(LivesupportMinimalAudioSmil * smil,
/* now create a partial play element */ /* now create a partial play element */
len = strlen("partialplay_XXXXXXXXXX") + 1; len = strlen("partialplay_XXXXXXXXXX") + 1;
str = g_malloc(len); name = g_malloc(len);
g_snprintf(str, len, "partialplay_%d", index); g_snprintf(name, len, "partialplay_%d", index);
if (!(pplay = gst_element_factory_make("partialplay", str))) { if (!(pplay = gst_element_factory_make("partialplay", name))) {
GST_WARNING("can't create a required gstreamer element"); GST_WARNING("can't create a required gstreamer element");
g_free(str); g_free(name);
return 0; return 0;
} }
g_free(str);
g_object_set(G_OBJECT(pplay), "location", src, NULL); g_object_set(G_OBJECT(pplay), "location", src, NULL);
len = strlen(begin) len = strlen(begin)
@ -370,7 +580,45 @@ handle_audio_element(LivesupportMinimalAudioSmil * smil,
g_object_set(G_OBJECT(pplay), "config", str, NULL); g_object_set(G_OBJECT(pplay), "config", str, NULL);
g_free(str); g_free(str);
return pplay; gst_bin_add(bin, pplay);
/* now handle the possible animate elements inside this audio element */
element = pplay;
for (ix = 0, node = audio->children; node; node = node->next, ++ix) {
if (node->type == XML_ELEMENT_NODE) {
GstElement * elem = 0;
if (!strcmp(node->name, "animate")) {
elem = handle_animate_element(smil, bin, nsBegin,
node, name, ix);
} else {
GST_WARNING("unsupported SMIL element %s found inside a audio",
node->name);
}
if (elem) {
gst_element_link(element, elem);
gst_bin_add(bin, elem);
/* FIXME: this is an ugly workaround.
* for some reason, the EOS event does not get
* propagated to the volenv elements from the
* partial play element. so we catch the EOS
* event from each element, and set the next in
* line to EOS explicitly */
g_signal_connect(element,
"eos",
G_CALLBACK(element_eos_signal_handler),
elem);
element = elem;
}
}
}
g_free(name);
return element;
} }
@ -408,7 +656,10 @@ handle_par_element(LivesupportMinimalAudioSmil * smil,
GstElement * element = 0; GstElement * element = 0;
if (!strcmp(node->name, "audio")) { if (!strcmp(node->name, "audio")) {
element = handle_audio_element(smil, node, index); element = handle_audio_element(smil,
GST_BIN(pipeline),
node,
index);
} else { } else {
GST_WARNING("unsupported SMIL element %s found inside a par", GST_WARNING("unsupported SMIL element %s found inside a par",
node->name); node->name);
@ -418,7 +669,6 @@ handle_par_element(LivesupportMinimalAudioSmil * smil,
if (!gst_element_link(element, adder)) { if (!gst_element_link(element, adder)) {
GST_WARNING("can't link par child to adder"); GST_WARNING("can't link par child to adder");
} }
gst_bin_add(GST_BIN(pipeline), element);
} }
} }
} }

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ Author : $Author: maroy $
Version : $Revision: 1.1 $ Version : $Revision: 1.2 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/smil-util.c,v $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/smil-util.c,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -152,3 +152,22 @@ smil_clock_value_to_nanosec(const gchar * value)
return -1LL; 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;
}

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ Author : $Author: maroy $
Version : $Revision: 1.1 $ Version : $Revision: 1.2 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/smil-util.h,v $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/smil-util.h,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -34,7 +34,7 @@
* Utility functions helping to work with SMIL-related data structures. * Utility functions helping to work with SMIL-related data structures.
* *
* @author $Author: maroy $ * @author $Author: maroy $
* @version $Revision: 1.1 $ * @version $Revision: 1.2 $
*/ */
@ -84,5 +84,18 @@ gint64
smil_clock_value_to_nanosec(const gchar * value); 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 */ #endif /* SmilUtil_h */

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ Author : $Author: maroy $
Version : $Revision: 1.8 $ Version : $Revision: 1.9 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/switcher.c,v $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/gstreamerElements/src/switcher.c,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -64,7 +64,7 @@ GST_PLUGIN_DEFINE (
"switcher", "switcher",
"A filter that connects to a swtich, and changes its source", "A filter that connects to a swtich, and changes its source",
plugin_init, plugin_init,
"$Revision: 1.8 $", "$Revision: 1.9 $",
"GPL", "GPL",
"LiveSupport", "LiveSupport",
"http://livesupport.campware.org/" "http://livesupport.campware.org/"
@ -418,6 +418,8 @@ switch_to_next_source(LivesupportSwitcher * switcher)
: switcher->elapsedTime + newConfig->duration; : switcher->elapsedTime + newConfig->duration;
} else { } else {
/* mark EOS, as there are no more sources to switch to */ /* 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; switcher->eos = TRUE;
} }
} }
@ -442,7 +444,7 @@ livesupport_switcher_loop(GstElement * element)
if (switcher->eos) { if (switcher->eos) {
GstEvent * event; GstEvent * event;
GST_DEBUG("switcher_loop: eos"); GST_INFO("switcher_loop: eos");
/* push an EOS event down the srcpad, just to make sure */ /* push an EOS event down the srcpad, just to make sure */
event = gst_event_new(GST_EVENT_EOS); event = gst_event_new(GST_EVENT_EOS);
gst_pad_send_event(switcher->srcpad, event); gst_pad_send_event(switcher->srcpad, event);

View file

@ -0,0 +1,16 @@
<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>

View file

@ -0,0 +1,27 @@
<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>

View file

@ -0,0 +1,26 @@
<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>

View file

@ -0,0 +1,48 @@
<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>