2 * Initially based on gst-omx/omx/gstomxvideodec.c
4 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
5 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
7 * Copyright (C) 2012, Collabora Ltd.
8 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
10 * Copyright (C) 2015, Sebastian Dröge <sebastian@centricular.com>
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation
15 * version 2.1 of the License.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <gst/audio/audio.h>
39 #define orc_memcpy memcpy
42 #include "gstamcaudiodec.h"
43 #include "gstamc-constants.h"
45 GST_DEBUG_CATEGORY_STATIC (gst_amc_audio_dec_debug_category);
46 #define GST_CAT_DEFAULT gst_amc_audio_dec_debug_category
48 #define GST_AUDIO_DECODER_ERROR_FROM_ERROR(el, err) G_STMT_START { \
49 gchar *__dbg = g_strdup (err->message); \
50 GstAudioDecoder *__dec = GST_AUDIO_DECODER (el); \
51 GST_WARNING_OBJECT (el, "error: %s", __dbg); \
52 _gst_audio_decoder_error (__dec, 1, \
53 err->domain, err->code, \
54 NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__); \
55 g_clear_error (&err); \
59 static void gst_amc_audio_dec_finalize (GObject * object);
61 static GstStateChangeReturn
62 gst_amc_audio_dec_change_state (GstElement * element,
63 GstStateChange transition);
65 static gboolean gst_amc_audio_dec_open (GstAudioDecoder * decoder);
66 static gboolean gst_amc_audio_dec_close (GstAudioDecoder * decoder);
67 static gboolean gst_amc_audio_dec_start (GstAudioDecoder * decoder);
68 static gboolean gst_amc_audio_dec_stop (GstAudioDecoder * decoder);
69 static gboolean gst_amc_audio_dec_set_format (GstAudioDecoder * decoder,
71 static void gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard);
72 static GstFlowReturn gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder,
75 static GstFlowReturn gst_amc_audio_dec_drain (GstAmcAudioDec * self);
82 /* class initialization */
84 static void gst_amc_audio_dec_class_init (GstAmcAudioDecClass * klass);
85 static void gst_amc_audio_dec_init (GstAmcAudioDec * self);
86 static void gst_amc_audio_dec_base_init (gpointer g_class);
88 static GstAudioDecoderClass *parent_class = NULL;
91 gst_amc_audio_dec_get_type (void)
93 static gsize type = 0;
95 if (g_once_init_enter (&type)) {
97 static const GTypeInfo info = {
98 sizeof (GstAmcAudioDecClass),
99 gst_amc_audio_dec_base_init,
101 (GClassInitFunc) gst_amc_audio_dec_class_init,
104 sizeof (GstAmcAudioDec),
106 (GInstanceInitFunc) gst_amc_audio_dec_init,
110 _type = g_type_register_static (GST_TYPE_AUDIO_DECODER, "GstAmcAudioDec",
113 GST_DEBUG_CATEGORY_INIT (gst_amc_audio_dec_debug_category, "amcaudiodec", 0,
114 "Android MediaCodec audio decoder");
116 g_once_init_leave (&type, _type);
122 caps_to_mime (GstCaps * caps)
127 s = gst_caps_get_structure (caps, 0);
131 name = gst_structure_get_name (s);
133 if (strcmp (name, "audio/mpeg") == 0) {
136 if (!gst_structure_get_int (s, "mpegversion", &mpegversion))
139 if (mpegversion == 1) {
142 if (!gst_structure_get_int (s, "layer", &layer) || layer == 3)
145 return "audio/mpeg-L2";
146 } else if (mpegversion == 2 || mpegversion == 4) {
147 return "audio/mp4a-latm";
149 } else if (strcmp (name, "audio/AMR") == 0) {
151 } else if (strcmp (name, "audio/AMR-WB") == 0) {
152 return "audio/amr-wb";
153 } else if (strcmp (name, "audio/x-alaw") == 0) {
154 return "audio/g711-alaw";
155 } else if (strcmp (name, "audio/x-mulaw") == 0) {
156 return "audio/g711-mlaw";
157 } else if (strcmp (name, "audio/x-vorbis") == 0) {
158 return "audio/vorbis";
159 } else if (strcmp (name, "audio/x-opus") == 0) {
167 gst_amc_audio_dec_base_init (gpointer g_class)
169 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
170 GstAmcAudioDecClass *amcaudiodec_class = GST_AMC_AUDIO_DEC_CLASS (g_class);
171 const GstAmcCodecInfo *codec_info;
172 GstPadTemplate *templ;
173 GstCaps *sink_caps, *src_caps;
177 g_type_get_qdata (G_TYPE_FROM_CLASS (g_class), gst_amc_codec_info_quark);
178 /* This happens for the base class and abstract subclasses */
182 amcaudiodec_class->codec_info = codec_info;
184 gst_amc_codec_info_to_caps (codec_info, &sink_caps, &src_caps);
185 /* Add pad templates */
187 gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps);
188 gst_element_class_add_pad_template (element_class, templ);
189 gst_caps_unref (sink_caps);
191 templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps);
192 gst_element_class_add_pad_template (element_class, templ);
193 gst_caps_unref (src_caps);
195 longname = g_strdup_printf ("Android MediaCodec %s", codec_info->name);
196 gst_element_class_set_metadata (element_class,
198 "Codec/Decoder/Audio",
199 longname, "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
204 gst_amc_audio_dec_class_init (GstAmcAudioDecClass * klass)
206 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
207 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
208 GstAudioDecoderClass *audiodec_class = GST_AUDIO_DECODER_CLASS (klass);
210 parent_class = g_type_class_peek_parent (klass);
212 gobject_class->finalize = gst_amc_audio_dec_finalize;
214 element_class->change_state =
215 GST_DEBUG_FUNCPTR (gst_amc_audio_dec_change_state);
217 audiodec_class->start = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_start);
218 audiodec_class->stop = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_stop);
219 audiodec_class->open = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_open);
220 audiodec_class->close = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_close);
221 audiodec_class->flush = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_flush);
222 audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_set_format);
223 audiodec_class->handle_frame =
224 GST_DEBUG_FUNCPTR (gst_amc_audio_dec_handle_frame);
228 gst_amc_audio_dec_init (GstAmcAudioDec * self)
230 gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (self), TRUE);
231 gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (self), TRUE);
233 g_mutex_init (&self->drain_lock);
234 g_cond_init (&self->drain_cond);
235 self->output_adapter = gst_adapter_new ();
239 gst_amc_audio_dec_open (GstAudioDecoder * decoder)
241 GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (decoder);
242 GstAmcAudioDecClass *klass = GST_AMC_AUDIO_DEC_GET_CLASS (self);
245 GST_DEBUG_OBJECT (self, "Opening decoder");
247 self->codec = gst_amc_codec_new (klass->codec_info->name, FALSE, &err);
249 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
252 self->started = FALSE;
253 self->flushing = TRUE;
255 GST_DEBUG_OBJECT (self, "Opened decoder");
261 gst_amc_audio_dec_close (GstAudioDecoder * decoder)
263 GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (decoder);
265 GST_DEBUG_OBJECT (self, "Closing decoder");
270 gst_amc_codec_release (self->codec, &err);
272 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
274 gst_amc_codec_free (self->codec);
278 self->started = FALSE;
279 self->flushing = TRUE;
281 GST_DEBUG_OBJECT (self, "Closed decoder");
287 gst_amc_audio_dec_finalize (GObject * object)
289 GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (object);
291 if (self->output_adapter)
292 gst_object_unref (self->output_adapter);
293 self->output_adapter = NULL;
295 g_mutex_clear (&self->drain_lock);
296 g_cond_clear (&self->drain_cond);
298 G_OBJECT_CLASS (parent_class)->finalize (object);
301 static GstStateChangeReturn
302 gst_amc_audio_dec_change_state (GstElement * element, GstStateChange transition)
304 GstAmcAudioDec *self;
305 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
308 g_return_val_if_fail (GST_IS_AMC_AUDIO_DEC (element),
309 GST_STATE_CHANGE_FAILURE);
310 self = GST_AMC_AUDIO_DEC (element);
312 switch (transition) {
313 case GST_STATE_CHANGE_NULL_TO_READY:
315 case GST_STATE_CHANGE_READY_TO_PAUSED:
316 self->downstream_flow_ret = GST_FLOW_OK;
317 self->draining = FALSE;
318 self->started = FALSE;
320 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
322 case GST_STATE_CHANGE_PAUSED_TO_READY:
323 self->flushing = TRUE;
324 gst_amc_codec_flush (self->codec, &err);
326 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
327 g_mutex_lock (&self->drain_lock);
328 self->draining = FALSE;
329 g_cond_broadcast (&self->drain_cond);
330 g_mutex_unlock (&self->drain_lock);
336 if (ret == GST_STATE_CHANGE_FAILURE)
339 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
341 if (ret == GST_STATE_CHANGE_FAILURE)
344 switch (transition) {
345 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
347 case GST_STATE_CHANGE_PAUSED_TO_READY:
348 self->downstream_flow_ret = GST_FLOW_FLUSHING;
349 self->started = FALSE;
351 case GST_STATE_CHANGE_READY_TO_NULL:
361 gst_amc_audio_dec_set_src_caps (GstAmcAudioDec * self, GstAmcFormat * format)
364 guint32 channel_mask = 0;
365 GstAudioChannelPosition to[64];
368 if (!gst_amc_format_get_int (format, "sample-rate", &rate, &err) ||
369 !gst_amc_format_get_int (format, "channel-count", &channels, &err)) {
370 GST_ERROR_OBJECT (self, "Failed to get output format metadata: %s",
372 g_clear_error (&err);
376 if (rate == 0 || channels == 0) {
377 GST_ERROR_OBJECT (self, "Rate or channels not set");
381 /* Not always present */
382 gst_amc_format_get_int (format, "channel-mask", (gint *) & channel_mask,
385 gst_amc_audio_channel_mask_to_positions (channel_mask, channels,
387 memcpy (to, self->positions, sizeof (to));
388 gst_audio_channel_positions_to_valid_order (to, channels);
389 self->needs_reorder =
390 (memcmp (self->positions, to,
391 sizeof (GstAudioChannelPosition) * channels) != 0);
392 if (self->needs_reorder)
393 gst_audio_get_channel_reorder_map (channels, self->positions, to,
396 gst_audio_info_init (&self->info);
397 gst_audio_info_set_format (&self->info, GST_AUDIO_FORMAT_S16, rate, channels,
400 if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (self),
404 self->input_caps_changed = FALSE;
410 gst_amc_audio_dec_loop (GstAmcAudioDec * self)
412 GstFlowReturn flow_ret = GST_FLOW_OK;
415 GstAmcBufferInfo buffer_info;
419 GST_AUDIO_DECODER_STREAM_LOCK (self);
422 /*if (self->input_caps_changed) {
423 idx = INFO_OUTPUT_FORMAT_CHANGED;
425 GST_DEBUG_OBJECT (self, "Waiting for available output buffer");
426 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
427 /* Wait at most 100ms here, some codecs don't fail dequeueing if
428 * the codec is flushing, causing deadlocks during shutdown */
430 gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000,
432 GST_AUDIO_DECODER_STREAM_LOCK (self);
436 if (self->flushing) {
437 g_clear_error (&err);
442 case INFO_OUTPUT_BUFFERS_CHANGED:
443 /* Handled internally */
444 g_assert_not_reached ();
446 case INFO_OUTPUT_FORMAT_CHANGED:{
447 GstAmcFormat *format;
448 gchar *format_string;
450 GST_DEBUG_OBJECT (self, "Output format has changed");
452 format = gst_amc_codec_get_output_format (self->codec, &err);
456 format_string = gst_amc_format_to_string (format, &err);
458 gst_amc_format_free (format);
461 GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
462 g_free (format_string);
464 if (!gst_amc_audio_dec_set_src_caps (self, format)) {
465 gst_amc_format_free (format);
468 gst_amc_format_free (format);
473 case INFO_TRY_AGAIN_LATER:
474 GST_DEBUG_OBJECT (self, "Dequeueing output buffer timed out");
478 GST_ERROR_OBJECT (self, "Failure dequeueing output buffer");
482 g_assert_not_reached ();
489 GST_DEBUG_OBJECT (self,
490 "Got output buffer at index %d: offset %d size %d time %" G_GINT64_FORMAT
491 " flags 0x%08x", idx, buffer_info.offset, buffer_info.size,
492 buffer_info.presentation_time_us, buffer_info.flags);
494 is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
496 buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
498 if (self->flushing) {
499 g_clear_error (&err);
502 goto failed_to_get_output_buffer;
504 goto got_null_output_buffer;
507 if (buffer_info.size > 0) {
511 /* This sometimes happens at EOS or if the input is not properly framed,
512 * let's handle it gracefully by allocating a new buffer for the current
513 * caps and filling it
516 if (buffer_info.size % self->info.bpf != 0)
517 goto invalid_buffer_size;
520 gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (self),
523 goto failed_allocate;
525 gst_buffer_map (outbuf, &minfo, GST_MAP_WRITE);
526 if (self->needs_reorder) {
527 gint i, n_samples, c, n_channels;
528 gint *reorder_map = self->reorder_map;
529 gint16 *dest, *source;
531 dest = (gint16 *) minfo.data;
532 source = (gint16 *) (buf->data + buffer_info.offset);
533 n_samples = buffer_info.size / self->info.bpf;
534 n_channels = self->info.channels;
536 for (i = 0; i < n_samples; i++) {
537 for (c = 0; c < n_channels; c++) {
538 dest[i * n_channels + reorder_map[c]] = source[i * n_channels + c];
542 orc_memcpy (minfo.data, buf->data + buffer_info.offset, buffer_info.size);
544 gst_buffer_unmap (outbuf, &minfo);
546 if (self->spf != -1) {
547 gst_adapter_push (self->output_adapter, outbuf);
550 gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1);
554 gst_amc_buffer_free (buf);
557 if (self->spf != -1) {
559 guint avail = gst_adapter_available (self->output_adapter);
562 /* On EOS we take the complete adapter content, no matter
563 * if it is a multiple of the codec frame size or not.
564 * Otherwise we take a multiple of codec frames and push
567 avail /= self->info.bpf;
569 nframes = avail / self->spf;
570 avail = nframes * self->spf;
572 nframes = (avail + self->spf - 1) / self->spf;
574 avail *= self->info.bpf;
577 outbuf = gst_adapter_take_buffer (self->output_adapter, avail);
579 gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf,
584 if (!gst_amc_codec_release_output_buffer (self->codec, idx, FALSE, &err)) {
585 if (self->flushing) {
586 g_clear_error (&err);
592 if (is_eos || flow_ret == GST_FLOW_EOS) {
593 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
594 g_mutex_lock (&self->drain_lock);
595 if (self->draining) {
596 GST_DEBUG_OBJECT (self, "Drained");
597 self->draining = FALSE;
598 g_cond_broadcast (&self->drain_cond);
599 } else if (flow_ret == GST_FLOW_OK) {
600 GST_DEBUG_OBJECT (self, "Component signalled EOS");
601 flow_ret = GST_FLOW_EOS;
603 g_mutex_unlock (&self->drain_lock);
604 GST_AUDIO_DECODER_STREAM_LOCK (self);
606 GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
609 self->downstream_flow_ret = flow_ret;
611 if (flow_ret != GST_FLOW_OK)
614 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
620 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
621 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
622 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
623 self->downstream_flow_ret = GST_FLOW_ERROR;
624 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
625 g_mutex_lock (&self->drain_lock);
626 self->draining = FALSE;
627 g_cond_broadcast (&self->drain_cond);
628 g_mutex_unlock (&self->drain_lock);
635 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
637 GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
638 ("Failed to handle format"));
639 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
640 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
641 self->downstream_flow_ret = GST_FLOW_ERROR;
642 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
643 g_mutex_lock (&self->drain_lock);
644 self->draining = FALSE;
645 g_cond_broadcast (&self->drain_cond);
646 g_mutex_unlock (&self->drain_lock);
651 GST_AUDIO_DECODER_ERROR_FROM_ERROR (self, err);
652 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
653 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
654 self->downstream_flow_ret = GST_FLOW_ERROR;
655 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
656 g_mutex_lock (&self->drain_lock);
657 self->draining = FALSE;
658 g_cond_broadcast (&self->drain_cond);
659 g_mutex_unlock (&self->drain_lock);
664 GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
665 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
666 self->downstream_flow_ret = GST_FLOW_FLUSHING;
667 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
673 if (flow_ret == GST_FLOW_EOS) {
674 GST_DEBUG_OBJECT (self, "EOS");
675 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self),
676 gst_event_new_eos ());
677 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
678 } else if (flow_ret < GST_FLOW_EOS) {
679 GST_ELEMENT_FLOW_ERROR (self, flow_ret);
680 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self),
681 gst_event_new_eos ());
682 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
683 } else if (flow_ret == GST_FLOW_FLUSHING) {
684 GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
685 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
687 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
688 g_mutex_lock (&self->drain_lock);
689 self->draining = FALSE;
690 g_cond_broadcast (&self->drain_cond);
691 g_mutex_unlock (&self->drain_lock);
695 failed_to_get_output_buffer:
697 GST_AUDIO_DECODER_ERROR_FROM_ERROR (self, err);
698 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
699 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
700 self->downstream_flow_ret = GST_FLOW_ERROR;
701 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
702 g_mutex_lock (&self->drain_lock);
703 self->draining = FALSE;
704 g_cond_broadcast (&self->drain_cond);
705 g_mutex_unlock (&self->drain_lock);
709 got_null_output_buffer:
711 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
712 ("Got no output buffer"));
713 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
714 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
715 self->downstream_flow_ret = GST_FLOW_ERROR;
716 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
717 g_mutex_lock (&self->drain_lock);
718 self->draining = FALSE;
719 g_cond_broadcast (&self->drain_cond);
720 g_mutex_unlock (&self->drain_lock);
726 GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
727 ("Invalid buffer size %u (bfp %d)", buffer_info.size, self->info.bpf));
728 gst_amc_codec_release_output_buffer (self->codec, idx, FALSE, &err);
729 if (err && !self->flushing)
730 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
731 g_clear_error (&err);
732 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
733 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
734 self->downstream_flow_ret = GST_FLOW_ERROR;
735 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
736 g_mutex_lock (&self->drain_lock);
737 self->draining = FALSE;
738 g_cond_broadcast (&self->drain_cond);
739 g_mutex_unlock (&self->drain_lock);
745 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
746 ("Failed to allocate output buffer"));
747 gst_amc_codec_release_output_buffer (self->codec, idx, FALSE, &err);
748 if (err && !self->flushing)
749 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
750 g_clear_error (&err);
751 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
752 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
753 self->downstream_flow_ret = GST_FLOW_ERROR;
754 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
755 g_mutex_lock (&self->drain_lock);
756 self->draining = FALSE;
757 g_cond_broadcast (&self->drain_cond);
758 g_mutex_unlock (&self->drain_lock);
764 gst_amc_audio_dec_start (GstAudioDecoder * decoder)
766 GstAmcAudioDec *self;
768 self = GST_AMC_AUDIO_DEC (decoder);
769 self->last_upstream_ts = 0;
770 self->drained = TRUE;
771 self->downstream_flow_ret = GST_FLOW_OK;
772 self->started = FALSE;
773 self->flushing = TRUE;
779 gst_amc_audio_dec_stop (GstAudioDecoder * decoder)
781 GstAmcAudioDec *self;
784 self = GST_AMC_AUDIO_DEC (decoder);
785 GST_DEBUG_OBJECT (self, "Stopping decoder");
786 self->flushing = TRUE;
788 gst_amc_codec_flush (self->codec, &err);
790 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
791 gst_amc_codec_stop (self->codec, &err);
793 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
794 self->started = FALSE;
796 gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder));
798 memset (self->positions, 0, sizeof (self->positions));
800 gst_adapter_flush (self->output_adapter,
801 gst_adapter_available (self->output_adapter));
803 g_list_foreach (self->codec_datas, (GFunc) g_free, NULL);
804 g_list_free (self->codec_datas);
805 self->codec_datas = NULL;
807 self->downstream_flow_ret = GST_FLOW_FLUSHING;
808 self->drained = TRUE;
809 g_mutex_lock (&self->drain_lock);
810 self->draining = FALSE;
811 g_cond_broadcast (&self->drain_cond);
812 g_mutex_unlock (&self->drain_lock);
814 GST_DEBUG_OBJECT (self, "Stopped decoder");
819 gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
821 GstAmcAudioDec *self;
823 GstAmcFormat *format;
825 gboolean is_format_change = FALSE;
826 gboolean needs_disable = FALSE;
827 gchar *format_string;
831 self = GST_AMC_AUDIO_DEC (decoder);
833 GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps);
835 /* Check if the caps change is a real format change or if only irrelevant
836 * parts of the caps have changed or nothing at all.
838 is_format_change |= (!self->input_caps
839 || !gst_caps_is_equal (self->input_caps, caps));
841 needs_disable = self->started;
843 /* If the component is not started and a real format change happens
844 * we have to restart the component. If no real format change
845 * happened we can just exit here.
847 if (needs_disable && !is_format_change) {
848 /* Framerate or something minor changed */
849 self->input_caps_changed = TRUE;
850 GST_DEBUG_OBJECT (self,
851 "Already running and caps did not change the format");
855 if (needs_disable && is_format_change) {
856 gst_amc_audio_dec_drain (self);
857 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
858 gst_amc_audio_dec_stop (GST_AUDIO_DECODER (self));
859 GST_AUDIO_DECODER_STREAM_LOCK (self);
860 gst_amc_audio_dec_close (GST_AUDIO_DECODER (self));
861 if (!gst_amc_audio_dec_open (GST_AUDIO_DECODER (self))) {
862 GST_ERROR_OBJECT (self, "Failed to open codec again");
866 if (!gst_amc_audio_dec_start (GST_AUDIO_DECODER (self))) {
867 GST_ERROR_OBJECT (self, "Failed to start codec again");
870 /* srcpad task is not running at this point */
872 mime = caps_to_mime (caps);
874 GST_ERROR_OBJECT (self, "Failed to convert caps to mime");
878 s = gst_caps_get_structure (caps, 0);
879 if (!gst_structure_get_int (s, "rate", &rate) ||
880 !gst_structure_get_int (s, "channels", &channels)) {
881 GST_ERROR_OBJECT (self, "Failed to get rate/channels");
885 format = gst_amc_format_new_audio (mime, rate, channels, &err);
887 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
891 if (gst_structure_has_name (s, "audio/mpeg")) {
893 const gchar *stream_format;
895 if (!gst_structure_get_int (s, "mpegversion", &mpegversion))
897 stream_format = gst_structure_get_string (s, "stream-format");
899 if (mpegversion == 4 && g_strcmp0 (stream_format, "adts") == 0) {
900 gst_amc_format_set_int (format, "is-adts", 1, &err);
902 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
906 /* FIXME: These buffers needs to be valid until the codec is stopped again */
907 g_list_foreach (self->codec_datas, (GFunc) gst_buffer_unref, NULL);
908 g_list_free (self->codec_datas);
909 self->codec_datas = NULL;
910 if (gst_structure_has_field (s, "codec_data")) {
911 const GValue *h = gst_structure_get_value (s, "codec_data");
912 GstBuffer *codec_data = gst_value_get_buffer (h);
916 gst_buffer_map (codec_data, &minfo, GST_MAP_READ);
917 data = g_memdup (minfo.data, minfo.size);
918 self->codec_datas = g_list_prepend (self->codec_datas, data);
919 gst_amc_format_set_buffer (format, "csd-0", data, minfo.size, &err);
921 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
922 gst_buffer_unmap (codec_data, &minfo);
923 } else if (gst_structure_has_field (s, "streamheader")) {
924 const GValue *sh = gst_structure_get_value (s, "streamheader");
925 gint nsheaders = gst_value_array_get_size (sh);
933 for (i = 0, j = 0; i < nsheaders; i++) {
934 h = gst_value_array_get_value (sh, i);
935 buf = gst_value_get_buffer (h);
937 if (strcmp (mime, "audio/vorbis") == 0) {
940 gst_buffer_extract (buf, 0, &header_type, 1);
942 /* Only use the identification and setup packets */
943 if (header_type != 0x01 && header_type != 0x05)
947 fname = g_strdup_printf ("csd-%d", j);
948 gst_buffer_map (buf, &minfo, GST_MAP_READ);
949 data = g_memdup (minfo.data, minfo.size);
950 self->codec_datas = g_list_prepend (self->codec_datas, data);
951 gst_amc_format_set_buffer (format, fname, data, minfo.size, &err);
953 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
954 gst_buffer_unmap (buf, &minfo);
960 format_string = gst_amc_format_to_string (format, &err);
962 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
963 GST_DEBUG_OBJECT (self, "Configuring codec with format: %s",
964 GST_STR_NULL (format_string));
965 g_free (format_string);
967 if (!gst_amc_codec_configure (self->codec, format, NULL, &err)) {
968 GST_ERROR_OBJECT (self, "Failed to configure codec");
969 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
973 gst_amc_format_free (format);
975 if (!gst_amc_codec_start (self->codec, &err)) {
976 GST_ERROR_OBJECT (self, "Failed to start codec");
977 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
982 /* TODO: Implement for other codecs too */
983 if (gst_structure_has_name (s, "audio/mpeg")) {
984 gint mpegversion = -1;
986 gst_structure_get_int (s, "mpegversion", &mpegversion);
987 if (mpegversion == 1) {
988 gint layer = -1, mpegaudioversion = -1;
990 gst_structure_get_int (s, "layer", &layer);
991 gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion);
996 else if (layer == 3 && mpegaudioversion != -1)
997 self->spf = (mpegaudioversion == 1 ? 1152 : 576);
1001 self->started = TRUE;
1002 self->input_caps_changed = TRUE;
1004 /* Start the srcpad loop again */
1005 self->flushing = FALSE;
1006 self->downstream_flow_ret = GST_FLOW_OK;
1007 gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self),
1008 (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL);
1014 gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
1016 GstAmcAudioDec *self;
1019 self = GST_AMC_AUDIO_DEC (decoder);
1021 GST_DEBUG_OBJECT (self, "Resetting decoder");
1023 if (!self->started) {
1024 GST_DEBUG_OBJECT (self, "Codec not started yet");
1028 self->flushing = TRUE;
1029 /* Wait until the srcpad loop is finished,
1030 * unlock GST_AUDIO_DECODER_STREAM_LOCK to prevent deadlocks
1031 * caused by using this lock from inside the loop function */
1032 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1033 GST_PAD_STREAM_LOCK (GST_AUDIO_DECODER_SRC_PAD (self));
1034 GST_PAD_STREAM_UNLOCK (GST_AUDIO_DECODER_SRC_PAD (self));
1035 GST_AUDIO_DECODER_STREAM_LOCK (self);
1036 gst_amc_codec_flush (self->codec, &err);
1038 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
1039 gst_adapter_flush (self->output_adapter,
1040 gst_adapter_available (self->output_adapter));
1041 self->flushing = FALSE;
1043 /* Start the srcpad loop again */
1044 self->last_upstream_ts = 0;
1045 self->drained = TRUE;
1046 self->downstream_flow_ret = GST_FLOW_OK;
1047 gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self),
1048 (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL);
1050 GST_DEBUG_OBJECT (self, "Reset decoder");
1053 static GstFlowReturn
1054 gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
1056 GstAmcAudioDec *self;
1059 GstAmcBufferInfo buffer_info;
1061 GstClockTime timestamp, duration, timestamp_offset = 0;
1065 memset (&minfo, 0, sizeof (minfo));
1067 self = GST_AMC_AUDIO_DEC (decoder);
1069 GST_DEBUG_OBJECT (self, "Handling frame");
1071 /* Make sure to keep a reference to the input here,
1072 * it can be unreffed from the other thread if
1073 * finish_frame() is called */
1075 inbuf = gst_buffer_ref (inbuf);
1077 if (!self->started) {
1078 GST_ERROR_OBJECT (self, "Codec not started yet");
1080 gst_buffer_unref (inbuf);
1081 return GST_FLOW_NOT_NEGOTIATED;
1087 if (self->downstream_flow_ret != GST_FLOW_OK)
1088 goto downstream_error;
1091 return gst_amc_audio_dec_drain (self);
1093 timestamp = GST_BUFFER_PTS (inbuf);
1094 duration = GST_BUFFER_DURATION (inbuf);
1096 gst_buffer_map (inbuf, &minfo, GST_MAP_READ);
1098 while (offset < minfo.size) {
1099 /* Make sure to release the base class stream lock, otherwise
1100 * _loop() can't call _finish_frame() and we might block forever
1101 * because no input buffers are released */
1102 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1103 /* Wait at most 100ms here, some codecs don't fail dequeueing if
1104 * the codec is flushing, causing deadlocks during shutdown */
1105 idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000, &err);
1106 GST_AUDIO_DECODER_STREAM_LOCK (self);
1109 if (self->flushing || self->downstream_flow_ret == GST_FLOW_FLUSHING) {
1110 g_clear_error (&err);
1115 case INFO_TRY_AGAIN_LATER:
1116 GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
1117 continue; /* next try */
1120 GST_ERROR_OBJECT (self, "Failed to dequeue input buffer");
1123 g_assert_not_reached ();
1130 if (self->flushing) {
1131 memset (&buffer_info, 0, sizeof (buffer_info));
1132 gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, NULL);
1136 if (self->downstream_flow_ret != GST_FLOW_OK) {
1137 memset (&buffer_info, 0, sizeof (buffer_info));
1138 gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err);
1139 if (err && !self->flushing)
1140 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
1141 g_clear_error (&err);
1142 goto downstream_error;
1145 /* Now handle the frame */
1147 /* Copy the buffer content in chunks of size as requested
1149 buf = gst_amc_codec_get_input_buffer (self->codec, idx, &err);
1151 goto failed_to_get_input_buffer;
1153 goto got_null_input_buffer;
1155 memset (&buffer_info, 0, sizeof (buffer_info));
1156 buffer_info.offset = 0;
1157 buffer_info.size = MIN (minfo.size - offset, buf->size);
1158 gst_amc_buffer_set_position_and_limit (buf, NULL, buffer_info.offset,
1161 orc_memcpy (buf->data, minfo.data + offset, buffer_info.size);
1163 gst_amc_buffer_free (buf);
1166 /* Interpolate timestamps if we're passing the buffer
1167 * in multiple chunks */
1168 if (offset != 0 && duration != GST_CLOCK_TIME_NONE) {
1169 timestamp_offset = gst_util_uint64_scale (offset, duration, minfo.size);
1172 if (timestamp != GST_CLOCK_TIME_NONE) {
1173 buffer_info.presentation_time_us =
1174 gst_util_uint64_scale (timestamp + timestamp_offset, 1, GST_USECOND);
1175 self->last_upstream_ts = timestamp + timestamp_offset;
1177 if (duration != GST_CLOCK_TIME_NONE)
1178 self->last_upstream_ts += duration;
1181 if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_DELTA_UNIT))
1182 buffer_info.flags |= BUFFER_FLAG_SYNC_FRAME;
1185 offset += buffer_info.size;
1186 GST_DEBUG_OBJECT (self,
1187 "Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x",
1188 idx, buffer_info.size, buffer_info.presentation_time_us,
1190 if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info,
1192 if (self->flushing) {
1193 g_clear_error (&err);
1198 self->drained = FALSE;
1200 gst_buffer_unmap (inbuf, &minfo);
1201 gst_buffer_unref (inbuf);
1203 return self->downstream_flow_ret;
1207 GST_ERROR_OBJECT (self, "Downstream returned %s",
1208 gst_flow_get_name (self->downstream_flow_ret));
1210 gst_buffer_unmap (inbuf, &minfo);
1212 gst_buffer_unref (inbuf);
1213 return self->downstream_flow_ret;
1215 failed_to_get_input_buffer:
1217 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
1219 gst_buffer_unmap (inbuf, &minfo);
1221 gst_buffer_unref (inbuf);
1222 return GST_FLOW_ERROR;
1224 got_null_input_buffer:
1226 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
1227 ("Got no input buffer"));
1229 gst_buffer_unmap (inbuf, &minfo);
1231 gst_buffer_unref (inbuf);
1232 return GST_FLOW_ERROR;
1236 GST_ELEMENT_ERROR_FROM_ERROR (self, err);
1238 gst_buffer_unmap (inbuf, &minfo);
1240 gst_buffer_unref (inbuf);
1241 return GST_FLOW_ERROR;
1245 GST_AUDIO_DECODER_ERROR_FROM_ERROR (self, err);
1247 gst_buffer_unmap (inbuf, &minfo);
1249 gst_buffer_unref (inbuf);
1250 return GST_FLOW_ERROR;
1254 GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING");
1256 gst_buffer_unmap (inbuf, &minfo);
1258 gst_buffer_unref (inbuf);
1259 return GST_FLOW_FLUSHING;
1263 static GstFlowReturn
1264 gst_amc_audio_dec_drain (GstAmcAudioDec * self)
1270 GST_DEBUG_OBJECT (self, "Draining codec");
1271 if (!self->started) {
1272 GST_DEBUG_OBJECT (self, "Codec not started yet");
1276 /* Don't send drain buffer twice, this doesn't work */
1277 if (self->drained) {
1278 GST_DEBUG_OBJECT (self, "Codec is drained already");
1282 /* Make sure to release the base class stream lock, otherwise
1283 * _loop() can't call _finish_frame() and we might block forever
1284 * because no input buffers are released */
1285 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1286 /* Send an EOS buffer to the component and let the base
1287 * class drop the EOS event. We will send it later when
1288 * the EOS buffer arrives on the output port.
1289 * Wait at most 0.5s here. */
1290 idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err);
1291 GST_AUDIO_DECODER_STREAM_LOCK (self);
1295 GstAmcBufferInfo buffer_info;
1297 buf = gst_amc_codec_get_input_buffer (self->codec, idx, &err);
1299 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1300 g_mutex_lock (&self->drain_lock);
1301 self->draining = TRUE;
1303 memset (&buffer_info, 0, sizeof (buffer_info));
1304 buffer_info.size = 0;
1305 buffer_info.presentation_time_us =
1306 gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
1307 buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
1309 gst_amc_buffer_set_position_and_limit (buf, NULL, 0, 0);
1310 gst_amc_buffer_free (buf);
1313 if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info,
1315 GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
1316 g_cond_wait (&self->drain_cond, &self->drain_lock);
1317 GST_DEBUG_OBJECT (self, "Drained codec");
1320 GST_ERROR_OBJECT (self, "Failed to queue input buffer");
1321 if (self->flushing) {
1322 g_clear_error (&err);
1323 ret = GST_FLOW_FLUSHING;
1325 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
1326 ret = GST_FLOW_ERROR;
1330 self->drained = TRUE;
1331 self->draining = FALSE;
1332 g_mutex_unlock (&self->drain_lock);
1333 GST_AUDIO_DECODER_STREAM_LOCK (self);
1335 GST_ERROR_OBJECT (self, "Failed to get buffer for EOS: %d", idx);
1337 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
1338 ret = GST_FLOW_ERROR;
1341 GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
1343 GST_ELEMENT_WARNING_FROM_ERROR (self, err);
1344 ret = GST_FLOW_ERROR;
1347 gst_adapter_flush (self->output_adapter,
1348 gst_adapter_available (self->output_adapter));