コード例 #1
0
static void
_upload_memory (GstGLMemory * gl_mem, GstMapInfo * info, gsize maxsize)
{
  GstGLContext *context = gl_mem->mem.context;
  const GstGLFuncs *gl;
  GLenum gl_format, gl_type, gl_target;
  gpointer data;
  gsize plane_start;

  if ((gl_mem->transfer_state & GST_GL_MEMORY_TRANSFER_NEED_UPLOAD) == 0)
    return;

  gl = context->gl_vtable;

  gl_type = GL_UNSIGNED_BYTE;
  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    gl_type = GL_UNSIGNED_SHORT_5_6_5;

  gl_format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
  gl_target = gl_mem->tex_target;

  if (USING_OPENGL (context) || USING_GLES3 (context)
      || USING_OPENGL3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->unpack_length);
  } else if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->unpack_length);
  }

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

  /* find the start of the plane data including padding */
  plane_start = _find_plane_frame_start (gl_mem);

  if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context)) {
    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, gl_mem->mem.id);
    data = (void *) plane_start;
  } else {
    data = (gpointer) ((gintptr) plane_start + (gintptr) gl_mem->mem.data);
  }

  gl->BindTexture (gl_target, gl_mem->tex_id);
  gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->tex_width,
      GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, data);

  if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context))
    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);

  /* Reset to default values */
  if (USING_OPENGL (context) || USING_GLES3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0);
  } else if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4);
  }

  gl->BindTexture (gl_target, 0);

  gl_mem->transfer_state &= ~GST_GL_MEMORY_TRANSFER_NEED_UPLOAD;
}
コード例 #2
0
static gpointer
_gl_mem_map_gpu_access (GstGLMemoryPBO * gl_mem, GstMapInfo * info, gsize size)
{
  gpointer data = &gl_mem->mem.tex_id;

  if ((info->flags & GST_MAP_READ) == GST_MAP_READ) {
    if (gl_mem->pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (gl_mem->mem.mem.context)) {
      GstMapInfo pbo_info;

      /* data -> pbo */
      if (!gst_memory_map (GST_MEMORY_CAST (gl_mem->pbo), &pbo_info,
              GST_MAP_READ | GST_MAP_GL)) {
        GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Failed to map pbo");
        return NULL;
      }

      /* pbo -> texture */
      _upload_pbo_memory (gl_mem, info, gl_mem->pbo, &pbo_info);

      gst_memory_unmap (GST_MEMORY_CAST (gl_mem->pbo), &pbo_info);
    } else {
      GstGLMemoryAllocatorClass *alloc_class;

      alloc_class = GST_GL_MEMORY_ALLOCATOR_CLASS (parent_class);

      data = alloc_class->map ((GstGLBaseMemory *) gl_mem, info, size);
    }
  }

  return data;
}
コード例 #3
0
/**
 * gst_gl_memory_pbo_download_transfer:
 * @gl_mem: a #GstGLMemoryPBO
 *
 * Transfer the texture data from the PBO into the texture if necessary.
 *
 * Since: 1.8
 */
void
gst_gl_memory_pbo_upload_transfer (GstGLMemoryPBO * gl_mem)
{
  g_return_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem));

  if (gl_mem->pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (gl_mem->mem.mem.context))
    gst_gl_context_thread_add (gl_mem->mem.mem.context,
        (GstGLContextThreadFunc) _upload_transfer, gl_mem);
}
コード例 #4
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 gl_format, gl_type, gl_target;
  guint pbo_id;
  gsize plane_start;

  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;

  gl_type = GL_UNSIGNED_BYTE;
  if (gl_mem->mem.tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    gl_type = GL_UNSIGNED_SHORT_5_6_5;

  gl_format = gst_gl_format_from_gl_texture_type (gl_mem->mem.tex_type);
  gl_target = gst_gl_texture_target_to_gl (gl_mem->mem.tex_target);

  if (USING_OPENGL (context) || USING_GLES3 (context)
      || USING_OPENGL3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->mem.unpack_length);
  } else if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->mem.unpack_length);
  }

  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));

  /* find the start of the plane data including padding */
  plane_start =
      gst_gl_get_plane_start (&gl_mem->mem.info, &gl_mem->mem.valign,
      gl_mem->mem.plane) + GST_MEMORY_CAST (gl_mem)->offset;

  gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, pbo_id);
  gl->BindTexture (gl_target, gl_mem->mem.tex_id);
  gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->mem.tex_width,
      GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, (void *) plane_start);
  gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
  gl->BindTexture (gl_target, 0);

  /* Reset to default values */
  if (USING_OPENGL (context) || USING_GLES3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0);
  } else if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4);
  }
}
コード例 #5
0
static gboolean
_gl_mem_create (GstGLMemoryPBO * gl_mem, GError ** error)
{
  GstGLContext *context = gl_mem->mem.mem.context;
  GstGLBaseMemoryAllocatorClass *alloc_class;

  alloc_class = GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class);
  if (!alloc_class->create ((GstGLBaseMemory *) gl_mem, error))
    return FALSE;

  if (CONTEXT_SUPPORTS_PBO_DOWNLOAD (context)
      || CONTEXT_SUPPORTS_PBO_UPLOAD (context)) {
    GstAllocationParams alloc_params =
        { 0, GST_MEMORY_CAST (gl_mem)->align, 0, 0 };
    GstGLBaseMemoryAllocator *buf_allocator;
    GstGLBufferAllocationParams *params;

    buf_allocator =
        GST_GL_BASE_MEMORY_ALLOCATOR (gst_allocator_find
        (GST_GL_BUFFER_ALLOCATOR_NAME));
    params =
        gst_gl_buffer_allocation_params_new (context,
        GST_MEMORY_CAST (gl_mem)->size, &alloc_params, GL_PIXEL_UNPACK_BUFFER,
        GL_STREAM_DRAW);

    /* FIXME: lazy init this for resource constrained platforms
     * Will need to fix pbo detection based on the existence of the mem.id then */
    gl_mem->pbo = (GstGLBuffer *) gst_gl_base_memory_alloc (buf_allocator,
        (GstGLAllocationParams *) params);

    gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
    gst_object_unref (buf_allocator);

    GST_CAT_LOG (GST_CAT_GL_MEMORY, "generated pbo %u", gl_mem->pbo->id);
  }

  return TRUE;
}
コード例 #6
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);
}