コード例 #1
0
gboolean
gst_opencv_parse_iplimage_params_from_caps (GstCaps * caps, gint * width,
    gint * height, gint * ipldepth, gint * channels, GError ** err)
{
  GstVideoInfo info;
  gint i, depth = 0;

  if (!gst_video_info_from_caps (&info, caps)) {
    GST_ERROR ("Failed to get the videoinfo from caps");
    g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
        "No width/heighti/depth/channels in caps");
    return FALSE;
  }

  *width = GST_VIDEO_INFO_WIDTH (&info);
  *height = GST_VIDEO_INFO_HEIGHT (&info);
  if (GST_VIDEO_INFO_IS_RGB (&info))
    *channels = 3;
  else if (GST_VIDEO_INFO_IS_GRAY (&info))
    *channels = 1;
  else {
    g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
        "Unsupported caps %s", gst_caps_to_string(caps));
    return FALSE;
  }

  for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (&info); i++)
    depth += GST_VIDEO_INFO_COMP_DEPTH (&info, i);

  if (depth / *channels == 8) {
    /* TODO signdness? */
    *ipldepth = IPL_DEPTH_8U;
  } else if (depth / *channels == 16) {
    *ipldepth = IPL_DEPTH_16U;
  } else {
    g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION,
        "Unsupported depth/channels %d/%d", depth, *channels);
    return FALSE;
  }
  return TRUE;
}
コード例 #2
0
static gboolean
gst_video_crop_set_info (GstVideoFilter * vfilter, GstCaps * in,
    GstVideoInfo * in_info, GstCaps * out, GstVideoInfo * out_info)
{
  GstVideoCrop *crop = GST_VIDEO_CROP (vfilter);
  int dx, dy;

  GST_OBJECT_LOCK (crop);
  crop->need_update = FALSE;
  crop->crop_left = crop->prop_left;
  crop->crop_right = crop->prop_right;
  crop->crop_top = crop->prop_top;
  crop->crop_bottom = crop->prop_bottom;
  GST_OBJECT_UNLOCK (crop);

  dx = GST_VIDEO_INFO_WIDTH (in_info) - GST_VIDEO_INFO_WIDTH (out_info);
  dy = GST_VIDEO_INFO_HEIGHT (in_info) - GST_VIDEO_INFO_HEIGHT (out_info);

  if (crop->crop_left == -1 && crop->crop_right == -1) {
    crop->crop_left = dx / 2;
    crop->crop_right = dx / 2 + (dx & 1);
  } else if (crop->crop_left == -1) {
    if (G_UNLIKELY (crop->crop_right > dx))
      goto cropping_too_much;
    crop->crop_left = dx - crop->crop_right;
  } else if (crop->crop_right == -1) {
    if (G_UNLIKELY (crop->crop_left > dx))
      goto cropping_too_much;
    crop->crop_right = dx - crop->crop_left;
  }

  if (crop->crop_top == -1 && crop->crop_bottom == -1) {
    crop->crop_top = dy / 2;
    crop->crop_bottom = dy / 2 + (dy & 1);
  } else if (crop->crop_top == -1) {
    if (G_UNLIKELY (crop->crop_bottom > dy))
      goto cropping_too_much;
    crop->crop_top = dy - crop->crop_bottom;
  } else if (crop->crop_bottom == -1) {
    if (G_UNLIKELY (crop->crop_top > dy))
      goto cropping_too_much;
    crop->crop_bottom = dy - crop->crop_top;
  }

  if (G_UNLIKELY ((crop->crop_left + crop->crop_right) >=
          GST_VIDEO_INFO_WIDTH (in_info)
          || (crop->crop_top + crop->crop_bottom) >=
          GST_VIDEO_INFO_HEIGHT (in_info)))
    goto cropping_too_much;

  if (in && out)
    GST_LOG_OBJECT (crop, "incaps = %" GST_PTR_FORMAT ", outcaps = %"
        GST_PTR_FORMAT, in, out);

  if ((crop->crop_left | crop->crop_right | crop->crop_top | crop->
          crop_bottom) == 0) {
    GST_LOG_OBJECT (crop, "we are using passthrough");
    gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (crop), TRUE);
  } else {
    GST_LOG_OBJECT (crop, "we are not using passthrough");
    gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (crop), FALSE);
  }

  if (GST_VIDEO_INFO_IS_RGB (in_info)
      || GST_VIDEO_INFO_IS_GRAY (in_info)) {
    crop->packing = VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE;
  } else {
    switch (GST_VIDEO_INFO_FORMAT (in_info)) {
      case GST_VIDEO_FORMAT_AYUV:
        crop->packing = VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE;
        break;
      case GST_VIDEO_FORMAT_YVYU:
      case GST_VIDEO_FORMAT_YUY2:
      case GST_VIDEO_FORMAT_UYVY:
        crop->packing = VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX;
        if (GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_UYVY) {
          /* UYVY = 4:2:2 - [U0 Y0 V0 Y1] [U2 Y2 V2 Y3] [U4 Y4 V4 Y5] */
          crop->macro_y_off = 1;
        } else {
          /* YUYV = 4:2:2 - [Y0 U0 Y1 V0] [Y2 U2 Y3 V2] [Y4 U4 Y5 V4] = YUY2 */
          crop->macro_y_off = 0;
        }
        break;
      case GST_VIDEO_FORMAT_I420:
      case GST_VIDEO_FORMAT_YV12:
        crop->packing = VIDEO_CROP_PIXEL_FORMAT_PLANAR;
        break;
      case GST_VIDEO_FORMAT_NV12:
      case GST_VIDEO_FORMAT_NV21:
        crop->packing = VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR;
        break;
      default:
        goto unknown_format;
    }
  }

  crop->in_info = *in_info;
  crop->out_info = *out_info;

  return TRUE;

  /* ERROR */
