[Swfdec-commits] 19 commits - autogen.sh configure.ac doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt swfdec-gtk/swfdec_gtk_widget.c swfdec-gtk/swfdec_playback_alsa.c swfdec-gtk/swfdec_playback_pulse.c swfdec/Makefile.am swfdec/swfdec_audio.c swfdec/swfdec_audio_event.c swfdec/swfdec_audio_event.h swfdec/swfdec_audio_flv.c swfdec/swfdec_audio.h swfdec/swfdec_audio_internal.h swfdec/swfdec_audio_stream.c swfdec/swfdec_codec_adpcm.c swfdec/swfdec_codec_audio.c swfdec/swfdec_codec_audio.h swfdec/swfdec_codec_ffmpeg.c swfdec/swfdec_codec_gst.c swfdec/swfdec_codec_mad.c swfdec/swfdec_codec_video.c swfdec/swfdec_internal.h swfdec/swfdec_player.c swfdec/swfdec_player.h swfdec/swfdec_player_internal.h swfdec/swfdec_renderer.c swfdec/swfdec_script.c swfdec/swfdec_sound.c swfdec/swfdec_sound.h swfdec/swfdec_text_field_movie_as.c swfdec/swfdec_text_field_movie.c swfdec/swfdec_text_field_movie.h tools/swfdec-extract.c vivified/code

Benjamin Otte company at kemper.freedesktop.org
Sat May 24 10:44:14 PDT 2008


 autogen.sh                             |    2 
 configure.ac                           |   49 ----
 doc/Makefile.am                        |   11 +
 doc/swfdec-docs.sgml                   |    1 
 doc/swfdec-sections.txt                |   37 +++
 swfdec-gtk/swfdec_gtk_widget.c         |    7 
 swfdec-gtk/swfdec_playback_alsa.c      |    3 
 swfdec-gtk/swfdec_playback_pulse.c     |    1 
 swfdec/Makefile.am                     |    6 
 swfdec/swfdec_audio.c                  |   51 +----
 swfdec/swfdec_audio.h                  |    2 
 swfdec/swfdec_audio_event.c            |   64 ++----
 swfdec/swfdec_audio_event.h            |    1 
 swfdec/swfdec_audio_flv.c              |   25 +-
 swfdec/swfdec_audio_internal.h         |    2 
 swfdec/swfdec_audio_stream.c           |   32 +--
 swfdec/swfdec_codec_adpcm.c            |   33 ++-
 swfdec/swfdec_codec_audio.c            |   73 ++++---
 swfdec/swfdec_codec_audio.h            |    2 
 swfdec/swfdec_codec_ffmpeg.c           |  331 ---------------------------------
 swfdec/swfdec_codec_gst.c              |   30 --
 swfdec/swfdec_codec_mad.c              |  238 -----------------------
 swfdec/swfdec_codec_video.c            |    3 
 swfdec/swfdec_internal.h               |   19 -
 swfdec/swfdec_player.c                 |   55 +++++
 swfdec/swfdec_player.h                 |    5 
 swfdec/swfdec_player_internal.h        |    1 
 swfdec/swfdec_renderer.c               |   33 +++
 swfdec/swfdec_script.c                 |    9 
 swfdec/swfdec_sound.c                  |  113 -----------
 swfdec/swfdec_sound.h                  |   12 -
 swfdec/swfdec_text_field_movie.c       |  153 ++++++---------
 swfdec/swfdec_text_field_movie.h       |    9 
 swfdec/swfdec_text_field_movie_as.c    |    8 
 tools/swfdec-extract.c                 |   32 +--
 vivified/code/vivi_code_asm_get_url2.c |    1 
 36 files changed, 389 insertions(+), 1065 deletions(-)

New commits:
commit b8e6bbd7f440138929b3e486f8b1613d55f293a3
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 19:40:48 2008 +0200

    update docs build to include new symbols
    
    and of course ignore non-public ones

diff --git a/doc/Makefile.am b/doc/Makefile.am
index 1c54ba9..d6c7498 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -50,6 +50,7 @@ CFILE_GLOB=$(top_srcdir)/swfdec/*.c $(top_srcdir)/swfdec-gtk/*.c
 IGNORE_HFILES= \
 	js \
 	jpeg \
+	swfdec_actor.h \
 	swfdec_amf.h \
 	swfdec_as_boolean.h \
 	swfdec_as_date.h \
@@ -71,15 +72,19 @@ IGNORE_HFILES= \
 	swfdec_audio_flv.h \
 	swfdec_audio_stream.h \
 	swfdec_bits.h \
+	swfdec_bots.h \
 	swfdec_button.h \
 	swfdec_button_movie.h \
 	swfdec_cache.h \
 	swfdec_cached.h \
+	swfdec_cached_image.h \
+	swfdec_cached_video.h \
 	swfdec_character.h \
 	swfdec_codec_audio.h \
 	swfdec_codec_video.h \
 	swfdec_color.h \
 	swfdec_color_as.h \
+	swfdec_constant_pool.h \
 	swfdec_debug.h \
 	swfdec_debugger.h \
 	swfdec_decoder.h \
@@ -116,6 +121,7 @@ IGNORE_HFILES= \
 	swfdec_player_internal.h \
 	swfdec_policy_file.h \
 	swfdec_rect.h \
+	swfdec_renderer_internal.h \
 	swfdec_resource.h \
 	swfdec_resource_request.h \
 	swfdec_ringbuffer.h \
@@ -134,11 +140,16 @@ IGNORE_HFILES= \
 	swfdec_swf_decoder.h \
 	swfdec_tag.h \
 	swfdec_text.h \
+	swfdec_text_attributes.h \
+	swfdec_text_buffer.h \
+	swfdec_text_layout.h \
 	swfdec_text_format.h \
 	swfdec_types.h \
 	swfdec_utils.h \
 	swfdec_video.h \
 	swfdec_video_movie.h \
+	swfdec_video_provider.h \
+	swfdec_video_video_provider.h \
 	swfdec_xml.h \
 	swfdec_xml_node.h \
 	swfdec_xml_socket.h
diff --git a/doc/swfdec-docs.sgml b/doc/swfdec-docs.sgml
index 04f9744..c3bdbeb 100644
--- a/doc/swfdec-docs.sgml
+++ b/doc/swfdec-docs.sgml
@@ -25,6 +25,7 @@
   <chapter>
     <title>extending SwfdecPlayer</title>
     <xi:include href="xml/SwfdecPlayerScripting.xml"/>
+    <xi:include href="xml/SwfdecRenderer.xml"/>
     <xi:include href="xml/SwfdecStream.xml"/>
     <xi:include href="xml/SwfdecLoader.xml"/>
     <xi:include href="xml/SwfdecSocket.xml"/>
diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index 67bb023..4ca26f7 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -99,6 +99,25 @@ swfdec_player_scripting_get_type
 </SECTION>
 
 <SECTION>
+<FILE>SwfdecRenderer</FILE>
+<TITLE>SwfdecRenderer</TITLE>
+SwfdecRenderer
+SwfdecRendererClass
+swfdec_renderer_new
+swfdec_renderer_new_for_player
+swfdec_renderer_get_surface
+<SUBSECTION Standard>
+SWFDEC_IS_RENDERER
+SWFDEC_IS_RENDERER_CLASS
+SWFDEC_RENDERER
+SWFDEC_RENDERER_CLASS
+SWFDEC_RENDERER_GET_CLASS
+SWFDEC_TYPE_RENDERER
+SwfdecRendererPrivate
+swfdec_renderer_get_type
+</SECTION>
+
+<SECTION>
 <FILE>SwfdecURL</FILE>
 <TITLE>SwfdecURL</TITLE>
 SwfdecURL
@@ -119,8 +138,9 @@ swfdec_url_get_url
 swfdec_url_is_local
 swfdec_url_is_parent
 swfdec_url_format_for_display
-swfdec_url_equal
 swfdec_url_hash
+swfdec_url_equal
+swfdec_url_host_equal
 swfdec_url_path_is_relative
 <SUBSECTION Standard>
 SWFDEC_TYPE_URL
@@ -146,21 +166,28 @@ swfdec_player_get_size
 swfdec_player_set_size
 swfdec_player_get_next_event
 swfdec_player_get_background_color
-swfdec_player_set_background_color
 swfdec_player_get_scale_mode
 swfdec_player_set_scale_mode
 swfdec_player_get_alignment
 swfdec_player_set_alignment
 swfdec_player_get_scripting
 swfdec_player_set_scripting
+swfdec_player_get_allow_fullscreen
+swfdec_player_set_allow_fullscreen
+swfdec_player_get_fullscreen
+swfdec_player_get_renderer
+swfdec_player_set_renderer
 swfdec_player_render
+swfdec_player_render_with_renderer
 swfdec_player_advance
 swfdec_player_mouse_move
 swfdec_player_mouse_press
 swfdec_player_mouse_release
 swfdec_player_key_press
 swfdec_player_key_release
-swfdec_player_render_audio
+swfdec_player_get_focus
+swfdec_player_set_focus
+swfdec_player_get_selection
 swfdec_player_get_audio
 swfdec_player_get_maximum_runtime
 swfdec_player_set_maximum_runtime
@@ -264,6 +291,8 @@ swfdec_rectangle_get_type
 <TITLE>SwfdecGtkPlayer</TITLE>
 <INCLUDE>swfdec/swfdec-gtk.h</INCLUDE>
 SwfdecGtkPlayer
+SWFDEC_GTK_PRIORITY_ITERATE
+SWFDEC_GTK_PRIORITY_REDRAW
 swfdec_gtk_player_new
 swfdec_gtk_player_get_playing
 swfdec_gtk_player_set_playing
@@ -291,6 +320,7 @@ SWFDEC_TYPE_GTK_PLAYER
 <INCLUDE>swfdec/swfdec-gtk.h</INCLUDE>
 SwfdecGtkWidget
 swfdec_gtk_widget_new
+swfdec_gtk_widget_new_fullscreen
 swfdec_gtk_widget_get_player
 swfdec_gtk_widget_set_player
 swfdec_gtk_widget_get_interactive
@@ -547,6 +577,7 @@ SwfdecScript
 swfdec_script_new
 swfdec_script_ref
 swfdec_script_unref
+swfdec_script_get_version
 <SUBSECTION Standard>
 swfdec_as_debugger_get_type
 SWFDEC_AS_DEBUGGER
commit 740ec3925c4aaa309d79758058e1ba2fbcb944ad
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 19:40:29 2008 +0200

    document rest of the new API that was undocumented

diff --git a/swfdec/swfdec_renderer.c b/swfdec/swfdec_renderer.c
index 532511b..eb41e5c 100644
--- a/swfdec/swfdec_renderer.c
+++ b/swfdec/swfdec_renderer.c
@@ -57,6 +57,29 @@ struct _SwfdecRendererPrivate {
  * See #SwfdecRendererClass for details about these functions.
  */
 
+/**
+ * SwfdecRenderer:
+ *
+ * The base renderer object. All its members are private.
+ */
+
+/**
+ * SwfdecRendererClass:
+ * @create_similar: This function imitates cairo_surface_create_similar(). It
+ *                  is supposed to create a surface with identical contents as
+ *                  the given surface, but tuned for usage with the given 
+ *                  renderer.
+ * @create_for_data: This function imitates cairo_surface_create_for_data(). It
+ *                   creates a surface for the given data, tuned for the given 
+ *                   renderer. The function takes ownership of the passed in 
+ *                   data and is responsible for freeing it with g_free() when
+ *                   it no longer needs it.
+ *
+ * The base class for the renderer. It contains some virtual functions that can
+ * be overridden in subclasses to accelerate certain time-critical Swfdec 
+ * functions. For example, a subclass could make use of special hardware 
+ * features on embedded devices.
+ */
 
 /*** OBJECT ***/
 
@@ -371,6 +394,16 @@ swfdec_renderer_new (cairo_surface_t *surface)
   return g_object_new (SWFDEC_TYPE_RENDERER, "surface", surface, NULL);
 }
 
+/**
+ * swfdec_renderer_new_for_player:
+ * @surface: a cairo surface
+ * @player: the player this renderer should be used with
+ *
+ * Creates a renderer to be used with the given @surface and @player. The 
+ * renderer will use the same cache as the @player.
+ *
+ * Returns: a new renderer
+ **/
 SwfdecRenderer *
 swfdec_renderer_new_for_player (cairo_surface_t *surface, SwfdecPlayer *player)
 {
diff --git a/swfdec/swfdec_script.c b/swfdec/swfdec_script.c
index d7e9e38..11d28c8 100644
--- a/swfdec/swfdec_script.c
+++ b/swfdec/swfdec_script.c
@@ -227,6 +227,15 @@ swfdec_script_unref (SwfdecScript *script)
   g_free (script);
 }
 
