Пример #1
0
static void
goo_engine_chain (GooEngine* self)
{
    g_assert (GOO_IS_ENGINE (self));
    g_assert (GOO_IS_COMPONENT (self->component));

    gboolean input_processed = FALSE;
    OMX_BUFFERHEADERTYPE* buffer = NULL;

    while (!input_processed && !goo_component_is_done (self->component))
    {
        /* OUTPUT PROCESSING */
        if (G_LIKELY (self->outport) &&
                !goo_port_is_tunneled (self->outport) &&
                !goo_port_is_eos (self->outport))
        {
            while ((buffer =
                        goo_port_try_grab_buffer (self->outport))
                    != NULL)
            {
                GOO_OBJECT_DEBUG (self,
                                  "popt output buffer: 0x%x",
                                  buffer);

                goo_port_process_buffer (self->outport,
                                         buffer,
                                         self->component);

                goo_component_release_buffer (self->component,
                                              buffer);
            }

        }

        /* INPUT PROCESSING */
        if (G_LIKELY (self->inport) &&
                !goo_port_is_tunneled (self->inport) &&
                !goo_port_is_eos (self->inport))
        {

            if ((buffer = goo_port_try_grab_buffer (self->inport))
                    != NULL)
            {
                GOO_OBJECT_DEBUG (self,
                                  "popt input buffer: 0x%x",
                                  buffer);
                goo_port_process_buffer (self->inport, buffer,
                                         self);
                goo_component_release_buffer (self->component,
                                              buffer);
                input_processed = TRUE;
            }
        }
    }

    return;
}
Пример #2
0
static void
goo_engine_process_input (GooEngine* self)
{
    g_assert (GOO_IS_ENGINE (self));
    g_assert (GOO_IS_COMPONENT (self->component));

    g_return_if_fail (G_LIKELY (self->inport));

    if (goo_port_is_tunneled (self->inport) ||
            goo_port_is_eos (self->inport))
    {
        return;
    }

    OMX_BUFFERHEADERTYPE* buffer = NULL;

    buffer = goo_port_grab_buffer (self->inport);

    GOO_OBJECT_DEBUG (self, "popt input buffer: 0x%x", buffer);

    goo_engine_inport_cb (self->inport, buffer, self->component);
    /* goo_port_process_buffer (self->inport, buffer, self); */

    g_atomic_int_inc (&self->incount);

    goo_component_release_buffer (self->component, buffer);

    return;
}
Пример #3
0
static void
goo_engine_outport_cb (GooPort* port, OMX_BUFFERHEADERTYPE* buffer,
                       gpointer data)
{
    g_assert (GOO_IS_PORT (port));
    g_assert (buffer != NULL);
    g_assert (GOO_IS_COMPONENT (data));

    GooComponent* component = GOO_COMPONENT (data);
    GooEngine* self = GOO_ENGINE (
                          g_object_get_data (G_OBJECT (component), "engine")
                      );

    g_assert (self->outstream != NULL);

    if (buffer->nFilledLen <= 0 &&
            (buffer->nFlags & OMX_BUFFERFLAG_EOS) != 0x1)
    {
        GOO_OBJECT_ERROR (self, "Empty buffer received!!");
    }

    if (buffer->nFilledLen > 0)
    {
        GOO_OBJECT_DEBUG (self, "%d bytes written",
                          buffer->nFilledLen);
        fwrite (buffer->pBuffer, 1, buffer->nFilledLen,
                self->outstream);
        /* fflush (self->outfile); */
    }

    /* we count the empty buffer only if it have de EOS flag */
    if ((buffer->nFilledLen > 0) ||
            ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0x1 &&
             buffer->nFilledLen == 0))
    {
        g_atomic_int_inc (&self->outcount);
    }

    /* if we assigned the number of buffer to process */
    if (self->numbuffers != 0 && self->outcount == self->numbuffers)
    {
        goo_port_set_eos (port);
    }

    if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0x1 ||
            goo_port_is_eos (port))
    {
        goo_component_set_done (self->component);
    }

    goo_component_release_buffer (component, buffer);

    return;
}
Пример #4
0
static GstFlowReturn
process_output_buffer (GstGooEncPcm* self, OMX_BUFFERHEADERTYPE* buffer)
{
	GstBuffer* out = NULL;
	GstFlowReturn ret = GST_FLOW_ERROR;

	if (buffer->nFilledLen <= 0)
	{
		GST_INFO_OBJECT (self, "Received an empty buffer!");
		goo_component_release_buffer (self->component, buffer);
		return;
	}

	GST_DEBUG_OBJECT (self, "outcount = %d", self->outcount);
	out = gst_buffer_new_and_alloc (buffer->nFilledLen);
	g_assert (out != NULL);
	memmove (GST_BUFFER_DATA (out),
			buffer->pBuffer, buffer->nFilledLen);
	goo_component_release_buffer (self->component, buffer);

	if (out != NULL)
	{
		GST_BUFFER_DURATION (out) = self->duration;
		GST_BUFFER_OFFSET (out) = self->outcount++;
		GST_BUFFER_TIMESTAMP (out) = self->ts;
		if (self->ts != -1)
		{
			self->ts += self->duration;
		}

		gst_buffer_set_caps (out, GST_PAD_CAPS (self->srcpad));

		GST_DEBUG_OBJECT (self, "pushing gst buffer");
		ret = gst_pad_push (self->srcpad, out);
	}

	GST_INFO_OBJECT (self, "");

	return ret;
}
Пример #5
0
static void
gst_goo_buffer_finalize (GstGooBuffer* buffer)
{
	g_return_if_fail (buffer != NULL);

	GST_CAT_LOG (GST_CAT_BUFFER, "GooBuffer released %p", buffer);

	OMX_BUFFERHEADERTYPE* omx_buffer;
	GooComponent* component;

	omx_buffer = buffer->omx_buffer;
	component = buffer->component;

	goo_component_release_buffer (component, omx_buffer);

	g_object_unref (component);

	gst_caps_replace (&GST_BUFFER_CAPS (buffer), NULL);
}
Пример #6
0
static void
omx_output_buffer_cb (GooPort* port,
		      OMX_BUFFERHEADERTYPE* buffer,
		      gpointer data)
{
	g_return_if_fail (buffer->nFlags != OMX_BUFFERFLAG_DATACORRUPT);

	g_assert (GOO_IS_PORT (port));
	g_assert (buffer != NULL);
	g_assert (GOO_IS_COMPONENT (data));

	GooComponent* component = GOO_COMPONENT (data);
	GstGooEncArmAac* self = GST_GOO_ENCARMAAC (
		g_object_get_data (G_OBJECT (data), "gst")
		);
	g_assert (self != NULL);

	{
		if (buffer->nFilledLen <= 0)
		{
			GST_INFO_OBJECT (self, "Received an empty buffer!");
			goo_component_release_buffer (self->component, buffer);
		}
		else
		{
			process_output_buffer (self, buffer);
		}

		if (buffer->nFlags & OMX_BUFFERFLAG_EOS == 0x1 ||
		    goo_port_is_eos (port))
		{
			GST_INFO_OBJECT (self,
					 "EOS found in output buffer (%d)",
					 buffer->nFilledLen);
			goo_component_set_done (self->component);
		}
	}

	GST_DEBUG_OBJECT (self, "");

	return;
}
Пример #7
0
static GstFlowReturn
gst_goo_encpcm_chain (GstPad* pad, GstBuffer* buffer)
{
	GstGooEncPcm* self = GST_GOO_ENCPCM (gst_pad_get_parent (pad));
	guint omxbufsiz = GOO_PORT_GET_DEFINITION (self->inport)->nBufferSize;
	GstFlowReturn ret;

	if (self->rate == 0 || self->channels == 0 ||
	    self->component->cur_state != OMX_StateExecuting)
	{
		goto not_negotiated;
	}

	if (goo_port_is_tunneled (self->inport))
	{
		GST_DEBUG_OBJECT (self, "DASF Source");
		OMX_BUFFERHEADERTYPE* omxbuf = NULL;
		omxbuf = goo_port_grab_buffer (self->outport);
		ret = process_output_buffer (self, omxbuf);
		return ret;
	}

	/* discontinuity clears adapter, FIXME, maybe we can set some
	 * encoder flag to mask the discont. */
	if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))
	{
		gst_goo_adapter_clear (self->adapter);
		self->ts = 0;
	}

	/* take latest timestamp, FIXME timestamp is the one of the
	 * first buffer in the adapter. */
	if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
	{
		self->ts = GST_BUFFER_TIMESTAMP (buffer);
	}

	ret = GST_FLOW_OK;
	GST_DEBUG_OBJECT (self, "Pushing a GST buffer to adapter (%d)",
			  GST_BUFFER_SIZE (buffer));
	gst_goo_adapter_push (self->adapter, buffer);

	/* Collect samples until we have enough for an output frame */
	while (gst_goo_adapter_available (self->adapter) >= omxbufsiz)
	{
		GST_DEBUG_OBJECT (self, "Popping an OMX buffer");
		OMX_BUFFERHEADERTYPE* omxbuf;
		omxbuf = goo_port_grab_buffer (self->inport);
		gst_goo_adapter_peek (self->adapter, omxbufsiz, omxbuf);
		omxbuf->nFilledLen = omxbufsiz;
		gst_goo_adapter_flush (self->adapter, omxbufsiz);
		goo_component_release_buffer (self->component, omxbuf);
	}

	GST_DEBUG_OBJECT (self, "");
	return ret;

	/* ERRORS */
