Blame tests/check/libs/gstglupload.c

Packit 971217
/* GStreamer
Packit 971217
 *
Packit 971217
 * Copyright (C) 2014 Matthew Waters <ystreet00@gmail.com>
Packit 971217
 *
Packit 971217
 * This library is free software; you can redistribute it and/or
Packit 971217
 * modify it under the terms of the GNU Library General Public
Packit 971217
 * License as published by the Free Software Foundation; either
Packit 971217
 * version 2 of the License, or (at your option) any later version.
Packit 971217
 *
Packit 971217
 * This library is distributed in the hope that it will be useful,
Packit 971217
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 971217
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 971217
 * Library General Public License for more details.
Packit 971217
 *
Packit 971217
 * You should have received a copy of the GNU Library General Public
Packit 971217
 * License along with this library; if not, write to the
Packit 971217
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 971217
 * Boston, MA 02110-1301, USA.
Packit 971217
 */
Packit 971217
Packit 971217
#ifdef HAVE_CONFIG_H
Packit 971217
#  include "config.h"
Packit 971217
#endif
Packit 971217
Packit 971217
#include <gst/check/gstcheck.h>
Packit 971217
#include <gst/gl/gstglfuncs.h>
Packit 971217
Packit 971217
#include <gst/gl/gl.h>
Packit 971217
Packit 971217
#include <stdio.h>
Packit 971217
Packit 971217
static GstGLDisplay *display;
Packit 971217
static GstGLContext *context;
Packit 971217
static GstGLWindow *window;
Packit 971217
static GstGLUpload *upload;
Packit 971217
static guint tex_id;
Packit 971217
static GstGLShader *shader;
Packit 971217
static GLint shader_attr_position_loc;
Packit 971217
static GLint shader_attr_texture_loc;
Packit 971217
static guint vbo, vbo_indices, vao;
Packit 971217
static GstGLFramebuffer *fbo;
Packit 971217
static GstGLMemory *fbo_tex;
Packit 971217
Packit 971217
static const GLfloat vertices[] = {
Packit 971217
  1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
Packit 971217
  -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
Packit 971217
  -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
Packit 971217
  1.0f, -1.0f, 0.0f, 1.0f, 1.0f
Packit 971217
};
Packit 971217
Packit 971217
static GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
Packit 971217
Packit 971217
#define FORMAT GST_GL_RGBA
Packit 971217
#define WIDTH 10
Packit 971217
#define HEIGHT 10
Packit 971217
#define RED 0xff, 0x00, 0x00, 0xff
Packit 971217
#define GREEN 0x00, 0xff, 0x00, 0xff
Packit 971217
#define BLUE 0x00, 0x00, 0xff, 0xff
Packit 971217
Packit 971217
static gchar rgba_data[] =
Packit 971217
    { RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
Packit 971217
  GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN,
Packit 971217
  BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE,
Packit 971217
  RED, RED, RED, RED, RED, RED, RED, RED, RED, RED,
Packit 971217
  GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN,
Packit 971217
  BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE, BLUE,
Packit 971217
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
Packit 971217
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
Packit 971217
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED,
Packit 971217
  RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE, RED
Packit 971217
};
Packit 971217
Packit 971217
static void
Packit 971217
setup (void)
Packit 971217
{
Packit 971217
  GError *error = NULL;
Packit 971217
Packit 971217
  display = gst_gl_display_new ();
Packit 971217
  context = gst_gl_context_new (display);
Packit 971217
Packit 971217
  gst_gl_context_create (context, 0, &error);
Packit 971217
  window = gst_gl_context_get_window (context);
Packit 971217
Packit 971217
  fail_if (error != NULL, "Error creating context: %s\n",
Packit 971217
      error ? error->message : "Unknown Error");
Packit 971217
Packit 971217
  upload = gst_gl_upload_new (context);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
_check_gl_error (GstGLContext * context, gpointer data)
Packit 971217
{
Packit 971217
  GLuint error = context->gl_vtable->GetError ();
Packit 971217
  fail_if (error != GL_NONE, "GL error 0x%x encountered during processing\n",
Packit 971217
      error);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
teardown (void)
Packit 971217
{
Packit 971217
  gst_object_unref (upload);
Packit 971217
  gst_object_unref (window);
Packit 971217
Packit 971217
  gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _check_gl_error,
Packit 971217
      NULL);
Packit 971217
  gst_object_unref (context);
Packit 971217
  gst_object_unref (display);
Packit 971217
  if (shader)
Packit 971217
    gst_object_unref (shader);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
_bind_buffer (GstGLContext * context)
Packit 971217
{
Packit 971217
  const GstGLFuncs *gl = context->gl_vtable;
Packit 971217
Packit 971217
  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
Packit 971217
  gl->BindBuffer (GL_ARRAY_BUFFER, vbo);
Packit 971217
Packit 971217
  /* Load the vertex position */
Packit 971217
  gl->VertexAttribPointer (shader_attr_position_loc, 3, GL_FLOAT, GL_FALSE,
Packit 971217
      5 * sizeof (GLfloat), (void *) 0);
Packit 971217
Packit 971217
  /* Load the texture coordinate */
Packit 971217
  gl->VertexAttribPointer (shader_attr_texture_loc, 2, GL_FLOAT, GL_FALSE,
Packit 971217
      5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat)));
Packit 971217
Packit 971217
  gl->EnableVertexAttribArray (shader_attr_position_loc);
Packit 971217
  gl->EnableVertexAttribArray (shader_attr_texture_loc);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
_unbind_buffer (GstGLContext * context)
Packit 971217
{
Packit 971217
  const GstGLFuncs *gl = context->gl_vtable;
Packit 971217
Packit 971217
  gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
Packit 971217
  gl->BindBuffer (GL_ARRAY_BUFFER, 0);
Packit 971217
Packit 971217
  gl->DisableVertexAttribArray (shader_attr_position_loc);
Packit 971217
  gl->DisableVertexAttribArray (shader_attr_texture_loc);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
init (gpointer data)
Packit 971217
{
Packit 971217
  const GstGLFuncs *gl = context->gl_vtable;
Packit 971217
  GError *error = NULL;
Packit 971217
Packit 971217
  shader = gst_gl_shader_new_default (context, &error);
Packit 971217
  fail_if (shader == NULL, "failed to create shader object %s", error->message);
Packit 971217
Packit 971217
  shader_attr_position_loc =
Packit 971217
      gst_gl_shader_get_attribute_location (shader, "a_position");
Packit 971217
  shader_attr_texture_loc =
Packit 971217
      gst_gl_shader_get_attribute_location (shader, "a_texcoord");
Packit 971217
Packit 971217
  fbo = gst_gl_framebuffer_new_with_default_depth (context, WIDTH, HEIGHT);
Packit 971217
Packit 971217
  {
Packit 971217
    GstGLMemoryAllocator *allocator;
Packit 971217
    GstGLVideoAllocationParams *params;
Packit 971217
    GstVideoInfo v_info;
Packit 971217
Packit 971217
    allocator = gst_gl_memory_allocator_get_default (context);
Packit 971217
    gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, WIDTH, HEIGHT);
Packit 971217
    params =
Packit 971217
        gst_gl_video_allocation_params_new (context, NULL, &v_info, 0, NULL,
Packit 971217
        GST_GL_TEXTURE_TARGET_2D, FORMAT);
Packit 971217
    fbo_tex =
Packit 971217
        (GstGLMemory *) gst_gl_base_memory_alloc ((GstGLBaseMemoryAllocator *)
Packit 971217
        allocator, (GstGLAllocationParams *) params);
Packit 971217
    gst_object_unref (allocator);
Packit 971217
    gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
Packit 971217
  }
Packit 971217
Packit 971217
  if (!vbo) {
Packit 971217
    if (gl->GenVertexArrays) {
Packit 971217
      gl->GenVertexArrays (1, &vao;;
Packit 971217
      gl->BindVertexArray (vao);
Packit 971217
    }
Packit 971217
Packit 971217
    gl->GenBuffers (1, &vbo);
Packit 971217
    gl->BindBuffer (GL_ARRAY_BUFFER, vbo);
Packit 971217
    gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), vertices,
Packit 971217
        GL_STATIC_DRAW);
Packit 971217
Packit 971217
    gl->GenBuffers (1, &vbo_indices);
Packit 971217
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo_indices);
Packit 971217
    gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices,
Packit 971217
        GL_STATIC_DRAW);