+/**
+ * swfdec_script_get_version:
+ * @script: the script
+ *
+ * Queries the Flash version this script was compiled with. Different versions
+ * result in slightly different behavior in the script interpreter.
+ *
+ * Returns: The Flash version this script conforms to
+ **/
 guint
 swfdec_script_get_version (SwfdecScript *script)
 {
commit 4d479202966a34025e2d07543826a9d98c4b8a8b
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 19:39:03 2008 +0200

    remove swfdec_player_render_audio()
    
    It doesnt work with new swfdec_audio_render() semantics anyway

diff --git a/swfdec/swfdec_audio.c b/swfdec/swfdec_audio.c
index 62ae10f..238aa64 100644
--- a/swfdec/swfdec_audio.c
+++ b/swfdec/swfdec_audio.c
@@ -180,37 +180,6 @@ swfdec_audio_render (SwfdecAudio *audio, gint16 *dest,
   return klass->render (audio, dest, start_offset, n_samples);
 }
 
-/**
- * swfdec_player_render_audio:
- * @player: a #SwfdecPlayer
- * @dest: location to add audio signal to. The audio signal will be in 
- *        44100kHz signed 16bit stereo.
- * @start_offset: offset in samples at which to start rendering. The offset is 
- *		  calculated relative to the last iteration, so the value set 
- *		  by swfdec_player_set_audio_advance() is ignored.
- * @n_samples: amount of samples to render.
- *
- * Renders the data for this frame into the given location. The data is added to @dest, 
- * so you probably want to initialize @dest to silence before calling this function.
- **/
-void 
-swfdec_player_render_audio (SwfdecPlayer *player, gint16* dest, 
-    guint start_offset, guint n_samples)
-{
-  GList *walk;
-  SwfdecAudio *audio;
-
-  g_return_if_fail (SWFDEC_IS_PLAYER (player));
-  g_return_if_fail (dest != NULL);
-  g_return_if_fail (n_samples > 0);
-
-  SWFDEC_LOG ("rendering offset %u, samples %u", start_offset, n_samples);
-  for (walk = player->priv->audio; walk; walk = walk->next) {
-    audio = walk->data;
-    swfdec_audio_render (audio, dest, start_offset, n_samples);
-  }
-}
-
 /*** SWFDEC_AUDIO_FORMAT ***/
 
 /* SwfdecAudioFormat is represented in the least significant bits of a uint:
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index 080d387..35f9b4c 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -190,10 +190,6 @@ gboolean	swfdec_player_key_release	(SwfdecPlayer *	player,
 						 guint		keycode,
 						 guint		character);
 /* audio - see swfdec_audio.c */
-void		swfdec_player_render_audio	(SwfdecPlayer *	player,
-						 gint16 *	dest, 
-						 guint		start_offset,
-						 guint		n_samples);
 const GList *	swfdec_player_get_audio		(SwfdecPlayer *	player);
 
 G_END_DECLS
commit 29826bdc9642134eafb4930279d75f21575e31cf
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 19:37:58 2008 +0200

    fix to work with new API

diff --git a/tools/swfdec-extract.c b/tools/swfdec-extract.c
index ebcba2c..3af5cf0 100644
--- a/tools/swfdec-extract.c
+++ b/tools/swfdec-extract.c
@@ -44,7 +44,7 @@
 #include <swfdec/swfdec_resource.h>
 
 static SwfdecBuffer *
-encode_wav (SwfdecBuffer *buffer, SwfdecAudioFormat format)
+encode_wav (SwfdecBuffer *buffer)
 {
   SwfdecBuffer *wav = swfdec_buffer_new (buffer->length + 44);
   unsigned char *data;
@@ -55,25 +55,20 @@ encode_wav (SwfdecBuffer *buffer, SwfdecAudioFormat format)
   memmove (data, "RIFF----WAVEfmt \020\0\0\0"
 		 "\001\0ccRRRRbbbbAAbbdata", 40);
   *(guint32 *) (void *) &data[4] = GUINT32_TO_LE (buffer->length + 36);
-  *(guint16 *) (void *) &data[22] = GUINT16_TO_LE (swfdec_audio_format_get_channels (format));
-  *(guint32 *) (void *) &data[24] = GUINT32_TO_LE (swfdec_audio_format_get_rate (format));
+  /* rate */
+  *(guint16 *) (void *) &data[22] = GUINT16_TO_LE (44100);
+  /* channels */
+  *(guint32 *) (void *) &data[24] = GUINT32_TO_LE (2);
   /* bits per sample */
-  i = swfdec_audio_format_is_16bit (format) ? 2 : 1;
-  *(guint16 *) (void *) &data[34] = GUINT16_TO_LE (i * 8);
+  *(guint16 *) (void *) &data[34] = GUINT16_TO_LE (16);
   /* block align */
-  i *= swfdec_audio_format_get_channels (format);
-  *(guint16 *) (void *) &data[32] = GUINT16_TO_LE (i);
+  *(guint16 *) (void *) &data[32] = GUINT16_TO_LE (16 * 2);
   /* bytes per second */
-  i *= swfdec_audio_format_get_rate (format);
-  *(guint32 *) (void *) &data[28] = GUINT32_TO_LE (i);
+  *(guint32 *) (void *) &data[28] = GUINT32_TO_LE (16 * 2 * 44100);
   *(guint32 *) (void *) &data[40] = GUINT32_TO_LE (buffer->length);
   data += 44;
-  if (swfdec_audio_format_is_16bit (format)) {
-    for (i = 0; i < buffer->length; i += 2) {
-      *(gint16 *) (void *) (data + i) = GINT16_TO_LE (*(gint16* ) (void *) (buffer->data + i));
-    }
-  } else {
-    memcpy (data, buffer->data, buffer->length);
+  for (i = 0; i < buffer->length; i += 2) {
+    *(gint16 *) (void *) (data + i) = GINT16_TO_LE (*(gint16* ) (void *) (buffer->data + i));
   }
   return wav;
 }
@@ -83,15 +78,14 @@ export_sound (SwfdecSound *sound, const char *filename)
 {
   GError *error = NULL;
   SwfdecBuffer *wav, *buffer;
-  SwfdecAudioFormat format;
 
   /* try to render the sound, that should decode it. */
-  buffer = swfdec_sound_get_decoded (sound, &format);
+  buffer = swfdec_sound_get_decoded (sound);
   if (buffer == NULL) {
     g_printerr ("Couldn't decode sound. For extraction of streams extract the sprite.\n");
     return FALSE;
   }
-  wav = encode_wav (buffer, format);
+  wav = encode_wav (buffer);
   if (!g_file_set_contents (filename, (char *) wav->data, 
 	wav->length, &error)) {
     g_printerr ("Couldn't save sound to file \"%s\": %s\n", filename, error->message);
@@ -146,7 +140,7 @@ export_sprite_sound (SwfdecSprite *sprite, const char *filename)
   }
   buffer = swfdec_buffer_queue_pull (queue, depth);
   swfdec_buffer_queue_unref (queue);
-  wav = encode_wav (buffer, swfdec_audio_format_new (44100, 2, TRUE));
+  wav = encode_wav (buffer);
   swfdec_buffer_unref (buffer);
   if (!g_file_set_contents (filename, (char *) wav->data, 
 	wav->length, &error)) {
commit 860a5f283c5c8db5662ae8e9b7d1ae5889f35788
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 17:47:03 2008 +0200

    change semantics of swfdec_sound_render()
    
    data is now overwritten, not added

diff --git a/swfdec-gtk/swfdec_playback_alsa.c b/swfdec-gtk/swfdec_playback_alsa.c
index 9d1a8f7..5ecff13 100644
--- a/swfdec-gtk/swfdec_playback_alsa.c
+++ b/swfdec-gtk/swfdec_playback_alsa.c
@@ -84,7 +84,6 @@ write_player (Stream *stream, const snd_pcm_channel_area_t *dst,
   g_assert (dst[0].step == dst[1].step);
   g_assert (dst[0].step == 32);
 
-  memset ((guint8 *) dst[0].addr + offset * dst[0].step / 8, 0, avail * 4);
   swfdec_audio_render (stream->audio, (gint16 *) ((guint8 *) dst[0].addr + offset * dst[0].step / 8), 
       stream->offset, avail);
   //g_print ("rendering %u %u\n", stream->offset, (guint) avail);
@@ -128,7 +127,7 @@ try_write_so_pa_gets_it (Stream *stream)
   ALSA_ERROR (avail, "snd_pcm_avail_update failed", FALSE);
 
   while (avail > 0) {
-    gint16 data[2 * STEP] = { 0, };
+    gint16 data[2 * STEP];
 
     step = MIN (avail, STEP);
     swfdec_audio_render (stream->audio, data, stream->offset, step);
diff --git a/swfdec-gtk/swfdec_playback_pulse.c b/swfdec-gtk/swfdec_playback_pulse.c
index 55b05c2..5aa85f0 100644
--- a/swfdec-gtk/swfdec_playback_pulse.c
+++ b/swfdec-gtk/swfdec_playback_pulse.c
@@ -83,7 +83,6 @@ stream_write_callback (pa_stream *pa,
   /* Set up our fragment and render swfdec's audio into it. The swfdec audio
    * decoder renders deltas from the existing data in the fragment.
    */
-  memset (frag, 0, bytes);
   swfdec_audio_render (stream->audio, (gint16 *)frag, stream->offset,
 		       samples);
 
diff --git a/swfdec/swfdec_audio.c b/swfdec/swfdec_audio.c
index 69eadb0..62ae10f 100644
--- a/swfdec/swfdec_audio.c
+++ b/swfdec/swfdec_audio.c
@@ -158,9 +158,8 @@ swfdec_audio_iterate (SwfdecAudio *audio, guint n_samples)
  *		  by swfdec_player_set_audio_advance() is ignored.
  * @n_samples: amount of samples to render.
  *
- * Renders the samples from @audio into the area pointed to by @dest. The data 
- * is added to @dest, so you probably want to initialize @dest to silence 
- * before calling this function.
+ * Renders the samples from @audio into the area pointed to by @dest. Existing
+ * data in @dest is overwritten.
  *
  * Returns: The amount of samples actually rendered. Usually this number is 
  *          equal to @n_samples, but if you arrived at the end of stream or the
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index bcef85b..a40081b 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -436,18 +436,10 @@ void
 swfdec_sound_buffer_render (gint16 *dest, const SwfdecBuffer *source, 
     guint offset, guint n_samples)
 {
-  const gint16 *src;
-  guint i;
-
   g_return_if_fail (dest != NULL);
   g_return_if_fail (source != NULL);
   g_return_if_fail ((offset + n_samples) * 4 <= source->length);
 
-  src = (gint16 *) source->data;
-  src += 2 * offset;
-  n_samples *= 2;
-  for (i = 0; i < n_samples; i++) {
-    *dest++ += *src++;
-  }
+  memcpy (dest, source->data + 4 * offset, 4 * n_samples);
 }
 
commit 12bf79ead0e5ed07635714cb204edea024925318
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 17:36:47 2008 +0200

    make swfdec_sound_buffer_render not do format conversion anymore

diff --git a/swfdec/swfdec_audio_event.c b/swfdec/swfdec_audio_event.c
index 024fb1f..528a848 100644
--- a/swfdec/swfdec_audio_event.c
+++ b/swfdec/swfdec_audio_event.c
@@ -103,9 +103,7 @@ swfdec_audio_event_render (SwfdecAudio *audio, gint16* dest, guint start,
   offset %= event->n_samples;
   for (rendered = 0; loop < event->n_loops && rendered < n_samples; loop++) {
     samples = MIN (n_samples - rendered, event->n_samples - offset);
-    swfdec_sound_buffer_render (dest_end, event->decoded,
-	swfdec_audio_format_new (44100, 2, TRUE), loop == 0 ? NULL : event->decoded, offset,
-	samples);
+    swfdec_sound_buffer_render (dest_end, event->decoded, offset, samples);
     rendered += samples;
     dest_end += samples * 2;
     offset = 0;
diff --git a/swfdec/swfdec_audio_flv.c b/swfdec/swfdec_audio_flv.c
index d610d7a..2780185 100644
--- a/swfdec/swfdec_audio_flv.c
+++ b/swfdec/swfdec_audio_flv.c
@@ -119,13 +119,12 @@ swfdec_audio_flv_render (SwfdecAudio *audio, gint16* dest,
   SwfdecAudioFlv *flv = SWFDEC_AUDIO_FLV (audio);
   GList *walk;
   guint samples, rendered;
-  SwfdecBuffer *buffer, *previous;
+  SwfdecBuffer *buffer;
 
   g_assert (start < G_MAXINT);
   start += flv->playback_skip;
   SWFDEC_LOG ("flv %p rendering offset %u, samples %u", flv, start, n_samples);
   walk = g_queue_peek_head_link (flv->playback_queue);
-  previous = NULL;
   while (n_samples) {
     if (walk) {
       buffer = walk->data;
@@ -149,14 +148,11 @@ swfdec_audio_flv_render (SwfdecAudio *audio, gint16* dest,
       SWFDEC_LOG ("rendering %u samples", samples);
     }
     samples = MIN (samples, n_samples);
-    swfdec_sound_buffer_render (dest, buffer, 
-	swfdec_audio_format_new (44100, 2, TRUE), previous, start, 
-	samples);
+    swfdec_sound_buffer_render (dest, buffer, start, samples);
     start = 0;
     rendered += samples;
     n_samples -= samples;
     dest += 2 * samples;
-    previous = buffer;
   }
   return rendered;
 }
diff --git a/swfdec/swfdec_audio_stream.c b/swfdec/swfdec_audio_stream.c
index 1e550ba..ad7dd60 100644
--- a/swfdec/swfdec_audio_stream.c
+++ b/swfdec/swfdec_audio_stream.c
@@ -84,13 +84,12 @@ swfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,
   SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (audio);
   GList *walk;
   guint samples, rendered;
-  SwfdecBuffer *buffer, *previous;
+  SwfdecBuffer *buffer;
 
   g_assert (start < G_MAXINT);
   start += stream->playback_skip;
   SWFDEC_LOG ("stream %p rendering offset %u, samples %u", stream, start, n_samples);
   walk = g_queue_peek_head_link (stream->playback_queue);
-  previous = NULL;
   for (rendered = 0; rendered < n_samples;) {
     if (walk) {
       buffer = walk->data;
@@ -117,13 +116,10 @@ swfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,
       SWFDEC_LOG ("rendering %u samples", samples);
     }
     samples = MIN (samples, n_samples - rendered);
-    swfdec_sound_buffer_render (dest, buffer, 
-	swfdec_audio_format_new (44100, 2, TRUE),
-	previous, start, samples);
+    swfdec_sound_buffer_render (dest, buffer, start, samples);
     start = 0;
     rendered += samples;
     dest += 2 * samples;
-    previous = buffer;
   }
 
   return rendered;
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index 0989f8d..bcef85b 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -422,79 +422,10 @@ swfdec_sound_buffer_get_n_samples (const SwfdecBuffer *buffer, SwfdecAudioFormat
     swfdec_audio_format_get_granularity (format);
 }
 
-static void
-swfdec_sound_buffer_render_stereo (gint16 *dest, const gint16 *source, guint offset,
-    guint n_samples, guint rate)
-{
-  guint i, j;
-
-  source += 2 * (offset / rate);
-  offset %= rate;
-
-  if (offset) {
-    offset = MIN (rate - offset, n_samples);
-    for (i = 0; i < offset; i++) {
-      *dest++ = source[0];
-      *dest++ = source[1];
-    }
-    source += 2;
-    n_samples -= offset;
-  }
-  for (i = rate; i <= n_samples; i += rate) {
-    for (j = 0; j < rate; j++) {
-      *dest++ = source[0];
-      *dest++ = source[1];
-    }
-    source += 2;
-  }
-  n_samples -= i - rate;
-  g_assert (n_samples < rate);
-  for (i = 0; i < n_samples; i++) {
-    *dest++ = source[0];
-    *dest++ = source[1];
-  }
-}
-
-static void
-swfdec_sound_buffer_render_mono (gint16 *dest, const gint16 *source, guint offset,
-    guint n_samples, guint rate)
-{
-  guint i, j;
-
-  source += (offset / rate);
-  offset %= rate;
-
-  if (offset) {
-    offset = MIN (rate - offset, n_samples);
-    for (i = 0; i < offset; i++) {
-      *dest++ = *source;
-      *dest++ = *source;
-    }
-    source++;
-    n_samples -= offset;
-  }
-  for (i = rate; i <= n_samples; i += rate) {
-    for (j = 0; j < rate; j++) {
-      *dest++ = *source;
-      *dest++ = *source;
-    }
-    source++;
-  }
-  n_samples -= i - rate;
-  g_assert (n_samples < rate);
-  for (i = 0; i < n_samples; i++) {
-    *dest++ = *source;
-    *dest++ = *source;
-  }
-}
-
 /**
  * swfdec_sound_render_buffer:
  * @dest: target buffer to render to
  * @source: source data to render
- * @format: format of data in @source and @previous
- * @previous: previous buffer or NULL for none. This is necessary for
- *            upsampling at buffer boundaries
  * @offset: offset in 44100Hz samples into @source
  * @n_samples: number of samples to render into @dest. If more data would be
  *	       rendered than is available in @source, 0 samples are used instead.
@@ -503,40 +434,20 @@ swfdec_sound_buffer_render_mono (gint16 *dest, const gint16 *source, guint offse
  **/
 void
 swfdec_sound_buffer_render (gint16 *dest, const SwfdecBuffer *source, 
-    SwfdecAudioFormat format, const SwfdecBuffer *previous,
     guint offset, guint n_samples)
 {
-  guint channels = swfdec_audio_format_get_channels (format);
-  guint rate = swfdec_audio_format_get_granularity (format);
-  guint width = swfdec_audio_format_is_16bit (format) ? 2 : 1;
-  guint total_samples;
-  gint16 *fixme = NULL;
+  const gint16 *src;
+  guint i;
 
   g_return_if_fail (dest != NULL);
   g_return_if_fail (source != NULL);
-  g_return_if_fail (swfdec_sound_buffer_get_n_samples (source, format) > 0);
-  g_return_if_fail (previous == NULL || swfdec_sound_buffer_get_n_samples (previous, format) > 0);
-
-  total_samples = (source->length / channels / width) * rate;
-  SWFDEC_LOG ("rendering [%u %u) - total: %u samples", offset, n_samples, total_samples);
-  /* FIXME: warn about this? */
-  n_samples = MIN (n_samples, total_samples - offset);
-  
-  if (width == 1) {
-    guint i;
-    /* FIXME: make this faster */
-    fixme = g_try_malloc (source->length * 2);
-    if (fixme == NULL)
-      return;
-    for (i = 0; i < source->length; i++) {
-      fixme[i] = (((gint16) source->data[i]) << 8) - 32768;
-    }
-  }
-  if (channels == 2) {
-    swfdec_sound_buffer_render_stereo (dest, (const void *) source->data, offset, n_samples, rate);
-  } else {
-    swfdec_sound_buffer_render_mono (dest, (const void *) source->data, offset, n_samples, rate);
+  g_return_if_fail ((offset + n_samples) * 4 <= source->length);
+
+  src = (gint16 *) source->data;
+  src += 2 * offset;
+  n_samples *= 2;
+  for (i = 0; i < n_samples; i++) {
+    *dest++ += *src++;
   }
-  g_free (fixme);
 }
 
diff --git a/swfdec/swfdec_sound.h b/swfdec/swfdec_sound.h
index e4a1f7f..e7b202c 100644
--- a/swfdec/swfdec_sound.h
+++ b/swfdec/swfdec_sound.h
@@ -88,8 +88,6 @@ int tag_func_define_button_sound (SwfdecSwfDecoder * s, guint tag);
 SwfdecBuffer *		swfdec_sound_get_decoded	(SwfdecSound *		sound);
 void			swfdec_sound_buffer_render	(gint16 *		dest, 
 							 const SwfdecBuffer *	source, 
-							 SwfdecAudioFormat	format,
-							 const SwfdecBuffer *	previous, 
 							 guint	  		offset,
 							 guint			n_samples);
 guint			swfdec_sound_buffer_get_n_samples (const SwfdecBuffer * buffer, 
commit 94595d313f087849596521d6a4b9acd405571fbb
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 17:27:25 2008 +0200

    get rid of decoded_format in SwfdecSound and SwfdecAudioEvent
    
    It's 44100 stereo all the way

diff --git a/swfdec/swfdec_audio_event.c b/swfdec/swfdec_audio_event.c
index 349a148..024fb1f 100644
--- a/swfdec/swfdec_audio_event.c
+++ b/swfdec/swfdec_audio_event.c
@@ -84,21 +84,17 @@ swfdec_audio_event_render (SwfdecAudio *audio, gint16* dest, guint start,
 {
   SwfdecAudioEvent *event = SWFDEC_AUDIO_EVENT (audio);
   guint offset = event->offset + start;
-  guint loop, samples, global_offset, pos, i, channels, rendered;
+  guint loop, samples, global_offset, pos, i, rendered;
   gint16 *dest_end;
 
   if (event->n_samples == 0)
     return 0;
 
-  channels = swfdec_audio_format_get_channels (event->decoded_format);
-
   {
-    guint granularity =
-      swfdec_audio_format_get_granularity (event->decoded_format);
     guint loop_length = (event->stop_sample != 0 ? event->stop_sample :
 	event->n_samples) - event->start_sample;
 
-    global_offset = channels * granularity * (event->loop * loop_length +
+    global_offset = 2 * (event->loop * loop_length +
       event->offset - event->start_sample);
   }
 
@@ -108,7 +104,7 @@ swfdec_audio_event_render (SwfdecAudio *audio, gint16* dest, guint start,
   for (rendered = 0; loop < event->n_loops && rendered < n_samples; loop++) {
     samples = MIN (n_samples - rendered, event->n_samples - offset);
     swfdec_sound_buffer_render (dest_end, event->decoded,
-	event->decoded_format, loop == 0 ? NULL : event->decoded, offset,
+	swfdec_audio_format_new (44100, 2, TRUE), loop == 0 ? NULL : event->decoded, offset,
 	samples);
     rendered += samples;
     dest_end += samples * 2;
@@ -124,15 +120,8 @@ swfdec_audio_event_render (SwfdecAudio *audio, gint16* dest, guint start,
     while (pos < event->n_envelopes &&
 	event->envelope[pos].offset <= global_offset + (i / 2))
       pos++;
-    if (channels == 1) {
-      dest[i] *= (swfdec_audio_event_get_envelop_volume (event, pos,
-	  global_offset + (i / 2), 0) * 0.5 +
-	  swfdec_audio_event_get_envelop_volume (event, pos,
-	    global_offset + (i / 2), 1) * 0.5) / 32768.0;
-    } else {
-      dest[i] *= swfdec_audio_event_get_envelop_volume (event, pos,
-	  global_offset + (i / 2), i % 2) / 32768.0;
-    }
+    dest[i] *= swfdec_audio_event_get_envelop_volume (event, pos,
+	global_offset + (i / 2), i % 2) / 32768.0;
   }
   return rendered;
 }
@@ -173,10 +162,7 @@ swfdec_audio_event_init (SwfdecAudioEvent *audio_event)
 static void
 swfdec_audio_event_decode (SwfdecAudioEvent *event)
 {
-  guint granule, bytes_per_sample;
-
-  event->decoded = swfdec_sound_get_decoded (event->sound,
-      &event->decoded_format);
+  event->decoded = swfdec_sound_get_decoded (event->sound);
   if (event->decoded == NULL) {
     SWFDEC_INFO ("Could not decode audio.");
     event->n_samples = 0;
@@ -184,18 +170,13 @@ swfdec_audio_event_decode (SwfdecAudioEvent *event)
   } else {
     swfdec_buffer_ref (event->decoded);
   }
-  granule = swfdec_audio_format_get_granularity (event->decoded_format);
-  bytes_per_sample = swfdec_audio_format_get_channels (event->decoded_format) *
-      (swfdec_audio_format_is_16bit (event->decoded_format) ? 2 : 1);
+
   if (event->start_sample) {
     guint skip;
-    if (event->start_sample % granule) {
-      SWFDEC_FIXME ("figure out how high resolution start samples work");
-    }
-    skip = bytes_per_sample * (event->start_sample / granule);
+    skip = 4 * event->start_sample;
     if (skip >= event->decoded->length) {
       SWFDEC_WARNING ("start sample %u > total number of samples %"G_GSIZE_FORMAT,
-	  event->start_sample / granule, event->decoded->length / bytes_per_sample);
+	  event->start_sample, event->decoded->length / 4);
       swfdec_buffer_unref (event->decoded);
       event->decoded = swfdec_buffer_new (0);
     } else {
@@ -207,14 +188,11 @@ swfdec_audio_event_decode (SwfdecAudioEvent *event)
   }
   if (event->stop_sample) {
     guint keep;
-    if (event->stop_sample % granule) {
-      SWFDEC_FIXME ("figure out how high resolution stop samples work");
-    }
-    keep = bytes_per_sample * (event->stop_sample / granule - event->start_sample / granule);
+    keep = 4 * (event->stop_sample - event->start_sample);
     if (keep > event->decoded->length) {
       SWFDEC_WARNING ("stop sample %u outside of decoded number of samples %"G_GSIZE_FORMAT,
-	  event->stop_sample / granule, event->decoded->length / bytes_per_sample +
-	  event->start_sample / granule);
+	  event->stop_sample, event->decoded->length / 4 +
+	  event->start_sample);
     } else if (keep < event->decoded->length) {
       SwfdecBuffer *sub = swfdec_buffer_new_subbuffer (event->decoded,
 	  0, keep);
@@ -222,7 +200,7 @@ swfdec_audio_event_decode (SwfdecAudioEvent *event)
       event->decoded = sub;
     }
   }
-  event->n_samples = event->decoded->length / bytes_per_sample * granule;
+  event->n_samples = event->decoded->length / 4;
   SWFDEC_LOG ("total 44100Hz samples: %u", event->n_samples);
 }
 
diff --git a/swfdec/swfdec_audio_event.h b/swfdec/swfdec_audio_event.h
index ed59cb5..6f86692 100644
--- a/swfdec/swfdec_audio_event.h
+++ b/swfdec/swfdec_audio_event.h
@@ -50,7 +50,6 @@ struct _SwfdecAudioEvent
   SwfdecSoundEnvelope *	envelope;		/* volume envelope or NULL if none */
   /* dynamic data */
   SwfdecBuffer *	decoded;		/* the decoded buffer we play back or NULL if failure */
-  SwfdecAudioFormat	decoded_format;		/* format of the decoded buffer */
   guint			offset;			/* current offset in 44.1kHz */
   guint			loop;			/* current loop we're in */
   guint			n_samples;	      	/* length of decoded buffer in 44.1kHz samples - can be 0 */
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index 9ac600d..0989f8d 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -152,7 +152,7 @@ tag_func_define_sound (SwfdecSwfDecoder * s, guint tag)
 }
 
 SwfdecBuffer *
-swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
+swfdec_sound_get_decoded (SwfdecSound *sound)
 {
   gpointer decoder;
   SwfdecBuffer *tmp;
@@ -162,10 +162,8 @@ swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
   guint depth;
 
   g_return_val_if_fail (SWFDEC_IS_SOUND (sound), NULL);
-  g_return_val_if_fail (format != NULL, NULL);
 
   if (sound->decoded) {
-    *format = sound->decoded_format;
     return sound->decoded;
   }
   if (sound->encoded == NULL)
@@ -181,7 +179,6 @@ swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
   while ((tmp = swfdec_audio_decoder_pull (decoder))) {
     swfdec_buffer_queue_push (queue, tmp);
   }
-  sound->decoded_format = swfdec_audio_format_new (44100, 2, TRUE);
   swfdec_audio_decoder_free (decoder);
   depth = swfdec_buffer_queue_get_depth (queue);
   if (depth == 0) {
@@ -191,8 +188,8 @@ swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
   tmp = swfdec_buffer_queue_pull (queue, depth);
   swfdec_buffer_queue_unref (queue);
 
-  sample_bytes = swfdec_audio_format_get_bytes_per_sample (sound->decoded_format);
-  n_samples = sound->n_samples / swfdec_audio_format_get_granularity (sound->decoded_format);
+  sample_bytes = 4;
+  n_samples = sound->n_samples;
 
   SWFDEC_LOG ("after decoding, got %"G_GSIZE_FORMAT" samples, should get %u and skip %u", 
       tmp->length / sample_bytes, n_samples, sound->skip);
@@ -218,7 +215,6 @@ swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
   /* only assign here, the decoding code checks this variable */
   sound->decoded = tmp;
 
-  *format = sound->decoded_format;
   return sound->decoded;
 }
 
diff --git a/swfdec/swfdec_sound.h b/swfdec/swfdec_sound.h
index 4d63b6e..e4a1f7f 100644
--- a/swfdec/swfdec_sound.h
+++ b/swfdec/swfdec_sound.h
@@ -69,7 +69,6 @@ struct _SwfdecSound
   guint			skip;			/* samples to skip at start */
   SwfdecBuffer *	encoded;		/* encoded data */
 
-  SwfdecAudioFormat	decoded_format;		/* format of decoded data */
   SwfdecBuffer *	decoded;		/* decoded data */
 };
 
@@ -86,16 +85,15 @@ int tag_func_sound_stream_head (SwfdecSwfDecoder * s, guint tag);
 int tag_func_start_sound (SwfdecSwfDecoder * s, guint tag);
 int tag_func_define_button_sound (SwfdecSwfDecoder * s, guint tag);
 
-SwfdecBuffer *		swfdec_sound_get_decoded	(SwfdecSound *		sound,
-							 SwfdecAudioFormat *	format);
+SwfdecBuffer *		swfdec_sound_get_decoded	(SwfdecSound *		sound);
 void			swfdec_sound_buffer_render	(gint16 *		dest, 
 							 const SwfdecBuffer *	source, 
-							 SwfdecAudioFormat		format,
+							 SwfdecAudioFormat	format,
 							 const SwfdecBuffer *	previous, 
-							 guint		offset,
-							 guint		n_samples);
+							 guint	  		offset,
+							 guint			n_samples);
 guint			swfdec_sound_buffer_get_n_samples (const SwfdecBuffer * buffer, 
-                                                         SwfdecAudioFormat		format);
+                                                         SwfdecAudioFormat	format);
 
 SwfdecSoundChunk *	swfdec_sound_parse_chunk	(SwfdecSwfDecoder *	s,
 							 SwfdecBits *		bits,
commit 244a3ea2b08ea5687205fa542fd063374bbe3d6b
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 17:17:14 2008 +0200

    remove format member in SwfdecAudioDecoder
    
    It's now guaranteed to be 44.1kHz stereo

diff --git a/swfdec/swfdec_audio_flv.c b/swfdec/swfdec_audio_flv.c
index c5ce351..d610d7a 100644
--- a/swfdec/swfdec_audio_flv.c
+++ b/swfdec/swfdec_audio_flv.c
@@ -136,7 +136,7 @@ swfdec_audio_flv_render (SwfdecAudio *audio, gint16* dest,
 	break;
     }
     samples = swfdec_sound_buffer_get_n_samples (buffer, 
-	swfdec_audio_decoder_get_format (flv->decoder));
+	swfdec_audio_format_new (44100, 2, TRUE));
     if (start) {
       if (samples <= start) {
 	start -= samples;
@@ -150,7 +150,7 @@ swfdec_audio_flv_render (SwfdecAudio *audio, gint16* dest,
     }
     samples = MIN (samples, n_samples);
     swfdec_sound_buffer_render (dest, buffer, 
-	swfdec_audio_decoder_get_format (flv->decoder), previous, start, 
+	swfdec_audio_format_new (44100, 2, TRUE), previous, start, 
 	samples);
     start = 0;
     rendered += samples;
@@ -171,14 +171,13 @@ swfdec_audio_flv_iterate (SwfdecAudio *audio, guint remove)
   flv->playback_skip += remove;
   buffer = g_queue_peek_head (flv->playback_queue);
   while (buffer && flv->playback_skip >= 
-	 swfdec_sound_buffer_get_n_samples (buffer, swfdec_audio_decoder_get_format (flv->decoder)) 
-	 + swfdec_audio_format_get_granularity (swfdec_audio_decoder_get_format (flv->decoder))) {
+	 swfdec_sound_buffer_get_n_samples (buffer, swfdec_audio_format_new (44100, 2, TRUE))
+	 + swfdec_audio_format_get_granularity (swfdec_audio_format_new (44100, 2, TRUE))) {
     buffer = g_queue_pop_head (flv->playback_queue);
     SWFDEC_LOG ("removing buffer with %u samples", 
-	swfdec_sound_buffer_get_n_samples (buffer, 
-	  swfdec_audio_decoder_get_format (flv->decoder)));
+	swfdec_sound_buffer_get_n_samples (buffer, swfdec_audio_format_new (44100, 2, TRUE))); 
     flv->playback_skip -= swfdec_sound_buffer_get_n_samples (buffer, 
-	swfdec_audio_decoder_get_format (flv->decoder));
+	swfdec_audio_format_new (44100, 2, TRUE));
     swfdec_buffer_unref (buffer);
     buffer = g_queue_peek_head (flv->playback_queue);
   }
diff --git a/swfdec/swfdec_audio_stream.c b/swfdec/swfdec_audio_stream.c
index 5ce2843..1e550ba 100644
--- a/swfdec/swfdec_audio_stream.c
+++ b/swfdec/swfdec_audio_stream.c
@@ -104,7 +104,7 @@ swfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,
       g_queue_push_tail (stream->playback_queue, buffer);
     }
     samples = swfdec_sound_buffer_get_n_samples (buffer, 
-	swfdec_audio_decoder_get_format (stream->decoder));
+	swfdec_audio_format_new (44100, 2, TRUE));
     if (start) {
       if (samples <= start) {
 	start -= samples;
@@ -118,7 +118,7 @@ swfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,
     }
     samples = MIN (samples, n_samples - rendered);
     swfdec_sound_buffer_render (dest, buffer, 
-	swfdec_audio_decoder_get_format (stream->decoder), 
+	swfdec_audio_format_new (44100, 2, TRUE),
 	previous, start, samples);
     start = 0;
     rendered += samples;
@@ -138,14 +138,14 @@ swfdec_audio_stream_iterate (SwfdecAudio *audio, guint remove)
   stream->playback_skip += remove;
   buffer = g_queue_peek_head (stream->playback_queue);
   while (buffer && stream->playback_skip >= 
-	 swfdec_sound_buffer_get_n_samples (buffer, swfdec_audio_decoder_get_format (stream->decoder)) 
-	 + swfdec_audio_format_get_granularity (swfdec_audio_decoder_get_format (stream->decoder))) {
+	 swfdec_sound_buffer_get_n_samples (buffer, swfdec_audio_format_new (44100, 2, TRUE))
+	 + swfdec_audio_format_get_granularity (swfdec_audio_format_new (44100, 2, TRUE))) {
     buffer = g_queue_pop_head (stream->playback_queue);
     SWFDEC_LOG ("removing buffer with %u samples", 
 	swfdec_sound_buffer_get_n_samples (buffer, 
-	  swfdec_audio_decoder_get_format (stream->decoder)));
+	  swfdec_audio_format_new (44100, 2, TRUE)));
     stream->playback_skip -= swfdec_sound_buffer_get_n_samples (buffer, 
-	swfdec_audio_decoder_get_format (stream->decoder));
+	swfdec_audio_format_new (44100, 2, TRUE));
     swfdec_buffer_unref (buffer);
     buffer = g_queue_peek_head (stream->playback_queue);
   }
@@ -155,7 +155,7 @@ swfdec_audio_stream_iterate (SwfdecAudio *audio, guint remove)
   } else {
     GList *walk;
     guint ret = 0;
-    SwfdecAudioFormat format = swfdec_audio_decoder_get_format (stream->decoder);
+    SwfdecAudioFormat format = swfdec_audio_format_new (44100, 2, TRUE);
     
     for (walk = g_queue_peek_head_link (stream->playback_queue); walk; walk = walk->next) {
       ret += swfdec_sound_buffer_get_n_samples (walk->data, format);
diff --git a/swfdec/swfdec_codec_adpcm.c b/swfdec/swfdec_codec_adpcm.c
index 4bd4076..bdd14f8 100644
--- a/swfdec/swfdec_codec_adpcm.c
+++ b/swfdec/swfdec_codec_adpcm.c
@@ -193,7 +193,6 @@ swfdec_audio_decoder_adpcm_new (guint type, SwfdecAudioFormat format)
     return NULL;
   adpcm = g_slice_new (SwfdecAudioDecoderAdpcm);
   adpcm->format = format;
-  adpcm->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
   adpcm->decoder.push = swfdec_audio_decoder_adpcm_push;
   adpcm->decoder.pull = swfdec_audio_decoder_adpcm_pull;
   adpcm->decoder.free = swfdec_audio_decoder_adpcm_free;
diff --git a/swfdec/swfdec_codec_audio.c b/swfdec/swfdec_codec_audio.c
index a93901d..e4d7b3b 100644
--- a/swfdec/swfdec_codec_audio.c
+++ b/swfdec/swfdec_codec_audio.c
@@ -135,7 +135,6 @@ swfdec_audio_decoder_uncompressed_new (guint type, SwfdecAudioFormat format)
     SWFDEC_WARNING ("endianness of audio unknown, assuming little endian");
   }
   dec = g_new (SwfdecAudioDecoderUncompressed, 1);
-  dec->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
   if (swfdec_audio_format_is_16bit (format))
     dec->decoder.push = swfdec_audio_decoder_uncompressed_decode_16bit;
   else
@@ -259,25 +258,6 @@ swfdec_audio_decoder_free (SwfdecAudioDecoder *decoder)
 }
 
 /**
- * swfdec_audio_decoder_get_format:
- * @decoder: a #SwfdecAudioDecoder
- *
- * Queries the format that is used by the decoder for its produced output.
- * The format will only be valid after swfdec_audio_decoder_pull () has been
- * called at least once.
- *
- * Returns: the format of the decoded data
- **/
-SwfdecAudioFormat
-swfdec_audio_decoder_get_format	(SwfdecAudioDecoder *decoder)
-{
-  g_return_val_if_fail (decoder != NULL, 0);
-  g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (decoder->format), 0);
-
-  return decoder->format;
-}
-
-/**
  * swfdec_audio_decoder_push:
  * @decoder: a #SwfdecAudioDecoder
  * @buffer: a #SwfdecBuffer to process or %NULL to flush
@@ -325,7 +305,6 @@ swfdec_audio_decoder_pull (SwfdecAudioDecoder *decoder)
   ret = decoder->pull (decoder);
   if (ret == NULL)
     return NULL;
-  g_return_val_if_fail (SWFDEC_IS_AUDIO_FORMAT (decoder->format), ret);
   return ret;
 }
 
diff --git a/swfdec/swfdec_codec_audio.h b/swfdec/swfdec_codec_audio.h
index d3fb74d..be32bf4 100644
--- a/swfdec/swfdec_codec_audio.h
+++ b/swfdec/swfdec_codec_audio.h
@@ -37,7 +37,6 @@ typedef SwfdecAudioDecoder * (SwfdecAudioDecoderNewFunc) (guint type, gboolean w
     SwfdecAudioFormat format);
 struct _SwfdecAudioDecoder {
   guint			codec;
-  SwfdecAudioFormat	format;
   void			(* push)	(SwfdecAudioDecoder *	decoder,
 					 SwfdecBuffer *		buffer);
   SwfdecBuffer *	(* pull)	(SwfdecAudioDecoder *	decoder);
@@ -50,7 +49,6 @@ gboolean		swfdec_audio_decoder_prepare	(guint			codec,
 SwfdecAudioDecoder *   	swfdec_audio_decoder_new      	(guint			codec,
 							 SwfdecAudioFormat	format);
 void			swfdec_audio_decoder_free      	(SwfdecAudioDecoder *	decoder);
-SwfdecAudioFormat	swfdec_audio_decoder_get_format	(SwfdecAudioDecoder *	decoder);
 void			swfdec_audio_decoder_push	(SwfdecAudioDecoder *	decoder,
 							 SwfdecBuffer *		buffer);
 SwfdecBuffer *		swfdec_audio_decoder_pull	(SwfdecAudioDecoder *	decoder);
diff --git a/swfdec/swfdec_codec_gst.c b/swfdec/swfdec_codec_gst.c
index 883561d..f48dfd7 100644
--- a/swfdec/swfdec_codec_gst.c
+++ b/swfdec/swfdec_codec_gst.c
@@ -430,7 +430,6 @@ swfdec_audio_decoder_gst_new (guint type, SwfdecAudioFormat format)
     return NULL;
 
   player = g_slice_new0 (SwfdecGstAudio);
-  player->decoder.format = SWFDEC_AUDIO_FORMAT_INVALID;
   player->decoder.pull = swfdec_audio_decoder_gst_pull;
   player->decoder.push = swfdec_audio_decoder_gst_push;
   player->decoder.free = swfdec_audio_decoder_gst_free;
@@ -458,7 +457,6 @@ swfdec_audio_decoder_gst_new (guint type, SwfdecAudioFormat format)
 
   gst_caps_unref (srccaps);
   gst_caps_unref (sinkcaps);
-  player->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
   return &player->decoder;
 
 error:
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index 4a46030..9ac600d 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -181,7 +181,7 @@ swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
   while ((tmp = swfdec_audio_decoder_pull (decoder))) {
     swfdec_buffer_queue_push (queue, tmp);
   }
-  sound->decoded_format = swfdec_audio_decoder_get_format (decoder);
+  sound->decoded_format = swfdec_audio_format_new (44100, 2, TRUE);
   swfdec_audio_decoder_free (decoder);
   depth = swfdec_buffer_queue_get_depth (queue);
   if (depth == 0) {
commit 00189c583417008e7d43c836a09d69ab94d19263
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 17:08:06 2008 +0200

    make uncompressed audio always convert to 44.1kHz stereo

diff --git a/swfdec/swfdec_codec_audio.c b/swfdec/swfdec_codec_audio.c
index c018881..a93901d 100644
--- a/swfdec/swfdec_codec_audio.c
+++ b/swfdec/swfdec_codec_audio.c
@@ -29,10 +29,36 @@
 
 typedef struct {
   SwfdecAudioDecoder	decoder;
+  SwfdecAudioFormat	format;
   SwfdecBufferQueue *	queue;		/* queue collecting output buffers */
 } SwfdecAudioDecoderUncompressed;
 
 static void
+swfdec_audio_decoder_uncompressed_upscale (SwfdecAudioDecoder *decoder, 
+    SwfdecBuffer *buffer)
+{
+  SwfdecAudioDecoderUncompressed *unc = (SwfdecAudioDecoderUncompressed *) decoder;
+  guint channels = swfdec_audio_format_get_channels (unc->format);
+  guint granularity = swfdec_audio_format_get_granularity (unc->format);
+  SwfdecBuffer *ret;
+  guint i, j;
+  gint16 *src, *dest;
+
+  ret = swfdec_buffer_new (buffer->length * 2 / channels * granularity);
+  src = (gint16 *) buffer->data;
+  dest = (gint16 *) ret->data;
+  for (i = 0; i < buffer->length / 2; i++) {
+    for (j = 0; j < granularity; j++) {
+      *dest++ = src[0];
+      *dest++ = src[channels - 1];
+    }
+    src += channels;
+  }
+
+  swfdec_buffer_queue_push (unc->queue, ret);
+}
+
+static void
 swfdec_audio_decoder_uncompressed_decode_8bit (SwfdecAudioDecoder *decoder, 
     SwfdecBuffer *buffer)
 {
@@ -52,18 +78,32 @@ swfdec_audio_decoder_uncompressed_decode_8bit (SwfdecAudioDecoder *decoder,
     out++;
     in++;
   }
-  swfdec_buffer_queue_push (((SwfdecAudioDecoderUncompressed *) decoder)->queue, ret);
+  swfdec_audio_decoder_uncompressed_upscale (decoder, ret);
+  swfdec_buffer_unref (ret);
 }
 
 static void
 swfdec_audio_decoder_uncompressed_decode_16bit (SwfdecAudioDecoder *decoder, 
     SwfdecBuffer *buffer)
 {
+  SwfdecBuffer *tmp;
+  gint16 *src, *dest;
+  guint i;
+
   if (buffer == NULL)
     return;
 
-  swfdec_buffer_ref (buffer);
-  swfdec_buffer_queue_push (((SwfdecAudioDecoderUncompressed *) decoder)->queue, buffer);
+  tmp = swfdec_buffer_new (buffer->length);
+  src = (gint16 *) buffer->data;
+  dest = (gint16 *) tmp->data;
+  for (i = 0; i < buffer->length; i += 2) {
+    *dest = GINT16_FROM_LE (*src);
+    dest++;
+    src++;
+  }
+
+  swfdec_audio_decoder_uncompressed_upscale (decoder, tmp);
+  swfdec_buffer_unref (tmp);
 }
 
 static SwfdecBuffer *
@@ -95,7 +135,7 @@ swfdec_audio_decoder_uncompressed_new (guint type, SwfdecAudioFormat format)
     SWFDEC_WARNING ("endianness of audio unknown, assuming little endian");
   }
   dec = g_new (SwfdecAudioDecoderUncompressed, 1);
-  dec->decoder.format = format;
+  dec->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
   if (swfdec_audio_format_is_16bit (format))
     dec->decoder.push = swfdec_audio_decoder_uncompressed_decode_16bit;
   else
commit f846c10689eaa292a43e245cfb7b26841c732132
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 14:02:19 2008 +0200

    make adpcm only output 44.1kHz stereo

diff --git a/swfdec/swfdec_codec_adpcm.c b/swfdec/swfdec_codec_adpcm.c
index 600e313..4bd4076 100644
--- a/swfdec/swfdec_codec_adpcm.c
+++ b/swfdec/swfdec_codec_adpcm.c
@@ -28,6 +28,7 @@
 
 typedef struct {
   SwfdecAudioDecoder	decoder;
+  SwfdecAudioFormat	format;
   SwfdecBufferQueue *	queue;
 } SwfdecAudioDecoderAdpcm;
 
@@ -51,10 +52,11 @@ static const int stepSizeTable[89] = {
 };
 
 static SwfdecBuffer *
-swfdec_audio_decoder_adpcm_decode_chunk (SwfdecBits *bits, guint n_bits, guint channels)
+swfdec_audio_decoder_adpcm_decode_chunk (SwfdecBits *bits, guint n_bits, 
+    guint channels, guint granularity)
 {
   SwfdecBuffer *ret;
-  guint len;
+  guint len, repeat;
   guint i, j, ch;
   guint index[2];
   int pred[2];
@@ -64,6 +66,9 @@ swfdec_audio_decoder_adpcm_decode_chunk (SwfdecBits *bits, guint n_bits, guint c
   const int *realIndexTable;
   guint step[2];
 
+  /* for scaling up the audio to 44100kHz */
+  repeat = 2 * granularity - channels;
+
   realIndexTable = indexTable[n_bits - 2];
   for (ch = 0; ch < channels; ch++) {
     /* can't use get_s16 here since that would be aligned */
@@ -78,12 +83,18 @@ swfdec_audio_decoder_adpcm_decode_chunk (SwfdecBits *bits, guint n_bits, guint c
   }
   len = swfdec_bits_left (bits) / channels / n_bits;
   len = MIN (len, 4095);
-  ret = swfdec_buffer_new ((len + 1) * sizeof (gint16) * channels);
+  ret = swfdec_buffer_new ((len + 1) * sizeof (gint16) * granularity * 2);
   out = (gint16 *) (void *) ret->data;
   /* output initial value */
   SWFDEC_LOG ("decoding %u samples", len + 1);
   for (ch = 0; ch < channels; ch++)
     *out++ = pred[ch];
+  /* upscale to 44.1kHz */
+  for (ch = 0; ch < repeat; ch++) {
+    *out = out[-(gssize) channels];
+    out++;
+  }
+
   sign_mask = 1 << (n_bits - 1);
   for (i = 0; i < len; i++) {
     for (ch = 0; ch < channels; ch++) {
@@ -123,6 +134,12 @@ swfdec_audio_decoder_adpcm_decode_chunk (SwfdecBits *bits, guint n_bits, guint c
       /* Step 7 - Output value */
       *out++ = pred[ch];
     }
+
+    /* upscale to 44.1kHz */
+    for (ch = 0; ch < repeat; ch++) {
+      *out = out[-(gssize) channels];
+      out++;
+    }
   }
   return ret;
 }
@@ -131,19 +148,20 @@ static void
 swfdec_audio_decoder_adpcm_push (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer)
 {
   SwfdecAudioDecoderAdpcm *adpcm = (SwfdecAudioDecoderAdpcm *) dec;
-  guint channels, n_bits;
+  guint channels, n_bits, granularity;
   SwfdecBits bits;
 
   if (buffer == NULL)
     return;
 
-  channels = swfdec_audio_format_get_channels (dec->format);
+  channels = swfdec_audio_format_get_channels (adpcm->format);
+  granularity = swfdec_audio_format_get_granularity (adpcm->format);
   swfdec_bits_init (&bits, buffer);
   n_bits = swfdec_bits_getbits (&bits, 2) + 2;
   SWFDEC_DEBUG ("starting decoding: %u channels, %u bits", channels, n_bits);
   /* 22 is minimum required header size */
   while (swfdec_bits_left (&bits) >= 22) {
-    buffer = swfdec_audio_decoder_adpcm_decode_chunk (&bits, n_bits, channels);
+    buffer = swfdec_audio_decoder_adpcm_decode_chunk (&bits, n_bits, channels, granularity);
     if (buffer)
       swfdec_buffer_queue_push (adpcm->queue, buffer);
   }
@@ -174,8 +192,8 @@ swfdec_audio_decoder_adpcm_new (guint type, SwfdecAudioFormat format)
   if (type != SWFDEC_AUDIO_CODEC_ADPCM)
     return NULL;
   adpcm = g_slice_new (SwfdecAudioDecoderAdpcm);
-  adpcm->decoder.format = swfdec_audio_format_new (swfdec_audio_format_get_rate (format),
-      swfdec_audio_format_get_channels (format), TRUE);
+  adpcm->format = format;
+  adpcm->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
   adpcm->decoder.push = swfdec_audio_decoder_adpcm_push;
   adpcm->decoder.pull = swfdec_audio_decoder_adpcm_pull;
   adpcm->decoder.free = swfdec_audio_decoder_adpcm_free;
commit 9d3134e04e53758477d4bab6670718a89635ac7f
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 13:27:46 2008 +0200

    throw away ffmpeg
    
    Same reason as for mad

diff --git a/configure.ac b/configure.ac
index fc84225..476649f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,29 +204,6 @@ if test "$HAVE_CAIRO" = "no"; then
   AC_MSG_ERROR([cairo and cairo-png = $CAIRO_VER is required to build swfdec])
 fi
 
-dnl  I'd put a required version in here if distros can agree on a way
-dnl  to detect ffmpeg. But as it stands even pkg-config versions are weird.
-dnl  So you'll have to update your ffmpeg checkout if compilation fails.
-dnl  Or you submit a patch that detects ffmpeg reliably on the distros.
-AC_ARG_ENABLE(ffmpeg,
-	AS_HELP_STRING([--enable-ffmpeg],
-			[enable ffmpeg support (default=no)])],
-	enable_ffmpeg=$enableval,
-	enable_ffmpeg="no")
-
-if test "$enable_ffmpeg" = "yes"; then
-	PKG_CHECK_MODULES(FFMPEG, libavcodec libswscale, HAVE_FFMPEG=yes, HAVE_FFMPEG=no)
-	AC_SUBST(FFMPEG_CFLAGS)
-	AC_SUBST(FFMPEG_LIBS)
-	if test "x$HAVE_FFMPEG" = xyes; then
-	  AC_DEFINE(HAVE_FFMPEG, 1, [Define if ffmpeg is enabled])
-	else
-	  AC_MSG_ERROR([Couldn't find ffmpeg. You might need to install the libavcodec-dev and libswscale-dev packages.])
-	fi
-else
-	AC_MSG_NOTICE([ffmpeg support was not enabled.])
-fi
-AM_CONDITIONAL(HAVE_FFMPEG, [test "x$HAVE_FFMPEG" = xyes])
 AC_ARG_ENABLE(gstreamer,
 	AS_HELP_STRING([--enable-gstreamer],
 			[enable GStreamer support (default=yes)])],
diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 31762ef..713c2f4 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -2,9 +2,6 @@ SUBDIRS = jpeg
 
 CODECS =
 
-if HAVE_FFMPEG
-CODECS += swfdec_codec_ffmpeg.c
-endif
 if HAVE_GST
 CODECS += swfdec_codec_gst.c
 endif
diff --git a/swfdec/swfdec_codec_audio.c b/swfdec/swfdec_codec_audio.c
index 8efa7e2..c018881 100644
--- a/swfdec/swfdec_codec_audio.c
+++ b/swfdec/swfdec_codec_audio.c
@@ -138,9 +138,6 @@ static const struct {
 #ifdef HAVE_GST
   { "gst",	swfdec_audio_decoder_gst_new, swfdec_audio_decoder_gst_prepare },
 #endif
-#ifdef HAVE_FFMPEG
-  { "ffmpeg",	swfdec_audio_decoder_ffmpeg_new, swfdec_audio_decoder_ffmpeg_prepare }
-#endif
 };
 
 gboolean
diff --git a/swfdec/swfdec_codec_ffmpeg.c b/swfdec/swfdec_codec_ffmpeg.c
deleted file mode 100644
index 8bfc889..0000000
--- a/swfdec/swfdec_codec_ffmpeg.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/* Swfdec
- * Copyright (C) 2006 Benjamin Otte <otte at gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library 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
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <string.h>
-#include <avcodec.h>
-#include <swscale.h>
-
-#include "swfdec_codec_audio.h"
-#include "swfdec_codec_video.h"
-#include "swfdec_debug.h"
-#include "swfdec_internal.h"
-
-/*** GENERAL ***/
-
-static AVCodecContext *
-swfdec_codec_ffmpeg_init (enum CodecID id)
-{
-  AVCodec *codec;
-  AVCodecContext *ctx;
-  static gboolean initialized = FALSE;
-
-  if (!initialized) {
-    avcodec_init();
-    avcodec_register_all ();
-    initialized = TRUE;
-  }
-
-  codec = avcodec_find_decoder (id);
-  if (!codec)
-    return NULL;
-
-  ctx = avcodec_alloc_context ();
-  if (avcodec_open (ctx, codec) < 0)
-    goto fail;
-
-  return ctx;
-fail:
-  SWFDEC_ERROR ("failed to initialize playback via ffmpeg");
-  avcodec_close (ctx);
-  av_free (ctx);
-  return NULL;
-}
-
-/*** AUDIO ***/
-
-typedef struct {
-  SwfdecAudioDecoder	decoder;
-  AVCodecContext *	ctx;
-  SwfdecBufferQueue *	queue;
-} SwfdecAudioDecoderFFMpeg;
-
-static SwfdecBuffer *
-swfdec_codec_ffmpeg_convert (AVCodecContext *ctx, SwfdecBuffer *buffer)
-{
-  SwfdecBuffer *ret;
-  guint count, i, j, rate;
-  gint16 *out, *in;
-
-  /* do the common case fast */
-  if (ctx->channels == 2 && ctx->sample_rate == 44100) {
-    ret = swfdec_buffer_new (buffer->length);
-    memcpy (ret->data, buffer->data, buffer->length);
-    return ret;
-  }
-
-  switch (ctx->sample_rate) {
-    case 44100:
-      rate = 1;
-      break;
-    case 22050:
-      rate = 2;
-      break;
-    case 11025:
-      rate = 4;
-      break;
-    default:
-      SWFDEC_ERROR ("unsupported sample rate %u", ctx->sample_rate);
-      return NULL;
-  }
-  if (ctx->channels == 1)
-    rate *= 2;
-  ret = swfdec_buffer_new (buffer->length * rate);
-  out = (gint16 *) ret->data;
-  in = (gint16 *) buffer->data;
-  count = buffer->length / 2;
-
-  for (i = 0; i < count; i++) {
-    for (j = 0; j < rate; j++) {
-      *out++ = *in;
-    }
-    in++;
-  }
-  return ret;
-}
-
-static void
-swfdec_audio_decoder_ffmpeg_push (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer)
-{
-  SwfdecAudioDecoderFFMpeg *ffmpeg = (SwfdecAudioDecoderFFMpeg *) dec;
-  int out_size;
-  int len;
-  guint amount;
-  SwfdecBuffer *outbuf = NULL;
-
-  if (buffer == NULL)
-    return;
-  outbuf = swfdec_buffer_new (AVCODEC_MAX_AUDIO_FRAME_SIZE);
-  for (amount = 0; amount < buffer->length; amount += len) {
-    
-    out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-    len = avcodec_decode_audio2 (ffmpeg->ctx, (short *) outbuf->data, &out_size, buffer->data + amount, buffer->length - amount);
-
-    if (len < 0) {
-      SWFDEC_ERROR ("Error %d while decoding", len);
-      swfdec_buffer_unref (outbuf);
-      return;
-    }
-    if (out_size > 0) {
-      SwfdecBuffer *convert;
-      outbuf->length = out_size;
-      convert = swfdec_codec_ffmpeg_convert (ffmpeg->ctx, outbuf);
-      if (convert == NULL) {
-	swfdec_buffer_unref (outbuf);
-	return;
-      }
-      swfdec_buffer_queue_push (ffmpeg->queue, convert);
-      outbuf->length = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-    }
-  }
-  swfdec_buffer_unref (outbuf);
-}
-
-static SwfdecBuffer *
-swfdec_audio_decoder_ffmpeg_pull (SwfdecAudioDecoder *dec)
-{
-  SwfdecAudioDecoderFFMpeg *ffmpeg = (SwfdecAudioDecoderFFMpeg *) dec;
-
-  return swfdec_buffer_queue_pull_buffer (ffmpeg->queue);
-}
-
-static void
-swfdec_audio_decoder_ffmpeg_free (SwfdecAudioDecoder *dec)
-{
-  SwfdecAudioDecoderFFMpeg *ffmpeg = (SwfdecAudioDecoderFFMpeg *) dec;
-
-  avcodec_close (ffmpeg->ctx);
-  av_free (ffmpeg->ctx);
-  swfdec_buffer_queue_unref (ffmpeg->queue);
-
-  g_slice_free (SwfdecAudioDecoderFFMpeg, ffmpeg);
-}
-
-gboolean
-swfdec_audio_decoder_ffmpeg_prepare (guint type, SwfdecAudioFormat format, char **details)
-{
-  return type == SWFDEC_AUDIO_CODEC_MP3 || type == SWFDEC_AUDIO_CODEC_ADPCM;
-}
-
-SwfdecAudioDecoder *
-swfdec_audio_decoder_ffmpeg_new (guint type, SwfdecAudioFormat format)
-{
-  SwfdecAudioDecoderFFMpeg *ffmpeg;
-  AVCodecContext *ctx;
-  enum CodecID id;
-
-  switch (type) {
-    case SWFDEC_AUDIO_CODEC_ADPCM:
-      id = CODEC_ID_ADPCM_SWF;
-      break;
-    case SWFDEC_AUDIO_CODEC_MP3:
-      id = CODEC_ID_MP3;
-      break;
-    default:
-      return NULL;
-  }
-  ctx = swfdec_codec_ffmpeg_init (id);
-  if (ctx == NULL)
-    return NULL;
-  ffmpeg = g_slice_new (SwfdecAudioDecoderFFMpeg);
-  ffmpeg->ctx = ctx;
-  ffmpeg->queue = swfdec_buffer_queue_new ();
-  ffmpeg->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
-  ffmpeg->decoder.pull = swfdec_audio_decoder_ffmpeg_pull;
-  ffmpeg->decoder.push = swfdec_audio_decoder_ffmpeg_push;
-  ffmpeg->decoder.free = swfdec_audio_decoder_ffmpeg_free;
-  ctx->sample_rate = swfdec_audio_format_get_rate (format);
-  ctx->channels = swfdec_audio_format_get_channels (format);
-
-  return &ffmpeg->decoder;
-}
-
-/*** VIDEO ***/
-
-typedef struct {
-  SwfdecVideoDecoder	decoder;
-  AVCodecContext *	ctx;		/* out context (d'oh) */
-  AVFrame *		frame;		/* the frame we use for decoding */
-  enum PixelFormat	format;		/* format we must output */
-} SwfdecVideoDecoderFFMpeg;
-
-static enum PixelFormat
-swfdec_video_decoder_ffmpeg_get_format (guint codec)
-{
-  switch (swfdec_video_codec_get_format (codec)) {
-    case SWFDEC_VIDEO_FORMAT_RGBA:
-      return PIX_FMT_RGB32;
-    case SWFDEC_VIDEO_FORMAT_I420:
-      return PIX_FMT_YUV420P;
-    default:
-      g_return_val_if_reached (PIX_FMT_RGB32);
-  }
-}
-
-#define ALIGNMENT 31
-static gboolean
-swfdec_video_decoder_ffmpeg_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer,
-    SwfdecVideoImage *image)
-{
-  SwfdecVideoDecoderFFMpeg *codec = (SwfdecVideoDecoderFFMpeg *) dec;
-  int got_image = 0;
-  guchar *tmp, *aligned;
-
-  /* fullfill alignment and padding requirements */
-  tmp = g_try_malloc (buffer->length + ALIGNMENT + FF_INPUT_BUFFER_PADDING_SIZE);
-  if (tmp == NULL) {
-    SWFDEC_WARNING ("Could not allocate temporary memory");
-    return FALSE;
-  }
-  aligned = (guchar *) (((uintptr_t) tmp + ALIGNMENT) & ~ALIGNMENT);
-  memcpy (aligned, buffer->data, buffer->length);
-  memset (aligned + buffer->length, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-  if (avcodec_decode_video (codec->ctx, codec->frame, &got_image, 
-	aligned, buffer->length) < 0) {
-    g_free (tmp);
-    SWFDEC_WARNING ("error decoding frame");
-    return FALSE;
-  }
-  g_free (tmp);
-  if (got_image == 0) {
-    SWFDEC_WARNING ("did not get an image from decoding");
-    return FALSE;
-  }
-  if (codec->ctx->pix_fmt != codec->format) {
-    SWFDEC_WARNING ("decoded to wrong format, expected %u, but got %u",
-	codec->format, codec->ctx->pix_fmt);
-    return FALSE;
-  }
-  image->width = codec->ctx->width;
-  image->height = codec->ctx->height;
-  image->mask = NULL;
-  image->plane[0] = codec->frame->data[0];
-  image->plane[1] = codec->frame->data[1];
-  image->plane[2] = codec->frame->data[2];
-  image->rowstride[0] = codec->frame->linesize[0];
-  image->rowstride[1] = codec->frame->linesize[1];
-  image->rowstride[2] = codec->frame->linesize[2];
-  return TRUE;
-}
-
-static void
-swfdec_video_decoder_ffmpeg_free (SwfdecVideoDecoder *dec)
-{
-  SwfdecVideoDecoderFFMpeg *codec = (SwfdecVideoDecoderFFMpeg *) dec;
-
-  avcodec_close (codec->ctx);
-  av_free (codec->ctx);
-  av_free (codec->frame);
-  g_free (codec);
-}
-
-gboolean
-swfdec_video_decoder_ffmpeg_prepare (guint codec, char **detail)
-{
-  return codec == SWFDEC_VIDEO_CODEC_H263 ||
-    codec == SWFDEC_VIDEO_CODEC_SCREEN ||
-    codec == SWFDEC_VIDEO_CODEC_VP6;
-}
-
-SwfdecVideoDecoder *
-swfdec_video_decoder_ffmpeg_new (guint type)
-{
-  SwfdecVideoDecoderFFMpeg *codec;
-  AVCodecContext *ctx;
-  enum CodecID id;
-
-  switch (type) {
-    case SWFDEC_VIDEO_CODEC_H263:
-      id = CODEC_ID_FLV1;
-      break;
-    case SWFDEC_VIDEO_CODEC_SCREEN:
-      id = CODEC_ID_FLASHSV;
-      break;
-    case SWFDEC_VIDEO_CODEC_VP6:
-      id = CODEC_ID_VP6F;
-      break;
-    default:
-      return NULL;
-  }
-  ctx = swfdec_codec_ffmpeg_init (id);
-
-  if (ctx == NULL)
-    return NULL;
-  codec = g_new0 (SwfdecVideoDecoderFFMpeg, 1);
-  codec->decoder.decode = swfdec_video_decoder_ffmpeg_decode;
-  codec->decoder.free = swfdec_video_decoder_ffmpeg_free;
-  codec->ctx = ctx;
-  codec->frame = avcodec_alloc_frame ();
-  codec->format = swfdec_video_decoder_ffmpeg_get_format (type);
-
-  return &codec->decoder;
-}
-
diff --git a/swfdec/swfdec_codec_video.c b/swfdec/swfdec_codec_video.c
index bfa5593..8260945 100644
--- a/swfdec/swfdec_codec_video.c
+++ b/swfdec/swfdec_codec_video.c
@@ -55,9 +55,6 @@ static const struct {
 #ifdef HAVE_GST
   , { "gst",		swfdec_video_decoder_gst_new,		swfdec_video_decoder_gst_prepare }
 #endif
-#ifdef HAVE_FFMPEG
-  , { "ffmpeg",		swfdec_video_decoder_ffmpeg_new,	swfdec_video_decoder_ffmpeg_prepare }
-#endif
 };
 
 char *
diff --git a/swfdec/swfdec_internal.h b/swfdec/swfdec_internal.h
index 5a8ae37..15bb69b 100644
--- a/swfdec/swfdec_internal.h
+++ b/swfdec/swfdec_internal.h
@@ -33,13 +33,6 @@ G_BEGIN_DECLS
 
 SwfdecAudioDecoder *	swfdec_audio_decoder_adpcm_new		(guint			type, 
 								 SwfdecAudioFormat	format);
-#ifdef HAVE_FFMPEG
-SwfdecAudioDecoder *	swfdec_audio_decoder_ffmpeg_new		(guint			type, 
-								 SwfdecAudioFormat	format);
-gboolean		swfdec_audio_decoder_ffmpeg_prepare	(guint			codec,
-								 SwfdecAudioFormat	format,
-								 char **		detail);
-#endif
 #ifdef HAVE_GST
 SwfdecAudioDecoder *	swfdec_audio_decoder_gst_new		(guint			type, 
 								 SwfdecAudioFormat	format);
@@ -52,11 +45,6 @@ gboolean		swfdec_audio_decoder_gst_prepare	(guint			codec,
 
 SwfdecVideoDecoder *	swfdec_video_decoder_screen_new		(guint			format);
 SwfdecVideoDecoder *	swfdec_video_decoder_vp6_alpha_new    	(guint			format);
-#ifdef HAVE_FFMPEG
-SwfdecVideoDecoder *	swfdec_video_decoder_ffmpeg_new		(guint			format);
-gboolean		swfdec_video_decoder_ffmpeg_prepare	(guint			codec,
-								 char **		detail);
-#endif
 #ifdef HAVE_GST
 SwfdecVideoDecoder *	swfdec_video_decoder_gst_new		(guint			format);
 gboolean		swfdec_video_decoder_gst_prepare	(guint			codec,
commit 161890f7327cc0b803aa5871ba76dcfc40559f2c
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 12:58:58 2008 +0200

    remove mad option for codecs
    
    It doesn't add anything useful, and I don't wanna keep it up to date when
    doing surgery on the audio subsystem

diff --git a/autogen.sh b/autogen.sh
index f91d629..efac6c5 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
 autoreconf -i -f &&
-./configure --disable-static --enable-gtk-doc --enable-vivified --enable-ffmpeg --enable-mad $@
+./configure --disable-static --enable-gtk-doc --enable-vivified --enable-ffmpeg $@
diff --git a/configure.ac b/configure.ac
index e3608e9..fc84225 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,30 +204,6 @@ if test "$HAVE_CAIRO" = "no"; then
   AC_MSG_ERROR([cairo and cairo-png = $CAIRO_VER is required to build swfdec])
 fi
 
-AC_ARG_ENABLE(mad,
-	AS_HELP_STRING([--enable-mad],
-			[enable mad audio (default=no)])],
-	enable_mad=$enableval,
-	enable_mad="no")
-
-if test "$enable_mad" = "yes"; then
-        PKG_CHECK_EXISTS([mad],[
-		MAD_VER=0.15.0
-                PKG_CHECK_MODULES(MAD, mad >= $MAD_VER mad >= $MAD_VER, HAVE_MAD=yes, HAVE_MAD=no)
-        ], [
-                AC_CHECK_LIB(mad, mad_decoder_finish, HAVE_MAD="yes" MAD_LIBS="-lmad", HAVE_MAD="no")
-        ])
-	AC_SUBST(MAD_LIBS)
-	if test "x$HAVE_MAD" = xyes; then
-	  AC_DEFINE(HAVE_MAD, 1, [Define if mad is enabled])
-	else
-	  AC_MSG_ERROR([Couldn't find mad. You might need to install the libmad0-dev package.])
-	fi
-else
-	AC_MSG_NOTICE([mad audio support was not enabled.])
-fi
-AM_CONDITIONAL(HAVE_MAD, [test "x$HAVE_MAD" = xyes])
-
 dnl  I'd put a required version in here if distros can agree on a way
 dnl  to detect ffmpeg. But as it stands even pkg-config versions are weird.
 dnl  So you'll have to update your ffmpeg checkout if compilation fails.
diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 4808c72..31762ef 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -8,9 +8,6 @@ endif
 if HAVE_GST
 CODECS += swfdec_codec_gst.c
 endif
-if HAVE_MAD
-CODECS += swfdec_codec_mad.c
-endif
 
 lib_LTLIBRARIES = libswfdec- at SWFDEC_MAJORMINOR@.la
 
diff --git a/swfdec/swfdec_codec_audio.c b/swfdec/swfdec_codec_audio.c
index 1f4bb23..8efa7e2 100644
--- a/swfdec/swfdec_codec_audio.c
+++ b/swfdec/swfdec_codec_audio.c
@@ -138,9 +138,6 @@ static const struct {
 #ifdef HAVE_GST
   { "gst",	swfdec_audio_decoder_gst_new, swfdec_audio_decoder_gst_prepare },
 #endif
-#ifdef HAVE_MAD
-  { "mad",	swfdec_audio_decoder_mad_new, swfdec_audio_decoder_mad_prepare },
-#endif
 #ifdef HAVE_FFMPEG
   { "ffmpeg",	swfdec_audio_decoder_ffmpeg_new, swfdec_audio_decoder_ffmpeg_prepare }
 #endif
diff --git a/swfdec/swfdec_codec_mad.c b/swfdec/swfdec_codec_mad.c
deleted file mode 100644
index 3b508b8..0000000
--- a/swfdec/swfdec_codec_mad.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* Swfdec
- * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library 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
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <string.h>
-#include <config.h>
-#include <liboil/liboil.h>
-#include <mad.h>
-
-#include "swfdec_codec_audio.h"
-#include "swfdec_debug.h"
-#include "swfdec_internal.h"
-
-typedef struct {
-  SwfdecAudioDecoder	decoder;
-
-  struct mad_stream	stream;
-  struct mad_frame	frame;
-  struct mad_synth	synth;
-  guint8		data[MAD_BUFFER_MDLEN * 3];
-  guint			data_len;
-  SwfdecBufferQueue *	queue;
-} MadData;
-
-static SwfdecBuffer *
-convert_synth_to_buffer (MadData *mdata)
-{
-  SwfdecBuffer *buffer;
-  int n_samples;
-  short *data;
-  int i;
-  short c0,c1;
-#define MAD_F_TO_S16(x) (CLAMP (x, -MAD_F_ONE, MAD_F_ONE) >> (MAD_F_FRACBITS - 14))
-
-  n_samples = mdata->synth.pcm.length;
-  if (n_samples == 0) {
-    return NULL;
-  }
-
-  switch (mdata->synth.pcm.samplerate) {
-    case 11025:
-      n_samples *= 4;
-      break;
-    case 22050:
-      n_samples *= 2;
-      break;
-    case 44100:
-      break;
-    default:
-      SWFDEC_ERROR ("sample rate not handled (%d)",
-          mdata->synth.pcm.samplerate);
-      return NULL;
-  }
-
-  buffer = swfdec_buffer_new (n_samples * 2 * 2);
-  data = (gint16 *) buffer->data;
-
-  if (mdata->synth.pcm.samplerate == 11025) {
-    if (mdata->synth.pcm.channels == 2) {
-      for (i = 0; i < mdata->synth.pcm.length; i++) {
-        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
-        c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);
-        *data++ = c0;
-        *data++ = c1;
-        *data++ = c0;
-        *data++ = c1;
-        *data++ = c0;
-        *data++ = c1;
-        *data++ = c0;
-        *data++ = c1;
-      }
-    } else {
-      for (i = 0; i < mdata->synth.pcm.length; i++) {
-        c0 = MAD_F_TO_S16( mdata->synth.pcm.samples[0][i]);
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-      }
-    }
-  } else if (mdata->synth.pcm.samplerate == 22050) {
-    if (mdata->synth.pcm.channels == 2) {
-      for (i = 0; i < mdata->synth.pcm.length; i++) {
-        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
-        c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);
-        *data++ = c0;
-        *data++ = c1;
-        *data++ = c0;
-        *data++ = c1;
-      }
-    } else {
-      for (i = 0; i < mdata->synth.pcm.length; i++) {
-        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-        *data++ = c0;
-      }
-    }
-  } else if (mdata->synth.pcm.samplerate == 44100) {
-    if (mdata->synth.pcm.channels == 2) {
-      for (i = 0; i < mdata->synth.pcm.length; i++) {
-        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
-        c1 = MAD_F_TO_S16 (mdata->synth.pcm.samples[1][i]);
-        *data++ = c0;
-        *data++ = c1;
-      }
-    } else {
-      for (i = 0; i < mdata->synth.pcm.length; i++) {
-        c0 = MAD_F_TO_S16 (mdata->synth.pcm.samples[0][i]);
-        *data++ = c0;
-        *data++ = c0;
-      }
-    }
-  } else {
-    SWFDEC_ERROR ("sample rate not handled (%d)",
-        mdata->synth.pcm.samplerate);
-  }
-  return buffer;
-}
-
-static void
-swfdec_audio_decoder_mad_push (SwfdecAudioDecoder *dec, SwfdecBuffer *buffer)
-{
-  MadData *data = (MadData *) dec;
-  SwfdecBuffer *out, *empty = NULL;
-  guint amount = 0, size;
-
-  if (buffer == NULL)
-    buffer = empty = swfdec_buffer_new0 (MAD_BUFFER_GUARD * 3);
-
-  //write (1, buffer->data, buffer->length);
-  //g_print ("buffer %p gave us %u bytes\n", buffer, buffer->length);
-  while (amount < buffer->length) {
-    size = MIN (buffer->length - amount, MAD_BUFFER_MDLEN * 3 - data->data_len);
-    memcpy (&data->data[data->data_len], buffer->data + amount, size);
-    //write (1, buffer->data + amount, size);
-    amount += size;
-    data->data_len += size;
-    mad_stream_buffer (&data->stream, data->data, data->data_len);
-    while (1) {
-      if (mad_frame_decode (&data->frame, &data->stream)) {
-	if (data->stream.error == MAD_ERROR_BUFLEN)
-	  break;
-	if (MAD_RECOVERABLE (data->stream.error)) {
-	  SWFDEC_LOG ("recoverable error 0x%04x", data->stream.error);
-	  continue;
-	}
-	SWFDEC_ERROR ("stream error 0x%04x", data->stream.error);
-	break;
-      }
-
-      mad_synth_frame (&data->synth, &data->frame);
-      out = convert_synth_to_buffer (data);
-      if (out)
-	swfdec_buffer_queue_push (data->queue, out);
-    }
-    if (data->stream.next_frame == NULL) {
-      data->data_len = 0;
-    } else {
-      data->data_len = data->stream.bufend - data->stream.next_frame;
-      memmove (data->data, data->stream.next_frame, data->data_len);
-    }
-  }
-  //g_print ("%u bytes left\n", data->data_len);
-
-  if (empty)
-    swfdec_buffer_unref (empty);
-}
-
-static void
-swfdec_audio_decoder_mad_free (SwfdecAudioDecoder *dec)
-{
-  MadData *data = (MadData *) dec;
-
-  mad_synth_finish (&data->synth);
-  mad_frame_finish (&data->frame);
-  mad_stream_finish (&data->stream);
-  swfdec_buffer_queue_unref (data->queue);
-  g_slice_free (MadData, data);
-}
-
-static SwfdecBuffer *
-swfdec_audio_decoder_mad_pull (SwfdecAudioDecoder *dec)
-{
-  return swfdec_buffer_queue_pull_buffer (((MadData *) dec)->queue);
-}
-
-gboolean
-swfdec_audio_decoder_mad_prepare (guint type, SwfdecAudioFormat format, char **details)
-{
-  return type == SWFDEC_AUDIO_CODEC_MP3;
-}
-
-SwfdecAudioDecoder *
-swfdec_audio_decoder_mad_new (guint type, SwfdecAudioFormat format)
-{
-  MadData *data;
-  
-  if (type != SWFDEC_AUDIO_CODEC_MP3)
-    return NULL;
-
-  data = g_slice_new (MadData);
-  data->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
-  data->decoder.push = swfdec_audio_decoder_mad_push;
-  data->decoder.pull = swfdec_audio_decoder_mad_pull;
-  data->decoder.free = swfdec_audio_decoder_mad_free;
-  mad_stream_init (&data->stream);
-  mad_frame_init (&data->frame);
-  mad_synth_init (&data->synth);
-  data->data_len = 0;
-  data->queue = swfdec_buffer_queue_new ();
-
-  return &data->decoder;
-}
-
diff --git a/swfdec/swfdec_internal.h b/swfdec/swfdec_internal.h
index b82ccf2..5a8ae37 100644
--- a/swfdec/swfdec_internal.h
+++ b/swfdec/swfdec_internal.h
@@ -33,13 +33,6 @@ G_BEGIN_DECLS
 
 SwfdecAudioDecoder *	swfdec_audio_decoder_adpcm_new		(guint			type, 
 								 SwfdecAudioFormat	format);
-#ifdef HAVE_MAD
-SwfdecAudioDecoder *	swfdec_audio_decoder_mad_new		(guint		type, 
-								 SwfdecAudioFormat	format);
-gboolean		swfdec_audio_decoder_mad_prepare	(guint			codec,
-								 SwfdecAudioFormat	format,
-								 char **		detail);
-#endif
 #ifdef HAVE_FFMPEG
 SwfdecAudioDecoder *	swfdec_audio_decoder_ffmpeg_new		(guint			type, 
 								 SwfdecAudioFormat	format);
commit c1db50ce84138b86d18ad94e1f079af27413acc3
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat May 24 12:48:14 2008 +0200

    make swfdec_audio_render() return the number of rendered samples
    
    This is a preparation for audio handling changes coming up

diff --git a/swfdec/swfdec_audio.c b/swfdec/swfdec_audio.c
index e9a5e5f..69eadb0 100644
--- a/swfdec/swfdec_audio.c
+++ b/swfdec/swfdec_audio.c
@@ -161,19 +161,24 @@ swfdec_audio_iterate (SwfdecAudio *audio, guint n_samples)
  * Renders the samples from @audio into the area pointed to by @dest. The data 
  * is added to @dest, so you probably want to initialize @dest to silence 
  * before calling this function.
+ *
+ * Returns: The amount of samples actually rendered. Usually this number is 
+ *          equal to @n_samples, but if you arrived at the end of stream or the
+ *          stream is still loading, this number may be lower. It indicates 
+ *          that no more samples are available.
  **/
-void
+guint
 swfdec_audio_render (SwfdecAudio *audio, gint16 *dest, 
     guint start_offset, guint n_samples)
 {
   SwfdecAudioClass *klass;
 
-  g_return_if_fail (SWFDEC_IS_AUDIO (audio));
-  g_return_if_fail (dest != NULL);
-  g_return_if_fail (n_samples > 0);
+  g_return_val_if_fail (SWFDEC_IS_AUDIO (audio), 0);
+  g_return_val_if_fail (dest != NULL, 0);
+  g_return_val_if_fail (n_samples > 0, 0);
 
   klass = SWFDEC_AUDIO_GET_CLASS (audio);
-  klass->render (audio, dest, start_offset, n_samples);
+  return klass->render (audio, dest, start_offset, n_samples);
 }
 
 /**
diff --git a/swfdec/swfdec_audio.h b/swfdec/swfdec_audio.h
index 4352faf..842dd92 100644
--- a/swfdec/swfdec_audio.h
+++ b/swfdec/swfdec_audio.h
@@ -38,7 +38,7 @@ typedef struct _SwfdecAudioClass SwfdecAudioClass;
 
 GType		swfdec_audio_get_type		(void);
 
-void		swfdec_audio_render		(SwfdecAudio *	audio,
+guint		swfdec_audio_render		(SwfdecAudio *	audio,
 						 gint16 *	dest,
 						 guint		start_offset,
 						 guint		n_samples);
diff --git a/swfdec/swfdec_audio_event.c b/swfdec/swfdec_audio_event.c
index 6c78bea..349a148 100644
--- a/swfdec/swfdec_audio_event.c
+++ b/swfdec/swfdec_audio_event.c
@@ -78,17 +78,17 @@ swfdec_audio_event_get_envelop_volume (SwfdecAudioEvent *event, guint pos,
     event->envelope[pos].volume[channel] * (offset / distance);
 }
 
-static void
+static guint
 swfdec_audio_event_render (SwfdecAudio *audio, gint16* dest, guint start,
     guint n_samples)
 {
   SwfdecAudioEvent *event = SWFDEC_AUDIO_EVENT (audio);
   guint offset = event->offset + start;
-  guint loop, samples, global_offset, pos, i, channels;
+  guint loop, samples, global_offset, pos, i, channels, rendered;
   gint16 *dest_end;
 
   if (event->n_samples == 0)
-    return;
+    return 0;
 
   channels = swfdec_audio_format_get_channels (event->decoded_format);
 
@@ -105,18 +105,19 @@ swfdec_audio_event_render (SwfdecAudio *audio, gint16* dest, guint start,
   dest_end = dest;
   loop = event->loop + offset / event->n_samples;
   offset %= event->n_samples;
-  for (; loop < event->n_loops && n_samples > 0; loop++) {
-    samples = MIN (n_samples, event->n_samples - offset);
+  for (rendered = 0; loop < event->n_loops && rendered < n_samples; loop++) {
+    samples = MIN (n_samples - rendered, event->n_samples - offset);
     swfdec_sound_buffer_render (dest_end, event->decoded,
 	event->decoded_format, loop == 0 ? NULL : event->decoded, offset,
 	samples);
-    n_samples -= samples;
+    rendered += samples;
     dest_end += samples * 2;
     offset = 0;
+    rendered += samples;
   }
 
   if (event->n_envelopes == 0)
-    return;
+    return rendered;
 
   pos = 0;
   for (i = 0; i < (guint) (dest_end - dest); i++) {
@@ -133,6 +134,7 @@ swfdec_audio_event_render (SwfdecAudio *audio, gint16* dest, guint start,
 	  global_offset + (i / 2), i % 2) / 32768.0;
     }
   }
+  return rendered;
 }
 
 static void
diff --git a/swfdec/swfdec_audio_flv.c b/swfdec/swfdec_audio_flv.c
index 59de5c5..c5ce351 100644
--- a/swfdec/swfdec_audio_flv.c
+++ b/swfdec/swfdec_audio_flv.c
@@ -112,13 +112,13 @@ swfdec_audio_flv_decode_one (SwfdecAudioFlv *flv)
   return buffer;
 }
 
-static void
+static guint
 swfdec_audio_flv_render (SwfdecAudio *audio, gint16* dest,
     guint start, guint n_samples)
 {
   SwfdecAudioFlv *flv = SWFDEC_AUDIO_FLV (audio);
   GList *walk;
-  guint samples;
+  guint samples, rendered;
   SwfdecBuffer *buffer, *previous;
 
   g_assert (start < G_MAXINT);
@@ -153,10 +153,12 @@ swfdec_audio_flv_render (SwfdecAudio *audio, gint16* dest,
 	swfdec_audio_decoder_get_format (flv->decoder), previous, start, 
 	samples);
     start = 0;
+    rendered += samples;
     n_samples -= samples;
     dest += 2 * samples;
     previous = buffer;
   }
+  return rendered;
 }
 
 static guint
diff --git a/swfdec/swfdec_audio_internal.h b/swfdec/swfdec_audio_internal.h
index 2332baa..a69df75 100644
--- a/swfdec/swfdec_audio_internal.h
+++ b/swfdec/swfdec_audio_internal.h
@@ -46,7 +46,7 @@ struct _SwfdecAudioClass {
 
   guint			(* iterate)	  		(SwfdecAudio *	audio,
 							 guint		n_samples);
-  void			(* render)			(SwfdecAudio *	audio,
+  guint			(* render)			(SwfdecAudio *	audio,
 							 gint16 *	dest,
 							 guint		start, 
 							 guint		n_samples);
diff --git a/swfdec/swfdec_audio_stream.c b/swfdec/swfdec_audio_stream.c
index d4eb6ca..5ce2843 100644
--- a/swfdec/swfdec_audio_stream.c
+++ b/swfdec/swfdec_audio_stream.c
@@ -77,13 +77,13 @@ end:
   return buffer;
 }
 
-static void
+static guint
 swfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,
     guint start, guint n_samples)
 {
   SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (audio);
   GList *walk;
-  guint samples;
+  guint samples, rendered;
   SwfdecBuffer *buffer, *previous;
 
   g_assert (start < G_MAXINT);
@@ -91,7 +91,7 @@ swfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,
   SWFDEC_LOG ("stream %p rendering offset %u, samples %u", stream, start, n_samples);
   walk = g_queue_peek_head_link (stream->playback_queue);
   previous = NULL;
-  while (n_samples) {
+  for (rendered = 0; rendered < n_samples;) {
     if (walk) {
       buffer = walk->data;
       walk = walk->next;
@@ -116,15 +116,17 @@ swfdec_audio_stream_render (SwfdecAudio *audio, gint16* dest,
     } else {
       SWFDEC_LOG ("rendering %u samples", samples);
     }
-    samples = MIN (samples, n_samples);
+    samples = MIN (samples, n_samples - rendered);
     swfdec_sound_buffer_render (dest, buffer, 
 	swfdec_audio_decoder_get_format (stream->decoder), 
 	previous, start, samples);
     start = 0;
-    n_samples -= samples;
+    rendered += samples;
     dest += 2 * samples;
     previous = buffer;
   }
+
+  return rendered;
 }
 
 static guint
commit e4b5177e74329dad4dfce00834fed3e9b21ff040
Author: Lúcio Corrêa <lucio.correa at gmail.com>
Date:   Sat May 24 11:21:33 2008 +0200

    Make swfdec compile with gold linker

diff --git a/configure.ac b/configure.ac
index 612f6ff..e3608e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -297,7 +297,7 @@ AC_SUBST(GLOBAL_CFLAGS)
 AC_SUBST(GLOBAL_CFLAGS)
 
 SWFDEC_CFLAGS="-I\$(top_srcdir) $GLIB_CFLAGS $CAIRO_CFLAGS"
-SWFDEC_LIBS="\$(top_builddir)/swfdec/libswfdec-$SWFDEC_MAJORMINOR.la $GLIB_LIBS $CAIRO_LIBS -lz"
+SWFDEC_LIBS="\$(top_builddir)/swfdec/libswfdec-$SWFDEC_MAJORMINOR.la $GLIB_LIBS $CAIRO_LIBS -lz -lm"
 AC_SUBST(SWFDEC_LIBS)
 AC_SUBST(SWFDEC_CFLAGS)
 
commit 49563f955e223988d0f05f1a7d3847d122130f5b
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri May 23 19:29:30 2008 +0200

    force audio to 44.1kHz streo 16bit
    
    Fixes some issues with weird sound formats

diff --git a/swfdec/swfdec_codec_gst.c b/swfdec/swfdec_codec_gst.c
index 6b27a67..883561d 100644
--- a/swfdec/swfdec_codec_gst.c
+++ b/swfdec/swfdec_codec_gst.c
@@ -419,30 +419,6 @@ swfdec_audio_decoder_gst_pull (SwfdecAudioDecoder *dec)
   return swfdec_buffer_new_from_gst (buf);
 }
 
-static gboolean
-swfdec_audio_decoder_set_caps (GstPad *pad, GstCaps *caps)
-{
-  SwfdecGstAudio *player = g_object_get_data (G_OBJECT (pad), "swfdec-player");
-  GstStructure *structure = gst_caps_get_structure (caps, 0);
-  int depth, channels, rate;
-
-  if (SWFDEC_IS_AUDIO_FORMAT (player->decoder.format)) {
-    SWFDEC_ERROR ("resetting format not allowed");
-    player->error = TRUE;
-    return FALSE;
-  }
-  if (!gst_structure_get_int (structure, "depth", &depth) ||
-      !gst_structure_get_int (structure, "rate", &rate) ||
-      !gst_structure_get_int (structure, "channels", &channels)) {
-    SWFDEC_ERROR ("invalid caps");
-    player->error = TRUE;
-    return FALSE;
-  }
-
-  player->decoder.format = swfdec_audio_format_new (rate, channels, depth == 16 ? TRUE : FALSE);
-  return TRUE;
-}
-
 SwfdecAudioDecoder *
 swfdec_audio_decoder_gst_new (guint type, SwfdecAudioFormat format)
 {
@@ -467,22 +443,22 @@ swfdec_audio_decoder_gst_new (guint type, SwfdecAudioFormat format)
   /* create audioconvert */
   gst_caps_unref (srccaps);
   srccaps = sinkcaps;
-  sinkcaps = gst_caps_from_string ("audio/x-raw-int, endianness=byte_order, signed=(boolean)true, width=16, depth=16, channels={2,1}");
+  sinkcaps = gst_caps_from_string ("audio/x-raw-int, endianness=byte_order, signed=(boolean)true, width=16, depth=16, channels=2");
   g_assert (sinkcaps);
   if (!swfdec_gst_decoder_init (&player->convert, "audioconvert", srccaps, sinkcaps))
     goto error;
   /* create audiorate */
   gst_caps_unref (srccaps);
   srccaps = sinkcaps;
-  sinkcaps = gst_caps_from_string ("audio/x-raw-int, endianness=byte_order, signed=(boolean)true, width=16, depth=16, rate={44100, 22050, 11025, 5512}, channels={2,1}");
+  sinkcaps = gst_caps_from_string ("audio/x-raw-int, endianness=byte_order, signed=(boolean)true, width=16, depth=16, rate=44100, channels=2");
   g_assert (sinkcaps);
   if (!swfdec_gst_decoder_init (&player->resample, "audioresample", srccaps, sinkcaps))
     goto error;
   g_object_set_data (G_OBJECT (player->resample.sink), "swfdec-player", player);
-  gst_pad_set_setcaps_function (player->resample.sink, swfdec_audio_decoder_set_caps);
 
   gst_caps_unref (srccaps);
   gst_caps_unref (sinkcaps);
+  player->decoder.format = swfdec_audio_format_new (44100, 2, TRUE);
   return &player->decoder;
 
 error:
commit 970c06eaefb040435855077524a72e9d190b162c
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri May 23 17:58:35 2008 +0200

    fix emitted code to include length

diff --git a/vivified/code/vivi_code_asm_get_url2.c b/vivified/code/vivi_code_asm_get_url2.c
index 210eb33..b244953 100644
--- a/vivified/code/vivi_code_asm_get_url2.c
+++ b/vivified/code/vivi_code_asm_get_url2.c
@@ -37,6 +37,7 @@ vivi_code_asm_get_url2_emit (ViviCodeAsm *code, ViviCodeEmitter *emitter,
   SwfdecBots *emit = vivi_code_emitter_get_bots (emitter);
 
   swfdec_bots_put_u8 (emit, SWFDEC_AS_ACTION_GET_URL2);
+  swfdec_bots_put_u16 (emit, 1);
   swfdec_bots_put_u8 (emit, get_url->flags);
 
   return TRUE;
commit 81b9e9804db7538eb929e9f97032745bceb04f69
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri May 23 13:56:10 2008 +0200

    store the to-stage and from-stage matrices in the textfield
    
    This makes it possible to do full conversion from/to the layout coordinate
    system and not just distances. And this in turn allows proper conversion of
    mouse coordinates. So selection should work properly now.

diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index 4b4d5f9..d6ec755 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -46,72 +46,96 @@ G_DEFINE_TYPE (SwfdecTextFieldMovie, swfdec_text_field_movie, SWFDEC_TYPE_ACTOR)
 
 /*** VFUNCS ***/
 
+static void
+swfdec_text_field_movie_compute_layout_area (SwfdecTextFieldMovie *text)
+{
+  int tmpx, tmpy;
+
+  tmpx = round ((BORDER_LEFT + BORDER_RIGHT) * SWFDEC_TWIPS_SCALE_FACTOR * text->to_layout.xx);
+  tmpy = round ((BORDER_TOP + BORDER_BOTTOM) * SWFDEC_TWIPS_SCALE_FACTOR * text->to_layout.yy);
+  text->layout_area = text->stage_area;
+  if (tmpx >= text->layout_area.width ||
+      tmpy >= text->layout_area.height)
+    return;
+  
+  text->layout_area.x += tmpx / 2;
+  text->layout_area.y += tmpy / 2;
+  text->layout_area.width -= tmpx;
+  text->layout_area.height -= tmpy;
+}
+
 /* NB: This signal can happen without a locked player */
 static void
 swfdec_text_field_movie_update_area (SwfdecTextFieldMovie *text)
 {
   SwfdecMovie *movie = SWFDEC_MOVIE (text);
-  cairo_matrix_t matrix, translate;
+  cairo_matrix_t *matrix, translate;
   double x, y;
 
   if (swfdec_player_is_locked (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (text)->context)))
     swfdec_movie_invalidate_next (movie);
 
   /* check if we indeed want to render */
-  swfdec_movie_local_to_global_matrix (movie, &matrix);
-  cairo_matrix_multiply (&matrix, &matrix,
+  matrix = &text->to_layout;
+  swfdec_movie_local_to_global_matrix (movie, matrix);
+  cairo_matrix_multiply (matrix, matrix,
       &SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context)->priv->global_to_stage);
-  if (matrix.xy != 0.0 || matrix.yx != 0.0 ||
-      matrix.xx <= 0.0 || matrix.yy <= 0.0) {
-    swfdec_rectangle_init_empty (&text->stage_rect);
+  if (matrix->xy != 0.0 || matrix->yx != 0.0 ||
+      matrix->xx <= 0.0 || matrix->yy <= 0.0) {
+    swfdec_rectangle_init_empty (&text->stage_area);
+    swfdec_rectangle_init_empty (&text->layout_area);
     return;
   }
 
-  translate = matrix;
   x = text->extents.x0;
   y = text->extents.y0;
-  cairo_matrix_transform_point (&matrix, &x, &y);
+  cairo_matrix_transform_point (matrix, &x, &y);
   cairo_matrix_init_translate (&translate, round (x) - x, round (y) - y);
-  cairo_matrix_multiply (&matrix, &matrix, &translate);
+  cairo_matrix_multiply (matrix, matrix, &translate);
+  text->from_layout = *matrix;
+  if (cairo_matrix_invert (&text->from_layout)) {
+    SWFDEC_ERROR ("cannot invert to-layout matrix");
+    swfdec_rectangle_init_empty (&text->stage_area);
+    swfdec_rectangle_init_empty (&text->layout_area);
+    return;
+  }
   
   x = text->extents.x0;
   y = text->extents.y0;
-  cairo_matrix_transform_point (&matrix, &x, &y);
-  text->stage_rect.x = x;
-  text->stage_rect.y = y;
+  cairo_matrix_transform_point (matrix, &x, &y);
+  text->stage_area.x = x;
+  text->stage_area.y = y;
   x = text->extents.x1;
   y = text->extents.y1;
-  cairo_matrix_transform_point (&matrix, &x, &y);
+  cairo_matrix_transform_point (matrix, &x, &y);
   /* FIXME: floor, ceil or round? */
-  text->stage_rect.width = round (x) - text->stage_rect.x;
-  text->stage_rect.height = round (y) - text->stage_rect.y;
-  text->xscale = matrix.xx * SWFDEC_TWIPS_SCALE_FACTOR;
-  text->yscale = matrix.yy * SWFDEC_TWIPS_SCALE_FACTOR;
-  swfdec_text_layout_set_scale (text->layout, text->yscale);
-  swfdec_text_layout_set_wrap_width (text->layout, text->stage_rect.width - 
-      BORDER_LEFT - BORDER_RIGHT);
+  text->stage_area.width = round (x) - text->stage_area.x;
+  text->stage_area.height = round (y) - text->stage_area.y;
+
+  swfdec_text_field_movie_compute_layout_area (text);
+
+  swfdec_text_layout_set_scale (text->layout, matrix->yy * SWFDEC_TWIPS_SCALE_FACTOR);
+  swfdec_text_layout_set_wrap_width (text->layout, text->layout_area.width);
 }
 
 static void
 swfdec_text_field_movie_auto_size (SwfdecTextFieldMovie *text)
 {
   SwfdecMovie *movie = SWFDEC_MOVIE (text);
-  SwfdecRectangle area;
   double x0, z0, x1, z1; /* y0 and y1 are taken by math.h */
 
   if (text->auto_size == SWFDEC_AUTO_SIZE_NONE)
     return;
 
-  swfdec_text_field_movie_get_visible_area (text, &area);
-  x1 = (double) text->layout_width - area.width;
-  z1 = (double) text->layout_height - area.height;
+  x1 = (double) text->layout_width - text->layout_area.width;
+  z1 = (double) text->layout_height - text->layout_area.height;
 
   if (x1 == 0 && z1 == 0)
     return;
 
   /* FIXME: rounding */
-  x1 *= SWFDEC_TWIPS_SCALE_FACTOR / text->xscale;
-  z1 *= SWFDEC_TWIPS_SCALE_FACTOR / text->yscale;
+  x1 *= text->from_layout.xx;
+  z1 *= text->from_layout.yy;
 
   switch (text->auto_size) {
     case SWFDEC_AUTO_SIZE_LEFT:
@@ -170,10 +194,10 @@ swfdec_text_field_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *ma
   SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (movie);
   SwfdecRect rect;
 
-  rect.x0 = text->stage_rect.x;
-  rect.y0 = text->stage_rect.y;
-  rect.x1 = text->stage_rect.x + text->stage_rect.width;
-  rect.y1 = text->stage_rect.y + text->stage_rect.height;
+  rect.x0 = text->stage_area.x;
+  rect.y0 = text->stage_area.y;
+  rect.x1 = text->stage_area.x + text->stage_area.width;
+  rect.y1 = text->stage_area.y + text->stage_area.height;
 
   if (text->border) {
     rect.x1++;
@@ -200,27 +224,26 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
 {
   static const cairo_matrix_t identity = { 1, 0, 0, 1, 0, 0 };
   SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (movie);
-  SwfdecRectangle area;
   SwfdecColor color;
 
   /* textfields don't mask */
   if (swfdec_color_transform_is_mask (ctrans) ||
-      swfdec_rectangle_is_empty (&text->stage_rect))
+      swfdec_rectangle_is_empty (&text->stage_area))
     return;
 
   /* FIXME: need to handle the case where we're not drawing with identity */
   cairo_set_matrix (cr, &identity);
 
   if (text->background) {
-    cairo_rectangle (cr, text->stage_rect.x, text->stage_rect.y,
-	text->stage_rect.width, text->stage_rect.height);
+    cairo_rectangle (cr, text->stage_area.x, text->stage_area.y,
+	text->stage_area.width, text->stage_area.height);
     color = swfdec_color_apply_transform (text->background_color, ctrans);
     swfdec_color_set_source (cr, SWFDEC_COLOR_OPAQUE (color));
     cairo_fill (cr);
   }
   if (text->border) {
-    cairo_rectangle (cr, text->stage_rect.x + 0.5, text->stage_rect.y + 0.5,
-	text->stage_rect.width, text->stage_rect.height);
+    cairo_rectangle (cr, text->stage_area.x + 0.5, text->stage_area.y + 0.5,
+	text->stage_area.width, text->stage_area.height);
     color = swfdec_color_apply_transform (text->border_color, ctrans);
     swfdec_color_set_source (cr, SWFDEC_COLOR_OPAQUE (color));
     cairo_set_line_width (cr, 1.0);
@@ -228,7 +251,6 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
     cairo_stroke (cr);
   }
 
-  swfdec_text_field_movie_get_visible_area (text, &area);
   if (swfdec_text_field_movie_has_focus (text) &&
       (text->editable ||
        (text->selectable && swfdec_text_buffer_has_selection (text->text)))) {
@@ -243,11 +265,13 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
   }
 
   /* render the layout */
-  cairo_rectangle (cr, area.x, area.y, area.width, area.height);
+  cairo_rectangle (cr, text->layout_area.x, text->layout_area.y, 
+      text->layout_area.width, text->layout_area.height);
   cairo_clip (cr);
-  cairo_translate (cr, (double) area.x - text->hscroll, area.y);
+  /* FIXME: This -1 is spacing? */
+  cairo_translate (cr, (double) text->layout_area.x - text->hscroll, text->layout_area.y - 1);
   swfdec_text_layout_render (text->layout, cr, ctrans,
-      text->scroll, area.height, color);
+      text->scroll, text->layout_area.height, color);
 }
 
 static void
@@ -310,7 +334,7 @@ swfdec_text_field_movie_update_scroll (SwfdecTextFieldMovie *text)
 {
   guint scroll_max, lines_visible, rows, height;
 
-  height = text->stage_rect.height - BORDER_TOP - BORDER_BOTTOM;
+  height = text->layout_area.height;
   rows = swfdec_text_layout_get_n_rows (text->layout);
   scroll_max = rows - swfdec_text_layout_get_visible_rows_end (text->layout, height);
   if (scroll_max != text->scroll_max) {
@@ -499,19 +523,11 @@ static void
 swfdec_text_field_movie_xy_to_index (SwfdecTextFieldMovie *text, double x,
     double y, gsize *index_, gboolean *hit)
 {
-  SwfdecRectangle area;
   int trailing;
-  int stage_x, stage_y;
-
-  stage_x = x * text->xscale / SWFDEC_TWIPS_SCALE_FACTOR;
-  stage_y = y * text->yscale / SWFDEC_TWIPS_SCALE_FACTOR;
-  swfdec_text_field_movie_get_visible_area (text, &area);
-#if 0
-  g_print ("@ %g,%g => %d,%d => %d, %d\n", x, y, stage_x, stage_y,
-      stage_x - area.x, stage_y - area.y);
-#endif
+
+  cairo_matrix_transform_point (&text->to_layout, &x, &y);
   swfdec_text_layout_query_position (text->layout, text->scroll,
-      stage_x, stage_y, index_, hit, &trailing);
+      x - text->layout_area.x, y - text->layout_area.y, index_, hit, &trailing);
 
   if (index_)
     *index_ += trailing;
@@ -1009,46 +1025,17 @@ swfdec_text_field_movie_set_text (SwfdecTextFieldMovie *text, const char *str,
   }
 }
 
-gboolean
-swfdec_text_field_movie_get_visible_area (SwfdecTextFieldMovie *text, SwfdecRectangle *rect)
-{
-  int tmp;
-
-  g_return_val_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text), FALSE);
-  g_return_val_if_fail (rect != NULL, FALSE);
-
-  tmp = round ((BORDER_LEFT + BORDER_RIGHT) * text->xscale);
-  if (tmp >= text->stage_rect.width) {
-    *rect = text->stage_rect;
-    return FALSE;
-  } else {
-    rect->width = text->stage_rect.width - tmp;
-  }
-  tmp = round ((BORDER_TOP + BORDER_BOTTOM) * text->yscale);
-  if (tmp >= text->stage_rect.height) {
-    *rect = text->stage_rect;
-    return FALSE;
-  } else {
-    rect->height = text->stage_rect.height - tmp;
-  }
-  rect->x = text->stage_rect.x + round (BORDER_LEFT * text->xscale);
-  rect->y = text->stage_rect.y + round (BORDER_TOP * text->yscale) - 1;
-  return TRUE;
-}
-
 guint
 swfdec_text_field_movie_get_hscroll_max (SwfdecTextFieldMovie *text)
 {
-  SwfdecRectangle area;
   guint width;
 
   g_return_val_if_fail (SWFDEC_IS_TEXT_FIELD_MOVIE (text), 0);
 
-  swfdec_text_field_movie_get_visible_area (text, &area);
   width = text->layout_width;
-  if ((guint) area.width >= width)
+  if ((guint) text->layout_area.width >= width)
     return 0;
   else
-    return width - area.width;
+    return width - text->layout_area.width;
 }
 
diff --git a/swfdec/swfdec_text_field_movie.h b/swfdec/swfdec_text_field_movie.h
index 5cdae42..98a17ee 100644
--- a/swfdec/swfdec_text_field_movie.h
+++ b/swfdec/swfdec_text_field_movie.h
@@ -44,9 +44,10 @@ struct _SwfdecTextFieldMovie {
   SwfdecActor		actor;
 
   SwfdecRect		extents;	/* original extents (copied from graphic) */
-  double		xscale;		/* scale movie => stage in x direction */
-  double		yscale;		/* scale movie => stage in y direction */
-  SwfdecRectangle	stage_rect;	/* these extents in stage coordinates */
+  cairo_matrix_t	to_layout;	/* matrix to go from movie => layout */
+  cairo_matrix_t	from_layout;	/* matrix to go from layout => movie */
+  SwfdecRectangle	layout_area;	/* layout we render to in stage coordinates */
+  SwfdecRectangle	stage_area;	/* complete size of textfield in stage coordinates */
 
   /* properties copied from textfield */
   gboolean		html;
@@ -112,8 +113,6 @@ void		swfdec_text_field_movie_replace_text	(SwfdecTextFieldMovie *		text,
 							 guint				end_index,
 							 const char *			str);
 
-gboolean	swfdec_text_field_movie_get_visible_area(SwfdecTextFieldMovie *	text,
-							 SwfdecRectangle *	rect);
 guint		swfdec_text_field_movie_get_hscroll_max (SwfdecTextFieldMovie *	text);
 
 /* implemented in swfdec_text_field_movie_as.c */
commit b86e863556ef7012b2d265ae87fa790f6e011433
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri May 23 10:55:31 2008 +0200

    properly set the matrix on creation
    
    We forgot to recalculate the inverse matrix

diff --git a/swfdec/swfdec_text_field_movie_as.c b/swfdec/swfdec_text_field_movie_as.c
index c23be82..b38227c 100644
--- a/swfdec/swfdec_text_field_movie_as.c
+++ b/swfdec/swfdec_text_field_movie_as.c
@@ -427,7 +427,8 @@ swfdec_text_field_movie_get_textHeight (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
-  SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_height / text->yscale));
+  SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_height * 
+	SWFDEC_TWIPS_SCALE_FACTOR * text->from_layout.yy));
 }
 
 static void
@@ -439,7 +440,8 @@ swfdec_text_field_movie_get_textWidth (SwfdecAsContext *cx,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_TEXT_FIELD_MOVIE, &text, "");
 
-  SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_width / text->yscale));
+  SWFDEC_AS_VALUE_SET_INT (ret, floor (text->layout_height *
+	SWFDEC_TWIPS_SCALE_FACTOR * text->from_layout.xx));
 }
 
 /*
@@ -1355,9 +1357,11 @@ swfdec_text_field_movie_createTextField (SwfdecAsContext *cx,
   g_assert (SWFDEC_IS_TEXT_FIELD_MOVIE (movie));
   g_object_unref (edittext);
 
+  swfdec_movie_begin_update_matrix (movie);
   movie->matrix.x0 = SWFDEC_DOUBLE_TO_TWIPS (x);
   movie->matrix.y0 = SWFDEC_DOUBLE_TO_TWIPS (y);
   movie->modified = TRUE;
+  swfdec_movie_end_update_matrix (movie);
 
   swfdec_movie_initialize (movie);
   swfdec_movie_update (movie);
commit 7db7c6656fa29f7d6be82bdd1953460ca2194779
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu May 22 19:17:54 2008 +0200

    add selection getting code
    
    And use it in the gtk player so we can set PRIMARY

diff --git a/swfdec-gtk/swfdec_gtk_widget.c b/swfdec-gtk/swfdec_gtk_widget.c
index c533c79..f23a4fb 100644
--- a/swfdec-gtk/swfdec_gtk_widget.c
+++ b/swfdec-gtk/swfdec_gtk_widget.c
@@ -735,6 +735,13 @@ swfdec_gtk_widget_notify_cb (SwfdecPlayer *player, GParamSpec *pspec, SwfdecGtkW
     swfdec_gtk_widget_do_fullscreen (widget, swfdec_player_get_fullscreen (player));
   } else if (g_str_equal (pspec->name, "background-color")) {
     swfdec_gtk_widget_update_background (widget);
+  } else if (g_str_equal (pspec->name, "selection")) {
+    const char *text = swfdec_player_get_selection (player);
+    if (GTK_WIDGET_HAS_FOCUS (widget) && text) {
+      GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (widget),
+	  GDK_SELECTION_PRIMARY);
+      gtk_clipboard_set_text (clipboard, text, -1);
+    }
   }
 }
 
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 27a8ee9..c06537c 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -673,7 +673,8 @@ enum {
   PROP_FOCUS,
   PROP_RENDERER,
   PROP_FULLSCREEN,
-  PROP_ALLOW_FULLSCREEN
+  PROP_ALLOW_FULLSCREEN,
+  PROP_SELECTION
 };
 
 G_DEFINE_TYPE (SwfdecPlayer, swfdec_player, SWFDEC_TYPE_AS_CONTEXT)
@@ -805,6 +806,9 @@ swfdec_player_get_property (GObject *object, guint param_id, GValue *value,
     case PROP_ALLOW_FULLSCREEN:
       g_value_set_boolean (value, priv->allow_fullscreen);
       break;
+    case PROP_SELECTION:
+      g_value_set_string (value, priv->selection);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -1945,6 +1949,35 @@ swfdec_player_update_focusrect (SwfdecPlayer *player)
   swfdec_player_invalidate (player, &priv->focusrect);
 }
 
+static void
+swfdec_player_update_selection (SwfdecPlayer *player)
+{
+  SwfdecPlayerPrivate *priv = player->priv;
+
+  if (SWFDEC_IS_TEXT_FIELD_MOVIE (priv->focus)) {
+    SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (priv->focus);
+    gsize start, end;
+    swfdec_text_buffer_get_selection (text->text, &start, &end);
+    if (start != end) {
+      const char *s = swfdec_text_buffer_get_text (text->text);
+      if (priv->selection != NULL &&
+	  priv->selection[end - start] == '\0' &&
+	  strncmp (s + start, priv->selection, end - start) == 0)
+	return;
+      g_free (priv->selection);
+      priv->selection = g_strndup (s + start, end - start);
+      g_object_notify (G_OBJECT (player), "selection");
+      return;
+    }
+  }
+  /* only possible if both are NULL */
+  if (priv->selection == NULL)
+    return;
+  g_free (priv->selection);
+  priv->selection = NULL;
+  g_object_notify (G_OBJECT (player), "selection");
+}
+
 /* used for breakpoints */
 void
 swfdec_player_unlock_soft (SwfdecPlayer *player)
@@ -1957,6 +1990,7 @@ swfdec_player_unlock_soft (SwfdecPlayer *player)
   swfdec_player_update_movies (player);
   swfdec_player_update_mouse_cursor (player);
   swfdec_player_update_focusrect (player);
+  swfdec_player_update_selection (player);
   g_object_thaw_notify (G_OBJECT (player));
   swfdec_player_emit_signals (player);
   player->priv->locked = FALSE;
@@ -2122,6 +2156,9 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
       g_param_spec_boolean ("allow-fullscreen", "allow fullscreen", 
 	  "if the player is allowed to change into fullscreen mode",
 	  FALSE, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_SELECTION,
+      g_param_spec_string ("selection", "selection", "currently selected text",
+	  NULL, G_PARAM_READABLE));
 
   /**
    * SwfdecPlayer::invalidate:
@@ -3805,3 +3842,19 @@ swfdec_player_set_allow_fullscreen (SwfdecPlayer *player, gboolean allow)
   g_object_notify (G_OBJECT (player), "allow-fullscreen");
 }
 
+/**
+ * swfdec_player_get_selection:
+ * @player: the player
+ *
+ * Retrieves the currently selected text of the player. If no text is currently
+ * selected, %NULL is returned.
+ *
+ * Returns: the currently selected text or %NULL
+ **/
+const char *
+swfdec_player_get_selection (SwfdecPlayer *player)
+{
+  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+
+  return player->priv->selection;
+}
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index 9855a47..080d387 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -143,6 +143,7 @@ SwfdecPlayerScripting *
 		swfdec_player_get_scripting	(SwfdecPlayer *		player);
 void		swfdec_player_set_scripting	(SwfdecPlayer *		player,
 						 SwfdecPlayerScripting *scripting);
+const char *	swfdec_player_get_selection	(SwfdecPlayer *		player);
 gboolean	swfdec_player_get_focus		(SwfdecPlayer *		player);
 void		swfdec_player_set_focus		(SwfdecPlayer *		player,
 						 gboolean		focus);
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index 4fe3dc4..2eee43e 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -82,6 +82,7 @@ struct _SwfdecPlayerPrivate
   GType			socket_type;		/* type to use for creating sockets */
   gboolean		has_focus;		/* TRUE if this movie is given focus */
   gboolean		allow_fullscreen;	/* TRUE if this movie may go fullscreen */
+  char *		selection;		/* selected string or %NULL if none */
   /* stage properties */
   guint			internal_width;		/* width used by the scripting engine */
   guint			internal_height;	/* height used by the scripting engine */


More information about the Swfdec-commits mailing list