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; }
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; } }
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 (¶ms); allocator = gst_allocator_find (GST_GL_MEMORY_ALLOCATOR); gst_query_add_allocation_param (query, allocator, ¶ms); 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; } }