示例#1
0
static GstGLMemoryEGL *
_gl_mem_egl_alloc (GstGLBaseMemoryAllocator * allocator,
                   GstGLVideoAllocationParams * params)
{
    guint alloc_flags = params->parent.alloc_flags;
    GstGLMemoryEGL *mem;

    g_return_val_if_fail (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO,
                          NULL);
    g_return_val_if_fail ((alloc_flags &
                           GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM) == 0, NULL);
    if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) {
        g_return_val_if_fail (GST_IS_EGL_IMAGE (params->parent.gl_handle), NULL);
    }

    mem = g_new0 (GstGLMemoryEGL, 1);
    if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) {
        if (params->target != GST_GL_TEXTURE_TARGET_2D) {
            g_free (mem);
            GST_CAT_ERROR (GST_CAT_GL_MEMORY, "GstGLMemoryEGL only supports wrapping "
                           "2D textures");
            return NULL;
        }
        mem->image = gst_egl_image_ref (params->parent.gl_handle);
    }

    gst_gl_memory_init (GST_GL_MEMORY_CAST (mem), GST_ALLOCATOR_CAST (allocator),
                        NULL, params->parent.context, params->target, params->tex_type,
                        params->parent.alloc_params, params->v_info, params->plane,
                        params->valign, params->parent.user_data, params->parent.notify);

    return mem;
}
示例#2
0
static void
_upload_pbo_memory (GstGLMemoryPBO * gl_mem, GstMapInfo * info,
    GstGLBuffer * pbo, GstMapInfo * pbo_info)
{
  GstGLContext *context = gl_mem->mem.mem.context;
  const GstGLFuncs *gl;
  guint pbo_id;

  if (!GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD))
    return;

  g_return_if_fail (CONTEXT_SUPPORTS_PBO_UPLOAD (context));

  gl = context->gl_vtable;
  pbo_id = *(guint *) pbo_info->data;

  GST_CAT_LOG (GST_CAT_GL_MEMORY, "upload for texture id:%u, with pbo %u %ux%u",
      gl_mem->mem.tex_id, pbo_id, gl_mem->mem.tex_width,
      GL_MEM_HEIGHT (gl_mem));

  gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, pbo_id);
  gst_gl_memory_texsubimage (GST_GL_MEMORY_CAST (gl_mem), NULL);
  gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
}
示例#3
0
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;
  }
}