Packit 971217
Packit 971217
    if (gl->GenVertexArrays) {
Packit 971217
      _bind_buffer (context);
Packit 971217
      gl->BindVertexArray (0);
Packit 971217
    }
Packit 971217
Packit 971217
    gl->BindBuffer (GL_ARRAY_BUFFER, 0);
Packit 971217
    gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
deinit (gpointer data)
Packit 971217
{
Packit 971217
  GstGLContext *context = data;
Packit 971217
  const GstGLFuncs *gl = context->gl_vtable;
Packit 971217
Packit 971217
  if (vbo)
Packit 971217
    gl->DeleteBuffers (1, &vbo);
Packit 971217
  vbo = 0;
Packit 971217
  if (vbo_indices)
Packit 971217
    gl->DeleteBuffers (1, &vbo_indices);
Packit 971217
  vbo_indices = 0;
Packit 971217
  if (vao)
Packit 971217
    gl->DeleteVertexArrays (1, &vao;;
Packit 971217
  vao = 0;
Packit 971217
Packit 971217
  if (fbo)
Packit 971217
    gst_object_unref (fbo);
Packit 971217
  fbo = NULL;
Packit 971217
Packit 971217
  if (fbo_tex)
Packit 971217
    gst_memory_unref (GST_MEMORY_CAST (fbo_tex));
Packit 971217
  fbo_tex = NULL;
Packit 971217
}
Packit 971217
Packit 971217
static gboolean
Packit 971217
blit_tex (gpointer data)
Packit 971217
{
Packit 971217
  GstGLContext *context = data;
Packit 971217
  const GstGLFuncs *gl = context->gl_vtable;
Packit 971217
Packit 971217
  gl->Clear (GL_COLOR_BUFFER_BIT);
Packit 971217
Packit 971217
  gst_gl_shader_use (shader);
Packit 971217
Packit 971217
  if (gl->GenVertexArrays)
Packit 971217
    gl->BindVertexArray (vao);
Packit 971217
  _bind_buffer (context);
Packit 971217
Packit 971217
  gl->ActiveTexture (GL_TEXTURE0);
Packit 971217
  gl->BindTexture (GL_TEXTURE_2D, tex_id);
Packit 971217
  gst_gl_shader_set_uniform_1i (shader, "s_texture", 0);
Packit 971217
Packit 971217
  gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
Packit 971217
Packit 971217
  if (gl->GenVertexArrays)
Packit 971217
    gl->BindVertexArray (0);
Packit 971217
  _unbind_buffer (context);
Packit 971217
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
draw_render (gpointer data)
Packit 971217
{
Packit 971217
  gst_gl_framebuffer_draw_to_texture (fbo, fbo_tex,
Packit 971217
      (GstGLFramebufferFunc) blit_tex, data);
Packit 971217
}
Packit 971217
Packit 971217
GST_START_TEST (test_upload_data)
Packit 971217
{
Packit 971217
  GstCaps *in_caps, *out_caps;
Packit 971217
  GstBuffer *inbuf, *outbuf;
Packit 971217
  GstMapInfo map_info;
Packit 971217
  gboolean res;
Packit 971217
  gint i = 0;
Packit 971217
Packit 971217
  in_caps = gst_caps_from_string ("video/x-raw,format=RGBA,"
Packit 971217
      "width=10,height=10");
Packit 971217
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
Packit 971217
      "format=RGBA,width=10,height=10");
Packit 971217
Packit 971217
  gst_gl_upload_set_caps (upload, in_caps, out_caps);
Packit 971217
Packit 971217
  inbuf = gst_buffer_new_wrapped_full (0, rgba_data, WIDTH * HEIGHT * 4,
Packit 971217
      0, WIDTH * HEIGHT * 4, NULL, NULL);
Packit 971217
Packit 971217
  res = gst_gl_upload_perform_with_buffer (upload, inbuf, &outbuf);
Packit 971217
  fail_if (res == FALSE, "Failed to upload buffer");
Packit 971217
  fail_unless (GST_IS_BUFFER (outbuf));
Packit 971217
Packit 971217
  res = gst_buffer_map (outbuf, &map_info, GST_MAP_READ | GST_MAP_GL);
Packit 971217
  fail_if (res == FALSE, "Failed to map gl memory");
Packit 971217
Packit 971217
  tex_id = *(guint *) map_info.data;
Packit 971217
Packit 971217
  gst_buffer_unmap (outbuf, &map_info);
Packit 971217
Packit 971217
  gst_gl_window_set_preferred_size (window, WIDTH, HEIGHT);
Packit 971217
  gst_gl_window_draw (window);
Packit 971217
Packit 971217
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init), context);
Packit 971217
Packit 971217
  while (i < 2) {
Packit 971217
    gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
Packit 971217
        context);
