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

Reply via email to