2 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
3 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
4 * Copyright (C) 2013, Collabora Ltd.
5 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
6 * Copyright (C) 2014, Sebastian Dröge <sebastian@centricular.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "gstomxaudiodec.h"
34 GST_DEBUG_CATEGORY_STATIC (gst_omx_audio_dec_debug_category);
35 #define GST_CAT_DEFAULT gst_omx_audio_dec_debug_category
38 static void gst_omx_audio_dec_finalize (GObject * object);
40 static GstStateChangeReturn
41 gst_omx_audio_dec_change_state (GstElement * element,
42 GstStateChange transition);
44 static gboolean gst_omx_audio_dec_open (GstAudioDecoder * decoder);
45 static gboolean gst_omx_audio_dec_close (GstAudioDecoder * decoder);
46 static gboolean gst_omx_audio_dec_start (GstAudioDecoder * decoder);
47 static gboolean gst_omx_audio_dec_stop (GstAudioDecoder * decoder);
48 static gboolean gst_omx_audio_dec_set_format (GstAudioDecoder * decoder,
50 static void gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard);
51 static GstFlowReturn gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder,
53 static GstFlowReturn gst_omx_audio_dec_drain (GstOMXAudioDec * self);
60 /* class initialization */
63 GST_DEBUG_CATEGORY_INIT (gst_omx_audio_dec_debug_category, "omxaudiodec", 0, \
64 "debug category for gst-omx audio decoder base class");
67 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstOMXAudioDec, gst_omx_audio_dec,
68 GST_TYPE_AUDIO_DECODER, DEBUG_INIT);
71 gst_omx_audio_dec_class_init (GstOMXAudioDecClass * klass)
73 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
74 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
75 GstAudioDecoderClass *audio_decoder_class = GST_AUDIO_DECODER_CLASS (klass);
77 gobject_class->finalize = gst_omx_audio_dec_finalize;
79 element_class->change_state =
80 GST_DEBUG_FUNCPTR (gst_omx_audio_dec_change_state);
82 audio_decoder_class->open = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_open);
83 audio_decoder_class->close = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_close);
84 audio_decoder_class->start = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_start);
85 audio_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_stop);
86 audio_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_omx_audio_dec_flush);
87 audio_decoder_class->set_format =
88 GST_DEBUG_FUNCPTR (gst_omx_audio_dec_set_format);
89 audio_decoder_class->handle_frame =
90 GST_DEBUG_FUNCPTR (gst_omx_audio_dec_handle_frame);
92 klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER;
93 klass->cdata.default_src_template_caps =
95 "rate = (int) [ 1, MAX ], "
96 "channels = (int) [ 1, " G_STRINGIFY (OMX_AUDIO_MAXCHANNELS) " ], "
97 "format = (string) " GST_AUDIO_FORMATS_ALL;
101 gst_omx_audio_dec_init (GstOMXAudioDec * self)
103 gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (self), TRUE);
104 gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (self), TRUE);
105 gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
107 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (self));
109 g_mutex_init (&self->drain_lock);
110 g_cond_init (&self->drain_cond);
112 self->output_adapter = gst_adapter_new ();
116 gst_omx_audio_dec_open (GstAudioDecoder * decoder)
118 GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder);
119 GstOMXAudioDecClass *klass = GST_OMX_AUDIO_DEC_GET_CLASS (self);
120 gint in_port_index, out_port_index;
122 GST_DEBUG_OBJECT (self, "Opening decoder");
125 gst_omx_component_new (GST_OBJECT_CAST (self), klass->cdata.core_name,
126 klass->cdata.component_name, klass->cdata.component_role,
128 self->started = FALSE;
133 if (gst_omx_component_get_state (self->dec,
134 GST_CLOCK_TIME_NONE) != OMX_StateLoaded)
137 in_port_index = klass->cdata.in_port_index;
138 out_port_index = klass->cdata.out_port_index;
140 if (in_port_index == -1 || out_port_index == -1) {
141 OMX_PORT_PARAM_TYPE param;
144 GST_OMX_INIT_STRUCT (¶m);
147 gst_omx_component_get_parameter (self->dec, OMX_IndexParamAudioInit,
149 if (err != OMX_ErrorNone) {
150 GST_WARNING_OBJECT (self, "Couldn't get port information: %s (0x%08x)",
151 gst_omx_error_to_string (err), err);
156 GST_DEBUG_OBJECT (self, "Detected %u ports, starting at %u",
157 (guint) param.nPorts, (guint) param.nStartPortNumber);
158 in_port_index = param.nStartPortNumber + 0;
159 out_port_index = param.nStartPortNumber + 1;
162 self->dec_in_port = gst_omx_component_add_port (self->dec, in_port_index);
163 self->dec_out_port = gst_omx_component_add_port (self->dec, out_port_index);
165 if (!self->dec_in_port || !self->dec_out_port)
168 GST_DEBUG_OBJECT (self, "Opened decoder");
174 gst_omx_audio_dec_shutdown (GstOMXAudioDec * self)
178 GST_DEBUG_OBJECT (self, "Shutting down decoder");
180 state = gst_omx_component_get_state (self->dec, 0);
181 if (state > OMX_StateLoaded || state == OMX_StateInvalid) {
182 if (state > OMX_StateIdle) {
183 gst_omx_component_set_state (self->dec, OMX_StateIdle);
184 gst_omx_component_get_state (self->dec, 5 * GST_SECOND);
186 gst_omx_component_set_state (self->dec, OMX_StateLoaded);
187 gst_omx_port_deallocate_buffers (self->dec_in_port);
188 gst_omx_port_deallocate_buffers (self->dec_out_port);
189 if (state > OMX_StateLoaded)
190 gst_omx_component_get_state (self->dec, 5 * GST_SECOND);
197 gst_omx_audio_dec_close (GstAudioDecoder * decoder)
199 GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder);
201 GST_DEBUG_OBJECT (self, "Closing decoder");
203 if (!gst_omx_audio_dec_shutdown (self))
206 self->dec_in_port = NULL;
207 self->dec_out_port = NULL;
209 gst_omx_component_unref (self->dec);
212 self->started = FALSE;
214 GST_DEBUG_OBJECT (self, "Closed decoder");
220 gst_omx_audio_dec_finalize (GObject * object)
222 GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (object);
224 g_mutex_clear (&self->drain_lock);
225 g_cond_clear (&self->drain_cond);
227 if (self->output_adapter)
228 gst_object_unref (self->output_adapter);
229 self->output_adapter = NULL;
231 G_OBJECT_CLASS (gst_omx_audio_dec_parent_class)->finalize (object);
234 static GstStateChangeReturn
235 gst_omx_audio_dec_change_state (GstElement * element, GstStateChange transition)
237 GstOMXAudioDec *self;
238 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
240 g_return_val_if_fail (GST_IS_OMX_AUDIO_DEC (element),
241 GST_STATE_CHANGE_FAILURE);
242 self = GST_OMX_AUDIO_DEC (element);
244 switch (transition) {
245 case GST_STATE_CHANGE_NULL_TO_READY:
247 case GST_STATE_CHANGE_READY_TO_PAUSED:
248 self->downstream_flow_ret = GST_FLOW_OK;
249 self->draining = FALSE;
250 self->started = FALSE;
252 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
254 case GST_STATE_CHANGE_PAUSED_TO_READY:
255 if (self->dec_in_port)
256 gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE);
257 if (self->dec_out_port)
258 gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE);
260 g_mutex_lock (&self->drain_lock);
261 self->draining = FALSE;
262 g_cond_broadcast (&self->drain_cond);
263 g_mutex_unlock (&self->drain_lock);
270 GST_ELEMENT_CLASS (gst_omx_audio_dec_parent_class)->change_state
271 (element, transition);
273 if (ret == GST_STATE_CHANGE_FAILURE)
276 switch (transition) {
277 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
279 case GST_STATE_CHANGE_PAUSED_TO_READY:
280 self->downstream_flow_ret = GST_FLOW_FLUSHING;
281 self->started = FALSE;
283 if (!gst_omx_audio_dec_shutdown (self))
284 ret = GST_STATE_CHANGE_FAILURE;
286 case GST_STATE_CHANGE_READY_TO_NULL:
296 gst_omx_audio_dec_loop (GstOMXAudioDec * self)
298 GstOMXAudioDecClass *klass = GST_OMX_AUDIO_DEC_GET_CLASS (self);
299 GstOMXPort *port = self->dec_out_port;
300 GstOMXBuffer *buf = NULL;
301 GstFlowReturn flow_ret = GST_FLOW_OK;
302 GstOMXAcquireBufferReturn acq_return;
306 acq_return = gst_omx_port_acquire_buffer (port, &buf, GST_OMX_WAIT);
307 if (acq_return == GST_OMX_ACQUIRE_BUFFER_ERROR) {
308 goto component_error;
309 } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
311 } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) {
315 if (!gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (self)) ||
316 acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
317 OMX_PARAM_PORTDEFINITIONTYPE port_def;
318 OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
319 GstAudioChannelPosition omx_position[OMX_AUDIO_MAXCHANNELS];
320 GstOMXAudioDecClass *klass = GST_OMX_AUDIO_DEC_GET_CLASS (self);
323 GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps");
325 /* Reallocate all buffers */
326 if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE
327 && gst_omx_port_is_enabled (port)) {
328 err = gst_omx_port_set_enabled (port, FALSE);
329 if (err != OMX_ErrorNone)
330 goto reconfigure_error;
332 err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
333 if (err != OMX_ErrorNone)
334 goto reconfigure_error;
336 err = gst_omx_port_deallocate_buffers (port);
337 if (err != OMX_ErrorNone)
338 goto reconfigure_error;
340 err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
341 if (err != OMX_ErrorNone)
342 goto reconfigure_error;
345 /* Just update caps */
346 GST_AUDIO_DECODER_STREAM_LOCK (self);
348 gst_omx_port_get_port_definition (port, &port_def);
349 g_assert (port_def.format.audio.eEncoding == OMX_AUDIO_CodingPCM);
351 GST_OMX_INIT_STRUCT (&pcm_param);
352 pcm_param.nPortIndex = self->dec_out_port->index;
354 gst_omx_component_get_parameter (self->dec, OMX_IndexParamAudioPcm,
356 if (err != OMX_ErrorNone) {
357 GST_ERROR_OBJECT (self, "Failed to get PCM parameters: %s (0x%08x)",
358 gst_omx_error_to_string (err), err);
362 g_assert (pcm_param.ePCMMode == OMX_AUDIO_PCMModeLinear);
363 g_assert (pcm_param.bInterleaved == OMX_TRUE);
365 gst_audio_info_init (&self->info);
367 for (i = 0; i < pcm_param.nChannels; i++) {
368 switch (pcm_param.eChannelMapping[i]) {
369 case OMX_AUDIO_ChannelLF:
370 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
372 case OMX_AUDIO_ChannelRF:
373 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
375 case OMX_AUDIO_ChannelCF:
376 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
378 case OMX_AUDIO_ChannelLS:
379 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
381 case OMX_AUDIO_ChannelRS:
382 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
384 case OMX_AUDIO_ChannelLFE:
385 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_LFE1;
387 case OMX_AUDIO_ChannelCS:
388 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
390 case OMX_AUDIO_ChannelLR:
391 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
393 case OMX_AUDIO_ChannelRR:
394 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
396 case OMX_AUDIO_ChannelNone:
398 /* This will break the outer loop too as the
399 * i == pcm_param.nChannels afterwards */
400 for (i = 0; i < pcm_param.nChannels; i++)
401 omx_position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
405 if (pcm_param.nChannels == 1
406 && omx_position[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER)
407 omx_position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
409 if (omx_position[0] == GST_AUDIO_CHANNEL_POSITION_NONE
410 && klass->get_channel_positions) {
411 GST_WARNING_OBJECT (self,
412 "Failed to get a valid channel layout, trying fallback");
413 klass->get_channel_positions (self, self->dec_out_port, omx_position);
416 memcpy (self->position, omx_position, sizeof (omx_position));
417 gst_audio_channel_positions_to_valid_order (self->position,
418 pcm_param.nChannels);
419 self->needs_reorder =
420 (memcmp (self->position, omx_position,
421 sizeof (GstAudioChannelPosition) * pcm_param.nChannels) != 0);
422 if (self->needs_reorder)
423 gst_audio_get_channel_reorder_map (pcm_param.nChannels, self->position,
424 omx_position, self->reorder_map);
426 gst_audio_info_set_format (&self->info,
427 gst_audio_format_build_integer (pcm_param.eNumData ==
428 OMX_NumericalDataSigned,
430 OMX_EndianLittle ? G_LITTLE_ENDIAN : G_BIG_ENDIAN,
431 pcm_param.nBitPerSample, pcm_param.nBitPerSample),
432 pcm_param.nSamplingRate, pcm_param.nChannels, self->position);
434 GST_DEBUG_OBJECT (self,
435 "Setting output state: format %s, rate %u, channels %u",
436 gst_audio_format_to_string (self->info.finfo->format),
437 (guint) pcm_param.nSamplingRate, (guint) pcm_param.nChannels);
439 if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (self),
441 || !gst_audio_decoder_negotiate (GST_AUDIO_DECODER (self))) {
443 gst_omx_port_release_buffer (port, buf);
447 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
449 if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
450 err = gst_omx_port_set_enabled (port, TRUE);
451 if (err != OMX_ErrorNone)
452 goto reconfigure_error;
454 err = gst_omx_port_allocate_buffers (port);
455 if (err != OMX_ErrorNone)
456 goto reconfigure_error;
458 err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
459 if (err != OMX_ErrorNone)
460 goto reconfigure_error;
462 err = gst_omx_port_populate (port);
463 if (err != OMX_ErrorNone)
464 goto reconfigure_error;
466 err = gst_omx_port_mark_reconfigured (port);
467 if (err != OMX_ErrorNone)
468 goto reconfigure_error;
471 /* Now get a buffer */
472 if (acq_return != GST_OMX_ACQUIRE_BUFFER_OK) {
477 g_assert (acq_return == GST_OMX_ACQUIRE_BUFFER_OK);
479 g_assert ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER));
480 GST_AUDIO_DECODER_STREAM_LOCK (self);
484 /* This prevents a deadlock between the srcpad stream
485 * lock and the audiocodec stream lock, if ::reset()
486 * is called at the wrong time
488 if (gst_omx_port_is_flushing (port)) {
489 GST_DEBUG_OBJECT (self, "Flushing");
490 gst_omx_port_release_buffer (port, buf);
494 GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %" G_GUINT64_FORMAT,
495 (guint) buf->omx_buf->nFlags,
496 (guint64) GST_OMX_GET_TICKS (buf->omx_buf->nTimeStamp));
498 GST_AUDIO_DECODER_STREAM_LOCK (self);
500 spf = klass->get_samples_per_frame (self, self->dec_out_port);
502 if (buf->omx_buf->nFilledLen > 0) {
506 GST_DEBUG_OBJECT (self, "Handling output data");
508 if (buf->omx_buf->nFilledLen % self->info.bpf != 0) {
509 gst_omx_port_release_buffer (port, buf);
514 gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (self),
515 buf->omx_buf->nFilledLen);
517 gst_buffer_map (outbuf, &minfo, GST_MAP_WRITE);
518 if (self->needs_reorder) {
519 gint i, n_samples, c, n_channels;
520 gint *reorder_map = self->reorder_map;
521 gint16 *dest, *source;
523 dest = (gint16 *) minfo.data;
524 source = (gint16 *) (buf->omx_buf->pBuffer + buf->omx_buf->nOffset);
525 n_samples = buf->omx_buf->nFilledLen / self->info.bpf;
526 n_channels = self->info.channels;
528 for (i = 0; i < n_samples; i++) {
529 for (c = 0; c < n_channels; c++) {
530 dest[i * n_channels + reorder_map[c]] = source[i * n_channels + c];
534 memcpy (minfo.data, buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
535 buf->omx_buf->nFilledLen);
537 gst_buffer_unmap (outbuf, &minfo);
540 gst_adapter_push (self->output_adapter, outbuf);
543 gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1);
547 GST_DEBUG_OBJECT (self, "Read frame from component");
551 guint avail = gst_adapter_available (self->output_adapter);
554 /* We take a multiple of codec frames and push
557 avail /= self->info.bpf;
558 nframes = avail / spf;
559 avail = nframes * spf;
560 avail *= self->info.bpf;
563 outbuf = gst_adapter_take_buffer (self->output_adapter, avail);
565 gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf,
570 GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
573 err = gst_omx_port_release_buffer (port, buf);
574 if (err != OMX_ErrorNone)
578 self->downstream_flow_ret = flow_ret;
580 if (flow_ret != GST_FLOW_OK)
583 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
589 GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
590 ("OpenMAX component in error state %s (0x%08x)",
591 gst_omx_component_get_last_error_string (self->dec),
592 gst_omx_component_get_last_error (self->dec)));
593 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
594 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
595 self->downstream_flow_ret = GST_FLOW_ERROR;
596 self->started = FALSE;
602 GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
603 g_mutex_lock (&self->drain_lock);
604 if (self->draining) {
605 self->draining = FALSE;
606 g_cond_broadcast (&self->drain_cond);
608 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
609 self->downstream_flow_ret = GST_FLOW_FLUSHING;
610 self->started = FALSE;
611 g_mutex_unlock (&self->drain_lock);
617 spf = klass->get_samples_per_frame (self, self->dec_out_port);
620 guint avail = gst_adapter_available (self->output_adapter);
623 /* On EOS we take the complete adapter content, no matter
624 * if it is a multiple of the codec frame size or not.
626 avail /= self->info.bpf;
627 nframes = (avail + spf - 1) / spf;
628 avail *= self->info.bpf;
631 outbuf = gst_adapter_take_buffer (self->output_adapter, avail);
633 gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf,
638 g_mutex_lock (&self->drain_lock);
639 if (self->draining) {
640 GST_DEBUG_OBJECT (self, "Drained");
641 self->draining = FALSE;
642 g_cond_broadcast (&self->drain_cond);
643 flow_ret = GST_FLOW_OK;
644 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
646 GST_DEBUG_OBJECT (self, "Component signalled EOS");
647 flow_ret = GST_FLOW_EOS;
649 g_mutex_unlock (&self->drain_lock);
651 GST_AUDIO_DECODER_STREAM_LOCK (self);
652 self->downstream_flow_ret = flow_ret;
654 /* Here we fallback and pause the task for the EOS case */
655 if (flow_ret != GST_FLOW_OK)
658 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
665 if (flow_ret == GST_FLOW_EOS) {
666 GST_DEBUG_OBJECT (self, "EOS");
668 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self),
669 gst_event_new_eos ());
670 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
671 self->started = FALSE;
672 } else if (flow_ret < GST_FLOW_EOS) {
673 GST_ELEMENT_ERROR (self, STREAM, FAILED,
674 ("Internal data stream error."), ("stream stopped, reason %s",
675 gst_flow_get_name (flow_ret)));
677 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self),
678 gst_event_new_eos ());
679 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
680 self->started = FALSE;
681 } else if (flow_ret == GST_FLOW_FLUSHING) {
682 GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
683 g_mutex_lock (&self->drain_lock);
684 if (self->draining) {
685 self->draining = FALSE;
686 g_cond_broadcast (&self->drain_cond);
688 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
689 self->started = FALSE;
690 g_mutex_unlock (&self->drain_lock);
692 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
698 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
699 ("Unable to reconfigure output port"));
700 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
701 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
702 self->downstream_flow_ret = GST_FLOW_ERROR;
703 self->started = FALSE;
709 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
710 ("Invalid sized input buffer"));
711 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
712 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
713 self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
714 self->started = FALSE;
715 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
721 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), ("Failed to set caps"));
722 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
723 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
724 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
725 self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
726 self->started = FALSE;
731 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
732 ("Failed to relase output buffer to component: %s (0x%08x)",
733 gst_omx_error_to_string (err), err));
734 gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
735 gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
736 self->downstream_flow_ret = GST_FLOW_ERROR;
737 self->started = FALSE;
738 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
744 gst_omx_audio_dec_start (GstAudioDecoder * decoder)
746 GstOMXAudioDec *self;
748 self = GST_OMX_AUDIO_DEC (decoder);
750 self->last_upstream_ts = 0;
751 self->downstream_flow_ret = GST_FLOW_OK;
757 gst_omx_audio_dec_stop (GstAudioDecoder * decoder)
759 GstOMXAudioDec *self;
761 self = GST_OMX_AUDIO_DEC (decoder);
763 GST_DEBUG_OBJECT (self, "Stopping decoder");
765 gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE);
766 gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE);
768 gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder));
770 if (gst_omx_component_get_state (self->dec, 0) > OMX_StateIdle)
771 gst_omx_component_set_state (self->dec, OMX_StateIdle);
773 self->downstream_flow_ret = GST_FLOW_FLUSHING;
774 self->started = FALSE;
776 g_mutex_lock (&self->drain_lock);
777 self->draining = FALSE;
778 g_cond_broadcast (&self->drain_cond);
779 g_mutex_unlock (&self->drain_lock);
781 gst_adapter_flush (self->output_adapter,
782 gst_adapter_available (self->output_adapter));
784 gst_omx_component_get_state (self->dec, 5 * GST_SECOND);
786 gst_buffer_replace (&self->codec_data, NULL);
788 GST_DEBUG_OBJECT (self, "Stopped decoder");
794 gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
796 GstOMXAudioDec *self;
797 GstOMXAudioDecClass *klass;
799 const GValue *codec_data;
800 gboolean is_format_change = FALSE;
801 gboolean needs_disable = FALSE;
803 self = GST_OMX_AUDIO_DEC (decoder);
804 klass = GST_OMX_AUDIO_DEC_GET_CLASS (decoder);
806 GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps);
808 /* Check if the caps change is a real format change or if only irrelevant
809 * parts of the caps have changed or nothing at all.
811 if (klass->is_format_change)
812 is_format_change = klass->is_format_change (self, self->dec_in_port, caps);
815 gst_omx_component_get_state (self->dec,
816 GST_CLOCK_TIME_NONE) != OMX_StateLoaded;
817 /* If the component is not in Loaded state and a real format change happens
818 * we have to disable the port and re-allocate all buffers. If no real
819 * format change happened we can just exit here.
821 if (needs_disable && !is_format_change) {
822 GST_DEBUG_OBJECT (self,
823 "Already running and caps did not change the format");
827 if (needs_disable && is_format_change) {
828 GstOMXPort *out_port = self->dec_out_port;
830 GST_DEBUG_OBJECT (self, "Need to disable and drain decoder");
832 gst_omx_audio_dec_drain (self);
833 gst_omx_audio_dec_flush (decoder, FALSE);
834 gst_omx_port_set_flushing (out_port, 5 * GST_SECOND, TRUE);
836 if (klass->cdata.hacks & GST_OMX_HACK_NO_COMPONENT_RECONFIGURE) {
837 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
838 gst_omx_audio_dec_stop (GST_AUDIO_DECODER (self));
839 gst_omx_audio_dec_close (GST_AUDIO_DECODER (self));
840 GST_AUDIO_DECODER_STREAM_LOCK (self);
842 if (!gst_omx_audio_dec_open (GST_AUDIO_DECODER (self)))
844 needs_disable = FALSE;
846 /* Disabling at the same time input port and output port is only
847 * required when a buffer is shared between the ports. This cannot
848 * be the case for a decoder because its input and output buffers
849 * are of different nature. So let's disable ports sequencially.
850 * Starting from IL 1.2.0, this point has been clarified.
851 * OMX_SendCommand will return an error if the IL client attempts to
852 * call it when there is already an on-going command being processed.
853 * The exception is for buffer sharing above and the event
854 * OMX_EventPortNeedsDisable will be sent to request disabling the
855 * other port at the same time. */
856 if (gst_omx_port_set_enabled (self->dec_in_port, FALSE) != OMX_ErrorNone)
858 if (gst_omx_port_wait_buffers_released (self->dec_in_port,
859 5 * GST_SECOND) != OMX_ErrorNone)
861 if (gst_omx_port_deallocate_buffers (self->dec_in_port) != OMX_ErrorNone)
863 if (gst_omx_port_wait_enabled (self->dec_in_port,
864 1 * GST_SECOND) != OMX_ErrorNone)
867 if (gst_omx_port_set_enabled (out_port, FALSE) != OMX_ErrorNone)
869 if (gst_omx_port_wait_buffers_released (out_port,
870 1 * GST_SECOND) != OMX_ErrorNone)
872 if (gst_omx_port_deallocate_buffers (out_port) != OMX_ErrorNone)
874 if (gst_omx_port_wait_enabled (out_port, 1 * GST_SECOND) != OMX_ErrorNone)
878 GST_DEBUG_OBJECT (self, "Decoder drained and disabled");
881 if (klass->set_format) {
882 if (!klass->set_format (self, self->dec_in_port, caps)) {
883 GST_ERROR_OBJECT (self, "Subclass failed to set the new format");
888 GST_DEBUG_OBJECT (self, "Updating outport port definition");
889 if (gst_omx_port_update_port_definition (self->dec_out_port,
890 NULL) != OMX_ErrorNone)
893 /* Get codec data from caps */
894 gst_buffer_replace (&self->codec_data, NULL);
895 s = gst_caps_get_structure (caps, 0);
896 codec_data = gst_structure_get_value (s, "codec_data");
898 /* Vorbis and some other codecs have multiple buffers in
899 * the stream-header field */
900 self->codec_data = gst_value_get_buffer (codec_data);
901 if (self->codec_data)
902 gst_buffer_ref (self->codec_data);
905 GST_DEBUG_OBJECT (self, "Enabling component");
908 if (gst_omx_port_set_enabled (self->dec_in_port, TRUE) != OMX_ErrorNone)
910 if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
913 if ((klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
914 if (gst_omx_port_set_enabled (self->dec_out_port, TRUE) != OMX_ErrorNone)
916 if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
919 if (gst_omx_port_wait_enabled (self->dec_out_port,
920 5 * GST_SECOND) != OMX_ErrorNone)
924 if (gst_omx_port_wait_enabled (self->dec_in_port,
925 5 * GST_SECOND) != OMX_ErrorNone)
927 if (gst_omx_port_mark_reconfigured (self->dec_in_port) != OMX_ErrorNone)
930 if (!(klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
931 /* Disable output port */
932 if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone)
935 if (gst_omx_port_wait_enabled (self->dec_out_port,
936 1 * GST_SECOND) != OMX_ErrorNone)
939 if (gst_omx_component_set_state (self->dec,
940 OMX_StateIdle) != OMX_ErrorNone)
943 /* Need to allocate buffers to reach Idle state */
944 if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
947 if (gst_omx_component_set_state (self->dec,
948 OMX_StateIdle) != OMX_ErrorNone)
951 /* Need to allocate buffers to reach Idle state */
952 if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
954 if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
958 if (gst_omx_component_get_state (self->dec,
959 GST_CLOCK_TIME_NONE) != OMX_StateIdle)
962 if (gst_omx_component_set_state (self->dec,
963 OMX_StateExecuting) != OMX_ErrorNone)
966 if (gst_omx_component_get_state (self->dec,
967 GST_CLOCK_TIME_NONE) != OMX_StateExecuting)
971 /* Unset flushing to allow ports to accept data again */
972 gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
973 gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
975 if (gst_omx_component_get_last_error (self->dec) != OMX_ErrorNone) {
976 GST_ERROR_OBJECT (self, "Component in error state: %s (0x%08x)",
977 gst_omx_component_get_last_error_string (self->dec),
978 gst_omx_component_get_last_error (self->dec));
982 self->downstream_flow_ret = GST_FLOW_OK;
988 gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
990 GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder);
991 OMX_ERRORTYPE err = OMX_ErrorNone;
993 GST_DEBUG_OBJECT (self, "Flushing decoder");
995 if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded)
998 /* 0) Pause the components */
999 if (gst_omx_component_get_state (self->dec, 0) == OMX_StateExecuting) {
1000 gst_omx_component_set_state (self->dec, OMX_StatePause);
1001 gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
1004 /* 1) Flush the ports */
1005 GST_DEBUG_OBJECT (self, "flushing ports");
1006 gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE);
1007 gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE);
1009 /* 2) Wait until the srcpad loop is stopped,
1010 * unlock GST_AUDIO_DECODER_STREAM_LOCK to prevent deadlocks
1011 * caused by using this lock from inside the loop function */
1012 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1013 gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder));
1014 GST_DEBUG_OBJECT (self, "Flushing -- task stopped");
1015 GST_AUDIO_DECODER_STREAM_LOCK (self);
1017 /* 3) Resume components */
1018 gst_omx_component_set_state (self->dec, OMX_StateExecuting);
1019 gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
1021 /* 4) Unset flushing to allow ports to accept data again */
1022 gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
1023 gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
1025 err = gst_omx_port_populate (self->dec_out_port);
1027 if (err != OMX_ErrorNone) {
1028 GST_WARNING_OBJECT (self, "Failed to populate output port: %s (0x%08x)",
1029 gst_omx_error_to_string (err), err);
1032 /* Reset our state */
1033 gst_adapter_flush (self->output_adapter,
1034 gst_adapter_available (self->output_adapter));
1035 self->last_upstream_ts = 0;
1036 self->downstream_flow_ret = GST_FLOW_OK;
1037 self->started = FALSE;
1038 GST_DEBUG_OBJECT (self, "Flush finished");
1041 static GstFlowReturn
1042 gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
1044 GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
1045 GstOMXAudioDec *self;
1048 GstBuffer *codec_data = NULL;
1050 GstClockTime timestamp, duration;
1054 self = GST_OMX_AUDIO_DEC (decoder);
1056 GST_DEBUG_OBJECT (self, "Handling frame");
1058 if (self->downstream_flow_ret != GST_FLOW_OK) {
1059 return self->downstream_flow_ret;
1062 if (!self->started) {
1063 GST_DEBUG_OBJECT (self, "Starting task");
1064 gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self),
1065 (GstTaskFunction) gst_omx_audio_dec_loop, decoder, NULL);
1069 return gst_omx_audio_dec_drain (self);
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 */
1074 gst_buffer_ref (inbuf);
1076 timestamp = GST_BUFFER_TIMESTAMP (inbuf);
1077 duration = GST_BUFFER_DURATION (inbuf);
1079 port = self->dec_in_port;
1081 gst_buffer_map (inbuf, &minfo, GST_MAP_READ);
1083 while (offset < minfo.size) {
1084 /* Make sure to release the base class stream lock, otherwise
1085 * _loop() can't call _finish_frame() and we might block forever
1086 * because no input buffers are released */
1087 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1088 acq_ret = gst_omx_port_acquire_buffer (port, &buf, GST_OMX_WAIT);
1090 if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) {
1091 GST_AUDIO_DECODER_STREAM_LOCK (self);
1092 goto component_error;
1093 } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
1094 GST_AUDIO_DECODER_STREAM_LOCK (self);
1096 } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
1097 /* Reallocate all buffers */
1098 err = gst_omx_port_set_enabled (port, FALSE);
1099 if (err != OMX_ErrorNone) {
1100 GST_AUDIO_DECODER_STREAM_LOCK (self);
1101 goto reconfigure_error;
1104 err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
1105 if (err != OMX_ErrorNone) {
1106 GST_AUDIO_DECODER_STREAM_LOCK (self);
1107 goto reconfigure_error;
1110 err = gst_omx_port_deallocate_buffers (port);
1111 if (err != OMX_ErrorNone) {
1112 GST_AUDIO_DECODER_STREAM_LOCK (self);
1113 goto reconfigure_error;
1116 err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
1117 if (err != OMX_ErrorNone) {
1118 GST_AUDIO_DECODER_STREAM_LOCK (self);
1119 goto reconfigure_error;
1122 err = gst_omx_port_set_enabled (port, TRUE);
1123 if (err != OMX_ErrorNone) {
1124 GST_AUDIO_DECODER_STREAM_LOCK (self);
1125 goto reconfigure_error;
1128 err = gst_omx_port_allocate_buffers (port);
1129 if (err != OMX_ErrorNone) {
1130 GST_AUDIO_DECODER_STREAM_LOCK (self);
1131 goto reconfigure_error;
1134 err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
1135 if (err != OMX_ErrorNone) {
1136 GST_AUDIO_DECODER_STREAM_LOCK (self);
1137 goto reconfigure_error;
1140 err = gst_omx_port_mark_reconfigured (port);
1141 if (err != OMX_ErrorNone) {
1142 GST_AUDIO_DECODER_STREAM_LOCK (self);
1143 goto reconfigure_error;
1146 /* Now get a new buffer and fill it */
1147 GST_AUDIO_DECODER_STREAM_LOCK (self);
1150 GST_AUDIO_DECODER_STREAM_LOCK (self);
1152 g_assert (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK && buf != NULL);
1154 if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <= 0) {
1155 gst_omx_port_release_buffer (port, buf);
1159 if (self->downstream_flow_ret != GST_FLOW_OK) {
1160 gst_omx_port_release_buffer (port, buf);
1164 if (self->codec_data) {
1165 GST_DEBUG_OBJECT (self, "Passing codec data to the component");
1167 codec_data = self->codec_data;
1169 if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <
1170 gst_buffer_get_size (codec_data)) {
1171 gst_omx_port_release_buffer (port, buf);
1172 goto too_large_codec_data;
1175 buf->omx_buf->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
1176 buf->omx_buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1177 buf->omx_buf->nFilledLen = gst_buffer_get_size (codec_data);
1178 gst_buffer_extract (codec_data, 0,
1179 buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
1180 buf->omx_buf->nFilledLen);
1182 if (GST_CLOCK_TIME_IS_VALID (timestamp))
1183 GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp,
1184 gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND,
1187 GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp, G_GUINT64_CONSTANT (0));
1188 buf->omx_buf->nTickCount = 0;
1190 self->started = TRUE;
1191 err = gst_omx_port_release_buffer (port, buf);
1192 gst_buffer_replace (&self->codec_data, NULL);
1193 if (err != OMX_ErrorNone)
1195 /* Acquire new buffer for the actual frame */
1199 /* Now handle the frame */
1200 GST_DEBUG_OBJECT (self, "Passing frame offset %d to the component", offset);
1202 /* Copy the buffer content in chunks of size as requested
1204 buf->omx_buf->nFilledLen =
1205 MIN (minfo.size - offset,
1206 buf->omx_buf->nAllocLen - buf->omx_buf->nOffset);
1207 gst_buffer_extract (inbuf, offset,
1208 buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
1209 buf->omx_buf->nFilledLen);
1211 if (timestamp != GST_CLOCK_TIME_NONE) {
1212 GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp,
1213 gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND));
1214 self->last_upstream_ts = timestamp;
1216 GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp, G_GUINT64_CONSTANT (0));
1219 if (duration != GST_CLOCK_TIME_NONE && offset == 0) {
1220 buf->omx_buf->nTickCount =
1221 gst_util_uint64_scale (duration, OMX_TICKS_PER_SECOND, GST_SECOND);
1222 self->last_upstream_ts += duration;
1224 buf->omx_buf->nTickCount = 0;
1228 buf->omx_buf->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
1231 * - OMX_BUFFERFLAG_DECODEONLY for buffers that are outside
1235 offset += buf->omx_buf->nFilledLen;
1237 if (offset == minfo.size)
1238 buf->omx_buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1240 self->started = TRUE;
1241 err = gst_omx_port_release_buffer (port, buf);
1242 if (err != OMX_ErrorNone)
1245 gst_buffer_unmap (inbuf, &minfo);
1246 gst_buffer_unref (inbuf);
1248 GST_DEBUG_OBJECT (self, "Passed frame to component");
1250 return self->downstream_flow_ret;
1254 gst_buffer_unmap (inbuf, &minfo);
1255 gst_buffer_unref (inbuf);
1257 GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
1258 ("Got OpenMAX buffer with no free space (%p, %u/%u)", buf,
1259 (guint) buf->omx_buf->nOffset, (guint) buf->omx_buf->nAllocLen));
1260 return GST_FLOW_ERROR;
1265 gst_buffer_unmap (inbuf, &minfo);
1266 gst_buffer_unref (inbuf);
1268 return self->downstream_flow_ret;
1271 too_large_codec_data:
1273 gst_buffer_unmap (inbuf, &minfo);
1274 gst_buffer_unref (inbuf);
1276 GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
1277 ("codec_data larger than supported by OpenMAX port "
1278 "(%" G_GSIZE_FORMAT " > %u)", gst_buffer_get_size (codec_data),
1279 (guint) self->dec_in_port->port_def.nBufferSize));
1280 return GST_FLOW_ERROR;
1285 gst_buffer_unmap (inbuf, &minfo);
1286 gst_buffer_unref (inbuf);
1288 GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
1289 ("OpenMAX component in error state %s (0x%08x)",
1290 gst_omx_component_get_last_error_string (self->dec),
1291 gst_omx_component_get_last_error (self->dec)));
1292 return GST_FLOW_ERROR;
1297 gst_buffer_unmap (inbuf, &minfo);
1298 gst_buffer_unref (inbuf);
1300 GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING");
1301 return GST_FLOW_FLUSHING;
1305 gst_buffer_unmap (inbuf, &minfo);
1306 gst_buffer_unref (inbuf);
1308 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
1309 ("Unable to reconfigure input port"));
1310 return GST_FLOW_ERROR;
1314 gst_buffer_unmap (inbuf, &minfo);
1315 gst_buffer_unref (inbuf);
1317 GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
1318 ("Failed to relase input buffer to component: %s (0x%08x)",
1319 gst_omx_error_to_string (err), err));
1321 return GST_FLOW_ERROR;
1325 static GstFlowReturn
1326 gst_omx_audio_dec_drain (GstOMXAudioDec * self)
1328 GstOMXAudioDecClass *klass;
1330 GstOMXAcquireBufferReturn acq_ret;
1333 GST_DEBUG_OBJECT (self, "Draining component");
1335 klass = GST_OMX_AUDIO_DEC_GET_CLASS (self);
1337 if (!self->started) {
1338 GST_DEBUG_OBJECT (self, "Component not started yet");
1341 self->started = FALSE;
1343 if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) {
1344 GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers");
1348 /* Make sure to release the base class stream lock, otherwise
1349 * _loop() can't call _finish_frame() and we might block forever
1350 * because no input buffers are released */
1351 GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1353 /* Send an EOS buffer to the component and let the base
1354 * class drop the EOS event. We will send it later when
1355 * the EOS buffer arrives on the output port. */
1356 acq_ret = gst_omx_port_acquire_buffer (self->dec_in_port, &buf, GST_OMX_WAIT);
1357 if (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) {
1358 GST_AUDIO_DECODER_STREAM_LOCK (self);
1359 GST_ERROR_OBJECT (self, "Failed to acquire buffer for draining: %d",
1361 return GST_FLOW_ERROR;
1364 g_mutex_lock (&self->drain_lock);
1365 self->draining = TRUE;
1366 buf->omx_buf->nFilledLen = 0;
1367 GST_OMX_SET_TICKS (buf->omx_buf->nTimeStamp,
1368 gst_util_uint64_scale (self->last_upstream_ts, OMX_TICKS_PER_SECOND,
1370 buf->omx_buf->nTickCount = 0;
1371 buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS;
1372 err = gst_omx_port_release_buffer (self->dec_in_port, buf);
1373 if (err != OMX_ErrorNone) {
1374 GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)",
1375 gst_omx_error_to_string (err), err);
1376 g_mutex_unlock (&self->drain_lock);
1377 GST_AUDIO_DECODER_STREAM_LOCK (self);
1378 return GST_FLOW_ERROR;
1381 GST_DEBUG_OBJECT (self, "Waiting until component is drained");
1383 if (G_UNLIKELY (self->dec->hacks & GST_OMX_HACK_DRAIN_MAY_NOT_RETURN)) {
1384 gint64 wait_until = g_get_monotonic_time () + G_TIME_SPAN_SECOND / 2;
1386 if (!g_cond_wait_until (&self->drain_cond, &self->drain_lock, wait_until))
1387 GST_WARNING_OBJECT (self, "Drain timed out");
1389 GST_DEBUG_OBJECT (self, "Drained component");
1392 g_cond_wait (&self->drain_cond, &self->drain_lock);
1393 GST_DEBUG_OBJECT (self, "Drained component");
1396 g_mutex_unlock (&self->drain_lock);
1397 GST_AUDIO_DECODER_STREAM_LOCK (self);
1399 gst_adapter_flush (self->output_adapter,
1400 gst_adapter_available (self->output_adapter));
1401 self->started = FALSE;