not_negotiated:
	{
		GST_ELEMENT_ERROR (self, STREAM, TYPE_NOT_FOUND,
				   (NULL), ("unknown type"));
		return GST_FLOW_NOT_NEGOTIATED;
	}
}
Пример #8
0
static GstFlowReturn
gst_dasf_src_create (GstAudioSrc *audiosrc,
						guint64 offset,
						guint length,
						GstBuffer **buffer)
{
	GstDasfSrc* self = GST_DASF_SRC (audiosrc);
	GstBaseAudioSrc *baseaudiosrc = GST_BASE_AUDIO_SRC (self);
	GstBuffer* gst_buffer = NULL;
	OMX_BUFFERHEADERTYPE* omx_buffer = NULL;
	GstDasfSrcPrivate* priv = GST_DASF_SRC_GET_PRIVATE (self);
	GstGooAudioFilter* me = self->peer_element;

	GST_DEBUG ("");

	if (me->component->cur_state != OMX_StateExecuting)
	{
		return GST_FLOW_UNEXPECTED;
	}

	GST_DEBUG ("goo stuff");
	{
		omx_buffer = goo_port_grab_buffer (me->outport);

		if (gst_pad_alloc_buffer (GST_BASE_SRC_PAD (self),
					  priv->outcount,
					  omx_buffer->nFilledLen,
					  GST_PAD_CAPS (GST_BASE_SRC_PAD (self)),
					  &gst_buffer) == GST_FLOW_OK)
		{
			if (GST_IS_GOO_BUFFER (gst_buffer))
			{
				memcpy (GST_BUFFER_DATA (gst_buffer),
					omx_buffer->pBuffer,
					omx_buffer->nFilledLen);

				goo_component_release_buffer (me->component,
							      omx_buffer);
			}
			else
 			{
				gst_buffer_unref (gst_buffer);
				gst_buffer = (GstBuffer*) gst_goo_buffer_new ();
				gst_goo_buffer_set_data (gst_buffer,
							 me->component,
							 omx_buffer);
			}
		}
		else
		{
			goto fail;
		}
	}


	GST_DEBUG ("gst stuff");
	{
		GstClock* clock = NULL;
		GstClockTime timestamp, duration;
		clock = gst_element_get_clock (GST_ELEMENT (self));

		timestamp = gst_clock_get_time (clock);
		timestamp -= gst_element_get_base_time (GST_ELEMENT (self));
		gst_object_unref (clock);

		GST_BUFFER_TIMESTAMP (gst_buffer) = gst_util_uint64_scale_int (GST_SECOND, priv->outcount, 50);

		/* Set 20 millisecond duration */
		duration = gst_util_uint64_scale_int
			(GST_SECOND,
			 1,
			 50);

		GST_BUFFER_DURATION (gst_buffer) = duration;
		GST_BUFFER_OFFSET (gst_buffer) = priv->outcount++;
		GST_BUFFER_OFFSET_END (gst_buffer) = priv->outcount;

		gst_buffer_set_caps (gst_buffer,
		GST_PAD_CAPS (GST_BASE_SRC_PAD (self)));
	}

beach:
	*buffer = gst_buffer;
	return GST_FLOW_OK;

fail:
	if (G_LIKELY (*buffer))
	{
		gst_buffer_unref (*buffer);
	}

	return GST_FLOW_ERROR;
}
Пример #9
0
static GstFlowReturn
gst_goo_filter_chain (GstPad* pad, GstBuffer* buffer)
{
	GST_LOG ("");

	GstGooFilter* self = GST_GOO_FILTER (gst_pad_get_parent (pad));
	GstGooFilterPrivate* priv = GST_GOO_FILTER_GET_PRIVATE (self);
	GstGooAdapter* adapter = self->adapter;
	GstFlowReturn ret = GST_FLOW_OK;
	static OMX_S64 omx_normalize_timestamp;

	GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);

	if (priv->incount == 0)
	{
		omx_normalize_timestamp	= (gint64)timestamp / CONVERSION;
	}

	if (goo_port_is_tunneled (self->inport))
	{
		/* shall we send a ghost buffer here ? */
		GST_INFO ("port is tunneled");
		ret = GST_FLOW_OK;

		GST_DEBUG_OBJECT (self, "Buffer timestamp: time %" GST_TIME_FORMAT,
						GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));

		GST_DEBUG_OBJECT (self, "Buffer duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));

		GST_DEBUG_OBJECT (self, "Pushing buffer to next element. Size =%d", GST_BUFFER_SIZE (buffer));

		/** FIXME GStreamer should not insert the header.  OMX component should take
		 * care of it.	Remove this function upon resolution of DR OMAPS00140835 and
		 * OMAPS00140836 **/
 		priv->outcount++;
		buffer = gst_goo_filter_insert_header (self, buffer, priv->outcount);

		gst_buffer_set_caps (buffer, GST_PAD_CAPS (self->srcpad));
		gst_pad_push (self->srcpad, buffer);

		goto done;
	}

	if (goo_port_is_eos (self->inport))
	{
		GST_INFO ("port is eos");
		ret = GST_FLOW_UNEXPECTED;
		goto fail;
	}

	/** @todo GstGooAdapter! */
	if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
		gst_goo_adapter_clear (adapter);
	}

	if (priv->incount == 0 &&
	    goo_component_get_state (self->component) == OMX_StateLoaded)
	{

		/** Some filters require header processing,
			apended to the first buffer **/
		buffer = gst_goo_filter_codec_data_processing (self, GST_BUFFER (buffer));

		/** Todo: Use the gst_caps_fixatecaps_func to make
		    this cleaner **/
		if (!gst_goo_filter_check_fixed_src_caps (self))
			return GST_FLOW_NOT_NEGOTIATED;
		/** Remove gst_goo_filter_check_fixed_src_caps function when fixed **/

		g_object_set (self->inport,
				"buffercount",
				priv->num_input_buffers, NULL);
		g_object_set (self->outport,
				"buffercount",
				priv->num_output_buffers, NULL);

		GST_INFO ("going to idle");
		goo_component_set_state_idle (self->component);
		GST_INFO ("going to executing");
		goo_component_set_state_executing (self->component);

	}

	/** Function to perform post buffering processing **/
	buffer = gst_goo_filter_extra_buffer_processing (self, GST_BUFFER (buffer));

	gst_goo_adapter_push (adapter, buffer);

	if (self->component->cur_state != OMX_StateExecuting)
	{
		goto done;
	}

	int omxbufsiz;

	if (priv->process_mode == STREAMMODE)
		omxbufsiz = GOO_PORT_GET_DEFINITION (self->inport)->nBufferSize;
	else
		omxbufsiz = GST_BUFFER_SIZE (buffer);

	while (gst_goo_adapter_available (adapter) >= omxbufsiz &&
	       ret == GST_FLOW_OK && omxbufsiz != 0)
	{

		GST_DEBUG ("Adapter available =%d  omxbufsiz = %d", gst_goo_adapter_available (adapter), omxbufsiz);

		OMX_BUFFERHEADERTYPE* omx_buffer;
		omx_buffer = goo_port_grab_buffer (self->inport);
		GST_DEBUG ("memcpy to buffer %d bytes", omxbufsiz);
		gst_goo_adapter_peek (adapter, omxbufsiz, omx_buffer);
		omx_buffer->nFilledLen = omxbufsiz;
		gst_goo_adapter_flush (adapter, omxbufsiz);
		/* transfer timestamp to openmax */
		{

			GST_DEBUG_OBJECT (self, "checking timestamp: time %" GST_TIME_FORMAT,
					GST_TIME_ARGS (timestamp));

			if (GST_CLOCK_TIME_IS_VALID (timestamp))
			{
				gint64 buffer_ts = (gint64)timestamp;
				omx_buffer->nTimeStamp = (OMX_S64)buffer_ts / CONVERSION;
				omx_buffer->nTimeStamp = omx_buffer->nTimeStamp - omx_normalize_timestamp;

			} else GST_WARNING_OBJECT (self, "Invalid timestamp!");
		}

		priv->incount++;
		goo_component_release_buffer (self->component, omx_buffer);
		ret = GST_FLOW_OK;
	}

	if (goo_port_is_tunneled (self->outport))
	{
		/** @todo send a ghost buffer */
		GstBuffer *ghost_buffer = (GstBuffer*) gst_ghost_buffer_new ();
		GST_BUFFER_TIMESTAMP (ghost_buffer) = timestamp;
		gst_pad_push (self->srcpad, ghost_buffer);
	}

	goto done;

