Exemplo n.º 1
0
static GUBGraphicContext *gub_create_graphic_context_egl(GstPipeline *pipeline, float crop_left, float crop_top, float crop_right, float crop_bottom)
{
    static const GLfloat vVertices[] = {
        -1.f, -1.f,   0.f, 0.f,
        -1.f,  1.f,   0.f, 1.f,
         1.f, -1.f,   1.f, 0.f,
         1.f,  1.f,   1.f, 1.f
    };
    guintptr raw_context;
    GstStructure *s;
    GstGLDisplay *display;
    GstGLContext *gl_context;
    GUBGraphicContextEGL *gcontext;

    raw_context = gst_gl_context_get_current_gl_context(GST_GL_PLATFORM_EGL);
    if (!raw_context) {
        gub_log("Could not retrieve current EGL context");
        return NULL;
    }

    display = (GstGLDisplay *)gst_gl_display_egl_new();
    gl_context = gst_gl_context_new_wrapped(display, raw_context, GST_GL_PLATFORM_EGL, GST_GL_API_GLES2);
    gub_log("Current GL context is %p (GSTGL Platform %s GSTGL API %s)", raw_context,
        gst_gl_platform_to_string(gst_gl_context_get_gl_platform(gl_context)),
        gst_gl_api_to_string(gst_gl_context_get_gl_api(gl_context)));
    gub_log("VENDOR: %s", glGetString(GL_VENDOR));
    gub_log("RENDERER: %s", glGetString(GL_RENDERER));
    gub_log("VERSION: %s", glGetString(GL_VERSION));
    gub_log("GLSL VERSION: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));

    gcontext = (GUBGraphicContextEGL *)malloc(sizeof(GUBGraphicContextEGL));
    gcontext->gl = gl_context;
    gcontext->display = display;
    gcontext->crop_left = crop_left;
    gcontext->crop_top = crop_top;
    gcontext->crop_right = crop_right;
    gcontext->crop_bottom = crop_bottom;

    glGenFramebuffers(1, &gcontext->fbo);

    if (gl_context->gl_vtable->GenVertexArrays)
        gl_context->gl_vtable->GenVertexArrays(1, &gcontext->vao);
    if (gcontext->gl->gl_vtable->BindVertexArray)
        gcontext->gl->gl_vtable->BindVertexArray(gcontext->vao);

    glGenBuffers(1, &gcontext->vbo);
    glBindBuffer(GL_ARRAY_BUFFER, gcontext->vbo);
    glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), vVertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    gcontext->po = gub_create_program();

    gcontext->samplerLoc = glGetUniformLocation(gcontext->po, "sTexture");

    return gcontext;
}
Exemplo n.º 2
0
static GstPadProbeReturn
query_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
    APP_STATE_T *state = (APP_STATE_T *) user_data;
    GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);
    GstStructure *external_gl_context_desc = NULL;
    gchar *platform = NULL;
    gchar *gl_apis = NULL;

    switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_ALLOCATION:
    {
        platform = gst_gl_platform_to_string (GST_GL_PLATFORM_EGL);
        gl_apis = gst_gl_api_to_string (GST_GL_API_GLES2);

        external_gl_context_desc =
            gst_structure_new ("GstVideoGLTextureUploadMeta",
                               "gst.gl.context.handle", G_TYPE_POINTER, state->context,
                               "gst.gl.context.type", G_TYPE_STRING, platform,
                               "gst.gl.context.apis", G_TYPE_STRING, gl_apis, NULL);
        gst_query_add_allocation_meta (query,
                                       GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, external_gl_context_desc);
        gst_structure_free (external_gl_context_desc);

        g_free (gl_apis);
        g_free (platform);

        GST_DEBUG ("done alocation");
        return GST_PAD_PROBE_OK;
        break;
    }
    case GST_QUERY_CONTEXT:
    {
        return gst_gl_handle_context_query (state->pipeline, query,
                                            (GstGLDisplay **) & state->gst_display);
        break;
    }
    case GST_QUERY_DRAIN:
    {
        flush_internal (state);
        break;
    }
    default:
        break;
    }

    return GST_PAD_PROBE_OK;
}
static gboolean
gst_glimage_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
  GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (bsink);
  GstBufferPool *pool;
  GstStructure *config;
  GstCaps *caps;
  guint size;
  gboolean need_pool;
  GstStructure *gl_context;
  gchar *platform, *gl_apis;
  gpointer handle;

  if (!_ensure_gl_setup (glimage_sink))
    return FALSE;

  gst_query_parse_allocation (query, &caps, &need_pool);

  if (caps == NULL)
    goto no_caps;

  if ((pool = glimage_sink->pool))
    gst_object_ref (pool);

  if (pool != NULL) {
    GstCaps *pcaps;

    /* we had a pool, check caps */
    GST_DEBUG_OBJECT (glimage_sink, "check existing pool caps");
    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);

    if (!gst_caps_is_equal (caps, pcaps)) {
      GST_DEBUG_OBJECT (glimage_sink, "pool has different caps");
      /* different caps, we can't use this pool */
      gst_object_unref (pool);
      pool = NULL;
    }
    gst_structure_free (config);
  }

  if (pool == NULL && need_pool) {
    GstVideoInfo info;

    if (!gst_video_info_from_caps (&info, caps))
      goto invalid_caps;

    GST_DEBUG_OBJECT (glimage_sink, "create new pool");
    pool = gst_gl_buffer_pool_new (glimage_sink->context);

    /* the normal size of a frame */
    size = info.size;

    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
    if (!gst_buffer_pool_set_config (pool, config))
      goto config_failed;
  }
  /* we need at least 2 buffer because we hold on to the last one */
  gst_query_add_allocation_pool (query, pool, size, 2, 0);

  /* we also support various metadata */
  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0);

  gst_object_unref (pool);

  gl_apis =
      gst_gl_api_to_string (gst_gl_context_get_gl_api (glimage_sink->context));
  platform =
      gst_gl_platform_to_string (gst_gl_context_get_gl_platform
      (glimage_sink->context));
  handle = (gpointer) gst_gl_context_get_gl_context (glimage_sink->context);

  gl_context =
      gst_structure_new ("GstVideoGLTextureUploadMeta", "gst.gl.GstGLContext",
      GST_GL_TYPE_CONTEXT, glimage_sink->context, "gst.gl.context.handle",
      G_TYPE_POINTER, handle, "gst.gl.context.type", G_TYPE_STRING, platform,
      "gst.gl.context.apis", G_TYPE_STRING, gl_apis, NULL);
  gst_query_add_allocation_meta (query,
      GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, gl_context);

  g_free (gl_apis);
  g_free (platform);
  gst_structure_free (gl_context);

  return TRUE;

  /* ERRORS */