Packit 971217
    i++;
Packit 971217
  }
Packit 971217
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit), context);
Packit 971217
Packit 971217
  gst_caps_unref (in_caps);
Packit 971217
  gst_caps_unref (out_caps);
Packit 971217
  gst_buffer_unref (inbuf);
Packit 971217
  gst_buffer_unref (outbuf);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST;
Packit 971217
Packit 971217
GST_START_TEST (test_upload_gl_memory)
Packit 971217
{
Packit 971217
  GstGLBaseMemoryAllocator *base_mem_alloc;
Packit 971217
  GstGLVideoAllocationParams *params;
Packit 971217
  GstBuffer *buffer, *outbuf;
Packit 971217
  GstGLMemory *gl_mem;
Packit 971217
  GstCaps *in_caps, *out_caps;
Packit 971217
  GstStructure *out_s;
Packit 971217
  GstVideoInfo in_info;
Packit 971217
  GstMapInfo map_info;
Packit 971217
  gint i = 0;
Packit 971217
  gboolean res;
Packit 971217
Packit 971217
  base_mem_alloc =
Packit 971217
      GST_GL_BASE_MEMORY_ALLOCATOR (gst_allocator_find
Packit 971217
      (GST_GL_MEMORY_ALLOCATOR_NAME));
Packit 971217
Packit 971217
  in_caps = gst_caps_from_string ("video/x-raw,format=RGBA,width=10,height=10");
Packit 971217
  gst_video_info_from_caps (&in_info, in_caps);
Packit 971217
Packit 971217
  /* create GL buffer */
Packit 971217
  buffer = gst_buffer_new ();
Packit 971217
  params = gst_gl_video_allocation_params_new_wrapped_data (context, NULL,
Packit 971217
      &in_info, 0, NULL, GST_GL_TEXTURE_TARGET_2D,
Packit 971217
      GST_GL_RGBA, rgba_data, NULL, NULL);
Packit 971217
  gl_mem = (GstGLMemory *) gst_gl_base_memory_alloc (base_mem_alloc,
Packit 971217
      (GstGLAllocationParams *) params);
Packit 971217
  gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
Packit 971217
Packit 971217
  res =
Packit 971217
      gst_memory_map ((GstMemory *) gl_mem, &map_info,
Packit 971217
      GST_MAP_READ | GST_MAP_GL);
Packit 971217
  fail_if (res == FALSE, "Failed to map gl memory\n");
Packit 971217
  tex_id = *(guint *) map_info.data;
Packit 971217
  gst_memory_unmap ((GstMemory *) gl_mem, &map_info);
Packit 971217
Packit 971217
  gst_buffer_append_memory (buffer, (GstMemory *) gl_mem);
Packit 971217
Packit 971217
  /* at this point glupload hasn't received any buffers so can output anything */
Packit 971217
  out_caps = gst_gl_upload_transform_caps (upload, context,
Packit 971217
      GST_PAD_SINK, in_caps, NULL);
Packit 971217
  out_s = gst_caps_get_structure (out_caps, 0);
Packit 971217
  fail_unless (gst_structure_has_field_typed (out_s, "texture-target",
Packit 971217
          GST_TYPE_LIST));
Packit 971217
  gst_caps_unref (out_caps);
Packit 971217
Packit 971217
  /* set some output caps without setting texture-target: this should trigger RECONFIGURE */
Packit 971217
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
Packit 971217
      "format=RGBA,width=10,height=10");
