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