diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-10-18 16:41:07 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-10-25 14:05:48 +0200 |
commit | 079c68e4de878390304da28330c149508448fa6e (patch) | |
tree | a455dac4255b3590c194328db68b58d98e469da4 /sys/androidmedia/gstamcaudiodec.c | |
parent | 36680b1190b3ddbe733e526e870ce9e904b129c4 (diff) | |
download | gstreamer-plugins-bad-079c68e4de878390304da28330c149508448fa6e.tar.gz |
androidmedia: Port to 1.0
Diffstat (limited to 'sys/androidmedia/gstamcaudiodec.c')
-rw-r--r-- | sys/androidmedia/gstamcaudiodec.c | 230 |
1 files changed, 130 insertions, 100 deletions
diff --git a/sys/androidmedia/gstamcaudiodec.c b/sys/androidmedia/gstamcaudiodec.c index 31a8bf5f2..886556ae2 100644 --- a/sys/androidmedia/gstamcaudiodec.c +++ b/sys/androidmedia/gstamcaudiodec.c @@ -28,7 +28,7 @@ #endif #include <gst/gst.h> -#include <gst/audio/multichannel.h> +#include <gst/audio/audio.h> #include <string.h> #ifdef HAVE_ORC @@ -69,11 +69,12 @@ enum /* class initialization */ -#define DEBUG_INIT(bla) \ +#define DEBUG_INIT \ GST_DEBUG_CATEGORY_INIT (gst_amc_audio_dec_debug_category, "amcaudiodec", 0, \ "Android MediaCodec audio decoder"); +#define parent_class gst_amc_audio_dec_parent_class -GST_BOILERPLATE_FULL (GstAmcAudioDec, gst_amc_audio_dec, GstAudioDecoder, +G_DEFINE_TYPE_WITH_CODE (GstAmcAudioDec, gst_amc_audio_dec, GST_TYPE_AUDIO_DECODER, DEBUG_INIT); static GstCaps * @@ -95,21 +96,21 @@ create_sink_caps (const GstAmcCodecInfo * codec_info) "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, "parsed", G_TYPE_BOOLEAN, TRUE, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else if (strcmp (type->mime, "audio/3gpp") == 0) { GstStructure *tmp; tmp = gst_structure_new ("audio/AMR", "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else if (strcmp (type->mime, "audio/amr-wb") == 0) { GstStructure *tmp; tmp = gst_structure_new ("audio/AMR-WB", "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else if (strcmp (type->mime, "audio/mp4a-latm") == 0) { gint j; GstStructure *tmp, *tmp2; @@ -147,13 +148,13 @@ create_sink_caps (const GstAmcCodecInfo * codec_info) tmp2 = gst_structure_copy (tmp); gst_structure_set (tmp2, "profile", G_TYPE_STRING, profile, NULL); - gst_caps_merge_structure (ret, tmp2); + ret = gst_caps_merge_structure (ret, tmp2); have_profile = TRUE; } if (!have_profile) { - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else { gst_structure_free (tmp); } @@ -163,21 +164,21 @@ create_sink_caps (const GstAmcCodecInfo * codec_info) tmp = gst_structure_new ("audio/x-alaw", "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else if (strcmp (type->mime, "audio/g711-mlaw") == 0) { GstStructure *tmp; tmp = gst_structure_new ("audio/x-mulaw", "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else if (strcmp (type->mime, "audio/vorbis") == 0) { GstStructure *tmp; tmp = gst_structure_new ("audio/x-vorbis", "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else if (strcmp (type->mime, "audio/flac") == 0) { GstStructure *tmp; @@ -185,7 +186,7 @@ create_sink_caps (const GstAmcCodecInfo * codec_info) "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, "framed", G_TYPE_BOOLEAN, TRUE, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else if (strcmp (type->mime, "audio/mpeg-L2") == 0) { GstStructure *tmp; @@ -195,7 +196,7 @@ create_sink_caps (const GstAmcCodecInfo * codec_info) "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, "parsed", G_TYPE_BOOLEAN, TRUE, NULL); - gst_caps_merge_structure (ret, tmp); + ret = gst_caps_merge_structure (ret, tmp); } else { GST_WARNING ("Unsupported mimetype '%s'", type->mime); } @@ -264,22 +265,38 @@ create_src_caps (const GstAmcCodecInfo * codec_info) } static void -gst_amc_audio_dec_base_init (gpointer g_class) +gst_amc_audio_dec_class_init (GstAmcAudioDecClass * klass) { - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - GstAmcAudioDecClass *audiodec_class = GST_AMC_AUDIO_DEC_CLASS (g_class); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstAudioDecoderClass *audiodec_class = GST_AUDIO_DECODER_CLASS (klass); + GstAmcAudioDecClass *amcaudiodec_class = GST_AMC_AUDIO_DEC_CLASS (klass); const GstAmcCodecInfo *codec_info; GstPadTemplate *templ; GstCaps *caps; gchar *longname; + gobject_class->finalize = gst_amc_audio_dec_finalize; + + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_amc_audio_dec_change_state); + + audiodec_class->start = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_start); + audiodec_class->stop = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_stop); + audiodec_class->open = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_open); + audiodec_class->close = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_close); + audiodec_class->flush = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_flush); + audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_set_format); + audiodec_class->handle_frame = + GST_DEBUG_FUNCPTR (gst_amc_audio_dec_handle_frame); + codec_info = - g_type_get_qdata (G_TYPE_FROM_CLASS (g_class), gst_amc_codec_info_quark); + g_type_get_qdata (G_TYPE_FROM_CLASS (klass), gst_amc_codec_info_quark); /* This happens for the base class and abstract subclasses */ if (!codec_info) return; - audiodec_class->codec_info = codec_info; + amcaudiodec_class->codec_info = codec_info; /* Add pad templates */ caps = create_sink_caps (codec_info); @@ -293,7 +310,7 @@ gst_amc_audio_dec_base_init (gpointer g_class) gst_object_unref (templ); longname = g_strdup_printf ("Android MediaCodec %s", codec_info->name); - gst_element_class_set_details_simple (element_class, + gst_element_class_set_metadata (element_class, codec_info->name, "Codec/Decoder/Audio", longname, "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); @@ -301,31 +318,7 @@ gst_amc_audio_dec_base_init (gpointer g_class) } static void -gst_amc_audio_dec_class_init (GstAmcAudioDecClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstAudioDecoderClass *audiodec_class = GST_AUDIO_DECODER_CLASS (klass); - - gobject_class->finalize = gst_amc_audio_dec_finalize; - - element_class->change_state = - GST_DEBUG_FUNCPTR (gst_amc_audio_dec_change_state); - - audiodec_class->start = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_start); - audiodec_class->stop = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_stop); -#if 0 - audiodec_class->open = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_open); - audiodec_class->close = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_close); -#endif - audiodec_class->flush = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_flush); - audiodec_class->set_format = GST_DEBUG_FUNCPTR (gst_amc_audio_dec_set_format); - audiodec_class->handle_frame = - GST_DEBUG_FUNCPTR (gst_amc_audio_dec_handle_frame); -} - -static void -gst_amc_audio_dec_init (GstAmcAudioDec * self, GstAmcAudioDecClass * klass) +gst_amc_audio_dec_init (GstAmcAudioDec * self) { gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (self), TRUE); gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (self), TRUE); @@ -400,8 +393,6 @@ gst_amc_audio_dec_change_state (GstElement * element, GstStateChange transition) self->downstream_flow_ret = GST_FLOW_OK; self->draining = FALSE; self->started = FALSE; - if (!gst_amc_audio_dec_open (GST_AUDIO_DECODER (self))) - return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; @@ -429,9 +420,7 @@ gst_amc_audio_dec_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_READY: - if (!gst_amc_audio_dec_close (GST_AUDIO_DECODER (self))) - return GST_STATE_CHANGE_FAILURE; - self->downstream_flow_ret = GST_FLOW_WRONG_STATE; + self->downstream_flow_ret = GST_FLOW_FLUSHING; self->started = FALSE; break; case GST_STATE_CHANGE_READY_TO_NULL: @@ -449,6 +438,7 @@ gst_amc_audio_dec_set_src_caps (GstAmcAudioDec * self, GstAmcFormat * format) GstCaps *caps; gint rate, channels; guint32 channel_mask = 0; + GstAudioChannelPosition to[64]; if (!gst_amc_format_get_int (format, "sample-rate", &rate) || !gst_amc_format_get_int (format, "channel-count", &channels)) { @@ -465,26 +455,23 @@ gst_amc_audio_dec_set_src_caps (GstAmcAudioDec * self, GstAmcFormat * format) if (gst_amc_format_contains_key (format, "channel-mask")) gst_amc_format_get_int (format, "channel-mask", (gint *) & channel_mask); - if (self->positions) - g_free (self->positions); - self->positions = - gst_amc_audio_channel_mask_to_positions (channel_mask, channels); + gst_amc_audio_channel_mask_to_positions (channel_mask, channels, + self->positions); + memcpy (to, self->positions, sizeof (to)); + gst_audio_channel_positions_to_valid_order (to, channels); + self->needs_reorder = + (memcmp (self->positions, to, + sizeof (GstAudioChannelPosition) * channels) != 0); + if (self->needs_reorder) + gst_audio_get_channel_reorder_map (channels, self->positions, to, + self->reorder_map); + gst_audio_info_init (&self->info); + gst_audio_info_set_format (&self->info, GST_AUDIO_FORMAT_S16, rate, channels, + to); - caps = gst_caps_new_simple ("audio/x-raw-int", - "rate", G_TYPE_INT, rate, - "channels", G_TYPE_INT, channels, - "width", G_TYPE_INT, 16, - "depth", G_TYPE_INT, 16, - "signed", G_TYPE_BOOLEAN, TRUE, - "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL); + caps = gst_audio_info_to_caps (&self->info); - if (self->positions) - gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), - self->positions); - - self->channels = channels; - self->rate = rate; gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (self), caps); gst_caps_unref (caps); @@ -592,6 +579,7 @@ retry: GstAmcAudioDecClass *klass = GST_AMC_AUDIO_DEC_GET_CLASS (self); GstBuffer *outbuf; GstAmcBuffer *buf; + GstMapInfo minfo; /* This sometimes happens at EOS or if the input is not properly framed, * let's handle it gracefully by allocating a new buffer for the current @@ -610,13 +598,33 @@ retry: } } - outbuf = gst_buffer_try_new_and_alloc (buffer_info.size); + outbuf = + gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (self), + buffer_info.size); if (!outbuf) goto failed_allocate; + gst_buffer_map (outbuf, &minfo, GST_MAP_WRITE); buf = &self->output_buffers[idx]; - orc_memcpy (GST_BUFFER_DATA (outbuf), buf->data + buffer_info.offset, - buffer_info.size); + if (self->needs_reorder) { + gint i, n_samples, c, n_channels; + gint *reorder_map = self->reorder_map; + gint16 *dest, *source; + + dest = (gint16 *) minfo.data; + source = (gint16 *) (buf->data + buffer_info.offset); + n_samples = buffer_info.size / self->info.bpf; + n_channels = self->info.channels; + + for (i = 0; i < n_samples; i++) { + for (c = 0; c < n_channels; c++) { + dest[i * n_channels + reorder_map[c]] = source[i * n_channels + c]; + } + } + } else { + orc_memcpy (minfo.data, buf->data + buffer_info.offset, buffer_info.size); + } + gst_buffer_unmap (outbuf, &minfo); /* FIXME: We should get one decoded input frame here for * every buffer. If this is not the case somewhere, we will @@ -630,7 +638,7 @@ done: if (!gst_amc_codec_release_output_buffer (self->codec, idx)) goto failed_release; - if (is_eos || flow_ret == GST_FLOW_UNEXPECTED) { + if (is_eos || flow_ret == GST_FLOW_EOS) { GST_AUDIO_DECODER_STREAM_UNLOCK (self); g_mutex_lock (self->drain_lock); if (self->draining) { @@ -639,7 +647,7 @@ done: g_cond_broadcast (self->drain_cond); } else if (flow_ret == GST_FLOW_OK) { GST_DEBUG_OBJECT (self, "Component signalled EOS"); - flow_ret = GST_FLOW_UNEXPECTED; + flow_ret = GST_FLOW_EOS; } g_mutex_unlock (self->drain_lock); GST_AUDIO_DECODER_STREAM_LOCK (self); @@ -702,20 +710,19 @@ flushing: { GST_DEBUG_OBJECT (self, "Flushing -- stopping task"); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); - self->downstream_flow_ret = GST_FLOW_WRONG_STATE; + self->downstream_flow_ret = GST_FLOW_FLUSHING; GST_AUDIO_DECODER_STREAM_UNLOCK (self); return; } flow_error: { - if (flow_ret == GST_FLOW_UNEXPECTED) { + if (flow_ret == GST_FLOW_EOS) { GST_DEBUG_OBJECT (self, "EOS"); gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self)); - } else - if (flow_ret == GST_FLOW_NOT_LINKED || flow_ret < GST_FLOW_UNEXPECTED) { + } else if (flow_ret == GST_FLOW_NOT_LINKED || flow_ret < GST_FLOW_EOS) { GST_ELEMENT_ERROR (self, STREAM, FAILED, ("Internal data stream error."), ("stream stopped, reason %s", gst_flow_get_name (flow_ret))); @@ -786,20 +793,19 @@ gst_amc_audio_dec_stop (GstAudioDecoder * decoder) } gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder)); - g_free (self->positions); - self->positions = NULL; + memset (self->positions, 0, sizeof (self->positions)); - g_list_foreach (self->codec_datas, (GFunc) gst_buffer_unref, NULL); + g_list_foreach (self->codec_datas, (GFunc) g_free, NULL); g_list_free (self->codec_datas); self->codec_datas = NULL; - self->downstream_flow_ret = GST_FLOW_WRONG_STATE; + self->downstream_flow_ret = GST_FLOW_FLUSHING; self->eos = FALSE; g_mutex_lock (self->drain_lock); self->draining = FALSE; g_cond_broadcast (self->drain_cond); g_mutex_unlock (self->drain_lock); - gst_buffer_replace (&self->codec_data, NULL); + GST_DEBUG_OBJECT (self, "Stopped decoder"); return TRUE; } @@ -883,10 +889,14 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) if (gst_structure_has_field (s, "codec_data")) { const GValue *h = gst_structure_get_value (s, "codec_data"); GstBuffer *codec_data = gst_value_get_buffer (h); - - self->codec_datas = - g_list_prepend (self->codec_datas, gst_buffer_ref (codec_data)); - gst_amc_format_set_buffer (format, "csd-0", codec_data); + GstMapInfo minfo; + guint8 *data; + + gst_buffer_map (codec_data, &minfo, GST_MAP_READ); + data = g_memdup (minfo.data, minfo.size); + self->codec_datas = g_list_prepend (self->codec_datas, data); + gst_amc_format_set_buffer (format, "csd-0", data, minfo.size); + gst_buffer_unmap (codec_data, &minfo); } else if (gst_structure_has_field (s, "streamheader")) { const GValue *sh = gst_structure_get_value (s, "streamheader"); gint nsheaders = gst_value_array_get_size (sh); @@ -894,13 +904,17 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) const GValue *h; gint i, j; gchar *fname; + GstMapInfo minfo; + guint8 *data; for (i = 0, j = 0; i < nsheaders; i++) { h = gst_value_array_get_value (sh, i); buf = gst_value_get_buffer (h); if (strcmp (mime, "audio/vorbis") == 0) { - guint8 header_type = GST_BUFFER_DATA (buf)[0]; + guint8 header_type; + + gst_buffer_extract (buf, 0, &header_type, 1); /* Only use the identification and setup packets */ if (header_type != 0x01 && header_type != 0x05) @@ -908,9 +922,11 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) } fname = g_strdup_printf ("csd-%d", j); - self->codec_datas = - g_list_prepend (self->codec_datas, gst_buffer_ref (buf)); - gst_amc_format_set_buffer (format, fname, buf); + gst_buffer_map (buf, &minfo, GST_MAP_READ); + data = g_memdup (minfo.data, minfo.size); + self->codec_datas = g_list_prepend (self->codec_datas, data); + gst_amc_format_set_buffer (format, fname, data, minfo.size); + gst_buffer_unmap (buf, &minfo); g_free (fname); j++; } @@ -949,7 +965,7 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) self->flushing = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_audio_dec_loop, decoder); + (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); return TRUE; } @@ -985,7 +1001,7 @@ gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) self->eos = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), - (GstTaskFunction) gst_amc_audio_dec_loop, decoder); + (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); GST_DEBUG_OBJECT (self, "Reset decoder"); } @@ -999,6 +1015,9 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) GstAmcBufferInfo buffer_info; guint offset = 0; GstClockTime timestamp, duration, timestamp_offset = 0; + GstMapInfo minfo; + + memset (&minfo, 0, sizeof (minfo)); self = GST_AMC_AUDIO_DEC (decoder); @@ -1021,7 +1040,7 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) GST_WARNING_OBJECT (self, "Got frame after EOS"); if (inbuf) gst_buffer_unref (inbuf); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } if (self->flushing) @@ -1033,10 +1052,12 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) if (!inbuf) return gst_amc_audio_dec_drain (self); - timestamp = GST_BUFFER_TIMESTAMP (inbuf); + timestamp = GST_BUFFER_PTS (inbuf); duration = GST_BUFFER_DURATION (inbuf); - while (offset < GST_BUFFER_SIZE (inbuf)) { + gst_buffer_map (inbuf, &minfo, GST_MAP_READ); + + while (offset < minfo.size) { /* Make sure to release the base class stream lock, otherwise * _loop() can't call _finish_frame() and we might block forever * because no input buffers are released */ @@ -1085,15 +1106,14 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) memset (&buffer_info, 0, sizeof (buffer_info)); buffer_info.offset = 0; - buffer_info.size = MIN (GST_BUFFER_SIZE (inbuf) - offset, buf->size); + buffer_info.size = MIN (minfo.size - offset, buf->size); - orc_memcpy (buf->data, GST_BUFFER_DATA (inbuf) + offset, buffer_info.size); + orc_memcpy (buf->data, minfo.data + offset, buffer_info.size); /* Interpolate timestamps if we're passing the buffer * in multiple chunks */ if (offset != 0 && duration != GST_CLOCK_TIME_NONE) { - timestamp_offset = - gst_util_uint64_scale (offset, duration, GST_BUFFER_SIZE (inbuf)); + timestamp_offset = gst_util_uint64_scale (offset, duration, minfo.size); } if (timestamp != GST_CLOCK_TIME_NONE) { @@ -1117,7 +1137,7 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf) if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) goto queue_error; } - + gst_buffer_unmap (inbuf, &minfo); gst_buffer_unref (inbuf); return self->downstream_flow_ret; @@ -1126,6 +1146,8 @@ downstream_error: { GST_ERROR_OBJECT (self, "Downstream returned %s", gst_flow_get_name (self->downstream_flow_ret)); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); if (inbuf) gst_buffer_unref (inbuf); return self->downstream_flow_ret; @@ -1134,6 +1156,8 @@ invalid_buffer_index: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Invalid input buffer index %d of %d", idx, self->n_input_buffers)); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); if (inbuf) gst_buffer_unref (inbuf); return GST_FLOW_ERROR; @@ -1142,6 +1166,8 @@ dequeue_error: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Failed to dequeue input buffer")); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); if (inbuf) gst_buffer_unref (inbuf); return GST_FLOW_ERROR; @@ -1150,16 +1176,20 @@ queue_error: { GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), ("Failed to queue input buffer")); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); if (inbuf) gst_buffer_unref (inbuf); return GST_FLOW_ERROR; } flushing: { - GST_DEBUG_OBJECT (self, "Flushing -- returning WRONG_STATE"); + GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING"); + if (minfo.data) + gst_buffer_unmap (inbuf, &minfo); if (inbuf) gst_buffer_unref (inbuf); - return GST_FLOW_WRONG_STATE; + return GST_FLOW_FLUSHING; } } |