Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / gst / real / gstrealaudiodec.c
1 /* RealAudio wrapper plugin
2  *
3  * Copyright (C) 2006 Lutz Mueller <lutz@topfrose.de>
4  * Copyright (C) 2006 Edward Hervey <bilboed@bilboed.com>
5  * 
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "gstreal.h"
27 #include "gstrealaudiodec.h"
28
29 #include <string.h>
30
31 GST_DEBUG_CATEGORY_STATIC (real_audio_dec_debug);
32 #define GST_CAT_DEFAULT real_audio_dec_debug
33
34 static GstStaticPadTemplate snk_t =
35     GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
36     GST_STATIC_CAPS ("audio/x-pn-realaudio, "
37         "raversion = { 3, 4, 5, 6, 8 }; " "audio/x-sipro "));
38
39 static GstStaticPadTemplate src_t =
40 GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
41     GST_STATIC_CAPS ("audio/x-raw-int, "
42         "width = (int) [ 1, MAX ], "
43         "depth = (int) [ 1, MAX ], "
44         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]"));
45
46 #define DEFAULT_RACOOK_NAMES "cook.so:cook.so.6.0"
47 #define DEFAULT_RAATRK_NAMES "atrc.so:atrc.so.6.0"
48 #define DEFAULT_RA14_4_NAMES "14_4.so.6.0"
49 #define DEFAULT_RA28_8_NAMES "28_8.so.6.0"
50 #define DEFAULT_RASIPR_NAMES "sipr.so:sipr.so.6.0"
51 #define DEFAULT_PWD "Ardubancel Quazanga"
52
53 enum
54 {
55   PROP_0,
56   PROP_REAL_CODECS_PATH,
57   PROP_RACOOK_NAMES,
58   PROP_RAATRK_NAMES,
59   PROP_RA14_4_NAMES,
60   PROP_RA28_8_NAMES,
61   PROP_RASIPR_NAMES,
62   PROP_PASSWORD
63 };
64
65 typedef enum
66 {
67   GST_REAL_AUDIO_DEC_VERSION_ATRK = 3,
68   GST_REAL_AUDIO_DEC_VERSION_14_4 = 4,
69   GST_REAL_AUDIO_DEC_VERSION_28_8 = 5,
70   GST_REAL_AUDIO_DEC_VERSION_SIPR = 6,
71   GST_REAL_AUDIO_DEC_VERSION_COOK = 8
72 } GstRealAudioDecVersion;
73
74 typedef struct
75 {
76   /* Hooks */
77   GModule *module;
78
79   /* Used by the REAL library. */
80   gpointer context;
81
82     guint16 (*RADecode) (gpointer, guint8 *, guint32, guint8 *, guint32 *,
83       guint32);
84     guint16 (*RACloseCodec) (gpointer);
85     guint16 (*RAFreeDecoder) (gpointer);
86     guint16 (*RAInitDecoder) (gpointer, gpointer);
87     guint16 (*RAOpenCodec2) (gpointer, const gchar *);
88     guint16 (*RASetFlavor) (gpointer, guint16);
89   void (*SetDLLAccessPath) (gchar *);
90   void (*RASetPwd) (gpointer, const gchar *);
91 } GstRADecLibrary;
92
93 typedef struct
94 {
95   guint32 samplerate;
96   guint16 width;
97   guint16 channels;
98   guint16 quality;
99   guint32 leaf_size;
100   guint32 packet_size;
101   guint32 datalen;
102   gpointer data;
103 } RAInit;
104
105 struct _GstRealAudioDec
106 {
107   GstElement parent;
108
109   GstPad *src, *snk;
110
111   /* Caps */
112   guint width, height, leaf_size;
113
114   GstRADecLibrary lib;
115
116   /* Properties */
117   gboolean checked_modules;
118   gchar *real_codecs_path;
119   gchar *raatrk_names;
120   gboolean valid_atrk;
121   gchar *ra14_4_names;
122   gboolean valid_ra14_4;
123   gchar *ra28_8_names;
124   gboolean valid_ra28_8;
125   gchar *rasipr_names;
126   gboolean valid_sipr;
127   gchar *racook_names;
128   gboolean valid_cook;
129   gchar *pwd;
130 };
131
132 struct _GstRealAudioDecClass
133 {
134   GstElementClass parent_class;
135 };
136
137 GST_BOILERPLATE (GstRealAudioDec, gst_real_audio_dec, GstElement,
138     GST_TYPE_ELEMENT);
139
140 static GstFlowReturn
141 gst_real_audio_dec_chain (GstPad * pad, GstBuffer * in)
142 {
143   GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (GST_PAD_PARENT (pad));
144   GstFlowReturn flow;
145   GstClockTime timestamp;
146   GstBuffer *out = NULL;
147   guint16 res = 0;
148   guint len;
149
150   if (G_UNLIKELY (dec->lib.RADecode == NULL || dec->lib.module == NULL))
151     goto not_negotiated;
152
153   timestamp = GST_BUFFER_TIMESTAMP (in);
154
155   flow = gst_pad_alloc_buffer (dec->src, GST_BUFFER_OFFSET_NONE,
156       dec->width * dec->leaf_size * dec->height * 16,
157       GST_PAD_CAPS (dec->src), &out);
158
159   if (flow != GST_FLOW_OK)
160     goto done;
161
162   res = dec->lib.RADecode (dec->lib.context, GST_BUFFER_DATA (in),
163       GST_BUFFER_SIZE (in), GST_BUFFER_DATA (out), &len, -1);
164
165   if (res != 0)
166     goto could_not_decode;
167
168   GST_BUFFER_SIZE (out) = len;
169   GST_BUFFER_TIMESTAMP (out) = timestamp;
170
171   flow = gst_pad_push (dec->src, out);
172
173 done:
174   gst_buffer_unref (in);
175   return flow;
176
177   /* Errors */
178 could_not_decode:
179   {
180     gst_buffer_unref (out);
181     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
182         ("Could not decode buffer (%i).", res));
183     flow = GST_FLOW_ERROR;
184     goto done;
185   }
186 not_negotiated:
187   {
188     GST_WARNING_OBJECT (dec, "decoder not open, probably no input caps set "
189         "yet, caps on input buffer: %" GST_PTR_FORMAT, GST_BUFFER_CAPS (in));
190     flow = GST_FLOW_NOT_NEGOTIATED;
191     goto done;
192   }
193 }
194
195 static void
196 close_library (GstRealAudioDec * dec, GstRADecLibrary * lib)
197 {
198   if (lib->context) {
199     GST_LOG_OBJECT (dec, "closing library");
200     if (lib->RACloseCodec)
201       lib->RACloseCodec (lib->context);
202     /* lib->RAFreeDecoder (lib->context); */
203   }
204   if (lib->module) {
205     GST_LOG_OBJECT (dec, "closing library module");
206     g_module_close (lib->module);
207   }
208   memset (lib, 0, sizeof (GstRADecLibrary));
209 }
210
211 static gboolean
212 open_library (GstRealAudioDec * dec, gint version, GstRADecLibrary * lib)
213 {
214   const gchar *path, *names;
215   gchar **split_names, **split_path;
216   gint i, j;
217   gpointer ra_close_codec, ra_decode, ra_free_decoder;
218   gpointer ra_open_codec2, ra_init_decoder, ra_set_flavor;
219   gpointer set_dll_access_path = NULL, ra_set_pwd = NULL;
220   gchar *tmppath = NULL;
221   guint16 res = 0;
222
223   path = dec->real_codecs_path ? dec->real_codecs_path :
224       DEFAULT_REAL_CODECS_PATH;
225
226   switch (version) {
227     case GST_REAL_AUDIO_DEC_VERSION_COOK:
228       names = dec->racook_names ? dec->racook_names : DEFAULT_RACOOK_NAMES;
229       break;
230     case GST_REAL_AUDIO_DEC_VERSION_ATRK:
231       names = dec->raatrk_names ? dec->raatrk_names : DEFAULT_RAATRK_NAMES;
232       break;
233     case GST_REAL_AUDIO_DEC_VERSION_14_4:
234       names = dec->ra14_4_names ? dec->ra14_4_names : DEFAULT_RA14_4_NAMES;
235       break;
236     case GST_REAL_AUDIO_DEC_VERSION_28_8:
237       names = dec->ra28_8_names ? dec->ra28_8_names : DEFAULT_RA28_8_NAMES;
238       break;
239     case GST_REAL_AUDIO_DEC_VERSION_SIPR:
240       names = dec->rasipr_names ? dec->rasipr_names : DEFAULT_RASIPR_NAMES;
241       break;
242     default:
243       goto unknown_version;
244   }
245
246   GST_LOG_OBJECT (dec, "splitting paths %s, names %s", path, names);
247
248   split_path = g_strsplit (path, ":", 0);
249   split_names = g_strsplit (names, ":", 0);
250
251   for (i = 0; split_path[i]; i++) {
252     for (j = 0; split_names[j]; j++) {
253       gchar *codec = g_strconcat (split_path[i], "/", split_names[j], NULL);
254
255       GST_LOG_OBJECT (dec, "opening module %s", codec);
256
257       /* This is racy, but it doesn't matter here; would be nice if GModule
258        * gave us a GError instead of an error string, but it doesn't, so.. */
259       if (g_file_test (codec, G_FILE_TEST_EXISTS)) {
260         lib->module = g_module_open (codec, G_MODULE_BIND_LAZY);
261         if (lib->module == NULL) {
262           GST_ERROR_OBJECT (dec, "Could not open codec library '%s': %s",
263               codec, g_module_error ());
264         }
265       } else {
266         GST_DEBUG_OBJECT (dec, "%s does not exist", codec);
267       }
268       g_free (codec);
269       if (lib->module)
270         goto codec_search_done;
271     }
272   }
273
274 codec_search_done:
275   /* we keep the path for a while to set the dll access path */
276   g_strfreev (split_names);
277
278   if (lib->module == NULL)
279     goto could_not_open;
280
281   GST_LOG_OBJECT (dec, "finding symbols");
282
283   if (!g_module_symbol (lib->module, "RACloseCodec", &ra_close_codec) ||
284       !g_module_symbol (lib->module, "RADecode", &ra_decode) ||
285       !g_module_symbol (lib->module, "RAFreeDecoder", &ra_free_decoder) ||
286       !g_module_symbol (lib->module, "RAOpenCodec2", &ra_open_codec2) ||
287       !g_module_symbol (lib->module, "RAInitDecoder", &ra_init_decoder) ||
288       !g_module_symbol (lib->module, "RASetFlavor", &ra_set_flavor)) {
289     goto could_not_load;
290   }
291
292   g_module_symbol (lib->module, "RASetPwd", &ra_set_pwd);
293   g_module_symbol (lib->module, "SetDLLAccessPath", &set_dll_access_path);
294
295   lib->RACloseCodec = (guint16 (*)(gpointer)) ra_close_codec;
296   lib->RADecode =
297       (guint16 (*)(gpointer, guint8 *, guint32, guint8 *, guint32 *, guint32))
298       ra_decode;
299   lib->RAFreeDecoder = (guint16 (*)(gpointer)) ra_free_decoder;
300   lib->RAOpenCodec2 = (guint16 (*)(gpointer, const gchar *)) ra_open_codec2;
301   lib->RAInitDecoder = (guint16 (*)(gpointer, gpointer)) ra_init_decoder;
302   lib->RASetFlavor = (guint16 (*)(gpointer, guint16)) ra_set_flavor;
303   lib->RASetPwd = (void (*)(gpointer, const gchar *)) ra_set_pwd;
304   lib->SetDLLAccessPath = (void (*)(gchar *)) set_dll_access_path;
305
306   if (lib->SetDLLAccessPath)
307     lib->SetDLLAccessPath (split_path[i]);
308
309   tmppath = g_strdup_printf ("%s/", split_path[i]);
310   if ((res = lib->RAOpenCodec2 (&lib->context, tmppath))) {
311     g_free (tmppath);
312     goto could_not_initialize;
313   }
314   g_free (tmppath);
315
316   /* now we are done with the split paths, so free them */
317   g_strfreev (split_path);
318
319   return TRUE;
320
321   /* ERRORS */
322 unknown_version:
323   {
324     GST_DEBUG_OBJECT (dec, "Cannot handle version %i.", version);
325     return FALSE;
326   }
327 could_not_open:
328   {
329     g_strfreev (split_path);
330     GST_DEBUG_OBJECT (dec, "Could not find library '%s' in '%s'", names, path);
331     return FALSE;
332   }
333 could_not_load:
334   {
335     g_strfreev (split_path);
336     close_library (dec, lib);
337     GST_DEBUG_OBJECT (dec, "Could not load all symbols: %s", g_module_error ());
338     return FALSE;
339   }
340 could_not_initialize:
341   {
342     close_library (dec, lib);
343     GST_WARNING_OBJECT (dec, "Initialization of REAL driver failed (%i).", res);
344     return FALSE;
345   }
346 }
347
348 static void
349 gst_real_audio_dec_probe_modules (GstRealAudioDec * dec)
350 {
351   GstRADecLibrary dummy = { NULL };
352
353   if ((dec->valid_atrk =
354           open_library (dec, GST_REAL_AUDIO_DEC_VERSION_ATRK, &dummy)))
355     close_library (dec, &dummy);
356   if ((dec->valid_ra14_4 =
357           open_library (dec, GST_REAL_AUDIO_DEC_VERSION_14_4, &dummy)))
358     close_library (dec, &dummy);
359   if ((dec->valid_ra28_8 =
360           open_library (dec, GST_REAL_AUDIO_DEC_VERSION_28_8, &dummy)))
361     close_library (dec, &dummy);
362 #ifdef HAVE_CPU_X86_64
363   /* disabled because it does not seem to work on 64 bits */
364   dec->valid_sipr = FALSE;
365 #else
366   if ((dec->valid_sipr =
367           open_library (dec, GST_REAL_AUDIO_DEC_VERSION_SIPR, &dummy)))
368     close_library (dec, &dummy);
369 #endif
370   if ((dec->valid_cook =
371           open_library (dec, GST_REAL_AUDIO_DEC_VERSION_COOK, &dummy)))
372     close_library (dec, &dummy);
373 }
374
375 static GstCaps *
376 gst_real_audio_dec_getcaps (GstPad * pad)
377 {
378   GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (GST_PAD_PARENT (pad));
379   GstCaps *res;
380
381   if (dec->checked_modules) {
382     GValue versions = { 0 };
383     GValue version = { 0 };
384
385     GST_LOG_OBJECT (dec, "constructing caps");
386
387     g_value_init (&versions, GST_TYPE_LIST);
388     g_value_init (&version, G_TYPE_INT);
389
390     if (dec->valid_atrk) {
391       g_value_set_int (&version, GST_REAL_AUDIO_DEC_VERSION_ATRK);
392       gst_value_list_append_value (&versions, &version);
393     }
394     if (dec->valid_ra14_4) {
395       g_value_set_int (&version, GST_REAL_AUDIO_DEC_VERSION_14_4);
396       gst_value_list_append_value (&versions, &version);
397     }
398     if (dec->valid_ra28_8) {
399       g_value_set_int (&version, GST_REAL_AUDIO_DEC_VERSION_28_8);
400       gst_value_list_append_value (&versions, &version);
401     }
402     if (dec->valid_sipr) {
403       g_value_set_int (&version, GST_REAL_AUDIO_DEC_VERSION_SIPR);
404       gst_value_list_append_value (&versions, &version);
405     }
406     if (dec->valid_cook) {
407       g_value_set_int (&version, GST_REAL_AUDIO_DEC_VERSION_COOK);
408       gst_value_list_append_value (&versions, &version);
409     }
410
411     if (gst_value_list_get_size (&versions) > 0) {
412       res = gst_caps_new_simple ("audio/x-pn-realaudio", NULL);
413       gst_structure_set_value (gst_caps_get_structure (res, 0),
414           "raversion", &versions);
415     } else {
416       res = gst_caps_new_empty ();
417     }
418
419     if (dec->valid_sipr) {
420       gst_caps_append (res, gst_caps_new_simple ("audio/x-sipro", NULL));
421     }
422     g_value_unset (&versions);
423     g_value_unset (&version);
424   } else {
425     GST_LOG_OBJECT (dec, "returning padtemplate caps");
426     res = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
427   }
428   GST_LOG_OBJECT (dec, "returning caps %" GST_PTR_FORMAT, res);
429
430   return res;
431 }
432
433 static gboolean
434 gst_real_audio_dec_setcaps (GstPad * pad, GstCaps * caps)
435 {
436   GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (GST_PAD_PARENT (pad));
437   GstStructure *s = gst_caps_get_structure (caps, 0);
438   gint version, flavor, channels, rate, leaf_size, packet_size, width, height;
439   guint16 res = 0;
440   RAInit data;
441   gboolean bres;
442   const GValue *v;
443   GstBuffer *buf = NULL;
444   const gchar *name = gst_structure_get_name (s);
445
446   if (!strcmp (name, "audio/x-sipro")) {
447     version = GST_REAL_AUDIO_DEC_VERSION_SIPR;
448   } else {
449     if (!gst_structure_get_int (s, "raversion", &version))
450       goto missing_keys;
451   }
452
453   if (!gst_structure_get_int (s, "flavor", &flavor) ||
454       !gst_structure_get_int (s, "channels", &channels) ||
455       !gst_structure_get_int (s, "width", &width) ||
456       !gst_structure_get_int (s, "rate", &rate) ||
457       !gst_structure_get_int (s, "height", &height) ||
458       !gst_structure_get_int (s, "leaf_size", &leaf_size) ||
459       !gst_structure_get_int (s, "packet_size", &packet_size))
460     goto missing_keys;
461
462   if ((v = gst_structure_get_value (s, "codec_data")))
463     buf = g_value_peek_pointer (v);
464
465   GST_LOG_OBJECT (dec, "opening code for version %d", version);
466
467   /* first close existing decoder */
468   close_library (dec, &dec->lib);
469
470   if (!open_library (dec, version, &dec->lib))
471     goto could_not_open;
472
473   /* we have the module, no initialize with the caps data */
474   data.samplerate = rate;
475   data.width = width;
476   data.channels = channels;
477   data.quality = 100;
478   data.leaf_size = leaf_size;
479   data.packet_size = packet_size;
480   data.datalen = buf ? GST_BUFFER_SIZE (buf) : 0;
481   data.data = buf ? GST_BUFFER_DATA (buf) : NULL;
482
483   if ((res = dec->lib.RAInitDecoder (dec->lib.context, &data))) {
484     GST_WARNING_OBJECT (dec, "RAInitDecoder() failed");
485     goto could_not_initialize;
486   }
487
488   if (dec->lib.RASetPwd) {
489     dec->lib.RASetPwd (dec->lib.context, dec->pwd ? dec->pwd : DEFAULT_PWD);
490   }
491
492   if ((res = dec->lib.RASetFlavor (dec->lib.context, flavor))) {
493     GST_WARNING_OBJECT (dec, "RASetFlavor(%d) failed", flavor);
494     goto could_not_initialize;
495   }
496
497   caps = gst_caps_new_simple ("audio/x-raw-int",
498       "endianness", G_TYPE_INT, G_BYTE_ORDER,
499       "width", G_TYPE_INT, width,
500       "depth", G_TYPE_INT, width,
501       "rate", G_TYPE_INT, rate,
502       "channels", G_TYPE_INT, channels, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
503   bres = gst_pad_set_caps (GST_PAD (dec->src), caps);
504   gst_caps_unref (caps);
505   if (!bres)
506     goto could_not_set_caps;
507
508   dec->width = width;
509   dec->height = height;
510   dec->leaf_size = leaf_size;
511
512   GST_LOG_OBJECT (dec, "opened module");
513
514   return TRUE;
515
516 missing_keys:
517   {
518     GST_DEBUG_OBJECT (dec, "Could not find all necessary keys in structure.");
519     return FALSE;
520   }
521 could_not_open:
522   {
523     GST_DEBUG_OBJECT (dec, "Could not find decoder");
524     return FALSE;
525   }
526 could_not_initialize:
527   {
528     close_library (dec, &dec->lib);
529     GST_WARNING_OBJECT (dec, "Initialization of REAL driver failed (%i).", res);
530     return FALSE;
531   }
532 could_not_set_caps:
533   {
534     /* should normally not fail */
535     close_library (dec, &dec->lib);
536     GST_DEBUG_OBJECT (dec, "Could not convince peer to accept caps.");
537     return FALSE;
538   }
539 }
540
541 static void
542 gst_real_audio_dec_init (GstRealAudioDec * dec, GstRealAudioDecClass * klass)
543 {
544   dec->snk = gst_pad_new_from_static_template (&snk_t, "sink");
545   gst_pad_set_setcaps_function (dec->snk,
546       GST_DEBUG_FUNCPTR (gst_real_audio_dec_setcaps));
547   gst_pad_set_getcaps_function (dec->snk,
548       GST_DEBUG_FUNCPTR (gst_real_audio_dec_getcaps));
549   gst_pad_set_chain_function (dec->snk,
550       GST_DEBUG_FUNCPTR (gst_real_audio_dec_chain));
551   gst_element_add_pad (GST_ELEMENT (dec), dec->snk);
552
553   dec->src = gst_pad_new_from_static_template (&src_t, "src");
554   gst_pad_use_fixed_caps (dec->src);
555   gst_element_add_pad (GST_ELEMENT (dec), dec->src);
556 }
557
558 static void
559 gst_real_audio_dec_base_init (gpointer g_class)
560 {
561   GstElementClass *ec = GST_ELEMENT_CLASS (g_class);
562
563   gst_element_class_add_static_pad_template (ec, &snk_t);
564   gst_element_class_add_static_pad_template (ec, &src_t);
565   gst_element_class_set_details_simple (ec, "RealAudio decoder",
566       "Codec/Decoder/Audio", "Decoder for RealAudio streams",
567       "Lutz Mueller <lutz@topfrose.de>");
568 }
569
570 static GstStateChangeReturn
571 gst_real_audio_dec_change_state (GstElement * element,
572     GstStateChange transition)
573 {
574   GstStateChangeReturn ret;
575   GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (element);
576
577   switch (transition) {
578     case GST_STATE_CHANGE_NULL_TO_READY:
579       gst_real_audio_dec_probe_modules (dec);
580       dec->checked_modules = TRUE;
581       break;
582     default:
583       break;
584   }
585
586   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
587
588   switch (transition) {
589     case GST_STATE_CHANGE_PAUSED_TO_READY:
590       close_library (dec, &dec->lib);
591       break;
592     case GST_STATE_CHANGE_READY_TO_NULL:
593       dec->checked_modules = FALSE;
594       break;
595     default:
596       break;
597   }
598   return ret;
599 }
600
601 static void
602 gst_real_audio_dec_finalize (GObject * object)
603 {
604   GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (object);
605
606   close_library (dec, &dec->lib);
607
608   if (dec->real_codecs_path) {
609     g_free (dec->real_codecs_path);
610     dec->real_codecs_path = NULL;
611   }
612   if (dec->racook_names) {
613     g_free (dec->racook_names);
614     dec->racook_names = NULL;
615   }
616   if (dec->raatrk_names) {
617     g_free (dec->raatrk_names);
618     dec->raatrk_names = NULL;
619   }
620   if (dec->ra14_4_names) {
621     g_free (dec->ra14_4_names);
622     dec->ra14_4_names = NULL;
623   }
624   if (dec->ra28_8_names) {
625     g_free (dec->ra28_8_names);
626     dec->ra28_8_names = NULL;
627   }
628   if (dec->rasipr_names) {
629     g_free (dec->rasipr_names);
630     dec->rasipr_names = NULL;
631   }
632
633   G_OBJECT_CLASS (parent_class)->finalize (object);
634 }
635
636 static void
637 gst_real_audio_dec_set_property (GObject * object, guint prop_id,
638     const GValue * value, GParamSpec * pspec)
639 {
640   GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (object);
641
642   switch (prop_id) {
643     case PROP_REAL_CODECS_PATH:
644       if (dec->real_codecs_path)
645         g_free (dec->real_codecs_path);
646       dec->real_codecs_path = g_value_dup_string (value);
647       break;
648     case PROP_RACOOK_NAMES:
649       if (dec->racook_names)
650         g_free (dec->racook_names);
651       dec->racook_names = g_value_dup_string (value);
652       break;
653     case PROP_RAATRK_NAMES:
654       if (dec->raatrk_names)
655         g_free (dec->raatrk_names);
656       dec->raatrk_names = g_value_dup_string (value);
657       break;
658     case PROP_RA14_4_NAMES:
659       if (dec->ra14_4_names)
660         g_free (dec->ra14_4_names);
661       dec->ra14_4_names = g_value_dup_string (value);
662       break;
663     case PROP_RA28_8_NAMES:
664       if (dec->ra28_8_names)
665         g_free (dec->ra28_8_names);
666       dec->ra28_8_names = g_value_dup_string (value);
667       break;
668     case PROP_RASIPR_NAMES:
669       if (dec->rasipr_names)
670         g_free (dec->rasipr_names);
671       dec->rasipr_names = g_value_dup_string (value);
672       break;
673     case PROP_PASSWORD:
674       if (dec->pwd)
675         g_free (dec->pwd);
676       dec->pwd = g_value_dup_string (value);
677       break;
678     default:
679       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
680       break;
681   }
682 }
683
684 static void
685 gst_real_audio_dec_get_property (GObject * object, guint prop_id,
686     GValue * value, GParamSpec * pspec)
687 {
688   GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (object);
689
690   switch (prop_id) {
691     case PROP_REAL_CODECS_PATH:
692       g_value_set_string (value, dec->real_codecs_path ? dec->real_codecs_path
693           : DEFAULT_REAL_CODECS_PATH);
694       break;
695     case PROP_RACOOK_NAMES:
696       g_value_set_string (value, dec->racook_names ? dec->racook_names :
697           DEFAULT_RACOOK_NAMES);
698       break;
699     case PROP_RAATRK_NAMES:
700       g_value_set_string (value, dec->raatrk_names ? dec->raatrk_names :
701           DEFAULT_RAATRK_NAMES);
702       break;
703     case PROP_RA14_4_NAMES:
704       g_value_set_string (value, dec->ra14_4_names ? dec->ra14_4_names :
705           DEFAULT_RA14_4_NAMES);
706       break;
707     case PROP_RA28_8_NAMES:
708       g_value_set_string (value, dec->ra28_8_names ? dec->ra28_8_names :
709           DEFAULT_RA28_8_NAMES);
710       break;
711     case PROP_RASIPR_NAMES:
712       g_value_set_string (value, dec->rasipr_names ? dec->rasipr_names :
713           DEFAULT_RASIPR_NAMES);
714       break;
715     case PROP_PASSWORD:
716       g_value_set_string (value, dec->pwd ? dec->pwd : DEFAULT_PWD);
717       break;
718     default:
719       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
720       break;
721   }
722 }
723
724 static void
725 gst_real_audio_dec_class_init (GstRealAudioDecClass * klass)
726 {
727   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
728   GObjectClass *object_class = G_OBJECT_CLASS (klass);
729
730   object_class->set_property = gst_real_audio_dec_set_property;
731   object_class->get_property = gst_real_audio_dec_get_property;
732   object_class->finalize = gst_real_audio_dec_finalize;
733
734   element_class->change_state = gst_real_audio_dec_change_state;
735
736   g_object_class_install_property (object_class, PROP_REAL_CODECS_PATH,
737       g_param_spec_string ("real-codecs-path",
738           "Path where to search for RealPlayer codecs",
739           "Path where to search for RealPlayer codecs",
740           DEFAULT_REAL_CODECS_PATH,
741           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
742   g_object_class_install_property (object_class, PROP_RACOOK_NAMES,
743       g_param_spec_string ("racook-names", "Names of cook driver",
744           "Names of cook driver", DEFAULT_RACOOK_NAMES,
745           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
746   g_object_class_install_property (object_class, PROP_RAATRK_NAMES,
747       g_param_spec_string ("raatrk-names", "Names of atrk driver",
748           "Names of atrk driver", DEFAULT_RAATRK_NAMES,
749           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
750   g_object_class_install_property (object_class, PROP_RA14_4_NAMES,
751       g_param_spec_string ("ra14-4-names", "Names of 14_4 driver",
752           "Names of 14_4 driver", DEFAULT_RA14_4_NAMES,
753           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
754   g_object_class_install_property (object_class, PROP_RA28_8_NAMES,
755       g_param_spec_string ("ra28-8-names", "Names of 28_8 driver",
756           "Names of 28_8 driver", DEFAULT_RA28_8_NAMES,
757           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
758   g_object_class_install_property (object_class, PROP_RASIPR_NAMES,
759       g_param_spec_string ("rasipr-names", "Names of sipr driver",
760           "Names of sipr driver", DEFAULT_RASIPR_NAMES,
761           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
762   g_object_class_install_property (object_class, PROP_PASSWORD,
763       g_param_spec_string ("password", "Password", "Password",
764           DEFAULT_PWD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
765
766   GST_DEBUG_CATEGORY_INIT (real_audio_dec_debug, "realaudiodec", 0,
767       "RealAudio decoder");
768 }