Benjamin Otte
2007-Apr-06 06:46 UTC
[Swfdec] 3 commits - libswfdec-gtk/swfdec_gtk_loader.c libswfdec/Makefile.am libswfdec/swfdec_codec.c libswfdec/swfdec_codec_ffmpeg.c libswfdec/swfdec_codec_gst.c libswfdec/swfdec_codec.h libswfdec/swfdec_codec_screen.c libswfdec/swfdec_codec_video.c libswfdec/swfdec_codec_video.h libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_flv_decoder.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_net_stream.h libswfdec/swfdec_video.c libswfdec/swfdec_video.h libswfdec/swfdec_video_movie.c libswfdec/swfdec_video_movie.h player/Makefile.am player/swfplay.c
libswfdec-gtk/swfdec_gtk_loader.c | 10 -- libswfdec/Makefile.am | 2 libswfdec/swfdec_codec.c | 39 -------- libswfdec/swfdec_codec.h | 26 ----- libswfdec/swfdec_codec_ffmpeg.c | 98 ++++++++------------- libswfdec/swfdec_codec_gst.c | 174 +++++++++++++++++++------------------- libswfdec/swfdec_codec_screen.c | 60 +++++-------- libswfdec/swfdec_codec_video.c | 151 ++++++++++++++++++++++++++++++++ libswfdec/swfdec_codec_video.h | 57 ++++++++++++ libswfdec/swfdec_flv_decoder.c | 22 +--- libswfdec/swfdec_flv_decoder.h | 1 libswfdec/swfdec_net_stream.c | 37 ++------ libswfdec/swfdec_net_stream.h | 4 libswfdec/swfdec_video.c | 29 ------ libswfdec/swfdec_video.h | 9 - libswfdec/swfdec_video_movie.c | 9 - libswfdec/swfdec_video_movie.h | 4 player/Makefile.am | 4 player/swfplay.c | 10 ++ 19 files changed, 418 insertions(+), 328 deletions(-) New commits: diff-tree f9ed2528c36837320c94bb1fec2313445c85c886 (from 25c390688e91b470212ae7eade090d28d0546a00) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 6 15:45:20 2007 +0200 revamp the video decoding API lots of code saved, and VP6 with GStreamer works now diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 0ad15c5..fa1abb6 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -35,6 +35,7 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_codec_adpcm.c \ $(CODECS) \ swfdec_codec_screen.c \ + swfdec_codec_video.c \ swfdec_color.c \ swfdec_connection.c \ swfdec_debug.c \ @@ -122,6 +123,7 @@ noinst_HEADERS = \ swfdec_cached.h \ swfdec_character.h \ swfdec_codec.h \ + swfdec_codec_video.h \ swfdec_color.h \ swfdec_connection.h \ swfdec_debug.h \ diff --git a/libswfdec/swfdec_codec.c b/libswfdec/swfdec_codec.c index 8affa1c..32ad9cc 100644 --- a/libswfdec/swfdec_codec.c +++ b/libswfdec/swfdec_codec.c @@ -27,7 +27,6 @@ /*** DECODER LIST ***/ extern const SwfdecAudioCodec swfdec_codec_adpcm; -extern const SwfdecVideoCodec swfdec_codec_screen; #ifdef HAVE_MAD extern const SwfdecAudioCodec swfdec_codec_mad; @@ -35,11 +34,8 @@ extern const SwfdecAudioCodec swfdec_cod #ifdef HAVE_FFMPEG extern const SwfdecAudioCodec swfdec_codec_ffmpeg_audio; -extern const SwfdecVideoCodec swfdec_codec_ffmpeg_video; #endif -extern const SwfdecVideoCodec swfdec_codec_gst_video; - /*** UNCOMPRESSED SOUND ***/ #define U8_FLAG (0x10000) @@ -144,38 +140,3 @@ swfdec_codec_get_audio (SwfdecAudioForma } } -const SwfdecVideoCodec * -swfdec_codec_get_video (SwfdecVideoFormat format) -{ - switch (format) { - case SWFDEC_VIDEO_FORMAT_SCREEN: - return &swfdec_codec_screen; -#ifdef HAVE_FFMPEG - return &swfdec_codec_ffmpeg_video; -#endif - SWFDEC_ERROR ("Screen video requires ffmpeg"); - return NULL; - case SWFDEC_VIDEO_FORMAT_H263: -#ifdef HAVE_GST - return &swfdec_codec_gst_video; -#else -#ifdef HAVE_FFMPEG - return &swfdec_codec_ffmpeg_video; -#else - SWFDEC_ERROR ("H263 video requires ffmpeg or GStreamer"); - return NULL; -#endif -#endif - case SWFDEC_VIDEO_FORMAT_VP6: -#ifdef HAVE_GST - return &swfdec_codec_gst_video; -#else - SWFDEC_ERROR ("VP6 video requires ffmpeg or GStreamer"); - return NULL; -#endif - default: - SWFDEC_ERROR ("video codec %u not implemented yet", (guint) format); - return NULL; - } -} - diff --git a/libswfdec/swfdec_codec.h b/libswfdec/swfdec_codec.h index a248170..1920e03 100644 --- a/libswfdec/swfdec_codec.h +++ b/libswfdec/swfdec_codec.h @@ -25,7 +25,6 @@ #include <libswfdec/swfdec_buffer.h> typedef struct _SwfdecAudioCodec SwfdecAudioCodec; -typedef struct _SwfdecVideoCodec SwfdecVideoCodec; typedef enum { SWFDEC_AUDIO_FORMAT_UNDEFINED = 0, @@ -36,15 +35,6 @@ typedef enum { SWFDEC_AUDIO_FORMAT_NELLYMOSER = 6 } SwfdecAudioFormat; -typedef enum { - SWFDEC_VIDEO_FORMAT_UNDEFINED = 0, - SWFDEC_VIDEO_FORMAT_H263 = 2, - SWFDEC_VIDEO_FORMAT_SCREEN = 3, - SWFDEC_VIDEO_FORMAT_VP6 = 4, - SWFDEC_VIDEO_FORMAT_VP6_ALPHA = 5, - SWFDEC_VIDEO_FORMAT_SCREEN2 = 6 -} SwfdecVideoFormat; - struct _SwfdecAudioCodec { gpointer (* init) (SwfdecAudioFormat type, gboolean width, @@ -56,29 +46,13 @@ struct _SwfdecAudioCodec { SwfdecBuffer * (* finish) (gpointer codec_data); }; -struct _SwfdecVideoCodec { - gpointer (* init) (SwfdecVideoFormat type); - gboolean (* get_size) (gpointer codec_data, - guint * width, - guint * height); - SwfdecBuffer * (* decode) (gpointer codec_data, - SwfdecBuffer * buffer); - void (* finish) (gpointer codec_data); -}; - const SwfdecAudioCodec * swfdec_codec_get_audio (SwfdecAudioFormat format); -const SwfdecVideoCodec * swfdec_codec_get_video (SwfdecVideoFormat format); #define swfdec_audio_codec_init(codec,type,width,format) (codec)->init (type, width, format) #define swfdec_audio_codec_get_format(codec, codec_data) (codec)->get_format (codec_data) #define swfdec_audio_codec_decode(codec, codec_data, buffer) (codec)->decode (codec_data, buffer) #define swfdec_audio_codec_finish(codec, codec_data) (codec)->finish (codec_data) -#define swfdec_video_codec_init(codec,type) (codec)->init (type) -#define swfdec_video_codec_get_size(codec, codec_data, width, height) (codec)->get_size (codec_data, width, height) -#define swfdec_video_codec_decode(codec, codec_data, buffer) (codec)->decode (codec_data, buffer) -#define swfdec_video_codec_finish(codec, codec_data) (codec)->finish (codec_data) - G_END_DECLS #endif diff --git a/libswfdec/swfdec_codec_ffmpeg.c b/libswfdec/swfdec_codec_ffmpeg.c index 5f2dcaf..08b9c34 100644 --- a/libswfdec/swfdec_codec_ffmpeg.c +++ b/libswfdec/swfdec_codec_ffmpeg.c @@ -24,6 +24,7 @@ #include <avcodec.h> #include "swfdec_codec.h" +#include "swfdec_codec_video.h" #include "swfdec_debug.h" /*** GENERAL ***/ @@ -201,60 +202,16 @@ const SwfdecAudioCodec swfdec_codec_ffmp /*** VIDEO ***/ typedef struct { + SwfdecVideoDecoder decoder; AVCodecContext * ctx; /* out context (d'oh) */ AVFrame * frame; /* the frame we use for decoding */ -} SwfdecCodecFFMpegVideo; - -static gpointer -swfdec_codec_ffmpeg_video_init (SwfdecVideoFormat type) -{ - SwfdecCodecFFMpegVideo *codec; - AVCodecContext *ctx; - enum CodecID id; - - switch (type) { - case SWFDEC_VIDEO_FORMAT_H263: - id = CODEC_ID_FLV1; - break; - case SWFDEC_VIDEO_FORMAT_SCREEN: - id = CODEC_ID_FLASHSV; - break; - default: - g_assert_not_reached (); - id = 0; - break; - } - ctx = swfdec_codec_ffmpeg_init (id); - - if (ctx == NULL) - return NULL; - codec = g_new (SwfdecCodecFFMpegVideo, 1); - codec->ctx = ctx; - codec->frame = avcodec_alloc_frame (); - - return codec; -} - -static gboolean -swfdec_codec_ffmpeg_video_get_size (gpointer codec_data, - guint *width, guint *height) -{ - SwfdecCodecFFMpegVideo *codec = codec_data; - AVCodecContext *ctx = codec->ctx; - - if (ctx->width <= 0 || ctx->height <= 0) - return FALSE; - - *width = ctx->width; - *height = ctx->height; - - return TRUE; -} +} SwfdecVideoDecoderFFMpeg; SwfdecBuffer * -swfdec_codec_ffmpeg_video_decode (gpointer codec_data, SwfdecBuffer *buffer) +swfdec_video_decoder_ffmpeg_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer, + guint *width, guint *height, guint *rowstride) { - SwfdecCodecFFMpegVideo *codec = codec_data; + SwfdecVideoDecoderFFMpeg *codec = (SwfdecVideoDecoderFFMpeg *) dec; int got_image; SwfdecBuffer *ret; AVPicture picture; @@ -270,23 +227,50 @@ swfdec_codec_ffmpeg_video_decode (gpoint img_convert (&picture, PIX_FMT_RGB32, (AVPicture *) codec->frame, codec->ctx->pix_fmt, codec->ctx->width, codec->ctx->height); + *width = codec->ctx->width; + *height = codec->ctx->height; + *rowstride = codec->ctx->width * 4; return ret; } static void -swfdec_codec_ffmpeg_video_finish (gpointer codec_data) +swfdec_video_decoder_ffmpeg_free (SwfdecVideoDecoder *dec) { - SwfdecCodecFFMpegVideo *codec = codec_data; + SwfdecVideoDecoderFFMpeg *codec = (SwfdecVideoDecoderFFMpeg *) dec; + avcodec_close (codec->ctx); av_free (codec->ctx); av_free (codec->frame); + g_free (codec); } +SwfdecVideoDecoder * +swfdec_video_decoder_ffmpeg_new (SwfdecVideoFormat type) +{ + SwfdecVideoDecoderFFMpeg *codec; + AVCodecContext *ctx; + enum CodecID id; -const SwfdecVideoCodec swfdec_codec_ffmpeg_video = { - swfdec_codec_ffmpeg_video_init, - swfdec_codec_ffmpeg_video_get_size, - swfdec_codec_ffmpeg_video_decode, - swfdec_codec_ffmpeg_video_finish -}; + switch (type) { + case SWFDEC_VIDEO_FORMAT_H263: + id = CODEC_ID_FLV1; + break; + case SWFDEC_VIDEO_FORMAT_SCREEN: + id = CODEC_ID_FLASHSV; + break; + default: + return NULL; + } + ctx = swfdec_codec_ffmpeg_init (id); + + if (ctx == NULL) + return NULL; + codec = g_new (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 (); + + return &codec->decoder; +} diff --git a/libswfdec/swfdec_codec_gst.c b/libswfdec/swfdec_codec_gst.c index c10a201..cd4f517 100644 --- a/libswfdec/swfdec_codec_gst.c +++ b/libswfdec/swfdec_codec_gst.c @@ -23,10 +23,10 @@ #include <string.h> #include <gst/gst.h> -#include "swfdec_codec.h" +#include "swfdec_codec_video.h" #include "swfdec_debug.h" -#if 1 +#if 0 #define swfdec_cond_wait(cond, mutex) G_STMT_START { \ g_print ("waiting at %s\n", G_STRLOC); \ g_cond_wait (cond, mutex); \ @@ -38,6 +38,8 @@ typedef struct _SwfdecGstVideo SwfdecGstVideo; struct _SwfdecGstVideo { + SwfdecVideoDecoder decoder; + GMutex * mutex; /* mutex that blocks everything below */ GCond * cond; /* cond used to signal when stuff below changes */ volatile int refcount; /* refcount (d'oh) */ @@ -48,6 +50,8 @@ struct _SwfdecGstVideo { int width; /* width of last output buffer */ int height; /* height of last output buffer */ GstCaps * srccaps; /* caps to set on buffers */ + gboolean out_next; /* wether the pipeline expects input or output */ + gboolean error; /* we're in an error state */ }; static void @@ -68,9 +72,9 @@ swfdec_gst_video_unref (gpointer data, G } static void -swfdec_codec_gst_video_finish (gpointer codec_data) +swfdec_video_decoder_gst_free (SwfdecVideoDecoder *dec) { - SwfdecGstVideo *player = codec_data; + SwfdecGstVideo *player = (SwfdecGstVideo *) dec; GstElement *pipeline; g_mutex_lock (player->mutex); @@ -84,22 +88,57 @@ swfdec_codec_gst_video_finish (gpointer swfdec_gst_video_unref (player, NULL); } +SwfdecBuffer * +swfdec_video_decoder_gst_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer, + guint *width, guint *height, guint *rowstride) +{ + SwfdecGstVideo *player = (SwfdecGstVideo *) dec; + + g_mutex_lock (player->mutex); + while (player->in != NULL && !player->error) { + swfdec_cond_wait (player->cond, player->mutex); + } + player->in = buffer; + g_cond_signal (player->cond); + while (player->out == NULL && !player->error) { + swfdec_cond_wait (player->cond, player->mutex); + } + if (player->error) { + g_mutex_unlock (player->mutex); + return NULL; + } + buffer = player->out; + player->out = NULL; + *width = player->width; + *height = player->height; + *rowstride = player->width * 4; + g_mutex_unlock (player->mutex); + return buffer; +} + static void swfdec_codec_gst_fakesrc_handoff (GstElement *fakesrc, GstBuffer *buf, GstPad *pad, SwfdecGstVideo *player) { g_mutex_lock (player->mutex); + if (player->out_next) { + player->error = TRUE; + g_cond_signal (player->cond); + g_mutex_unlock (player->mutex); + return; + } while (player->pipeline != NULL && player->in == NULL) swfdec_cond_wait (player->cond, player->mutex); if (player->pipeline == NULL) { g_mutex_unlock (player->mutex); return; } - g_print ("got one\n"); buf->data = g_memdup (player->in->data, player->in->length); + buf->malloc_data = buf->data; buf->size = player->in->length; gst_buffer_set_caps (buf, player->srccaps); player->in = NULL; + player->out_next = TRUE; g_cond_signal (player->cond); g_mutex_unlock (player->mutex); } @@ -111,6 +150,12 @@ swfdec_codec_gst_fakesink_handoff (GstEl GstCaps *caps; g_mutex_lock (player->mutex); + if (!player->out_next) { + player->error = TRUE; + g_cond_signal (player->cond); + g_mutex_unlock (player->mutex); + return; + } caps = gst_buffer_get_caps (buf); if (caps) { GstStructure *structure = gst_caps_get_structure (caps, 0); @@ -123,57 +168,60 @@ swfdec_codec_gst_fakesink_handoff (GstEl } while (player->pipeline != NULL && player->out != NULL) swfdec_cond_wait (player->cond, player->mutex); - if (player->pipeline == NULL) + if (player->pipeline == NULL) { + g_mutex_unlock (player->mutex); return; - g_print ("put one\n"); - player->out = swfdec_buffer_new (); - player->out->data = g_memdup (buf->data, buf->size); - player->out->length = buf->size; + } + player->out = swfdec_buffer_new_for_data ( + g_memdup (buf->data, buf->size), buf->size); + player->out_next = FALSE; g_cond_signal (player->cond); g_mutex_unlock (player->mutex); } static void -do_the_link (GstElement *src, GstPad *pad, GstElement *sink) +swfdec_codec_gst_do_link (GstElement *src, GstPad *pad, GstElement *sink) { - g_print ("link!\n"); if (!gst_element_link (src, sink)) { SWFDEC_ERROR ("no delayed link"); } } -static gpointer -swfdec_codec_gst_video_init (SwfdecVideoFormat type) +SwfdecVideoDecoder * +swfdec_video_decoder_gst_new (SwfdecVideoFormat type) { SwfdecGstVideo *player; GstElement *fakesrc, *fakesink, *decoder, *csp; - GstCaps *sinkcaps; + GstCaps *caps; if (!gst_init_check (NULL, NULL, NULL)) - return FALSE; + return NULL; - player = g_slice_new0 (SwfdecGstVideo); - player->pipeline = gst_pipeline_new ("pipeline"); - player->refcount = 1; - g_assert (player->pipeline); - player->mutex = g_mutex_new (); - player->cond = g_cond_new (); switch (type) { case SWFDEC_VIDEO_FORMAT_H263: - player->srccaps = gst_caps_from_string ("video/x-flash-video"); + caps = gst_caps_from_string ("video/x-flash-video"); break; case SWFDEC_VIDEO_FORMAT_VP6: - player->srccaps = gst_caps_from_string ("video/x-vp6-flash"); + caps = gst_caps_from_string ("video/x-vp6-flash"); break; default: - g_assert_not_reached (); - break; + return NULL; } - g_assert (player->srccaps); + g_assert (caps); + + player = g_slice_new0 (SwfdecGstVideo); + player->decoder.decode = swfdec_video_decoder_gst_decode; + player->decoder.free = swfdec_video_decoder_gst_free; + player->pipeline = gst_pipeline_new ("pipeline"); + player->refcount = 1; + g_assert (player->pipeline); + player->mutex = g_mutex_new (); + player->cond = g_cond_new (); + player->srccaps = caps; fakesrc = gst_element_factory_make ("fakesrc", NULL); if (fakesrc == NULL) { SWFDEC_ERROR ("failed to create fakesrc"); - swfdec_codec_gst_video_finish (player); + swfdec_video_decoder_gst_free (&player->decoder); return NULL; } g_object_set (fakesrc, "signal-handoffs", TRUE, @@ -186,7 +234,7 @@ swfdec_codec_gst_video_init (SwfdecVideo fakesink = gst_element_factory_make ("fakesink", NULL); if (fakesink == NULL) { SWFDEC_ERROR ("failed to create fakesink"); - swfdec_codec_gst_video_finish (player); + swfdec_video_decoder_gst_free (&player->decoder); return NULL; } g_object_set (fakesink, "signal-handoffs", TRUE, NULL); @@ -198,85 +246,41 @@ swfdec_codec_gst_video_init (SwfdecVideo decoder = gst_element_factory_make ("decodebin", NULL); if (decoder == NULL) { SWFDEC_ERROR ("failed to create decoder"); - swfdec_codec_gst_video_finish (player); + swfdec_video_decoder_gst_free (&player->decoder); return NULL; } gst_bin_add (GST_BIN (player->pipeline), decoder); csp = gst_element_factory_make ("ffmpegcolorspace", NULL); if (csp == NULL) { SWFDEC_ERROR ("failed to create colorspace"); - swfdec_codec_gst_video_finish (player); + swfdec_video_decoder_gst_free (&player->decoder); return NULL; } gst_bin_add (GST_BIN (player->pipeline), csp); - g_signal_connect (decoder, "pad-added", G_CALLBACK (do_the_link), csp); + g_signal_connect (decoder, "pad-added", + G_CALLBACK (swfdec_codec_gst_do_link), csp); #if G_BYTE_ORDER == G_BIG_ENDIAN - sinkcaps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, " + caps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, " "red_mask=16711680, green_mask=65280, blue_mask=255"); #else - sinkcaps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, " + caps = gst_caps_from_string ("video/x-raw-rgb, bpp=32, endianness=4321, depth=24, " "red_mask=65280, green_mask=16711680, blue_mask=-16777216"); #endif - g_assert (sinkcaps); + g_assert (caps); if (!gst_element_link_filtered (fakesrc, decoder, player->srccaps) || -#if 0 - !gst_element_link (decoder, csp) || -#endif - !gst_element_link_filtered (csp, fakesink, sinkcaps)) { + !gst_element_link_filtered (csp, fakesink, caps)) { SWFDEC_ERROR ("linking failed"); - swfdec_codec_gst_video_finish (player); + swfdec_video_decoder_gst_free (&player->decoder); return NULL; } - gst_caps_unref (sinkcaps); + gst_caps_unref (caps); if (gst_element_set_state (player->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { SWFDEC_ERROR ("failed to change sate"); - swfdec_codec_gst_video_finish (player); + swfdec_video_decoder_gst_free (&player->decoder); return NULL; } - return player; -} - -static gboolean -swfdec_codec_gst_video_get_size (gpointer codec_data, - guint *width, guint *height) -{ - SwfdecGstVideo *player = codec_data; - - g_mutex_lock (player->mutex); - if (player->width == 0 || player->height == 0) { - g_mutex_unlock (player->mutex); - return FALSE; - } - *width = player->width; - *height = player->height; - g_mutex_unlock (player->mutex); - return TRUE; -} - -SwfdecBuffer * -swfdec_codec_gst_video_decode (gpointer codec_data, SwfdecBuffer *buffer) -{ - SwfdecGstVideo *player = codec_data; - - g_mutex_lock (player->mutex); - g_assert (player->in == NULL); - player->in = buffer; - g_cond_signal (player->cond); - while (player->out == NULL) { - swfdec_cond_wait (player->cond, player->mutex); - } - buffer = player->out; - player->out = NULL; - g_mutex_unlock (player->mutex); - return buffer; + return &player->decoder; } -const SwfdecVideoCodec swfdec_codec_gst_video = { - swfdec_codec_gst_video_init, - swfdec_codec_gst_video_get_size, - swfdec_codec_gst_video_decode, - swfdec_codec_gst_video_finish -}; - diff --git a/libswfdec/swfdec_codec_screen.c b/libswfdec/swfdec_codec_screen.c index 6c88696..369ff88 100644 --- a/libswfdec/swfdec_codec_screen.c +++ b/libswfdec/swfdec_codec_screen.c @@ -25,44 +25,24 @@ #include <zlib.h> #include <liboil/liboil.h> -#include "swfdec_codec.h" +#include "swfdec_codec_video.h" #include "swfdec_bits.h" #include "swfdec_debug.h" typedef struct _SwfdecCodecScreen SwfdecCodecScreen; struct _SwfdecCodecScreen { + SwfdecVideoDecoder decoder; /* the decoder */ gulong width; /* width of last image */ gulong height; /* height of last image */ SwfdecBuffer * buffer; /* buffer containing last decoded image */ }; -static gpointer -swfdec_codec_screen_init (SwfdecVideoFormat type) -{ - SwfdecCodecScreen *screen = g_new0 (SwfdecCodecScreen, 1); - - return screen; -} - -static gboolean -swfdec_codec_screen_get_size (gpointer codec_data, - guint *width, guint *height) -{ - SwfdecCodecScreen *screen = codec_data; - - if (screen->width == 0 || screen->height == 0) - return FALSE; - - *width = screen->width; - *height = screen->height; - return TRUE; -} -#include <unistd.h> static SwfdecBuffer * -swfdec_codec_screen_decode (gpointer codec_data, SwfdecBuffer *buffer) +swfdec_video_decoder_screen_decode (SwfdecVideoDecoder *dec, SwfdecBuffer *buffer, + guint *width, guint *height, guint *rowstride) { - SwfdecCodecScreen *screen = codec_data; + SwfdecCodecScreen *screen = (SwfdecCodecScreen *) dec; SwfdecBuffer *ret; SwfdecBits bits; gulong i, j, w, h, bw, bh, stride; @@ -82,7 +62,7 @@ swfdec_codec_screen_decode (gpointer cod } else if (screen->width != w || screen->height != h) { SWFDEC_ERROR ("width or height differ from original: was %lux%lu, is %lux%lu", screen->width, screen->height, w, h); - /* FIXME: this is was ffmpeg does, should we be more forgiving? */ + /* FIXME: this is what ffmpeg does, should we be more forgiving? */ return NULL; } if (screen->buffer && screen->buffer->ref_count == 1) { @@ -127,22 +107,34 @@ swfdec_codec_screen_decode (gpointer cod } } } + *width = screen->width; + *height = screen->height; + *rowstride = stride; return ret; } static void -swfdec_codec_screen_finish (gpointer codec_data) +swfdec_video_decoder_screen_free (SwfdecVideoDecoder *dec) { - SwfdecCodecScreen *screen = codec_data; + SwfdecCodecScreen *screen = (SwfdecCodecScreen *) dec; if (screen->buffer) swfdec_buffer_unref (screen->buffer); g_free (screen); } -const SwfdecVideoCodec swfdec_codec_screen = { - swfdec_codec_screen_init, - swfdec_codec_screen_get_size, - swfdec_codec_screen_decode, - swfdec_codec_screen_finish -}; +SwfdecVideoDecoder * +swfdec_video_decoder_screen_new (SwfdecVideoFormat type) +{ + SwfdecCodecScreen *screen; + + if (type != SWFDEC_VIDEO_FORMAT_SCREEN) + return NULL; + + screen = g_new0 (SwfdecCodecScreen, 1); + screen->decoder.decode = swfdec_video_decoder_screen_decode; + screen->decoder.free = swfdec_video_decoder_screen_free; + + return &screen->decoder; +} + diff --git a/libswfdec/swfdec_codec_video.c b/libswfdec/swfdec_codec_video.c new file mode 100644 index 0000000..b6a7185 --- /dev/null +++ b/libswfdec/swfdec_codec_video.c @@ -0,0 +1,151 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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_codec_video.h" +#include "swfdec_debug.h" + +extern SwfdecVideoDecoderNewFunc swfdec_video_decoder_screen_new; +#ifdef HAVE_FFMPEG +extern SwfdecVideoDecoderNewFunc swfdec_video_decoder_ffmpeg_new; +#endif +#ifdef HAVE_GST +extern SwfdecVideoDecoderNewFunc swfdec_video_decoder_gst_new; +#endif + +/** + * swfdec_video_decoder_new: + * @format: #SwfdecVideoFormat to create the #SwfdecVideoDecoder for + * + * Creates a new decoder to decode videos of type @format. If no suitable + * decoder could be created, %NULL is returned. + * + * Returns: + **/ +SwfdecVideoDecoder * +swfdec_video_decoder_new (SwfdecVideoFormat format) +{ + SwfdecVideoDecoder *ret; + + ret = swfdec_video_decoder_screen_new (format); +#ifdef HAVE_FFMPEG + if (ret == NULL) + ret = swfdec_video_decoder_ffmpeg_new (format); +#endif +#ifdef HAVE_GST + if (ret == NULL) + ret = swfdec_video_decoder_gst_new (format); +#endif + + if (ret != NULL) { + ret->format = format; + g_return_val_if_fail (ret->decode, ret); + g_return_val_if_fail (ret->free, ret); + } else { + SWFDEC_WARNING ("no decoder found for codec %u\n", (guint) format); + } + return ret; +} + +/** + * swfdec_video_decoder_free: + * @decoder: a #SwfdecVideoDecoder + * + * Frees the given @decoder and all associated ressources. + **/ +void +swfdec_video_decoder_free (SwfdecVideoDecoder *decoder) +{ + g_return_if_fail (decoder); + + decoder->free (decoder); +} + +static void +foo (gpointer data) +{ + //g_print ("boom baby %u\n", ((SwfdecBuffer *) data)->ref_count); + swfdec_buffer_unref (data); +} +/** + * swfdec_video_decoder_decode: + * @decoder: a #SwfdecVideoDecoder + * @buffer: buffer to decode + * + * Decodes the given buffer into an image surface. + * + * Returns: a new cairo image surface or %NULL on error. + **/ +cairo_surface_t * +swfdec_video_decoder_decode (SwfdecVideoDecoder *decoder, SwfdecBuffer *buffer) +{ + static const cairo_user_data_key_t key; + cairo_surface_t *surface; + guint width, height, rowstride; + + g_return_val_if_fail (decoder != NULL, NULL); + g_return_val_if_fail (buffer != NULL, NULL); + + if (decoder->format == SWFDEC_VIDEO_FORMAT_VP6) { + guint wsub, hsub; + SwfdecBuffer *tmp; + wsub = *buffer->data; + hsub = wsub & 0xF; + wsub >>= 4; + tmp = swfdec_buffer_new_subbuffer (buffer, 1, buffer->length - 1); + buffer = decoder->decode (decoder, tmp, &width, &height, &rowstride); + swfdec_buffer_unref (tmp); + if (wsub >= width || hsub >= height) { + SWFDEC_ERROR ("size subtraction too big"); + if (buffer) + swfdec_buffer_unref (buffer); + return NULL; + } + width -= wsub; + height -= hsub; + } else { + buffer = decoder->decode (decoder, buffer, &width, &height, &rowstride); + } + if (buffer == NULL) { + SWFDEC_ERROR ("failed to decode video"); + return NULL; + } + if (width == 0 || height == 0 || rowstride < width * 4) { + SWFDEC_ERROR ("invalid image size"); + swfdec_buffer_unref (buffer); + return NULL; + } + surface = cairo_image_surface_create_for_data (buffer->data, CAIRO_FORMAT_RGB24, + width, height, rowstride); + if (cairo_surface_status (surface)) { + SWFDEC_ERROR ("failed to create surface: %s", + cairo_status_to_string (cairo_surface_status (surface))); + cairo_surface_destroy (surface); + swfdec_buffer_unref (buffer); + return NULL; + } + cairo_surface_set_user_data (surface, &key, buffer, + foo); + //(cairo_destroy_func_t) swfdec_buffer_unref); + return surface; +} + diff --git a/libswfdec/swfdec_codec_video.h b/libswfdec/swfdec_codec_video.h new file mode 100644 index 0000000..010fe02 --- /dev/null +++ b/libswfdec/swfdec_codec_video.h @@ -0,0 +1,57 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@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 + */ + +#ifndef _SWFDEC_CODEC_VIDEO_H_ +#define _SWFDEC_CODEC_VIDEO_H_ + +#include <glib.h> +#include <cairo.h> +#include <libswfdec/swfdec_buffer.h> + +typedef enum { + SWFDEC_VIDEO_FORMAT_UNDEFINED = 0, + SWFDEC_VIDEO_FORMAT_H263 = 2, + SWFDEC_VIDEO_FORMAT_SCREEN = 3, + SWFDEC_VIDEO_FORMAT_VP6 = 4, + SWFDEC_VIDEO_FORMAT_VP6_ALPHA = 5, + SWFDEC_VIDEO_FORMAT_SCREEN2 = 6 +} SwfdecVideoFormat; + +typedef struct _SwfdecVideoDecoder SwfdecVideoDecoder; +typedef SwfdecVideoDecoder * (SwfdecVideoDecoderNewFunc) (SwfdecVideoFormat format); + +struct _SwfdecVideoDecoder { + SwfdecVideoFormat format; + SwfdecBuffer * (* decode) (SwfdecVideoDecoder * decoder, + SwfdecBuffer * buffer, + guint * width, + guint * height, + guint * rowstride); + void (* free) (SwfdecVideoDecoder * decoder); +}; + +SwfdecVideoDecoder * swfdec_video_decoder_new (SwfdecVideoFormat format); +void swfdec_video_decoder_free (SwfdecVideoDecoder * decoder); + +cairo_surface_t * swfdec_video_decoder_decode (SwfdecVideoDecoder * decoder, + SwfdecBuffer * buffer); + + +G_END_DECLS +#endif diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c index ac644e2..b6dfff0 100644 --- a/libswfdec/swfdec_flv_decoder.c +++ b/libswfdec/swfdec_flv_decoder.c @@ -269,23 +269,19 @@ swfdec_flv_decoder_parse_video_tag (Swfd } if (dec->width == 0 && dec->height == 0) { SwfdecFlvVideoTag *tag = &g_array_index (flv->video, SwfdecFlvVideoTag, 0); - const SwfdecVideoCodec *codec = swfdec_codec_get_video (tag->format); - gpointer decoder; - SwfdecBuffer *ignore; + SwfdecVideoDecoder *decoder; + cairo_surface_t *surface; - if (codec == NULL) - return SWFDEC_STATUS_OK; - decoder = swfdec_video_codec_init (codec, tag->format); + /* nice hack... */ + decoder = swfdec_video_decoder_new (tag->format); if (decoder == NULL) return SWFDEC_STATUS_OK; - ignore = swfdec_video_codec_decode (codec, decoder, tag->buffer); - if (ignore) - swfdec_buffer_unref (ignore); - if (!swfdec_video_codec_get_size (codec, decoder, &dec->width, &dec->height)) { - swfdec_video_codec_finish (codec, decoder); + surface = swfdec_video_decoder_decode (decoder, tag->buffer); + if (surface == NULL) return SWFDEC_STATUS_OK; - } - swfdec_video_codec_finish (codec, decoder); + dec->width = cairo_image_surface_get_width (surface); + dec->height = cairo_image_surface_get_height (surface); + swfdec_video_decoder_free (decoder); return SWFDEC_STATUS_INIT; } else { return SWFDEC_STATUS_IMAGE; diff --git a/libswfdec/swfdec_flv_decoder.h b/libswfdec/swfdec_flv_decoder.h index 7bb9c72..c26b169 100644 --- a/libswfdec/swfdec_flv_decoder.h +++ b/libswfdec/swfdec_flv_decoder.h @@ -21,6 +21,7 @@ #define __SWFDEC_FLV_DECODER_H__ #include <libswfdec/swfdec_codec.h> +#include <libswfdec/swfdec_codec_video.h> #include <libswfdec/swfdec_decoder.h> G_BEGIN_DECLS diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c index 7e16631..d0ab3e6 100644 --- a/libswfdec/swfdec_net_stream.c +++ b/libswfdec/swfdec_net_stream.c @@ -85,32 +85,17 @@ swfdec_net_stream_video_goto (SwfdecNetS } else { if (format != stream->format) { if (stream->decoder) - swfdec_video_codec_finish (stream->codec, stream->decoder); + swfdec_video_decoder_free (stream->decoder); stream->format = format; - stream->codec = swfdec_codec_get_video (format); - if (stream->codec) - stream->decoder = swfdec_video_codec_init (stream->codec, format); - else - stream->decoder = NULL; + stream->decoder = swfdec_video_decoder_new (format); } if (stream->decoder) { - SwfdecBuffer *decoded = swfdec_video_codec_decode (stream->codec, stream->decoder, buffer); - if (decoded) { - static const cairo_user_data_key_t key; - guint w, h; - if (!swfdec_video_codec_get_size (stream->codec, stream->decoder, &w, &h)) { - g_assert_not_reached (); - } - stream->surface = cairo_image_surface_create_for_data (decoded->data, - CAIRO_FORMAT_RGB24, 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); - } - } + stream->surface = swfdec_video_decoder_decode (stream->decoder, buffer); + } + if (stream->surface) { + GList *walk; + for (walk = stream->movies; walk; walk = walk->next) { + swfdec_video_movie_new_image (walk->data, stream->surface); } } } @@ -336,8 +321,10 @@ swfdec_net_stream_dispose (GObject *obje cairo_surface_destroy (stream->surface); stream->surface = NULL; } - if (stream->decoder) - swfdec_video_codec_finish (stream->codec, stream->decoder); + if (stream->decoder) { + swfdec_video_decoder_free (stream->decoder); + stream->decoder = NULL; + } swfdec_net_stream_set_loader (stream, NULL); g_object_unref (stream->conn); stream->conn = NULL; diff --git a/libswfdec/swfdec_net_stream.h b/libswfdec/swfdec_net_stream.h index 7973b5f..9a1ff11 100644 --- a/libswfdec/swfdec_net_stream.h +++ b/libswfdec/swfdec_net_stream.h @@ -21,6 +21,7 @@ #define _SWFDEC_NET_STREAM_H_ #include <libswfdec/swfdec.h> +#include <libswfdec/swfdec_codec_video.h> #include <libswfdec/swfdec_connection.h> #include <libswfdec/swfdec_flv_decoder.h> #include <libswfdec/swfdec_player_internal.h> @@ -58,8 +59,7 @@ struct _SwfdecNetStream guint current_time; /* current playback timestamp */ guint next_time; /* next video image at this timestamp */ SwfdecVideoFormat format; /* current format */ - const SwfdecVideoCodec *codec; /* codec used to decode the video */ - gpointer decoder; /* decoder used for decoding */ + SwfdecVideoDecoder * decoder; /* decoder used for decoding */ cairo_surface_t * surface; /* current image */ SwfdecTimeout timeout; /* timeout to advance to */ SwfdecVideoMovieInput input; /* used when attaching to a video movie */ diff --git a/libswfdec/swfdec_video.c b/libswfdec/swfdec_video.c index 70afa13..eb682b1 100644 --- a/libswfdec/swfdec_video.c +++ b/libswfdec/swfdec_video.c @@ -70,8 +70,6 @@ swfdec_video_input_iterate (SwfdecVideoM { 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; @@ -81,17 +79,8 @@ swfdec_video_input_iterate (SwfdecVideoM if (buffer == NULL) return; - 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 (); - } - surface = cairo_image_surface_create_for_data (buffer->data, - CAIRO_FORMAT_RGB24, 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, w, h); + surface = swfdec_video_decoder_decode (input->decoder, buffer); + swfdec_video_movie_new_image (input->movie, surface); cairo_surface_destroy (surface); } @@ -111,7 +100,7 @@ swfdec_video_input_disconnect (SwfdecVid g_assert (input->movie == movie); if (input->decoder) - swfdec_video_codec_finish (input->video->codec, input->decoder); + swfdec_video_decoder_free (input->decoder); g_object_unref (input->video); g_free (input); } @@ -123,11 +112,8 @@ swfdec_video_input_new (SwfdecVideo *vid if (video->n_frames == 0) return NULL; - if (video->codec == NULL) - return NULL; input = g_new0 (SwfdecVideoInput, 1); - if (video->codec) - input->decoder = swfdec_video_codec_init (video->codec, video->format); + input->decoder = swfdec_video_decoder_new (video->format); if (input->decoder == NULL) { g_free (input); return NULL; @@ -214,13 +200,6 @@ tag_func_define_video (SwfdecSwfDecoder SWFDEC_LOG (" deblocking: %d", deblocking); SWFDEC_LOG (" smoothing: %d", smoothing); SWFDEC_LOG (" format: %d", (int) video->format); - if (video->format != SWFDEC_VIDEO_FORMAT_UNDEFINED) { - video->codec = swfdec_codec_get_video (video->format); - if (video->codec == NULL) { - SWFDEC_WARNING ("no codec for format %d", (int) video->format); - return SWFDEC_STATUS_OK; - } - } return SWFDEC_STATUS_OK; } diff --git a/libswfdec/swfdec_video.h b/libswfdec/swfdec_video.h index 97c997f..a64065b 100644 --- a/libswfdec/swfdec_video.h +++ b/libswfdec/swfdec_video.h @@ -21,7 +21,7 @@ #define _SWFDEC_VIDEO_H_ #include <libswfdec/swfdec_graphic.h> -#include <libswfdec/swfdec_codec.h> +#include <libswfdec/swfdec_codec_video.h> G_BEGIN_DECLS @@ -37,13 +37,12 @@ typedef struct _SwfdecVideoClass SwfdecV struct _SwfdecVideo { SwfdecGraphic graphic; - guint width; /* width in pixels */ - guint height; /* height in pixels */ - guint n_frames; /* length of movie */ + guint width; /* width in pixels */ + guint height; /* height in pixels */ + guint n_frames; /* length of movie */ GArray * images; /* actual images of the movie */ SwfdecVideoFormat format; /* format in use */ - const SwfdecVideoCodec * codec; /* codec for this video (can be NULL) */ }; struct _SwfdecVideoClass { diff --git a/libswfdec/swfdec_video_movie.c b/libswfdec/swfdec_video_movie.c index cf74a92..6c94d73 100644 --- a/libswfdec/swfdec_video_movie.c +++ b/libswfdec/swfdec_video_movie.c @@ -142,20 +142,17 @@ swfdec_video_movie_clear (SwfdecVideoMov } void -swfdec_video_movie_new_image (SwfdecVideoMovie *movie, cairo_surface_t *image, - guint width, guint height) +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); - 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; + movie->image_width = cairo_image_surface_get_width (image); + movie->image_height = cairo_image_surface_get_height (image); swfdec_movie_invalidate (SWFDEC_MOVIE (movie)); } diff --git a/libswfdec/swfdec_video_movie.h b/libswfdec/swfdec_video_movie.h index 87ee9c9..9ba9f1a 100644 --- a/libswfdec/swfdec_video_movie.h +++ b/libswfdec/swfdec_video_movie.h @@ -70,9 +70,7 @@ 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, - guint width, - guint height); + cairo_surface_t * surface); G_END_DECLS #endif diff-tree 25c390688e91b470212ae7eade090d28d0546a00 (from 9df37a6370130977093126a74e1d2341e07399d5) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 6 15:44:43 2007 +0200 fix gnome-vfs integratrion to use the right conversion func I hope this was the last time... diff --git a/player/Makefile.am b/player/Makefile.am index d22e527..11c0b56 100644 --- a/player/Makefile.am +++ b/player/Makefile.am @@ -24,8 +24,8 @@ noinst_HEADERS = \ swfdec_player_manager.h \ swfdec_slow_loader.h -swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS) -swfplay_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS) +swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS) $(GNOMEVFS_CFLAGS) +swfplay_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS) $(GNOMEVFS_LIBS) swfdebug_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS) -DXP_UNIX -I$(top_builddir)/libswfdec/js swfdebug_LDFLAGS = $(GTK_LIBS) $(SWFDEC_GTK_LIBS) diff --git a/player/swfplay.c b/player/swfplay.c index 78c5c48..7cc4dbe 100644 --- a/player/swfplay.c +++ b/player/swfplay.c @@ -25,6 +25,9 @@ #include <libswfdec/swfdec.h> #include <libswfdec-gtk/swfdec-gtk.h> +#if HAVE_GNOMEVFS +#include <libgnomevfs/gnome-vfs.h> +#endif #include "swfdec_slow_loader.h" @@ -76,6 +79,7 @@ main (int argc, char *argv[]) gboolean trace = FALSE; char *variables = NULL; GtkWidget *window; + char *s; GOptionEntry options[] = { { "delay", 'd', 0, G_OPTION_ARG_INT, &delay, "make loading of resources take time", "SECS" }, @@ -109,7 +113,13 @@ main (int argc, char *argv[]) return 1; } +#if HAVE_GNOMEVFS + s = gnome_vfs_make_uri_from_shell_arg (argv[1]); + loader = swfdec_gtk_loader_new (s); + g_free (s); +#else loader = swfdec_gtk_loader_new (argv[1]); +#endif if (loader->error) { g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], loader->error); g_object_unref (loader); diff-tree 9df37a6370130977093126a74e1d2341e07399d5 (from bb03d104fbecb67c43dd6822288f57a73e6897c3) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 6 13:58:50 2007 +0200 back out calling gnome_vfs_make_uri_from_input() LEt the user do this and document that it's a good idea diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c index f0e8c40..1247a30 100644 --- a/libswfdec-gtk/swfdec_gtk_loader.c +++ b/libswfdec-gtk/swfdec_gtk_loader.c @@ -225,8 +225,9 @@ swfdec_gtk_loader_init (SwfdecGtkLoader * * Creates a new loader for the given URI using gnome-vfs (or using the local * file backend, if compiled without gnome-vfs support). The uri must be valid - * UTF-8. If using gnome-vfs, gnome_vfs_make_uri_from_input() will be called on - * @uri. + * UTF-8. If using gnome-vfs, you might want to use + * gnome_vfs_make_uri_from_shell_arg() or gnome_vfs_make_uri_from_input() on + * the @uri prior to calling this function. * * Returns: a new #SwfdecLoader using gnome-vfs. **/ @@ -234,14 +235,11 @@ SwfdecLoader * swfdec_gtk_loader_new (const char *uri) { GnomeVFSURI *guri; - char *s; g_return_val_if_fail (uri != NULL, NULL); gnome_vfs_init (); - s = gnome_vfs_make_uri_from_input (uri); - guri = gnome_vfs_uri_new (s); - g_free (s); + guri = gnome_vfs_uri_new (uri); return swfdec_gtk_loader_new_from_uri (guri); }
Seemingly Similar Threads
- 4 commits - libswfdec/swfdec_audio_flv.c libswfdec/swfdec_audio_stream.c libswfdec/swfdec_codec_adpcm.c libswfdec/swfdec_codec.c libswfdec/swfdec_codec_ffmpeg.c libswfdec/swfdec_codec_gst.c libswfdec/swfdec_codec.h libswfdec/swfdec_codec_mad.c
- configure.ac libswfdec/Makefile.am libswfdec/swfdec_codec.c libswfdec/swfdec_codec_gst.c
- configure.ac libswfdec-gtk/swfdec_gtk_widget.c libswfdec-gtk/swfdec_playback_alsa.c libswfdec/swfdec_as_date.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_types.c libswfdec/swfdec_audio_flv.c libswfdec/swfdec_audio_flv.h
- 4 commits - libswfdec/swfdec_codec_audio.c libswfdec/swfdec_codec_gst.c libswfdec/swfdec_codec_video.c libswfdec/swfdec_sound.c
- 6 commits - libswfdec/Makefile.am libswfdec/swfdec_audio_flv.c libswfdec/swfdec_audio_flv.h libswfdec/swfdec_audio_stream.c libswfdec/swfdec_audio_stream.h libswfdec/swfdec_buffer.c libswfdec/swfdec_codec_adpcm.c libswfdec/swfdec_codec_audio.c