static GstFlowReturn
gst_opencv_video_filter_transform_ip (GstBaseTransform * trans,
    GstBuffer * buffer)
{
  GstOpencvVideoFilter *transform;
  GstOpencvVideoFilterClass *fclass;
  GstMapInfo info;
  GstFlowReturn ret;

  transform = GST_OPENCV_VIDEO_FILTER (trans);
  fclass = GST_OPENCV_VIDEO_FILTER_GET_CLASS (transform);

  g_return_val_if_fail (fclass->cv_trans_ip_func != NULL, GST_FLOW_ERROR);
  g_return_val_if_fail (transform->cvImage != NULL, GST_FLOW_ERROR);

  if (!gst_buffer_map (buffer, &info, GST_MAP_READWRITE))
    goto map_failed;

  transform->cvImage->imageData = (char *) info.data;

  ret = fclass->cv_trans_ip_func (transform, buffer, transform->cvImage);

  gst_buffer_unmap (buffer, &info);

  return ret;

map_failed:
  GST_ELEMENT_ERROR (transform, RESOURCE, WRITE,
      ("Failed to map buffer for reading and writing"), (NULL));
  return GST_FLOW_ERROR;
}
static GstFlowReturn
gst_opencv_video_filter_transform_ip (GstBaseTransform * trans,
    GstBuffer * buffer)
{
  GstOpencvVideoFilter *transform;
  GstOpencvVideoFilterClass *fclass;
  GstFlowReturn ret;

  transform = GST_OPENCV_VIDEO_FILTER (trans);
  fclass = GST_OPENCV_VIDEO_FILTER_GET_CLASS (transform);

  g_return_val_if_fail (fclass->cv_trans_ip_func != NULL, GST_FLOW_ERROR);
  g_return_val_if_fail (transform->cvImage != NULL, GST_FLOW_ERROR);

  /* TODO this is not always needed and should be solved at BaseTransform
   * level */
  buffer = gst_buffer_make_writable (buffer);

  transform->cvImage->imageData = (char *) gst_buffer_map (buffer,
      NULL, NULL, GST_MAP_READWRITE);

  /* FIXME how to release buffer? */
  ret = fclass->cv_trans_ip_func (transform, buffer, transform->cvImage);

  gst_buffer_unmap (buffer, transform->cvImage->imageData, -1);

  return ret;
}