static gboolean
sink_setcaps (GstPad *pad,
              GstCaps *caps)
{
    GstStructure *structure;
    GstOmxBaseFilter21 *self;
    GOmxCore *gomx;
    GstVideoFormat format;
    int sink_number;
    self = GST_OMX_BASE_FILTER21 (GST_PAD_PARENT (pad));
	if(strcmp(GST_PAD_NAME(pad), "sink_00") == 0){
		sink_number=0;
	}
	else if(strcmp(GST_PAD_NAME(pad), "sink_01") == 0){
		sink_number=1;
	}
    gomx = (GOmxCore *) self->gomx;
	GST_INFO_OBJECT (self, "setcaps (sink): %d", sink_number);
    GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
	
    g_return_val_if_fail (caps, FALSE);
    g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

    structure = gst_caps_get_structure (caps, 0);

    g_return_val_if_fail (structure, FALSE);
    if (!gst_video_format_parse_caps_strided (caps,
            &format, &self->in_width[sink_number], &self->in_height[sink_number], &self->in_stride[sink_number]))
    {
        GST_WARNING_OBJECT (self, "width and/or height is not set in caps");
        return FALSE;
    }

    if (!self->in_stride[sink_number]) 
    {
        self->in_stride[sink_number] = gstomx_calculate_stride (self->in_width[sink_number], format);
    }

    {
        /* Output framerate correspond to the minimum input framerate */
        const GValue *sink_framerate = NULL;
        sink_framerate = gst_structure_get_value (structure, "framerate");
        if( GST_VALUE_HOLDS_FRACTION(sink_framerate) )
        {
            if( self->out_framerate == NULL || gst_value_compare(sink_framerate, self->out_framerate) == GST_VALUE_LESS_THAN )
            {
                self->out_framerate = sink_framerate;
                self->duration = gst_util_uint64_scale_int(GST_SECOND, gst_value_get_fraction_denominator(sink_framerate),
                                                                       gst_value_get_fraction_numerator(sink_framerate));
            }
        }
    }

    return gst_pad_set_caps (pad, caps);
}
static gboolean
src_setcaps (GstPad *pad, GstCaps *caps)
{
    GstOmxBaseFilter21 *self;
    GstVideoFormat format;
    GstStructure *structure;

    self = GST_OMX_BASE_FILTER21 (GST_PAD_PARENT (pad));
    structure = gst_caps_get_structure (caps, 0);

    GST_INFO_OBJECT (self, "setcaps (src): %" GST_PTR_FORMAT, caps);
    g_return_val_if_fail (caps, FALSE);
    g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

    if (!gst_video_format_parse_caps_strided (caps, &format, &self->out_width, &self->out_height, &self->out_stride))
    {
        GST_WARNING_OBJECT (self, "width and/or height is not set in caps");
        return FALSE;
    }

    if (!self->out_stride)
    {
        self->out_stride = gstomx_calculate_stride (self->out_width, format);
    }

    /* Set output framerate already calculated in sink_setcaps */
    if( self->out_framerate == NULL ) {
        GST_WARNING_OBJECT (self, "unable to calculate output framerate");
        return FALSE;
    }

    gint out_framerate_num = gst_value_get_fraction_numerator(self->out_framerate);
    gint out_framerate_denom = gst_value_get_fraction_denominator(self->out_framerate);

    gst_structure_set(structure, "framerate", GST_TYPE_FRACTION, out_framerate_num, out_framerate_denom, NULL);
    
    GST_INFO_OBJECT(self, "output framerate is: %d/%d", out_framerate_num, out_framerate_denom);

    /* save the src caps later needed by omx transport buffer */
    if (self->out_port->caps)
        gst_caps_unref (self->out_port->caps);

    self->out_port->caps = gst_caps_copy (caps);

    return TRUE;
}
static gboolean
src_setcaps (GstPad *pad, GstCaps *caps)
{
    GstOmxBaseVfpc2 *self;
    GstOmxBaseFilter2 *omx_base;
    GstVideoFormat format;
    GstStructure *structure;
	int i;

    self = GST_OMX_BASE_VFPC2 (GST_PAD_PARENT (pad));
    omx_base = GST_OMX_BASE_FILTER2 (self);
    structure = gst_caps_get_structure (caps, 0);

    GST_INFO_OBJECT (omx_base, "setcaps (src): %" GST_PTR_FORMAT, caps);
    g_return_val_if_fail (caps, FALSE);
    g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

	for (i=0; i<NUM_OUTPUTS; i++) 
		if (pad == omx_base->srcpad[i]) break;
	if (!(i<NUM_OUTPUTS)) return FALSE;

    if (!gst_video_format_parse_caps_strided (caps,
            &format, &self->out_width[i], &self->out_height[i], &self->out_stride[i]))
    {
        GST_WARNING_OBJECT (self, "width and/or height is not set in caps");
        return FALSE;
    }

    if (!self->out_stride[i])
    {
        self->out_stride[i] = gstomx_calculate_stride (self->out_width[i], format);
    }

    /* save the src caps later needed by omx transport buffer */
    if (omx_base->out_port[i]->caps)
        gst_caps_unref (omx_base->out_port[i]->caps);

    omx_base->out_port[i]->caps = gst_caps_copy (caps);

    return TRUE;
}
static gboolean
sink_setcaps (GstPad *pad,
              GstCaps *caps)
{
    GstStructure *structure;
    GstOmxBaseVfpc2 *self;
    GstOmxBaseFilter2 *omx_base;
    GOmxCore *gomx;
    GstVideoFormat format;

    self = GST_OMX_BASE_VFPC2 (GST_PAD_PARENT (pad));
    omx_base = GST_OMX_BASE_FILTER2 (self);

    gomx = (GOmxCore *) omx_base->gomx;

    GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);

    g_return_val_if_fail (caps, FALSE);
    g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

    structure = gst_caps_get_structure (caps, 0);

    g_return_val_if_fail (structure, FALSE);

    if (!gst_video_format_parse_caps_strided (caps,
            &format, &self->in_width, &self->in_height, &self->in_stride))
    {
        GST_WARNING_OBJECT (self, "width and/or height is not set in caps");
        return FALSE;
    }

    if (!self->in_stride) 
    {
        self->in_stride = gstomx_calculate_stride (self->in_width, format);
    }

    {
        const GValue *framerate = NULL;
        framerate = gst_structure_get_value (structure, "framerate");
        if (framerate)
        {
            self->framerate_num = gst_value_get_fraction_numerator (framerate);
            self->framerate_denom = gst_value_get_fraction_denominator (framerate);

			if (self->framerate_num && self->framerate_denom) {
				omx_base->duration = gst_util_uint64_scale_int(GST_SECOND,
						gst_value_get_fraction_denominator (framerate),
						gst_value_get_fraction_numerator (framerate));
			}
			GST_DEBUG_OBJECT (self, "Nominal frame duration =%"GST_TIME_FORMAT,
					GST_TIME_ARGS (omx_base->duration));
        }
    }
	/* check for pixel-aspect-ratio, to set to src caps */
    {
        const GValue *v = NULL;
        v = gst_structure_get_value (structure, "pixel-aspect-ratio");
        if (v) {
            self->pixel_aspect_ratio_num = gst_value_get_fraction_numerator (v);
            self->pixel_aspect_ratio_denom = gst_value_get_fraction_denominator (v);
		} else self->pixel_aspect_ratio_denom = 0;
    }

	if (!gst_structure_get_boolean (structure, "interlaced", &self->interlaced))
		self->interlaced = FALSE;

    if (self->sink_setcaps)
        self->sink_setcaps (pad, caps);

    return gst_pad_set_caps (pad, caps);
}
static gboolean
sink_setcaps (GstPad *pad,
              GstCaps *caps)
{
    GstOmxBaseVideoEnc *self;
    GstOmxBaseFilter *omx_base;
    GstQuery *query;
    GstVideoFormat format;
    gint width, height, rowstride;
    const GValue *framerate = NULL;

    self = GST_OMX_BASE_VIDEOENC (GST_PAD_PARENT (pad));
    omx_base = GST_OMX_BASE_FILTER (self);

    GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);

    g_return_val_if_fail (caps, FALSE);
    g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

    framerate = gst_structure_get_value (
            gst_caps_get_structure (caps, 0), "framerate");

    if (framerate)
    {
        omx_base->duration = gst_util_uint64_scale_int(GST_SECOND,
                gst_value_get_fraction_denominator (framerate),
                gst_value_get_fraction_numerator (framerate));
        GST_DEBUG_OBJECT (self, "Nominal frame duration =%"GST_TIME_FORMAT,
                            GST_TIME_ARGS (omx_base->duration));
    }

    if (gst_video_format_parse_caps_strided (caps,
            &format, &width, &height, &rowstride))
    {
        /* Output port configuration: */
        OMX_PARAM_PORTDEFINITIONTYPE param;

        G_OMX_PORT_GET_DEFINITION (omx_base->in_port, &param);

        param.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar ;
        param.format.video.nFrameWidth  = width;
        param.format.video.nFrameHeight = height;
        if (!rowstride)
            rowstride = (width + 15) & 0xFFFFFFF0;
        param.format.video.nStride      = self->rowstride = rowstride;

        if (framerate)
        {
            self->framerate_num = gst_value_get_fraction_numerator (framerate);
            self->framerate_denom = gst_value_get_fraction_denominator (framerate);

            /* convert to Q.16 */
            param.format.video.xFramerate =
                (gst_value_get_fraction_numerator (framerate) << 16) /
                gst_value_get_fraction_denominator (framerate);
        }

        G_OMX_PORT_SET_DEFINITION (omx_base->out_port, &param);
    }


    return TRUE;
}