Added exception handling for null buffer
[platform/upstream/gstreamer.git] / omx / gstomxaudioenc.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  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation
8  * version 2.1 of the License.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
18  *
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gst/gst.h>
26 #include <string.h>
27
28 #include "gstomxaudioenc.h"
29
30 GST_DEBUG_CATEGORY_STATIC (gst_omx_audio_enc_debug_category);
31 #define GST_CAT_DEFAULT gst_omx_audio_enc_debug_category
32
33 /* prototypes */
34 static void gst_omx_audio_enc_finalize (GObject * object);
35
36 static GstStateChangeReturn
37 gst_omx_audio_enc_change_state (GstElement * element,
38     GstStateChange transition);
39
40 static gboolean gst_omx_audio_enc_open (GstAudioEncoder * encoder);
41 static gboolean gst_omx_audio_enc_close (GstAudioEncoder * encoder);
42 static gboolean gst_omx_audio_enc_start (GstAudioEncoder * encoder);
43 static gboolean gst_omx_audio_enc_stop (GstAudioEncoder * encoder);
44 static gboolean gst_omx_audio_enc_set_format (GstAudioEncoder * encoder,
45     GstAudioInfo * info);
46 static GstFlowReturn gst_omx_audio_enc_handle_frame (GstAudioEncoder *
47     encoder, GstBuffer * buffer);
48 static void gst_omx_audio_enc_flush (GstAudioEncoder * encoder);
49
50 static GstFlowReturn gst_omx_audio_enc_drain (GstOMXAudioEnc * self);
51
52 enum
53 {
54   PROP_0
55 };
56
57 /* class initialization */
58
59 #define DEBUG_INIT \
60   GST_DEBUG_CATEGORY_INIT (gst_omx_audio_enc_debug_category, "omxaudioenc", 0, \
61       "debug category for gst-omx audio encoder base class");
62
63 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstOMXAudioEnc, gst_omx_audio_enc,
64     GST_TYPE_AUDIO_ENCODER, DEBUG_INIT);
65
66 static void
67 gst_omx_audio_enc_class_init (GstOMXAudioEncClass * klass)
68 {
69   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
70   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
71   GstAudioEncoderClass *audio_encoder_class = GST_AUDIO_ENCODER_CLASS (klass);
72
73   gobject_class->finalize = gst_omx_audio_enc_finalize;
74
75   element_class->change_state =
76       GST_DEBUG_FUNCPTR (gst_omx_audio_enc_change_state);
77
78   audio_encoder_class->open = GST_DEBUG_FUNCPTR (gst_omx_audio_enc_open);
79   audio_encoder_class->close = GST_DEBUG_FUNCPTR (gst_omx_audio_enc_close);
80   audio_encoder_class->start = GST_DEBUG_FUNCPTR (gst_omx_audio_enc_start);
81   audio_encoder_class->stop = GST_DEBUG_FUNCPTR (gst_omx_audio_enc_stop);
82   audio_encoder_class->flush = GST_DEBUG_FUNCPTR (gst_omx_audio_enc_flush);
83   audio_encoder_class->set_format =
84       GST_DEBUG_FUNCPTR (gst_omx_audio_enc_set_format);
85   audio_encoder_class->handle_frame =
86       GST_DEBUG_FUNCPTR (gst_omx_audio_enc_handle_frame);
87
88   klass->cdata.type = GST_OMX_COMPONENT_TYPE_FILTER;
89   klass->cdata.default_sink_template_caps = "audio/x-raw, "
90       "rate = (int) [ 1, MAX ], "
91       "channels = (int) [ 1, " G_STRINGIFY (OMX_AUDIO_MAXCHANNELS) " ], "
92       "format = (string) { S8, U8, S16LE, S16BE, U16LE, U16BE, "
93       "S24LE, S24BE, U24LE, U24BE, S32LE, S32BE, U32LE, U32BE }";
94 }
95
96 static void
97 gst_omx_audio_enc_init (GstOMXAudioEnc * self)
98 {
99   g_mutex_init (&self->drain_lock);
100   g_cond_init (&self->drain_cond);
101 }
102
103 static gboolean
104 gst_omx_audio_enc_open (GstAudioEncoder * encoder)
105 {
106   GstOMXAudioEnc *self = GST_OMX_AUDIO_ENC (encoder);
107   GstOMXAudioEncClass *klass = GST_OMX_AUDIO_ENC_GET_CLASS (self);
108   gint in_port_index, out_port_index;
109
110   self->enc =
111       gst_omx_component_new (GST_OBJECT_CAST (self), klass->cdata.core_name,
112       klass->cdata.component_name, klass->cdata.component_role,
113       klass->cdata.hacks);
114   self->started = FALSE;
115
116   if (!self->enc)
117     return FALSE;
118
119   if (gst_omx_component_get_state (self->enc,
120           GST_CLOCK_TIME_NONE) != OMX_StateLoaded)
121     return FALSE;
122
123   in_port_index = klass->cdata.in_port_index;
124   out_port_index = klass->cdata.out_port_index;
125
126   if (in_port_index == -1 || out_port_index == -1) {
127     OMX_PORT_PARAM_TYPE param;
128     OMX_ERRORTYPE err;
129
130     GST_OMX_INIT_STRUCT (&param);
131
132     err =
133         gst_omx_component_get_parameter (self->enc, OMX_IndexParamAudioInit,
134         &param);
135     if (err != OMX_ErrorNone) {
136       GST_WARNING_OBJECT (self, "Couldn't get port information: %s (0x%08x)",
137           gst_omx_error_to_string (err), err);
138       /* Fallback */
139       in_port_index = 0;
140       out_port_index = 1;
141     } else {
142       GST_DEBUG_OBJECT (self, "Detected %u ports, starting at %u",
143           (guint) param.nPorts, (guint) param.nStartPortNumber);
144       in_port_index = param.nStartPortNumber + 0;
145       out_port_index = param.nStartPortNumber + 1;
146     }
147   }
148
149   self->enc_in_port = gst_omx_component_add_port (self->enc, in_port_index);
150   self->enc_out_port = gst_omx_component_add_port (self->enc, out_port_index);
151
152   if (!self->enc_in_port || !self->enc_out_port)
153     return FALSE;
154
155   return TRUE;
156 }
157
158
159 static gboolean
160 gst_omx_audio_enc_shutdown (GstOMXAudioEnc * self)
161 {
162   OMX_STATETYPE state;
163
164   GST_DEBUG_OBJECT (self, "Shutting down encoder");
165
166   state = gst_omx_component_get_state (self->enc, 0);
167   if (state > OMX_StateLoaded || state == OMX_StateInvalid) {
168     if (state > OMX_StateIdle) {
169       gst_omx_component_set_state (self->enc, OMX_StateIdle);
170       gst_omx_component_get_state (self->enc, 5 * GST_SECOND);
171     }
172     gst_omx_component_set_state (self->enc, OMX_StateLoaded);
173     gst_omx_port_deallocate_buffers (self->enc_in_port);
174     gst_omx_port_deallocate_buffers (self->enc_out_port);
175     if (state > OMX_StateLoaded)
176       gst_omx_component_get_state (self->enc, 5 * GST_SECOND);
177   }
178
179   return TRUE;
180 }
181
182 static gboolean
183 gst_omx_audio_enc_close (GstAudioEncoder * encoder)
184 {
185   GstOMXAudioEnc *self = GST_OMX_AUDIO_ENC (encoder);
186
187   GST_DEBUG_OBJECT (self, "Closing encoder");
188
189   if (!gst_omx_audio_enc_shutdown (self))
190     return FALSE;
191
192   self->enc_in_port = NULL;
193   self->enc_out_port = NULL;
194   if (self->enc)
195     gst_omx_component_free (self->enc);
196   self->enc = NULL;
197
198   return TRUE;
199 }
200
201 static void
202 gst_omx_audio_enc_finalize (GObject * object)
203 {
204   GstOMXAudioEnc *self = GST_OMX_AUDIO_ENC (object);
205
206   g_mutex_clear (&self->drain_lock);
207   g_cond_clear (&self->drain_cond);
208
209   G_OBJECT_CLASS (gst_omx_audio_enc_parent_class)->finalize (object);
210 }
211
212 static GstStateChangeReturn
213 gst_omx_audio_enc_change_state (GstElement * element, GstStateChange transition)
214 {
215   GstOMXAudioEnc *self;
216   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
217
218   g_return_val_if_fail (GST_IS_OMX_AUDIO_ENC (element),
219       GST_STATE_CHANGE_FAILURE);
220   self = GST_OMX_AUDIO_ENC (element);
221
222   switch (transition) {
223     case GST_STATE_CHANGE_NULL_TO_READY:
224       break;
225     case GST_STATE_CHANGE_READY_TO_PAUSED:
226       self->downstream_flow_ret = GST_FLOW_OK;
227
228       self->draining = FALSE;
229       self->started = FALSE;
230       break;
231     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
232       break;
233     case GST_STATE_CHANGE_PAUSED_TO_READY:
234       if (self->enc_in_port)
235         gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, TRUE);
236       if (self->enc_out_port)
237         gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, TRUE);
238
239       g_mutex_lock (&self->drain_lock);
240       self->draining = FALSE;
241       g_cond_broadcast (&self->drain_cond);
242       g_mutex_unlock (&self->drain_lock);
243       break;
244     default:
245       break;
246   }
247
248   ret =
249       GST_ELEMENT_CLASS (gst_omx_audio_enc_parent_class)->change_state (element,
250       transition);
251
252   if (ret == GST_STATE_CHANGE_FAILURE)
253     return ret;
254
255   switch (transition) {
256     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
257       break;
258     case GST_STATE_CHANGE_PAUSED_TO_READY:
259       self->downstream_flow_ret = GST_FLOW_FLUSHING;
260       self->started = FALSE;
261
262       if (!gst_omx_audio_enc_shutdown (self))
263         ret = GST_STATE_CHANGE_FAILURE;
264       break;
265     case GST_STATE_CHANGE_READY_TO_NULL:
266       break;
267     default:
268       break;
269   }
270
271   return ret;
272 }
273
274 static void
275 gst_omx_audio_enc_loop (GstOMXAudioEnc * self)
276 {
277   GstOMXAudioEncClass *klass;
278   GstOMXPort *port = self->enc_out_port;
279   GstOMXBuffer *buf = NULL;
280   GstFlowReturn flow_ret = GST_FLOW_OK;
281   GstOMXAcquireBufferReturn acq_return;
282   OMX_ERRORTYPE err;
283
284   klass = GST_OMX_AUDIO_ENC_GET_CLASS (self);
285
286   acq_return = gst_omx_port_acquire_buffer (port, &buf);
287   if (acq_return == GST_OMX_ACQUIRE_BUFFER_ERROR) {
288     goto component_error;
289   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
290     goto flushing;
291   } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) {
292     goto eos;
293   }
294
295   if (!gst_pad_has_current_caps (GST_AUDIO_ENCODER_SRC_PAD (self))
296       || acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
297     GstAudioInfo *info =
298         gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (self));
299     GstCaps *caps;
300
301     GST_DEBUG_OBJECT (self, "Port settings have changed, updating caps");
302
303     /* Reallocate all buffers */
304     if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
305       err = gst_omx_port_set_enabled (port, FALSE);
306       if (err != OMX_ErrorNone)
307         goto reconfigure_error;
308
309       err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
310       if (err != OMX_ErrorNone)
311         goto reconfigure_error;
312
313       err = gst_omx_port_deallocate_buffers (port);
314       if (err != OMX_ErrorNone)
315         goto reconfigure_error;
316
317       err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
318       if (err != OMX_ErrorNone)
319         goto reconfigure_error;
320
321     }
322
323     GST_AUDIO_ENCODER_STREAM_LOCK (self);
324
325     caps = klass->get_caps (self, self->enc_out_port, info);
326     if (!caps) {
327       if (buf)
328         gst_omx_port_release_buffer (self->enc_out_port, buf);
329       GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
330       goto caps_failed;
331     }
332
333     GST_DEBUG_OBJECT (self, "Setting output caps: %" GST_PTR_FORMAT, caps);
334
335     if (!gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (self), caps)) {
336       gst_caps_unref (caps);
337       if (buf)
338         gst_omx_port_release_buffer (self->enc_out_port, buf);
339       GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
340       goto caps_failed;
341     }
342     gst_caps_unref (caps);
343
344     GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
345
346     if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
347       err = gst_omx_port_set_enabled (port, TRUE);
348       if (err != OMX_ErrorNone)
349         goto reconfigure_error;
350
351       err = gst_omx_port_allocate_buffers (port);
352       if (err != OMX_ErrorNone)
353         goto reconfigure_error;
354
355       err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
356       if (err != OMX_ErrorNone)
357         goto reconfigure_error;
358
359       err = gst_omx_port_populate (port);
360       if (err != OMX_ErrorNone)
361         goto reconfigure_error;
362
363       err = gst_omx_port_mark_reconfigured (port);
364       if (err != OMX_ErrorNone)
365         goto reconfigure_error;
366     }
367
368     /* Now get a buffer */
369     if (acq_return != GST_OMX_ACQUIRE_BUFFER_OK) {
370       return;
371     }
372   }
373
374   g_assert (acq_return == GST_OMX_ACQUIRE_BUFFER_OK);
375   if (!buf) {
376     g_assert ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER));
377     GST_AUDIO_ENCODER_STREAM_LOCK (self);
378     goto eos;
379   }
380
381   GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %" G_GUINT64_FORMAT,
382       (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp);
383
384   /* This prevents a deadlock between the srcpad stream
385    * lock and the videocodec stream lock, if ::reset()
386    * is called at the wrong time
387    */
388   if (gst_omx_port_is_flushing (self->enc_out_port)) {
389     GST_DEBUG_OBJECT (self, "Flushing");
390     gst_omx_port_release_buffer (self->enc_out_port, buf);
391     goto flushing;
392   }
393
394   GST_AUDIO_ENCODER_STREAM_LOCK (self);
395
396   if ((buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
397       && buf->omx_buf->nFilledLen > 0) {
398     GstCaps *caps;
399     GstBuffer *codec_data;
400     GstMapInfo map = GST_MAP_INFO_INIT;
401
402     GST_DEBUG_OBJECT (self, "Handling codec data");
403     caps =
404         gst_caps_copy (gst_pad_get_current_caps (GST_AUDIO_ENCODER_SRC_PAD
405             (self)));
406     codec_data = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
407
408     gst_buffer_map (codec_data, &map, GST_MAP_WRITE);
409     memcpy (map.data,
410         buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
411         buf->omx_buf->nFilledLen);
412     gst_buffer_unmap (codec_data, &map);
413
414     gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
415     if (!gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (self), caps)) {
416       gst_caps_unref (caps);
417       if (buf)
418         gst_omx_port_release_buffer (self->enc_out_port, buf);
419       GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
420       goto caps_failed;
421     }
422     gst_caps_unref (caps);
423     flow_ret = GST_FLOW_OK;
424   } else if (buf->omx_buf->nFilledLen > 0) {
425     GstBuffer *outbuf;
426     guint n_samples;
427
428     GST_DEBUG_OBJECT (self, "Handling output data");
429
430     n_samples =
431         klass->get_num_samples (self, self->enc_out_port,
432         gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (self)), buf);
433
434     if (buf->omx_buf->nFilledLen > 0) {
435       GstMapInfo map = GST_MAP_INFO_INIT;
436       outbuf = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
437
438       gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
439
440       memcpy (map.data,
441           buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
442           buf->omx_buf->nFilledLen);
443       gst_buffer_unmap (outbuf, &map);
444
445     } else {
446       outbuf = gst_buffer_new ();
447     }
448
449     GST_BUFFER_TIMESTAMP (outbuf) =
450         gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND,
451         OMX_TICKS_PER_SECOND);
452     if (buf->omx_buf->nTickCount != 0)
453       GST_BUFFER_DURATION (outbuf) =
454           gst_util_uint64_scale (buf->omx_buf->nTickCount, GST_SECOND,
455           OMX_TICKS_PER_SECOND);
456
457     flow_ret =
458         gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (self),
459         outbuf, n_samples);
460   }
461
462   GST_DEBUG_OBJECT (self, "Handled output data");
463
464   GST_DEBUG_OBJECT (self, "Finished frame: %s", gst_flow_get_name (flow_ret));
465
466   err = gst_omx_port_release_buffer (port, buf);
467   if (err != OMX_ErrorNone)
468     goto release_error;
469
470   self->downstream_flow_ret = flow_ret;
471
472   if (flow_ret != GST_FLOW_OK)
473     goto flow_error;
474
475   GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
476
477   return;
478
479 component_error:
480   {
481     GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
482         ("OpenMAX component in error state %s (0x%08x)",
483             gst_omx_component_get_last_error_string (self->enc),
484             gst_omx_component_get_last_error (self->enc)));
485     gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
486     gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
487     self->downstream_flow_ret = GST_FLOW_ERROR;
488     self->started = FALSE;
489     return;
490   }
491 flushing:
492   {
493     GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
494     g_mutex_lock (&self->drain_lock);
495     if (self->draining) {
496       self->draining = FALSE;
497       g_cond_broadcast (&self->drain_cond);
498     }
499     gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
500     self->downstream_flow_ret = GST_FLOW_FLUSHING;
501     self->started = FALSE;
502     g_mutex_unlock (&self->drain_lock);
503     return;
504   }
505 eos:
506   {
507     g_mutex_lock (&self->drain_lock);
508     if (self->draining) {
509       GST_DEBUG_OBJECT (self, "Drained");
510       self->draining = FALSE;
511       g_cond_broadcast (&self->drain_cond);
512       flow_ret = GST_FLOW_OK;
513       gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
514     } else {
515       GST_DEBUG_OBJECT (self, "Component signalled EOS");
516       flow_ret = GST_FLOW_EOS;
517     }
518     g_mutex_unlock (&self->drain_lock);
519
520     GST_AUDIO_ENCODER_STREAM_LOCK (self);
521     self->downstream_flow_ret = flow_ret;
522
523     /* Here we fallback and pause the task for the EOS case */
524     if (flow_ret != GST_FLOW_OK)
525       goto flow_error;
526
527     GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
528
529     return;
530   }
531 flow_error:
532   {
533     if (flow_ret == GST_FLOW_EOS) {
534       GST_DEBUG_OBJECT (self, "EOS");
535
536       gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (self),
537           gst_event_new_eos ());
538       gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
539       self->started = FALSE;
540     } else if (flow_ret < GST_FLOW_EOS) {
541       GST_ELEMENT_ERROR (self, STREAM, FAILED, ("Internal data stream error."),
542           ("stream stopped, reason %s", gst_flow_get_name (flow_ret)));
543
544       gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (self),
545           gst_event_new_eos ());
546       gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
547       self->started = FALSE;
548     } else if (flow_ret == GST_FLOW_FLUSHING) {
549       GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
550       g_mutex_lock (&self->drain_lock);
551       if (self->draining) {
552         self->draining = FALSE;
553         g_cond_broadcast (&self->drain_cond);
554       }
555       gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
556       self->started = FALSE;
557       g_mutex_unlock (&self->drain_lock);
558     }
559     GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
560     return;
561   }
562 reconfigure_error:
563   {
564     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
565         ("Unable to reconfigure output port"));
566     gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
567     gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
568     self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
569     self->started = FALSE;
570     return;
571   }
572 caps_failed:
573   {
574     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), ("Failed to set caps"));
575     gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
576     gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
577     self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
578     self->started = FALSE;
579     return;
580   }
581 release_error:
582   {
583     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
584         ("Failed to relase output buffer to component: %s (0x%08x)",
585             gst_omx_error_to_string (err), err));
586     gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
587     gst_pad_pause_task (GST_AUDIO_ENCODER_SRC_PAD (self));
588     self->downstream_flow_ret = GST_FLOW_ERROR;
589     self->started = FALSE;
590     GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
591     return;
592   }
593 }
594
595 static gboolean
596 gst_omx_audio_enc_start (GstAudioEncoder * encoder)
597 {
598   GstOMXAudioEnc *self;
599
600   self = GST_OMX_AUDIO_ENC (encoder);
601
602   self->last_upstream_ts = 0;
603   self->downstream_flow_ret = GST_FLOW_OK;
604
605   return TRUE;
606 }
607
608 static gboolean
609 gst_omx_audio_enc_stop (GstAudioEncoder * encoder)
610 {
611   GstOMXAudioEnc *self;
612
613   self = GST_OMX_AUDIO_ENC (encoder);
614
615   GST_DEBUG_OBJECT (self, "Stopping encoder");
616
617   gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, TRUE);
618   gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, TRUE);
619
620   gst_pad_stop_task (GST_AUDIO_ENCODER_SRC_PAD (encoder));
621
622   if (gst_omx_component_get_state (self->enc, 0) > OMX_StateIdle)
623     gst_omx_component_set_state (self->enc, OMX_StateIdle);
624
625   self->downstream_flow_ret = GST_FLOW_FLUSHING;
626   self->started = FALSE;
627
628   g_mutex_lock (&self->drain_lock);
629   self->draining = FALSE;
630   g_cond_broadcast (&self->drain_cond);
631   g_mutex_unlock (&self->drain_lock);
632
633   gst_omx_component_get_state (self->enc, 5 * GST_SECOND);
634
635   return TRUE;
636 }
637
638 static gboolean
639 gst_omx_audio_enc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
640 {
641   GstOMXAudioEnc *self;
642   GstOMXAudioEncClass *klass;
643   gboolean needs_disable = FALSE;
644   OMX_PARAM_PORTDEFINITIONTYPE port_def;
645   OMX_AUDIO_PARAM_PCMMODETYPE pcm_param;
646   gint i;
647   OMX_ERRORTYPE err;
648
649   self = GST_OMX_AUDIO_ENC (encoder);
650   klass = GST_OMX_AUDIO_ENC_GET_CLASS (encoder);
651
652   GST_DEBUG_OBJECT (self, "Setting new caps");
653
654   /* Set audio encoder base class properties */
655   gst_audio_encoder_set_frame_samples_min (encoder,
656       gst_util_uint64_scale_ceil (OMX_MIN_PCMPAYLOAD_MSEC,
657           GST_MSECOND * info->rate, GST_SECOND));
658   gst_audio_encoder_set_frame_samples_max (encoder, 0);
659
660   gst_omx_port_get_port_definition (self->enc_in_port, &port_def);
661
662   needs_disable =
663       gst_omx_component_get_state (self->enc,
664       GST_CLOCK_TIME_NONE) != OMX_StateLoaded;
665   /* If the component is not in Loaded state and a real format change happens
666    * we have to disable the port and re-allocate all buffers. If no real
667    * format change happened we can just exit here.
668    */
669   if (needs_disable) {
670     GST_DEBUG_OBJECT (self, "Need to disable and drain encoder");
671     gst_omx_audio_enc_drain (self);
672     gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, TRUE);
673
674     /* Wait until the srcpad loop is finished,
675      * unlock GST_AUDIO_ENCODER_STREAM_LOCK to prevent deadlocks
676      * caused by using this lock from inside the loop function */
677     GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
678     gst_pad_stop_task (GST_AUDIO_ENCODER_SRC_PAD (encoder));
679     GST_AUDIO_ENCODER_STREAM_LOCK (self);
680
681     if (klass->cdata.hacks & GST_OMX_HACK_NO_COMPONENT_RECONFIGURE) {
682       GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
683       gst_omx_audio_enc_stop (GST_AUDIO_ENCODER (self));
684       gst_omx_audio_enc_close (GST_AUDIO_ENCODER (self));
685       GST_AUDIO_ENCODER_STREAM_LOCK (self);
686
687       if (!gst_omx_audio_enc_open (GST_AUDIO_ENCODER (self)))
688         return FALSE;
689       needs_disable = FALSE;
690     } else {
691       if (gst_omx_port_set_enabled (self->enc_in_port, FALSE) != OMX_ErrorNone)
692         return FALSE;
693       if (gst_omx_port_set_enabled (self->enc_out_port, FALSE) != OMX_ErrorNone)
694         return FALSE;
695       if (gst_omx_port_wait_buffers_released (self->enc_in_port,
696               5 * GST_SECOND) != OMX_ErrorNone)
697         return FALSE;
698       if (gst_omx_port_wait_buffers_released (self->enc_out_port,
699               1 * GST_SECOND) != OMX_ErrorNone)
700         return FALSE;
701       if (gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone)
702         return FALSE;
703       if (gst_omx_port_deallocate_buffers (self->enc_out_port) != OMX_ErrorNone)
704         return FALSE;
705       if (gst_omx_port_wait_enabled (self->enc_in_port,
706               1 * GST_SECOND) != OMX_ErrorNone)
707         return FALSE;
708       if (gst_omx_port_wait_enabled (self->enc_out_port,
709               1 * GST_SECOND) != OMX_ErrorNone)
710         return FALSE;
711     }
712
713     GST_DEBUG_OBJECT (self, "Encoder drained and disabled");
714   }
715
716   port_def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
717   GST_DEBUG_OBJECT (self, "Setting inport port definition");
718   if (gst_omx_port_update_port_definition (self->enc_in_port,
719           &port_def) != OMX_ErrorNone)
720     return FALSE;
721
722   GST_OMX_INIT_STRUCT (&pcm_param);
723   pcm_param.nPortIndex = self->enc_in_port->index;
724   pcm_param.nChannels = info->channels;
725   pcm_param.eNumData =
726       ((info->finfo->flags & GST_AUDIO_FORMAT_FLAG_SIGNED) ?
727       OMX_NumericalDataSigned : OMX_NumericalDataUnsigned);
728   pcm_param.eEndian =
729       ((info->finfo->endianness == G_LITTLE_ENDIAN) ?
730       OMX_EndianLittle : OMX_EndianBig);
731   pcm_param.bInterleaved = OMX_TRUE;
732   pcm_param.nBitPerSample = info->finfo->width;
733   pcm_param.nSamplingRate = info->rate;
734   pcm_param.ePCMMode = OMX_AUDIO_PCMModeLinear;
735
736   for (i = 0; i < pcm_param.nChannels; i++) {
737     OMX_AUDIO_CHANNELTYPE pos;
738
739     switch (info->position[i]) {
740       case GST_AUDIO_CHANNEL_POSITION_MONO:
741       case GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER:
742         pos = OMX_AUDIO_ChannelCF;
743         break;
744       case GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT:
745         pos = OMX_AUDIO_ChannelLF;
746         break;
747       case GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT:
748         pos = OMX_AUDIO_ChannelRF;
749         break;
750       case GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT:
751         pos = OMX_AUDIO_ChannelLS;
752         break;
753       case GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT:
754         pos = OMX_AUDIO_ChannelRS;
755         break;
756       case GST_AUDIO_CHANNEL_POSITION_LFE1:
757         pos = OMX_AUDIO_ChannelLFE;
758         break;
759       case GST_AUDIO_CHANNEL_POSITION_REAR_CENTER:
760         pos = OMX_AUDIO_ChannelCS;
761         break;
762       case GST_AUDIO_CHANNEL_POSITION_REAR_LEFT:
763         pos = OMX_AUDIO_ChannelLR;
764         break;
765       case GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT:
766         pos = OMX_AUDIO_ChannelRR;
767         break;
768       default:
769         pos = OMX_AUDIO_ChannelNone;
770         break;
771     }
772     pcm_param.eChannelMapping[i] = pos;
773   }
774
775   GST_DEBUG_OBJECT (self, "Setting PCM parameters");
776   err =
777       gst_omx_component_set_parameter (self->enc, OMX_IndexParamAudioPcm,
778       &pcm_param);
779   if (err != OMX_ErrorNone) {
780     GST_ERROR_OBJECT (self, "Failed to set PCM parameters: %s (0x%08x)",
781         gst_omx_error_to_string (err), err);
782     return FALSE;
783   }
784
785   if (klass->set_format) {
786     if (!klass->set_format (self, self->enc_in_port, info)) {
787       GST_ERROR_OBJECT (self, "Subclass failed to set the new format");
788       return FALSE;
789     }
790   }
791
792   GST_DEBUG_OBJECT (self, "Updating outport port definition");
793   if (gst_omx_port_update_port_definition (self->enc_out_port,
794           NULL) != OMX_ErrorNone)
795     return FALSE;
796
797   GST_DEBUG_OBJECT (self, "Enabling component");
798   if (needs_disable) {
799     if (gst_omx_port_set_enabled (self->enc_in_port, TRUE) != OMX_ErrorNone)
800       return FALSE;
801     if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone)
802       return FALSE;
803
804     if ((klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
805       if (gst_omx_port_set_enabled (self->enc_out_port, TRUE) != OMX_ErrorNone)
806         return FALSE;
807       if (gst_omx_port_allocate_buffers (self->enc_out_port) != OMX_ErrorNone)
808         return FALSE;
809
810       if (gst_omx_port_wait_enabled (self->enc_out_port,
811               5 * GST_SECOND) != OMX_ErrorNone)
812         return FALSE;
813     }
814
815     if (gst_omx_port_wait_enabled (self->enc_in_port,
816             5 * GST_SECOND) != OMX_ErrorNone)
817       return FALSE;
818     if (gst_omx_port_mark_reconfigured (self->enc_in_port) != OMX_ErrorNone)
819       return FALSE;
820   } else {
821     if (!(klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
822       /* Disable output port */
823       if (gst_omx_port_set_enabled (self->enc_out_port, FALSE) != OMX_ErrorNone)
824         return FALSE;
825
826       if (gst_omx_port_wait_enabled (self->enc_out_port,
827               1 * GST_SECOND) != OMX_ErrorNone)
828         return FALSE;
829
830       if (gst_omx_component_set_state (self->enc,
831               OMX_StateIdle) != OMX_ErrorNone)
832         return FALSE;
833
834       /* Need to allocate buffers to reach Idle state */
835       if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone)
836         return FALSE;
837     } else {
838       if (gst_omx_component_set_state (self->enc,
839               OMX_StateIdle) != OMX_ErrorNone)
840         return FALSE;
841
842       /* Need to allocate buffers to reach Idle state */
843       if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone)
844         return FALSE;
845       if (gst_omx_port_allocate_buffers (self->enc_out_port) != OMX_ErrorNone)
846         return FALSE;
847     }
848
849     if (gst_omx_component_get_state (self->enc,
850             GST_CLOCK_TIME_NONE) != OMX_StateIdle)
851       return FALSE;
852
853     if (gst_omx_component_set_state (self->enc,
854             OMX_StateExecuting) != OMX_ErrorNone)
855       return FALSE;
856
857     if (gst_omx_component_get_state (self->enc,
858             GST_CLOCK_TIME_NONE) != OMX_StateExecuting)
859       return FALSE;
860   }
861
862   /* Unset flushing to allow ports to accept data again */
863   gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, FALSE);
864   gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, FALSE);
865
866   if (gst_omx_component_get_last_error (self->enc) != OMX_ErrorNone) {
867     GST_ERROR_OBJECT (self, "Component in error state: %s (0x%08x)",
868         gst_omx_component_get_last_error_string (self->enc),
869         gst_omx_component_get_last_error (self->enc));
870     return FALSE;
871   }
872
873   /* Start the srcpad loop again */
874   GST_DEBUG_OBJECT (self, "Starting task again");
875   self->downstream_flow_ret = GST_FLOW_OK;
876   gst_pad_start_task (GST_AUDIO_ENCODER_SRC_PAD (self),
877       (GstTaskFunction) gst_omx_audio_enc_loop, encoder, NULL);
878
879   return TRUE;
880 }
881
882 static void
883 gst_omx_audio_enc_flush (GstAudioEncoder * encoder)
884 {
885   GstOMXAudioEnc *self;
886
887   self = GST_OMX_AUDIO_ENC (encoder);
888
889   GST_DEBUG_OBJECT (self, "Resetting encoder");
890
891   gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, TRUE);
892   gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, TRUE);
893
894   /* Wait until the srcpad loop is finished */
895   GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
896   GST_PAD_STREAM_LOCK (GST_AUDIO_ENCODER_SRC_PAD (self));
897   GST_PAD_STREAM_UNLOCK (GST_AUDIO_ENCODER_SRC_PAD (self));
898   GST_AUDIO_ENCODER_STREAM_LOCK (self);
899
900   gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, FALSE);
901   gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, FALSE);
902   gst_omx_port_populate (self->enc_out_port);
903
904   /* Start the srcpad loop again */
905   self->last_upstream_ts = 0;
906   self->downstream_flow_ret = GST_FLOW_OK;
907   self->started = FALSE;
908   gst_pad_start_task (GST_AUDIO_ENCODER_SRC_PAD (self),
909       (GstTaskFunction) gst_omx_audio_enc_loop, encoder, NULL);
910 }
911
912 static GstFlowReturn
913 gst_omx_audio_enc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
914 {
915   GstOMXAcquireBufferReturn acq_ret = GST_OMX_ACQUIRE_BUFFER_ERROR;
916   GstOMXAudioEnc *self;
917   GstOMXPort *port;
918   GstOMXBuffer *buf;
919   gsize size;
920   guint offset = 0;
921   GstClockTime timestamp, duration, timestamp_offset = 0;
922   OMX_ERRORTYPE err;
923
924   self = GST_OMX_AUDIO_ENC (encoder);
925
926   if (self->downstream_flow_ret != GST_FLOW_OK) {
927     return self->downstream_flow_ret;
928   }
929
930   if (inbuf == NULL)
931     return gst_omx_audio_enc_drain (self);
932
933   GST_DEBUG_OBJECT (self, "Handling frame");
934
935   timestamp = GST_BUFFER_TIMESTAMP (inbuf);
936   duration = GST_BUFFER_DURATION (inbuf);
937
938   port = self->enc_in_port;
939
940   size = gst_buffer_get_size (inbuf);
941   while (offset < size) {
942     /* Make sure to release the base class stream lock, otherwise
943      * _loop() can't call _finish_frame() and we might block forever
944      * because no input buffers are released */
945     GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
946     acq_ret = gst_omx_port_acquire_buffer (port, &buf);
947
948     if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) {
949       GST_AUDIO_ENCODER_STREAM_LOCK (self);
950       goto component_error;
951     } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
952       GST_AUDIO_ENCODER_STREAM_LOCK (self);
953       goto flushing;
954     } else if (acq_ret == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
955       /* Reallocate all buffers */
956       err = gst_omx_port_set_enabled (port, FALSE);
957       if (err != OMX_ErrorNone) {
958         GST_AUDIO_ENCODER_STREAM_LOCK (self);
959         goto reconfigure_error;
960       }
961
962       err = gst_omx_port_wait_buffers_released (port, 5 * GST_SECOND);
963       if (err != OMX_ErrorNone) {
964         GST_AUDIO_ENCODER_STREAM_LOCK (self);
965         goto reconfigure_error;
966       }
967
968       err = gst_omx_port_deallocate_buffers (port);
969       if (err != OMX_ErrorNone) {
970         GST_AUDIO_ENCODER_STREAM_LOCK (self);
971         goto reconfigure_error;
972       }
973
974       err = gst_omx_port_wait_enabled (port, 1 * GST_SECOND);
975       if (err != OMX_ErrorNone) {
976         GST_AUDIO_ENCODER_STREAM_LOCK (self);
977         goto reconfigure_error;
978       }
979
980       err = gst_omx_port_set_enabled (port, TRUE);
981       if (err != OMX_ErrorNone) {
982         GST_AUDIO_ENCODER_STREAM_LOCK (self);
983         goto reconfigure_error;
984       }
985
986       err = gst_omx_port_allocate_buffers (port);
987       if (err != OMX_ErrorNone) {
988         GST_AUDIO_ENCODER_STREAM_LOCK (self);
989         goto reconfigure_error;
990       }
991
992       err = gst_omx_port_wait_enabled (port, 5 * GST_SECOND);
993       if (err != OMX_ErrorNone) {
994         GST_AUDIO_ENCODER_STREAM_LOCK (self);
995         goto reconfigure_error;
996       }
997
998       err = gst_omx_port_mark_reconfigured (port);
999       if (err != OMX_ErrorNone) {
1000         GST_AUDIO_ENCODER_STREAM_LOCK (self);
1001         goto reconfigure_error;
1002       }
1003
1004       /* Now get a new buffer and fill it */
1005       GST_AUDIO_ENCODER_STREAM_LOCK (self);
1006       continue;
1007     }
1008     GST_AUDIO_ENCODER_STREAM_LOCK (self);
1009
1010     g_assert (acq_ret == GST_OMX_ACQUIRE_BUFFER_OK && buf != NULL);
1011
1012     if (self->downstream_flow_ret != GST_FLOW_OK) {
1013       gst_omx_port_release_buffer (port, buf);
1014       return self->downstream_flow_ret;
1015     }
1016
1017     if (buf->omx_buf->nAllocLen - buf->omx_buf->nOffset <= 0) {
1018       gst_omx_port_release_buffer (port, buf);
1019       goto full_buffer;
1020     }
1021
1022     GST_DEBUG_OBJECT (self, "Handling frame at offset %d", offset);
1023
1024     /* Copy the buffer content in chunks of size as requested
1025      * by the port */
1026     buf->omx_buf->nFilledLen =
1027         MIN (size - offset, buf->omx_buf->nAllocLen - buf->omx_buf->nOffset);
1028     gst_buffer_extract (inbuf, offset,
1029         buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
1030         buf->omx_buf->nFilledLen);
1031
1032     /* Interpolate timestamps if we're passing the buffer
1033      * in multiple chunks */
1034     if (offset != 0 && duration != GST_CLOCK_TIME_NONE) {
1035       timestamp_offset = gst_util_uint64_scale (offset, duration, size);
1036     }
1037
1038     if (timestamp != GST_CLOCK_TIME_NONE) {
1039       buf->omx_buf->nTimeStamp =
1040           gst_util_uint64_scale (timestamp + timestamp_offset,
1041           OMX_TICKS_PER_SECOND, GST_SECOND);
1042       self->last_upstream_ts = timestamp + timestamp_offset;
1043     }
1044     if (duration != GST_CLOCK_TIME_NONE) {
1045       buf->omx_buf->nTickCount =
1046           gst_util_uint64_scale (buf->omx_buf->nFilledLen, duration, size);
1047       buf->omx_buf->nTickCount =
1048           gst_util_uint64_scale (buf->omx_buf->nTickCount,
1049           OMX_TICKS_PER_SECOND, GST_SECOND);
1050       self->last_upstream_ts += duration;
1051     }
1052
1053     offset += buf->omx_buf->nFilledLen;
1054     self->started = TRUE;
1055     err = gst_omx_port_release_buffer (port, buf);
1056     if (err != OMX_ErrorNone)
1057       goto release_error;
1058   }
1059
1060   GST_DEBUG_OBJECT (self, "Passed frame to component");
1061
1062   return self->downstream_flow_ret;
1063
1064 full_buffer:
1065   {
1066     GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
1067         ("Got OpenMAX buffer with no free space (%p, %u/%u)", buf,
1068             (guint) buf->omx_buf->nOffset, (guint) buf->omx_buf->nAllocLen));
1069     return GST_FLOW_ERROR;
1070   }
1071 component_error:
1072   {
1073     GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
1074         ("OpenMAX component in error state %s (0x%08x)",
1075             gst_omx_component_get_last_error_string (self->enc),
1076             gst_omx_component_get_last_error (self->enc)));
1077     return GST_FLOW_ERROR;
1078   }
1079
1080 flushing:
1081   {
1082     GST_DEBUG_OBJECT (self, "Flushing -- returning FLUSHING");
1083     return GST_FLOW_FLUSHING;
1084   }
1085 reconfigure_error:
1086   {
1087     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
1088         ("Unable to reconfigure input port"));
1089     return GST_FLOW_ERROR;
1090   }
1091 release_error:
1092   {
1093     GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
1094         ("Failed to relase input buffer to component: %s (0x%08x)",
1095             gst_omx_error_to_string (err), err));
1096     return GST_FLOW_ERROR;
1097   }
1098 }
1099
1100 static GstFlowReturn
1101 gst_omx_audio_enc_drain (GstOMXAudioEnc * self)
1102 {
1103   GstOMXAudioEncClass *klass;
1104   GstOMXBuffer *buf;
1105   GstOMXAcquireBufferReturn acq_ret;
1106   OMX_ERRORTYPE err;
1107
1108   GST_DEBUG_OBJECT (self, "Draining component");
1109
1110   klass = GST_OMX_AUDIO_ENC_GET_CLASS (self);
1111
1112   if (!self->started) {
1113     GST_DEBUG_OBJECT (self, "Component not started yet");
1114     return GST_FLOW_OK;
1115   }
1116   self->started = FALSE;
1117
1118   if ((klass->cdata.hacks & GST_OMX_HACK_NO_EMPTY_EOS_BUFFER)) {
1119     GST_WARNING_OBJECT (self, "Component does not support empty EOS buffers");
1120     return GST_FLOW_OK;
1121   }
1122
1123   /* Make sure to release the base class stream lock, otherwise
1124    * _loop() can't call _finish_frame() and we might block forever
1125    * because no input buffers are released */
1126   GST_AUDIO_ENCODER_STREAM_UNLOCK (self);
1127
1128   /* Send an EOS buffer to the component and let the base
1129    * class drop the EOS event. We will send it later when
1130    * the EOS buffer arrives on the output port. */
1131   acq_ret = gst_omx_port_acquire_buffer (self->enc_in_port, &buf);
1132   if (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) {
1133     GST_AUDIO_ENCODER_STREAM_LOCK (self);
1134     GST_ERROR_OBJECT (self, "Failed to acquire buffer for draining: %d",
1135         acq_ret);
1136     return GST_FLOW_ERROR;
1137   }
1138
1139   g_mutex_lock (&self->drain_lock);
1140   self->draining = TRUE;
1141   buf->omx_buf->nFilledLen = 0;
1142   buf->omx_buf->nTimeStamp =
1143       gst_util_uint64_scale (self->last_upstream_ts, OMX_TICKS_PER_SECOND,
1144       GST_SECOND);
1145   buf->omx_buf->nTickCount = 0;
1146   buf->omx_buf->nFlags |= OMX_BUFFERFLAG_EOS;
1147   err = gst_omx_port_release_buffer (self->enc_in_port, buf);
1148   if (err != OMX_ErrorNone) {
1149     GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)",
1150         gst_omx_error_to_string (err), err);
1151     GST_AUDIO_ENCODER_STREAM_LOCK (self);
1152     return GST_FLOW_ERROR;
1153   }
1154   GST_DEBUG_OBJECT (self, "Waiting until component is drained");
1155   g_cond_wait (&self->drain_cond, &self->drain_lock);
1156   GST_DEBUG_OBJECT (self, "Drained component");
1157   g_mutex_unlock (&self->drain_lock);
1158   GST_AUDIO_ENCODER_STREAM_LOCK (self);
1159
1160   self->started = FALSE;
1161
1162   return GST_FLOW_OK;
1163 }