fail:
	gst_goo_adapter_clear (adapter);
done:
	gst_object_unref (self);
	gst_buffer_unref (buffer);
	return ret;
}
Пример #10
0
static void
gst_goo_filter_wait_for_done (GstGooFilter* self)
{
	g_assert (self != NULL);
	GstGooFilterPrivate* priv = GST_GOO_FILTER_GET_PRIVATE (self);

	/* flushing the last buffers in adapter */

	OMX_BUFFERHEADERTYPE* omx_buffer;
	OMX_PARAM_PORTDEFINITIONTYPE* param =
		GOO_PORT_GET_DEFINITION (self->inport);
	GstGooAdapter* adapter = self->adapter;
	int omxbufsiz = param->nBufferSize;
	int avail = gst_goo_adapter_available (adapter);

	if (goo_port_is_tunneled (self->inport))
	{
		GST_INFO ("Input port is tunneled: Setting done");
		goo_component_set_done (self->component);
		return;
	}


	if (avail < omxbufsiz && avail > 0)
	{
		GST_INFO ("Marking EOS buffer");
		omx_buffer = goo_port_grab_buffer (self->inport);
		GST_DEBUG ("Peek to buffer %d bytes", avail);
		gst_goo_adapter_peek (adapter, avail, omx_buffer);
		omx_buffer->nFilledLen = avail;
		/* let's send the EOS flag right now */
		omx_buffer->nFlags = OMX_BUFFERFLAG_EOS;
		/** @todo timestamp the buffers */
		priv->incount++;
		goo_component_release_buffer (self->component, omx_buffer);
	}
	else if (avail == 0)
	{
		GST_DEBUG ("Sending empty buffer with EOS flag in it");
		goo_component_send_eos (self->component);
	}
	else
	{
		/* For some reason the adapter didn't extract all
		   possible buffers */
		GST_ERROR ("Adapter algorithm error!");
		goo_component_send_eos (self->component);
	}

	gst_goo_adapter_clear (adapter);

	if (goo_port_is_tunneled (self->outport))
	{
		GST_INFO ("Outport is tunneled: Setting done");
		goo_component_set_done (self->component);
	}
	else
	{
		GST_INFO ("Waiting for done signal");
		goo_component_wait_for_done (self->component);
	}

	return;
}
Пример #11
0
static GstFlowReturn
gst_goo_encjpeg_chain (GstPad* pad, GstBuffer* buffer)
{
	GST_LOG ("");

	GstGooEncJpeg* self = GST_GOO_ENCJPEG (gst_pad_get_parent (pad));
	GstGooEncJpegPrivate* priv = GST_GOO_ENCJPEG_GET_PRIVATE (self);
	GstFlowReturn ret = GST_FLOW_OK;
	GstGooAdapter* adapter = self->adapter;
	OMX_BUFFERHEADERTYPE* omx_buffer = NULL;

	GstClockTime timestamp, duration;
	guint64 offset, offsetend;
	GstBuffer* outbuf = NULL;

	if (goo_port_is_tunneled (self->inport))
	{
		GST_INFO ("Inport is tunneled");
		ret = GST_FLOW_OK;
		priv->incount++;
		goto process_output;
	}

	if (goo_port_is_eos (self->inport))
	{
		GST_INFO ("port is eos");
		ret = GST_FLOW_UNEXPECTED;
		goto fail;
	}

	if (self->component->cur_state != OMX_StateExecuting)
	{
		goto fail;
	}

	/* let's copy the timestamp meta data */
	timestamp = GST_BUFFER_TIMESTAMP (buffer);
	duration  = GST_BUFFER_DURATION (buffer);
	offset	  = GST_BUFFER_OFFSET (buffer);
	offsetend = GST_BUFFER_OFFSET_END (buffer);

	if (GST_IS_GOO_BUFFER (buffer) &&
	    goo_port_is_my_buffer (self->inport,
				   GST_GOO_BUFFER (buffer)->omx_buffer))
	{
		GST_INFO ("My own OMX buffer");
		priv->incount++;
		gst_buffer_unref (buffer); /* let's push the buffer to omx */
		ret = GST_FLOW_OK;
	}
	else if (GST_IS_GOO_BUFFER (buffer) &&
		 !goo_port_is_my_buffer (self->inport,
					 GST_GOO_BUFFER (buffer)->omx_buffer))
	{
		GST_INFO ("Other OMX buffer");

		if (GST_BUFFER_SIZE (buffer) != priv->omxbufsiz)
		{
			GST_ELEMENT_ERROR (self, STREAM, FORMAT,
					   ("Frame is incomplete (%u!=%u)",
					    GST_BUFFER_SIZE (buffer),
					    priv->omxbufsiz),
					   ("Frame is incomplete (%u!=%u)",
					    GST_BUFFER_SIZE (buffer),
					    priv->omxbufsiz));
			ret = GST_FLOW_ERROR;
		}

		omx_buffer = goo_port_grab_buffer (self->inport);
		memcpy (omx_buffer->pBuffer, GST_BUFFER_DATA (buffer),
			priv->omxbufsiz);
		omx_buffer->nFilledLen = priv->omxbufsiz;
		priv->incount++;
		goo_component_release_buffer (self->component, omx_buffer);
		gst_buffer_unref (buffer);
		ret = GST_FLOW_OK;
	}
	else
	{
		if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))
		{
			gst_goo_adapter_clear (adapter);
		}

		GST_LOG ("size = %d bytes", GST_BUFFER_SIZE (buffer));
		gst_goo_adapter_push (adapter, buffer);

		guint tmp = priv->incount;
		while (gst_goo_adapter_available (adapter) >= priv->omxbufsiz &&
		       ret == GST_FLOW_OK)
		{
			GST_DEBUG ("Pushing data to OMX");
			OMX_BUFFERHEADERTYPE* omx_buffer;
			omx_buffer = goo_port_grab_buffer (self->inport);
			gst_goo_adapter_peek (adapter, priv->omxbufsiz,
					      omx_buffer);
			omx_buffer->nFilledLen = priv->omxbufsiz;
			gst_goo_adapter_flush (adapter, priv->omxbufsiz);
			priv->incount++;
			goo_component_release_buffer (self->component,
						      omx_buffer);
			ret = GST_FLOW_OK;
		}

		if (tmp == priv->incount)
		{
			goto done;
		}
	}

