Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 1 | /* GStreamer Musepack decoder plugin |
| 2 | * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net> |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 3 | * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net> |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 4 | * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org> |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 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 | |
Edward Hervey | a1b7f84 | 2012-03-06 18:11:35 +0100 | [diff] [blame] | 22 | /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex |
| 23 | * with newer GLib versions (>= 2.31.0) */ |
| 24 | #define GLIB_DISABLE_DEPRECATION_WARNINGS |
| 25 | |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 26 | #ifdef HAVE_CONFIG_H |
| 27 | #include "config.h" |
| 28 | #endif |
| 29 | |
| 30 | #include "gstmusepackdec.h" |
| 31 | #include "gstmusepackreader.h" |
| 32 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 33 | GST_DEBUG_CATEGORY (musepackdec_debug); |
| 34 | #define GST_CAT_DEFAULT musepackdec_debug |
| 35 | |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 36 | static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", |
| 37 | GST_PAD_SINK, |
| 38 | GST_PAD_ALWAYS, |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 39 | #ifdef MPC_IS_OLD_API |
| 40 | GST_STATIC_CAPS ("audio/x-musepack, streamversion = (int) 7") |
| 41 | #else |
| 42 | GST_STATIC_CAPS ("audio/x-musepack, streamversion = (int) { 7, 8 }") |
| 43 | #endif |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 44 | ); |
| 45 | |
Ronald S. Bultje | 40e9cff | 2004-12-03 18:13:43 +0000 | [diff] [blame] | 46 | #ifdef MPC_FIXED_POINT |
| 47 | #define BASE_CAPS \ |
| 48 | "audio/x-raw-int, " \ |
| 49 | "signed = (bool) TRUE, " \ |
| 50 | "width = (int) 32, " \ |
| 51 | "depth = (int) 32" |
| 52 | #else |
| 53 | #define BASE_CAPS \ |
| 54 | "audio/x-raw-float, " \ |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 55 | "width = (int) 32" |
Ronald S. Bultje | 40e9cff | 2004-12-03 18:13:43 +0000 | [diff] [blame] | 56 | #endif |
| 57 | |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 58 | static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", |
| 59 | GST_PAD_SRC, |
| 60 | GST_PAD_ALWAYS, |
Ronald S. Bultje | 40e9cff | 2004-12-03 18:13:43 +0000 | [diff] [blame] | 61 | GST_STATIC_CAPS (BASE_CAPS ", " |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 62 | "endianness = (int) BYTE_ORDER, " |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 63 | "rate = (int) [ 8000, 96000 ], " "channels = (int) [ 1, 2 ]") |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 64 | ); |
| 65 | |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 66 | static void gst_musepackdec_dispose (GObject * obj); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 67 | |
| 68 | static gboolean gst_musepackdec_src_event (GstPad * pad, GstEvent * event); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 69 | static const GstQueryType *gst_musepackdec_get_src_query_types (GstPad * pad); |
| 70 | static gboolean gst_musepackdec_src_query (GstPad * pad, GstQuery * query); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 71 | static gboolean gst_musepackdec_sink_activate (GstPad * sinkpad); |
| 72 | static gboolean |
| 73 | gst_musepackdec_sink_activate_pull (GstPad * sinkpad, gboolean active); |
| 74 | |
| 75 | static void gst_musepackdec_loop (GstPad * sinkpad); |
Jan Schmidt | 012dfb8 | 2005-09-05 17:20:29 +0000 | [diff] [blame] | 76 | static GstStateChangeReturn |
| 77 | gst_musepackdec_change_state (GstElement * element, GstStateChange transition); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 78 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 79 | GST_BOILERPLATE (GstMusepackDec, gst_musepackdec, GstElement, GST_TYPE_ELEMENT); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 80 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 81 | static void |
| 82 | gst_musepackdec_base_init (gpointer klass) |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 83 | { |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 84 | GstElementClass *element_class = GST_ELEMENT_CLASS (klass); |
| 85 | |
| 86 | gst_element_class_add_pad_template (element_class, |
| 87 | gst_static_pad_template_get (&src_template)); |
| 88 | gst_element_class_add_pad_template (element_class, |
| 89 | gst_static_pad_template_get (&sink_template)); |
| 90 | |
Mark Nauwelaerts | 578861a | 2012-09-14 17:08:49 +0200 | [diff] [blame] | 91 | gst_element_class_set_metadata (element_class, "Musepack decoder", |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 92 | "Codec/Decoder/Audio", |
| 93 | "Musepack decoder", "Ronald Bultje <rbultje@ronald.bitfreak.net>"); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | static void |
| 97 | gst_musepackdec_class_init (GstMusepackDecClass * klass) |
| 98 | { |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 99 | GST_ELEMENT_CLASS (klass)->change_state = |
| 100 | GST_DEBUG_FUNCPTR (gst_musepackdec_change_state); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 101 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 102 | G_OBJECT_CLASS (klass)->dispose = GST_DEBUG_FUNCPTR (gst_musepackdec_dispose); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 103 | } |
| 104 | |
| 105 | static void |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 106 | gst_musepackdec_init (GstMusepackDec * musepackdec, GstMusepackDecClass * klass) |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 107 | { |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 108 | musepackdec->offset = 0; |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 109 | musepackdec->rate = 0; |
| 110 | musepackdec->bps = 0; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 111 | |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 112 | musepackdec->r = g_new (mpc_reader, 1); |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 113 | #ifdef MPC_IS_OLD_API |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 114 | musepackdec->d = g_new (mpc_decoder, 1); |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 115 | #endif |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 116 | |
| 117 | musepackdec->sinkpad = |
Tim-Philipp Müller | 8b081dd | 2006-04-14 13:12:58 +0000 | [diff] [blame] | 118 | gst_pad_new_from_static_template (&sink_template, "sink"); |
| 119 | gst_pad_set_activate_function (musepackdec->sinkpad, |
| 120 | GST_DEBUG_FUNCPTR (gst_musepackdec_sink_activate)); |
| 121 | gst_pad_set_activatepull_function (musepackdec->sinkpad, |
| 122 | GST_DEBUG_FUNCPTR (gst_musepackdec_sink_activate_pull)); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 123 | gst_element_add_pad (GST_ELEMENT (musepackdec), musepackdec->sinkpad); |
| 124 | |
Tim-Philipp Müller | 8b081dd | 2006-04-14 13:12:58 +0000 | [diff] [blame] | 125 | musepackdec->srcpad = gst_pad_new_from_static_template (&src_template, "src"); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 126 | gst_pad_set_event_function (musepackdec->srcpad, |
| 127 | GST_DEBUG_FUNCPTR (gst_musepackdec_src_event)); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 128 | gst_pad_set_query_function (musepackdec->srcpad, |
| 129 | GST_DEBUG_FUNCPTR (gst_musepackdec_src_query)); |
| 130 | gst_pad_set_query_type_function (musepackdec->srcpad, |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 131 | GST_DEBUG_FUNCPTR (gst_musepackdec_get_src_query_types)); |
| 132 | gst_pad_use_fixed_caps (musepackdec->srcpad); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 133 | gst_element_add_pad (GST_ELEMENT (musepackdec), musepackdec->srcpad); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 134 | } |
| 135 | |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 136 | static void |
| 137 | gst_musepackdec_dispose (GObject * obj) |
| 138 | { |
| 139 | GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (obj); |
| 140 | |
| 141 | g_free (musepackdec->r); |
| 142 | musepackdec->r = NULL; |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 143 | |
| 144 | #ifdef MPC_IS_OLD_API |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 145 | g_free (musepackdec->d); |
| 146 | musepackdec->d = NULL; |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 147 | #else |
| 148 | if (musepackdec->d) { |
| 149 | mpc_demux_exit (musepackdec->d); |
| 150 | musepackdec->d = NULL; |
| 151 | } |
| 152 | #endif |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 153 | |
| 154 | G_OBJECT_CLASS (parent_class)->dispose (obj); |
| 155 | } |
| 156 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 157 | static void |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 158 | gst_musepackdec_send_newsegment (GstMusepackDec * dec) |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 159 | { |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 160 | GstSegment *s = &dec->segment; |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 161 | gint64 stop_time = GST_CLOCK_TIME_NONE; |
| 162 | gint64 start_time = 0; |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 163 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 164 | start_time = gst_util_uint64_scale_int (s->start, GST_SECOND, dec->rate); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 165 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 166 | if (s->stop != -1) |
| 167 | stop_time = gst_util_uint64_scale_int (s->stop, GST_SECOND, dec->rate); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 168 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 169 | GST_DEBUG_OBJECT (dec, "sending newsegment from %" GST_TIME_FORMAT |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 170 | " to %" GST_TIME_FORMAT ", rate = %.1f", GST_TIME_ARGS (start_time), |
| 171 | GST_TIME_ARGS (stop_time), s->rate); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 172 | |
| 173 | gst_pad_push_event (dec->srcpad, |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 174 | gst_event_new_new_segment (FALSE, s->rate, GST_FORMAT_TIME, |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 175 | start_time, stop_time, start_time)); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 176 | } |
| 177 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 178 | static gboolean |
| 179 | gst_musepackdec_handle_seek_event (GstMusepackDec * dec, GstEvent * event) |
| 180 | { |
| 181 | GstSeekType start_type, stop_type; |
| 182 | GstSeekFlags flags; |
| 183 | GstSegment segment; |
| 184 | GstFormat format; |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 185 | gboolean flush; |
| 186 | gdouble rate; |
| 187 | gint64 start, stop; |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 188 | gint samplerate; |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 189 | |
| 190 | gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, |
| 191 | &stop_type, &stop); |
| 192 | |
| 193 | if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) { |
| 194 | GST_DEBUG_OBJECT (dec, "seek failed: only TIME or DEFAULT format allowed"); |
| 195 | return FALSE; |
| 196 | } |
| 197 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 198 | samplerate = g_atomic_int_get (&dec->rate); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 199 | |
| 200 | if (format == GST_FORMAT_TIME) { |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 201 | if (start_type != GST_SEEK_TYPE_NONE) |
| 202 | start = gst_util_uint64_scale_int (start, samplerate, GST_SECOND); |
| 203 | if (stop_type != GST_SEEK_TYPE_NONE) |
| 204 | stop = gst_util_uint64_scale_int (stop, samplerate, GST_SECOND); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 205 | } |
| 206 | |
| 207 | flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH); |
| 208 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 209 | if (flush) |
| 210 | gst_pad_push_event (dec->srcpad, gst_event_new_flush_start ()); |
| 211 | else |
| 212 | gst_pad_pause_task (dec->sinkpad); /* not _stop_task()? */ |
| 213 | |
| 214 | GST_PAD_STREAM_LOCK (dec->sinkpad); |
| 215 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 216 | /* operate on segment copy until we know the seek worked */ |
| 217 | segment = dec->segment; |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 218 | |
| 219 | gst_segment_set_seek (&segment, rate, GST_FORMAT_DEFAULT, |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 220 | flags, start_type, start, stop_type, stop, NULL); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 221 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 222 | gst_pad_push_event (dec->sinkpad, gst_event_new_flush_stop ()); |
| 223 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 224 | GST_DEBUG_OBJECT (dec, "segment: [%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT |
| 225 | "] = [%" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "]", |
| 226 | segment.start, segment.stop, |
| 227 | GST_TIME_ARGS (segment.start * GST_SECOND / dec->rate), |
| 228 | GST_TIME_ARGS (segment.stop * GST_SECOND / dec->rate)); |
| 229 | |
| 230 | GST_DEBUG_OBJECT (dec, "performing seek to sample %" G_GINT64_FORMAT, |
| 231 | segment.start); |
| 232 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 233 | if (segment.start < 0 || segment.start >= segment.duration) { |
| 234 | GST_WARNING_OBJECT (dec, "seek out of bounds"); |
| 235 | goto failed; |
| 236 | } |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 237 | #ifdef MPC_IS_OLD_API |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 238 | if (!mpc_decoder_seek_sample (dec->d, segment.start)) |
| 239 | goto failed; |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 240 | #else |
| 241 | if (mpc_demux_seek_sample (dec->d, segment.start) != MPC_STATUS_OK) |
| 242 | goto failed; |
| 243 | #endif |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 244 | |
Tim-Philipp Müller | af701d8 | 2006-04-20 18:02:07 +0000 | [diff] [blame] | 245 | if ((flags & GST_SEEK_FLAG_SEGMENT) == GST_SEEK_FLAG_SEGMENT) { |
| 246 | GST_DEBUG_OBJECT (dec, "posting SEGMENT_START message"); |
| 247 | |
| 248 | gst_element_post_message (GST_ELEMENT (dec), |
| 249 | gst_message_new_segment_start (GST_OBJECT (dec), GST_FORMAT_TIME, |
| 250 | gst_util_uint64_scale_int (segment.start, GST_SECOND, dec->rate))); |
| 251 | } |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 252 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 253 | if (flush) { |
| 254 | gst_pad_push_event (dec->srcpad, gst_event_new_flush_stop ()); |
| 255 | } |
| 256 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 257 | gst_segment_set_last_stop (&segment, GST_FORMAT_DEFAULT, segment.start); |
| 258 | dec->segment = segment; |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 259 | gst_musepackdec_send_newsegment (dec); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 260 | |
| 261 | GST_DEBUG_OBJECT (dec, "seek successful"); |
| 262 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 263 | gst_pad_start_task (dec->sinkpad, |
Wim Taymans | dbed726 | 2012-06-20 10:34:48 +0200 | [diff] [blame] | 264 | (GstTaskFunction) gst_musepackdec_loop, dec->sinkpad, NULL); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 265 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 266 | GST_PAD_STREAM_UNLOCK (dec->sinkpad); |
| 267 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 268 | return TRUE; |
| 269 | |
| 270 | failed: |
| 271 | { |
| 272 | GST_WARNING_OBJECT (dec, "seek failed"); |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 273 | GST_PAD_STREAM_UNLOCK (dec->sinkpad); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 274 | return FALSE; |
| 275 | } |
| 276 | } |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 277 | |
| 278 | static gboolean |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 279 | gst_musepackdec_src_event (GstPad * pad, GstEvent * event) |
| 280 | { |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 281 | GstMusepackDec *dec; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 282 | gboolean res; |
| 283 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 284 | dec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); |
| 285 | |
| 286 | GST_DEBUG_OBJECT (dec, "handling %s event", GST_EVENT_TYPE_NAME (event)); |
| 287 | |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 288 | switch (GST_EVENT_TYPE (event)) { |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 289 | case GST_EVENT_SEEK: |
| 290 | res = gst_musepackdec_handle_seek_event (dec, event); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 291 | break; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 292 | default: |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 293 | res = gst_pad_event_default (pad, event); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 294 | break; |
| 295 | } |
| 296 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 297 | gst_object_unref (dec); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 298 | return res; |
| 299 | } |
| 300 | |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 301 | static const GstQueryType * |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 302 | gst_musepackdec_get_src_query_types (GstPad * pad) |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 303 | { |
| 304 | static const GstQueryType query_types[] = { |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 305 | GST_QUERY_POSITION, |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 306 | GST_QUERY_DURATION, |
Sebastian Dröge | 7de65d9 | 2009-07-24 07:40:17 +0200 | [diff] [blame] | 307 | GST_QUERY_SEEKING, |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 308 | (GstQueryType) 0 |
| 309 | }; |
| 310 | |
| 311 | return query_types; |
| 312 | } |
| 313 | |
| 314 | static gboolean |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 315 | gst_musepackdec_src_query (GstPad * pad, GstQuery * query) |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 316 | { |
| 317 | GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (gst_pad_get_parent (pad)); |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 318 | GstFormat format; |
| 319 | gboolean res = FALSE; |
| 320 | gint samplerate; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 321 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 322 | samplerate = g_atomic_int_get (&musepackdec->rate); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 323 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 324 | if (samplerate == 0) |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 325 | goto done; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 326 | |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 327 | switch (GST_QUERY_TYPE (query)) { |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 328 | case GST_QUERY_POSITION:{ |
| 329 | gint64 cur, cur_off; |
| 330 | |
| 331 | gst_query_parse_position (query, &format, NULL); |
| 332 | |
| 333 | GST_OBJECT_LOCK (musepackdec); |
| 334 | cur_off = musepackdec->segment.last_stop; |
| 335 | GST_OBJECT_UNLOCK (musepackdec); |
| 336 | |
| 337 | if (format == GST_FORMAT_TIME) { |
| 338 | cur = gst_util_uint64_scale_int (cur_off, GST_SECOND, samplerate); |
| 339 | gst_query_set_position (query, GST_FORMAT_TIME, cur); |
| 340 | res = TRUE; |
| 341 | } else if (format == GST_FORMAT_DEFAULT) { |
| 342 | gst_query_set_position (query, GST_FORMAT_DEFAULT, cur_off); |
| 343 | res = TRUE; |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 344 | } |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 345 | break; |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 346 | } |
| 347 | case GST_QUERY_DURATION:{ |
| 348 | gint64 len, len_off; |
| 349 | |
| 350 | gst_query_parse_duration (query, &format, NULL); |
| 351 | |
| 352 | GST_OBJECT_LOCK (musepackdec); |
| 353 | len_off = musepackdec->segment.duration; |
| 354 | GST_OBJECT_UNLOCK (musepackdec); |
| 355 | |
| 356 | if (format == GST_FORMAT_TIME) { |
| 357 | len = gst_util_uint64_scale_int (len_off, GST_SECOND, samplerate); |
| 358 | gst_query_set_duration (query, GST_FORMAT_TIME, len); |
| 359 | res = TRUE; |
| 360 | } else if (format == GST_FORMAT_DEFAULT) { |
| 361 | gst_query_set_duration (query, GST_FORMAT_DEFAULT, len_off); |
| 362 | res = TRUE; |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 363 | } |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 364 | break; |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 365 | } |
Sebastian Dröge | 7de65d9 | 2009-07-24 07:40:17 +0200 | [diff] [blame] | 366 | case GST_QUERY_SEEKING:{ |
| 367 | GstFormat fmt; |
| 368 | |
| 369 | res = TRUE; |
| 370 | gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); |
| 371 | if (fmt == GST_FORMAT_TIME || fmt == GST_FORMAT_DEFAULT) |
| 372 | gst_query_set_seeking (query, fmt, TRUE, 0, -1); |
| 373 | else |
| 374 | gst_query_set_seeking (query, fmt, FALSE, -1, -1); |
| 375 | |
| 376 | break; |
| 377 | } |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 378 | default: |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 379 | res = gst_pad_query_default (pad, query); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 380 | break; |
| 381 | } |
| 382 | |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 383 | done: |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 384 | gst_object_unref (musepackdec); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 385 | return res; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 386 | } |
| 387 | |
| 388 | static gboolean |
| 389 | gst_musepack_stream_init (GstMusepackDec * musepackdec) |
| 390 | { |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 391 | mpc_streaminfo i; |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 392 | GstTagList *tags; |
Ronald S. Bultje | 40e9cff | 2004-12-03 18:13:43 +0000 | [diff] [blame] | 393 | GstCaps *caps; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 394 | |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 395 | /* set up reading */ |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 396 | gst_musepack_init_reader (musepackdec->r, musepackdec); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 397 | |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 398 | #ifdef MPC_IS_OLD_API |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 399 | /* streaminfo */ |
| 400 | mpc_streaminfo_init (&i); |
| 401 | if (mpc_streaminfo_read (&i, musepackdec->r) < 0) { |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 402 | GST_ELEMENT_ERROR (musepackdec, STREAM, WRONG_TYPE, (NULL), (NULL)); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 403 | return FALSE; |
| 404 | } |
| 405 | |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 406 | /* decoding */ |
| 407 | mpc_decoder_setup (musepackdec->d, musepackdec->r); |
| 408 | mpc_decoder_scale_output (musepackdec->d, 1.0); |
| 409 | if (!mpc_decoder_initialize (musepackdec->d, &i)) { |
| 410 | GST_ELEMENT_ERROR (musepackdec, STREAM, WRONG_TYPE, (NULL), (NULL)); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 411 | return FALSE; |
| 412 | } |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 413 | #else |
| 414 | musepackdec->d = mpc_demux_init (musepackdec->r); |
| 415 | if (!musepackdec->d) { |
| 416 | GST_ELEMENT_ERROR (musepackdec, STREAM, WRONG_TYPE, (NULL), (NULL)); |
| 417 | return FALSE; |
| 418 | } |
| 419 | |
| 420 | mpc_demux_get_info (musepackdec->d, &i); |
| 421 | #endif |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 422 | |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 423 | /* capsnego */ |
Ronald S. Bultje | 40e9cff | 2004-12-03 18:13:43 +0000 | [diff] [blame] | 424 | caps = gst_caps_from_string (BASE_CAPS); |
| 425 | gst_caps_set_simple (caps, |
| 426 | "endianness", G_TYPE_INT, G_BYTE_ORDER, |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 427 | "channels", G_TYPE_INT, i.channels, |
| 428 | "rate", G_TYPE_INT, i.sample_freq, NULL); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 429 | gst_pad_use_fixed_caps (musepackdec->srcpad); |
| 430 | if (!gst_pad_set_caps (musepackdec->srcpad, caps)) { |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 431 | GST_ELEMENT_ERROR (musepackdec, CORE, NEGOTIATION, (NULL), (NULL)); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 432 | return FALSE; |
| 433 | } |
| 434 | |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 435 | g_atomic_int_set (&musepackdec->bps, 4 * i.channels); |
| 436 | g_atomic_int_set (&musepackdec->rate, i.sample_freq); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 437 | |
| 438 | gst_segment_set_last_stop (&musepackdec->segment, GST_FORMAT_DEFAULT, 0); |
| 439 | gst_segment_set_duration (&musepackdec->segment, GST_FORMAT_DEFAULT, |
| 440 | mpc_streaminfo_get_length_samples (&i)); |
| 441 | |
| 442 | /* send basic tags */ |
| 443 | tags = gst_tag_list_new (); |
| 444 | gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, |
| 445 | GST_TAG_AUDIO_CODEC, "Musepack", NULL); |
| 446 | |
| 447 | if (i.encoder[0] != '\0' && i.encoder_version > 0) { |
| 448 | gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, |
| 449 | GST_TAG_ENCODER, i.encoder, |
| 450 | GST_TAG_ENCODER_VERSION, i.encoder_version, NULL); |
| 451 | } |
| 452 | |
| 453 | if (i.bitrate > 0) { |
| 454 | gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, |
| 455 | GST_TAG_BITRATE, i.bitrate, NULL); |
| 456 | } else if (i.average_bitrate > 0.0) { |
| 457 | gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, |
| 458 | GST_TAG_BITRATE, (guint) i.average_bitrate, NULL); |
| 459 | } |
| 460 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 461 | if (i.gain_title != 0 || i.gain_album != 0) { |
| 462 | gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, |
| 463 | GST_TAG_TRACK_GAIN, (gdouble) i.gain_title / 100.0, |
| 464 | GST_TAG_ALBUM_GAIN, (gdouble) i.gain_album / 100.0, NULL); |
| 465 | } |
| 466 | |
Tim-Philipp Müller | 8b081dd | 2006-04-14 13:12:58 +0000 | [diff] [blame] | 467 | if (i.peak_title != 0 && i.peak_title != 32767 && |
| 468 | i.peak_album != 0 && i.peak_album != 32767) { |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 469 | gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, |
Tim-Philipp Müller | 8b081dd | 2006-04-14 13:12:58 +0000 | [diff] [blame] | 470 | GST_TAG_TRACK_PEAK, (gdouble) i.peak_title / 32767.0, |
| 471 | GST_TAG_ALBUM_PEAK, (gdouble) i.peak_album / 32767.0, NULL); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 472 | } |
| 473 | |
| 474 | GST_LOG_OBJECT (musepackdec, "Posting tags: %" GST_PTR_FORMAT, tags); |
| 475 | gst_element_found_tags (GST_ELEMENT (musepackdec), tags); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 476 | |
| 477 | return TRUE; |
| 478 | } |
| 479 | |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 480 | static gboolean |
| 481 | gst_musepackdec_sink_activate (GstPad * sinkpad) |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 482 | { |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 483 | if (!gst_pad_check_pull_range (sinkpad)) |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 484 | return FALSE; |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 485 | |
| 486 | return gst_pad_activate_pull (sinkpad, TRUE); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 487 | } |
| 488 | |
| 489 | static gboolean |
| 490 | gst_musepackdec_sink_activate_pull (GstPad * sinkpad, gboolean active) |
| 491 | { |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 492 | gboolean result; |
| 493 | |
| 494 | if (active) { |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 495 | result = gst_pad_start_task (sinkpad, |
Wim Taymans | dbed726 | 2012-06-20 10:34:48 +0200 | [diff] [blame] | 496 | (GstTaskFunction) gst_musepackdec_loop, sinkpad, NULL); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 497 | } else { |
| 498 | result = gst_pad_stop_task (sinkpad); |
| 499 | } |
| 500 | |
| 501 | return result; |
| 502 | } |
| 503 | |
| 504 | static void |
| 505 | gst_musepackdec_loop (GstPad * sinkpad) |
| 506 | { |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 507 | GstMusepackDec *musepackdec; |
| 508 | GstFlowReturn flow; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 509 | GstBuffer *out; |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 510 | |
| 511 | #ifdef MPC_IS_OLD_API |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 512 | guint32 update_acc, update_bits; |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 513 | #else |
| 514 | mpc_frame_info frame; |
| 515 | mpc_status err; |
| 516 | #endif |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 517 | gint num_samples, samplerate, bitspersample; |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 518 | |
| 519 | musepackdec = GST_MUSEPACK_DEC (GST_PAD_PARENT (sinkpad)); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 520 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 521 | samplerate = g_atomic_int_get (&musepackdec->rate); |
| 522 | |
| 523 | if (samplerate == 0) { |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 524 | if (!gst_musepack_stream_init (musepackdec)) |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 525 | goto pause_task; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 526 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 527 | gst_musepackdec_send_newsegment (musepackdec); |
| 528 | samplerate = g_atomic_int_get (&musepackdec->rate); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 529 | } |
| 530 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 531 | bitspersample = g_atomic_int_get (&musepackdec->bps); |
| 532 | |
| 533 | flow = gst_pad_alloc_buffer_and_set_caps (musepackdec->srcpad, -1, |
| 534 | MPC_DECODER_BUFFER_LENGTH * 4, GST_PAD_CAPS (musepackdec->srcpad), &out); |
| 535 | |
| 536 | if (flow != GST_FLOW_OK) { |
| 537 | GST_DEBUG_OBJECT (musepackdec, "Flow: %s", gst_flow_get_name (flow)); |
| 538 | goto pause_task; |
| 539 | } |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 540 | #ifdef MPC_IS_OLD_API |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 541 | num_samples = mpc_decoder_decode (musepackdec->d, |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 542 | (MPC_SAMPLE_FORMAT *) GST_BUFFER_DATA (out), &update_acc, &update_bits); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 543 | |
| 544 | if (num_samples < 0) { |
| 545 | GST_ERROR_OBJECT (musepackdec, "Failed to decode sample"); |
| 546 | GST_ELEMENT_ERROR (musepackdec, STREAM, DECODE, (NULL), (NULL)); |
| 547 | goto pause_task; |
| 548 | } else if (num_samples == 0) { |
Tim-Philipp Müller | af701d8 | 2006-04-20 18:02:07 +0000 | [diff] [blame] | 549 | goto eos_and_pause; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 550 | } |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 551 | #else |
| 552 | frame.buffer = (MPC_SAMPLE_FORMAT *) GST_BUFFER_DATA (out); |
| 553 | err = mpc_demux_decode (musepackdec->d, &frame); |
| 554 | |
| 555 | if (err != MPC_STATUS_OK) { |
| 556 | GST_ERROR_OBJECT (musepackdec, "Failed to decode sample"); |
| 557 | GST_ELEMENT_ERROR (musepackdec, STREAM, DECODE, (NULL), (NULL)); |
| 558 | goto pause_task; |
| 559 | } else if (frame.bits == -1) { |
| 560 | goto eos_and_pause; |
| 561 | } |
| 562 | |
| 563 | num_samples = frame.samples; |
| 564 | #endif |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 565 | |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 566 | GST_BUFFER_SIZE (out) = num_samples * bitspersample; |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 567 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 568 | GST_BUFFER_OFFSET (out) = musepackdec->segment.last_stop; |
| 569 | GST_BUFFER_TIMESTAMP (out) = |
| 570 | gst_util_uint64_scale_int (musepackdec->segment.last_stop, |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 571 | GST_SECOND, samplerate); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 572 | GST_BUFFER_DURATION (out) = |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 573 | gst_util_uint64_scale_int (num_samples, GST_SECOND, samplerate); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 574 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 575 | musepackdec->segment.last_stop += num_samples; |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 576 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 577 | GST_LOG_OBJECT (musepackdec, "Pushing buffer, timestamp %" GST_TIME_FORMAT, |
Tim-Philipp Müller | 6435014 | 2005-12-12 10:40:42 +0000 | [diff] [blame] | 578 | GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (out))); |
| 579 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 580 | flow = gst_pad_push (musepackdec->srcpad, out); |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 581 | if (flow != GST_FLOW_OK) { |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 582 | GST_DEBUG_OBJECT (musepackdec, "Flow: %s", gst_flow_get_name (flow)); |
| 583 | goto pause_task; |
| 584 | } |
| 585 | |
Tim-Philipp Müller | af701d8 | 2006-04-20 18:02:07 +0000 | [diff] [blame] | 586 | /* check if we're at the end of a configured segment */ |
| 587 | if (musepackdec->segment.stop != -1 && |
| 588 | musepackdec->segment.last_stop >= musepackdec->segment.stop) { |
| 589 | gint64 stop_time; |
| 590 | |
| 591 | GST_DEBUG_OBJECT (musepackdec, "Reached end of configured segment"); |
| 592 | |
| 593 | if ((musepackdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) |
| 594 | goto eos_and_pause; |
| 595 | |
| 596 | GST_DEBUG_OBJECT (musepackdec, "Posting SEGMENT_DONE message"); |
| 597 | |
| 598 | stop_time = gst_util_uint64_scale_int (musepackdec->segment.stop, |
| 599 | GST_SECOND, samplerate); |
| 600 | |
| 601 | gst_element_post_message (GST_ELEMENT (musepackdec), |
| 602 | gst_message_new_segment_done (GST_OBJECT (musepackdec), |
| 603 | GST_FORMAT_TIME, stop_time)); |
Sebastian Dröge | 9c7d749 | 2012-07-05 13:18:47 +0200 | [diff] [blame] | 604 | gst_pad_push_event (musepackdec->srcpad, |
| 605 | gst_event_new_segment_done (GST_FORMAT_TIME, stop_time)); |
Tim-Philipp Müller | af701d8 | 2006-04-20 18:02:07 +0000 | [diff] [blame] | 606 | |
| 607 | goto pause_task; |
| 608 | } |
| 609 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 610 | return; |
| 611 | |
Tim-Philipp Müller | af701d8 | 2006-04-20 18:02:07 +0000 | [diff] [blame] | 612 | eos_and_pause: |
| 613 | { |
| 614 | GST_DEBUG_OBJECT (musepackdec, "sending EOS event"); |
| 615 | gst_pad_push_event (musepackdec->srcpad, gst_event_new_eos ()); |
| 616 | /* fall through to pause */ |
| 617 | } |
| 618 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 619 | pause_task: |
| 620 | { |
| 621 | GST_DEBUG_OBJECT (musepackdec, "Pausing task"); |
| 622 | gst_pad_pause_task (sinkpad); |
| 623 | return; |
| 624 | } |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 625 | } |
| 626 | |
Jan Schmidt | 012dfb8 | 2005-09-05 17:20:29 +0000 | [diff] [blame] | 627 | static GstStateChangeReturn |
| 628 | gst_musepackdec_change_state (GstElement * element, GstStateChange transition) |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 629 | { |
| 630 | GstMusepackDec *musepackdec = GST_MUSEPACK_DEC (element); |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 631 | GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; |
| 632 | |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 633 | switch (transition) { |
| 634 | case GST_STATE_CHANGE_READY_TO_PAUSED: |
| 635 | gst_segment_init (&musepackdec->segment, GST_FORMAT_DEFAULT); |
| 636 | gst_segment_set_last_stop (&musepackdec->segment, GST_FORMAT_DEFAULT, 0); |
| 637 | break; |
| 638 | default: |
| 639 | break; |
| 640 | } |
| 641 | |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 642 | if (GST_ELEMENT_CLASS (parent_class)->change_state) |
| 643 | ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); |
| 644 | |
Jan Schmidt | 012dfb8 | 2005-09-05 17:20:29 +0000 | [diff] [blame] | 645 | switch (transition) { |
Jan Schmidt | 012dfb8 | 2005-09-05 17:20:29 +0000 | [diff] [blame] | 646 | case GST_STATE_CHANGE_PAUSED_TO_READY: |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 647 | gst_segment_init (&musepackdec->segment, GST_FORMAT_UNDEFINED); |
Tim-Philipp Müller | b92a9c4 | 2006-01-24 21:33:25 +0000 | [diff] [blame] | 648 | musepackdec->offset = 0; |
Tim-Philipp Müller | 13cd0b0 | 2006-03-06 13:13:44 +0000 | [diff] [blame] | 649 | musepackdec->rate = 0; |
| 650 | musepackdec->bps = 0; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 651 | break; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 652 | default: |
| 653 | break; |
| 654 | } |
| 655 | |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 656 | return ret; |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 657 | |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 658 | } |
| 659 | |
| 660 | static gboolean |
| 661 | plugin_init (GstPlugin * plugin) |
| 662 | { |
Sebastian Dröge | 01bcb09 | 2008-04-24 22:19:48 +0000 | [diff] [blame] | 663 | GST_DEBUG_CATEGORY_INIT (musepackdec_debug, "musepackdec", 0, "mpc decoder"); |
| 664 | |
Edgard Lima | a5ef8ae | 2005-11-22 15:09:28 +0000 | [diff] [blame] | 665 | return gst_element_register (plugin, "musepackdec", |
Ronald S. Bultje | f6b6f72 | 2005-01-29 01:28:34 +0000 | [diff] [blame] | 666 | GST_RANK_PRIMARY, GST_TYPE_MUSEPACK_DEC); |
Ronald S. Bultje | 868291e | 2004-11-07 18:30:06 +0000 | [diff] [blame] | 667 | } |
| 668 | |
| 669 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, |
| 670 | GST_VERSION_MINOR, |
Sebastian Dröge | cda192b | 2012-04-05 18:02:56 +0200 | [diff] [blame] | 671 | musepack, |
Thomas Vander Stichele | 60f8059 | 2006-04-01 10:09:11 +0000 | [diff] [blame] | 672 | "Musepack decoder", plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, |
| 673 | GST_PACKAGE_ORIGIN) |