/** * gst_gl_query_local_gl_context: * @element: a #GstElement to query from * @direction: the #GstPadDirection to query * @context_ptr: (inout): location containing the current and/or resulting * #GstGLContext * * Performs a GST_QUERY_CONTEXT query of type "gst.gl.local_context" on all * #GstPads in @element of @direction for the local OpenGL context used by * GStreamer elements. * * Returns: whether @context_ptr contains a #GstGLContext */ gboolean gst_gl_query_local_gl_context (GstElement * element, GstPadDirection direction, GstGLContext ** context_ptr) { GstQuery *query; GstContext *context; const GstStructure *s; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); g_return_val_if_fail (context_ptr != NULL, FALSE); if (*context_ptr) return TRUE; query = gst_query_new_context ("gst.gl.local_context"); if (gst_gl_run_query (GST_ELEMENT (element), query, direction)) { gst_query_parse_context (query, &context); if (context) { s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, context_ptr, NULL); } } gst_query_unref (query); return *context_ptr != NULL; }
static gboolean _find_local_gl_context (GstGLStereoSplit * split) { GstQuery *query; GstContext *context; const GstStructure *s; if (split->context) return TRUE; query = gst_query_new_context ("gst.gl.local_context"); if (!split->context && gst_gl_run_query (GST_ELEMENT (split), query, GST_PAD_SRC)) { gst_query_parse_context (query, &context); if (context) { s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &split->context, NULL); } } if (!split->context && gst_gl_run_query (GST_ELEMENT (split), query, GST_PAD_SINK)) { gst_query_parse_context (query, &context); if (context) { s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &split->context, NULL); } } GST_DEBUG_OBJECT (split, "found local context %p", split->context); gst_query_unref (query); if (split->context) return TRUE; return FALSE; }
gboolean gst_vaapi_video_context_get_display (GstContext * context, GstVaapiDisplay ** display_ptr) { const GstStructure *structure; g_return_val_if_fail (GST_IS_CONTEXT (context), FALSE); g_return_val_if_fail (g_strcmp0 (gst_context_get_context_type (context), GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME) == 0, FALSE); structure = gst_context_get_structure (context); return gst_structure_get (structure, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME, GST_TYPE_VAAPI_DISPLAY, display_ptr, NULL); }
gboolean gst_vaapi_find_gl_local_context (GstElement * element, GstObject ** gl_context_ptr) { #if USE_GST_GL_HELPERS GstQuery *query; GstContext *context; const GstStructure *s; GstObject *gl_context; g_return_val_if_fail (gl_context_ptr, FALSE); gl_context = NULL; query = gst_query_new_context ("gst.gl.local_context"); if (_gst_context_run_query (element, query, GST_PAD_SRC)) { gst_query_parse_context (query, &context); if (context) { s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); } } if (!gl_context && _gst_context_run_query (element, query, GST_PAD_SINK)) { gst_query_parse_context (query, &context); if (context) { s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL); } } gst_query_unref (query); if (gl_context) { *gl_context_ptr = gl_context; return TRUE; } #endif return FALSE; }
/** * gst_context_get_vulkan_device: * @context: a #GstContext * @device: resulting #GstVulkanDevice * * Returns: Whether @device was in @context * * Since: 1.10 */ gboolean gst_context_get_vulkan_device (GstContext * context, GstVulkanDevice ** device) { const GstStructure *s; gboolean ret; g_return_val_if_fail (device != NULL, FALSE); g_return_val_if_fail (context != NULL, FALSE); s = gst_context_get_structure (context); ret = gst_structure_get (s, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, GST_TYPE_VULKAN_DEVICE, device, NULL); GST_CAT_LOG (GST_CAT_CONTEXT, "got GstVulkanDevice(%" GST_PTR_FORMAT ") from context(%" GST_PTR_FORMAT ")", *device, context); return ret; }
/** * gst_context_get_gl_display: * @context: a #GstContext * @display: resulting #GstGLDisplay * * Returns: Whether @display was in @context * * Since: 1.4 */ gboolean gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display) { const GstStructure *s; gboolean ret; g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (context != NULL, FALSE); s = gst_context_get_structure (context); ret = gst_structure_get (s, GST_GL_DISPLAY_CONTEXT_TYPE, GST_TYPE_GL_DISPLAY, display, NULL); GST_CAT_LOG (gst_context, "got GstGLDisplay(%p) from context(%p)", *display, context); return ret; }
static void gst_gl_display_context_query (GstElement * element, GstGLDisplay ** display_ptr) { GstContext *ctxt; GstQuery *query; #ifndef GST_DISABLE_GST_DEBUG if (!GST_CAT_CONTEXT) GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); #endif query = _gst_context_query (element, display_ptr, GST_GL_DISPLAY_CONTEXT_TYPE); gst_query_parse_context (query, &ctxt); if (ctxt && gst_context_has_context_type (ctxt, GST_GL_DISPLAY_CONTEXT_TYPE)) gst_context_get_gl_display (ctxt, display_ptr); if (*display_ptr) goto out; #if GST_GL_HAVE_WINDOW_X11 gst_query_unref (query); query = _gst_context_query (element, display_ptr, "gst.x11.display.handle"); gst_query_parse_context (query, &ctxt); if (ctxt && gst_context_has_context_type (ctxt, "gst.x11.display.handle")) { const GstStructure *s; Display *display; s = gst_context_get_structure (ctxt); if (gst_structure_get (s, "display", G_TYPE_POINTER, &display, NULL) && display) { *display_ptr = (GstGLDisplay *) gst_gl_display_x11_new_with_display (display); } } if (*display_ptr) goto out; #endif out: gst_query_unref (query); }
static void gst_gl_context_query (GstElement * element, GstGLContext ** context_ptr) { GstContext *ctxt; GstQuery *query; #ifndef GST_DISABLE_GST_DEBUG if (!GST_CAT_CONTEXT) GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); #endif query = _gst_context_query (element, context_ptr, "gst.gl.app_context"); gst_query_parse_context (query, &ctxt); if (ctxt && gst_context_has_context_type (ctxt, "gst.gl.app_context")) { const GstStructure *s = gst_context_get_structure (ctxt); gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, context_ptr, NULL); } gst_query_unref (query); }
/** * gstbt_audio_tempo_context_get_tempo: * @ctx: the context * @bpm: beats per minute * @tpb: ticks per beat * @stpb: sub-ticks per beat * * Get values from the audio-tempo context. Pointers can be %NULL to skip them. * * Returns: %FALSE if the context if of the wrong type or any of the values were * not stored in the context. */ gboolean gstbt_audio_tempo_context_get_tempo (GstContext * ctx, guint * bpm, guint * tpb, guint * stpb) { const GstStructure *s; gboolean res = TRUE; if (!ctx) return FALSE; if (!gst_context_has_context_type (ctx, GSTBT_AUDIO_TEMPO_TYPE)) return FALSE; s = gst_context_get_structure (ctx); if (bpm) res &= gst_structure_get_uint (s, "beats-per-minute", bpm); if (tpb) res &= gst_structure_get_uint (s, "ticks-per-beat", tpb); if (stpb) res &= gst_structure_get_uint (s, "subticks-per-beat", stpb); return res; }
bool ofGstUtils::gstHandleMessage(GstBus * bus, GstMessage * msg){ if(appsink && appsink->on_message(msg)) return true; /*ofLogVerbose("ofGstUtils") << "gstHandleMessage(): got " << GST_MESSAGE_TYPE_NAME(msg) << " message from " << GST_MESSAGE_SRC_NAME(msg);*/ switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_BUFFERING: gint pctBuffered; gst_message_parse_buffering(msg,&pctBuffered); ofLogVerbose("ofGstUtils") << "gstHandleMessage(): buffering " << pctBuffered; if(pctBuffered<100){ gst_element_set_state (gstPipeline, GST_STATE_PAUSED); }else if(!bPaused){ gst_element_set_state (gstPipeline, GST_STATE_PLAYING); } break; #if GST_VERSION_MAJOR==0 case GST_MESSAGE_DURATION:{ GstFormat format=GST_FORMAT_TIME; gst_element_query_duration(gstPipeline,&format,&durationNanos); }break; #else case GST_MESSAGE_DURATION_CHANGED: gst_element_query_duration(gstPipeline,GST_FORMAT_TIME,&durationNanos); break; #endif case GST_MESSAGE_STATE_CHANGED:{ GstState oldstate, newstate, pendstate; gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendstate); if(isStream && newstate==GST_STATE_PAUSED && !bPlaying ){ bLoaded = true; bPlaying = true; if(!bPaused){ //ofLogVerbose("ofGstUtils") << "gstHandleMessage(): setting stream pipeline to play"; play(); } } /*ofLogVerbose("ofGstUtils") << "gstHandleMessage(): " << GST_MESSAGE_SRC_NAME(msg) << " state changed from " << getName(oldstate) << " to " << getName(newstate) << " (" + getName(pendstate) << ")";*/ }break; case GST_MESSAGE_ASYNC_DONE: ofLogVerbose("ofGstUtils") << "gstHandleMessage(): async done"; break; case GST_MESSAGE_ERROR: { GError *err; gchar *debug; gst_message_parse_error(msg, &err, &debug); gchar * name = gst_element_get_name(GST_MESSAGE_SRC (msg)); ofLogError("ofGstUtils") << "gstHandleMessage(): embedded video playback halted for plugin, module " << name << " reported: " << err->message; g_free(name); g_error_free(err); g_free(debug); gst_element_set_state(GST_ELEMENT(gstPipeline), GST_STATE_NULL); }break; case GST_MESSAGE_EOS:{ ofLogVerbose("ofGstUtils") << "gstHandleMessage(): end of the stream"; bool isClosing = closing; eos_cb(); if(isClosing){ busWatchID = 0; return false; } switch(loopMode){ case OF_LOOP_NORMAL:{ GstFormat format = GST_FORMAT_TIME; GstSeekFlags flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT); if(speed>0){ if(!gst_element_seek(GST_ELEMENT(gstPipeline), speed, format, flags, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, -1)) { ofLogWarning("ofGstUtils") << "gstHandleMessage(): unable to seek"; } }else if(speed<0){ if(!gst_element_seek(GST_ELEMENT(gstPipeline),speed, format, flags, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, durationNanos-1000000)) { ofLogWarning("ofGstUtils") << "gstHandleMessage(): unable to seek"; } } }break; case OF_LOOP_PALINDROME:{ GstFormat format = GST_FORMAT_TIME; GstSeekFlags flags = (GstSeekFlags) (GST_SEEK_FLAG_FLUSH |GST_SEEK_FLAG_KEY_UNIT); gint64 pos; #if GST_VERSION_MAJOR==0 gst_element_query_position(GST_ELEMENT(gstPipeline),&format,&pos); #else gst_element_query_position(GST_ELEMENT(gstPipeline),format,&pos); #endif float loopSpeed; if(pos>0) loopSpeed=-speed; else loopSpeed=speed; if(!gst_element_seek(GST_ELEMENT(gstPipeline), loopSpeed, GST_FORMAT_UNDEFINED, flags, GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0)) { ofLogWarning("ofGstUtils") << "gstHandleMessage(): unable to seek"; } }break; default: break; } }break; case GST_MESSAGE_LATENCY: gst_bin_recalculate_latency (GST_BIN (getPipeline())); break; case GST_MESSAGE_REQUEST_STATE: { GstState state; gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (msg)); gst_message_parse_request_state (msg, &state); gst_element_set_state (getPipeline(), state); g_free (name); break; } case GST_MESSAGE_HAVE_CONTEXT:{ GstContext *context; const gchar *context_type; gchar *context_str; gst_message_parse_have_context (msg, &context); context_type = gst_context_get_context_type (context); context_str = gst_structure_to_string (gst_context_get_structure (context)); ofLogNotice("ofGstUtils","Got context from element '%s': %s=%s\n", GST_ELEMENT_NAME (GST_MESSAGE_SRC (msg)), context_type, context_str); g_free (context_str); gst_context_unref (context); break; } default: ofLogVerbose("ofGstUtils") << "gstHandleMessage(): unhandled message from " << GST_MESSAGE_SRC_NAME(msg); break; } return true; }
/** * gst_gl_handle_set_context: * @element: a #GstElement * @context: a #GstContext * @display: (inout) (transfer full): location of a #GstGLDisplay * @other_context: (inout) (transfer full): location of a #GstGLContext * * Helper function for implementing GstElement::set_context() in OpenGL capable * elements. * * Retrieve's the #GstGLDisplay or #GstGLContext in @context and places the * result in @display or @other_context respectively. * * Returns: whether the @display or @other_context could be set successfully */ gboolean gst_gl_handle_set_context (GstElement * element, GstContext * context, GstGLDisplay ** display, GstGLContext ** other_context) { GstGLDisplay *display_replacement = NULL; GstGLContext *context_replacement = NULL; const gchar *context_type; g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (other_context != NULL, FALSE); if (!context) return FALSE; context_type = gst_context_get_context_type (context); if (g_strcmp0 (context_type, GST_GL_DISPLAY_CONTEXT_TYPE) == 0) { if (!gst_context_get_gl_display (context, &display_replacement)) { GST_WARNING_OBJECT (element, "Failed to get display from context"); return FALSE; } } #if GST_GL_HAVE_WINDOW_X11 else if (g_strcmp0 (context_type, "gst.x11.display.handle") == 0) { const GstStructure *s; Display *display; s = gst_context_get_structure (context); if (gst_structure_get (s, "display", G_TYPE_POINTER, &display, NULL)) display_replacement = (GstGLDisplay *) gst_gl_display_x11_new_with_display (display); } #endif #if GST_GL_HAVE_WINDOW_WAYLAND else if (g_strcmp0 (context_type, "GstWaylandDisplayHandleContextType") == 0) { const GstStructure *s; struct wl_display *display; s = gst_context_get_structure (context); if (gst_structure_get (s, "display", G_TYPE_POINTER, &display, NULL)) display_replacement = (GstGLDisplay *) gst_gl_display_wayland_new_with_display (display); } #endif else if (g_strcmp0 (context_type, "gst.gl.app_context") == 0) { const GstStructure *s = gst_context_get_structure (context); GstGLDisplay *context_display; GstGLDisplay *element_display; if (gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &context_replacement, NULL)) { context_display = gst_gl_context_get_display (context_replacement); element_display = display_replacement ? display_replacement : *display; if (element_display && (gst_gl_display_get_handle_type (element_display) & gst_gl_display_get_handle_type (context_display)) == 0) { GST_ELEMENT_WARNING (element, LIBRARY, SETTINGS, ("%s", "Cannot set a GL context with a different display type"), ("%s", "Cannot set a GL context with a different display type")); gst_object_unref (context_replacement); context_replacement = NULL; } gst_object_unref (context_display); } } if (display_replacement) { GstGLDisplay *old = *display; *display = display_replacement; if (old) gst_object_unref (old); } if (context_replacement) { GstGLContext *old = *other_context; *other_context = context_replacement; if (old) gst_object_unref (old); } return TRUE; }
static gboolean gst_vtdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query) { gboolean ret; GstCaps *caps; GstCapsFeatures *features; GstVtdec *vtdec = GST_VTDEC (decoder); ret = GST_VIDEO_DECODER_CLASS (gst_vtdec_parent_class)->decide_allocation (decoder, query); if (!ret) goto out; gst_query_parse_allocation (query, &caps, NULL); if (caps) { GstGLContext *gl_context = NULL; features = gst_caps_get_features (caps, 0); if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) { GstContext *context = NULL; GstQuery *query = gst_query_new_context ("gst.gl.local_context"); if (gst_pad_peer_query (GST_VIDEO_DECODER_SRC_PAD (decoder), query)) { gst_query_parse_context (query, &context); if (context) { const GstStructure *s = gst_context_get_structure (context); gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &gl_context, NULL); } } gst_query_unref (query); if (context) { GstVideoFormat internal_format; GstVideoCodecState *output_state = gst_video_decoder_get_output_state (decoder); GST_INFO_OBJECT (decoder, "pushing textures. GL context %p", context); if (vtdec->texture_cache) gst_core_video_texture_cache_free (vtdec->texture_cache); #ifdef HAVE_IOS internal_format = GST_VIDEO_FORMAT_NV12; #else internal_format = GST_VIDEO_FORMAT_UYVY; #endif vtdec->texture_cache = gst_core_video_texture_cache_new (gl_context); gst_core_video_texture_cache_set_format (vtdec->texture_cache, internal_format, output_state->caps); gst_video_codec_state_unref (output_state); gst_object_unref (gl_context); } else { GST_WARNING_OBJECT (decoder, "got memory:GLMemory caps but not GL context from downstream element"); } } } out: return ret; }