back to development
[swfdec.git] / swfdec / swfdec_video_movie.c
blob86aa47f2bf97150926df091ad0ad7046993c47ba
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_utils.h"
31 #include "swfdec_video_provider.h"
32 #include "swfdec_video_video_provider.h"
34 G_DEFINE_TYPE (SwfdecVideoMovie, swfdec_video_movie, SWFDEC_TYPE_MOVIE)
36 static void
37 swfdec_video_movie_update_extents (SwfdecMovie *movie,
38 SwfdecRect *extents)
40 SwfdecVideo *org = SWFDEC_VIDEO (movie->graphic);
41 SwfdecRect rect = { 0, 0,
42 SWFDEC_TWIPS_SCALE_FACTOR * org->width,
43 SWFDEC_TWIPS_SCALE_FACTOR * org->height };
45 swfdec_rect_union (extents, extents, &rect);
48 static void
49 swfdec_video_movie_render (SwfdecMovie *mov, cairo_t *cr,
50 const SwfdecColorTransform *trans)
52 SwfdecVideoMovie *movie = SWFDEC_VIDEO_MOVIE (mov);
53 cairo_surface_t *surface;
54 guint width, height;
56 if (movie->provider == NULL || movie->clear)
57 return;
59 surface = swfdec_video_provider_get_image (movie->provider,
60 swfdec_renderer_get (cr), &width, &height);
61 if (surface == NULL)
62 return;
63 cairo_scale (cr,
64 (mov->original_extents.x1 - mov->original_extents.x0)
65 / width,
66 (mov->original_extents.y1 - mov->original_extents.y0)
67 / height);
68 cairo_set_source_surface (cr, surface, 0.0, 0.0);
69 cairo_paint (cr);
70 cairo_surface_destroy (surface);
73 static void
74 swfdec_video_movie_new_image (SwfdecVideoProvider *provider, SwfdecVideoMovie *movie)
76 movie->clear = FALSE;
77 swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
80 static void
81 swfdec_video_movie_dispose (GObject *object)
83 SwfdecVideoMovie *movie = SWFDEC_VIDEO_MOVIE (object);
85 if (movie->provider) {
86 g_signal_handlers_disconnect_by_func (movie->provider,
87 swfdec_video_movie_new_image, movie);
88 g_object_unref (movie->provider);
89 movie->provider = NULL;
92 G_OBJECT_CLASS (swfdec_video_movie_parent_class)->dispose (object);
95 static void
96 swfdec_video_movie_set_ratio (SwfdecMovie *movie)
98 SwfdecVideoMovie *video = SWFDEC_VIDEO_MOVIE (movie);
100 if (video->provider)
101 swfdec_video_provider_set_ratio (video->provider, movie->original_ratio);
104 static gboolean
105 swfdec_video_movie_get_variable (SwfdecAsObject *object, SwfdecAsObject *orig,
106 const char *variable, SwfdecAsValue *val, guint *flags)
108 guint version = swfdec_gc_object_get_context (object)->version;
109 SwfdecVideoMovie *video;
111 video = SWFDEC_VIDEO_MOVIE (object);
113 if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_width) == 0) {
114 guint w;
115 if (video->provider) {
116 w = swfdec_video_provider_get_width (video->provider);
117 } else {
118 w = 0;
120 SWFDEC_AS_VALUE_SET_INT (val, w);
121 return TRUE;
122 } else if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_height) == 0) {
123 guint h;
124 if (video->provider) {
125 h = swfdec_video_provider_get_height (video->provider);
126 } else {
127 h = 0;
129 SWFDEC_AS_VALUE_SET_INT (val, h);
130 return TRUE;
131 } else if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_deblocking) == 0) {
132 SWFDEC_STUB ("Video.deblocking (get)");
133 SWFDEC_AS_VALUE_SET_NUMBER (val, 0);
134 return TRUE;
135 } else if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_smoothing) == 0) {
136 SWFDEC_STUB ("Video.smoothing (get)");
137 SWFDEC_AS_VALUE_SET_BOOLEAN (val, FALSE);
138 return TRUE;
139 } else {
140 return SWFDEC_AS_OBJECT_CLASS (swfdec_video_movie_parent_class)->get (
141 object, orig, variable, val, flags);
145 static void
146 swfdec_video_movie_set_variable (SwfdecAsObject *object, const char *variable,
147 const SwfdecAsValue *val, guint flags)
149 guint version = swfdec_gc_object_get_context (object)->version;
151 if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_deblocking) == 0) {
152 SWFDEC_STUB ("Video.deblocking (set)");
153 } else if (swfdec_strcmp (version, variable, SWFDEC_AS_STR_smoothing) == 0) {
154 SWFDEC_STUB ("Video.smoothing (set)");
155 } else {
156 SWFDEC_AS_OBJECT_CLASS (swfdec_video_movie_parent_class)->set (object,
157 variable, val, flags);
161 static gboolean
162 swfdec_video_movie_foreach_variable (SwfdecAsObject *object, SwfdecAsVariableForeach func, gpointer data)
164 const char *native_variables[] = { SWFDEC_AS_STR_width, SWFDEC_AS_STR_height,
165 SWFDEC_AS_STR_smoothing, SWFDEC_AS_STR_deblocking, NULL };
166 int i;
168 for (i = 0; native_variables[i] != NULL; i++) {
169 SwfdecAsValue val;
170 swfdec_as_object_get_variable (object, native_variables[i], &val);
171 if (!func (object, native_variables[i], &val, 0, data))
172 return FALSE;
175 return SWFDEC_AS_OBJECT_CLASS (swfdec_video_movie_parent_class)->foreach (
176 object, func, data);
179 static void
180 swfdec_video_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gboolean last)
182 SwfdecVideo *org = SWFDEC_VIDEO (movie->graphic);
183 SwfdecRect rect = { 0, 0,
184 SWFDEC_TWIPS_SCALE_FACTOR * org->width,
185 SWFDEC_TWIPS_SCALE_FACTOR * org->height };
187 swfdec_rect_transform (&rect, &rect, matrix);
188 swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
191 static GObject *
192 swfdec_video_movie_constructor (GType type, guint n_construct_properties,
193 GObjectConstructParam *construct_properties)
195 GObject *object;
196 SwfdecMovie *movie;
197 SwfdecVideo *video;
199 object = G_OBJECT_CLASS (swfdec_video_movie_parent_class)->constructor (type,
200 n_construct_properties, construct_properties);
202 movie = SWFDEC_MOVIE (object);
203 swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), movie->resource->sandbox->Video);
205 video = SWFDEC_VIDEO (movie->graphic);
207 if (video->n_frames > 0) {
208 SwfdecVideoProvider *provider = swfdec_video_video_provider_new (video);
209 swfdec_video_movie_set_provider (SWFDEC_VIDEO_MOVIE (movie), provider);
210 g_object_unref (provider);
213 return object;
216 static void
217 swfdec_video_movie_class_init (SwfdecVideoMovieClass * g_class)
219 GObjectClass *object_class = G_OBJECT_CLASS (g_class);
220 SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (g_class);
221 SwfdecMovieClass *movie_class = SWFDEC_MOVIE_CLASS (g_class);
223 object_class->constructor = swfdec_video_movie_constructor;
224 object_class->dispose = swfdec_video_movie_dispose;
226 asobject_class->get = swfdec_video_movie_get_variable;
227 asobject_class->set = swfdec_video_movie_set_variable;
228 asobject_class->foreach = swfdec_video_movie_foreach_variable;
230 movie_class->update_extents = swfdec_video_movie_update_extents;
231 movie_class->render = swfdec_video_movie_render;
232 movie_class->invalidate = swfdec_video_movie_invalidate;
233 movie_class->set_ratio = swfdec_video_movie_set_ratio;
236 static void
237 swfdec_video_movie_init (SwfdecVideoMovie * video_movie)
241 void
242 swfdec_video_movie_set_provider (SwfdecVideoMovie *movie,
243 SwfdecVideoProvider *provider)
245 g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
246 g_return_if_fail (provider == NULL || SWFDEC_IS_VIDEO_PROVIDER (provider));
248 if (provider == movie->provider)
249 return;
251 if (provider) {
252 g_object_ref (provider);
253 g_signal_connect (provider, "new-image",
254 G_CALLBACK (swfdec_video_movie_new_image), movie);
257 if (movie->provider) {
258 g_signal_handlers_disconnect_by_func (movie->provider,
259 swfdec_video_movie_new_image, movie);
260 g_object_unref (movie->provider);
263 movie->provider = provider;
264 swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));
267 void
268 swfdec_video_movie_clear (SwfdecVideoMovie *movie)
270 g_return_if_fail (SWFDEC_IS_VIDEO_MOVIE (movie));
272 movie->clear = TRUE;
273 swfdec_movie_invalidate_last (SWFDEC_MOVIE (movie));