1 /* GStreamer DTS decoder plugin based on libdtsdec
2 * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
3 * Copyright (C) 2009 Jan Schmidt <thaytan@noraisin.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., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
22 * SECTION:element-dtsdec
25 * Digital Theatre System (DTS) audio decoder
27 * ## Example launch line
29 * gst-launch-1.0 dvdreadsrc title=1 ! mpegpsdemux ! dtsdec ! audioresample ! audioconvert ! alsasink
30 * ]| Play a DTS audio track from a dvd.
32 * gst-launch-1.0 filesrc location=abc.dts ! dtsdec ! audioresample ! audioconvert ! alsasink
33 * ]| Decode a standalone file and play it.
49 #include <gst/audio/audio.h>
56 typedef struct dts_state_s dca_state_t;
57 #define DCA_MONO DTS_MONO
58 #define DCA_CHANNEL DTS_CHANNEL
59 #define DCA_STEREO DTS_STEREO
60 #define DCA_STEREO_SUMDIFF DTS_STEREO_SUMDIFF
61 #define DCA_STEREO_TOTAL DTS_STEREO_TOTAL
63 #define DCA_2F1R DTS_2F1R
64 #define DCA_3F1R DTS_3F1R
65 #define DCA_2F2R DTS_2F2R
66 #define DCA_3F2R DTS_3F2R
67 #define DCA_4F2R DTS_4F2R
68 #define DCA_DOLBY DTS_DOLBY
69 #define DCA_CHANNEL_MAX DTS_CHANNEL_MAX
70 #define DCA_CHANNEL_BITS DTS_CHANNEL_BITS
71 #define DCA_CHANNEL_MASK DTS_CHANNEL_MASK
72 #define DCA_LFE DTS_LFE
73 #define DCA_ADJUST_LEVEL DTS_ADJUST_LEVEL
75 #define dca_init dts_init
76 #define dca_syncinfo dts_syncinfo
77 #define dca_frame dts_frame
78 #define dca_dynrng dts_dynrng
79 #define dca_blocks_num dts_blocks_num
80 #define dca_block dts_block
81 #define dca_samples dts_samples
82 #define dca_free dts_free
85 #include "gstdtsdec.h"
91 #if defined(LIBDTS_FIXED) || defined(LIBDCA_FIXED)
92 #define SAMPLE_WIDTH 16
93 #define SAMPLE_FORMAT GST_AUDIO_NE(S16)
94 #define SAMPLE_TYPE GST_AUDIO_FORMAT_S16
95 #elif defined (LIBDTS_DOUBLE) || defined(LIBDCA_DOUBLE)
96 #define SAMPLE_WIDTH 64
97 #define SAMPLE_FORMAT GST_AUDIO_NE(F64)
98 #define SAMPLE_TYPE GST_AUDIO_FORMAT_F64
100 #define SAMPLE_WIDTH 32
101 #define SAMPLE_FORMAT GST_AUDIO_NE(F32)
102 #define SAMPLE_TYPE GST_AUDIO_FORMAT_F32
105 GST_DEBUG_CATEGORY_STATIC (dtsdec_debug);
106 #define GST_CAT_DEFAULT (dtsdec_debug)
114 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
117 GST_STATIC_CAPS ("audio/x-dts; audio/x-private1-dts")
120 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
123 GST_STATIC_CAPS ("audio/x-raw, "
124 "format = (string) " SAMPLE_FORMAT ", "
125 "layout = (string) interleaved, "
126 "rate = (int) [ 4000, 96000 ], " "channels = (int) [ 1, 6 ]")
131 static gboolean gst_dtsdec_start (GstAudioDecoder * dec);
132 static gboolean gst_dtsdec_stop (GstAudioDecoder * dec);
133 static gboolean gst_dtsdec_set_format (GstAudioDecoder * bdec, GstCaps * caps);
134 static GstFlowReturn gst_dtsdec_parse (GstAudioDecoder * dec,
135 GstAdapter * adapter, gint * offset, gint * length);
136 static GstFlowReturn gst_dtsdec_handle_frame (GstAudioDecoder * dec,
139 static GstFlowReturn gst_dtsdec_chain (GstPad * pad, GstObject * parent,
142 static void gst_dtsdec_set_property (GObject * object, guint prop_id,
143 const GValue * value, GParamSpec * pspec);
144 static void gst_dtsdec_get_property (GObject * object, guint prop_id,
145 GValue * value, GParamSpec * pspec);
146 static gboolean dtsdec_element_init (GstPlugin * plugin);
148 G_DEFINE_TYPE (GstDtsDec, gst_dtsdec, GST_TYPE_AUDIO_DECODER);
149 GST_ELEMENT_REGISTER_DEFINE_CUSTOM (dtsdec, dtsdec_element_init);
152 gst_dtsdec_class_init (GstDtsDecClass * klass)
154 GObjectClass *gobject_class;
155 GstElementClass *gstelement_class;
156 GstAudioDecoderClass *gstbase_class;
159 gobject_class = (GObjectClass *) klass;
160 gstelement_class = (GstElementClass *) klass;
161 gstbase_class = (GstAudioDecoderClass *) klass;
163 gobject_class->set_property = gst_dtsdec_set_property;
164 gobject_class->get_property = gst_dtsdec_get_property;
166 gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);
167 gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
168 gst_element_class_set_static_metadata (gstelement_class, "DTS audio decoder",
169 "Codec/Decoder/Audio",
170 "Decodes DTS audio streams",
171 "Jan Schmidt <thaytan@noraisin.net>, "
172 "Ronald Bultje <rbultje@ronald.bitfreak.net>");
174 gstbase_class->start = GST_DEBUG_FUNCPTR (gst_dtsdec_start);
175 gstbase_class->stop = GST_DEBUG_FUNCPTR (gst_dtsdec_stop);
176 gstbase_class->set_format = GST_DEBUG_FUNCPTR (gst_dtsdec_set_format);
177 gstbase_class->parse = GST_DEBUG_FUNCPTR (gst_dtsdec_parse);
178 gstbase_class->handle_frame = GST_DEBUG_FUNCPTR (gst_dtsdec_handle_frame);
183 * Set to true to apply the recommended DTS dynamic range compression
184 * to the audio stream. Dynamic range compression makes loud sounds
185 * softer and soft sounds louder, so you can more easily listen
186 * to the stream without disturbing other people.
188 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DRC,
189 g_param_spec_boolean ("drc", "Dynamic Range Compression",
190 "Use Dynamic Range Compression", FALSE,
191 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
193 klass->dts_cpuflags = 0;
196 cpuflags = orc_target_get_default_flags (orc_target_get_by_name ("mmx"));
197 if (cpuflags & ORC_TARGET_MMX_MMX)
198 klass->dts_cpuflags |= MM_ACCEL_X86_MMX;
199 if (cpuflags & ORC_TARGET_MMX_3DNOW)
200 klass->dts_cpuflags |= MM_ACCEL_X86_3DNOW;
201 if (cpuflags & ORC_TARGET_MMX_MMXEXT)
202 klass->dts_cpuflags |= MM_ACCEL_X86_MMXEXT;
205 klass->dts_cpuflags = 0;
208 GST_LOG ("CPU flags: dts=%08x, orc=%08x", klass->dts_cpuflags, cpuflags);
212 gst_dtsdec_init (GstDtsDec * dtsdec)
214 dtsdec->request_channels = DCA_CHANNEL;
215 dtsdec->dynamic_range_compression = FALSE;
217 gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
219 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (dtsdec));
221 /* retrieve and intercept base class chain.
222 * Quite HACKish, but that's dvd specs for you,
223 * since one buffer needs to be split into 2 frames */
224 dtsdec->base_chain = GST_PAD_CHAINFUNC (GST_AUDIO_DECODER_SINK_PAD (dtsdec));
225 gst_pad_set_chain_function (GST_AUDIO_DECODER_SINK_PAD (dtsdec),
226 GST_DEBUG_FUNCPTR (gst_dtsdec_chain));
230 gst_dtsdec_start (GstAudioDecoder * dec)
232 GstDtsDec *dts = GST_DTSDEC (dec);
233 GstDtsDecClass *klass;
235 GST_DEBUG_OBJECT (dec, "start");
237 klass = GST_DTSDEC_CLASS (G_OBJECT_GET_CLASS (dts));
238 dts->state = dca_init (klass->dts_cpuflags);
239 dts->samples = dca_samples (dts->state);
241 dts->sample_rate = -1;
242 dts->stream_channels = DCA_CHANNEL;
243 dts->using_channels = DCA_CHANNEL;
246 dts->flag_update = TRUE;
248 /* call upon legacy upstream byte support (e.g. seeking) */
249 gst_audio_decoder_set_estimate_rate (dec, TRUE);
255 gst_dtsdec_stop (GstAudioDecoder * dec)
257 GstDtsDec *dts = GST_DTSDEC (dec);
259 GST_DEBUG_OBJECT (dec, "stop");
263 dca_free (dts->state);
271 gst_dtsdec_parse (GstAudioDecoder * bdec, GstAdapter * adapter,
272 gint * _offset, gint * len)
277 gint length = 0, flags, sample_rate, bit_rate, frame_length;
278 GstFlowReturn result = GST_FLOW_EOS;
280 dts = GST_DTSDEC (bdec);
282 size = av = gst_adapter_available (adapter);
283 data = (guint8 *) gst_adapter_map (adapter, av);
285 /* find and read header */
286 bit_rate = dts->bit_rate;
287 sample_rate = dts->sample_rate;
290 length = dca_syncinfo (dts->state, data, &flags,
291 &sample_rate, &bit_rate, &frame_length);
294 /* shift window to re-find sync */
297 } else if (length <= size) {
298 GST_LOG_OBJECT (dts, "Sync: frame size %d", length);
299 result = GST_FLOW_OK;
302 GST_LOG_OBJECT (dts, "Not enough data available (needed %d had %d)",
307 gst_adapter_unmap (adapter);
309 *_offset = av - size;
316 gst_dtsdec_channels (uint32_t flags, GstAudioChannelPosition * pos)
320 switch (flags & DCA_CHANNEL_MASK) {
324 pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
327 /* case DCA_CHANNEL: */
329 case DCA_STEREO_SUMDIFF:
330 case DCA_STEREO_TOTAL:
334 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
335 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
341 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
342 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
343 pos[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
349 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
350 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
351 pos[2] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
357 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
358 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
359 pos[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
360 pos[3] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
366 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
367 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
368 pos[2] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
369 pos[3] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
375 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
376 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
377 pos[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
378 pos[3] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
379 pos[4] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
385 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER;
386 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
387 pos[2] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
388 pos[3] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
389 pos[4] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
390 pos[5] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
394 g_warning ("dtsdec: invalid flags 0x%x", flags);
397 if (flags & DCA_LFE) {
399 pos[chans] = GST_AUDIO_CHANNEL_POSITION_LFE1;
408 gst_dtsdec_renegotiate (GstDtsDec * dts)
411 gboolean result = FALSE;
412 GstAudioChannelPosition from[7], to[7];
415 channels = gst_dtsdec_channels (dts->using_channels, from);
417 if (channels <= 0 || channels > 7)
420 GST_INFO_OBJECT (dts, "dtsdec renegotiate, channels=%d, rate=%d",
421 channels, dts->sample_rate);
423 memcpy (to, from, sizeof (GstAudioChannelPosition) * channels);
424 gst_audio_channel_positions_to_valid_order (to, channels);
425 gst_audio_get_channel_reorder_map (channels, from, to,
426 dts->channel_reorder_map);
429 gst_audio_info_init (&info);
430 gst_audio_info_set_format (&info,
431 SAMPLE_TYPE, dts->sample_rate, channels, (channels > 1 ? to : NULL));
433 if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (dts), &info))
443 gst_dtsdec_update_streaminfo (GstDtsDec * dts)
447 if (dts->bit_rate > 3) {
448 taglist = gst_tag_list_new_empty ();
449 /* 1 => open bitrate, 2 => variable bitrate, 3 => lossless */
450 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_BITRATE,
451 (guint) dts->bit_rate, NULL);
452 gst_audio_decoder_merge_tags (GST_AUDIO_DECODER (dts), taglist,
453 GST_TAG_MERGE_REPLACE);
455 gst_tag_list_unref (taglist);
460 gst_dtsdec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buffer)
463 gint channels, i, num_blocks;
464 gboolean need_renegotiation = FALSE;
468 #ifndef G_DISABLE_ASSERT
472 gint flags, sample_rate, bit_rate, frame_length;
473 GstFlowReturn result = GST_FLOW_OK;
476 dts = GST_DTSDEC (bdec);
478 /* no fancy draining */
479 if (G_UNLIKELY (!buffer))
482 /* parsed stuff already, so this should work out fine */
483 gst_buffer_map (buffer, &map, GST_MAP_READ);
486 #ifndef G_DISABLE_ASSERT
488 g_assert (size >= 7);
491 bit_rate = dts->bit_rate;
492 sample_rate = dts->sample_rate;
495 #ifndef G_DISABLE_ASSERT
496 length = dca_syncinfo (dts->state, data, &flags, &sample_rate, &bit_rate,
498 g_assert (length == size);
500 (void) dca_syncinfo (dts->state, data, &flags, &sample_rate, &bit_rate,
504 if (flags != dts->prev_flags) {
505 dts->prev_flags = flags;
506 dts->flag_update = TRUE;
509 /* go over stream properties, renegotiate or update streaminfo if needed */
510 if (dts->sample_rate != sample_rate) {
511 need_renegotiation = TRUE;
512 dts->sample_rate = sample_rate;
516 dts->stream_channels = flags & (DCA_CHANNEL_MASK | DCA_LFE);
519 if (bit_rate != dts->bit_rate) {
520 dts->bit_rate = bit_rate;
521 gst_dtsdec_update_streaminfo (dts);
524 /* If we haven't had an explicit number of channels chosen through properties
525 * at this point, choose what to downmix to now, based on what the peer will
526 * accept - this allows a52dec to do downmixing in preference to a
527 * downstream element such as audioconvert.
528 * FIXME: Add the property back in for forcing output channels.
530 if (dts->request_channels != DCA_CHANNEL) {
531 flags = dts->request_channels;
532 } else if (dts->flag_update) {
535 dts->flag_update = FALSE;
537 caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (dts));
538 if (caps && gst_caps_get_size (caps) > 0) {
539 GstCaps *copy = gst_caps_copy_nth (caps, 0);
540 GstStructure *structure = gst_caps_get_structure (copy, 0);
542 const int dts_channels[6] = {
545 DCA_STEREO | DCA_LFE,
551 /* Prefer the original number of channels, but fixate to something
552 * preferred (first in the caps) downstream if possible.
554 gst_structure_fixate_field_nearest_int (structure, "channels",
555 flags ? gst_dtsdec_channels (flags, NULL) : 6);
556 gst_structure_get_int (structure, "channels", &channels);
558 flags = dts_channels[channels - 1];
560 flags = dts_channels[5];
562 gst_caps_unref (copy);
564 flags = dts->stream_channels;
566 flags = DCA_3F2R | DCA_LFE;
570 gst_caps_unref (caps);
572 flags = dts->using_channels;
576 flags |= DCA_ADJUST_LEVEL;
578 if (dca_frame (dts->state, data, &flags, &dts->level, dts->bias)) {
579 gst_buffer_unmap (buffer, &map);
580 GST_AUDIO_DECODER_ERROR (dts, 1, STREAM, DECODE, (NULL),
581 ("dts_frame error"), result);
584 gst_buffer_unmap (buffer, &map);
586 channels = flags & (DCA_CHANNEL_MASK | DCA_LFE);
587 if (dts->using_channels != channels) {
588 need_renegotiation = TRUE;
589 dts->using_channels = channels;
592 /* negotiate if required */
593 if (need_renegotiation) {
594 GST_DEBUG_OBJECT (dts,
595 "dtsdec: sample_rate:%d stream_chans:0x%x using_chans:0x%x",
596 dts->sample_rate, dts->stream_channels, dts->using_channels);
597 if (!gst_dtsdec_renegotiate (dts))
598 goto failed_negotiation;
601 if (dts->dynamic_range_compression == FALSE) {
602 dca_dynrng (dts->state, NULL, NULL);
605 flags &= (DCA_CHANNEL_MASK | DCA_LFE);
606 chans = gst_dtsdec_channels (flags, NULL);
610 /* handle decoded data, one block is 256 samples */
611 num_blocks = dca_blocks_num (dts->state);
613 gst_buffer_new_and_alloc (256 * chans * (SAMPLE_WIDTH / 8) * num_blocks);
615 gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
619 for (i = 0; i < num_blocks; i++) {
620 if (dca_block (dts->state)) {
621 /* also marks discont */
622 GST_AUDIO_DECODER_ERROR (dts, 1, STREAM, DECODE, (NULL),
623 ("error decoding block %d", i), result);
624 if (result != GST_FLOW_OK)
628 gint *reorder_map = dts->channel_reorder_map;
630 for (n = 0; n < 256; n++) {
631 for (c = 0; c < chans; c++) {
632 ((sample_t *) ptr)[n * chans + reorder_map[c]] =
633 dts->samples[c * 256 + n];
637 ptr += 256 * chans * (SAMPLE_WIDTH / 8);
640 gst_buffer_unmap (outbuf, &map);
642 result = gst_audio_decoder_finish_frame (bdec, outbuf, 1);
650 GST_ELEMENT_ERROR (dts, CORE, NEGOTIATION, (NULL), (NULL));
651 return GST_FLOW_ERROR;
655 GST_ELEMENT_ERROR (GST_ELEMENT (dts), STREAM, DECODE, (NULL),
656 ("Invalid channel flags: %d", flags));
657 return GST_FLOW_ERROR;
662 gst_dtsdec_set_format (GstAudioDecoder * bdec, GstCaps * caps)
664 GstDtsDec *dts = GST_DTSDEC (bdec);
665 GstStructure *structure;
667 structure = gst_caps_get_structure (caps, 0);
669 if (structure && gst_structure_has_name (structure, "audio/x-private1-dts"))
672 dts->dvdmode = FALSE;
678 gst_dtsdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
680 GstFlowReturn ret = GST_FLOW_OK;
681 GstDtsDec *dts = GST_DTSDEC (parent);
690 size = gst_buffer_get_size (buf);
692 goto not_enough_data;
694 gst_buffer_extract (buf, 0, data, 2);
695 first_access = (data[0] << 8) | data[1];
697 /* Skip the first_access header */
700 if (first_access > 1) {
701 /* Length of data before first_access */
702 len = first_access - 1;
704 if (len <= 0 || offset + len > size)
705 goto bad_first_access_parameter;
707 subbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset, len);
708 GST_BUFFER_TIMESTAMP (subbuf) = GST_CLOCK_TIME_NONE;
709 ret = dts->base_chain (pad, parent, subbuf);
710 if (ret != GST_FLOW_OK) {
711 gst_buffer_unref (buf);
719 subbuf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset, len);
720 GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buf);
722 ret = dts->base_chain (pad, parent, subbuf);
724 gst_buffer_unref (buf);
726 /* first_access = 0 or 1, so if there's a timestamp it applies to the first byte */
728 gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset,
730 GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buf);
731 ret = dts->base_chain (pad, parent, subbuf);
732 gst_buffer_unref (buf);
735 ret = dts->base_chain (pad, parent, buf);
744 GST_ELEMENT_ERROR (GST_ELEMENT (dts), STREAM, DECODE, (NULL),
745 ("Insufficient data in buffer. Can't determine first_acess"));
746 gst_buffer_unref (buf);
747 return GST_FLOW_ERROR;
749 bad_first_access_parameter:
751 GST_ELEMENT_ERROR (GST_ELEMENT (dts), STREAM, DECODE, (NULL),
752 ("Bad first_access parameter (%d) in buffer", first_access));
753 gst_buffer_unref (buf);
754 return GST_FLOW_ERROR;
759 gst_dtsdec_set_property (GObject * object, guint prop_id, const GValue * value,
762 GstDtsDec *dts = GST_DTSDEC (object);
766 dts->dynamic_range_compression = g_value_get_boolean (value);
769 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
775 gst_dtsdec_get_property (GObject * object, guint prop_id, GValue * value,
778 GstDtsDec *dts = GST_DTSDEC (object);
782 g_value_set_boolean (value, dts->dynamic_range_compression);
785 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
791 dtsdec_element_init (GstPlugin * plugin)
793 GST_DEBUG_CATEGORY_INIT (dtsdec_debug, "dtsdec", 0, "DTS/DCA audio decoder");
799 return gst_element_register (plugin, "dtsdec", GST_RANK_PRIMARY,
804 plugin_init (GstPlugin * plugin)
806 return GST_ELEMENT_REGISTER (dtsdec, plugin);
809 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
812 "Decodes DTS audio streams",
813 plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);