Packit 971217
Packit 971217
  /* set caps with texture-target not fixed. This should trigger RECONFIGURE. */
Packit 971217
  gst_gl_upload_set_caps (upload, in_caps, out_caps);
Packit 971217
  gst_caps_unref (out_caps);
Packit 971217
Packit 971217
  /* push a texture-target=2D buffer */
Packit 971217
  res = gst_gl_upload_perform_with_buffer (upload, buffer, &outbuf);
Packit 971217
  fail_unless (res == GST_GL_UPLOAD_RECONFIGURE);
Packit 971217
  fail_if (outbuf);
Packit 971217
Packit 971217
  /* now glupload has seen a 2D buffer and so wants to transform to that */
Packit 971217
  out_caps = gst_gl_upload_transform_caps (upload, context,
Packit 971217
      GST_PAD_SINK, in_caps, NULL);
Packit 971217
  out_s = gst_caps_get_structure (out_caps, 0);
Packit 971217
  fail_unless_equals_string (gst_structure_get_string (out_s, "texture-target"),
Packit 971217
      "2D");
Packit 971217
  gst_caps_unref (out_caps);
Packit 971217
Packit 971217
  /* try setting the wrong type first tho */
Packit 971217
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
Packit 971217
      "format=RGBA,width=10,height=10,texture-target=RECTANGLE");
