make swfdec_as_object_mark() only mark if not marked yet
[swfdec.git] / swfdec / swfdec_video_movie.c
blob611bdda9084d4753c16bff121d76e0733dc28186
1 /* Swfdec
2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "swfdec_video_movie.h"
25 #include "swfdec_as_strings.h"
26 #include "swfdec_debug.h"
27 #include "swfdec_player_internal.h"
28 #include "swfdec_resource.h"
29 #include "swfdec_renderer_internal.h"
30 #include "swfdec_sandbox.h"
31 #include "swfdec_utils.h"
32 #include "swfdec_video_provider.h"
33 #include "swfdec_video_video_provider.h"
35 G_DEFINE_TYPE (SwfdecVideoMovie, swfdec_video_movie, SWFDEC_TYPE_MOVIE)
37 static void
38 swfdec_video_movie_update_extents (SwfdecMovie *movie,
39 SwfdecRect *extents)
41 SwfdecVideo *org = SWFDEC_VIDEO (movie->graphic);
42 SwfdecRect rect = { 0, 0,
43 SWFDEC_TWIPS_SCALE_FACTOR * org->width,
44 SWFDEC_TWIPS_SCALE_FACTOR * org->height };
46 swfdec_rect_union (extents, extents, &rect);
49 static void
50 swfdec_video_movie_render (SwfdecMovie *mov, cairo_t *cr,
51 const SwfdecColorTransform *trans)
53 SwfdecVideoMovie *movie = SWFDEC_VIDEO_MOVIE (mov);
54 cairo_surface_t *surface;
55 guint width, height;
57 if (movie->provider == NULL || movie->clear)
58 return;
60 surface = swfdec_video_provider_get_image (movie->provider,
61 swfdec_renderer_get (cr), &width, &height);
62 if (surface == NULL)
63 return;
64 cairo_scale (cr,
65 (mov->original_extents.x1 - mov->original_extents.x0)
66 / width,
67 (mov->original_extents.y1 - mov->original_extents.y0)
68 / height);
69 cairo_set_source_surface (cr, surface, 0.0, 0.0);
70 cairo_paint (cr);
71 cairo_surface_destroy (surface);
74 static void
75 swfdec_video_movie_new_image (SwfdecVideoProvider *provider, SwfdecVideoMovie *movie)
77 movie->clear = FALSE;
78 swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
81 static void
82 swfdec_video_movie_dispose (GObject *object)
84 SwfdecVideoMovie *movie = SWFDEC_VIDEO_MOVIE (object);
86 if (movie->provider) {
87 g_signal_handlers_disconnect_by_func (movie->provider,
88 swfdec_video_movie_new_image, movie);
89 g_object_unref (movie->provider);
90 movie->provider = NULL;
93 G_OBJECT_CLASS (swfdec_video_movie_parent_class)->dispose (object);
96 static void
97 swfdec_video_movie_set_ratio (SwfdecMovie *movie)
99 SwfdecVideoMovie *video = SWFDEC_VIDEO_MOVIE (movie);
101 if (video->provider)
102 swfdec_video_provider_set_ratio (video->provider, movie->original_ratio);
105 static void
106 swfdec_video_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last)
108 SwfdecVideo *org = SWFDEC_VIDEO (movie->graphic);
109 SwfdecRect rect = { 0, 0,
110 SWFDEC_TWIPS_SCALE_FACTOR * org->width,
111 SWFDEC_TWIPS_SCALE_FACTOR * org->height };
113 swfdec_rect_transform (&rect, &rect, matrix);
114 swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)),
115 movie, &rect);
118 static GObject *
119 swfdec_video_movie_constructor (GType type, guint n_construct_properties,
120 GObjectConstructParam *construct_properties)
122 GObject *object;
123 SwfdecMovie *movie;
124 SwfdecVideo *video;
125 gboolean unuse;
127 object = G_OBJECT_CLASS (swfdec_video_movie_parent_class)->constructor (type,
128 n_construct_properties, construct_properties);
130 movie = SWFDEC_MOVIE (object);
131 unuse = swfdec_sandbox_try_use (movie->resource->sandbox);
132 swfdec_video_movie_init_properties (swfdec_gc_object_get_context (movie));
133 swfdec_as_object_set_constructor_by_name (swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (movie)),
134 SWFDEC_AS_STR_Video, NULL);
135 if (unuse)
136 swfdec_sandbox_unuse (movie->resource->sandbox);
138 video = SWFDEC_VIDEO (movie->graphic);
140 if (video->n_frames > 0) {
141 SwfdecVideoProvider *provider = swfdec_video_video_provider_new (video);
142 swfdec_video_movie_set_provider (SWFDEC_VIDEO_MOVIE (movie), provider);
143 g_object_unref (provider);
146 return object;
149 static void
150 swfdec_video_movie_class_init (SwfdecVideoMovieClass * g_class)
152 GObjectClass *object_class = G_OBJECT_CLASS (g_class);
153 SwfdecMovieClass *movie_class = SWFDEC_MOVIE_CLASS (g_class);
155 object_class->constructor = swfdec_video_movie_constructor;
156 object_class->dispose = swfdec_video_movie_dispose;
158 movie_class->update_extents = swfdec_video_movie_update_extents;
159 movie_class->render = swfdec_video_movie_render;
160 movie_class->invalidate = swfdec_video_movie_invalidate;
161 movie_class->set_ratio = swfdec_video_movie_set_ratio;
164 static void
165 swfdec_video_movie_init (SwfdecVideoMovie * video_movie)
169 void
170 swfdec_video_movie_set_provider (SwfdecVideoMovie *movie,
171 SwfdecVideoProvider *provider)
173 g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
174 g_return_if_fail (provider == NULL || SWFDEC_IS_VIDEO_PROVIDER (provider));
176 if (provider == movie->provider)
177 return;
179 if (provider) {
180 g_object_ref (provider);
181 g_signal_connect (provider, "new-image",
182 G_CALLBACK (swfdec_video_movie_new_image), movie);
185 if (movie->provider) {
186 g_signal_handlers_disconnect_by_func (movie->provider,
187 swfdec_video_movie_new_image, movie);
188 g_object_unref (movie->provider);
191 movie->provider = provider;
192 swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
195 void
196 swfdec_video_movie_clear (SwfdecVideoMovie *movie)
198 g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
200 movie->clear = TRUE;
201 swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));