cropping_too_much:
  {
    GST_WARNING_OBJECT (crop, "we are cropping too much");
    return FALSE;
  }
unknown_format:
  {
    GST_WARNING_OBJECT (crop, "Unsupported format");
    return FALSE;
  }
}
コード例 #3
0
static void
check_1x1_buffer (GstBuffer * buf, GstCaps * caps)
{
  GstVideoInfo info;
  GstVideoFrame frame;
  /* the exact values we check for come from videotestsrc */
  static const guint yuv_values[] = { 81, 90, 240, 255 };
  static const guint rgb_values[] = { 0xff, 0, 0, 255 };
  static const guint gray8_values[] = { 0x51 };
  static const guint gray16_values[] = { 0x5151 };
  const guint *values;
  guint i;
  const GstVideoFormatInfo *finfo;

  fail_unless (buf != NULL);
  fail_unless (caps != NULL);

  fail_unless (gst_video_info_from_caps (&info, caps));
  fail_unless (gst_video_frame_map (&frame, &info, buf, GST_MAP_READ));

  finfo = info.finfo;

  if (GST_VIDEO_INFO_IS_YUV (&info))
    values = yuv_values;
  else if (GST_VIDEO_INFO_IS_GRAY (&info))
    if (GST_VIDEO_FORMAT_INFO_BITS (finfo) == 8)
      values = gray8_values;
    else
      values = gray16_values;
  else
    values = rgb_values;

  GST_MEMDUMP ("buffer", GST_VIDEO_FRAME_PLANE_DATA (&frame, 0), 8);

  for (i = 0; i < GST_VIDEO_FRAME_N_COMPONENTS (&frame); i++) {
    guint8 *data = GST_VIDEO_FRAME_COMP_DATA (&frame, i);

    GST_DEBUG ("W: %d", GST_VIDEO_FORMAT_INFO_W_SUB (finfo, i));
    GST_DEBUG ("H: %d", GST_VIDEO_FORMAT_INFO_H_SUB (finfo, i));

    if (GST_VIDEO_FORMAT_INFO_W_SUB (finfo,
            i) >= GST_VIDEO_FRAME_WIDTH (&frame))
      continue;
    if (GST_VIDEO_FORMAT_INFO_H_SUB (finfo,
            i) >= GST_VIDEO_FRAME_HEIGHT (&frame))
      continue;

    if (GST_VIDEO_FORMAT_INFO_BITS (finfo) == 8) {
      fail_unless_equals_int (data[0], values[i]);
    } else if (GST_VIDEO_FORMAT_INFO_BITS (finfo) == 16) {
      guint16 pixels, val;
      gint depth;

      if (GST_VIDEO_FORMAT_INFO_IS_LE (finfo))
        pixels = GST_READ_UINT16_LE (data);
      else
        pixels = GST_READ_UINT16_BE (data);

      depth = GST_VIDEO_FORMAT_INFO_DEPTH (finfo, i);
      val = pixels >> GST_VIDEO_FORMAT_INFO_SHIFT (finfo, i);
      val = val & ((1 << depth) - 1);

      GST_DEBUG ("val %08x %d : %d", pixels, i, val);
      if (depth <= 8) {
        fail_unless_equals_int (val, values[i] >> (8 - depth));
      } else {
コード例 #4
0
/* Called in the gl thread */
static gboolean
_init_convert (GstGLColorConvert * convert)
{
  GstGLFuncs *gl;
  gboolean res;
  struct ConvertInfo *info = &convert->priv->convert_info;
  gint i;

  gl = convert->context->gl_vtable;

  if (convert->initted)
    return TRUE;

  GST_INFO ("Initializing color conversion from %s to %s",
      gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->in_info)),
      gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->out_info)));

  if (!gl->CreateProgramObject && !gl->CreateProgram) {
    gst_gl_context_set_error (convert->context,
        "Cannot perform color conversion without OpenGL shaders");
    goto error;
  }

  if (GST_VIDEO_INFO_IS_RGB (&convert->in_info)) {
    if (GST_VIDEO_INFO_IS_RGB (&convert->out_info)) {
      _RGB_to_RGB (convert);
    }
  }

  if (GST_VIDEO_INFO_IS_YUV (&convert->in_info)) {
    if (GST_VIDEO_INFO_IS_RGB (&convert->out_info)) {
      _YUV_to_RGB (convert);
    }
  }

  if (GST_VIDEO_INFO_IS_RGB (&convert->in_info)) {
    if (GST_VIDEO_INFO_IS_YUV (&convert->out_info)) {
      _RGB_to_YUV (convert);
    }
  }

  if (GST_VIDEO_INFO_IS_RGB (&convert->in_info)) {
    if (GST_VIDEO_INFO_IS_GRAY (&convert->out_info)) {
      _RGB_to_GRAY (convert);
    }
  }

  if (GST_VIDEO_INFO_IS_GRAY (&convert->in_info)) {
    if (GST_VIDEO_INFO_IS_RGB (&convert->out_info)) {
      _GRAY_to_RGB (convert);
    }
  }

  if (!info->frag_prog || info->in_n_textures == 0 || info->out_n_textures == 0)
    goto unhandled_format;

  /* multiple draw targets not supported on GLES2...yet */
  if (info->out_n_textures > 1 && (!gl->DrawBuffers ||
          USING_GLES2 (convert->context))) {
    g_free (info->frag_prog);
    GST_ERROR ("Conversion requires output to multiple draw buffers");
    goto incompatible_api;
  }

  /* Requires reading from a RG/LA framebuffer... */
  if (USING_GLES2 (convert->context) &&
      (GST_VIDEO_INFO_FORMAT (&convert->out_info) == GST_VIDEO_FORMAT_YUY2 ||
          GST_VIDEO_INFO_FORMAT (&convert->out_info) ==
          GST_VIDEO_FORMAT_UYVY)) {
    g_free (info->frag_prog);
    GST_ERROR ("Conversion requires reading with an unsupported format");
    goto incompatible_api;
  }

  res =
      gst_gl_context_gen_shader (convert->context, text_vertex_shader,
      info->frag_prog, &convert->shader);
  g_free (info->frag_prog);
  if (!res)
    goto error;

  convert->shader_attr_position_loc =
      gst_gl_shader_get_attribute_location (convert->shader, "a_position");
  convert->shader_attr_texture_loc =
      gst_gl_shader_get_attribute_location (convert->shader, "a_texcoord");

  gst_gl_shader_use (convert->shader);

  if (info->cms_offset && info->cms_coeff1
      && info->cms_coeff2 && info->cms_coeff3) {
    gst_gl_shader_set_uniform_3fv (convert->shader, "offset", 1,
        info->cms_offset);
    gst_gl_shader_set_uniform_3fv (convert->shader, "coeff1", 1,
        info->cms_coeff1);
    gst_gl_shader_set_uniform_3fv (convert->shader, "coeff2", 1,
        info->cms_coeff2);
    gst_gl_shader_set_uniform_3fv (convert->shader, "coeff3", 1,
        info->cms_coeff3);
  }

  for (i = info->in_n_textures; i >= 0; i--) {
    if (info->shader_tex_names[i])
      gst_gl_shader_set_uniform_1i (convert->shader, info->shader_tex_names[i],
          i);
  }

  gst_gl_shader_set_uniform_1f (convert->shader, "width",
      GST_VIDEO_INFO_WIDTH (&convert->in_info));
  gst_gl_shader_set_uniform_1f (convert->shader, "height",
      GST_VIDEO_INFO_HEIGHT (&convert->in_info));

  if (info->chroma_sampling[0] > 0.0f && info->chroma_sampling[1] > 0.0f) {
    gst_gl_shader_set_uniform_2fv (convert->shader, "chroma_sampling", 1,
        info->chroma_sampling);
  }

  gst_gl_context_clear_shader (convert->context);

  if (!_init_convert_fbo (convert)) {
    goto error;
  }

  gl->BindTexture (GL_TEXTURE_2D, 0);

  convert->initted = TRUE;

  return TRUE;

unhandled_format:
  gst_gl_context_set_error (convert->context,
      "Don't know how to convert from %s to %s",
      gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->in_info)),
      gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->out_info)));

error:
  return FALSE;

incompatible_api:
  {
    gst_gl_context_set_error (convert->context,
        "Converting from %s to %s requires "
        "functionality that the current OpenGL setup does not support",
        gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&convert->in_info)),
        gst_video_format_to_string (GST_VIDEO_INFO_FORMAT
            (&convert->out_info)));
    return FALSE;
  }
}