2006-11-09 (木) の 12:12 +0900 に Hiroyuki Ikezoe さんは書きました:
> 2006-11-09 (木) の 11:51 +0900 に Hiroyuki Ikezoe さんは書きました:
> > So, I have an idea for avoinding this adder issue. The idea is that
> > creating multiple pipeline instead of using adder. I modified the sample
> > code that you posted at GNOME bugzilla to use multiple pipeline, it
> > seems to work fine. I attach the modified somple code.
> >
> > I am not sure whether creating multiple pipeline causes some side effect
> > or not, but I will try to apply the way to Gnash.
>
> Just a quick report.
>
> Creating multiple pipeline was effective against gangsta_rap_se.swf,
> even though sounds are not syncronized. (I guess "unsynchronized" is
> another issue.)
>
> I am going to send a patch before the end of the day.
I attach the patch in this mail.
Thank you,
Hiroyuki Ikezoe
Index: backend/sound_handler_gst.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_gst.cpp,v
retrieving revision 1.29
diff -d -u -p -r1.29 sound_handler_gst.cpp
--- backend/sound_handler_gst.cpp 8 Nov 2006 21:57:04 -0000 1.29
+++ backend/sound_handler_gst.cpp 9 Nov 2006 03:26:27 -0000
@@ -45,6 +45,12 @@
// Used to hold the gstreamer when doing on-demand-decoding
typedef struct
{
+ // gstreamer pipeline objects
+
+ // the main bin containing the adder and output (sink)
+ GstElement *pipeline;
+ GstElement *audiosink;
+
// gstreamer objects
GstElement *input;
GstElement *decoder;
@@ -53,7 +59,6 @@ typedef struct
GstElement *audioresample;
GstElement *volume;
GstElement *bin;
- GstPad *addersinkpad;
// position in the stream
long position;
@@ -106,20 +111,9 @@ typedef struct
class GST_sound_handler : public gnash::sound_handler
{
public:
- // gstreamer pipeline objects
-
- // the main bin containing the adder and output (sink)
- GstElement *pipeline;
-
- GstElement *adder;
- GstElement *audiosink;
-
// Sound data.
std::vector<sound_data*> m_sound_data;
- // Keeps track of numbers of playing sounds
- int soundsPlaying;
-
// Is the loop running?
bool looping;
@@ -127,48 +121,11 @@ public:
bool muted;
GST_sound_handler()
- : soundsPlaying(0),
- looping(false),
+ : looping(false),
muted(false)
{
// init gstreamer
gst_init(NULL, NULL);
-
- // create main pipeline
- pipeline = gst_pipeline_new (NULL);
-
- // create adder
- adder = gst_element_factory_make ("adder", NULL);
-
- // create an audio sink - use oss, alsa or...? make a commandline option?
- // we first try atudetect, then alsa, then oss, then esd, then...?
- audiosink = gst_element_factory_make ("autoaudiosink", NULL);
- if (!audiosink) audiosink = gst_element_factory_make ("alsasink", NULL);
- if (!audiosink) audiosink = gst_element_factory_make ("osssink", NULL);
- if (!audiosink) audiosink = gst_element_factory_make ("esdsink", NULL);
-
- // Check if the creation of the gstreamer pipeline, adder and audiosink was a succes
- if (!pipeline) {
- gnash::log_error("The gstreamer pipeline element could not be created\n");
- }
- if (!adder) {
- gnash::log_error("The gstreamer adder element could not be created\n");
- }
- if (!audiosink) {
- gnash::log_error("The gstreamer audiosink element could not be created\n");
- }
-
- // link adder and output to bin
- gst_bin_add (GST_BIN (pipeline), adder);
- gst_bin_add (GST_BIN (pipeline), audiosink);
-
- // link adder and audiosink
- GstPad *srcpad = gst_element_get_pad (adder, "src");
- GstPad *sinkpad = gst_element_get_pad (audiosink, "sink");
- gst_pad_link (srcpad, sinkpad);
- gst_object_unref (GST_OBJECT (srcpad));
- gst_object_unref (GST_OBJECT (sinkpad));
-
}
~GST_sound_handler()
@@ -178,9 +135,6 @@ public:
stop_sound(i);
delete_sound(i);
}
-
- gst_object_unref (GST_OBJECT (pipeline));
-
}
@@ -409,6 +363,27 @@ public:
// Set number of loop we should do. -1 is infinte loop, 0 plays it once, 1 twice etc.
gst_element->loop_count = loop_count;
+ // create main pipeline
+ gst_element->pipeline = gst_pipeline_new (NULL);
+
+ // create an audio sink - use oss, alsa or...? make a commandline option?
+ // we first try atudetect, then alsa, then oss, then esd, then...?
+ gst_element->audiosink = gst_element_factory_make ("autoaudiosink", NULL);
+ if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("alsasink", NULL);
+ if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("osssink", NULL);
+ if (!gst_element->audiosink) gst_element->audiosink = gst_element_factory_make ("esdsink", NULL);
+
+ // Check if the creation of the gstreamer pipeline, adder and audiosink was a succes
+ if (!gst_element->pipeline) {
+ gnash::log_error("The gstreamer pipeline element could not be created\n");
+ }
+ if (!gst_element->audiosink) {
+ gnash::log_error("The gstreamer audiosink element could not be created\n");
+ }
+
+ // link adder and output to bin
+ gst_bin_add (GST_BIN (gst_element->pipeline), gst_element->audiosink);
+
gst_element->bin = gst_bin_new(NULL);
gst_element->input = gst_element_factory_make ("fakesrc", NULL);
gst_element->capsfilter = gst_element_factory_make ("capsfilter", NULL);
@@ -527,13 +502,14 @@ public:
gst_object_unref (GST_OBJECT (pad));
// Add the bin to the main pipeline
- gst_bin_add(GST_BIN (pipeline), gst_element->bin);
+ gst_bin_add(GST_BIN (gst_element->pipeline), gst_element->bin);
// Link to the adder sink pad
- gst_element->addersinkpad = gst_element_get_request_pad (adder, "sink%d");
+ GstPad *sinkpad = gst_element_get_pad (gst_element->audiosink, "sink");
GstPad *srcpad = gst_element_get_pad (gst_element->bin, "src");
- gst_pad_link (srcpad, gst_element->addersinkpad);
+ gst_pad_link (srcpad, sinkpad);
gst_object_unref (GST_OBJECT (srcpad));
-
+ gst_object_unref (GST_OBJECT (sinkpad));
+
// Set the volume
g_object_set (G_OBJECT (gst_element->volume), "volume", static_cast<double>(m_sound_data[sound_handle]->volume) / 100.0, NULL);
@@ -543,9 +519,8 @@ public:
m_sound_data[sound_handle]->m_gst_elements.push_back(gst_element);
// If not already playing, start doing it
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+ gst_element_set_state (GST_ELEMENT (gst_element->pipeline), GST_STATE_PLAYING);
- ++soundsPlaying;
}
@@ -561,10 +536,6 @@ public:
sound_data* sounddata = m_sound_data[sound_handle];
- // This variable is used to asure that we don't try to pause
- // if nothing is playing, which would mess things up
- bool stopped = false;
-
// Stop all the instances of this sound.
// TODO: fix the loop to use size_t instead of i
for (int i = sounddata->m_gst_elements.size()-1; i >= 0 ; i--)
@@ -578,33 +549,15 @@ public:
// Disconnect signals
g_signal_handler_disconnect (elements->input, elements->handoff_signal_id);
- // FIXME: This stops ALL sounds, not just the current.
- if (gst_element_set_state (GST_ELEMENT (elements->bin), GST_STATE_NULL) != 1) continue;
-
- // Unlink the pad which is linked the adder sink pad.
- GstPad *srcpad = gst_element_get_pad (elements->bin, "src");
- gst_pad_unlink (srcpad, elements->addersinkpad);
- gst_element_release_request_pad (adder, elements->addersinkpad);
- gst_object_unref (GST_OBJECT (srcpad));
-
- // Unref/delete the elements
- gst_bin_remove (GST_BIN (pipeline), elements->bin);
+ gst_element_set_state (GST_ELEMENT (elements->pipeline), GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (elements->pipeline));
// Delete the gst_element struct
// @@ we're deleting the elements from the start, so half-way of the loop we will be referring to undefined elements. Is this intended ? --strk;
delete elements;
sounddata->m_gst_elements.erase(sounddata->m_gst_elements.begin() + i);
- --soundsPlaying;
- stopped = true;
}
-
-
- // If no sounds, set pipeline to paused. Else the pipeline thinks it's still playing,
- // and will fastforward through new sounds until it reach the "correct posistion".
- if (soundsPlaying == 0 && stopped) {
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
- }
-
+
}
_______________________________________________
Gnash-dev mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/gnash-dev