diff --git a/.rustfmt.toml b/.rustfmt.toml index fa15a9754..70ca331a2 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -13,4 +13,5 @@ ignore = [ "gstreamer-video/src/auto", "gstreamer-webrtc/src/auto", "gstreamer-editing-services/src/auto", + "gstreamer-gl/src/auto", ] diff --git a/Cargo.toml b/Cargo.toml index 2c74db3a7..d8c8b1533 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ members = [ "gstreamer-webrtc", "gstreamer-check", "gstreamer-editing-services", + "gstreamer-gl", "examples", "tutorials", ] diff --git a/Gir_GstGL.toml b/Gir_GstGL.toml new file mode 100644 index 000000000..9efddf1ae --- /dev/null +++ b/Gir_GstGL.toml @@ -0,0 +1,367 @@ +[options] +girs_dir = "gir-files" +library = "GstGL" +version = "1.0" +min_cfg_version = "1.14" +target_path = "gstreamer-gl" +work_mode = "normal" +concurrency = "send+sync" +generate_safety_asserts = true +single_version_file = true + +external_libraries = [ + "GLib", + "GObject", + "Gst", + "GstBase", + "GstVideo", +] + +generate = [ + # BitFlags + "GstGL.GLAPI", + "GstGL.GLDisplayType", + "GstGL.GLPlatform", + "GstGL.GLSLProfile", + # Enums + "GstGL.GLFormat", + "GstGL.GLQueryType", + "GstGL.GLSLVersion", + "GstGL.GLTextureTarget", + "GstGL.GLStereoDownmix", + "GstGL.GLUploadReturn", + # Enums Errors + #"GstGL.GLBaseMemoryError", + "GstGL.GLContextError", + "GstGL.GLSLError", + "GstGL.GLWindowError", + # Records + #"GstGL.GLAllocationParams", + #"GstGL.GLRenderbufferAllocationParams", + #"GstGL.GLVideoAllocationParams", + # Objects + "GstGL.GLBaseFilter", + #"GstGL.GLBufferPool", + "GstGL.GLFramebuffer", + #"GstGL.GLBaseMemory", + #"GstGL.GLBaseMemoryAllocator", + #"GstGL.GLMemoryPBOAllocator", + #"GstGL.GLRenderbufferAllocator", +] + +manual = [ + "GLib.Error", + "GLib.Thread", + "GObject.Object", + "Gst.Object", + "Gst.FlowReturn", + "Gst.PadDirection", + "GstVideo.VideoMultiviewFlags", + "GstVideo.VideoMultiviewMode", +] + +[[object]] +name = "Gst.Structure" +status = "manual" +ref_mode = "ref-mut" + +[[object]] +name = "Gst.Buffer" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Caps" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.Query" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "GstGL.GLBuffer" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "GstGL.GLQuery" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "GstGL.GLContext" +status = "generate" + + [[object.function]] + name = "new_wrapped" + # input handle + ignore = true + + [[object.function]] + name = "get_gl_context" + # return handle + ignore = true + + [[object.function]] + name = "get_current_gl_context" + # return handle + ignore = true + + [[object.function]] + name = "get_proc_address" + ignore = true + + [[object.function]] + name = "default_get_proc_address" + ignore = true + + [[object.function]] + name = "get_proc_address_with_platform" + ignore = true + + [[object.function]] + name = "thread_add" + # unimplemented GLContextThreadFunc + ignore = true + + [[object.function]] + name = "get_thread" + # glib::Thread not found in `glib` + ignore = true + + [[object.function]] + name = "get_gl_context_for_thread" + # glib::Thread not found in `glib` + ignore = true + + [[object.function]] + name = "error_quark" + # bad error domian definition in gir + ignore = true + + [[object.function]] + name = "activate" + [object.function.return] + bool_return_is_error = "Failed to activate OpenGL context" + + [[object.function]] + name = "get_display" + [object.function.return] + nullable = false + + +[[object]] +name = "GstGL.GLDisplay" +status = "generate" + + [[object.function]] + name = "find_window" + # unimplemented pointer + ignore = true + + [[object.function]] + name = "get_handle" + # return handle + ignore = true + + [[object.function]] + name = "get_gl_context_for_thread" + # glib::Thread not found in `glib` + ignore = true + + [[object.function]] + name = "add_context" + [object.function.return] + bool_return_is_error = "Failed to add OpenGL context" + + [[object.function]] + name = "remove_window" + [object.function.return] + bool_return_is_error = "Failed to remove window" + +[[object]] +name = "GstGL.GLDisplayEGL" +status = "generate" +trait = false +cfg_condition = "feature = \"egl\"" + +[[object]] +name = "GstGL.GLWindow" +status = "generate" + + [[object.function]] + name = "get_window_handle" + # return native handle + ignore = true + + [[object.function]] + name = "send_message" + # callback + ignore = true + + [[object.function]] + name = "send_message_async" + # callback + ignore = true + + [[object.function]] + name = "set_close_callback" + # callback + ignore = true + + [[object.function]] + name = "set_draw_callback" + # callback + ignore = true + + [[object.function]] + name = "set_resize_callback" + # callback + ignore = true + + [[object.function]] + name = "set_window_handle" + # handle + ignore = true + + [[object.function]] + name = "get_display" + # handle + ignore = true + + [[object.function]] + name = "error_quark" + # bad error domian definition in gir + ignore = true + +[[object]] +name = "GstGL.GLColorConvert" +status = "generate" +trait = false + + [[object.function]] + name = "decide_allocation" + # correct mutability + ignore = true + + [[object.function]] + name = "fixate_caps" + # correct reference ownership + ignore = true + + [[object.function]] + name = "perform" + # transfer gst::Buffer not reference + ignore = true + +[[object]] +name = "GstGL.GLOverlayCompositor" +status = "generate" +trait = false + + [[object.function]] + name = "upload_overlays" + # correct mutability + ignore = true + +[[object]] +name = "GstGL.GLSLStage" +status = "generate" +trait = false + +[[object]] +name = "GstGL.GLShader" +status = "generate" +trait = false + + [[object.function]] + name = "set_uniform_matrix_2fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_2x3fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_2x4fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_3fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_3x2fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_3x4fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_4fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_4x2fv" + # array with size + ignore = true + + [[object.function]] + name = "set_uniform_matrix_4x3fv" + # array with size + ignore = true + +[[object]] +name = "GstGL.GLUpload" +status = "generate" +trait = false + + [[object.function]] + name = "perform_with_buffer" + # Result + ignore = true + + [[object.function]] + name = "propose_allocation" + # fix mutability + ignore = true + + [[object.function]] + name = "get_input_template_caps" + [object.function.return] + nullable = false + +[[object]] +name = "GstGL.GLViewConvert" +status = "generate" +trait = false + + [[object.function]] + name = "fixate_caps" + # correct reference ownership + ignore = true + + [[object.function]] + name = "get_output" + # Result + ignore = true + + [[object.function]] + name = "tranform_caps" + [object.function.return] + nullable = false + + [[object.function]] + name = "submit_input_buffer" + # Buffer ownership transfer + ignore = true diff --git a/docs/gstreamer-gl/docs.md b/docs/gstreamer-gl/docs.md new file mode 100644 index 000000000..368f1dd5f --- /dev/null +++ b/docs/gstreamer-gl/docs.md @@ -0,0 +1,1509 @@ + + +`GLBaseFilter` handles the nitty gritty details of retrieving an OpenGL +context. It also provided some wrappers around `gst_base::BaseTransform`'s +`start`, `stop` and `set_caps` virtual methods that ensure an OpenGL context +is available and current in the calling thread. + +# Implements + +[`GLBaseFilterExt`](trait.GLBaseFilterExt.html), [`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `GLBaseFilter` methods. + +# Implementors + +[`GLBaseFilter`](struct.GLBaseFilter.html) + +GstGLBuffer is a `gst::Memory` subclass providing support for the mapping of +GL buffers. + +Data is uploaded or downloaded from the GPU as is necessary. + +Initializes the GL Buffer allocator. It is safe to call this function +multiple times. This must be called before any other `GLBuffer` operation. + +`GLColorConvert` is an object that converts between color spaces and/or +formats using OpenGL Shaders. + +A `GLColorConvert` can be created with `GLColorConvert::new`, the +configuration negotiated with `GLColorConvert::transform_caps` and the +conversion performed with `GLColorConvert::perform`. + +The glcolorconvertelement provides a GStreamer element that uses +`GLColorConvert` to convert between video formats and color spaces. + +# Implements + +[`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +## `context` +a `GLContext` + +# Returns + +a new `GLColorConvert` object + +Provides an implementation of `gst_base::BaseTransformClass::fixate_caps`() +## `context` +a `GLContext` to use for transforming `caps` +## `direction` +a `gst::PadDirection` +## `caps` +the `gst::Caps` of `direction` +## `other` +the `gst::Caps` to fixate + +# Returns + +the fixated `gst::Caps` + +Provides an implementation of `gst_base::BaseTransformClass::transform_caps`() +## `context` +a `GLContext` to use for transforming `caps` +## `direction` +a `gst::PadDirection` +## `caps` +the `gst::Caps` to transform +## `filter` +a set of filter `gst::Caps` + +# Returns + +the converted `gst::Caps` + +Provides an implementation of `GstBaseTransfromClass::decide_allocation`() +## `query` +a completed ALLOCATION `gst::Query` + +# Returns + +whether the allocation parameters were successfully chosen + +Converts the data contained by `inbuf` using the formats specified by the +`gst::Caps` passed to `GLColorConvert::set_caps` +## `inbuf` +the `GLMemory` filled `gst::Buffer` to convert + +# Returns + +a converted `gst::Buffer` or `None` + +Initializes `self` with the information required for conversion. +## `in_caps` +input `gst::Caps` +## `out_caps` +output `gst::Caps` + +`GLContext` wraps an OpenGL context object in a uniform API. As a result +of the limitation on OpenGL context, this object is not thread safe unless +specified and must only be activated in a single thread. + +# Implements + +[`GLContextExt`](trait.GLContextExt.html), [`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `GLContext` methods. + +# Implementors + +[`GLContext`](struct.GLContext.html) + +Create a new `GLContext` with the specified `display` +## `display` +a `GLDisplay` + +# Returns + +a new `GLContext` + +Wraps an existing OpenGL context into a `GLContext`. + +Note: The caller is responsible for ensuring that the OpenGL context +represented by `handle` stays alive while the returned `GLContext` is +active. +## `display` +a `GLDisplay` +## `handle` +the OpenGL context to wrap +## `context_type` +a `GLPlatform` specifying the type of context in `handle` +## `available_apis` +a `GLAPI` containing the available OpenGL apis in `handle` + +# Returns + +a `GLContext` wrapping `handle` + +A default implementation of the various GetProcAddress functions that looks +for `name` in the OpenGL shared libraries or in the current process. + +See also: `GLContext::get_proc_address` +## `gl_api` +a `GLAPI` +## `name` +then function to get the address of + +# Returns + +an address pointing to `name` or `None` + +See also `GLContextExt::activate`. + +# Returns + +the `GLContext` active in the current thread or `None` + +If an error occurs, `major` and `minor` are not modified and `GLAPI::None` is +returned. +## `platform` +the `GLPlatform` to retrieve the API for +## `major` +the major version +## `minor` +the minor version + +# Returns + +The version supported by the OpenGL context current in the calling + thread or `GLAPI::None` + +## `context_type` +a `GLPlatform` specifying the type of context to retrieve + +# Returns + +The OpenGL context handle current in the calling thread or `None` + +Attempts to use the `context_type` specific GetProcAddress implementations +to retreive `name`. + +See also `GLContext::get_proc_address`. +## `context_type` +a `GLPlatform` +## `gl_api` +a `GLAPI` +## `name` +the name of the function to retrieve + +# Returns + +a function pointer for `name`, or `None` + +(De)activate the OpenGL context represented by this `self`. + +In OpenGL terms, calls eglMakeCurrent or similar with this context and the +currently set window. See `GLContextExt::set_window` for details. +## `activate` +`true` to activate, `false` to deactivate + +# Returns + +Whether the activation succeeded + +Note: This will always fail for two wrapped `GLContext`'s +## `other_context` +another `GLContext` + +# Returns + +whether `self` and `other_context` are able to share OpenGL + resources. + +Check for an OpenGL `feature` being supported. + +Note: Most features require that the context be created before it is +possible to determine their existence and so will fail if that is not the +case. +## `feature` +a platform specific feature + +# Returns + +Whether `feature` is supported by `self` + +## `fbo_target` +the GL value of the framebuffer target, GL_FRAMEBUFFER, + GL_READ_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER + +# Returns + +whether whether the current framebuffer is complete + +## `api` +api type required +## `maj` +major version required +## `min` +minor version required + +# Returns + +whether OpenGL context implements the required api and specified +version. + +Unbind the current framebuffer + +Clear's the currently set shader from the GL state machine. + +Note: must be called in the GL thread. + +Creates an OpenGL context with the specified `other_context` as a context +to share shareable OpenGL objects with. See the OpenGL specification for +what is shared between OpenGL contexts. + +If an error occurs, and `error` is not `None`, then error will contain details +of the error and `false` will be returned. + +Should only be called once. +## `other_context` +a `GLContext` to share OpenGL objects with + +# Returns + +whether the context could successfully be created + +Destroys an OpenGL context. + +Should only be called after `GLContextExt::create` has been successfully +called for this context. + +Fills `self`'s info (version, extensions, vtable, etc) from the GL +context in the current thread. Typically used with wrapped contexts to +allow wrapped contexts to be used as regular `GLContext`'s. + + +# Returns + +the `GLDisplay` associated with this `self` + +Get the currently enabled OpenGL api. + +The currently available API may be limited by the `GLDisplay` in use and/or +the `GLWindow` chosen. + +# Returns + +the available OpenGL api + +Gets the backing OpenGL context used by `self`. + +# Returns + +The platform specific backing OpenGL context + +Gets the OpenGL platform that used by `self`. + +# Returns + +The platform specific backing OpenGL context + +Get the version of the OpenGL platform (GLX, EGL, etc) used. Only valid +after a call to `gst_gl_context_create_context`. +## `major` +return for the major version +## `minor` +return for the minor version + +Returns the OpenGL version implemented by `self`. See +`GLContextExt::get_gl_api` for retreiving the OpenGL api implemented by +`self`. +## `maj` +resulting major version +## `min` +resulting minor version + +Get a function pointer to a specified opengl function, `name`. If the the +specific function does not exist, NULL is returned instead. + +Platform specfic functions (names starting 'egl', 'glX', 'wgl', etc) can also +be retrieved using this method. + +Note: This function may return valid function pointers that may not be valid +to call in `self`. The caller is responsible for ensuring that the +returned function is a valid function to call in `self` by either checking +the OpenGL API and version or for an appropriate OpenGL extension. + +Note: On success, you need to cast the returned function pointer to the +correct type to be able to call it correctly. On 32-bit Windows, this will +include the `GSTGLAPI` identifier to use the correct calling convention. +e.g. + + +```C +void (GSTGLAPI *PFN_glGetIntegerv) (GLenum name, GLint * ret) +``` +## `name` +an opengl function name + +# Returns + +a function pointer or `None` + + +# Returns + +The `glib::Thread`, `self` is current in or NULL + + +# Returns + +the currently set window + + +# Returns + +Whether the `GLContext` has been shared with another `GLContext` + +Will internally set `self` as shared with `share` +## `share` +another `GLContext` + +Set's the current window on `self` to `window`. The window can only be +changed before `GLContextExt::create` has been called and the `window` is not +already running. +## `window` +a `GLWindow` + +# Returns + +Whether the window was successfully updated + +## `version` +a `GLSLVersion` +## `profile` +a `GLSLProfile` + +# Returns + +Whether `self` supports the combination of `version` with `profile` + +Swap the front and back buffers on the window attached to `self`. +This will display the frame on the next refresh cycle. + +Execute `func` in the OpenGL thread of `self` with `data` + +MT-safe +## `func` +a `GstGLContextThreadFunc` +## `data` +user data to call `func` with + +OpenGL context errors. + +Failed for an unspecified reason + +The configuration requested is not correct + +The OpenGL API requested is not correct + +The OpenGL libraries are too old + +glXCreateContext (or similar) failed + +A resource is not available + +`GLDisplay` represents a connection to the underlying windowing system. +Elements are required to make use of `gst::Context` to share and propogate +a `GLDisplay`. + +There are a number of environment variables that influence the choice of +platform and window system specific functionality. +- GST_GL_WINDOW influences the window system to use. Common values are + 'x11', 'wayland', 'win32' or 'cocoa'. +- GST_GL_PLATFORM influences the OpenGL platform to use. Common values are + 'egl', 'glx', 'wgl' or 'cgl'. +- GST_GL_API influences the OpenGL API requested by the OpenGL platform. + Common values are 'opengl', 'opengl3' and 'gles2'. + +> Certain window systems require a special function to be called to +> initialize threading support. As this GStreamer GL library does not preclude +> concurrent access to the windowing system, it is strongly advised that +> applications ensure that threading support has been initialized before any +> other toolkit/library functionality is accessed. Failure to do so could +> result in sudden application abortion during execution. The most notably +> example of such a function is X11's XInitThreads\(). + +# Implements + +[`GLDisplayExt`](trait.GLDisplayExt.html), [`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `GLDisplay` methods. + +# Implementors + +[`GLDisplayEGL`](struct.GLDisplayEGL.html), [`GLDisplay`](struct.GLDisplay.html) + + +# Returns + +a new `GLDisplay` + +## `context` +a `GLContext` + +# Returns + +whether `context` was successfully added. `false` may be returned +if there already exists another context for `context`'s active thread. + +Must be called with the object lock held. + +It requires the display's object lock to be held. +## `other_context` +other `GLContext` to share resources with. +## `p_context` +resulting `GLContext` + +# Returns + +whether a new context could be created. + +It requires the display's object lock to be held. + +# Returns + +a new `GLWindow` for `self` or `None`. + +limit the use of OpenGL to the requested `gl_api`. This is intended to allow +application and elements to request a specific set of OpenGL API's based on +what they support. See `GLContextExt::get_gl_api` for the retreiving the +API supported by a `GLContext`. +## `gl_api` +a `GLAPI` to filter with + +Execute `compare_func` over the list of windows stored by `self`. The +first argment to `compare_func` is the `GLWindow` being checked and the +second argument is `data`. +## `data` +some data to pass to `compare_func` +## `compare_func` +a comparison function to run + +# Returns + +The first `GLWindow` that causes a match + from `compare_func` + +see `GLDisplayExt::filter_gl_api` for what the returned value represents + +# Returns + +the `GLAPI` configured for `self` + +## `thread` +a `glib::Thread` + +# Returns + +the `GLContext` current on `thread` or `None` + +Must be called with the object lock held. + + +# Returns + +the native handle for the display + + +# Returns + +the `GLDisplayType` of `self` + +## `window` +a `GLWindow` to remove + +# Returns + +if `window` could be removed from `self` + +Overrides the `GLContext` creation mechanism. +It can be called in any thread and it is emitted with +display's object lock held. +## `context` +other context to share resources with. + +# Returns + +the new context. + +the contents of a `GLDisplayEGL` are private and should only be accessed +through the provided API + +# Implements + +[`GLDisplayExt`](trait.GLDisplayExt.html), [`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Create a new `GLDisplayEGL` using the default EGL_DEFAULT_DISPLAY. + +# Returns + +a new `GLDisplayEGL` or `None` + +Attempts to create a new `EGLDisplay` from `display`. If `type_` is +`GLDisplayType::Any`, then `display` must be 0. `type_` must not be +`GLDisplayType::None`. +## `type_` +a `GLDisplayType` +## `display` +pointer to a display (or 0) + +# Returns + +A `EGLDisplay` or `EGL_NO_DISPLAY` + + +Single component replicated across R, G, and B textures + components + +Single component stored in the A texture component + +Combination of `GLFormat::Luminance` and `GLFormat::Alpha` + +Single component stored in the R texture component + +Single 8-bit component stored in the R texture component + +Two components stored in the R and G texture components + +Two 8-bit components stored in the R and G texture components + +Three components stored in the R, G, and B texture components + +Three 8-bit components stored in the R, G, and B + texture components + +Three components of bit depth 5, 6 and 5 stored in the R, G, + and B texture components respectively. + +Four components stored in the R, G, B, and A texture + components respectively. + +Four 8-bit components stored in the R, G, B, and A texture + components respectively. + +A single 16-bit component for depth information. + +A 24-bit component for depth information and + a 8-bit component for stencil informat. + +A `GLFramebuffer` represents and holds an OpenGL framebuffer object with +it's associated attachments. + +A `GLFramebuffer` can be created with `GLFramebuffer::new` or +`GLFramebuffer::new_with_default_depth` and bound with +`GLFramebufferExt::bind`. Other resources can be bound with +`GLFramebufferExt::attach` + +Note: OpenGL framebuffers are not shareable resources so cannot be used +between multiple OpenGL contexts. + +# Implements + +[`GLFramebufferExt`](trait.GLFramebufferExt.html), [`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `GLFramebuffer` methods. + +# Implementors + +[`GLFramebuffer`](struct.GLFramebuffer.html) + +## `context` +a `GLContext` + +# Returns + +a new `GLFramebuffer` + +## `context` +a `GLContext` +## `width` +width for the depth buffer +## `height` +for the depth buffer + +# Returns + +a new `GLFramebuffer` with a depth buffer of `width` and `height` + +attach `mem` to `attachment_point` +## `attachment_point` +the OpenGL attachment point to bind `mem` to +## `mem` +the memory object to bind to `attachment_point` + +Bind `self` into the current thread + +Perform the steps necessary to have the output of a glDraw* command in +`func` update the contents of `mem`. +## `mem` +the `GLMemory` to draw to +## `func` +the function to run +## `user_data` +data to pass to `func` + +# Returns + +the result of executing `func` + +Retreive the effective dimensions from the current attachments attached to +`self`. +## `width` +output width +## `height` +output height + + +# Returns + +the OpenGL id for `self` + +Opaque `GLOverlayCompositor` object + +# Implements + +[`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +A `GLQuery` represents and holds an OpenGL query object. Various types of +queries can be run or counters retrieved. + +Record the result of a counter + +End counting the query + +Frees a `GLQuery` + +## `context` +a `GLContext` +## `query_type` +the `GLQueryType` + + +# Returns + +the result of the query + +Start counting the query + +Free any dynamically allocated resources + +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. +## `element` +a `gst::Element` to query from +## `direction` +the `gst::PadDirection` to query +## `context_ptr` +location containing the current and/or resulting + `GLContext` + +# Returns + +whether `context_ptr` contains a `GLContext` + +Free with `GLQuery::free` +## `context` +a `GLContext` +## `query_type` +the `GLQueryType` to create + +# Returns + +a new `GLQuery` + + +no query + +query the time elapsed + +query the current time + +Compilation stage that caused an error + +Compilation error occured + +Link error occured + +General program error occured + +`GLSLStage` holds and represents a single OpenGL shader stage. + +# Implements + +[`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +## `context` +a `GLContext` +## `type_` +the GL enum shader stage type + +# Returns + +a new `GLSLStage` of the specified `type_` + +## `context` +a `GLContext` +## `type_` +the GL enum shader stage type +## `version` +the `GLSLVersion` +## `profile` +the `GLSLProfile` +## `str` +a shader string + +# Returns + +a new `GLSLStage` of the specified `type_` + +## `context` +a `GLContext` +## `type_` +the GL enum shader stage type +## `version` +the `GLSLVersion` +## `profile` +the `GLSLProfile` +## `n_strings` +the number of strings in `str` +## `str` + + an array of strings concatted together to produce a shader + +# Returns + +a new `GLSLStage` of the specified `type_` + + +# Returns + +whether the compilation suceeded + + +# Returns + +The GL handle for this shader stage + + +# Returns + +The GLSL profile for the current shader stage + + +# Returns + +The GL shader type for this shader stage + + +# Returns + +The GLSL version for the current shader stage + +Replaces the current shader string with `str`. +## `version` +a `GLSLVersion` +## `profile` +a `GLSLProfile` +## `n_strings` +number of strings in `str` +## `str` +a GLSL shader string + +GLSL version list + +no version + +version 100 (only valid for ES) + +version 110 (only valid for compatibility desktop GL) + +version 120 (only valid for compatibility desktop GL) + +version 130 (only valid for compatibility desktop GL) + +version 140 (only valid for compatibility desktop GL) + +version 150 (valid for compatibility/core desktop GL) + +version 300 (only valid for ES) + +version 310 (only valid for ES) + +version 320 (only valid for ES) + +version 330 (valid for compatibility/core desktop GL) + +version 400 (valid for compatibility/core desktop GL) + +version 410 (valid for compatibility/core desktop GL) + +version 420 (valid for compatibility/core desktop GL) + +version 430 (valid for compatibility/core desktop GL) + +version 440 (valid for compatibility/core desktop GL) + +version 450 (valid for compatibility/core desktop GL) + + + +# Implements + +[`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Note: must be called in the GL thread +## `context` +a `GLContext` + +# Returns + +a new empty `shader` + +Note: must be called in the GL thread +## `context` +a `GLContext` + +# Returns + +a default `shader` or `None` on failure + +Each stage will attempt to be compiled and attached to `shader`. Then +the shader will be linked. On error, `None` will be returned and `error` will +contain the details of the error. + +Note: must be called in the GL thread +## `context` +a `GLContext` +## `error` +a `glib::Error` + +# Returns + +a new `shader` with the specified stages. + +Each stage will attempt to be compiled and attached to `shader`. On error, +`None` will be returned and `error` will contain the details of the error. + +Note: must be called in the GL thread +## `context` +a `GLContext` +## `error` +a `glib::Error` + +# Returns + +a new `shader` with the specified stages. + +Attaches `stage` to `self`. `stage` must have been successfully compiled +with `GLSLStage::compile`. + +Note: must be called in the GL thread +## `stage` +a `GLSLStage` to attach + +# Returns + +whether `stage` could be attached to `self` + +Attaches `stage` to `self`. `stage` must have been successfully compiled +with `GLSLStage::compile`. + +Note: must be called in the GL thread +## `stage` +a `GLSLStage` to attach + +# Returns + +whether `stage` could be attached to `self` + +Bind attribute `name` to the specified location `index` using +glBindAttributeLocation(). +## `index` +attribute index to set +## `name` +name of the attribute + +Bind attribute `name` to the specified location `index` using +glBindFragDataLocation(). +## `index` +attribute index to set +## `name` +name of the attribute + +Compiles `stage` and attaches it to `self`. + +Note: must be called in the GL thread +## `stage` +a `GLSLStage` to attach + +# Returns + +whether `stage` could be compiled and attached to `self` + +Detaches `stage` from `self`. `stage` must have been successfully attached +to `self` with `GLShader::attach` or `GLShader::attach_unlocked`. + +Note: must be called in the GL thread +## `stage` +a `GLSLStage` to attach + +Detaches `stage` from `self`. `stage` must have been successfully attached +to `self` with `GLShader::attach` or `GLShader::attach_unlocked`. + +Note: must be called in the GL thread +## `stage` +a `GLSLStage` to attach + +## `name` +name of the attribute + +# Returns + +the attribute index for `name` in `self` or -1 on failure + + +# Returns + +the GL program handle for this shader + +Note: must be called in the GL thread + +# Returns + +whether `self` has been successfully linked + +Links the current list of `GLSLStage`'s in `self`. + +Note: must be called in the GL thread + +# Returns + +whether `self` could be linked together. + +Releases the shader and stages. + +Note: must be called in the GL thread + +Releases the shader and stages. + +Note: must be called in the GL thread + +Perform glUniform1f() for `name` on `self` +## `name` +name of the uniform +## `value` +value to set + +Perform glUniform1fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniform1i() for `name` on `self` +## `name` +name of the uniform +## `value` +value to set + +Perform glUniform1iv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniform2f() for `name` on `self` +## `name` +name of the uniform +## `v0` +first value to set +## `v1` +second value to set + +Perform glUniform2fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniform2i() for `name` on `self` +## `name` +name of the uniform +## `v0` +first value to set +## `v1` +second value to set + +Perform glUniform2iv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniform3f() for `name` on `self` +## `name` +name of the uniform +## `v0` +first value to set +## `v1` +second value to set +## `v2` +third value to set + +Perform glUniform3fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniform3i() for `name` on `self` +## `name` +name of the uniform +## `v0` +first value to set +## `v1` +second value to set +## `v2` +third value to set + +Perform glUniform3iv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniform4f() for `name` on `self` +## `name` +name of the uniform +## `v0` +first value to set +## `v1` +second value to set +## `v2` +third value to set +## `v3` +fourth value to set + +Perform glUniform4fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniform4i() for `name` on `self` +## `name` +name of the uniform +## `v0` +first value to set +## `v1` +second value to set +## `v2` +third value to set +## `v3` +fourth value to set + +Perform glUniform4iv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of values to set +## `value` +values to set + +Perform glUniformMatrix2fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 2x2 matrices to set +## `transpose` +transpose the matrix +## `value` +matrix to set + +Perform glUniformMatrix2x3fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 2x3 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Perform glUniformMatrix2x4fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 2x4 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Perform glUniformMatrix3fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 3x3 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Perform glUniformMatrix3x2fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 3x2 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Perform glUniformMatrix3x4fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 3x4 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Perform glUniformMatrix4fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 4x4 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Perform glUniformMatrix4x2fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 4x2 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Perform glUniformMatrix4x3fv() for `name` on `self` +## `name` +name of the uniform +## `count` +number of 4x3 matrices to set +## `transpose` +transpose the matrix +## `value` +values to set + +Mark's `self` as being used for the next GL draw command. + +Note: must be called in the GL thread and `self` must have been linked. + +Output anaglyph type to generate when downmixing to mono + + +no texture target + +2D texture target + +rectangle texture target + +external oes texture target + +`GLUpload` is an object that uploads data from system memory into GL textures. + +A `GLUpload` can be created with `GLUpload::new` + +# Implements + +[`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +## `context` +a `GLContext` + +# Returns + +a new `GLUpload` object + +## `in_caps` +the input `gst::Caps` +## `out_caps` +the output `gst::Caps` + +Uploads `buffer` using the transformation specified by +`GLUpload::set_caps` creating a new `gst::Buffer` in `outbuf_ptr`. +## `buffer` +input `gst::Buffer` +## `outbuf_ptr` +resulting `gst::Buffer` + +# Returns + +whether the upload was successful + +Adds the required allocation parameters to support uploading. +## `decide_query` +a `gst::Query` from a decide allocation +## `query` +the proposed allocation query + +Initializes `self` with the information required for upload. +## `in_caps` +input `gst::Caps` +## `out_caps` +output `gst::Caps` + +# Returns + +whether `in_caps` and `out_caps` could be set on `self` + + +No further processing required + +An unspecified error occured + +The configuration is unsupported. + +This element requires a reconfiguration. + +Convert stereoscopic/multiview video using fragment shaders. + +# Implements + +[`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + + +# Returns + +a new `GLViewConvert` + +Provides an implementation of `gst_base::BaseTransformClass::fixate_caps`() +## `direction` +a `gst::PadDirection` +## `caps` +the `gst::Caps` of `direction` +## `othercaps` +the `gst::Caps` to fixate + +# Returns + +the fixated `gst::Caps` + +Retrieve the processed output buffer placing the output in `outbuf_ptr`. +## `outbuf_ptr` +a `gst::Buffer` + +# Returns + +a `gst::FlowReturn` + +Converts the data contained by `inbuf` using the formats specified by the +`gst::Caps` passed to `GLViewConvert::set_caps` +## `inbuf` +the `GLMemory` filled `gst::Buffer` to convert + +# Returns + +a converted `gst::Buffer` or `None` + +Reset `self` to the default state. Further operation will require +setting the caps with `GLViewConvert::set_caps`. + +Initializes `self` with the information required for conversion. +## `in_caps` +input `gst::Caps` +## `out_caps` +output `gst::Caps` + +Set `context` on `self` +## `context` +the `GLContext` to set + +Submit `input` to be processed by `self` +## `is_discont` +true if we have a discontinuity +## `input` +a `gst::Buffer` + +# Returns + +a `gst::FlowReturn` + +Provides an implementation of `gst_base::BaseTransformClass::transform_caps`() +## `direction` +a `gst::PadDirection` +## `caps` +the `gst::Caps` to transform +## `filter` +a set of filter `gst::Caps` + +# Returns + +the converted `gst::Caps` + +GstGLWindow represents a window that elements can render into. A window can +either be a user visible window (onscreen) or hidden (offscreen). + +# Implements + +[`GLWindowExt`](trait.GLWindowExt.html), [`gst::ObjectExt`](../gst/trait.ObjectExt.html), [`glib::object::ObjectExt`](../glib/object/trait.ObjectExt.html) + +Trait containing all `GLWindow` methods. + +# Implementors + +[`GLWindow`](struct.GLWindow.html) + +## `display` +a `GLDisplay` + +# Returns + +a new `GLWindow` using `display`'s connection + +Redraw the window contents. Implementations should invoke the draw callback. + + +# Returns + +the `GLContext` associated with this `self` + + +# Returns + +the windowing system display handle for this `self` + +## `width` +resulting surface width +## `height` +resulting surface height + + +# Returns + +the window handle we are currently rendering into + +Tell a `self` that it should handle events from the window system. These +events are forwarded upstream as navigation events. In some window systems +events are not propagated in the window hierarchy if a client is listening +for them. This method allows you to disable events handling completely +from the `self`. +## `handle_events` +a `gboolean` indicating if events should be handled or not. + +Quit the runloop's execution. + +Start the execution of the runloop. + +Invoke `callback` with data on the window thread. `callback` is guarenteed to +have executed when this function returns. +## `callback` +function to invoke +## `data` +data to invoke `callback` with + +Invoke `callback` with `data` on the window thread. The callback may not +have been executed when this function returns. +## `callback` +function to invoke +## `data` +data to invoke `callback` with +## `destroy` +called when `data` is not needed anymore + +Sets the callback called when the window is about to close. +## `callback` +function to invoke +## `data` +data to invoke `callback` with +## `destroy_notify` +called when `data` is not needed any more + +Sets the draw callback called everytime `GLWindowExt::draw` is called +## `callback` +function to invoke +## `data` +data to invoke `callback` with +## `destroy_notify` +called when `data` is not needed any more + +Set the preferred width and height of the window. Implementations are free +to ignore this information. +## `width` +new preferred width +## `height` +new preferred height + +Tell a `self` that it should render into a specific region of the window +according to the `gst_video::VideoOverlay` interface. +## `x` +x position +## `y` +y position +## `width` +width +## `height` +height + +# Returns + +whether the specified region could be set + +Sets the resize callback called everytime a resize of the window occurs. +## `callback` +function to invoke +## `data` +data to invoke `callback` with +## `destroy_notify` +called when `data` is not needed any more + +Sets the window that this `self` should render into. Some implementations +require this to be called with a valid handle before drawing can commence. +## `handle` +handle to the window + +Present the window to the screen. + +Will be emitted when a key event is received by the GstGLwindow. +## `id` +the name of the event +## `key` +the id of the key pressed + +Will be emitted when a mouse event is received by the GstGLwindow. +## `id` +the name of the event +## `button` +the id of the button +## `x` +the x coordinate of the mouse event +## `y` +the y coordinate of the mouse event + + +failed for a unspecified reason + +the implementation is too old + +no such resource was found diff --git a/gstreamer-gl/Cargo.toml b/gstreamer-gl/Cargo.toml new file mode 100644 index 000000000..25cbcacc0 --- /dev/null +++ b/gstreamer-gl/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "gstreamer-gl" +version = "0.13.0" +authors = ["Sebastian Dröge ", + "Víctor M. Jáquez L. "] +categories = ["api-bindings", "multimedia"] +description = "Rust bindings for GStreamer GL library" +repository = "https://github.com/sdroege/gstreamer-rs" +license = "MIT/Apache-2.0" +readme = "README.md" +homepage = "https://gstreamer.freedesktop.org" +documentation = "https://sdroege.github.io/rustdoc/gstreamer/gstreamer_gl" +keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"] +build = "build.rs" + +[dependencies] +bitflags = "1.0" +byteorder = "1" +libc = "0.2" +lazy_static = "1.0" +glib-sys = { git = "https://github.com/gtk-rs/sys" } +gobject-sys = { git = "https://github.com/gtk-rs/sys" } +gstreamer-sys = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys" } +gstreamer-base-sys = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys", features = ["v1_14"] } +gstreamer-video-sys = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys", features = ["v1_14"] } +gstreamer-gl-sys = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys" } +glib = { git = "https://github.com/gtk-rs/glib" } +gstreamer = { path = "../gstreamer", features = ["v1_14"] } +gstreamer-base = { path = "../gstreamer-base", features = ["v1_14"] } +gstreamer-video = { path = "../gstreamer-video", features = ["v1_14"] } + +[build-dependencies.rustdoc-stripper] +version = "0.1" +optional = true + +[features] +default-features = [] +dox = ["gstreamer-gl-sys/dox", "glib/dox", "gstreamer/dox", "gstreamer-base/dox"] +egl = ["gstreamer-gl-sys/egl"] +embed-lgpl-docs = ["rustdoc-stripper"] +purge-lgpl-docs = ["rustdoc-stripper"] diff --git a/gstreamer-gl/LICENSE-APACHE b/gstreamer-gl/LICENSE-APACHE new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/gstreamer-gl/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/gstreamer-gl/LICENSE-MIT b/gstreamer-gl/LICENSE-MIT new file mode 100644 index 000000000..31aa79387 --- /dev/null +++ b/gstreamer-gl/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/gstreamer-gl/build.rs b/gstreamer-gl/build.rs new file mode 100644 index 000000000..becc9aa54 --- /dev/null +++ b/gstreamer-gl/build.rs @@ -0,0 +1,34 @@ +fn main() { + manage_docs(); +} + +#[cfg(any(feature = "embed-lgpl-docs", feature = "purge-lgpl-docs"))] +fn manage_docs() { + extern crate stripper_lib; + use std::io; + + let path = "src"; + let ignores: &[&str] = &[]; + + stripper_lib::loop_over_files( + path.as_ref(), + &mut |w, s| stripper_lib::strip_comments(w, s, &mut io::sink(), true), + &ignores, + false, + ); + + #[cfg(feature = "embed-lgpl-docs")] + { + let docs = include_str!("../docs/gstreamer-gl/docs.md"); + let mut infos = stripper_lib::parse_cmts(docs.lines(), true); + stripper_lib::loop_over_files( + path.as_ref(), + &mut |w, s| stripper_lib::regenerate_comments(w, s, &mut infos, true, true), + &ignores, + false, + ); + } +} + +#[cfg(not(any(feature = "embed-lgpl-docs", feature = "purge-lgpl-docs")))] +fn manage_docs() {} diff --git a/gstreamer-gl/src/auto/enums.rs b/gstreamer-gl/src/auto/enums.rs new file mode 100644 index 000000000..3a6e88a49 --- /dev/null +++ b/gstreamer-gl/src/auto/enums.rs @@ -0,0 +1,529 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use ffi; +use glib::Quark; +use glib::StaticType; +use glib::Type; +use glib::error::ErrorDomain; +use glib::translate::*; +use glib::value::FromValue; +use glib::value::FromValueOptional; +use glib::value::SetValue; +use glib::value::Value; +use gobject_ffi; + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLContextError { + Failed, + WrongConfig, + WrongApi, + OldLibs, + CreateContext, + ResourceUnavailable, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLContextError { + type GlibType = ffi::GstGLContextError; + + fn to_glib(&self) -> ffi::GstGLContextError { + match *self { + GLContextError::Failed => ffi::GST_GL_CONTEXT_ERROR_FAILED, + GLContextError::WrongConfig => ffi::GST_GL_CONTEXT_ERROR_WRONG_CONFIG, + GLContextError::WrongApi => ffi::GST_GL_CONTEXT_ERROR_WRONG_API, + GLContextError::OldLibs => ffi::GST_GL_CONTEXT_ERROR_OLD_LIBS, + GLContextError::CreateContext => ffi::GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, + GLContextError::ResourceUnavailable => ffi::GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, + GLContextError::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLContextError { + fn from_glib(value: ffi::GstGLContextError) -> Self { + skip_assert_initialized!(); + match value { + 0 => GLContextError::Failed, + 1 => GLContextError::WrongConfig, + 2 => GLContextError::WrongApi, + 3 => GLContextError::OldLibs, + 4 => GLContextError::CreateContext, + 5 => GLContextError::ResourceUnavailable, + value => GLContextError::__Unknown(value), + } + } +} + +impl ErrorDomain for GLContextError { + fn domain() -> Quark { + skip_assert_initialized!(); + unsafe { from_glib(ffi::gst_gl_context_error_quark()) } + } + + fn code(self) -> i32 { + self.to_glib() + } + + fn from(code: i32) -> Option { + skip_assert_initialized!(); + match code { + 0 => Some(GLContextError::Failed), + 1 => Some(GLContextError::WrongConfig), + 2 => Some(GLContextError::WrongApi), + 3 => Some(GLContextError::OldLibs), + 4 => Some(GLContextError::CreateContext), + 5 => Some(GLContextError::ResourceUnavailable), + _ => Some(GLContextError::Failed), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLFormat { + Luminance, + Alpha, + LuminanceAlpha, + Red, + R8, + Rg, + Rg8, + Rgb, + Rgb8, + Rgb565, + Rgba, + Rgba8, + DepthComponent16, + Depth24Stencil8, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLFormat { + type GlibType = ffi::GstGLFormat; + + fn to_glib(&self) -> ffi::GstGLFormat { + match *self { + GLFormat::Luminance => ffi::GST_GL_LUMINANCE, + GLFormat::Alpha => ffi::GST_GL_ALPHA, + GLFormat::LuminanceAlpha => ffi::GST_GL_LUMINANCE_ALPHA, + GLFormat::Red => ffi::GST_GL_RED, + GLFormat::R8 => ffi::GST_GL_R8, + GLFormat::Rg => ffi::GST_GL_RG, + GLFormat::Rg8 => ffi::GST_GL_RG8, + GLFormat::Rgb => ffi::GST_GL_RGB, + GLFormat::Rgb8 => ffi::GST_GL_RGB8, + GLFormat::Rgb565 => ffi::GST_GL_RGB565, + GLFormat::Rgba => ffi::GST_GL_RGBA, + GLFormat::Rgba8 => ffi::GST_GL_RGBA8, + GLFormat::DepthComponent16 => ffi::GST_GL_DEPTH_COMPONENT16, + GLFormat::Depth24Stencil8 => ffi::GST_GL_DEPTH24_STENCIL8, + GLFormat::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLFormat { + fn from_glib(value: ffi::GstGLFormat) -> Self { + skip_assert_initialized!(); + match value { + 6409 => GLFormat::Luminance, + 6406 => GLFormat::Alpha, + 6410 => GLFormat::LuminanceAlpha, + 6403 => GLFormat::Red, + 33321 => GLFormat::R8, + 33319 => GLFormat::Rg, + 33323 => GLFormat::Rg8, + 6407 => GLFormat::Rgb, + 32849 => GLFormat::Rgb8, + 36194 => GLFormat::Rgb565, + 6408 => GLFormat::Rgba, + 32856 => GLFormat::Rgba8, + 33189 => GLFormat::DepthComponent16, + 35056 => GLFormat::Depth24Stencil8, + value => GLFormat::__Unknown(value), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLQueryType { + None, + TimeElapsed, + Timestamp, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLQueryType { + type GlibType = ffi::GstGLQueryType; + + fn to_glib(&self) -> ffi::GstGLQueryType { + match *self { + GLQueryType::None => ffi::GST_GL_QUERY_NONE, + GLQueryType::TimeElapsed => ffi::GST_GL_QUERY_TIME_ELAPSED, + GLQueryType::Timestamp => ffi::GST_GL_QUERY_TIMESTAMP, + GLQueryType::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLQueryType { + fn from_glib(value: ffi::GstGLQueryType) -> Self { + skip_assert_initialized!(); + match value { + 0 => GLQueryType::None, + 1 => GLQueryType::TimeElapsed, + 2 => GLQueryType::Timestamp, + value => GLQueryType::__Unknown(value), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLSLError { + Compile, + Link, + Program, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLSLError { + type GlibType = ffi::GstGLSLError; + + fn to_glib(&self) -> ffi::GstGLSLError { + match *self { + GLSLError::Compile => ffi::GST_GLSL_ERROR_COMPILE, + GLSLError::Link => ffi::GST_GLSL_ERROR_LINK, + GLSLError::Program => ffi::GST_GLSL_ERROR_PROGRAM, + GLSLError::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLSLError { + fn from_glib(value: ffi::GstGLSLError) -> Self { + skip_assert_initialized!(); + match value { + 0 => GLSLError::Compile, + 1 => GLSLError::Link, + 2 => GLSLError::Program, + value => GLSLError::__Unknown(value), + } + } +} + +impl ErrorDomain for GLSLError { + fn domain() -> Quark { + skip_assert_initialized!(); + unsafe { from_glib(ffi::gst_glsl_error_quark()) } + } + + fn code(self) -> i32 { + self.to_glib() + } + + fn from(code: i32) -> Option { + skip_assert_initialized!(); + match code { + 0 => Some(GLSLError::Compile), + 1 => Some(GLSLError::Link), + 2 => Some(GLSLError::Program), + value => Some(GLSLError::__Unknown(value)), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLSLVersion { + None, + _100, + _110, + _120, + _130, + _140, + _150, + _300, + _310, + _320, + _330, + _400, + _410, + _420, + _430, + _440, + _450, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLSLVersion { + type GlibType = ffi::GstGLSLVersion; + + fn to_glib(&self) -> ffi::GstGLSLVersion { + match *self { + GLSLVersion::None => ffi::GST_GLSL_VERSION_NONE, + GLSLVersion::_100 => ffi::GST_GLSL_VERSION_100, + GLSLVersion::_110 => ffi::GST_GLSL_VERSION_110, + GLSLVersion::_120 => ffi::GST_GLSL_VERSION_120, + GLSLVersion::_130 => ffi::GST_GLSL_VERSION_130, + GLSLVersion::_140 => ffi::GST_GLSL_VERSION_140, + GLSLVersion::_150 => ffi::GST_GLSL_VERSION_150, + GLSLVersion::_300 => ffi::GST_GLSL_VERSION_300, + GLSLVersion::_310 => ffi::GST_GLSL_VERSION_310, + GLSLVersion::_320 => ffi::GST_GLSL_VERSION_320, + GLSLVersion::_330 => ffi::GST_GLSL_VERSION_330, + GLSLVersion::_400 => ffi::GST_GLSL_VERSION_400, + GLSLVersion::_410 => ffi::GST_GLSL_VERSION_410, + GLSLVersion::_420 => ffi::GST_GLSL_VERSION_420, + GLSLVersion::_430 => ffi::GST_GLSL_VERSION_430, + GLSLVersion::_440 => ffi::GST_GLSL_VERSION_440, + GLSLVersion::_450 => ffi::GST_GLSL_VERSION_450, + GLSLVersion::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLSLVersion { + fn from_glib(value: ffi::GstGLSLVersion) -> Self { + skip_assert_initialized!(); + match value { + 0 => GLSLVersion::None, + 100 => GLSLVersion::_100, + 110 => GLSLVersion::_110, + 120 => GLSLVersion::_120, + 130 => GLSLVersion::_130, + 140 => GLSLVersion::_140, + 150 => GLSLVersion::_150, + 300 => GLSLVersion::_300, + 310 => GLSLVersion::_310, + 320 => GLSLVersion::_320, + 330 => GLSLVersion::_330, + 400 => GLSLVersion::_400, + 410 => GLSLVersion::_410, + 420 => GLSLVersion::_420, + 430 => GLSLVersion::_430, + 440 => GLSLVersion::_440, + 450 => GLSLVersion::_450, + value => GLSLVersion::__Unknown(value), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLStereoDownmix { + GreenMagentaDubois, + RedCyanDubois, + AmberBlueDubois, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLStereoDownmix { + type GlibType = ffi::GstGLStereoDownmix; + + fn to_glib(&self) -> ffi::GstGLStereoDownmix { + match *self { + GLStereoDownmix::GreenMagentaDubois => ffi::GST_GL_STEREO_DOWNMIX_ANAGLYPH_GREEN_MAGENTA_DUBOIS, + GLStereoDownmix::RedCyanDubois => ffi::GST_GL_STEREO_DOWNMIX_ANAGLYPH_RED_CYAN_DUBOIS, + GLStereoDownmix::AmberBlueDubois => ffi::GST_GL_STEREO_DOWNMIX_ANAGLYPH_AMBER_BLUE_DUBOIS, + GLStereoDownmix::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLStereoDownmix { + fn from_glib(value: ffi::GstGLStereoDownmix) -> Self { + skip_assert_initialized!(); + match value { + 0 => GLStereoDownmix::GreenMagentaDubois, + 1 => GLStereoDownmix::RedCyanDubois, + 2 => GLStereoDownmix::AmberBlueDubois, + value => GLStereoDownmix::__Unknown(value), + } + } +} + +impl StaticType for GLStereoDownmix { + fn static_type() -> Type { + unsafe { from_glib(ffi::gst_gl_stereo_downmix_mode_get_type()) } + } +} + +impl<'a> FromValueOptional<'a> for GLStereoDownmix { + unsafe fn from_value_optional(value: &Value) -> Option { + Some(FromValue::from_value(value)) + } +} + +impl<'a> FromValue<'a> for GLStereoDownmix { + unsafe fn from_value(value: &Value) -> Self { + from_glib(gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl SetValue for GLStereoDownmix { + unsafe fn set_value(value: &mut Value, this: &Self) { + gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib()) + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLTextureTarget { + None, + _2d, + Rectangle, + ExternalOes, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLTextureTarget { + type GlibType = ffi::GstGLTextureTarget; + + fn to_glib(&self) -> ffi::GstGLTextureTarget { + match *self { + GLTextureTarget::None => ffi::GST_GL_TEXTURE_TARGET_NONE, + GLTextureTarget::_2d => ffi::GST_GL_TEXTURE_TARGET_2D, + GLTextureTarget::Rectangle => ffi::GST_GL_TEXTURE_TARGET_RECTANGLE, + GLTextureTarget::ExternalOes => ffi::GST_GL_TEXTURE_TARGET_EXTERNAL_OES, + GLTextureTarget::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLTextureTarget { + fn from_glib(value: ffi::GstGLTextureTarget) -> Self { + skip_assert_initialized!(); + match value { + 0 => GLTextureTarget::None, + 1 => GLTextureTarget::_2d, + 2 => GLTextureTarget::Rectangle, + 3 => GLTextureTarget::ExternalOes, + value => GLTextureTarget::__Unknown(value), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLUploadReturn { + Done, + Error, + Unsupported, + Reconfigure, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLUploadReturn { + type GlibType = ffi::GstGLUploadReturn; + + fn to_glib(&self) -> ffi::GstGLUploadReturn { + match *self { + GLUploadReturn::Done => ffi::GST_GL_UPLOAD_DONE, + GLUploadReturn::Error => ffi::GST_GL_UPLOAD_ERROR, + GLUploadReturn::Unsupported => ffi::GST_GL_UPLOAD_UNSUPPORTED, + GLUploadReturn::Reconfigure => ffi::GST_GL_UPLOAD_RECONFIGURE, + GLUploadReturn::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLUploadReturn { + fn from_glib(value: ffi::GstGLUploadReturn) -> Self { + skip_assert_initialized!(); + match value { + 1 => GLUploadReturn::Done, + -1 => GLUploadReturn::Error, + -2 => GLUploadReturn::Unsupported, + -3 => GLUploadReturn::Reconfigure, + value => GLUploadReturn::__Unknown(value), + } + } +} + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Copy)] +pub enum GLWindowError { + Failed, + OldLibs, + ResourceUnavailable, + #[doc(hidden)] + __Unknown(i32), +} + +#[doc(hidden)] +impl ToGlib for GLWindowError { + type GlibType = ffi::GstGLWindowError; + + fn to_glib(&self) -> ffi::GstGLWindowError { + match *self { + GLWindowError::Failed => ffi::GST_GL_WINDOW_ERROR_FAILED, + GLWindowError::OldLibs => ffi::GST_GL_WINDOW_ERROR_OLD_LIBS, + GLWindowError::ResourceUnavailable => ffi::GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE, + GLWindowError::__Unknown(value) => value + } + } +} + +#[doc(hidden)] +impl FromGlib for GLWindowError { + fn from_glib(value: ffi::GstGLWindowError) -> Self { + skip_assert_initialized!(); + match value { + 0 => GLWindowError::Failed, + 1 => GLWindowError::OldLibs, + 2 => GLWindowError::ResourceUnavailable, + value => GLWindowError::__Unknown(value), + } + } +} + +impl ErrorDomain for GLWindowError { + fn domain() -> Quark { + skip_assert_initialized!(); + unsafe { from_glib(ffi::gst_gl_window_error_quark()) } + } + + fn code(self) -> i32 { + self.to_glib() + } + + fn from(code: i32) -> Option { + skip_assert_initialized!(); + match code { + 0 => Some(GLWindowError::Failed), + 1 => Some(GLWindowError::OldLibs), + 2 => Some(GLWindowError::ResourceUnavailable), + _ => Some(GLWindowError::Failed), + } + } +} + diff --git a/gstreamer-gl/src/auto/flags.rs b/gstreamer-gl/src/auto/flags.rs new file mode 100644 index 000000000..bbf82f7f1 --- /dev/null +++ b/gstreamer-gl/src/auto/flags.rs @@ -0,0 +1,123 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use ffi; +use glib::translate::*; + +bitflags! { + pub struct GLAPI: u32 { + const NONE = 0; + const OPENGL = 1; + const OPENGL3 = 2; + const GLES1 = 32768; + const GLES2 = 65536; + const ANY = 4294967295; + } +} + +#[doc(hidden)] +impl ToGlib for GLAPI { + type GlibType = ffi::GstGLAPI; + + fn to_glib(&self) -> ffi::GstGLAPI { + self.bits() + } +} + +#[doc(hidden)] +impl FromGlib for GLAPI { + fn from_glib(value: ffi::GstGLAPI) -> GLAPI { + skip_assert_initialized!(); + GLAPI::from_bits_truncate(value) + } +} + +bitflags! { + pub struct GLDisplayType: u32 { + const NONE = 0; + const X11 = 1; + const WAYLAND = 2; + const COCOA = 4; + const WIN32 = 8; + const DISPMANX = 16; + const EGL = 32; + const VIV_FB = 64; + const GBM = 128; + const ANY = 4294967295; + } +} + +#[doc(hidden)] +impl ToGlib for GLDisplayType { + type GlibType = ffi::GstGLDisplayType; + + fn to_glib(&self) -> ffi::GstGLDisplayType { + self.bits() + } +} + +#[doc(hidden)] +impl FromGlib for GLDisplayType { + fn from_glib(value: ffi::GstGLDisplayType) -> GLDisplayType { + skip_assert_initialized!(); + GLDisplayType::from_bits_truncate(value) + } +} + +bitflags! { + pub struct GLPlatform: u32 { + const NONE = 0; + const EGL = 1; + const GLX = 2; + const WGL = 4; + const CGL = 8; + const EAGL = 16; + const ANY = 4294967295; + } +} + +#[doc(hidden)] +impl ToGlib for GLPlatform { + type GlibType = ffi::GstGLPlatform; + + fn to_glib(&self) -> ffi::GstGLPlatform { + self.bits() + } +} + +#[doc(hidden)] +impl FromGlib for GLPlatform { + fn from_glib(value: ffi::GstGLPlatform) -> GLPlatform { + skip_assert_initialized!(); + GLPlatform::from_bits_truncate(value) + } +} + +bitflags! { + pub struct GLSLProfile: u32 { + const NONE = 0; + const ES = 1; + const CORE = 2; + const COMPATIBILITY = 4; + const ANY = 4294967295; + } +} + +#[doc(hidden)] +impl ToGlib for GLSLProfile { + type GlibType = ffi::GstGLSLProfile; + + fn to_glib(&self) -> ffi::GstGLSLProfile { + self.bits() + } +} + +#[doc(hidden)] +impl FromGlib for GLSLProfile { + fn from_glib(value: ffi::GstGLSLProfile) -> GLSLProfile { + skip_assert_initialized!(); + GLSLProfile::from_bits_truncate(value) + } +} + diff --git a/gstreamer-gl/src/auto/gl_base_filter.rs b/gstreamer-gl/src/auto/gl_base_filter.rs new file mode 100644 index 000000000..c0b2d0bbd --- /dev/null +++ b/gstreamer-gl/src/auto/gl_base_filter.rs @@ -0,0 +1,65 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLContext; +use ffi; +use glib; +use glib::StaticType; +use glib::Value; +use glib::object::Downcast; +use glib::object::IsA; +use glib::signal::SignalHandlerId; +use glib::signal::connect; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::boxed::Box as Box_; +use std::mem; +use std::mem::transmute; +use std::ptr; + +glib_wrapper! { + pub struct GLBaseFilter(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_base_filter_get_type(), + } +} + +unsafe impl Send for GLBaseFilter {} +unsafe impl Sync for GLBaseFilter {} + +pub trait GLBaseFilterExt { + fn get_property_context(&self) -> Option; + + fn connect_property_context_notify(&self, f: F) -> SignalHandlerId; +} + +impl + IsA> GLBaseFilterExt for O { + fn get_property_context(&self) -> Option { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "context".to_glib_none().0, value.to_glib_none_mut().0); + value.get() + } + } + + fn connect_property_context_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::context", + transmute(notify_context_trampoline:: as usize), Box_::into_raw(f) as *mut _) + } + } +} + +unsafe extern "C" fn notify_context_trampoline

(this: *mut ffi::GstGLBaseFilter, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) +where P: IsA { + let f: &&(Fn(&P) + Send + Sync + 'static) = transmute(f); + f(&GLBaseFilter::from_glib_borrow(this).downcast_unchecked()) +} diff --git a/gstreamer-gl/src/auto/gl_color_convert.rs b/gstreamer-gl/src/auto/gl_color_convert.rs new file mode 100644 index 000000000..8bc65279b --- /dev/null +++ b/gstreamer-gl/src/auto/gl_color_convert.rs @@ -0,0 +1,48 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLContext; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct GLColorConvert(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_color_convert_get_type(), + } +} + +impl GLColorConvert { + pub fn new(context: &GLContext) -> GLColorConvert { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_gl_color_convert_new(context.to_glib_none().0)) + } + } + + pub fn set_caps(&self, in_caps: &gst::Caps, out_caps: &gst::Caps) -> bool { + unsafe { + from_glib(ffi::gst_gl_color_convert_set_caps(self.to_glib_none().0, in_caps.to_glib_none().0, out_caps.to_glib_none().0)) + } + } + + pub fn transform_caps(context: &GLContext, direction: gst::PadDirection, caps: &gst::Caps, filter: &gst::Caps) -> Option { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_gl_color_convert_transform_caps(context.to_glib_none().0, direction.to_glib(), caps.to_glib_none().0, filter.to_glib_none().0)) + } + } +} + +unsafe impl Send for GLColorConvert {} +unsafe impl Sync for GLColorConvert {} diff --git a/gstreamer-gl/src/auto/gl_context.rs b/gstreamer-gl/src/auto/gl_context.rs new file mode 100644 index 000000000..aa0b0abe8 --- /dev/null +++ b/gstreamer-gl/src/auto/gl_context.rs @@ -0,0 +1,244 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use Error; +use GLAPI; +use GLDisplay; +use GLPlatform; +use GLSLProfile; +use GLSLVersion; +use GLWindow; +use ffi; +use glib; +use glib::object::IsA; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct GLContext(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_context_get_type(), + } +} + +impl GLContext { + pub fn new>(display: &P) -> GLContext { + skip_assert_initialized!(); + unsafe { + from_glib_none(ffi::gst_gl_context_new(display.to_glib_none().0)) + } + } + + pub fn get_current() -> Option { + assert_initialized_main_thread!(); + unsafe { + from_glib_none(ffi::gst_gl_context_get_current()) + } + } + + pub fn get_current_gl_api(platform: GLPlatform) -> (GLAPI, u32, u32) { + assert_initialized_main_thread!(); + unsafe { + let mut major = mem::uninitialized(); + let mut minor = mem::uninitialized(); + let ret = from_glib(ffi::gst_gl_context_get_current_gl_api(platform.to_glib(), &mut major, &mut minor)); + (ret, major, minor) + } + } +} + +unsafe impl Send for GLContext {} +unsafe impl Sync for GLContext {} + +pub trait GLContextExt { + fn activate(&self, activate: bool) -> Result<(), glib::error::BoolError>; + + fn can_share(&self, other_context: &GLContext) -> bool; + + fn check_feature(&self, feature: &str) -> bool; + + fn check_framebuffer_status(&self, fbo_target: u32) -> bool; + + fn check_gl_version(&self, api: GLAPI, maj: i32, min: i32) -> bool; + + fn clear_framebuffer(&self); + + fn clear_shader(&self); + + fn create<'a, P: Into>>(&self, other_context: P) -> Result<(), Error>; + + fn destroy(&self); + + fn fill_info(&self) -> Result<(), Error>; + + fn get_display(&self) -> GLDisplay; + + fn get_gl_api(&self) -> GLAPI; + + fn get_gl_platform(&self) -> GLPlatform; + + fn get_gl_platform_version(&self) -> (i32, i32); + + fn get_gl_version(&self) -> (i32, i32); + + fn get_window(&self) -> Option; + + fn is_shared(&self) -> bool; + + fn set_shared_with(&self, share: &GLContext); + + fn set_window(&self, window: &GLWindow) -> bool; + + fn supports_glsl_profile_version(&self, version: GLSLVersion, profile: GLSLProfile) -> bool; + + fn swap_buffers(&self); +} + +impl> GLContextExt for O { + fn activate(&self, activate: bool) -> Result<(), glib::error::BoolError> { + unsafe { + glib::error::BoolError::from_glib(ffi::gst_gl_context_activate(self.to_glib_none().0, activate.to_glib()), "Failed to activate OpenGL context") + } + } + + fn can_share(&self, other_context: &GLContext) -> bool { + unsafe { + from_glib(ffi::gst_gl_context_can_share(self.to_glib_none().0, other_context.to_glib_none().0)) + } + } + + fn check_feature(&self, feature: &str) -> bool { + unsafe { + from_glib(ffi::gst_gl_context_check_feature(self.to_glib_none().0, feature.to_glib_none().0)) + } + } + + fn check_framebuffer_status(&self, fbo_target: u32) -> bool { + unsafe { + from_glib(ffi::gst_gl_context_check_framebuffer_status(self.to_glib_none().0, fbo_target)) + } + } + + fn check_gl_version(&self, api: GLAPI, maj: i32, min: i32) -> bool { + unsafe { + from_glib(ffi::gst_gl_context_check_gl_version(self.to_glib_none().0, api.to_glib(), maj, min)) + } + } + + fn clear_framebuffer(&self) { + unsafe { + ffi::gst_gl_context_clear_framebuffer(self.to_glib_none().0); + } + } + + fn clear_shader(&self) { + unsafe { + ffi::gst_gl_context_clear_shader(self.to_glib_none().0); + } + } + + fn create<'a, P: Into>>(&self, other_context: P) -> Result<(), Error> { + let other_context = other_context.into(); + let other_context = other_context.to_glib_none(); + unsafe { + let mut error = ptr::null_mut(); + let _ = ffi::gst_gl_context_create(self.to_glib_none().0, other_context.0, &mut error); + if error.is_null() { Ok(()) } else { Err(from_glib_full(error)) } + } + } + + fn destroy(&self) { + unsafe { + ffi::gst_gl_context_destroy(self.to_glib_none().0); + } + } + + fn fill_info(&self) -> Result<(), Error> { + unsafe { + let mut error = ptr::null_mut(); + let _ = ffi::gst_gl_context_fill_info(self.to_glib_none().0, &mut error); + if error.is_null() { Ok(()) } else { Err(from_glib_full(error)) } + } + } + + fn get_display(&self) -> GLDisplay { + unsafe { + from_glib_full(ffi::gst_gl_context_get_display(self.to_glib_none().0)) + } + } + + fn get_gl_api(&self) -> GLAPI { + unsafe { + from_glib(ffi::gst_gl_context_get_gl_api(self.to_glib_none().0)) + } + } + + fn get_gl_platform(&self) -> GLPlatform { + unsafe { + from_glib(ffi::gst_gl_context_get_gl_platform(self.to_glib_none().0)) + } + } + + fn get_gl_platform_version(&self) -> (i32, i32) { + unsafe { + let mut major = mem::uninitialized(); + let mut minor = mem::uninitialized(); + ffi::gst_gl_context_get_gl_platform_version(self.to_glib_none().0, &mut major, &mut minor); + (major, minor) + } + } + + fn get_gl_version(&self) -> (i32, i32) { + unsafe { + let mut maj = mem::uninitialized(); + let mut min = mem::uninitialized(); + ffi::gst_gl_context_get_gl_version(self.to_glib_none().0, &mut maj, &mut min); + (maj, min) + } + } + + fn get_window(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_gl_context_get_window(self.to_glib_none().0)) + } + } + + fn is_shared(&self) -> bool { + unsafe { + from_glib(ffi::gst_gl_context_is_shared(self.to_glib_none().0)) + } + } + + fn set_shared_with(&self, share: &GLContext) { + unsafe { + ffi::gst_gl_context_set_shared_with(self.to_glib_none().0, share.to_glib_none().0); + } + } + + fn set_window(&self, window: &GLWindow) -> bool { + unsafe { + from_glib(ffi::gst_gl_context_set_window(self.to_glib_none().0, window.to_glib_full())) + } + } + + fn supports_glsl_profile_version(&self, version: GLSLVersion, profile: GLSLProfile) -> bool { + unsafe { + from_glib(ffi::gst_gl_context_supports_glsl_profile_version(self.to_glib_none().0, version.to_glib(), profile.to_glib())) + } + } + + fn swap_buffers(&self) { + unsafe { + ffi::gst_gl_context_swap_buffers(self.to_glib_none().0); + } + } +} diff --git a/gstreamer-gl/src/auto/gl_display.rs b/gstreamer-gl/src/auto/gl_display.rs new file mode 100644 index 000000000..bbf5b7d5b --- /dev/null +++ b/gstreamer-gl/src/auto/gl_display.rs @@ -0,0 +1,139 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use Error; +use GLAPI; +use GLContext; +use GLDisplayType; +use GLWindow; +use ffi; +use glib; +use glib::object::Downcast; +use glib::object::IsA; +use glib::signal::SignalHandlerId; +use glib::signal::connect; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::boxed::Box as Box_; +use std::mem; +use std::mem::transmute; +use std::ptr; + +glib_wrapper! { + pub struct GLDisplay(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_display_get_type(), + } +} + +impl GLDisplay { + pub fn new() -> GLDisplay { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_gl_display_new()) + } + } +} + +impl Default for GLDisplay { + fn default() -> Self { + Self::new() + } +} + +unsafe impl Send for GLDisplay {} +unsafe impl Sync for GLDisplay {} + +pub trait GLDisplayExt { + fn add_context(&self, context: &GLContext) -> Result<(), glib::error::BoolError>; + + fn create_context(&self, other_context: &GLContext) -> Result; + + fn create_window(&self) -> Option; + + fn filter_gl_api(&self, gl_api: GLAPI); + + fn get_gl_api(&self) -> GLAPI; + + fn get_gl_api_unlocked(&self) -> GLAPI; + + fn get_handle_type(&self) -> GLDisplayType; + + fn remove_window(&self, window: &GLWindow) -> Result<(), glib::error::BoolError>; + + fn connect_create_context GLContext + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId; +} + +impl + IsA> GLDisplayExt for O { + fn add_context(&self, context: &GLContext) -> Result<(), glib::error::BoolError> { + unsafe { + glib::error::BoolError::from_glib(ffi::gst_gl_display_add_context(self.to_glib_none().0, context.to_glib_none().0), "Failed to add OpenGL context") + } + } + + fn create_context(&self, other_context: &GLContext) -> Result { + unsafe { + let mut p_context = ptr::null_mut(); + let mut error = ptr::null_mut(); + let _ = ffi::gst_gl_display_create_context(self.to_glib_none().0, other_context.to_glib_none().0, &mut p_context, &mut error); + if error.is_null() { Ok(from_glib_full(p_context)) } else { Err(from_glib_full(error)) } + } + } + + fn create_window(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_gl_display_create_window(self.to_glib_none().0)) + } + } + + fn filter_gl_api(&self, gl_api: GLAPI) { + unsafe { + ffi::gst_gl_display_filter_gl_api(self.to_glib_none().0, gl_api.to_glib()); + } + } + + fn get_gl_api(&self) -> GLAPI { + unsafe { + from_glib(ffi::gst_gl_display_get_gl_api(self.to_glib_none().0)) + } + } + + fn get_gl_api_unlocked(&self) -> GLAPI { + unsafe { + from_glib(ffi::gst_gl_display_get_gl_api_unlocked(self.to_glib_none().0)) + } + } + + fn get_handle_type(&self) -> GLDisplayType { + unsafe { + from_glib(ffi::gst_gl_display_get_handle_type(self.to_glib_none().0)) + } + } + + fn remove_window(&self, window: &GLWindow) -> Result<(), glib::error::BoolError> { + unsafe { + glib::error::BoolError::from_glib(ffi::gst_gl_display_remove_window(self.to_glib_none().0, window.to_glib_none().0), "Failed to remove window") + } + } + + fn connect_create_context GLContext + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_ GLContext + Send + Sync + 'static>> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "create-context", + transmute(create_context_trampoline:: as usize), Box_::into_raw(f) as *mut _) + } + } +} + +unsafe extern "C" fn create_context_trampoline

