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