process_output:
	if (goo_port_is_tunneled (self->outport))
	{
		outbuf = gst_ghost_buffer_new ();
		GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_READONLY);
		GST_BUFFER_DATA (outbuf)       = NULL;
		GST_BUFFER_SIZE (outbuf)       = 0;
		GST_BUFFER_TIMESTAMP (outbuf)  = timestamp;
		GST_BUFFER_DURATION (outbuf)   = duration;
		GST_BUFFER_OFFSET (outbuf)     = offset;
		GST_BUFFER_OFFSET_END (outbuf) = offsetend;
		gst_buffer_set_caps (outbuf, GST_PAD_CAPS (self->srcpad));
		gst_pad_push (self->srcpad, outbuf);
		goto done;
	}

	GST_DEBUG ("Poping out buffer from OMX");
	omx_buffer = goo_port_grab_buffer (self->outport);

	if (omx_buffer->nFilledLen <= 0)
	{
		ret = GST_FLOW_ERROR;
		goto done;
	}

	if (gst_pad_alloc_buffer (self->srcpad, priv->outcount,
				  omx_buffer->nFilledLen,
				  GST_PAD_CAPS (self->srcpad),
				  &outbuf) == GST_FLOW_OK)
	{
		priv->outcount++;

		/* if the buffer is a goo buffer of the peer element */
		if (GST_IS_GOO_BUFFER (outbuf))
		{
			GST_INFO ("It is a OMX buffer!");
			memcpy (GST_GOO_BUFFER (outbuf)->omx_buffer->pBuffer,
				omx_buffer->pBuffer, omx_buffer->nFilledLen);
			GST_GOO_BUFFER (outbuf)->omx_buffer->nFilledLen =
				omx_buffer->nFilledLen;
			GST_GOO_BUFFER (outbuf)->omx_buffer->nFlags =
				omx_buffer->nFlags;
			GST_GOO_BUFFER (outbuf)->omx_buffer->nTimeStamp =
				GST2OMX_TIMESTAMP (timestamp);
			goo_component_release_buffer (self->component,
						      omx_buffer);
		}
		else
		{
			/* @fixme! */
			/* we do this because there is a buffer extarbation
			 * when a filesink is used.
			 * Maybe using multiple buffers it could be solved.
			 */
			memcpy (GST_BUFFER_DATA (outbuf),
				omx_buffer->pBuffer, omx_buffer->nFilledLen);
			goo_component_release_buffer (self->component,
						      omx_buffer);

/* 			gst_buffer_unref (outbuf); */
/* 			outbuf = GST_BUFFER (gst_goo_buffer_new ()); */
/* 			gst_goo_buffer_set_data (outbuf, */
/* 						 self->component, */
/* 						 omx_buffer); */
		}

		GST_BUFFER_TIMESTAMP (outbuf)  = timestamp;
		GST_BUFFER_DURATION (outbuf)   = duration;
		GST_BUFFER_OFFSET (outbuf)     = offset;
		GST_BUFFER_OFFSET_END (outbuf) = offsetend;

		gst_buffer_set_caps (outbuf, GST_PAD_CAPS (self->srcpad));
		g_signal_emit (G_OBJECT (self),
			       gst_goo_encjpeg_signals[FRAME_ENCODED], 0);
	
		ret = gst_pad_push (self->srcpad, outbuf);
		if (omx_buffer->nFlags & OMX_BUFFERFLAG_EOS ||
		   	goo_port_is_eos (self->outport))
		{
			GST_INFO ("EOS flag found in output buffer (%d)",
			  	omx_buffer->nFilledLen);
			goo_component_set_done (self->component);

		}

		goto done;
	}
	else
	{
		ret = GST_FLOW_ERROR;
		goto done;
	}

fail:
	gst_buffer_unref (buffer);
	gst_goo_adapter_clear (adapter);

done:
	gst_object_unref (self);
	return ret;

}