2 * Copyright (C) 2004 Benjamin Otte <otte@gnome.org>
3 * 2012 Stefan Sauer <ensonic@users.sf.net>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
27 GST_DEBUG_CATEGORY_EXTERN (libvisual_debug);
28 #define GST_CAT_DEFAULT (libvisual_debug)
30 /* amounf of samples before we can feed libvisual */
31 #define VISUAL_SAMPLES 512
33 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
36 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (" { "
37 #if G_BYTE_ORDER == G_BIG_ENDIAN
38 "\"xRGB\", " "\"RGB\", "
40 "\"BGRx\", " "\"BGR\", "
45 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
48 GST_STATIC_CAPS ("audio/x-raw, "
49 "format = (string) " GST_AUDIO_NE (S16) ", "
50 "layout = (string) interleaved, " "channels = (int) { 1, 2 }, "
51 "channel-mask = (bitmask) 0x3, "
52 #if defined(VISUAL_API_VERSION) && VISUAL_API_VERSION >= 4000 && VISUAL_API_VERSION < 5000
53 "rate = (int) { 8000, 11250, 22500, 32000, 44100, 48000, 96000 }"
55 "rate = (int) [ 1000, MAX ]"
61 static void gst_visual_init (GstVisual * visual);
62 static void gst_visual_finalize (GObject * object);
64 static gboolean gst_visual_setup (GstAudioBaseVisualizer * bscope);
65 static gboolean gst_visual_render (GstAudioBaseVisualizer * bscope,
66 GstBuffer * audio, GstBuffer * video);
68 static GstElementClass *parent_class = NULL;
71 gst_visual_get_type (void)
73 static GType type = 0;
75 if (G_UNLIKELY (type == 0)) {
76 static const GTypeInfo info = {
77 sizeof (GstVisualClass),
80 gst_visual_class_init,
85 (GInstanceInitFunc) gst_visual_init,
89 g_type_register_static (GST_TYPE_AUDIO_BASE_VISUALIZER, "GstVisual",
96 gst_visual_class_init (gpointer g_class, gpointer class_data)
98 GObjectClass *gobject_class = (GObjectClass *) g_class;
99 GstElementClass *element_class = (GstElementClass *) g_class;
100 GstAudioBaseVisualizerClass *scope_class =
101 (GstAudioBaseVisualizerClass *) g_class;
102 GstVisualClass *klass = (GstVisualClass *) g_class;
104 klass->plugin = class_data;
106 if (class_data == NULL) {
107 parent_class = g_type_class_peek_parent (g_class);
109 gchar *longname = g_strdup_printf ("libvisual %s plugin v.%s",
110 klass->plugin->info->name, klass->plugin->info->version);
112 /* FIXME: improve to only register what plugin supports? */
113 gst_element_class_add_pad_template (element_class,
114 gst_static_pad_template_get (&src_template));
115 gst_element_class_add_pad_template (element_class,
116 gst_static_pad_template_get (&sink_template));
118 gst_element_class_set_static_metadata (element_class,
119 longname, "Visualization",
120 klass->plugin->info->about, "Benjamin Otte <otte@gnome.org>");
125 gobject_class->finalize = gst_visual_finalize;
127 scope_class->setup = GST_DEBUG_FUNCPTR (gst_visual_setup);
128 scope_class->render = GST_DEBUG_FUNCPTR (gst_visual_render);
132 gst_visual_init (GstVisual * visual)
138 gst_visual_clear_actors (GstVisual * visual)
141 visual_object_unref (VISUAL_OBJECT (visual->actor));
142 visual->actor = NULL;
145 visual_object_unref (VISUAL_OBJECT (visual->video));
146 visual->video = NULL;
149 visual_object_unref (VISUAL_OBJECT (visual->audio));
150 visual->audio = NULL;
155 gst_visual_finalize (GObject * object)
157 GstVisual *visual = GST_VISUAL (object);
159 gst_visual_clear_actors (visual);
161 GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
165 gst_visual_setup (GstAudioBaseVisualizer * bscope)
167 GstVisual *visual = GST_VISUAL (bscope);
170 gst_visual_clear_actors (visual);
172 depth = bscope->vinfo.finfo->pixel_stride[0];
173 if (bscope->vinfo.finfo->bits >= 8) {
178 visual_actor_new (GST_VISUAL_GET_CLASS (visual)->plugin->info->plugname);
179 visual->video = visual_video_new ();
180 visual->audio = visual_audio_new ();
181 /* can't have a play without actors */
182 if (!visual->actor || !visual->video)
185 if (visual_actor_realize (visual->actor) != 0)
188 visual_actor_set_video (visual->actor, visual->video);
190 visual_video_set_depth (visual->video,
191 visual_video_depth_enum_from_value (depth));
192 visual_video_set_dimension (visual->video, bscope->width, bscope->height);
193 pitch = GST_ROUND_UP_4 (bscope->width * visual->video->bpp);
194 visual_video_set_pitch (visual->video, pitch);
195 visual_actor_video_negotiate (visual->actor, 0, FALSE, FALSE);
197 GST_DEBUG_OBJECT (visual, "WxH: %dx%d, bpp: %d, pitch: %d, depth: %d",
198 bscope->width, bscope->height, visual->video->bpp, pitch, depth);
204 GST_ELEMENT_ERROR (visual, LIBRARY, INIT, (NULL),
205 ("could not create actors"));
206 gst_visual_clear_actors (visual);
211 GST_ELEMENT_ERROR (visual, LIBRARY, INIT, (NULL),
212 ("could not realize actor"));
213 gst_visual_clear_actors (visual);
219 gst_visual_render (GstAudioBaseVisualizer * bscope, GstBuffer * audio,
222 GstVisual *visual = GST_VISUAL (bscope);
223 GstMapInfo amap, vmap;
224 const guint16 *adata;
228 gst_buffer_map (audio, &amap, GST_MAP_READ);
229 gst_buffer_map (video, &vmap, GST_MAP_WRITE);
231 visual_video_set_buffer (visual->video, vmap.data);
233 channels = GST_AUDIO_INFO_CHANNELS (&bscope->ainfo);
234 adata = (const guint16 *) amap.data;
236 #if defined(VISUAL_API_VERSION) && VISUAL_API_VERSION >= 4000 && VISUAL_API_VERSION < 5000
238 VisBuffer *lbuf, *rbuf;
239 guint16 ldata[VISUAL_SAMPLES], rdata[VISUAL_SAMPLES];
240 VisAudioSampleRateType vrate;
242 lbuf = visual_buffer_new_with_buffer (ldata, sizeof (ldata), NULL);
243 rbuf = visual_buffer_new_with_buffer (rdata, sizeof (rdata), NULL);
246 for (i = 0; i < VISUAL_SAMPLES; i++) {
251 for (i = 0; i < VISUAL_SAMPLES; i++) {
257 /* TODO(ensonic): move to setup */
258 switch (bscope->ainfo.rate) {
260 vrate = VISUAL_AUDIO_SAMPLE_RATE_8000;
263 vrate = VISUAL_AUDIO_SAMPLE_RATE_11250;
266 vrate = VISUAL_AUDIO_SAMPLE_RATE_22500;
269 vrate = VISUAL_AUDIO_SAMPLE_RATE_32000;
272 vrate = VISUAL_AUDIO_SAMPLE_RATE_44100;
275 vrate = VISUAL_AUDIO_SAMPLE_RATE_48000;
278 vrate = VISUAL_AUDIO_SAMPLE_RATE_96000;
281 visual_object_unref (VISUAL_OBJECT (lbuf));
282 visual_object_unref (VISUAL_OBJECT (rbuf));
283 GST_ERROR_OBJECT (visual, "unsupported rate %d", bscope->ainfo.rate);
288 visual_audio_samplepool_input_channel (visual->audio->samplepool,
290 vrate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
291 (char *) VISUAL_AUDIO_CHANNEL_LEFT);
292 visual_audio_samplepool_input_channel (visual->audio->samplepool, rbuf,
293 vrate, VISUAL_AUDIO_SAMPLE_FORMAT_S16,
294 (char *) VISUAL_AUDIO_CHANNEL_RIGHT);
296 visual_object_unref (VISUAL_OBJECT (lbuf));
297 visual_object_unref (VISUAL_OBJECT (rbuf));
302 guint16 *ldata = visual->audio->plugpcm[0];
303 guint16 *rdata = visual->audio->plugpcm[1];
304 for (i = 0; i < VISUAL_SAMPLES; i++) {
309 for (i = 0; i < VISUAL_SAMPLES; i++) {
316 visual_audio_analyze (visual->audio);
317 visual_actor_run (visual->actor, visual->audio);
318 visual_video_set_buffer (visual->video, NULL);
320 GST_DEBUG_OBJECT (visual, "rendered one frame");
322 gst_buffer_unmap (video, &vmap);
323 gst_buffer_unmap (audio, &amap);