static GstFlowReturn
pad_chain (GstPad *pad,
           GstBuffer *buf)
{
    GOmxCore *gomx;
    GOmxPort *in_port;
    GstOmxBaseFilter2 *self;
    GstFlowReturn ret = GST_FLOW_OK;
	int i;

    self = GST_OMX_BASE_FILTER2 (GST_OBJECT_PARENT (pad));

    //printf("INput!!\n");
    PRINT_BUFFER (self, buf);

    gomx = self->gomx;

    GST_LOG_OBJECT (self, "begin: size=%u, state=%d", GST_BUFFER_SIZE (buf), gomx->omx_state);

    if (G_UNLIKELY (gomx->omx_state == OMX_StateLoaded))
    {
        g_mutex_lock (self->ready_lock);

        GST_INFO_OBJECT (self, "omx: prepare");
        
        /** @todo this should probably go after doing preparations. */
        if (self->omx_setup)
        {
            self->omx_setup (self);
        }

        setup_input_buffer (self, buf);

        setup_ports (self);

        g_omx_core_prepare (self->gomx);

        if (gomx->omx_state == OMX_StateIdle)
        {
            self->ready = TRUE;
			for (i = 0; i < NUM_OUTPUTS; i++) 
            	gst_pad_start_task (self->srcpad[i], output_loop, self->srcpad[i]);
        }

        g_mutex_unlock (self->ready_lock);

        if (gomx->omx_state != OMX_StateIdle)
            goto out_flushing;
    }

    in_port = self->in_port;

    if (G_LIKELY (in_port->enabled))
    {        
        if (G_UNLIKELY (gomx->omx_state == OMX_StateIdle))
        {
            GST_INFO_OBJECT (self, "omx: play");
            g_omx_core_start (gomx);

            if (gomx->omx_state != OMX_StateExecuting)
                goto out_flushing;

            /* send buffer with codec data flag */
            if (self->codec_data)
            {
                GST_BUFFER_FLAG_SET (self->codec_data, GST_BUFFER_FLAG_IN_CAPS);  /* just in case */
                g_omx_port_send (in_port, self->codec_data);
            }

        }

        if (G_UNLIKELY (gomx->omx_state != OMX_StateExecuting))
        {
            GST_ERROR_OBJECT (self, "Whoa! very wrong");
        }

        while (TRUE)
        {
            gint sent;

            if (self->last_pad_push_return != GST_FLOW_OK ||
                !(gomx->omx_state == OMX_StateExecuting ||
                  gomx->omx_state == OMX_StatePause))
            {
                GST_DEBUG_OBJECT (self, "last_pad_push_return=%d", self->last_pad_push_return);
                goto out_flushing;
            }

			if (self->input_fields_separately) {
				g_omx_port_send_interlaced_fields (in_port, buf, self->second_field_offset);
                gst_buffer_unref (buf);
				break;
			}

            sent = g_omx_port_send (in_port, buf);

            if (G_UNLIKELY (sent < 0))
            {
                ret = GST_FLOW_WRONG_STATE;
                goto out_flushing;
            }
            else if (sent < GST_BUFFER_SIZE (buf))
            {
                GstBuffer *subbuf = gst_buffer_create_sub (buf, sent,
                        GST_BUFFER_SIZE (buf) - sent);
                gst_buffer_unref (buf);
                buf = subbuf;
            }
            else
            {
                gst_buffer_unref (buf);
                break;
            }
        }
    }
    else
    {
        GST_WARNING_OBJECT (self, "done");
        ret = GST_FLOW_UNEXPECTED;
    }

leave:

    GST_LOG_OBJECT (self, "end");

    return ret;

    /* special conditions */
out_flushing:
    {
        const gchar *error_msg = NULL;

        if (gomx->omx_error)
        {
            error_msg = "Error from OpenMAX component";
        }
        else if (gomx->omx_state != OMX_StateExecuting &&
                 gomx->omx_state != OMX_StatePause)
        {
            error_msg = "OpenMAX component in wrong state";
        }

        if (error_msg)
        {
            GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), (error_msg));
            ret = GST_FLOW_ERROR;
        }

        gst_buffer_unref (buf);

        goto leave;
    }
}
static GstFlowReturn collected_pads(GstCollectPads *pads, GstOmxBaseFilter21 *self)
{
    GSList *item;
    GstCollectData *collectdata;
    GstFlowReturn ret = GST_FLOW_OK;
    GOmxCore *gomx = self->gomx;
    gint sink_number;
    GstBuffer *buffers[2];
    gboolean eos = FALSE;

    GST_DEBUG_OBJECT(self, "Collected pads !");

    // Collect buffers
    for( item = pads->data ; item != NULL ; item = item->next ) {
        collectdata = (GstCollectData *) item->data;
        
        //FIXME Use collect data
        if(strcmp(GST_PAD_NAME(collectdata->pad), "sink_00") == 0){
    		sink_number=0;
	    }
	    else{
		    sink_number=1;
	    }
	    
	    buffers[sink_number] = gst_collect_pads_pop(pads, collectdata);
	    
	    if( buffers[sink_number] == NULL ) {
	        eos = TRUE;
	    }
    }

    // Detect EOS
    if( eos == TRUE ) {
        GST_INFO_OBJECT(self, "EOS");
        for( sink_number=0 ; sink_number<2 ; sink_number++ ) {
            if( buffers[sink_number] ) {
                gst_buffer_unref(buffers[sink_number]);
            }
        }
        gst_pad_push_event(self->srcpad, gst_event_new_eos());
        return GST_FLOW_UNEXPECTED;
    }

    // Setup input ports if not done yet
    if (G_LIKELY (gomx->omx_state != OMX_StateExecuting)) {
      for( sink_number=0 ; sink_number<2 ; sink_number++ ) {
        GST_INFO_OBJECT(self, "Setup port %d", sink_number);
        setup_input_buffer (self, buffers[sink_number], sink_number);
      }
    }
    
    // Call chain foreach buffer
    for( sink_number=0 ; sink_number<2 ; sink_number++ ) {
        ret = pad_chain(self->sinkpad[sink_number], buffers[sink_number]);
    }
    
    // Call output_loop after pad_chain
    output_loop(self->srcpad);
    
    return ret;
}