示例#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
guint
gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
    guint format, guint type)
{
  gboolean ext_texture_rg =
      gst_gl_context_check_feature (context, "GL_EXT_texture_rg");

  switch (format) {
    case GL_RGBA:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          return USING_GLES2 (context)
              && !USING_GLES3 (context) ? GL_RGBA : GL_RGBA8;
          break;
      }
      break;
    case GL_RGB:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          return GL_RGB8;
          break;
        case GL_UNSIGNED_SHORT_5_6_5:
          return GL_RGB;
          break;
      }
      break;
    case GL_RG:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
            return GL_RG;
          return GL_RG8;
          break;
      }
      break;
    case GL_RED:
      switch (type) {
        case GL_UNSIGNED_BYTE:
          if (!USING_GLES3 (context) && USING_GLES2 (context) && ext_texture_rg)
            return GL_RED;
          return GL_R8;
          break;
      }
      break;
    case GL_LUMINANCE:
      return GL_LUMINANCE;
      break;
    case GL_LUMINANCE_ALPHA:
      return GL_LUMINANCE_ALPHA;
      break;
    case GL_ALPHA:
      return GL_ALPHA;
      break;
    default:
      break;
  }

  g_assert_not_reached ();
  return 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);
  }
}
示例#4
0
static gboolean
_init_download (GstGLDownload * download)
{
  GstVideoFormat v_format;
  guint out_width, out_height;
  GstVideoInfo in_info;

  v_format = GST_VIDEO_INFO_FORMAT (&download->info);
  out_width = GST_VIDEO_INFO_WIDTH (&download->info);
  out_height = GST_VIDEO_INFO_HEIGHT (&download->info);

  if (download->initted)
    return TRUE;

  GST_TRACE ("initializing texture download for format %s",
      gst_video_format_to_string (v_format));

  if (USING_GLES2 (download->context) && !USING_GLES3 (download->context)) {
    /* GL_RGBA is the only officially supported texture format in GLES2 */
    if (v_format == GST_VIDEO_FORMAT_RGB || v_format == GST_VIDEO_FORMAT_BGR) {
      gst_gl_context_set_error (download->context, "Cannot download RGB "
          "textures in GLES2");
      return FALSE;
    }
  }

  gst_video_info_set_format (&in_info, GST_VIDEO_FORMAT_RGBA, out_width,
      out_height);

  gst_gl_color_convert_set_format (download->convert, &in_info,
      &download->info);

  return TRUE;
}
示例#5
0
static void
_upload_memory (GstGLContext * context, GstGLMemory * gl_mem)
{
  const GstGLFuncs *gl;
  GLenum gl_format, gl_type;

  if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
    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);

  if (USING_OPENGL (context) || USING_GLES3 (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_CAT_LOG (GST_CAT_GL_MEMORY, "upload for texture id:%u, %ux%u",
      gl_mem->tex_id, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem));

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

  /* 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_TEXTURE_2D, 0);

  GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
}
示例#6
0
static inline void
_calculate_unpack_length (GstGLMemory * gl_mem)
{
  guint n_gl_bytes;

  gl_mem->tex_scaling[0] = 1.0f;
  gl_mem->tex_scaling[1] = 1.0f;
  gl_mem->unpack_length = 1;
  gl_mem->tex_width = GL_MEM_WIDTH (gl_mem);

  n_gl_bytes = _gl_texture_type_n_bytes (gl_mem->tex_type);
  if (n_gl_bytes == 0) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Unsupported texture type %d",
        gl_mem->tex_type);
    return;
  }

  if (USING_OPENGL (gl_mem->context) || USING_GLES3 (gl_mem->context)) {
    gl_mem->unpack_length = GL_MEM_STRIDE (gl_mem) / n_gl_bytes;
  } else if (USING_GLES2 (gl_mem->context)) {
    guint j = 8;

    while (j >= n_gl_bytes) {
      /* GST_ROUND_UP_j(GL_MEM_WIDTH (gl_mem) * n_gl_bytes) */
      guint round_up_j =
          ((GL_MEM_WIDTH (gl_mem) * n_gl_bytes) + j - 1) & ~(j - 1);

      if (round_up_j == GL_MEM_STRIDE (gl_mem)) {
        GST_CAT_LOG (GST_CAT_GL_MEMORY, "Found alignment of %u based on width "
            "(with plane width:%u, plane stride:%u and pixel stride:%u. "
            "RU%u(%u*%u) = %u)", j, GL_MEM_WIDTH (gl_mem),
            GL_MEM_STRIDE (gl_mem), n_gl_bytes, j, GL_MEM_WIDTH (gl_mem),
            n_gl_bytes, round_up_j);

        gl_mem->unpack_length = j;
        break;
      }
      j >>= 1;
    }

    if (j < n_gl_bytes) {
      /* Failed to find a suitable alignment, try based on plane_stride and
       * scale in the shader.  Useful for alignments that are greater than 8.
       */
      j = 8;

      while (j >= n_gl_bytes) {
        /* GST_ROUND_UP_j((GL_MEM_STRIDE (gl_mem)) */
        guint round_up_j = ((GL_MEM_STRIDE (gl_mem)) + j - 1) & ~(j - 1);

        if (round_up_j == (GL_MEM_STRIDE (gl_mem))) {
          GST_CAT_LOG (GST_CAT_GL_MEMORY, "Found alignment of %u based on "
              "stride (with plane stride:%u and pixel stride:%u. "
              "RU%u(%u) = %u)", j, GL_MEM_STRIDE (gl_mem), n_gl_bytes, j,
              GL_MEM_STRIDE (gl_mem), round_up_j);

          gl_mem->unpack_length = j;
          gl_mem->tex_scaling[0] =
              (gfloat) (GL_MEM_WIDTH (gl_mem) * n_gl_bytes) /
              (gfloat) GL_MEM_STRIDE (gl_mem);
          gl_mem->tex_width = GL_MEM_STRIDE (gl_mem) / n_gl_bytes;
          break;
        }
        j >>= 1;
      }

      if (j < n_gl_bytes) {
        GST_CAT_ERROR
            (GST_CAT_GL_MEMORY, "Failed to find matching alignment. Image may "
            "look corrupted. plane width:%u, plane stride:%u and pixel "
            "stride:%u", GL_MEM_WIDTH (gl_mem), GL_MEM_STRIDE (gl_mem),
            n_gl_bytes);
      }
    }