(this: *mut ffi::GstGLDisplay, context: *mut ffi::GstGLContext, f: glib_ffi::gpointer) -> *mut ffi::GstGLContext +where P: IsA { + let f: &&(Fn(&P, &GLContext) -> GLContext + Send + Sync + 'static) = transmute(f); + f(&GLDisplay::from_glib_borrow(this).downcast_unchecked(), &from_glib_borrow(context)).to_glib_full() +} diff --git a/gstreamer-gl/src/auto/gl_display_egl.rs b/gstreamer-gl/src/auto/gl_display_egl.rs new file mode 100644 index 000000000..85288a56d --- /dev/null +++ b/gstreamer-gl/src/auto/gl_display_egl.rs @@ -0,0 +1,50 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLDisplay; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct GLDisplayEGL(Object): [ + GLDisplay, + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_display_egl_get_type(), + } +} + +impl GLDisplayEGL { + pub fn new() -> GLDisplayEGL { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_gl_display_egl_new()) + } + } + + //pub fn new_with_egl_display>>(display: P) -> GLDisplayEGL { + // unsafe { TODO: call ffi::gst_gl_display_egl_new_with_egl_display() } + //} + + //pub fn get_from_native(type_: GLDisplayType, display: /*Unimplemented*/Fundamental: UIntPtr) -> /*Unimplemented*/Option { + // unsafe { TODO: call ffi::gst_gl_display_egl_get_from_native() } + //} +} + +impl Default for GLDisplayEGL { + fn default() -> Self { + Self::new() + } +} + +unsafe impl Send for GLDisplayEGL {} +unsafe impl Sync for GLDisplayEGL {} diff --git a/gstreamer-gl/src/auto/gl_framebuffer.rs b/gstreamer-gl/src/auto/gl_framebuffer.rs new file mode 100644 index 000000000..19e8d471d --- /dev/null +++ b/gstreamer-gl/src/auto/gl_framebuffer.rs @@ -0,0 +1,86 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLContext; +use ffi; +use glib::object::IsA; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct GLFramebuffer(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_framebuffer_get_type(), + } +} + +impl GLFramebuffer { + pub fn new(context: &GLContext) -> GLFramebuffer { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_gl_framebuffer_new(context.to_glib_none().0)) + } + } + + pub fn new_with_default_depth(context: &GLContext, width: u32, height: u32) -> GLFramebuffer { + skip_assert_initialized!(); + unsafe { + from_glib_none(ffi::gst_gl_framebuffer_new_with_default_depth(context.to_glib_none().0, width, height)) + } + } +} + +unsafe impl Send for GLFramebuffer {} +unsafe impl Sync for GLFramebuffer {} + +pub trait GLFramebufferExt { + //fn attach(&self, attachment_point: u32, mem: /*Ignored*/&mut GLBaseMemory); + + fn bind(&self); + + //fn draw_to_texture>>(&self, mem: /*Ignored*/&mut GLMemory, func: /*Unknown conversion*//*Unimplemented*/GLFramebufferFunc, user_data: P) -> bool; + + fn get_effective_dimensions(&self) -> (u32, u32); + + fn get_id(&self) -> u32; +} + +impl> GLFramebufferExt for O { + //fn attach(&self, attachment_point: u32, mem: /*Ignored*/&mut GLBaseMemory) { + // unsafe { TODO: call ffi::gst_gl_framebuffer_attach() } + //} + + fn bind(&self) { + unsafe { + ffi::gst_gl_framebuffer_bind(self.to_glib_none().0); + } + } + + //fn draw_to_texture>>(&self, mem: /*Ignored*/&mut GLMemory, func: /*Unknown conversion*//*Unimplemented*/GLFramebufferFunc, user_data: P) -> bool { + // unsafe { TODO: call ffi::gst_gl_framebuffer_draw_to_texture() } + //} + + fn get_effective_dimensions(&self) -> (u32, u32) { + unsafe { + let mut width = mem::uninitialized(); + let mut height = mem::uninitialized(); + ffi::gst_gl_framebuffer_get_effective_dimensions(self.to_glib_none().0, &mut width, &mut height); + (width, height) + } + } + + fn get_id(&self) -> u32 { + unsafe { + ffi::gst_gl_framebuffer_get_id(self.to_glib_none().0) + } + } +} diff --git a/gstreamer-gl/src/auto/gl_overlay_compositor.rs b/gstreamer-gl/src/auto/gl_overlay_compositor.rs new file mode 100644 index 000000000..1310a766b --- /dev/null +++ b/gstreamer-gl/src/auto/gl_overlay_compositor.rs @@ -0,0 +1,54 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLContext; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct GLOverlayCompositor(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_overlay_compositor_get_type(), + } +} + +impl GLOverlayCompositor { + pub fn new(context: &GLContext) -> GLOverlayCompositor { + skip_assert_initialized!(); + unsafe { + from_glib_none(ffi::gst_gl_overlay_compositor_new(context.to_glib_none().0)) + } + } + + pub fn draw_overlays(&self) { + unsafe { + ffi::gst_gl_overlay_compositor_draw_overlays(self.to_glib_none().0); + } + } + + pub fn free_overlays(&self) { + unsafe { + ffi::gst_gl_overlay_compositor_free_overlays(self.to_glib_none().0); + } + } + + pub fn add_caps(caps: &gst::Caps) -> Option { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_gl_overlay_compositor_add_caps(caps.to_glib_none().0)) + } + } +} + +unsafe impl Send for GLOverlayCompositor {} +unsafe impl Sync for GLOverlayCompositor {} diff --git a/gstreamer-gl/src/auto/gl_shader.rs b/gstreamer-gl/src/auto/gl_shader.rs new file mode 100644 index 000000000..576be8291 --- /dev/null +++ b/gstreamer-gl/src/auto/gl_shader.rs @@ -0,0 +1,273 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use Error; +use GLContext; +use GLSLStage; +use ffi; +use glib::StaticType; +use glib::Value; +use glib::signal::SignalHandlerId; +use glib::signal::connect; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::boxed::Box as Box_; +use std::mem; +use std::mem::transmute; +use std::ptr; + +glib_wrapper! { + pub struct GLShader(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_shader_get_type(), + } +} + +impl GLShader { + pub fn new(context: &GLContext) -> GLShader { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_gl_shader_new(context.to_glib_none().0)) + } + } + + pub fn new_default(context: &GLContext) -> Result { + skip_assert_initialized!(); + unsafe { + let mut error = ptr::null_mut(); + let ret = ffi::gst_gl_shader_new_default(context.to_glib_none().0, &mut error); + if error.is_null() { Ok(from_glib_full(ret)) } else { Err(from_glib_full(error)) } + } + } + + //pub fn new_link_with_stages(context: &GLContext, error: &mut Error, : /*Unknown conversion*//*Unimplemented*/Fundamental: VarArgs) -> GLShader { + // unsafe { TODO: call ffi::gst_gl_shader_new_link_with_stages() } + //} + + //pub fn new_with_stages(context: &GLContext, error: &mut Error, : /*Unknown conversion*//*Unimplemented*/Fundamental: VarArgs) -> GLShader { + // unsafe { TODO: call ffi::gst_gl_shader_new_with_stages() } + //} + + pub fn attach(&self, stage: &GLSLStage) -> bool { + unsafe { + from_glib(ffi::gst_gl_shader_attach(self.to_glib_none().0, stage.to_glib_none().0)) + } + } + + pub fn attach_unlocked(&self, stage: &GLSLStage) -> bool { + unsafe { + from_glib(ffi::gst_gl_shader_attach_unlocked(self.to_glib_none().0, stage.to_glib_none().0)) + } + } + + pub fn bind_attribute_location(&self, index: u32, name: &str) { + unsafe { + ffi::gst_gl_shader_bind_attribute_location(self.to_glib_none().0, index, name.to_glib_none().0); + } + } + + pub fn bind_frag_data_location(&self, index: u32, name: &str) { + unsafe { + ffi::gst_gl_shader_bind_frag_data_location(self.to_glib_none().0, index, name.to_glib_none().0); + } + } + + pub fn compile_attach_stage(&self, stage: &GLSLStage) -> Result<(), Error> { + unsafe { + let mut error = ptr::null_mut(); + let _ = ffi::gst_gl_shader_compile_attach_stage(self.to_glib_none().0, stage.to_glib_none().0, &mut error); + if error.is_null() { Ok(()) } else { Err(from_glib_full(error)) } + } + } + + pub fn detach(&self, stage: &GLSLStage) { + unsafe { + ffi::gst_gl_shader_detach(self.to_glib_none().0, stage.to_glib_none().0); + } + } + + pub fn detach_unlocked(&self, stage: &GLSLStage) { + unsafe { + ffi::gst_gl_shader_detach_unlocked(self.to_glib_none().0, stage.to_glib_none().0); + } + } + + pub fn get_attribute_location(&self, name: &str) -> i32 { + unsafe { + ffi::gst_gl_shader_get_attribute_location(self.to_glib_none().0, name.to_glib_none().0) + } + } + + pub fn get_program_handle(&self) -> i32 { + unsafe { + ffi::gst_gl_shader_get_program_handle(self.to_glib_none().0) + } + } + + pub fn is_linked(&self) -> bool { + unsafe { + from_glib(ffi::gst_gl_shader_is_linked(self.to_glib_none().0)) + } + } + + pub fn link(&self) -> Result<(), Error> { + unsafe { + let mut error = ptr::null_mut(); + let _ = ffi::gst_gl_shader_link(self.to_glib_none().0, &mut error); + if error.is_null() { Ok(()) } else { Err(from_glib_full(error)) } + } + } + + pub fn release(&self) { + unsafe { + ffi::gst_gl_shader_release(self.to_glib_none().0); + } + } + + pub fn release_unlocked(&self) { + unsafe { + ffi::gst_gl_shader_release_unlocked(self.to_glib_none().0); + } + } + + pub fn set_uniform_1f(&self, name: &str, value: f32) { + unsafe { + ffi::gst_gl_shader_set_uniform_1f(self.to_glib_none().0, name.to_glib_none().0, value); + } + } + + pub fn set_uniform_1fv(&self, name: &str, value: &[f32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_1fv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn set_uniform_1i(&self, name: &str, value: i32) { + unsafe { + ffi::gst_gl_shader_set_uniform_1i(self.to_glib_none().0, name.to_glib_none().0, value); + } + } + + pub fn set_uniform_1iv(&self, name: &str, value: &[i32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_1iv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn set_uniform_2f(&self, name: &str, v0: f32, v1: f32) { + unsafe { + ffi::gst_gl_shader_set_uniform_2f(self.to_glib_none().0, name.to_glib_none().0, v0, v1); + } + } + + pub fn set_uniform_2fv(&self, name: &str, value: &[f32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_2fv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn set_uniform_2i(&self, name: &str, v0: i32, v1: i32) { + unsafe { + ffi::gst_gl_shader_set_uniform_2i(self.to_glib_none().0, name.to_glib_none().0, v0, v1); + } + } + + pub fn set_uniform_2iv(&self, name: &str, value: &[i32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_2iv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn set_uniform_3f(&self, name: &str, v0: f32, v1: f32, v2: f32) { + unsafe { + ffi::gst_gl_shader_set_uniform_3f(self.to_glib_none().0, name.to_glib_none().0, v0, v1, v2); + } + } + + pub fn set_uniform_3fv(&self, name: &str, value: &[f32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_3fv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn set_uniform_3i(&self, name: &str, v0: i32, v1: i32, v2: i32) { + unsafe { + ffi::gst_gl_shader_set_uniform_3i(self.to_glib_none().0, name.to_glib_none().0, v0, v1, v2); + } + } + + pub fn set_uniform_3iv(&self, name: &str, value: &[i32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_3iv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn set_uniform_4f(&self, name: &str, v0: f32, v1: f32, v2: f32, v3: f32) { + unsafe { + ffi::gst_gl_shader_set_uniform_4f(self.to_glib_none().0, name.to_glib_none().0, v0, v1, v2, v3); + } + } + + pub fn set_uniform_4fv(&self, name: &str, value: &[f32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_4fv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn set_uniform_4i(&self, name: &str, v0: i32, v1: i32, v2: i32, v3: i32) { + unsafe { + ffi::gst_gl_shader_set_uniform_4i(self.to_glib_none().0, name.to_glib_none().0, v0, v1, v2, v3); + } + } + + pub fn set_uniform_4iv(&self, name: &str, value: &[i32]) { + let count = value.len() as u32; + unsafe { + ffi::gst_gl_shader_set_uniform_4iv(self.to_glib_none().0, name.to_glib_none().0, count, value.to_glib_none().0); + } + } + + pub fn use_(&self) { + unsafe { + ffi::gst_gl_shader_use(self.to_glib_none().0); + } + } + + pub fn get_property_linked(&self) -> bool { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "linked".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() + } + } + + pub fn connect_property_linked_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::linked", + transmute(notify_linked_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } +} + +unsafe impl Send for GLShader {} +unsafe impl Sync for GLShader {} + +unsafe extern "C" fn notify_linked_trampoline(this: *mut ffi::GstGLShader, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) { + let f: &&(Fn(&GLShader) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} diff --git a/gstreamer-gl/src/auto/gl_upload.rs b/gstreamer-gl/src/auto/gl_upload.rs new file mode 100644 index 000000000..2d4814e39 --- /dev/null +++ b/gstreamer-gl/src/auto/gl_upload.rs @@ -0,0 +1,69 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLContext; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct GLUpload(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_upload_get_type(), + } +} + +impl GLUpload { + pub fn new(context: &GLContext) -> GLUpload { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_gl_upload_new(context.to_glib_none().0)) + } + } + + pub fn get_caps(&self) -> (gst::Caps, gst::Caps) { + unsafe { + let mut in_caps = ptr::null_mut(); + let mut out_caps = ptr::null_mut(); + ffi::gst_gl_upload_get_caps(self.to_glib_none().0, &mut in_caps, &mut out_caps); + (from_glib_full(in_caps), from_glib_full(out_caps)) + } + } + + pub fn set_caps(&self, in_caps: &gst::Caps, out_caps: &gst::Caps) -> bool { + unsafe { + from_glib(ffi::gst_gl_upload_set_caps(self.to_glib_none().0, in_caps.to_glib_none().0, out_caps.to_glib_none().0)) + } + } + + pub fn set_context(&self, context: &GLContext) { + unsafe { + ffi::gst_gl_upload_set_context(self.to_glib_none().0, context.to_glib_none().0); + } + } + + pub fn transform_caps(&self, context: &GLContext, direction: gst::PadDirection, caps: &gst::Caps, filter: &gst::Caps) -> Option { + unsafe { + from_glib_full(ffi::gst_gl_upload_transform_caps(self.to_glib_none().0, context.to_glib_none().0, direction.to_glib(), caps.to_glib_none().0, filter.to_glib_none().0)) + } + } + + pub fn get_input_template_caps() -> gst::Caps { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_gl_upload_get_input_template_caps()) + } + } +} + +unsafe impl Send for GLUpload {} +unsafe impl Sync for GLUpload {} diff --git a/gstreamer-gl/src/auto/gl_view_convert.rs b/gstreamer-gl/src/auto/gl_view_convert.rs new file mode 100644 index 000000000..22968cc0f --- /dev/null +++ b/gstreamer-gl/src/auto/gl_view_convert.rs @@ -0,0 +1,214 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLContext; +use GLStereoDownmix; +use ffi; +use glib::StaticType; +use glib::Value; +use glib::signal::SignalHandlerId; +use glib::signal::connect; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use gst_video; +use std::boxed::Box as Box_; +use std::mem; +use std::mem::transmute; +use std::ptr; + +glib_wrapper! { + pub struct GLViewConvert(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_view_convert_get_type(), + } +} + +impl GLViewConvert { + pub fn new() -> GLViewConvert { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_gl_view_convert_new()) + } + } + + pub fn perform(&self, inbuf: &gst::Buffer) -> Option { + unsafe { + from_glib_full(ffi::gst_gl_view_convert_perform(self.to_glib_none().0, inbuf.to_glib_none().0)) + } + } + + pub fn reset(&self) { + unsafe { + ffi::gst_gl_view_convert_reset(self.to_glib_none().0); + } + } + + pub fn set_caps(&self, in_caps: &gst::Caps, out_caps: &gst::Caps) -> bool { + unsafe { + from_glib(ffi::gst_gl_view_convert_set_caps(self.to_glib_none().0, in_caps.to_glib_none().0, out_caps.to_glib_none().0)) + } + } + + pub fn set_context(&self, context: &GLContext) { + unsafe { + ffi::gst_gl_view_convert_set_context(self.to_glib_none().0, context.to_glib_none().0); + } + } + + pub fn transform_caps(&self, direction: gst::PadDirection, caps: &gst::Caps, filter: &gst::Caps) -> Option { + unsafe { + from_glib_full(ffi::gst_gl_view_convert_transform_caps(self.to_glib_none().0, direction.to_glib(), caps.to_glib_none().0, filter.to_glib_none().0)) + } + } + + pub fn get_property_downmix_mode(&self) -> GLStereoDownmix { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "downmix-mode".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() + } + } + + pub fn set_property_downmix_mode(&self, downmix_mode: GLStereoDownmix) { + unsafe { + gobject_ffi::g_object_set_property(self.to_glib_none().0, "downmix-mode".to_glib_none().0, Value::from(&downmix_mode).to_glib_none().0); + } + } + + pub fn get_property_input_flags_override(&self) -> gst_video::VideoMultiviewFlags { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "input-flags-override".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() + } + } + + pub fn set_property_input_flags_override(&self, input_flags_override: gst_video::VideoMultiviewFlags) { + unsafe { + gobject_ffi::g_object_set_property(self.to_glib_none().0, "input-flags-override".to_glib_none().0, Value::from(&input_flags_override).to_glib_none().0); + } + } + + pub fn get_property_input_mode_override(&self) -> gst_video::VideoMultiviewMode { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "input-mode-override".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() + } + } + + pub fn set_property_input_mode_override(&self, input_mode_override: gst_video::VideoMultiviewMode) { + unsafe { + gobject_ffi::g_object_set_property(self.to_glib_none().0, "input-mode-override".to_glib_none().0, Value::from(&input_mode_override).to_glib_none().0); + } + } + + pub fn get_property_output_flags_override(&self) -> gst_video::VideoMultiviewFlags { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "output-flags-override".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() + } + } + + pub fn set_property_output_flags_override(&self, output_flags_override: gst_video::VideoMultiviewFlags) { + unsafe { + gobject_ffi::g_object_set_property(self.to_glib_none().0, "output-flags-override".to_glib_none().0, Value::from(&output_flags_override).to_glib_none().0); + } + } + + pub fn get_property_output_mode_override(&self) -> gst_video::VideoMultiviewMode { + unsafe { + let mut value = Value::from_type(::static_type()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "output-mode-override".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() + } + } + + pub fn set_property_output_mode_override(&self, output_mode_override: gst_video::VideoMultiviewMode) { + unsafe { + gobject_ffi::g_object_set_property(self.to_glib_none().0, "output-mode-override".to_glib_none().0, Value::from(&output_mode_override).to_glib_none().0); + } + } + + pub fn connect_property_downmix_mode_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::downmix-mode", + transmute(notify_downmix_mode_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } + + pub fn connect_property_input_flags_override_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::input-flags-override", + transmute(notify_input_flags_override_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } + + pub fn connect_property_input_mode_override_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::input-mode-override", + transmute(notify_input_mode_override_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } + + pub fn connect_property_output_flags_override_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::output-flags-override", + transmute(notify_output_flags_override_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } + + pub fn connect_property_output_mode_override_notify(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "notify::output-mode-override", + transmute(notify_output_mode_override_trampoline as usize), Box_::into_raw(f) as *mut _) + } + } +} + +impl Default for GLViewConvert { + fn default() -> Self { + Self::new() + } +} + +unsafe impl Send for GLViewConvert {} +unsafe impl Sync for GLViewConvert {} + +unsafe extern "C" fn notify_downmix_mode_trampoline(this: *mut ffi::GstGLViewConvert, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) { + let f: &&(Fn(&GLViewConvert) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} + +unsafe extern "C" fn notify_input_flags_override_trampoline(this: *mut ffi::GstGLViewConvert, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) { + let f: &&(Fn(&GLViewConvert) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} + +unsafe extern "C" fn notify_input_mode_override_trampoline(this: *mut ffi::GstGLViewConvert, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) { + let f: &&(Fn(&GLViewConvert) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} + +unsafe extern "C" fn notify_output_flags_override_trampoline(this: *mut ffi::GstGLViewConvert, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) { + let f: &&(Fn(&GLViewConvert) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} + +unsafe extern "C" fn notify_output_mode_override_trampoline(this: *mut ffi::GstGLViewConvert, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer) { + let f: &&(Fn(&GLViewConvert) + Send + Sync + 'static) = transmute(f); + f(&from_glib_borrow(this)) +} diff --git a/gstreamer-gl/src/auto/gl_window.rs b/gstreamer-gl/src/auto/gl_window.rs new file mode 100644 index 000000000..bd21ac9eb --- /dev/null +++ b/gstreamer-gl/src/auto/gl_window.rs @@ -0,0 +1,187 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use GLContext; +use GLDisplay; +use ffi; +use glib; +use glib::object::Downcast; +use glib::object::IsA; +use glib::signal::SignalHandlerId; +use glib::signal::connect; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use libc; +use std::boxed::Box as Box_; +use std::mem; +use std::mem::transmute; +use std::ptr; + +glib_wrapper! { + pub struct GLWindow(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_gl_window_get_type(), + } +} + +impl GLWindow { + pub fn new>(display: &P) -> GLWindow { + skip_assert_initialized!(); + unsafe { + from_glib_full(ffi::gst_gl_window_new(display.to_glib_none().0)) + } + } +} + +unsafe impl Send for GLWindow {} +unsafe impl Sync for GLWindow {} + +pub trait GLWindowExt { + fn draw(&self); + + fn get_context(&self) -> Option; + + fn get_surface_dimensions(&self) -> (u32, u32); + + fn handle_events(&self, handle_events: bool); + + fn queue_resize(&self); + + fn quit(&self); + + fn resize(&self, width: u32, height: u32); + + fn run(&self); + + fn send_key_event(&self, event_type: &str, key_str: &str); + + fn send_mouse_event(&self, event_type: &str, button: i32, posx: f64, posy: f64); + + fn set_preferred_size(&self, width: i32, height: i32); + + fn set_render_rectangle(&self, x: i32, y: i32, width: i32, height: i32) -> bool; + + fn show(&self); + + fn connect_key_event(&self, f: F) -> SignalHandlerId; + + fn connect_mouse_event(&self, f: F) -> SignalHandlerId; +} + +impl + IsA> GLWindowExt for O { + fn draw(&self) { + unsafe { + ffi::gst_gl_window_draw(self.to_glib_none().0); + } + } + + fn get_context(&self) -> Option { + unsafe { + from_glib_full(ffi::gst_gl_window_get_context(self.to_glib_none().0)) + } + } + + fn get_surface_dimensions(&self) -> (u32, u32) { + unsafe { + let mut width = mem::uninitialized(); + let mut height = mem::uninitialized(); + ffi::gst_gl_window_get_surface_dimensions(self.to_glib_none().0, &mut width, &mut height); + (width, height) + } + } + + fn handle_events(&self, handle_events: bool) { + unsafe { + ffi::gst_gl_window_handle_events(self.to_glib_none().0, handle_events.to_glib()); + } + } + + fn queue_resize(&self) { + unsafe { + ffi::gst_gl_window_queue_resize(self.to_glib_none().0); + } + } + + fn quit(&self) { + unsafe { + ffi::gst_gl_window_quit(self.to_glib_none().0); + } + } + + fn resize(&self, width: u32, height: u32) { + unsafe { + ffi::gst_gl_window_resize(self.to_glib_none().0, width, height); + } + } + + fn run(&self) { + unsafe { + ffi::gst_gl_window_run(self.to_glib_none().0); + } + } + + fn send_key_event(&self, event_type: &str, key_str: &str) { + unsafe { + ffi::gst_gl_window_send_key_event(self.to_glib_none().0, event_type.to_glib_none().0, key_str.to_glib_none().0); + } + } + + fn send_mouse_event(&self, event_type: &str, button: i32, posx: f64, posy: f64) { + unsafe { + ffi::gst_gl_window_send_mouse_event(self.to_glib_none().0, event_type.to_glib_none().0, button, posx, posy); + } + } + + fn set_preferred_size(&self, width: i32, height: i32) { + unsafe { + ffi::gst_gl_window_set_preferred_size(self.to_glib_none().0, width, height); + } + } + + fn set_render_rectangle(&self, x: i32, y: i32, width: i32, height: i32) -> bool { + unsafe { + from_glib(ffi::gst_gl_window_set_render_rectangle(self.to_glib_none().0, x, y, width, height)) + } + } + + fn show(&self) { + unsafe { + ffi::gst_gl_window_show(self.to_glib_none().0); + } + } + + fn connect_key_event(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "key-event", + transmute(key_event_trampoline:: as usize), Box_::into_raw(f) as *mut _) + } + } + + fn connect_mouse_event(&self, f: F) -> SignalHandlerId { + unsafe { + let f: Box_> = Box_::new(Box_::new(f)); + connect(self.to_glib_none().0, "mouse-event", + transmute(mouse_event_trampoline:: as usize), Box_::into_raw(f) as *mut _) + } + } +} + +unsafe extern "C" fn key_event_trampoline

