1 /* GStreamer LADSPA source category
2 * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
4 * 2003 Andy Wingo <wingo at pobox.com>
5 * Copyright (C) 2005 Stefan Kost <ensonic@users.sf.net> (audiotestsrc)
6 * Copyright (C) 2013 Juan Manuel Borges Caño <juanmabcmail@gmail.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "gstladspasource.h"
29 #include "gstladspa.h"
30 #include "gstladspautils.h"
31 #include <gst/base/gstbasetransform.h>
32
33 GST_DEBUG_CATEGORY_EXTERN (ladspa_debug);
34 #define GST_CAT_DEFAULT ladspa_debug
35
36 #define GST_LADSPA_SOURCE_CLASS_TAGS "Source/Audio/LADSPA"
37 #define GST_LADSPA_SOURCE_DEFAULT_SAMPLES_PER_BUFFER 1024
38 #define GST_LADSPA_SOURCE_DEFAULT_IS_LIVE FALSE
39 #define GST_LADSPA_SOURCE_DEFAULT_TIMESTAMP_OFFSET G_GINT64_CONSTANT (0)
40 #define GST_LADSPA_SOURCE_DEFAULT_CAN_ACTIVATE_PUSH TRUE
41 #define GST_LADSPA_SOURCE_DEFAULT_CAN_ACTIVATE_PULL FALSE
42
43 enum
44 {
45 GST_LADSPA_SOURCE_PROP_0,
46 GST_LADSPA_SOURCE_PROP_SAMPLES_PER_BUFFER,
47 GST_LADSPA_SOURCE_PROP_IS_LIVE,
48 GST_LADSPA_SOURCE_PROP_TIMESTAMP_OFFSET,
49 GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PUSH,
50 GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PULL,
51 GST_LADSPA_SOURCE_PROP_LAST
52 };
53
54 static GstLADSPASourceClass *gst_ladspa_source_type_parent_class = NULL;
55
56 /*
57 * Boilerplates BaseSrc add pad.
58 */
59 void
gst_my_base_source_class_add_pad_template(GstBaseSrcClass * base_class,GstCaps * srccaps)60 gst_my_base_source_class_add_pad_template (GstBaseSrcClass * base_class,
61 GstCaps * srccaps)
62 {
63 GstElementClass *elem_class = GST_ELEMENT_CLASS (base_class);
64 GstPadTemplate *pad_template;
65
66 g_return_if_fail (GST_IS_CAPS (srccaps));
67
68 pad_template =
69 gst_pad_template_new (GST_BASE_TRANSFORM_SRC_NAME, GST_PAD_SRC,
70 GST_PAD_ALWAYS, srccaps);
71 gst_element_class_add_pad_template (elem_class, pad_template);
72 }
73
74 static GstCaps *
gst_ladspa_source_type_fixate(GstBaseSrc * base,GstCaps * caps)75 gst_ladspa_source_type_fixate (GstBaseSrc * base, GstCaps * caps)
76 {
77 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
78 GstStructure *structure;
79
80 caps = gst_caps_make_writable (caps);
81
82 structure = gst_caps_get_structure (caps, 0);
83
84 GST_DEBUG_OBJECT (ladspa, "fixating samplerate to %d", GST_AUDIO_DEF_RATE);
85
86 gst_structure_fixate_field_nearest_int (structure, "rate",
87 GST_AUDIO_DEF_RATE);
88
89 gst_structure_fixate_field_string (structure, "format", GST_AUDIO_NE (F32));
90
91 gst_structure_fixate_field_nearest_int (structure, "channels",
92 ladspa->ladspa.klass->count.audio.out);
93
94 caps =
95 GST_BASE_SRC_CLASS (gst_ladspa_source_type_parent_class)->fixate
96 (base, caps);
97
98 return caps;
99 }
100
101 static gboolean
gst_ladspa_source_type_set_caps(GstBaseSrc * base,GstCaps * caps)102 gst_ladspa_source_type_set_caps (GstBaseSrc * base, GstCaps * caps)
103 {
104 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
105 GstAudioInfo info;
106
107 if (!gst_audio_info_from_caps (&info, caps)) {
108 GST_ERROR_OBJECT (base, "received invalid caps");
109 return FALSE;
110 }
111
112 GST_DEBUG_OBJECT (ladspa, "negotiated to caps %" GST_PTR_FORMAT, caps);
113
114 ladspa->info = info;
115
116 gst_base_src_set_blocksize (base,
117 GST_AUDIO_INFO_BPF (&info) * ladspa->samples_per_buffer);
118
119 return gst_ladspa_setup (&ladspa->ladspa, GST_AUDIO_INFO_RATE (&info));
120 }
121
122 static gboolean
gst_ladspa_source_type_query(GstBaseSrc * base,GstQuery * query)123 gst_ladspa_source_type_query (GstBaseSrc * base, GstQuery * query)
124 {
125 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
126 gboolean res = FALSE;
127
128 switch (GST_QUERY_TYPE (query)) {
129 case GST_QUERY_CONVERT:
130 {
131 GstFormat src_fmt, dest_fmt;
132 gint64 src_val, dest_val;
133
134 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
135
136 if (!gst_audio_info_convert (&ladspa->info, src_fmt, src_val, dest_fmt,
137 &dest_val)) {
138 GST_DEBUG_OBJECT (ladspa, "query failed");
139 return FALSE;
140 }
141
142 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
143 res = TRUE;
144 break;
145 }
146 case GST_QUERY_SCHEDULING:
147 {
148 /* if we can operate in pull mode */
149 gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0);
150 gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
151 if (ladspa->can_activate_pull)
152 gst_query_add_scheduling_mode (query, GST_PAD_MODE_PULL);
153
154 res = TRUE;
155 break;
156 }
157 default:
158 res =
159 GST_BASE_SRC_CLASS (gst_ladspa_source_type_parent_class)->query
160 (base, query);
161 break;
162 }
163
164 return res;
165 }
166
167 static void
gst_ladspa_source_type_get_times(GstBaseSrc * base,GstBuffer * buffer,GstClockTime * start,GstClockTime * end)168 gst_ladspa_source_type_get_times (GstBaseSrc * base, GstBuffer * buffer,
169 GstClockTime * start, GstClockTime * end)
170 {
171 /* for live sources, sync on the timestamp of the buffer */
172 if (gst_base_src_is_live (base)) {
173 GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
174
175 if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
176 /* get duration to calculate end time */
177 GstClockTime duration = GST_BUFFER_DURATION (buffer);
178
179 if (GST_CLOCK_TIME_IS_VALID (duration)) {
180 *end = timestamp + duration;
181 }
182 *start = timestamp;
183 }
184 } else {
185 *start = -1;
186 *end = -1;
187 }
188 }
189
190 /* seek to time, will be called when we operate in push mode. In pull mode we
191 * get the requested byte offset. */
192 static gboolean
gst_ladspa_source_type_do_seek(GstBaseSrc * base,GstSegment * segment)193 gst_ladspa_source_type_do_seek (GstBaseSrc * base, GstSegment * segment)
194 {
195 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
196 GstClockTime time;
197 gint samplerate, bpf;
198 gint64 next_sample;
199
200 GST_DEBUG_OBJECT (ladspa, "seeking %" GST_SEGMENT_FORMAT, segment);
201
202 time = segment->position;
203 ladspa->reverse = (segment->rate < 0.0);
204
205 samplerate = GST_AUDIO_INFO_RATE (&ladspa->info);
206 bpf = GST_AUDIO_INFO_BPF (&ladspa->info);
207
208 /* now move to the time indicated, don't seek to the sample *after* the time */
209 next_sample = gst_util_uint64_scale_int (time, samplerate, GST_SECOND);
210 ladspa->next_byte = next_sample * bpf;
211 if (samplerate == 0)
212 ladspa->next_time = 0;
213 else
214 ladspa->next_time =
215 gst_util_uint64_scale_round (next_sample, GST_SECOND, samplerate);
216
217 GST_DEBUG_OBJECT (ladspa, "seeking next_sample=%" G_GINT64_FORMAT
218 " next_time=%" GST_TIME_FORMAT, next_sample,
219 GST_TIME_ARGS (ladspa->next_time));
220
221 g_assert (ladspa->next_time <= time);
222
223 ladspa->next_sample = next_sample;
224
225 if (!ladspa->reverse) {
226 if (GST_CLOCK_TIME_IS_VALID (segment->start)) {
227 segment->time = segment->start;
228 }
229 } else {
230 if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
231 segment->time = segment->stop;
232 }
233 }
234
235 if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
236 time = segment->stop;
237 ladspa->sample_stop =
238 gst_util_uint64_scale_round (time, samplerate, GST_SECOND);
239 ladspa->check_seek_stop = TRUE;
240 } else {
241 ladspa->check_seek_stop = FALSE;
242 }
243 ladspa->eos_reached = FALSE;
244
245 return TRUE;
246 }
247
248 static gboolean
gst_ladspa_source_type_is_seekable(GstBaseSrc * base)249 gst_ladspa_source_type_is_seekable (GstBaseSrc * base)
250 {
251 /* we're seekable... */
252 return TRUE;
253 }
254
255 static GstFlowReturn
gst_ladspa_source_type_fill(GstBaseSrc * base,guint64 offset,guint length,GstBuffer * buffer)256 gst_ladspa_source_type_fill (GstBaseSrc * base, guint64 offset,
257 guint length, GstBuffer * buffer)
258 {
259 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
260 GstClockTime next_time;
261 gint64 next_sample, next_byte;
262 gint bytes, samples;
263 GstElementClass *eclass;
264 GstMapInfo map;
265 gint samplerate, bpf;
266
267 /* example for tagging generated data */
268 if (!ladspa->tags_pushed) {
269 GstTagList *taglist;
270
271 taglist = gst_tag_list_new (GST_TAG_DESCRIPTION, "ladspa wave", NULL);
272
273 eclass = GST_ELEMENT_CLASS (gst_ladspa_source_type_parent_class);
274 if (eclass->send_event)
275 eclass->send_event (GST_ELEMENT (base), gst_event_new_tag (taglist));
276 else
277 gst_tag_list_unref (taglist);
278 ladspa->tags_pushed = TRUE;
279 }
280
281 if (ladspa->eos_reached) {
282 GST_INFO_OBJECT (ladspa, "eos");
283 return GST_FLOW_EOS;
284 }
285
286 samplerate = GST_AUDIO_INFO_RATE (&ladspa->info);
287 bpf = GST_AUDIO_INFO_BPF (&ladspa->info);
288
289 /* if no length was given, use our default length in samples otherwise convert
290 * the length in bytes to samples. */
291 if (length == -1)
292 samples = ladspa->samples_per_buffer;
293 else
294 samples = length / bpf;
295
296 /* if no offset was given, use our next logical byte */
297 if (offset == -1)
298 offset = ladspa->next_byte;
299
300 /* now see if we are at the byteoffset we think we are */
301 if (offset != ladspa->next_byte) {
302 GST_DEBUG_OBJECT (ladspa, "seek to new offset %" G_GUINT64_FORMAT, offset);
303 /* we have a discont in the expected sample offset, do a 'seek' */
304 ladspa->next_sample = offset / bpf;
305 ladspa->next_time =
306 gst_util_uint64_scale_int (ladspa->next_sample, GST_SECOND, samplerate);
307 ladspa->next_byte = offset;
308 }
309
310 /* check for eos */
311 if (ladspa->check_seek_stop &&
312 (ladspa->sample_stop > ladspa->next_sample) &&
313 (ladspa->sample_stop < ladspa->next_sample + samples)
314 ) {
315 /* calculate only partial buffer */
316 ladspa->generate_samples_per_buffer =
317 ladspa->sample_stop - ladspa->next_sample;
318 next_sample = ladspa->sample_stop;
319 ladspa->eos_reached = TRUE;
320 } else {
321 /* calculate full buffer */
322 ladspa->generate_samples_per_buffer = samples;
323 next_sample =
324 ladspa->next_sample + (ladspa->reverse ? (-samples) : samples);
325 }
326
327 bytes = ladspa->generate_samples_per_buffer * bpf;
328
329 next_byte = ladspa->next_byte + (ladspa->reverse ? (-bytes) : bytes);
330 next_time = gst_util_uint64_scale_int (next_sample, GST_SECOND, samplerate);
331
332 GST_LOG_OBJECT (ladspa, "samplerate %d", samplerate);
333 GST_LOG_OBJECT (ladspa,
334 "next_sample %" G_GINT64_FORMAT ", ts %" GST_TIME_FORMAT, next_sample,
335 GST_TIME_ARGS (next_time));
336
337 gst_buffer_set_size (buffer, bytes);
338
339 GST_BUFFER_OFFSET (buffer) = ladspa->next_sample;
340 GST_BUFFER_OFFSET_END (buffer) = next_sample;
341 if (!ladspa->reverse) {
342 GST_BUFFER_TIMESTAMP (buffer) =
343 ladspa->timestamp_offset + ladspa->next_time;
344 GST_BUFFER_DURATION (buffer) = next_time - ladspa->next_time;
345 } else {
346 GST_BUFFER_TIMESTAMP (buffer) = ladspa->timestamp_offset + next_time;
347 GST_BUFFER_DURATION (buffer) = ladspa->next_time - next_time;
348 }
349
350 gst_object_sync_values (GST_OBJECT (ladspa), GST_BUFFER_TIMESTAMP (buffer));
351
352 ladspa->next_time = next_time;
353 ladspa->next_sample = next_sample;
354 ladspa->next_byte = next_byte;
355
356 GST_LOG_OBJECT (ladspa, "generating %u samples at ts %" GST_TIME_FORMAT,
357 ladspa->generate_samples_per_buffer,
358 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
359
360 gst_buffer_map (buffer, &map, GST_MAP_WRITE);
361 gst_ladspa_transform (&ladspa->ladspa, map.data,
362 ladspa->generate_samples_per_buffer, NULL);
363 gst_buffer_unmap (buffer, &map);
364
365 return GST_FLOW_OK;
366 }
367
368 static gboolean
gst_ladspa_source_type_start(GstBaseSrc * base)369 gst_ladspa_source_type_start (GstBaseSrc * base)
370 {
371 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
372
373 ladspa->next_sample = 0;
374 ladspa->next_byte = 0;
375 ladspa->next_time = 0;
376 ladspa->check_seek_stop = FALSE;
377 ladspa->eos_reached = FALSE;
378 ladspa->tags_pushed = FALSE;
379
380 return TRUE;
381 }
382
383 static gboolean
gst_ladspa_source_type_stop(GstBaseSrc * base)384 gst_ladspa_source_type_stop (GstBaseSrc * base)
385 {
386 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (base);
387 return gst_ladspa_cleanup (&ladspa->ladspa);
388 }
389
390 static void
gst_ladspa_source_type_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)391 gst_ladspa_source_type_set_property (GObject * object, guint prop_id,
392 const GValue * value, GParamSpec * pspec)
393 {
394 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (object);
395
396 switch (prop_id) {
397 case GST_LADSPA_SOURCE_PROP_SAMPLES_PER_BUFFER:
398 ladspa->samples_per_buffer = g_value_get_int (value);
399 gst_base_src_set_blocksize (GST_BASE_SRC (ladspa),
400 GST_AUDIO_INFO_BPF (&ladspa->info) * ladspa->samples_per_buffer);
401 break;
402 case GST_LADSPA_SOURCE_PROP_IS_LIVE:
403 gst_base_src_set_live (GST_BASE_SRC (ladspa),
404 g_value_get_boolean (value));
405 break;
406 case GST_LADSPA_SOURCE_PROP_TIMESTAMP_OFFSET:
407 ladspa->timestamp_offset = g_value_get_int64 (value);
408 break;
409 case GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PUSH:
410 GST_BASE_SRC (ladspa)->can_activate_push = g_value_get_boolean (value);
411 break;
412 case GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PULL:
413 ladspa->can_activate_pull = g_value_get_boolean (value);
414 break;
415 default:
416 gst_ladspa_object_set_property (&ladspa->ladspa, object, prop_id, value,
417 pspec);
418 break;
419 }
420 }
421
422 static void
gst_ladspa_source_type_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)423 gst_ladspa_source_type_get_property (GObject * object, guint prop_id,
424 GValue * value, GParamSpec * pspec)
425 {
426 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (object);
427
428 switch (prop_id) {
429 case GST_LADSPA_SOURCE_PROP_SAMPLES_PER_BUFFER:
430 g_value_set_int (value, ladspa->samples_per_buffer);
431 break;
432 case GST_LADSPA_SOURCE_PROP_IS_LIVE:
433 g_value_set_boolean (value, gst_base_src_is_live (GST_BASE_SRC (ladspa)));
434 break;
435 case GST_LADSPA_SOURCE_PROP_TIMESTAMP_OFFSET:
436 g_value_set_int64 (value, ladspa->timestamp_offset);
437 break;
438 case GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PUSH:
439 g_value_set_boolean (value, GST_BASE_SRC (ladspa)->can_activate_push);
440 break;
441 case GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PULL:
442 g_value_set_boolean (value, ladspa->can_activate_pull);
443 break;
444 default:
445 gst_ladspa_object_get_property (&ladspa->ladspa, object, prop_id, value,
446 pspec);
447 break;
448 }
449 }
450
451 static void
gst_ladspa_source_type_init(GstLADSPASource * ladspa,LADSPA_Descriptor * desc)452 gst_ladspa_source_type_init (GstLADSPASource * ladspa, LADSPA_Descriptor * desc)
453 {
454 GstLADSPASourceClass *ladspa_class = GST_LADSPA_SOURCE_GET_CLASS (ladspa);
455
456 gst_ladspa_init (&ladspa->ladspa, &ladspa_class->ladspa);
457
458 /* we operate in time */
459 gst_base_src_set_format (GST_BASE_SRC (ladspa), GST_FORMAT_TIME);
460 gst_base_src_set_live (GST_BASE_SRC (ladspa),
461 GST_LADSPA_SOURCE_DEFAULT_IS_LIVE);
462
463 ladspa->samples_per_buffer = GST_LADSPA_SOURCE_DEFAULT_SAMPLES_PER_BUFFER;
464 ladspa->generate_samples_per_buffer = ladspa->samples_per_buffer;
465 ladspa->timestamp_offset = GST_LADSPA_SOURCE_DEFAULT_TIMESTAMP_OFFSET;
466 ladspa->can_activate_pull = GST_LADSPA_SOURCE_DEFAULT_CAN_ACTIVATE_PULL;
467
468 gst_base_src_set_blocksize (GST_BASE_SRC (ladspa), -1);
469 }
470
471 static void
gst_ladspa_source_type_dispose(GObject * object)472 gst_ladspa_source_type_dispose (GObject * object)
473 {
474 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (object);
475
476 gst_ladspa_cleanup (&ladspa->ladspa);
477
478 G_OBJECT_CLASS (gst_ladspa_source_type_parent_class)->dispose (object);
479 }
480
481 static void
gst_ladspa_source_type_finalize(GObject * object)482 gst_ladspa_source_type_finalize (GObject * object)
483 {
484 GstLADSPASource *ladspa = GST_LADSPA_SOURCE (object);
485
486 gst_ladspa_finalize (&ladspa->ladspa);
487
488 G_OBJECT_CLASS (gst_ladspa_source_type_parent_class)->finalize (object);
489 }
490
491 /*
492 * It is okay for plugins to 'leak' a one-time allocation. This will be freed when
493 * the application exits. When the plugins are scanned for the first time, this is
494 * done from a separate process to not impose the memory overhead on the calling
495 * application (among other reasons). Hence no need for class_finalize.
496 */
497 static void
gst_ladspa_source_type_base_init(GstLADSPASourceClass * ladspa_class)498 gst_ladspa_source_type_base_init (GstLADSPASourceClass * ladspa_class)
499 {
500 GstElementClass *elem_class = GST_ELEMENT_CLASS (ladspa_class);
501 GstBaseSrcClass *base_class = GST_BASE_SRC_CLASS (ladspa_class);
502
503 gst_ladspa_class_init (&ladspa_class->ladspa,
504 G_TYPE_FROM_CLASS (ladspa_class));
505
506 gst_ladspa_element_class_set_metadata (&ladspa_class->ladspa, elem_class,
507 GST_LADSPA_SOURCE_CLASS_TAGS);
508
509 gst_ladspa_source_type_class_add_pad_template (&ladspa_class->ladspa,
510 base_class);
511 }
512
513 static void
gst_ladspa_source_type_base_finalize(GstLADSPASourceClass * ladspa_class)514 gst_ladspa_source_type_base_finalize (GstLADSPASourceClass * ladspa_class)
515 {
516 gst_ladspa_class_finalize (&ladspa_class->ladspa);
517 }
518
519 static void
gst_ladspa_source_type_class_init(GstLADSPASourceClass * ladspa_class,LADSPA_Descriptor * desc)520 gst_ladspa_source_type_class_init (GstLADSPASourceClass * ladspa_class,
521 LADSPA_Descriptor * desc)
522 {
523 GObjectClass *object_class = (GObjectClass *) ladspa_class;
524 GstBaseSrcClass *base_class = (GstBaseSrcClass *) ladspa_class;
525
526 gst_ladspa_source_type_parent_class = g_type_class_peek_parent (ladspa_class);
527
528 object_class->dispose = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_dispose);
529 object_class->finalize = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_finalize);
530 object_class->set_property =
531 GST_DEBUG_FUNCPTR (gst_ladspa_source_type_set_property);
532 object_class->get_property =
533 GST_DEBUG_FUNCPTR (gst_ladspa_source_type_get_property);
534
535 base_class->set_caps = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_set_caps);
536 base_class->fixate = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_fixate);
537 base_class->is_seekable =
538 GST_DEBUG_FUNCPTR (gst_ladspa_source_type_is_seekable);
539 base_class->do_seek = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_do_seek);
540 base_class->query = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_query);
541 base_class->get_times = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_get_times);
542 base_class->start = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_start);
543 base_class->stop = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_stop);
544 base_class->fill = GST_DEBUG_FUNCPTR (gst_ladspa_source_type_fill);
545
546 g_object_class_install_property (object_class,
547 GST_LADSPA_SOURCE_PROP_SAMPLES_PER_BUFFER,
548 g_param_spec_int ("samplesperbuffer", "Samples per buffer",
549 "Number of samples in each outgoing buffer", 1, G_MAXINT,
550 GST_LADSPA_SOURCE_DEFAULT_SAMPLES_PER_BUFFER,
551 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
552
553 g_object_class_install_property (object_class, GST_LADSPA_SOURCE_PROP_IS_LIVE,
554 g_param_spec_boolean ("is-live", "Is Live",
555 "Whether to act as a live source", GST_LADSPA_SOURCE_DEFAULT_IS_LIVE,
556 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
557
558 g_object_class_install_property (object_class,
559 GST_LADSPA_SOURCE_PROP_TIMESTAMP_OFFSET,
560 g_param_spec_int64 ("timestamp-offset", "Timestamp offset",
561 "An offset added to timestamps set on buffers (in ns)", G_MININT64,
562 G_MAXINT64, GST_LADSPA_SOURCE_DEFAULT_TIMESTAMP_OFFSET,
563 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
564
565 g_object_class_install_property (object_class,
566 GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PUSH,
567 g_param_spec_boolean ("can-activate-push", "Can activate push",
568 "Can activate in push mode",
569 GST_LADSPA_SOURCE_DEFAULT_CAN_ACTIVATE_PUSH,
570 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
571
572 g_object_class_install_property (object_class,
573 GST_LADSPA_SOURCE_PROP_CAN_ACTIVATE_PULL,
574 g_param_spec_boolean ("can-activate-pull", "Can activate pull",
575 "Can activate in pull mode",
576 GST_LADSPA_SOURCE_DEFAULT_CAN_ACTIVATE_PULL,
577 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
578
579 gst_ladspa_object_class_install_properties (&ladspa_class->ladspa,
580 object_class, GST_LADSPA_SOURCE_PROP_LAST);
581 }
582
583 G_DEFINE_ABSTRACT_TYPE (GstLADSPASource, gst_ladspa_source, GST_TYPE_BASE_SRC);
584
585 static void
gst_ladspa_source_init(GstLADSPASource * ladspa)586 gst_ladspa_source_init (GstLADSPASource * ladspa)
587 {
588 }
589
590 static void
gst_ladspa_source_class_init(GstLADSPASourceClass * ladspa_class)591 gst_ladspa_source_class_init (GstLADSPASourceClass * ladspa_class)
592 {
593 }
594
595 /*
596 * Construct the type.
597 */
598 void
ladspa_register_source_element(GstPlugin * plugin,GstStructure * ladspa_meta)599 ladspa_register_source_element (GstPlugin * plugin, GstStructure * ladspa_meta)
600 {
601 GTypeInfo info = {
602 sizeof (GstLADSPASourceClass),
603 (GBaseInitFunc) gst_ladspa_source_type_base_init,
604 (GBaseFinalizeFunc) gst_ladspa_source_type_base_finalize,
605 (GClassInitFunc) gst_ladspa_source_type_class_init,
606 NULL,
607 NULL,
608 sizeof (GstLADSPASource),
609 0,
610 (GInstanceInitFunc) gst_ladspa_source_type_init,
611 NULL
612 };
613 ladspa_register_element (plugin, GST_TYPE_LADSPA_SOURCE, &info, ladspa_meta);
614 }
615