no_caps:
  {
    GST_DEBUG_OBJECT (bsink, "no caps specified");
    return FALSE;
  }
invalid_caps:
  {
    GST_DEBUG_OBJECT (bsink, "invalid caps specified");
    return FALSE;
  }
config_failed:
  {
    GST_DEBUG_OBJECT (bsink, "failed setting config");
    return FALSE;
  }
}
Exemplo n.º 4
0
static gboolean
gst_gl_mixer_propose_allocation (GstGLMixer * mix,
    GstQuery * decide_query, GstQuery * query)
{
  GstBufferPool *pool;
  GstStructure *config;
  GstCaps *caps;
  guint size = 0;
  gboolean need_pool;
  GError *error = NULL;
  GstStructure *gl_context;
  gchar *platform, *gl_apis;
  gpointer handle;
  GstAllocator *allocator = NULL;
  GstAllocationParams params;

  gst_query_parse_allocation (query, &caps, &need_pool);

  if (caps == NULL)
    goto no_caps;

  if ((pool = mix->priv->pool))
    gst_object_ref (pool);

  if (pool != NULL) {
    GstCaps *pcaps;

    /* we had a pool, check caps */
    GST_DEBUG_OBJECT (mix, "check existing pool caps");
    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);

    if (!gst_caps_is_equal (caps, pcaps)) {
      GST_DEBUG_OBJECT (mix, "pool has different caps");
      /* different caps, we can't use this pool */
      gst_object_unref (pool);
      pool = NULL;
    }
    gst_structure_free (config);
  }

  if (!gst_gl_ensure_display (mix, &mix->display))
    return FALSE;

  if (!mix->context) {
    mix->context = gst_gl_context_new (mix->display);
    if (!gst_gl_context_create (mix->context, NULL, &error))
      goto context_error;
  }

  if (pool == NULL && need_pool) {
    GstVideoInfo info;

    if (!gst_video_info_from_caps (&info, caps))
      goto invalid_caps;

    GST_DEBUG_OBJECT (mix, "create new pool");
    pool = gst_gl_buffer_pool_new (mix->context);

    /* the normal size of a frame */
    size = info.size;

    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
    if (!gst_buffer_pool_set_config (pool, config))
      goto config_failed;
  }

  if (pool) {
    gst_query_add_allocation_pool (query, pool, size, 1, 0);
    gst_object_unref (pool);
  }

  /* we also support various metadata */
  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0);

  gl_apis = gst_gl_api_to_string (gst_gl_context_get_gl_api (mix->context));
  platform =
      gst_gl_platform_to_string (gst_gl_context_get_gl_platform (mix->context));
  handle = (gpointer) gst_gl_context_get_gl_context (mix->context);

  gl_context =
      gst_structure_new ("GstVideoGLTextureUploadMeta", "gst.gl.GstGLContext",
      GST_GL_TYPE_CONTEXT, mix->context, "gst.gl.context.handle",
      G_TYPE_POINTER, handle, "gst.gl.context.type", G_TYPE_STRING, platform,
      "gst.gl.context.apis", G_TYPE_STRING, gl_apis, NULL);
  gst_query_add_allocation_meta (query,
      GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, gl_context);

  g_free (gl_apis);
  g_free (platform);
  gst_structure_free (gl_context);

  gst_allocation_params_init (&params);

  allocator = gst_allocator_find (GST_GL_MEMORY_ALLOCATOR);
  gst_query_add_allocation_param (query, allocator, &params);
  gst_object_unref (allocator);

  return TRUE;

  /* ERRORS */
no_caps:
  {
    GST_DEBUG_OBJECT (mix, "no caps specified");
    return FALSE;
  }
invalid_caps:
  {
    GST_DEBUG_OBJECT (mix, "invalid caps specified");
    return FALSE;
  }
config_failed:
  {
    GST_DEBUG_OBJECT (mix, "failed setting config");
    return FALSE;
  }
context_error:
  {
    GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", error->message),
        (NULL));
    return FALSE;
  }
}