(this: *mut ffi::GstGLWindow, id: *mut libc::c_char, key: *mut libc::c_char, f: glib_ffi::gpointer) +where P: IsA { + let f: &&(Fn(&P, &str, &str) + Send + Sync + 'static) = transmute(f); + f(&GLWindow::from_glib_borrow(this).downcast_unchecked(), &String::from_glib_none(id), &String::from_glib_none(key)) +} + +unsafe extern "C" fn mouse_event_trampoline

(this: *mut ffi::GstGLWindow, id: *mut libc::c_char, button: libc::c_int, x: libc::c_double, y: libc::c_double, f: glib_ffi::gpointer) +where P: IsA { + let f: &&(Fn(&P, &str, i32, f64, f64) + Send + Sync + 'static) = transmute(f); + f(&GLWindow::from_glib_borrow(this).downcast_unchecked(), &String::from_glib_none(id), button, x, y) +} diff --git a/gstreamer-gl/src/auto/glsl_stage.rs b/gstreamer-gl/src/auto/glsl_stage.rs new file mode 100644 index 000000000..cb102a89f --- /dev/null +++ b/gstreamer-gl/src/auto/glsl_stage.rs @@ -0,0 +1,106 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use Error; +use GLContext; +use GLSLProfile; +use GLSLVersion; +use ffi; +use glib::translate::*; +use glib_ffi; +use gobject_ffi; +use gst; +use gst_ffi; +use std::mem; +use std::ptr; + +glib_wrapper! { + pub struct GLSLStage(Object): [ + gst::Object => gst_ffi::GstObject, + ]; + + match fn { + get_type => || ffi::gst_glsl_stage_get_type(), + } +} + +impl GLSLStage { + pub fn new(context: &GLContext, type_: u32) -> GLSLStage { + skip_assert_initialized!(); + unsafe { + from_glib_none(ffi::gst_glsl_stage_new(context.to_glib_none().0, type_)) + } + } + + pub fn new_default_fragment(context: &GLContext) -> GLSLStage { + skip_assert_initialized!(); + unsafe { + from_glib_none(ffi::gst_glsl_stage_new_default_fragment(context.to_glib_none().0)) + } + } + + pub fn new_default_vertex(context: &GLContext) -> GLSLStage { + skip_assert_initialized!(); + unsafe { + from_glib_none(ffi::gst_glsl_stage_new_default_vertex(context.to_glib_none().0)) + } + } + + pub fn new_with_string(context: &GLContext, type_: u32, version: GLSLVersion, profile: GLSLProfile, str: &str) -> GLSLStage { + skip_assert_initialized!(); + unsafe { + from_glib_none(ffi::gst_glsl_stage_new_with_string(context.to_glib_none().0, type_, version.to_glib(), profile.to_glib(), str.to_glib_none().0)) + } + } + + pub fn new_with_strings(context: &GLContext, type_: u32, version: GLSLVersion, profile: GLSLProfile, str: &[&str]) -> GLSLStage { + skip_assert_initialized!(); + let n_strings = str.len() as i32; + unsafe { + from_glib_none(ffi::gst_glsl_stage_new_with_strings(context.to_glib_none().0, type_, version.to_glib(), profile.to_glib(), n_strings, str.to_glib_none().0)) + } + } + + pub fn compile(&self) -> Result<(), Error> { + unsafe { + let mut error = ptr::null_mut(); + let _ = ffi::gst_glsl_stage_compile(self.to_glib_none().0, &mut error); + if error.is_null() { Ok(()) } else { Err(from_glib_full(error)) } + } + } + + pub fn get_handle(&self) -> u32 { + unsafe { + ffi::gst_glsl_stage_get_handle(self.to_glib_none().0) + } + } + + pub fn get_profile(&self) -> GLSLProfile { + unsafe { + from_glib(ffi::gst_glsl_stage_get_profile(self.to_glib_none().0)) + } + } + + pub fn get_shader_type(&self) -> u32 { + unsafe { + ffi::gst_glsl_stage_get_shader_type(self.to_glib_none().0) + } + } + + pub fn get_version(&self) -> GLSLVersion { + unsafe { + from_glib(ffi::gst_glsl_stage_get_version(self.to_glib_none().0)) + } + } + + pub fn set_strings(&self, version: GLSLVersion, profile: GLSLProfile, str: &[&str]) -> bool { + let n_strings = str.len() as i32; + unsafe { + from_glib(ffi::gst_glsl_stage_set_strings(self.to_glib_none().0, version.to_glib(), profile.to_glib(), n_strings, str.to_glib_none().0)) + } + } +} + +unsafe impl Send for GLSLStage {} +unsafe impl Sync for GLSLStage {} diff --git a/gstreamer-gl/src/auto/mod.rs b/gstreamer-gl/src/auto/mod.rs new file mode 100644 index 000000000..214b60853 --- /dev/null +++ b/gstreamer-gl/src/auto/mod.rs @@ -0,0 +1,72 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +mod gl_base_filter; +pub use self::gl_base_filter::GLBaseFilter; +pub use self::gl_base_filter::GLBaseFilterExt; + +mod gl_color_convert; +pub use self::gl_color_convert::GLColorConvert; + +mod gl_context; +pub use self::gl_context::GLContext; +pub use self::gl_context::GLContextExt; + +mod gl_display; +pub use self::gl_display::GLDisplay; +pub use self::gl_display::GLDisplayExt; + +#[cfg(any(feature = "egl", feature = "dox"))] +mod gl_display_egl; +#[cfg(any(feature = "egl", feature = "dox"))] +pub use self::gl_display_egl::GLDisplayEGL; + +mod gl_framebuffer; +pub use self::gl_framebuffer::GLFramebuffer; +pub use self::gl_framebuffer::GLFramebufferExt; + +mod gl_overlay_compositor; +pub use self::gl_overlay_compositor::GLOverlayCompositor; + +mod glsl_stage; +pub use self::glsl_stage::GLSLStage; + +mod gl_shader; +pub use self::gl_shader::GLShader; + +mod gl_upload; +pub use self::gl_upload::GLUpload; + +mod gl_view_convert; +pub use self::gl_view_convert::GLViewConvert; + +mod gl_window; +pub use self::gl_window::GLWindow; +pub use self::gl_window::GLWindowExt; + +mod enums; +pub use self::enums::GLContextError; +pub use self::enums::GLFormat; +pub use self::enums::GLQueryType; +pub use self::enums::GLSLError; +pub use self::enums::GLSLVersion; +pub use self::enums::GLStereoDownmix; +pub use self::enums::GLTextureTarget; +pub use self::enums::GLUploadReturn; +pub use self::enums::GLWindowError; + +mod flags; +pub use self::flags::GLAPI; +pub use self::flags::GLDisplayType; +pub use self::flags::GLPlatform; +pub use self::flags::GLSLProfile; + +#[doc(hidden)] +pub mod traits { + pub use super::GLBaseFilterExt; + pub use super::GLContextExt; + pub use super::GLDisplayExt; + pub use super::GLFramebufferExt; + pub use super::GLWindowExt; +} diff --git a/gstreamer-gl/src/auto/versions.txt b/gstreamer-gl/src/auto/versions.txt new file mode 100644 index 000000000..247fa04ef --- /dev/null +++ b/gstreamer-gl/src/auto/versions.txt @@ -0,0 +1,2 @@ +Generated by gir (https://github.com/gtk-rs/gir @ b5ea065) +from gir-files (https://github.com/gtk-rs/gir-files @ ???) diff --git a/gstreamer-gl/src/caps_features.rs b/gstreamer-gl/src/caps_features.rs new file mode 100644 index 000000000..1c2d5c8bd --- /dev/null +++ b/gstreamer-gl/src/caps_features.rs @@ -0,0 +1,21 @@ +// Copyright (C) 2018 Víctor Jáquez +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use gst::CapsFeatures; +use std::ffi::CStr; + +lazy_static! { + pub static ref CAPS_FEATURE_MEMORY_GL_MEMORY: &'static str = unsafe { + CStr::from_ptr(ffi::GST_CAPS_FEATURE_MEMORY_GL_MEMORY) + .to_str() + .unwrap() + }; + pub static ref CAPS_FEATURES_MEMORY_GL_MEMORY: CapsFeatures = + CapsFeatures::new(&[*CAPS_FEATURE_MEMORY_GL_MEMORY]); +} diff --git a/gstreamer-gl/src/context.rs b/gstreamer-gl/src/context.rs new file mode 100644 index 000000000..fbde54493 --- /dev/null +++ b/gstreamer-gl/src/context.rs @@ -0,0 +1,41 @@ +// Copyright (C) 2018 Víctor Jáquez +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use glib::translate::*; +use glib::IsA; +use gst::{ContextRef, MiniObject}; +use std::ptr; +use GLDisplay; + +pub trait ContextGLExt { + fn get_gl_display(&self) -> Option; + fn set_gl_display>(&self, display: &T); +} + +impl ContextGLExt for ContextRef { + fn get_gl_display(&self) -> Option { + unsafe { + let mut display = ptr::null_mut(); + if from_glib(ffi::gst_context_get_gl_display( + self.as_mut_ptr(), + &mut display, + )) { + Some(from_glib_full(display)) + } else { + None + } + } + } + + fn set_gl_display>(&self, display: &T) { + unsafe { + ffi::gst_context_set_gl_display(self.as_mut_ptr(), display.to_glib_none().0); + } + } +} diff --git a/gstreamer-gl/src/gl_context.rs b/gstreamer-gl/src/gl_context.rs new file mode 100644 index 000000000..d35cf0478 --- /dev/null +++ b/gstreamer-gl/src/gl_context.rs @@ -0,0 +1,77 @@ +// Copyright (C) 2018 Víctor Jáquez +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use glib::translate::*; +use glib::IsA; +use libc::uintptr_t; +use GLContext; +use GLDisplay; +use GLPlatform; +use GLAPI; + +impl GLContext { + pub unsafe fn new_wrapped>( + display: &T, + handle: uintptr_t, + context_type: GLPlatform, + available_apis: GLAPI, + ) -> Option { + from_glib_full(ffi::gst_gl_context_new_wrapped( + display.to_glib_none().0, + handle, + context_type.to_glib(), + available_apis.to_glib(), + )) + } +} + +pub trait GLContextExtManual { + fn get_gl_context(&self) -> uintptr_t; + + fn get_proc_address(&self, name: &str) -> uintptr_t; + + fn get_current_gl_context(context_type: GLPlatform) -> uintptr_t; + + fn get_proc_address_with_platform( + context_type: GLPlatform, + gl_api: GLAPI, + name: &str, + ) -> uintptr_t; +} + +impl> GLContextExtManual for O { + fn get_gl_context(&self) -> uintptr_t { + unsafe { ffi::gst_gl_context_get_gl_context(self.to_glib_none().0) as uintptr_t } + } + + fn get_proc_address(&self, name: &str) -> uintptr_t { + unsafe { + ffi::gst_gl_context_get_proc_address(self.to_glib_none().0, name.to_glib_none().0) + as uintptr_t + } + } + + fn get_current_gl_context(context_type: GLPlatform) -> uintptr_t { + unsafe { ffi::gst_gl_context_get_current_gl_context(context_type.to_glib()) as uintptr_t } + } + + fn get_proc_address_with_platform( + context_type: GLPlatform, + gl_api: GLAPI, + name: &str, + ) -> uintptr_t { + unsafe { + ffi::gst_gl_context_get_proc_address_with_platform( + context_type.to_glib(), + gl_api.to_glib(), + name.to_glib_none().0, + ) as uintptr_t + } + } +} diff --git a/gstreamer-gl/src/gl_display.rs b/gstreamer-gl/src/gl_display.rs new file mode 100644 index 000000000..7dcbd2365 --- /dev/null +++ b/gstreamer-gl/src/gl_display.rs @@ -0,0 +1,18 @@ +// Copyright (C) 2018 Víctor Jáquez +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use std::ffi::CStr; + +lazy_static! { + pub static ref GL_DISPLAY_CONTEXT_TYPE: &'static str = unsafe { + CStr::from_ptr(ffi::GST_GL_DISPLAY_CONTEXT_TYPE) + .to_str() + .unwrap() + }; +} diff --git a/gstreamer-gl/src/gl_display_egl.rs b/gstreamer-gl/src/gl_display_egl.rs new file mode 100644 index 000000000..1b2908746 --- /dev/null +++ b/gstreamer-gl/src/gl_display_egl.rs @@ -0,0 +1,26 @@ +// Copyright (C) 2018 Víctor Jáquez +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use glib::translate::*; +use glib_ffi::gpointer; +use libc::uintptr_t; +use GLDisplayEGL; +use GLDisplayType; + +impl GLDisplayEGL { + pub unsafe fn new_with_egl_display(display: uintptr_t) -> Option { + from_glib_full(ffi::gst_gl_display_egl_new_with_egl_display( + display as gpointer, + )) + } + + pub unsafe fn get_from_native(display_type: GLDisplayType, display: uintptr_t) -> gpointer { + ffi::gst_gl_display_egl_get_from_native(display_type.to_glib(), display) + } +} diff --git a/gstreamer-gl/src/gl_video_frame.rs b/gstreamer-gl/src/gl_video_frame.rs new file mode 100644 index 000000000..680f6c12e --- /dev/null +++ b/gstreamer-gl/src/gl_video_frame.rs @@ -0,0 +1,101 @@ +// Copyright (C) 2018 Víctor Jáquez +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use glib_ffi; +use gst_ffi; +use gst_video_ffi; + +use glib::translate::{from_glib, ToGlibPtr}; +use gst; +use gst::MiniObject; +use gst_video::video_frame::Readable; +use gst_video::*; + +use byteorder::{NativeEndian, ReadBytesExt}; +use std::mem; + +pub trait VideoFrameGLExt { + fn from_buffer_readable_gl( + buffer: gst::Buffer, + info: &VideoInfo, + ) -> Result, gst::Buffer>; + + fn get_texture_id(&self, idx: u32) -> Option; +} + +impl VideoFrameGLExt for VideoFrame { + fn from_buffer_readable_gl( + buffer: gst::Buffer, + info: &VideoInfo, + ) -> Result, gst::Buffer> { + skip_assert_initialized!(); + + let n_mem = match buffer_n_gl_memory(buffer.as_ref()) { + Some(n) => n, + None => return Err(buffer), + }; + + // FIXME: planes are not memories, in multiview use case, + // number of memories = planes * views, but the raw memory is + // not exposed in videoframe + if n_mem != info.n_planes() { + return Err(buffer); + } + + unsafe { + let mut frame = mem::zeroed(); + let res: bool = from_glib(gst_video_ffi::gst_video_frame_map( + &mut frame, + info.to_glib_none().0 as *mut _, + buffer.to_glib_none().0, + gst_video_ffi::GST_VIDEO_FRAME_MAP_FLAG_NO_REF + | gst_ffi::GST_MAP_READ + | ffi::GST_MAP_GL as u32, + )); + + if !res { + Err(buffer) + } else { + Ok(VideoFrame::from_glib_full(frame)) + } + } + } + + fn get_texture_id(&self, idx: u32) -> Option { + let len = buffer_n_gl_memory(self.buffer())?; + + if idx >= len { + return None; + } + + // FIXME: planes are not memories + if idx > self.n_planes() { + return None; + } + + let mut data = self.plane_data(idx)?; + let id = &data.read_u32::().ok()?; + + Some(*id) + } +} + +fn buffer_n_gl_memory(buffer: &gst::BufferRef) -> Option { + unsafe { + let buf = buffer.as_mut_ptr(); + let num = gst_ffi::gst_buffer_n_memory(buf); + for i in 0..num - 1 { + let mem = gst_ffi::gst_buffer_peek_memory(buf, i); + if ffi::gst_is_gl_memory(mem) != glib_ffi::GTRUE { + return None; + } + } + Some(num as u32) + } +} diff --git a/gstreamer-gl/src/lib.rs b/gstreamer-gl/src/lib.rs new file mode 100644 index 000000000..f4dab7f3b --- /dev/null +++ b/gstreamer-gl/src/lib.rs @@ -0,0 +1,72 @@ +// Copyright (C) 2018 Sebastian Dröge +// 2018 Víctor M. Jáquez L. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate bitflags; +extern crate byteorder; +#[macro_use] +extern crate lazy_static; +extern crate libc; +#[macro_use] +extern crate glib; +extern crate glib_sys as glib_ffi; +extern crate gobject_sys as gobject_ffi; +extern crate gstreamer as gst; +extern crate gstreamer_base as gst_base; +extern crate gstreamer_gl_sys as ffi; +extern crate gstreamer_sys as gst_ffi; +extern crate gstreamer_video as gst_video; +extern crate gstreamer_video_sys as gst_video_ffi; + +macro_rules! assert_initialized_main_thread { + () => { + if unsafe { ::gst_ffi::gst_is_initialized() } != ::glib_ffi::GTRUE { + panic!("GStreamer has not been initialized. Call `gst::init` first."); + } + }; +} + +macro_rules! skip_assert_initialized { + () => {}; +} + +pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue, Value}; + +#[cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))] +#[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))] +#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] +#[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))] +mod auto; +pub use auto::*; + +mod caps_features; +pub use caps_features::{CAPS_FEATURES_MEMORY_GL_MEMORY, CAPS_FEATURE_MEMORY_GL_MEMORY}; +mod context; +pub use context::ContextGLExt; +mod gl_context; +pub use gl_context::GLContextExtManual; +mod gl_display; +pub use gl_display::GL_DISPLAY_CONTEXT_TYPE; +#[cfg(any(feature = "egl", feature = "dox"))] +mod gl_display_egl; +mod gl_video_frame; +pub use gl_video_frame::VideoFrameGLExt; + +// Re-export all the traits in a prelude module, so that applications +// can always "use gst::prelude::*" without getting conflicts +pub mod prelude { + pub use glib::prelude::*; + pub use gst::prelude::*; + + pub use auto::traits::*; + + pub use context::ContextGLExt; + pub use gl_context::GLContextExtManual; + pub use gl_video_frame::VideoFrameGLExt; +}