static gboolean gst_eglimage_to_gl_texture_upload_meta (GstVideoGLTextureUploadMeta * meta, guint texture_id[4]) { gint i = 0; gint n = 0; g_return_val_if_fail (meta != NULL, FALSE); g_return_val_if_fail (texture_id != NULL, FALSE); GST_DEBUG ("Uploading for meta with textures %i,%i,%i,%i", texture_id[0], texture_id[1], texture_id[2], texture_id[3]); n = gst_buffer_n_memory (meta->buffer); for (i = 0; i < n; i++) { GstMemory *mem = gst_buffer_peek_memory (meta->buffer, i); const GstGLFuncs *gl = NULL; if (!gst_is_egl_image_memory (mem)) { GST_WARNING ("memory %p does not hold an EGLImage", mem); return FALSE; } gl = GST_GL_CONTEXT (GST_EGL_IMAGE_MEMORY (mem)->context)->gl_vtable; gl->ActiveTexture (GL_TEXTURE0 + i); gl->BindTexture (GL_TEXTURE_2D, texture_id[i]); gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, gst_egl_image_memory_get_image (mem)); } if (GST_IS_GL_BUFFER_POOL (meta->buffer->pool)) gst_gl_buffer_pool_replace_last_buffer (GST_GL_BUFFER_POOL (meta-> buffer->pool), meta->buffer); return TRUE; }
static gboolean gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query) { GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc); GstBufferPool *pool = NULL; GstStructure *config; GstCaps *caps; guint min, max, size; gboolean update_pool; GError *error = NULL; if (!gst_gl_ensure_element_data (src, &src->display, &src->other_context)) return FALSE; gst_gl_display_filter_gl_api (src->display, SUPPORTED_GL_APIS); _find_local_gl_context (src); if (!src->context) { GST_OBJECT_LOCK (src->display); do { if (src->context) { gst_object_unref (src->context); src->context = NULL; } /* just get a GL context. we don't care */ src->context = gst_gl_display_get_gl_context_for_thread (src->display, NULL); if (!src->context) { if (!gst_gl_display_create_context (src->display, src->other_context, &src->context, &error)) { GST_OBJECT_UNLOCK (src->display); goto context_error; } } } while (!gst_gl_display_add_context (src->display, src->context)); GST_OBJECT_UNLOCK (src->display); } if ((gst_gl_context_get_gl_api (src->context) & SUPPORTED_GL_APIS) == 0) goto unsupported_gl_api; gst_gl_context_thread_add (src->context, (GstGLContextThreadFunc) _src_generate_fbo_gl, src); if (!src->fbo) goto context_error; gst_query_parse_allocation (query, &caps, NULL); if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); update_pool = TRUE; } else { GstVideoInfo vinfo; gst_video_info_init (&vinfo); gst_video_info_from_caps (&vinfo, caps); size = vinfo.size; min = max = 0; update_pool = FALSE; } if (!pool || !GST_IS_GL_BUFFER_POOL (pool)) { /* can't use this pool */ if (pool) gst_object_unref (pool); pool = gst_gl_buffer_pool_new (src->context); } config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); if (gst_query_find_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL)) gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_GL_SYNC_META); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); gst_buffer_pool_set_config (pool, config); if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else gst_query_add_allocation_pool (query, pool, size, min, max); gst_gl_test_src_init_shader (src); gst_object_unref (pool); return TRUE; unsupported_gl_api: { GstGLAPI gl_api = gst_gl_context_get_gl_api (src->context); gchar *gl_api_str = gst_gl_api_to_string (gl_api); gchar *supported_gl_api_str = gst_gl_api_to_string (SUPPORTED_GL_APIS); GST_ELEMENT_ERROR (src, RESOURCE, BUSY, ("GL API's not compatible context: %s supported: %s", gl_api_str, supported_gl_api_str), (NULL)); g_free (supported_gl_api_str); g_free (gl_api_str); return FALSE; } context_error: { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s", error->message), (NULL)); g_clear_error (&error); if (src->context) gst_object_unref (src->context); src->context = NULL; return FALSE; } }