[Swfdec] 12 commits - libswfdec/Makefile.am
libswfdec/swfdec_audio_flv.c libswfdec/swfdec_flv_decoder.c
libswfdec/swfdec_js.c libswfdec/swfdec_js.h
libswfdec/swfdec_js_video.c libswfdec/swfdec_loader.c
libswfdec/swfdec_loader_internal.h
libswfdec/swfdec_loadertarget.c libswfdec/swfdec_net_stream.c
libswfdec/swfdec_net_stream.h libswfdec/swfdec_player.c
libswfdec/swfdec_root_movie.c libswfdec/swfdec_video.c
libswfdec/swfdec_video_movie.c libswfdec/swfdec_video_movie.h
Benjamin Otte
company at kemper.freedesktop.org
Fri Mar 2 14:33:13 PST 2007
libswfdec/Makefile.am | 1
libswfdec/swfdec_audio_flv.c | 4 -
libswfdec/swfdec_flv_decoder.c | 60 ++++++++++++++++---
libswfdec/swfdec_js.c | 1
libswfdec/swfdec_js.h | 1
libswfdec/swfdec_js_video.c | 114 +++++++++++++++++++++++++++++++++++++
libswfdec/swfdec_loader.c | 21 ++++++
libswfdec/swfdec_loader_internal.h | 1
libswfdec/swfdec_loadertarget.c | 18 ++++-
libswfdec/swfdec_net_stream.c | 36 +++++++----
libswfdec/swfdec_net_stream.h | 1
libswfdec/swfdec_player.c | 1
libswfdec/swfdec_root_movie.c | 30 +++------
libswfdec/swfdec_video.c | 63 ++++++++------------
libswfdec/swfdec_video_movie.c | 64 +++++++++++++++-----
libswfdec/swfdec_video_movie.h | 21 ++++--
16 files changed, 333 insertions(+), 104 deletions(-)
New commits:
diff-tree f3b5a7ee8d8516b94c160a3c67dca971ab8065f3 (from e5f35b0679044288cadd72bf14617c145af687ea)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 23:32:56 2007 +0100
fix video scaling is correct
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 078ed49..b524725 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -67,15 +67,15 @@ swfdec_net_stream_video_goto (SwfdecNetS
CAIRO_FORMAT_ARGB32, w, h, w * 4);
cairo_surface_set_user_data (stream->surface, &key,
decoded, (cairo_destroy_func_t) swfdec_buffer_unref);
+ if (old != stream->surface) {
+ GList *walk;
+ for (walk = stream->movies; walk; walk = walk->next) {
+ swfdec_video_movie_new_image (walk->data, stream->surface, w, h);
+ }
+ }
}
}
}
- if (old != stream->surface) {
- GList *walk;
- for (walk = stream->movies; walk; walk = walk->next) {
- swfdec_video_movie_new_image (walk->data, stream->surface);
- }
- }
}
static void
diff --git a/libswfdec/swfdec_video.c b/libswfdec/swfdec_video.c
index e67be19..bf6b460 100644
--- a/libswfdec/swfdec_video.c
+++ b/libswfdec/swfdec_video.c
@@ -91,7 +91,7 @@ swfdec_video_input_iterate (SwfdecVideoM
CAIRO_FORMAT_ARGB32, w, h, w * 4);
cairo_surface_set_user_data (surface, &key,
buffer, (cairo_destroy_func_t) swfdec_buffer_unref);
- swfdec_video_movie_new_image (input->movie, surface);
+ swfdec_video_movie_new_image (input->movie, surface, w, h);
cairo_surface_destroy (surface);
}
diff --git a/libswfdec/swfdec_video_movie.c b/libswfdec/swfdec_video_movie.c
index 49e1f4d..cf74a92 100644
--- a/libswfdec/swfdec_video_movie.c
+++ b/libswfdec/swfdec_video_movie.c
@@ -46,7 +46,9 @@ swfdec_video_movie_render (SwfdecMovie *
if (movie->image == NULL)
return;
- cairo_scale (cr, SWFDEC_TWIPS_SCALE_FACTOR, SWFDEC_TWIPS_SCALE_FACTOR);
+ cairo_scale (cr,
+ (mov->original_extents.x1 - mov->original_extents.x0) / movie->image_width,
+ (mov->original_extents.y1 - mov->original_extents.y0) / movie->image_height);
cairo_set_source_surface (cr, movie->image, 0.0, 0.0);
cairo_paint (cr);
}
@@ -140,15 +142,20 @@ swfdec_video_movie_clear (SwfdecVideoMov
}
void
-swfdec_video_movie_new_image (SwfdecVideoMovie *movie, cairo_surface_t *image)
+swfdec_video_movie_new_image (SwfdecVideoMovie *movie, cairo_surface_t *image,
+ guint width, guint height)
{
g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
g_return_if_fail (image != NULL);
+ g_return_if_fail (width > 0);
+ g_return_if_fail (height > 0);
if (movie->image)
cairo_surface_destroy (movie->image);
cairo_surface_reference (image);
movie->image = image;
+ movie->image_width = width;
+ movie->image_height = height;
swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
}
diff --git a/libswfdec/swfdec_video_movie.h b/libswfdec/swfdec_video_movie.h
index 9db5d45..87ee9c9 100644
--- a/libswfdec/swfdec_video_movie.h
+++ b/libswfdec/swfdec_video_movie.h
@@ -54,7 +54,9 @@ struct _SwfdecVideoMovie {
SwfdecVideo * video; /* video we play back */
SwfdecVideoMovieInput *input; /* where we take the input from */
- cairo_surface_t * image; /* TRUE if cleared */
+ cairo_surface_t * image; /* current image or NULL */
+ guint image_width; /* width of current image */
+ guint image_height; /* height of current image */
};
struct _SwfdecVideoMovieClass {
@@ -68,7 +70,9 @@ void swfdec_video_movie_set_input (Swf
void swfdec_video_movie_clear (SwfdecVideoMovie * movie);
/* API for SwfdecVideoMovieInput */
void swfdec_video_movie_new_image (SwfdecVideoMovie * movie,
- cairo_surface_t * surface);
+ cairo_surface_t * surface,
+ guint width,
+ guint height);
G_END_DECLS
#endif
diff-tree e5f35b0679044288cadd72bf14617c145af687ea (from 3631478784432ef1912bd12656721d3bbf3cf29f)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 22:52:14 2007 +0100
unref connection and stream after setting them
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index 831641f..da311d4 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -517,6 +517,8 @@ swfdec_flv_decoder_add_movie (SwfdecFlvD
}
swfdec_video_movie_set_input (SWFDEC_VIDEO_MOVIE (movie), &stream->input);
swfdec_net_stream_set_playing (stream, TRUE);
+ g_object_unref (conn);
+ g_object_unref (stream);
return movie;
}
diff-tree 3631478784432ef1912bd12656721d3bbf3cf29f (from 70509b76bb54d5973f2c01de07a47a9f02f95900)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 22:51:56 2007 +0100
make swfdec_flv_decoder_get_video/audio more robust
- handle case where there's no audio/video available yet
- first timestamp will always be 0 in both audio and video streams
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index 31834a2..831641f 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -392,22 +392,33 @@ SwfdecBuffer *
swfdec_flv_decoder_get_video (SwfdecFlvDecoder *flv, guint timestamp,
gboolean keyframe, SwfdecVideoFormat *format, guint *real_timestamp, guint *next_timestamp)
{
- guint id;
+ guint id, offset;
SwfdecFlvVideoTag *tag;
g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), NULL);
g_return_val_if_fail (flv->video != NULL, NULL);
+ if (flv->video->len == 0) {
+ if (next_timestamp)
+ *next_timestamp = 0;
+ if (real_timestamp)
+ *real_timestamp = 0;
+ if (format)
+ *format = SWFDEC_VIDEO_FORMAT_UNDEFINED;
+ return NULL;
+ }
+ offset = g_array_index (flv->video, SwfdecFlvVideoTag, 0).timestamp;
+ timestamp += offset;
id = swfdec_flv_decoder_find_video (flv, timestamp);
if (next_timestamp) {
if (id + 1 >= flv->video->len)
*next_timestamp = 0;
else
- *next_timestamp = g_array_index (flv->video, SwfdecFlvVideoTag, id + 1).timestamp;
+ *next_timestamp = g_array_index (flv->video, SwfdecFlvVideoTag, id + 1).timestamp - offset;
}
tag = &g_array_index (flv->video, SwfdecFlvVideoTag, id);
if (real_timestamp)
- *real_timestamp = tag->timestamp;
+ *real_timestamp = tag->timestamp - offset;
if (format)
*format = tag->format;
return tag->buffer;
@@ -418,22 +429,37 @@ swfdec_flv_decoder_get_audio (SwfdecFlvD
SwfdecAudioFormat *codec_format, gboolean *width, SwfdecAudioOut *format,
guint *real_timestamp, guint *next_timestamp)
{
- guint id;
+ guint id, offset;
SwfdecFlvAudioTag *tag;
g_return_val_if_fail (SWFDEC_IS_FLV_DECODER (flv), NULL);
g_return_val_if_fail (flv->audio != NULL, NULL);
+ if (flv->audio->len == 0) {
+ if (next_timestamp)
+ *next_timestamp = 0;
+ if (real_timestamp)
+ *real_timestamp = 0;
+ if (codec_format)
+ *codec_format = SWFDEC_AUDIO_FORMAT_UNDEFINED;
+ if (width)
+ *width = TRUE;
+ if (format)
+ *format = SWFDEC_AUDIO_OUT_STEREO_44100;
+ return NULL;
+ }
+ offset = g_array_index (flv->audio, SwfdecFlvAudioTag, 0).timestamp;
+ timestamp += offset;
id = swfdec_flv_decoder_find_audio (flv, timestamp);
if (next_timestamp) {
if (id + 1 >= flv->audio->len)
*next_timestamp = 0;
else
- *next_timestamp = g_array_index (flv->audio, SwfdecFlvAudioTag, id + 1).timestamp;
+ *next_timestamp = g_array_index (flv->audio, SwfdecFlvAudioTag, id + 1).timestamp - offset;
}
tag = &g_array_index (flv->audio, SwfdecFlvAudioTag, id);
if (real_timestamp)
- *real_timestamp = tag->timestamp;
+ *real_timestamp = tag->timestamp - offset;
if (codec_format)
*codec_format = tag->format;
if (width)
diff-tree 70509b76bb54d5973f2c01de07a47a9f02f95900 (from b7f4a1999efefba72f607472672ab97f910f32b8)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 22:49:53 2007 +0100
use swfdec_loader_queue_parse() here, too
- remove leftover g_print debugging
- fixup stuff that was broken due to missing parsing
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 4ca99ed..078ed49 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -104,7 +104,6 @@ swfdec_net_stream_update_playing (Swfdec
should_play &= stream->next_time > stream->current_time;
if (should_play && stream->timeout.callback == NULL) {
SWFDEC_DEBUG ("starting playback");
- g_print ("starting playback\n");
stream->timeout.callback = swfdec_net_stream_timeout;
stream->timeout.timestamp = stream->player->time + SWFDEC_MSECS_TO_TICKS (stream->next_time - stream->current_time);
swfdec_player_add_timeout (stream->player, &stream->timeout);
@@ -116,7 +115,6 @@ swfdec_net_stream_update_playing (Swfdec
SWFDEC_LOG ("no audio");
}
} else if (!should_play && stream->timeout.callback != NULL) {
- g_print ("stopping playback\n");
if (stream->audio) {
SWFDEC_LOG ("stopping audio");
swfdec_audio_remove (stream->audio);
@@ -147,11 +145,14 @@ static gboolean
swfdec_net_stream_loader_target_set_decoder (SwfdecLoaderTarget *target,
SwfdecDecoder *decoder)
{
+ SwfdecNetStream *stream = SWFDEC_NET_STREAM (target);
+
if (!SWFDEC_IS_FLV_DECODER (decoder)) {
g_object_unref (decoder);
return FALSE;
}
- SWFDEC_NET_STREAM (target)->flvdecoder = SWFDEC_FLV_DECODER (decoder);
+ stream->flvdecoder = SWFDEC_FLV_DECODER (decoder);
+ swfdec_net_stream_update_playing (stream);
return TRUE;
}
@@ -297,6 +298,7 @@ swfdec_net_stream_set_loader (SwfdecNetS
if (loader) {
g_object_ref (loader);
swfdec_loader_set_target (loader, SWFDEC_LOADER_TARGET (stream));
+ swfdec_loader_queue_parse (loader);
}
swfdec_net_stream_set_playing (stream, TRUE);
}
diff-tree b7f4a1999efefba72f607472672ab97f910f32b8 (from 38b78d92441c87d12b7a9c42eb23cb949cd24408)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 22:49:03 2007 +0100
use swfdec_loader_queue_parse here
diff --git a/libswfdec/swfdec_root_movie.c b/libswfdec/swfdec_root_movie.c
index fb41b82..707f3b4 100644
--- a/libswfdec/swfdec_root_movie.c
+++ b/libswfdec/swfdec_root_movie.c
@@ -170,12 +170,6 @@ swfdec_root_movie_init (SwfdecRootMovie
}
void
-swfdec_root_movie_do_parse (gpointer movie, gpointer unused)
-{
- swfdec_loader_target_parse (SWFDEC_LOADER_TARGET (movie), SWFDEC_ROOT_MOVIE (movie)->loader);
-}
-
-void
swfdec_root_movie_load (SwfdecRootMovie *root, const char *url, const char *target)
{
g_return_if_fail (SWFDEC_IS_ROOT_MOVIE (root));
@@ -196,9 +190,8 @@ swfdec_root_movie_load (SwfdecRootMovie
} else {
SwfdecLoader *loader = swfdec_loader_load (root->loader, url);
if (loader) {
- SwfdecRootMovie *added = swfdec_player_add_level_from_loader (root->player, depth, loader, NULL);
- swfdec_player_add_action (root->player, SWFDEC_MOVIE (added),
- swfdec_root_movie_do_parse, NULL);
+ swfdec_player_add_level_from_loader (root->player, depth, loader, NULL);
+ swfdec_loader_queue_parse (loader);
} else {
SWFDEC_WARNING ("didn't get a loader for url \"%s\" at depth %u", url, depth);
}
diff-tree 38b78d92441c87d12b7a9c42eb23cb949cd24408 (from 896b69f6d5f7211d8d08c9634d66a839c003289f)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 22:48:41 2007 +0100
reset decoder to NULL in error case
diff --git a/libswfdec/swfdec_audio_flv.c b/libswfdec/swfdec_audio_flv.c
index 4544a20..f829fd5 100644
--- a/libswfdec/swfdec_audio_flv.c
+++ b/libswfdec/swfdec_audio_flv.c
@@ -88,8 +88,10 @@ next:
flv->next_timestamp = soon;
if (flv->in == 0) {
/* init */
- if (flv->decoder)
+ if (flv->decoder) {
swfdec_audio_codec_finish (flv->codec, flv->decoder);
+ flv->decoder = NULL;
+ }
flv->format = format;
flv->width = width;
flv->in = in;
diff-tree 896b69f6d5f7211d8d08c9634d66a839c003289f (from e963f3024e9b1e07a381d22defbc9e5da7e31834)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 22:47:48 2007 +0100
new function swfdec_loader_queue_parse()
use the hack from last commit here
diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 32d0ca4..8a5568f 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -245,6 +245,27 @@ swfdec_loader_set_target (SwfdecLoader *
loader->target = target;
}
+static void
+swfdec_loader_do_parse (gpointer empty, gpointer loaderp)
+{
+ SwfdecLoader *loader = SWFDEC_LOADER (loaderp);
+
+ swfdec_loader_target_parse (loader->target, loader);
+}
+
+void
+swfdec_loader_queue_parse (SwfdecLoader *loader)
+{
+ SwfdecPlayer *player;
+
+ g_return_if_fail (SWFDEC_IS_LOADER (loader));
+ g_return_if_fail (loader->target != NULL);
+
+ player = swfdec_loader_target_get_player (loader->target);
+ /* HACK: using player as action object makes them get auto-removed */
+ swfdec_player_add_action (player, player, swfdec_loader_do_parse, loader);
+}
+
/** PUBLIC API ***/
/**
diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h
index 3c99959..7d5aaef 100644
--- a/libswfdec/swfdec_loader_internal.h
+++ b/libswfdec/swfdec_loader_internal.h
@@ -29,6 +29,7 @@ G_BEGIN_DECLS
SwfdecLoader * swfdec_loader_load (SwfdecLoader * loader,
const char * url);
void swfdec_loader_parse (SwfdecLoader * loader);
+void swfdec_loader_queue_parse (SwfdecLoader * loader);
void swfdec_loader_set_target (SwfdecLoader * loader,
SwfdecLoaderTarget * target);
void swfdec_loader_error_locked (SwfdecLoader * loader,
diff-tree e963f3024e9b1e07a381d22defbc9e5da7e31834 (from f39596ffc3e8d4f72da538f822f174390bbdf751)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 22:47:25 2007 +0100
Add a hack to allow adding actions that get executed "no matter what"
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 6de320b..81d06fa 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -358,6 +358,7 @@ swfdec_player_dispose (GObject *object)
swfdec_js_finish_player (player);
+ swfdec_player_remove_all_actions (player, player); /* HACK to allow non-removable actions */
g_assert (swfdec_ring_buffer_pop (player->actions) == NULL);
swfdec_ring_buffer_free (player->actions);
g_assert (player->movies == NULL);
diff-tree f39596ffc3e8d4f72da538f822f174390bbdf751 (from b0cf46e2bf75776ea6c5729c6996d8924c13e126)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 21:04:34 2007 +0100
fix how we handle FLV streams so it works with modified SwfdecLoaderTarget
It's still a huge hack
diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index b5640f7..31834a2 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -452,6 +452,17 @@ swfdec_flv_decoder_get_audio (SwfdecFlvD
#include "swfdec_root_movie.h"
#include "swfdec_sprite.h"
#include "swfdec_video_movie.h"
+
+static void
+notify_initialized (SwfdecPlayer *player, GParamSpec *pspec, SwfdecVideoMovie *movie)
+{
+ movie->video->width = player->width;
+ movie->video->height = player->height;
+
+ swfdec_movie_queue_update (SWFDEC_MOVIE (movie), SWFDEC_MOVIE_INVALID_MATRIX);
+ swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
+}
+
SwfdecMovie *
swfdec_flv_decoder_add_movie (SwfdecFlvDecoder *flv, SwfdecMovie *parent)
{
@@ -463,18 +474,19 @@ swfdec_flv_decoder_add_movie (SwfdecFlvD
/* set up the video movie */
video = g_object_new (SWFDEC_TYPE_VIDEO, NULL);
- video->width = SWFDEC_DECODER (flv)->width;
- video->height = SWFDEC_DECODER (flv)->height;
+ video->width = G_MAXUINT;
+ video->height = G_MAXUINT;
content->graphic = SWFDEC_GRAPHIC (video);
movie = swfdec_movie_new (parent, content);
g_object_weak_ref (G_OBJECT (movie), (GWeakNotify) swfdec_content_free, content);
g_object_weak_ref (G_OBJECT (movie), (GWeakNotify) g_object_unref, video);
+ g_signal_connect (SWFDEC_ROOT_MOVIE (parent)->player, "notify::initialized",
+ G_CALLBACK (notify_initialized), movie);
/* set up the playback stream */
conn = swfdec_connection_new (SWFDEC_ROOT_MOVIE (parent)->player->jscx);
stream = swfdec_net_stream_new (SWFDEC_ROOT_MOVIE (parent)->player, conn);
swfdec_net_stream_set_loader (stream, SWFDEC_ROOT_MOVIE (parent)->loader);
- g_object_ref (SWFDEC_ROOT_MOVIE (parent)->decoder);
- if (!swfdec_loader_target_set_decoder (SWFDEC_LOADER_TARGET (stream), SWFDEC_ROOT_MOVIE (parent)->decoder)) {
+ if (!swfdec_loader_target_set_decoder (SWFDEC_LOADER_TARGET (stream), SWFDEC_DECODER (flv))) {
g_assert_not_reached ();
}
swfdec_video_movie_set_input (SWFDEC_VIDEO_MOVIE (movie), &stream->input);
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 2a0b897..4ca99ed 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -34,7 +34,7 @@ swfdec_net_stream_video_goto (SwfdecNetS
SwfdecVideoFormat format;
cairo_surface_t *old;
- SWFDEC_LOG ("goto %ums\n", timestamp);
+ SWFDEC_LOG ("goto %ums", timestamp);
buffer = swfdec_flv_decoder_get_video (stream->flvdecoder, timestamp,
FALSE, &format, &stream->current_time, &stream->next_time);
old = stream->surface;
@@ -104,6 +104,7 @@ swfdec_net_stream_update_playing (Swfdec
should_play &= stream->next_time > stream->current_time;
if (should_play && stream->timeout.callback == NULL) {
SWFDEC_DEBUG ("starting playback");
+ g_print ("starting playback\n");
stream->timeout.callback = swfdec_net_stream_timeout;
stream->timeout.timestamp = stream->player->time + SWFDEC_MSECS_TO_TICKS (stream->next_time - stream->current_time);
swfdec_player_add_timeout (stream->player, &stream->timeout);
@@ -115,6 +116,7 @@ swfdec_net_stream_update_playing (Swfdec
SWFDEC_LOG ("no audio");
}
} else if (!should_play && stream->timeout.callback != NULL) {
+ g_print ("stopping playback\n");
if (stream->audio) {
SWFDEC_LOG ("stopping audio");
swfdec_audio_remove (stream->audio);
@@ -285,9 +287,8 @@ swfdec_net_stream_set_loader (SwfdecNetS
g_return_if_fail (SWFDEC_IS_NET_STREAM (stream));
g_return_if_fail (loader == NULL || SWFDEC_IS_LOADER (loader));
- if (stream->loader) {
+ if (stream->loader)
g_object_unref (stream->loader);
- }
if (stream->flvdecoder) {
g_object_unref (stream->flvdecoder);
stream->flvdecoder = NULL;
diff --git a/libswfdec/swfdec_root_movie.c b/libswfdec/swfdec_root_movie.c
index 1b7c264..fb41b82 100644
--- a/libswfdec/swfdec_root_movie.c
+++ b/libswfdec/swfdec_root_movie.c
@@ -57,7 +57,15 @@ static gboolean
swfdec_root_movie_loader_target_set_decoder (SwfdecLoaderTarget *target,
SwfdecDecoder *decoder)
{
- SWFDEC_ROOT_MOVIE (target)->decoder = decoder;
+ if (SWFDEC_IS_FLV_DECODER (decoder)) {
+ swfdec_flv_decoder_add_movie (SWFDEC_FLV_DECODER (decoder),
+ SWFDEC_MOVIE (target));
+ } else if (SWFDEC_IS_SWF_DECODER (decoder)) {
+ SWFDEC_ROOT_MOVIE (target)->decoder = decoder;
+ } else {
+ g_object_unref (decoder);
+ return FALSE;
+ }
return TRUE;
}
@@ -66,19 +74,12 @@ swfdec_root_movie_loader_target_do_init
{
SwfdecRootMovie *movie = SWFDEC_ROOT_MOVIE (target);
- swfdec_player_initialize (movie->player, movie->decoder->rate,
- movie->decoder->width, movie->decoder->height);
- if (SWFDEC_IS_SWF_DECODER (movie->decoder) &&
- movie->player->roots->next == 0) {
+ if (movie->player->roots->next == 0) {
/* if we're the only child */
/* FIXME: check case sensitivity wrt embedding movies of different version */
JS_SetContextCaseSensitive (movie->player->jscx,
SWFDEC_SWF_DECODER (movie->decoder)->version > 6);
}
- if (SWFDEC_IS_FLV_DECODER (movie->decoder)) {
- swfdec_flv_decoder_add_movie (SWFDEC_FLV_DECODER (movie->decoder),
- SWFDEC_MOVIE (movie));
- }
return TRUE;
}
diff-tree b0cf46e2bf75776ea6c5729c6996d8924c13e126 (from 6999042e149d403d64d3f16126d9840518a5afc7)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 21:01:18 2007 +0100
fix default parser
- reread target after setting the decoder, the target might change
- initialize player when decoder returns INIT
diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c
index 6af5504..5a25f1a 100644
--- a/libswfdec/swfdec_loadertarget.c
+++ b/libswfdec/swfdec_loadertarget.c
@@ -23,6 +23,7 @@
#include "swfdec_loadertarget.h"
#include "swfdec_loader_internal.h"
+#include "swfdec_player_internal.h"
static void
swfdec_loader_target_base_init (gpointer g_class)
@@ -95,6 +96,7 @@ swfdec_loader_target_parse_default (Swfd
swfdec_loader_error_locked (loader, "Internal error");
return;
}
+ target = loader->target;
}
klass = SWFDEC_DECODER_GET_CLASS (dec);
g_return_if_fail (klass->parse);
@@ -115,11 +117,17 @@ swfdec_loader_target_parse_default (Swfd
}
break;
case SWFDEC_STATUS_INIT:
- g_assert (dec->width > 0);
- g_assert (dec->height > 0);
- if (!swfdec_loader_target_init (target)) {
- swfdec_loader_error_locked (loader, "Internal error");
- return;
+ {
+ SwfdecPlayer *player;
+ player = swfdec_loader_target_get_player (target);
+ g_assert (dec->width > 0);
+ g_assert (dec->height > 0);
+ swfdec_player_initialize (player, dec->rate,
+ dec->width, dec->height);
+ if (!swfdec_loader_target_init (target)) {
+ swfdec_loader_error_locked (loader, "Internal error");
+ return;
+ }
}
break;
case SWFDEC_STATUS_EOF:
diff-tree 6999042e149d403d64d3f16126d9840518a5afc7 (from de1c2f0273dadc8e74161d157511bb0b6b59d823)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 09:57:14 2007 +0100
add Video class
diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 68cdbbf..cce0bbc 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -54,6 +54,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
swfdec_js_movie.c \
swfdec_js_net_stream.c \
swfdec_js_sound.c \
+ swfdec_js_video.c \
swfdec_js_xml.c \
swfdec_listener.c \
swfdec_loader.c \
diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c
index e26e33d..ce68144 100644
--- a/libswfdec/swfdec_js.c
+++ b/libswfdec/swfdec_js.c
@@ -112,6 +112,7 @@ swfdec_js_init_player (SwfdecPlayer *pla
swfdec_js_add_movieclip_class (player);
swfdec_js_add_color (player);
swfdec_js_add_sound (player);
+ swfdec_js_add_video (player);
swfdec_js_add_xml (player);
swfdec_js_add_connection (player);
swfdec_js_add_net_stream (player);
diff --git a/libswfdec/swfdec_js.h b/libswfdec/swfdec_js.h
index 6c5b804..f32374b 100644
--- a/libswfdec/swfdec_js.h
+++ b/libswfdec/swfdec_js.h
@@ -44,6 +44,7 @@ void swfdec_js_add_mouse (SwfdecPlayer
void swfdec_js_add_movieclip_class (SwfdecPlayer * player);
void swfdec_js_add_net_stream (SwfdecPlayer * player);
void swfdec_js_add_sound (SwfdecPlayer * player);
+void swfdec_js_add_video (SwfdecPlayer * player);
void swfdec_js_add_xml (SwfdecPlayer * player);
void swfdec_js_movie_add_property (SwfdecMovie * movie);
diff --git a/libswfdec/swfdec_js_video.c b/libswfdec/swfdec_js_video.c
new file mode 100644
index 0000000..db2e64f
--- /dev/null
+++ b/libswfdec/swfdec_js_video.c
@@ -0,0 +1,114 @@
+/* Swfdec
+ * Copyright (C) 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 "swfdec_video.h"
+#include "swfdec_debug.h"
+#include "swfdec_js.h"
+#include "swfdec_net_stream.h"
+#include "swfdec_player_internal.h"
+
+static JSBool
+swfdec_js_video_attach_video (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ SwfdecNetStream *stream;
+ SwfdecVideoMovie *video;
+
+ video = swfdec_scriptable_from_object (cx, obj, SWFDEC_TYPE_VIDEO_MOVIE);
+ if (video == NULL)
+ return JS_TRUE;
+
+ stream = swfdec_scriptable_from_jsval (cx, argv[0], SWFDEC_TYPE_NET_STREAM);
+ if (stream != NULL) {
+ swfdec_video_movie_set_input (video, &stream->input);
+ return JS_TRUE;
+ }
+ swfdec_video_movie_set_input (video, NULL);
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_js_video_clear (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ SwfdecVideoMovie *video;
+
+ video = swfdec_scriptable_from_object (cx, obj, SWFDEC_TYPE_VIDEO_MOVIE);
+ if (video == NULL)
+ return JS_TRUE;
+
+ swfdec_video_movie_clear (video);
+ return JS_TRUE;
+}
+
+static JSBool
+swfdec_js_video_to_string (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ JSString *string;
+
+ string = JS_InternString (cx, "[object Object]");
+ if (string == NULL)
+ return JS_FALSE;
+
+ *rval = STRING_TO_JSVAL (string);
+ return JS_TRUE;
+}
+
+static JSFunctionSpec video_methods[] = {
+ { "attachVideo", swfdec_js_video_attach_video, 1, 0, 0 },
+ { "clear", swfdec_js_video_clear, 0, 0, 0 },
+ { "toString", swfdec_js_video_to_string, 0, 0, 0 },
+ {0,0,0,0,0}
+};
+
+static void
+swfdec_js_video_finalize (JSContext *cx, JSObject *obj)
+{
+ SwfdecVideo *video;
+
+ video = JS_GetPrivate (cx, obj);
+ if (video) {
+ SWFDEC_SCRIPTABLE (video)->jsobj = NULL;
+ g_object_unref (video);
+ }
+}
+
+const JSClass video_class = {
+ "Video", JSCLASS_HAS_PRIVATE,
+ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, swfdec_js_video_finalize,
+ JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+static JSBool
+swfdec_js_video_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ return JS_TRUE;
+}
+
+void
+swfdec_js_add_video (SwfdecPlayer *player)
+{
+ JS_InitClass (player->jscx, player->jsobj, NULL,
+ &video_class, swfdec_js_video_new, 0, NULL, video_methods,
+ NULL, NULL);
+}
+
diff-tree de1c2f0273dadc8e74161d157511bb0b6b59d823 (from 7e865ad995f10d135ac60a20d725fb81e5c68372)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Mar 2 09:56:56 2007 +0100
rework video embedding API
It now only has the functions connect() and disconnect()
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index b6f15e8..2a0b897 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -32,10 +32,12 @@ swfdec_net_stream_video_goto (SwfdecNetS
{
SwfdecBuffer *buffer;
SwfdecVideoFormat format;
+ cairo_surface_t *old;
SWFDEC_LOG ("goto %ums\n", timestamp);
buffer = swfdec_flv_decoder_get_video (stream->flvdecoder, timestamp,
FALSE, &format, &stream->current_time, &stream->next_time);
+ old = stream->surface;
if (stream->surface) {
cairo_surface_destroy (stream->surface);
stream->surface = NULL;
@@ -68,8 +70,12 @@ swfdec_net_stream_video_goto (SwfdecNetS
}
}
}
- if (stream->input.movie)
- swfdec_movie_invalidate (SWFDEC_MOVIE (stream->input.movie));
+ if (old != stream->surface) {
+ GList *walk;
+ for (walk = stream->movies; walk; walk = walk->next) {
+ swfdec_video_movie_new_image (walk->data, stream->surface);
+ }
+ }
}
static void
@@ -182,19 +188,21 @@ swfdec_net_stream_loader_target_init (Sw
/*** SWFDEC VIDEO MOVIE INPUT ***/
-static cairo_surface_t *
-swfdec_net_stream_input_get_image (SwfdecVideoMovieInput *input)
+static void
+swfdec_net_stream_input_connect (SwfdecVideoMovieInput *input, SwfdecVideoMovie *movie)
{
SwfdecNetStream *stream = SWFDEC_NET_STREAM ((guchar *) input - G_STRUCT_OFFSET (SwfdecNetStream, input));
- return stream->surface;
+ stream->movies = g_list_prepend (stream->movies, movie);
+ g_object_ref (stream);
}
static void
-swfdec_net_stream_input_finalize (SwfdecVideoMovieInput *input)
+swfdec_net_stream_input_disconnect (SwfdecVideoMovieInput *input, SwfdecVideoMovie *movie)
{
SwfdecNetStream *stream = SWFDEC_NET_STREAM ((guchar *) input - G_STRUCT_OFFSET (SwfdecNetStream, input));
+ stream->movies = g_list_remove (stream->movies, movie);
g_object_unref (stream);
}
@@ -218,6 +226,7 @@ swfdec_net_stream_dispose (GObject *obje
swfdec_net_stream_set_loader (stream, NULL);
g_object_unref (stream->conn);
stream->conn = NULL;
+ g_assert (stream->movies == NULL);
G_OBJECT_CLASS (swfdec_net_stream_parent_class)->dispose (object);
}
@@ -237,8 +246,8 @@ swfdec_net_stream_class_init (SwfdecNetS
static void
swfdec_net_stream_init (SwfdecNetStream *stream)
{
- stream->input.get_image = swfdec_net_stream_input_get_image;
- stream->input.finalize = swfdec_net_stream_input_finalize;
+ stream->input.connect = swfdec_net_stream_input_connect;
+ stream->input.disconnect = swfdec_net_stream_input_disconnect;
}
SwfdecNetStream *
diff --git a/libswfdec/swfdec_net_stream.h b/libswfdec/swfdec_net_stream.h
index 012a11d..ce22330 100644
--- a/libswfdec/swfdec_net_stream.h
+++ b/libswfdec/swfdec_net_stream.h
@@ -59,6 +59,7 @@ struct _SwfdecNetStream
cairo_surface_t * surface; /* current image */
SwfdecTimeout timeout; /* timeout to advance to */
SwfdecVideoMovieInput input; /* used when attaching to a video movie */
+ GList * movies; /* movies we're connected to */
/* audio */
SwfdecAudio * audio; /* audio stream or NULL when not playing */
diff --git a/libswfdec/swfdec_video.c b/libswfdec/swfdec_video.c
index 867259c..e67be19 100644
--- a/libswfdec/swfdec_video.c
+++ b/libswfdec/swfdec_video.c
@@ -59,26 +59,20 @@ swfdec_video_find_frame (SwfdecVideo *vi
typedef struct {
SwfdecVideoMovieInput input;
+ SwfdecVideoMovie * movie;
SwfdecVideo * video;
gpointer decoder;
guint current_frame;
- SwfdecBuffer * current_buffer;
- cairo_surface_t * surface;
} SwfdecVideoInput;
-static cairo_surface_t *
-swfdec_video_input_get_image (SwfdecVideoMovieInput *input_)
-{
- SwfdecVideoInput *input = (SwfdecVideoInput *) input_;
-
- return input->surface;
-}
-
static void
swfdec_video_input_iterate (SwfdecVideoMovieInput *input_)
{
SwfdecVideoInput *input = (SwfdecVideoInput *) input_;
SwfdecBuffer *buffer;
+ static const cairo_user_data_key_t key;
+ guint w, h;
+ cairo_surface_t *surface;
input->current_frame = (input->current_frame + 1) % input->video->n_frames;
if (input->decoder == NULL)
@@ -87,38 +81,35 @@ swfdec_video_input_iterate (SwfdecVideoM
if (buffer == NULL)
return;
- if (input->current_buffer != NULL) {
- swfdec_buffer_unref (input->current_buffer);
- cairo_surface_destroy (input->surface);
- }
- input->current_buffer = swfdec_video_codec_decode (input->video->codec,
- input->decoder, buffer);
- if (input->current_buffer) {
- guint w, h;
- if (swfdec_video_codec_get_size (input->video->codec,
- input->decoder, &w, &h)) {
- input->surface = cairo_image_surface_create_for_data (
- input->current_buffer->data, CAIRO_FORMAT_ARGB32,
- w, h, w * 4);
- } else {
- /* if we get a buffer, the decoder must be able to tell us its size */
+ buffer = swfdec_video_codec_decode (input->video->codec, input->decoder, buffer);
+ if (buffer == NULL)
+ return;
+ if (!swfdec_video_codec_get_size (input->video->codec, input->decoder, &w, &h)) {
g_assert_not_reached ();
- }
- } else {
- input->surface = NULL;
}
- swfdec_movie_invalidate (SWFDEC_MOVIE (input->input.movie));
+ surface = cairo_image_surface_create_for_data (buffer->data,
+ CAIRO_FORMAT_ARGB32, w, h, w * 4);
+ cairo_surface_set_user_data (surface, &key,
+ buffer, (cairo_destroy_func_t) swfdec_buffer_unref);
+ swfdec_video_movie_new_image (input->movie, surface);
+ cairo_surface_destroy (surface);
}
static void
-swfdec_video_input_finalize (SwfdecVideoMovieInput *input_)
+swfdec_video_input_connect (SwfdecVideoMovieInput *input_, SwfdecVideoMovie *movie)
{
SwfdecVideoInput *input = (SwfdecVideoInput *) input_;
- if (input->current_buffer != NULL) {
- swfdec_buffer_unref (input->current_buffer);
- cairo_surface_destroy (input->surface);
- }
+ g_assert (input->movie == NULL);
+ input->movie = movie;
+}
+
+static void
+swfdec_video_input_disconnect (SwfdecVideoMovieInput *input_, SwfdecVideoMovie *movie)
+{
+ SwfdecVideoInput *input = (SwfdecVideoInput *) input_;
+
+ g_assert (input->movie == movie);
if (input->decoder)
swfdec_video_codec_finish (input->video->codec, input->decoder);
g_object_unref (input->video);
@@ -138,9 +129,9 @@ swfdec_video_input_new (SwfdecVideo *vid
input->decoder = swfdec_video_codec_init (video->codec);
if (input->decoder == NULL)
return NULL;
- input->input.get_image = swfdec_video_input_get_image;
+ input->input.connect = swfdec_video_input_connect;
input->input.iterate = swfdec_video_input_iterate;
- input->input.finalize = swfdec_video_input_finalize;
+ input->input.disconnect = swfdec_video_input_disconnect;
g_object_ref (video);
input->video = video;
input->current_frame = (guint) -1;
diff --git a/libswfdec/swfdec_video_movie.c b/libswfdec/swfdec_video_movie.c
index dc7e9ec..49e1f4d 100644
--- a/libswfdec/swfdec_video_movie.c
+++ b/libswfdec/swfdec_video_movie.c
@@ -42,21 +42,13 @@ swfdec_video_movie_render (SwfdecMovie *
const SwfdecColorTransform *trans, const SwfdecRect *inval, gboolean fill)
{
SwfdecVideoMovie *movie = SWFDEC_VIDEO_MOVIE (mov);
- cairo_surface_t *surface;
- if (movie->input == NULL)
+ if (movie->image == NULL)
return;
- surface = movie->input->get_image (movie->input);
cairo_scale (cr, SWFDEC_TWIPS_SCALE_FACTOR, SWFDEC_TWIPS_SCALE_FACTOR);
- if (surface != NULL) {
- cairo_set_source_surface (cr, surface, 0.0, 0.0);
- cairo_paint (cr);
- } else {
- cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_rectangle (cr, 0, 0, movie->video->width, movie->video->height);
- cairo_fill (cr);
- }
+ cairo_set_source_surface (cr, movie->image, 0.0, 0.0);
+ cairo_paint (cr);
}
static void
@@ -65,8 +57,8 @@ swfdec_video_movie_unset_input (SwfdecVi
if (movie->input == NULL)
return;
- if (movie->input->finalize)
- movie->input->finalize (movie->input);
+ if (movie->input->disconnect)
+ movie->input->disconnect (movie->input, movie);
movie->input = NULL;
}
@@ -76,6 +68,10 @@ swfdec_video_movie_dispose (GObject *obj
SwfdecVideoMovie *movie = SWFDEC_VIDEO_MOVIE (object);
swfdec_video_movie_unset_input (movie);
+ if (movie->image) {
+ cairo_surface_destroy (movie->image);
+ movie->image = NULL;
+ }
g_object_unref (movie->video);
G_OBJECT_CLASS (swfdec_video_movie_parent_class)->dispose (object);
@@ -96,14 +92,18 @@ swfdec_video_movie_iterate_end (SwfdecMo
return TRUE;
}
+extern const JSClass video_class;
static void
swfdec_video_movie_class_init (SwfdecVideoMovieClass * g_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+ SwfdecScriptableClass *scriptable_class = SWFDEC_SCRIPTABLE_CLASS (g_class);
SwfdecMovieClass *movie_class = SWFDEC_MOVIE_CLASS (g_class);
object_class->dispose = swfdec_video_movie_dispose;
+ scriptable_class->jsclass = &video_class;
+
movie_class->update_extents = swfdec_video_movie_update_extents;
movie_class->render = swfdec_video_movie_render;
movie_class->iterate_end = swfdec_video_movie_iterate_end;
@@ -119,11 +119,36 @@ swfdec_video_movie_set_input (SwfdecVide
{
g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
g_return_if_fail (input != NULL);
- g_return_if_fail (input->get_image);
swfdec_video_movie_unset_input (movie);
movie->input = input;
- input->movie = movie;
+ if (input->connect)
+ input->connect (input, movie);
+}
+
+void
+swfdec_video_movie_clear (SwfdecVideoMovie *movie)
+{
+ g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
+
+ if (movie->image == NULL)
+ return;
+
+ cairo_surface_destroy (movie->image);
+ movie->image = NULL;
+ swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
+}
+
+void
+swfdec_video_movie_new_image (SwfdecVideoMovie *movie, cairo_surface_t *image)
+{
+ g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
+ g_return_if_fail (image != NULL);
+
+ if (movie->image)
+ cairo_surface_destroy (movie->image);
+ cairo_surface_reference (image);
+ movie->image = image;
swfdec_movie_invalidate (SWFDEC_MOVIE (movie));
}
diff --git a/libswfdec/swfdec_video_movie.h b/libswfdec/swfdec_video_movie.h
index 7708c37..9db5d45 100644
--- a/libswfdec/swfdec_video_movie.h
+++ b/libswfdec/swfdec_video_movie.h
@@ -39,14 +39,14 @@ typedef struct _SwfdecVideoMovieInput Sw
/* FIXME: make an interface? */
struct _SwfdecVideoMovieInput {
- /* get surface holding current image or NULL to use black */
- cairo_surface_t * (* get_image) (SwfdecVideoMovieInput *input);
+ /* connect to movie */
+ void (* connect) (SwfdecVideoMovieInput *input,
+ SwfdecVideoMovie * movie);
+ /* called when input is unset */
+ void (* disconnect) (SwfdecVideoMovieInput *input,
+ SwfdecVideoMovie * movie);
/* called when movie is iterating */
void (* iterate) (SwfdecVideoMovieInput *input);
- /* called when input is unset */
- void (* finalize) (SwfdecVideoMovieInput *input);
- /* set by movie */
- SwfdecVideoMovie * movie;
};
struct _SwfdecVideoMovie {
@@ -54,6 +54,7 @@ struct _SwfdecVideoMovie {
SwfdecVideo * video; /* video we play back */
SwfdecVideoMovieInput *input; /* where we take the input from */
+ cairo_surface_t * image; /* TRUE if cleared */
};
struct _SwfdecVideoMovieClass {
@@ -64,6 +65,10 @@ GType swfdec_video_movie_get_type (voi
void swfdec_video_movie_set_input (SwfdecVideoMovie * movie,
SwfdecVideoMovieInput *input);
+void swfdec_video_movie_clear (SwfdecVideoMovie * movie);
+/* API for SwfdecVideoMovieInput */
+void swfdec_video_movie_new_image (SwfdecVideoMovie * movie,
+ cairo_surface_t * surface);
G_END_DECLS
#endif
More information about the Swfdec
mailing list