Added exception handling for null buffer
[platform/upstream/gstreamer.git] / omx / gstomxaudiodec.c
1 /*
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>
7  *
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.
12  *
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.
17  *
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
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <gst/gst.h>
29
30 #include <string.h>
31
32 #include "gstomxaudiodec.h"
33
34 GST_DEBUG_CATEGORY_STATIC (gst_omx_audio_dec_debug_category);
35 #define GST_CAT_DEFAULT gst_omx_audio_dec_debug_category
36
37 /* prototypes */
38 static void gst_omx_audio_dec_finalize (GObject * object);
39
40 static GstStateChangeReturn
41 gst_omx_audio_dec_change_state (GstElement * element,
42     GstStateChange transition);
43
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,
49     GstCaps * caps);
50 static void gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard);
51 static GstFlowReturn gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder,
52     GstBuffer * buffer);
53 static GstFlowReturn gst_omx_audio_dec_drain (GstOMXAudioDec * self);
54
55 enum
56 {
57   PROP_0
58 };
59
60 /* class initialization */
61
62 #define DEBUG_INIT \
63   GST_DEBUG_CATEGORY_INIT (gst_omx_audio_dec_debug_category, "omxaudiodec", 0, \
64       "debug category for gst-omx audio decoder base class");
65
66
67 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstOMXAudioDec, gst_omx_audio_dec,
68     GST_TYPE_AUDIO_DECODER, DEBUG_INIT);
69
70 static void
71 gst_omx_audio_dec_class_init (GstOMXAudioDecClass * klass)
72 {
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);
76
77   gobject_class->finalize = gst_omx_audio_dec_finalize;
78
79   element_class->change_state =
80       GST_DEBUG_FUNCPTR (gst_omx_audio_dec_change_state);
81
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);
91
92   klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER;
93   klass->cdata.default_src_template_caps =
94       "audio/x-raw, "
95       "rate = (int) [ 1, MAX ], "
96       "channels = (int) [ 1, " G_STRINGIFY (OMX_AUDIO_MAXCHANNELS) " ], "
97       "format = (string) " GST_AUDIO_FORMATS_ALL;
98 }
99
100 static void
101 gst_omx_audio_dec_init (GstOMXAudioDec * self)
102 {
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
106       (self), TRUE);
107   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (self));
108
109   g_mutex_init (&self->drain_lock);
110   g_cond_init (&self->drain_cond);
111
112   self->output_adapter = gst_adapter_new ();
113 }
114
115 static gboolean
116 gst_omx_audio_dec_open (GstAudioDecoder * decoder)
117 {
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;
121
122   GST_DEBUG_OBJECT (self, "Opening decoder");
123
124   self->dec =
125       gst_omx_component_new (GST_OBJECT_CAST (self), klass->cdata.core_name,
126       klass->cdata.component_name, klass->cdata.component_role,
127       klass->cdata.hacks);
128   self->started = FALSE;
129
130   if (!self->dec)
131     return FALSE;
132
133   if (gst_omx_component_get_state (self->dec,
134           GST_CLOCK_TIME_NONE) != OMX_StateLoaded)
135     return FALSE;
136
137   in_port_index = klass->cdata.in_port_index;
138   out_port_index = klass->cdata.out_port_index;
139
140   if (in_port_index == -1 || out_port_index == -1) {
141     OMX_PORT_PARAM_TYPE param;
142     OMX_ERRORTYPE err;
143
144     GST_OMX_INIT_STRUCT (&param);
145
146     err =
147         gst_omx_component_get_parameter (self->dec, OMX_IndexParamAudioInit,
148         &param);
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);
152       /* Fallback */
153       in_port_index = 0;
154       out_port_index = 1;
155     } else {
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;
160     }
161   }
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);
164
165   if (!self->dec_in_port || !self->dec_out_port)
166     return FALSE;
167
168   GST_DEBUG_OBJECT (self, "Opened decoder");
169
170   return TRUE;
171 }
172
173 static gboolean
174 gst_omx_audio_dec_shutdown (GstOMXAudioDec * self)
175 {
176   OMX_STATETYPE state;
177
178   GST_DEBUG_OBJECT (self, "Shutting down decoder");
179
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);
185     }
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);
191   }
192
193   return TRUE;
194 }
195
196 static gboolean
197 gst_omx_audio_dec_close (GstAudioDecoder * decoder)
198 {
199   GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder);
200
201   GST_DEBUG_OBJECT (self, "Closing decoder");
202
203   if (!gst_omx_audio_dec_shutdown (self))
204     return FALSE;
205
206   self->dec_in_port = NULL;
207   self->dec_out_port = NULL;
208   if (self->dec)
209     gst_omx_component_free (self->dec);
210   self->dec = NULL;
211
212   self->started = FALSE;
213
214   GST_DEBUG_OBJECT (self, "Closed decoder");
215
216   return TRUE;
217 }
218
219 static void
220 gst_omx_audio_dec_finalize (GObject * object)
221 {
222   GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (object);
223
224   g_mutex_clear (&self->drain_lock);
225   g_cond_clear (&self->drain_cond);
226
227   if (self->output_adapter)
228     gst_object_unref (self->output_adapter);
229   self->output_adapter = NULL;
230
231   G_OBJECT_CLASS (gst_omx_audio_dec_parent_class)->finalize (object);
232 }
233
234 static GstStateChangeReturn
235 gst_omx_audio_dec_change_state (GstElement * element, GstStateChange transition)
236 {
237   GstOMXAudioDec *self;
238   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
239
240   g_return_val_if_fail (GST_IS_OMX_AUDIO_DEC (element),
241       GST_STATE_CHANGE_FAILURE);
242   self = GST_OMX_AUDIO_DEC (element);
243
244   switch (transition) {
245     case GST_STATE_CHANGE_NULL_TO_READY:
246       break;
247     case GST_STATE_CHANGE_READY_TO_PAUSED:
248       self->downstream_flow_ret = GST_FLOW_OK;
249       self->draining = FALSE;
250       self->started = FALSE;
251       break;
252     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
253       break;
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);
259
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);
264       break;
265     default:
266       break;
267   }
268
269   ret =
270       GST_ELEMENT_CLASS (gst_omx_audio_dec_parent_class)->change_state
271       (element, transition);
272
273   if (ret == GST_STATE_CHANGE_FAILURE)
274     return ret;
275
276   switch (transition) {
277     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
278       break;
279     case GST_STATE_CHANGE_PAUSED_TO_READY:
280       self->downstream_flow_ret = GST_FLOW_FLUSHING;
281       self->started = FALSE;
282
283       if (!gst_omx_audio_dec_shutdown (self))
284         ret = GST_STATE_CHANGE_FAILURE;
285       break;
286     case GST_STATE_CHANGE_READY_TO_NULL:
287       break;
288     default:
289       break;
290   }
291
292   return ret;
293 }
294
295 static void
296 gst_omx_audio_dec_loop (GstOMXAudioDec * self)
297 {
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;
303   OMX_ERRORTYPE err;
304   gint spf;
305
306   acq_return = gst_omx_port_acquire_buffer (port, &buf);
307   if (acq_return == GST_OMX_ACQUIRE_BUFFER_ERROR) {
308     goto component_error;
309   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
310     goto flushing;
311   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) {
312     goto eos;
313   }
314
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);
321     gint i;
322
323     GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps");
324
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;
331
332       err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
333       if (err != OMX_ErrorNone)
334         goto reconfigure_error;
335
336       err = gst_omx_port_deallocate_buffers (port);
337       if (err != OMX_ErrorNone)
338         goto reconfigure_error;
339
340       err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
341       if (err != OMX_ErrorNone)
342         goto reconfigure_error;
343     }
344
345     /* Just update caps */
346     GST_AUDIO_DECODER_STREAM_LOCK (self);
347
348     gst_omx_port_get_port_definition (port, &port_def);
349     g_assert (port_def.format.audio.eEncoding == OMX_AUDIO_CodingPCM);
350
351     GST_OMX_INIT_STRUCT (&pcm_param);
352     pcm_param.nPortIndex = self->dec_out_port->index;
353     err =
354         gst_omx_component_get_parameter (self->dec, OMX_IndexParamAudioPcm,
355         &pcm_param);
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);
359       goto caps_failed;
360     }
361
362     g_assert (pcm_param.ePCMMode == OMX_AUDIO_PCMModeLinear);
363     g_assert (pcm_param.bInterleaved == OMX_TRUE);
364
365     gst_audio_info_init (&self->info);
366
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;
371           break;
372         case OMX_AUDIO_ChannelRF:
373           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
374           break;
375         case OMX_AUDIO_ChannelCF:
376           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
377           break;
378         case OMX_AUDIO_ChannelLS:
379           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
380           break;
381         case OMX_AUDIO_ChannelRS:
382           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
383           break;
384         case OMX_AUDIO_ChannelLFE:
385           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_LFE1;
386           break;
387         case OMX_AUDIO_ChannelCS:
388           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
389           break;
390         case OMX_AUDIO_ChannelLR:
391           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
392           break;
393         case OMX_AUDIO_ChannelRR:
394           omx_position[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
395           break;
396         case OMX_AUDIO_ChannelNone:
397         default:
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;
402           break;
403       }
404     }
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;
408
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);
414     }
415
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);
425
426     gst_audio_info_set_format (&self->info,
427         gst_audio_format_build_integer (pcm_param.eNumData ==
428             OMX_NumericalDataSigned,
429             pcm_param.eEndian ==
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);
433
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);
438
439     if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (self),
440             &self->info)
441         || !gst_audio_decoder_negotiate (GST_AUDIO_DECODER (self))) {
442       if (buf)
443         gst_omx_port_release_buffer (port, buf);
444       goto caps_failed;
445     }
446
447     GST_AUDIO_DECODER_STREAM_UNLOCK (self);
448
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;
453
454       err = gst_omx_port_allocate_buffers (port);
455       if (err != OMX_ErrorNone)
456         goto reconfigure_error;
457
458       err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
459       if (err != OMX_ErrorNone)
460         goto reconfigure_error;
461
462       err = gst_omx_port_populate (port);
463       if (err != OMX_ErrorNone)
464         goto reconfigure_error;
465
466       err = gst_omx_port_mark_reconfigured (port);
467       if (err != OMX_ErrorNone)
468         goto reconfigure_error;
469     }
470
471     /* Now get a buffer */
472     if (acq_return != GST_OMX_ACQUIRE_BUFFER_OK) {
473       return;
474     }
475   }
476
477   g_assert (acq_return == GST_OMX_ACQUIRE_BUFFER_OK);
478   if (!buf) {
479     g_assert ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER));
480     GST_AUDIO_DECODER_STREAM_LOCK (self);
481     goto eos;
482   }
483
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
487    */
488   if (gst_omx_port_is_flushing (port)) {
489     GST_DEBUG_OBJECT (self, "Flushing");
490     gst_omx_port_release_buffer (port, buf);
491     goto flushing;
492   }
493
494   GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %" G_GUINT64_FORMAT,
495       (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp);
496
497   GST_AUDIO_DECODER_STREAM_LOCK (self);
498
499   spf = klass->get_samples_per_frame (self, self->dec_out_port);
500
501   if (buf->omx_buf->nFilledLen > 0) {
502     GstBuffer *outbuf;
503     GstMapInfo minfo;
504
505     GST_DEBUG_OBJECT (self, "Handling output data");
506
507     if (buf->omx_buf->nFilledLen % self->info.bpf != 0) {
508       gst_omx_port_release_buffer (port, buf);
509       goto invalid_buffer;
510     }
511
512     outbuf =
513         gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (self),
514         buf->omx_buf->nFilledLen);
515
516     gst_buffer_map (outbuf, &minfo, GST_MAP_WRITE);
517     if (self->needs_reorder) {
518       gint i, n_samples, c, n_channels;
519       gint *reorder_map = self->reorder_map;
520       gint16 *dest, *source;
521
522       dest = (gint16 *) minfo.data;
523       source = (gint16 *) (buf->omx_buf->pBuffer + buf->omx_buf->nOffset);
524       n_samples = buf->omx_buf->nFilledLen / self->info.bpf;
525       n_channels = self->info.channels;
526
527       for (i = 0; i < n_samples; i++) {
528         for (c = 0; c < n_channels; c++) {
529           dest[i * n_channels + reorder_map[c]] = source[i * n_channels + c];
530         }
531       }
532     } else {
533       memcpy (minfo.data, buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
534           buf->omx_buf->nFilledLen);
535     }
536     gst_buffer_unmap (outbuf, &minfo);
537
538     if (spf != -1) {
539       gst_adapter_push (self->output_adapter, outbuf);
540     } else {
541       flow_ret =
542           gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1);
543     }
544   }
545
546   GST_DEBUG_OBJECT (self, "Read frame from component");
547
548   if (spf != -1) {
549     GstBuffer *outbuf;
550     guint avail = gst_adapter_available (self->output_adapter);
551     guint nframes;
552
553     /* We take a multiple of codec frames and push
554      * them downstream
555      */
556     avail /= self->info.bpf;
557     nframes = avail / spf;
558     avail = nframes * spf;
559     avail *= self->info.bpf;
560
561     if (avail > 0) {
562       outbuf = gst_adapter_take_buffer (self->output_adapter, avail);
563       flow_ret =
564           gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf,
565           nframes);
566     }
567   }
568
569   GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
570
571   if (buf) {
572     err = gst_omx_port_release_buffer (port, buf);
573     if (err != OMX_ErrorNone)
574       goto release_error;
575   }
576
577   self->downstream_flow_ret = flow_ret;
578
579   if (flow_ret != GST_FLOW_OK)
580     goto flow_error;
581
582   GST_AUDIO_DECODER_STREAM_UNLOCK (self);
583
584   return;
585
586 component_error:
587   {
588     GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
589         ("OpenMAX component in error state %s (0x%08x)",
590             gst_omx_component_get_last_error_string (self->dec),
591             gst_omx_component_get_last_error (self->dec)));
592     gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
593     gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
594     self->downstream_flow_ret = GST_FLOW_ERROR;
595     self->started = FALSE;
596     return;
597   }
598
599 flushing:
600   {
601     GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
602     g_mutex_lock (&self->drain_lock);
603     if (self->draining) {
604       self->draining = FALSE;
605       g_cond_broadcast (&self->drain_cond);
606     }
607     gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
608     self->downstream_flow_ret = GST_FLOW_FLUSHING;
609     self->started = FALSE;
610     g_mutex_unlock (&self->drain_lock);
611     return;
612   }
613
614 eos:
615   {
616     spf = klass->get_samples_per_frame (self, self->dec_out_port);
617     if (spf != -1) {
618       GstBuffer *outbuf;
619       guint avail = gst_adapter_available (self->output_adapter);
620       guint nframes;
621
622       /* On EOS we take the complete adapter content, no matter
623        * if it is a multiple of the codec frame size or not.
624        */
625       avail /= self->info.bpf;
626       nframes = (avail + spf - 1) / spf;
627       avail *= self->info.bpf;
628
629       if (avail > 0) {
630         outbuf = gst_adapter_take_buffer (self->output_adapter, avail);
631         flow_ret =
632             gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf,
633             nframes);
634       }
635     }
636
637     g_mutex_lock (&self->drain_lock);
638     if (self->draining) {
639       GST_DEBUG_OBJECT (self, "Drained");
640       self->draining = FALSE;
641       g_cond_broadcast (&self->drain_cond);
642       flow_ret = GST_FLOW_OK;
643       gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
644     } else {
645       GST_DEBUG_OBJECT (self, "Component signalled EOS");
646       flow_ret = GST_FLOW_EOS;
647     }
648     g_mutex_unlock (&self->drain_lock);
649
650     GST_AUDIO_DECODER_STREAM_LOCK (self);
651     self->downstream_flow_ret = flow_ret;
652
653     /* Here we fallback and pause the task for the EOS case */
654     if (flow_ret != GST_FLOW_OK)
655       goto flow_error;
656
657     GST_AUDIO_DECODER_STREAM_UNLOCK (self);
658
659     return;
660   }
661
662 flow_error:
663   {
664     if (flow_ret == GST_FLOW_EOS) {
665       GST_DEBUG_OBJECT (self, "EOS");
666
667       gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self),
668           gst_event_new_eos ());
669       gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
670       self->started = FALSE;
671     } else if (flow_ret < GST_FLOW_EOS) {
672       GST_ELEMENT_ERROR (self, STREAM, FAILED,
673           ("Internal data stream error."), ("stream stopped, reason %s",
674               gst_flow_get_name (flow_ret)));
675
676       gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self),
677           gst_event_new_eos ());
678       gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
679       self->started = FALSE;
680     } else if (flow_ret == GST_FLOW_FLUSHING) {
681       GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
682       g_mutex_lock (&self->drain_lock);
683       if (self->draining) {
684         self->draining = FALSE;
685         g_cond_broadcast (&self->drain_cond);
686       }
687       gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
688       self->started = FALSE;
689       g_mutex_unlock (&self->drain_lock);
690     }
691     GST_AUDIO_DECODER_STREAM_UNLOCK (self);
692     return;
693   }
694
695 reconfigure_error:
696   {
697     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
698         ("Unable to reconfigure output port"));
699     gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
700     gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
701     self->downstream_flow_ret = GST_FLOW_ERROR;
702     self->started = FALSE;
703     return;
704   }
705
706 invalid_buffer:
707   {
708     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
709         ("Invalid sized input buffer"));
710     gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
711     gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
712     self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
713     self->started = FALSE;
714     GST_AUDIO_DECODER_STREAM_UNLOCK (self);
715     return;
716   }
717
718 caps_failed:
719   {
720     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), ("Failed to set caps"));
721     gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
722     gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
723     GST_AUDIO_DECODER_STREAM_UNLOCK (self);
724     self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
725     self->started = FALSE;
726     return;
727   }
728 release_error:
729   {
730     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
731         ("Failed to relase output buffer to component: %s (0x%08x)",
732             gst_omx_error_to_string (err), err));
733     gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
734     gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
735     self->downstream_flow_ret = GST_FLOW_ERROR;
736     self->started = FALSE;
737     GST_AUDIO_DECODER_STREAM_UNLOCK (self);
738     return;
739   }
740 }
741
742 static gboolean
743 gst_omx_audio_dec_start (GstAudioDecoder * decoder)
744 {
745   GstOMXAudioDec *self;
746
747   self = GST_OMX_AUDIO_DEC (decoder);
748
749   self->last_upstream_ts = 0;
750   self->downstream_flow_ret = GST_FLOW_OK;
751
752   return TRUE;
753 }
754
755 static gboolean
756 gst_omx_audio_dec_stop (GstAudioDecoder * decoder)
757 {
758   GstOMXAudioDec *self;
759
760   self = GST_OMX_AUDIO_DEC (decoder);
761
762   GST_DEBUG_OBJECT (self, "Stopping decoder");
763
764   gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE);
765   gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE);
766
767   gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder));
768
769   if (gst_omx_component_get_state (self->dec, 0) > OMX_StateIdle)
770     gst_omx_component_set_state (self->dec, OMX_StateIdle);
771
772   self->downstream_flow_ret = GST_FLOW_FLUSHING;
773   self->started = FALSE;
774
775   g_mutex_lock (&self->drain_lock);
776   self->draining = FALSE;
777   g_cond_broadcast (&self->drain_cond);
778   g_mutex_unlock (&self->drain_lock);
779
780   gst_adapter_flush (self->output_adapter,
781       gst_adapter_available (self->output_adapter));
782
783   gst_omx_component_get_state (self->dec, 5 * GST_SECOND);
784
785   gst_buffer_replace (&self->codec_data, NULL);
786
787   GST_DEBUG_OBJECT (self, "Stopped decoder");
788
789   return TRUE;
790 }
791
792 static gboolean
793 gst_omx_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
794 {
795   GstOMXAudioDec *self;
796   GstOMXAudioDecClass *klass;
797   GstStructure *s;
798   const GValue *codec_data;
799   gboolean is_format_change = FALSE;
800   gboolean needs_disable = FALSE;
801
802   self = GST_OMX_AUDIO_DEC (decoder);
803   klass = GST_OMX_AUDIO_DEC_GET_CLASS (decoder);
804
805   GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps);
806
807   /* Check if the caps change is a real format change or if only irrelevant
808    * parts of the caps have changed or nothing at all.
809    */
810   if (klass->is_format_change)
811     is_format_change = klass->is_format_change (self, self->dec_in_port, caps);
812
813   needs_disable =
814       gst_omx_component_get_state (self->dec,
815       GST_CLOCK_TIME_NONE) != OMX_StateLoaded;
816   /* If the component is not in Loaded state and a real format change happens
817    * we have to disable the port and re-allocate all buffers. If no real
818    * format change happened we can just exit here.
819    */
820   if (needs_disable && !is_format_change) {
821     GST_DEBUG_OBJECT (self,
822         "Already running and caps did not change the format");
823     return TRUE;
824   }
825
826   if (needs_disable && is_format_change) {
827     GstOMXPort *out_port = self->dec_out_port;
828
829     GST_DEBUG_OBJECT (self, "Need to disable and drain decoder");
830
831     gst_omx_audio_dec_drain (self);
832     gst_omx_audio_dec_flush (decoder, FALSE);
833     gst_omx_port_set_flushing (out_port, 5 * GST_SECOND, TRUE);
834
835     if (klass->cdata.hacks & GST_OMX_HACK_NO_COMPONENT_RECONFIGURE) {
836       GST_AUDIO_DECODER_STREAM_UNLOCK (self);
837       gst_omx_audio_dec_stop (GST_AUDIO_DECODER (self));
838       gst_omx_audio_dec_close (GST_AUDIO_DECODER (self));
839       GST_AUDIO_DECODER_STREAM_LOCK (self);
840
841       if (!gst_omx_audio_dec_open (GST_AUDIO_DECODER (self)))
842         return FALSE;
843       needs_disable = FALSE;
844     } else {
845       if (gst_omx_port_set_enabled (self->dec_in_port, FALSE) != OMX_ErrorNone)
846         return FALSE;
847       if (gst_omx_port_set_enabled (out_port, FALSE) != OMX_ErrorNone)
848         return FALSE;
849       if (gst_omx_port_wait_buffers_released (self->dec_in_port,
850               5 * GST_SECOND) != OMX_ErrorNone)
851         return FALSE;
852       if (gst_omx_port_wait_buffers_released (out_port,
853               1 * GST_SECOND) != OMX_ErrorNone)
854         return FALSE;
855       if (gst_omx_port_deallocate_buffers (self->dec_in_port) != OMX_ErrorNone)
856         return FALSE;
857       if (gst_omx_port_deallocate_buffers (self->dec_out_port) != OMX_ErrorNone)
858         return FALSE;
859       if (gst_omx_port_wait_enabled (self->dec_in_port,
860               1 * GST_SECOND) != OMX_ErrorNone)
861         return FALSE;
862       if (gst_omx_port_wait_enabled (out_port, 1 * GST_SECOND) != OMX_ErrorNone)
863         return FALSE;
864     }
865
866     GST_DEBUG_OBJECT (self, "Decoder drained and disabled");
867   }
868
869   if (klass->set_format) {
870     if (!klass->set_format (self, self->dec_in_port, caps)) {
871       GST_ERROR_OBJECT (self, "Subclass failed to set the new format");
872       return FALSE;
873     }
874   }
875
876   GST_DEBUG_OBJECT (self, "Updating outport port definition");
877   if (gst_omx_port_update_port_definition (self->dec_out_port,
878           NULL) != OMX_ErrorNone)
879     return FALSE;
880
881   /* Get codec data from caps */
882   gst_buffer_replace (&self->codec_data, NULL);
883   s = gst_caps_get_structure (caps, 0);
884   codec_data = gst_structure_get_value (s, "codec_data");
885   if (codec_data) {
886     /* Vorbis and some other codecs have multiple buffers in
887      * the stream-header field */
888     self->codec_data = gst_value_get_buffer (codec_data);
889     if (self->codec_data)
890       gst_buffer_ref (self->codec_data);
891   }
892
893   GST_DEBUG_OBJECT (self, "Enabling component");
894
895   if (needs_disable) {
896     if (gst_omx_port_set_enabled (self->dec_in_port, TRUE) != OMX_ErrorNone)
897       return FALSE;
898     if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
899       return FALSE;
900
901     if ((klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
902       if (gst_omx_port_set_enabled (self->dec_out_port, TRUE) != OMX_ErrorNone)
903         return FALSE;
904       if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
905         return FALSE;
906
907       if (gst_omx_port_wait_enabled (self->dec_out_port,
908               5 * GST_SECOND) != OMX_ErrorNone)
909         return FALSE;
910     }
911
912     if (gst_omx_port_wait_enabled (self->dec_in_port,
913             5 * GST_SECOND) != OMX_ErrorNone)
914       return FALSE;
915     if (gst_omx_port_mark_reconfigured (self->dec_in_port) != OMX_ErrorNone)
916       return FALSE;
917   } else {
918     if (!(klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
919       /* Disable output port */
920       if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone)
921         return FALSE;
922
923       if (gst_omx_port_wait_enabled (self->dec_out_port,
924               1 * GST_SECOND) != OMX_ErrorNone)
925         return FALSE;
926
927       if (gst_omx_component_set_state (self->dec,
928               OMX_StateIdle) != OMX_ErrorNone)
929         return FALSE;
930
931       /* Need to allocate buffers to reach Idle state */
932       if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
933         return FALSE;
934     } else {
935       if (gst_omx_component_set_state (self->dec,
936               OMX_StateIdle) != OMX_ErrorNone)
937         return FALSE;
938
939       /* Need to allocate buffers to reach Idle state */
940       if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
941         return FALSE;
942       if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
943         return FALSE;
944     }
945
946     if (gst_omx_component_get_state (self->dec,
947             GST_CLOCK_TIME_NONE) != OMX_StateIdle)
948       return FALSE;
949
950     if (gst_omx_component_set_state (self->dec,
951             OMX_StateExecuting) != OMX_ErrorNone)
952       return FALSE;
953
954     if (gst_omx_component_get_state (self->dec,
955             GST_CLOCK_TIME_NONE) != OMX_StateExecuting)
956       return FALSE;
957   }
958
959   /* Unset flushing to allow ports to accept data again */
960   gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
961   gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
962
963   if (gst_omx_component_get_last_error (self->dec) != OMX_ErrorNone) {
964     GST_ERROR_OBJECT (self, "Component in error state: %s (0x%08x)",
965         gst_omx_component_get_last_error_string (self->dec),
966         gst_omx_component_get_last_error (self->dec));
967     return FALSE;
968   }
969
970   self->downstream_flow_ret = GST_FLOW_OK;
971
972   return TRUE;
973 }
974
975 static void
976 gst_omx_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
977 {
978   GstOMXAudioDec *self = GST_OMX_AUDIO_DEC (decoder);
979   OMX_ERRORTYPE err = OMX_ErrorNone;
980
981   GST_DEBUG_OBJECT (self, "Flushing decoder");
982
983   if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded)
984     return;
985
986   /* 0) Pause the components */
987   if (gst_omx_component_get_state (self->dec, 0) == OMX_StateExecuting) {
988     gst_omx_component_set_state (self->dec, OMX_StatePause);
989     gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
990   }
991
992   /* 1) Wait until the srcpad loop is stopped,
993    * unlock GST_AUDIO_DECODER_STREAM_LOCK to prevent deadlocks
994    * caused by using this lock from inside the loop function */
995   GST_AUDIO_DECODER_STREAM_UNLOCK (self);
996   gst_pad_stop_task (GST_AUDIO_DECODER_SRC_PAD (decoder));
997   GST_DEBUG_OBJECT (self, "Flushing -- task stopped");
998   GST_AUDIO_DECODER_STREAM_LOCK (self);
999
1000   /* 2) Flush the ports */
1001   GST_DEBUG_OBJECT (self, "flushing ports");
1002   gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE);
1003   gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE);
1004
1005   /* 3) Resume components */
1006   gst_omx_component_set_state (self->dec, OMX_StateExecuting);
1007   gst_omx_component_get_state (self->dec, GST_CLOCK_TIME_NONE);
1008
1009   /* 4) Unset flushing to allow ports to accept data again */
1010   gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
1011   gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
1012
1013   err = gst_omx_port_populate (self->dec_out_port);
1014
1015   if (err != OMX_ErrorNone) {
1016     GST_WARNING_OBJECT (self, "Failed to populate output port: %s (0x%08x)",
1017         gst_omx_error_to_string (err), err);
1018   }
1019
1020   /* Reset our state */
1021   gst_adapter_flush (self->output_adapter,
1022       gst_adapter_available (self->output_adapter));
1023   self->last_upstream_ts = 0;
1024   self->downstream_flow_ret = GST_FLOW_OK;
1025   self->started = FALSE;
1026   GST_DEBUG_OBJECT (self, "Flush finished");
1027 }
1028
1029 static GstFlowReturn
1030 gst_omx_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
1031 {
1032   GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
1033   GstOMXAudioDec *self;
1034   GstOMXPort *port;
1035   GstOMXBuffer *buf;
1036   GstBuffer *codec_data = NULL;
1037   guint offset = 0;
1038   GstClockTime timestamp, duration;
1039   OMX_ERRORTYPE err;
1040   GstMapInfo minfo;
1041
1042   self = GST_OMX_AUDIO_DEC (decoder);
1043
1044   GST_DEBUG_OBJECT (self, "Handling frame");
1045
1046   if (self->downstream_flow_ret != GST_FLOW_OK) {
1047     return self->downstream_flow_ret;
1048   }
1049
1050   if (!self->started) {
1051     GST_DEBUG_OBJECT (self, "Starting task");
1052     gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self),
1053         (GstTaskFunction) gst_omx_audio_dec_loop, decoder, NULL);
1054   }
1055
1056   if (inbuf == NULL)
1057     return gst_omx_audio_dec_drain (self);
1058
1059   /* Make sure to keep a reference to the input here,
1060    * it can be unreffed from the other thread if
1061    * finish_frame() is called */
1062   gst_buffer_ref (inbuf);
1063
1064   timestamp = GST_BUFFER_TIMESTAMP (inbuf);
1065   duration = GST_BUFFER_DURATION (inbuf);
1066
1067   port = self->dec_in_port;
1068
1069   gst_buffer_map (inbuf, &minfo, GST_MAP_READ);
1070
1071   while (offset < minfo.size) {
1072     /* Make sure to release the base class stream lock, otherwise
1073      * _loop() can't call _finish_frame() and we might block forever
1074      * because no input buffers are released */
1075     GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1076     acq_ret = gst_omx_port_acquire_buffer (port, &buf);
1077
1078     if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) {
1079       GST_AUDIO_DECODER_STREAM_LOCK (self);
1080       goto component_error;
1081     } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
1082       GST_AUDIO_DECODER_STREAM_LOCK (self);
1083       goto flushing;
1084     } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
1085       /* Reallocate all buffers */
1086       err = gst_omx_port_set_enabled (port, FALSE);
1087       if (err != OMX_ErrorNone) {
1088         GST_AUDIO_DECODER_STREAM_LOCK (self);
1089         goto reconfigure_error;
1090       }
1091
1092       err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
1093       if (err != OMX_ErrorNone) {
1094         GST_AUDIO_DECODER_STREAM_LOCK (self);
1095         goto reconfigure_error;
1096       }
1097
1098       err = gst_omx_port_deallocate_buffers (port);
1099       if (err != OMX_ErrorNone) {
1100         GST_AUDIO_DECODER_STREAM_LOCK (self);
1101         goto reconfigure_error;
1102       }
1103
1104       err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
1105       if (err != OMX_ErrorNone) {
1106         GST_AUDIO_DECODER_STREAM_LOCK (self);
1107         goto reconfigure_error;
1108       }
1109
1110       err = gst_omx_port_set_enabled (port, TRUE);
1111       if (err != OMX_ErrorNone) {
1112         GST_AUDIO_DECODER_STREAM_LOCK (self);
1113         goto reconfigure_error;
1114       }
1115
1116       err = gst_omx_port_allocate_buffers (port);
1117       if (err != OMX_ErrorNone) {
1118         GST_AUDIO_DECODER_STREAM_LOCK (self);
1119         goto reconfigure_error;
1120       }
1121
1122       err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
1123       if (err != OMX_ErrorNone) {
1124         GST_AUDIO_DECODER_STREAM_LOCK (self);
1125         goto reconfigure_error;
1126       }
1127
1128       err = gst_omx_port_mark_reconfigured (port);
1129       if (err != OMX_ErrorNone) {
1130         GST_AUDIO_DECODER_STREAM_LOCK (self);
1131         goto reconfigure_error;
1132       }
1133
1134       /* Now get a new buffer and fill it */
1135       GST_AUDIO_DECODER_STREAM_LOCK (self);
1136       continue;
1137     }
1138     GST_AUDIO_DECODER_STREAM_LOCK (self);
1139
1140     g_assert (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK && buf != NULL);
1141
1142     if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <= 0) {
1143       gst_omx_port_release_buffer (port, buf);
1144       goto full_buffer;
1145     }
1146
1147     if (self->downstream_flow_ret != GST_FLOW_OK) {
1148       gst_omx_port_release_buffer (port, buf);
1149       goto flow_error;
1150     }
1151
1152     if (self->codec_data) {
1153       GST_DEBUG_OBJECT (self, "Passing codec data to the component");
1154
1155       codec_data = self->codec_data;
1156
1157       if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <
1158           gst_buffer_get_size (codec_data)) {
1159         gst_omx_port_release_buffer (port, buf);
1160         goto too_large_codec_data;
1161       }
1162
1163       buf->omx_buf->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
1164       buf->omx_buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1165       buf->omx_buf->nFilledLen = gst_buffer_get_size (codec_data);
1166       gst_buffer_extract (codec_data, 0,
1167           buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
1168           buf->omx_buf->nFilledLen);
1169
1170       if (GST_CLOCK_TIME_IS_VALID (timestamp))
1171         buf->omx_buf->nTimeStamp =
1172             gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND);
1173       else
1174         buf->omx_buf->nTimeStamp = 0;
1175       buf->omx_buf->nTickCount = 0;
1176
1177       self->started = TRUE;
1178       err = gst_omx_port_release_buffer (port, buf);
1179       gst_buffer_replace (&self->codec_data, NULL);
1180       if (err != OMX_ErrorNone)
1181         goto release_error;
1182       /* Acquire new buffer for the actual frame */
1183       continue;
1184     }
1185
1186     /* Now handle the frame */
1187     GST_DEBUG_OBJECT (self, "Passing frame offset %d to the component", offset);
1188
1189     /* Copy the buffer content in chunks of size as requested
1190      * by the port */
1191     buf->omx_buf->nFilledLen =
1192         MIN (minfo.size - offset,
1193         buf->omx_buf->nAllocLen - buf->omx_buf->nOffset);
1194     gst_buffer_extract (inbuf, offset,
1195         buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
1196         buf->omx_buf->nFilledLen);
1197
1198     if (timestamp != GST_CLOCK_TIME_NONE) {
1199       buf->omx_buf->nTimeStamp =
1200           gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND);
1201       self->last_upstream_ts = timestamp;
1202     } else {
1203       buf->omx_buf->nTimeStamp = 0;
1204     }
1205
1206     if (duration != GST_CLOCK_TIME_NONE && offset == 0) {
1207       buf->omx_buf->nTickCount =
1208           gst_util_uint64_scale (duration, OMX_TICKS_PER_SECOND, GST_SECOND);
1209       self->last_upstream_ts += duration;
1210     } else {
1211       buf->omx_buf->nTickCount = 0;
1212     }
1213
1214     if (offset == 0)
1215       buf->omx_buf->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
1216
1217     /* TODO: Set flags
1218      *   - OMX_BUFFERFLAG_DECODEONLY for buffers that are outside
1219      *     the segment
1220      */
1221
1222     offset += buf->omx_buf->nFilledLen;
1223
1224     if (offset == minfo.size)
1225       buf->omx_buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1226
1227     self->started = TRUE;
1228     err = gst_omx_port_release_buffer (port, buf);
1229     if (err != OMX_ErrorNone)
1230       goto release_error;
1231   }
1232   gst_buffer_unmap (inbuf, &minfo);
1233   gst_buffer_unref (inbuf);
1234
1235   GST_DEBUG_OBJECT (self, "Passed frame to component");
1236
1237   return self->downstream_flow_ret;
1238
1239 full_buffer:
1240   {
1241     gst_buffer_unmap (inbuf, &minfo);
1242     gst_buffer_unref (inbuf);
1243
1244     GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
1245         ("Got OpenMAX buffer with no free space (%p, %u/%u)", buf,
1246             (guint) buf->omx_buf->nOffset, (guint) buf->omx_buf->nAllocLen));
1247     return GST_FLOW_ERROR;
1248   }
1249
1250 flow_error:
1251   {
1252     gst_buffer_unmap (inbuf, &minfo);
1253     gst_buffer_unref (inbuf);
1254
1255     return self->downstream_flow_ret;
1256   }
1257
1258 too_large_codec_data:
1259   {
1260     gst_buffer_unmap (inbuf, &minfo);
1261     gst_buffer_unref (inbuf);
1262
1263     GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
1264         ("codec_data larger than supported by OpenMAX port "
1265             "(%" G_GSIZE_FORMAT " > %u)", gst_buffer_get_size (codec_data),
1266             (guint) self->dec_in_port->port_def.nBufferSize));
1267     return GST_FLOW_ERROR;
1268   }
1269
1270 component_error:
1271   {
1272     gst_buffer_unmap (inbuf, &minfo);
1273     gst_buffer_unref (inbuf);
1274
1275     GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
1276         ("OpenMAX component in error state %s (0x%08x)",
1277             gst_omx_component_get_last_error_string (self->dec),
1278             gst_omx_component_get_last_error (self->dec)));
1279     return GST_FLOW_ERROR;
1280   }
1281
1282 flushing:
1283   {
1284     gst_buffer_unmap (inbuf, &minfo);
1285     gst_buffer_unref (inbuf);
1286
1287     GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING");
1288     return GST_FLOW_FLUSHING;
1289   }
1290 reconfigure_error:
1291   {
1292     gst_buffer_unmap (inbuf, &minfo);
1293     gst_buffer_unref (inbuf);
1294
1295     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
1296         ("Unable to reconfigure input port"));
1297     return GST_FLOW_ERROR;
1298   }
1299 release_error:
1300   {
1301     gst_buffer_unmap (inbuf, &minfo);
1302     gst_buffer_unref (inbuf);
1303
1304     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
1305         ("Failed to relase input buffer to component: %s (0x%08x)",
1306             gst_omx_error_to_string (err), err));
1307
1308     return GST_FLOW_ERROR;
1309   }
1310 }
1311
1312 static GstFlowReturn
1313 gst_omx_audio_dec_drain (GstOMXAudioDec * self)
1314 {
1315   GstOMXAudioDecClass *klass;
1316   GstOMXBuffer *buf;
1317   GstOMXAcquireBufferReturn acq_ret;
1318   OMX_ERRORTYPE err;
1319
1320   GST_DEBUG_OBJECT (self, "Draining component");
1321
1322   klass = GST_OMX_AUDIO_DEC_GET_CLASS (self);
1323
1324   if (!self->started) {
1325     GST_DEBUG_OBJECT (self, "Component not started yet");
1326     return GST_FLOW_OK;
1327   }
1328   self->started = FALSE;
1329
1330   if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) {
1331     GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers");
1332     return GST_FLOW_OK;
1333   }
1334
1335   /* Make sure to release the base class stream lock, otherwise
1336    * _loop() can't call _finish_frame() and we might block forever
1337    * because no input buffers are released */
1338   GST_AUDIO_DECODER_STREAM_UNLOCK (self);
1339
1340   /* Send an EOS buffer to the component and let the base
1341    * class drop the EOS event. We will send it later when
1342    * the EOS buffer arrives on the output port. */
1343   acq_ret = gst_omx_port_acquire_buffer (self->dec_in_port, &buf);
1344   if (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) {
1345     GST_AUDIO_DECODER_STREAM_LOCK (self);
1346     GST_ERROR_OBJECT (self, "Failed to acquire buffer for draining: %d",
1347         acq_ret);
1348     return GST_FLOW_ERROR;
1349   }
1350
1351   g_mutex_lock (&self->drain_lock);
1352   self->draining = TRUE;
1353   buf->omx_buf->nFilledLen = 0;
1354   buf->omx_buf->nTimeStamp =
1355       gst_util_uint64_scale (self->last_upstream_ts, OMX_TICKS_PER_SECOND,
1356       GST_SECOND);
1357   buf->omx_buf->nTickCount = 0;
1358   buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS;
1359   err = gst_omx_port_release_buffer (self->dec_in_port, buf);
1360   if (err != OMX_ErrorNone) {
1361     GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)",
1362         gst_omx_error_to_string (err), err);
1363     g_mutex_unlock (&self->drain_lock);
1364     GST_AUDIO_DECODER_STREAM_LOCK (self);
1365     return GST_FLOW_ERROR;
1366   }
1367
1368   GST_DEBUG_OBJECT (self, "Waiting until component is drained");
1369
1370   if (G_UNLIKELY (self->dec->hacks & GST_OMX_HACK_DRAIN_MAY_NOT_RETURN)) {
1371     gint64 wait_until = g_get_monotonic_time () + G_TIME_SPAN_SECOND / 2;
1372
1373     if (!g_cond_wait_until (&self->drain_cond, &self->drain_lock, wait_until))
1374       GST_WARNING_OBJECT (self, "Drain timed out");
1375     else
1376       GST_DEBUG_OBJECT (self, "Drained component");
1377
1378   } else {
1379     g_cond_wait (&self->drain_cond, &self->drain_lock);
1380     GST_DEBUG_OBJECT (self, "Drained component");
1381   }
1382
1383   g_mutex_unlock (&self->drain_lock);
1384   GST_AUDIO_DECODER_STREAM_LOCK (self);
1385
1386   gst_adapter_flush (self->output_adapter,
1387       gst_adapter_available (self->output_adapter));
1388   self->started = FALSE;
1389
1390   return GST_FLOW_OK;
1391 }