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);
  }
}
Example #2
0
static gboolean
_read_pixels_to_pbo (GstGLMemoryPBO * gl_mem)
{
  if (!gl_mem->pbo || !CONTEXT_SUPPORTS_PBO_DOWNLOAD (gl_mem->mem.mem.context)
      || gl_mem->mem.tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
      || gl_mem->mem.tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA)
    /* unsupported */
    return FALSE;

  if (GST_MEMORY_FLAG_IS_SET (gl_mem,
          GST_GL_BASE_MEMORY_TRANSFER_NEED_DOWNLOAD)) {
    /* copy texture data into into the pbo and map that */
    gsize plane_start;
    GstMapInfo pbo_info;

    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_mem->pbo->target = GL_PIXEL_PACK_BUFFER;
    if (!gst_memory_map (GST_MEMORY_CAST (gl_mem->pbo), &pbo_info,
            GST_MAP_WRITE | GST_MAP_GL)) {
      GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Failed to map pbo for writing");
      return FALSE;
    }

    if (!gst_gl_memory_read_pixels ((GstGLMemory *) gl_mem,
            (gpointer) plane_start)) {
      gst_memory_unmap (GST_MEMORY_CAST (gl_mem->pbo), &pbo_info);
      return FALSE;
    }

    gst_memory_unmap (GST_MEMORY_CAST (gl_mem->pbo), &pbo_info);
  }

  return TRUE;
}