Packit 971217
  gst_gl_upload_set_caps (upload, in_caps, out_caps);
Packit 971217
  gst_caps_unref (out_caps);
Packit 971217
Packit 971217
  res = gst_gl_upload_perform_with_buffer (upload, buffer, &outbuf);
Packit 971217
  fail_unless (res == GST_GL_UPLOAD_RECONFIGURE);
Packit 971217
  fail_if (outbuf);
Packit 971217
Packit 971217
  /* finally do set the correct texture-target */
Packit 971217
  out_caps = gst_caps_from_string ("video/x-raw(memory:GLMemory),"
Packit 971217
      "format=RGBA,width=10,height=10,texture-target=2D");
Packit 971217
  gst_gl_upload_set_caps (upload, in_caps, out_caps);
Packit 971217
  gst_caps_unref (out_caps);
Packit 971217
Packit 971217
  res = gst_gl_upload_perform_with_buffer (upload, buffer, &outbuf);
Packit 971217
  fail_unless (res == GST_GL_UPLOAD_DONE, "Failed to upload buffer");
Packit 971217
  fail_unless (GST_IS_BUFFER (outbuf));
Packit 971217
Packit 971217
  gst_gl_window_set_preferred_size (window, WIDTH, HEIGHT);
Packit 971217
  gst_gl_window_draw (window);
Packit 971217
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (init), context);
Packit 971217
Packit 971217
  while (i < 2) {
Packit 971217
    gst_gl_window_send_message (window, GST_GL_WINDOW_CB (draw_render),
Packit 971217
        context);
Packit 971217
    i++;
Packit 971217
  }
Packit 971217
  gst_gl_window_send_message (window, GST_GL_WINDOW_CB (deinit), context);
Packit 971217
Packit 971217
  gst_caps_unref (in_caps);
Packit 971217
  gst_buffer_unref (buffer);
Packit 971217
  gst_buffer_unref (outbuf);
Packit 971217
  gst_object_unref (base_mem_alloc);
Packit 971217
}
Packit 971217
Packit 971217
GST_END_TEST;
Packit 971217
Packit 971217
Packit 971217
static Suite *
Packit 971217
gst_gl_upload_suite (void)
Packit 971217
{
Packit 971217
  Suite *s = suite_create ("GstGLUpload");
Packit 971217
  TCase *tc_chain = tcase_create ("upload");
Packit 971217
Packit 971217
  suite_add_tcase (s, tc_chain);
Packit 971217
  tcase_add_checked_fixture (tc_chain, setup, teardown);
Packit 971217
  tcase_add_test (tc_chain, test_upload_data);
Packit 971217
  tcase_add_test (tc_chain, test_upload_gl_memory);
Packit 971217
Packit 971217
  return s;
Packit 971217
}
Packit 971217
Packit 971217
GST_CHECK_MAIN (gst_gl_upload);