static void
init_pixbuf_texture (GstGLContext * context, gpointer data)
{
  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (data);
  GstGLFilter *filter = GST_GL_FILTER (data);
  const GstGLFuncs *gl = context->gl_vtable;
  guint internal_format =
      gst_gl_sized_gl_format_from_gl_format_type (context, GL_RGBA,
      GL_UNSIGNED_BYTE);

  gl->DeleteTextures (1, &differencematte->newbgtexture);
  gl->GenTextures (1, &differencematte->newbgtexture);
  gl->BindTexture (GL_TEXTURE_2D, differencematte->newbgtexture);
  gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format,
      (gint) differencematte->pbuf_width, (gint) differencematte->pbuf_height,
      0, GL_RGBA, GL_UNSIGNED_BYTE, differencematte->pixbuf);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  if (differencematte->savedbgtexture == 0) {
    gl->GenTextures (1, &differencematte->savedbgtexture);
    gl->BindTexture (GL_TEXTURE_2D, differencematte->savedbgtexture);
    gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format,
        GST_VIDEO_INFO_WIDTH (&filter->out_info),
        GST_VIDEO_INFO_HEIGHT (&filter->out_info),
        0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  }
}
Beispiel #2
0
static void
_gen_texture_full (GstGLContext * context, GenTextureFull * data)
{
  const GstGLFuncs *gl = context->gl_vtable;
  GstVideoGLTextureType tex_type;
  GstVideoFormat v_format;
  GLint glinternalformat = 0;
  GLenum glformat = 0;
  GLenum gltype = 0;

  gl->GenTextures (1, &data->result);
  gl->BindTexture (GL_TEXTURE_2D, data->result);

  v_format = GST_VIDEO_INFO_FORMAT (data->info);
  tex_type = gst_gl_texture_type_from_format (context, v_format, data->comp);
  glformat = gst_gl_format_from_gl_texture_type (tex_type);
  gltype = GL_UNSIGNED_BYTE;
  if (v_format == GST_VIDEO_FORMAT_RGB16)
    gltype = GL_UNSIGNED_SHORT_5_6_5;
  glinternalformat = gst_gl_sized_gl_format_from_gl_format_type (context,
      glformat, gltype);

  gl->TexImage2D (GL_TEXTURE_2D, 0, glinternalformat,
      GST_VIDEO_INFO_COMP_WIDTH (data->info, data->comp),
      GST_VIDEO_INFO_COMP_HEIGHT (data->info, data->comp), 0, glformat, gltype,
      NULL);

  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
Beispiel #3
0
static void
_gen_texture (GstGLContext * context, GenTexture * data)
{
  const GstGLFuncs *gl = context->gl_vtable;
  GLenum internal_format;

  GST_TRACE ("Generating texture format:%u dimensions:%ux%u", data->format,
      data->width, data->height);

  gl->GenTextures (1, &data->result);
  gl->BindTexture (GL_TEXTURE_2D, data->result);

  internal_format =
      gst_gl_sized_gl_format_from_gl_format_type (context, GL_RGBA,
      GL_UNSIGNED_BYTE);
  if (data->width > 0 && data->height > 0)
    gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format,
        data->width, data->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  GST_LOG ("generated texture id:%d", data->result);
}
static void
_gl_mem_copy_thread (GstGLContext * context, gpointer data)
{
  const GstGLFuncs *gl;
  GstGLMemoryPBOCopyParams *copy_params;
  GstGLMemoryPBO *src;
  guint tex_id;
  guint out_tex_target;
  GLuint fboId;
  gsize out_width, out_height, out_stride;
  GLuint out_gl_format, out_gl_type;
  GLuint in_gl_format, in_gl_type;
  gsize in_size, out_size;

  copy_params = (GstGLMemoryPBOCopyParams *) data;
  src = copy_params->src;
  tex_id = copy_params->tex_id;
  out_tex_target = gst_gl_texture_target_to_gl (copy_params->tex_target);
  out_width = copy_params->out_width;
  out_height = copy_params->out_height;
  out_stride = copy_params->out_stride;

  gl = context->gl_vtable;
  out_gl_format = gst_gl_format_from_gl_texture_type (copy_params->out_format);
  out_gl_type = GL_UNSIGNED_BYTE;
  if (copy_params->out_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
  in_gl_format = gst_gl_format_from_gl_texture_type (src->mem.tex_type);
  in_gl_type = GL_UNSIGNED_BYTE;
  if (src->mem.tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    in_gl_type = GL_UNSIGNED_SHORT_5_6_5;

  if (!gl->GenFramebuffers) {
    gst_gl_context_set_error (context,
        "Context, EXT_framebuffer_object not supported");
    goto error;
  }

  in_size = GL_MEM_HEIGHT (src) * GL_MEM_STRIDE (src);
  out_size = out_height * out_stride;

  if (copy_params->respecify) {
    if (in_size != out_size) {
      GST_ERROR ("Cannot copy between textures with backing data of different"
          "sizes. input %" G_GSIZE_FORMAT " output %" G_GSIZE_FORMAT, in_size,
          out_size);
      goto error;
    }
  }

  if (!tex_id) {
    guint internal_format;
    guint out_gl_type;

    out_gl_type = GL_UNSIGNED_BYTE;
    if (copy_params->out_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
      out_gl_type = GL_UNSIGNED_SHORT_5_6_5;

    internal_format =
        gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format,
        out_gl_type);

    tex_id =
        _new_texture (context, out_tex_target,
        internal_format, out_gl_format, out_gl_type, copy_params->out_width,
        copy_params->out_height);
  }

  if (!tex_id) {
    GST_WARNING ("Could not create GL texture with context:%p", context);
  }

  GST_LOG ("copying memory %p, tex %u into texture %i",
      src, src->mem.tex_id, tex_id);

  /* FIXME: try and avoid creating and destroying fbo's every copy... */
  /* create a framebuffer object */
  gl->GenFramebuffers (1, &fboId);
  gl->BindFramebuffer (GL_FRAMEBUFFER, fboId);

  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      gst_gl_texture_target_to_gl (src->mem.tex_target), src->mem.tex_id, 0);

//  if (!gst_gl_context_check_framebuffer_status (src->mem.mem.context))
//    goto fbo_error;

  gl->BindTexture (out_tex_target, tex_id);
  if (copy_params->respecify) {
    GstMapInfo pbo_info;

    if (!gl->GenBuffers || !src->pbo) {
      gst_gl_context_set_error (context, "Cannot reinterpret texture contents "
          "without pixel buffer objects");
      gl->BindTexture (out_tex_target, 0);
      goto fbo_error;
    }

    if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2
        && (in_gl_format != GL_RGBA || in_gl_type != GL_UNSIGNED_BYTE)) {
      gst_gl_context_set_error (context, "Cannot copy non RGBA/UNSIGNED_BYTE "
          "textures on GLES2");
      gl->BindTexture (out_tex_target, 0);
      goto fbo_error;
    }

    GST_TRACE ("copying texture data with size of %u*%u*%u",
        gst_gl_format_type_n_bytes (in_gl_format, in_gl_type),
        src->mem.tex_width, GL_MEM_HEIGHT (src));

    /* copy tex */
    _read_pixels_to_pbo (src);

    src->pbo->target = GL_PIXEL_UNPACK_BUFFER;
    if (!gst_memory_map (GST_MEMORY_CAST (src->pbo), &pbo_info,
            GST_MAP_READ | GST_MAP_GL)) {
      GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Failed to map pbo for reading");
      goto fbo_error;
    }
    gl->TexSubImage2D (out_tex_target, 0, 0, 0, out_width, out_height,
        out_gl_format, out_gl_type, 0);
    gst_memory_unmap (GST_MEMORY_CAST (src->pbo), &pbo_info);
  } else {                      /* different sizes */
    gst_gl_memory_copy_teximage (GST_GL_MEMORY_CAST (src),
        tex_id, copy_params->tex_target, copy_params->out_format, out_width,
        out_height);
  }

  gl->BindTexture (out_tex_target, 0);
  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);

  gl->DeleteFramebuffers (1, &fboId);

  copy_params->tex_id = tex_id;
  copy_params->result = TRUE;

  return;

/* ERRORS */
fbo_error:
  {
    gl->DeleteFramebuffers (1, &fboId);

    copy_params->tex_id = 0;
    copy_params->result = FALSE;
    return;
  }

error:
  {
    copy_params->result = FALSE;
    return;
  }
}