├── .gitignore ├── LICENSE ├── README.md ├── bin.go ├── bin.md ├── buffer.go ├── buffer.md ├── buffer_list.go ├── buffer_list.md ├── bus.go ├── bus.md ├── caps.go ├── caps.md ├── clock.go ├── clock.md ├── common.go ├── context.go ├── context.md ├── control_binding.go ├── control_binding.md ├── discoverer.go ├── discoverer.md ├── element.go ├── element.md ├── element_factory.go ├── element_factory.md ├── element_metadata.go ├── element_metadata.md ├── event.go ├── event.md ├── examples ├── dynamic_pads.go ├── images │ ├── logo-153x55.png │ └── logo.png ├── live_webm.go ├── player.go └── simple.go ├── format.go ├── format.md ├── gerror.go ├── gerror.md ├── gst.go ├── gst.go.h ├── gst.md ├── info.go ├── info.md ├── iterator.go ├── iterator.md ├── message.go ├── message.md ├── object.go ├── object.md ├── pad.go ├── pad.md ├── pad_template.go ├── pad_template.md ├── pipeline.go ├── pipeline.md ├── query.go ├── query.md ├── segment.go ├── segment.md ├── structure.go ├── structure.md ├── taglist.go ├── taglist.md ├── toc.go ├── toc.md ├── type.go ├── value.go ├── value.md ├── videooverlay.go └── videooverlay.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | 26 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, Michal Derkacz 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. The name of the author may not be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gst 2 | based on ziutek's [Go bindings for GStreamer](https://github.com/ziutek/gst) and make some fixes 3 | 4 | ### Go bindings for GStreamer at a very early stage of maturity. 5 | 6 | This package is based on [GLib bindings](https://github.com/lidouf/glib). It 7 | should be goinstalable. Try 8 | 9 | $ go get github.com/lidouf/gst 10 | 11 | #### Documentation 12 | 13 | See *examples* directory and http://gopkgdoc.appspot.com/pkg/github.com/ziutek/gst 14 | 15 | To run examples use `go run` command: 16 | 17 | $ cd examples 18 | $ go run simple.go 19 | 20 | To run live WebM example use `go run live_webm.go` and open 21 | http://127.0.0.1:8080 with your browser. You probably need to wait a long time 22 | for video because of small bitrate of this stream and big buffer in you browser. 23 | 24 | ### PROGRESS 25 | #### GStreamer 26 | Gst 11/12 27 | GstBin 21/21 28 | GstBuffer 0/71 29 | GstBufferList 0/15 30 | GstBus 16/24 31 | GstCaps 14/65 32 | GstClock 1/49 33 | GstContext 0/12 34 | GstControlBinding 3/6 35 | GstElement 82/90 36 | GstElementFactory 7/19 37 | GstEvent 66/69 38 | GstFormat 0/7 39 | GstGError 1/1 40 | GstInfo 0/86 41 | GstIterator 0/23 42 | GstMessage 9/88 43 | GstObject 29/41 44 | GstPad 120/180 45 | GstPadTemplate 10/10 46 | GstPipeline 13/13 47 | GstQuery 3/96 48 | GstSegment 0/19 49 | GstStructure 3/69 50 | GstTagList 2/66 51 | GstToc 0/36 52 | GstValue 11/89 53 | #### gst-plugins-base-libs 54 | GstDiscoverer 20/54 55 | GstVideoOverlay 1/7 -------------------------------------------------------------------------------- /bin.go: -------------------------------------------------------------------------------- 1 | //GstBin — Base class and element that can contain other elements 2 | package gst 3 | 4 | /* 5 | #include 6 | #include 7 | */ 8 | import "C" 9 | 10 | import ( 11 | "github.com/lidouf/glib" 12 | "unsafe" 13 | ) 14 | 15 | type BinFlags C.GstBinFlags 16 | 17 | const ( 18 | BIN_FLAG_NO_RESYNC = BinFlags(C.GST_BIN_FLAG_NO_RESYNC) 19 | /* padding */ 20 | BIN_FLAG_LAST = BinFlags(C.GST_BIN_FLAG_LAST) 21 | ) 22 | 23 | type Bin struct { 24 | Element 25 | } 26 | 27 | func (b *Bin) g() *C.GstBin { 28 | return (*C.GstBin)(b.GetPtr()) 29 | } 30 | 31 | func (b *Bin) AsBin() *Bin { 32 | return b 33 | } 34 | 35 | //Creates a new bin with the given name. 36 | //Parameters 37 | //name 38 | //the name of the new bin. 39 | //Returns 40 | //a new GstBin. 41 | func NewBin(name string) *Bin { 42 | s := (*C.gchar)(C.CString(name)) 43 | defer C.free(unsafe.Pointer(s)) 44 | b := new(Bin) 45 | b.SetPtr(glib.Pointer(C.gst_bin_new(s))) 46 | return b 47 | } 48 | 49 | //Adds the given element to the bin. Sets the element's parent, and thus takes ownership of the element. An element can only be added to one bin. 50 | // 51 | //If the element's pads are linked to other pads, the pads will be unlinked before the element is added to the bin. 52 | //When you add an element to an already-running pipeline, you will have to take care to set the state of the newly-added element to the desired state 53 | //(usually PLAYING or PAUSED, same you set the pipeline to originally) with gst_element_set_state(), or use gst_element_sync_state_with_parent(). 54 | //The bin or pipeline will not take care of this for you. 55 | // 56 | //MT safe. 57 | //Parameters 58 | //bin 59 | //a GstBin 60 | //element 61 | //the GstElement to add. 62 | //Returns 63 | //TRUE if the element could be added, FALSE if the bin does not want to accept the element. 64 | func (b *Bin) Add(els ...*Element) bool { 65 | for _, e := range els { 66 | if C.gst_bin_add(b.g(), e.g()) == 0 { 67 | return false 68 | } 69 | } 70 | return true 71 | } 72 | 73 | //Removes the element from the bin, unparenting it as well. 74 | //Unparenting the element means that the element will be dereferenced, so if the bin holds the only reference to the element, 75 | //the element will be freed in the process of removing it from the bin. 76 | //If you want the element to still exist after removing, you need to call gst_object_ref() before removing it from the bin. 77 | // 78 | //If the element's pads are linked to other pads, the pads will be unlinked before the element is removed from the bin. 79 | // 80 | //MT safe. 81 | //Parameters 82 | //bin 83 | //a GstBin 84 | //element 85 | //the GstElement to remove. 86 | //Returns 87 | //TRUE if the element could be removed, FALSE if the bin does not want to remove the element. 88 | func (b *Bin) Remove(els ...*Element) bool { 89 | for _, e := range els { 90 | if C.gst_bin_remove(b.g(), e.g()) == 0 { 91 | return false 92 | } 93 | } 94 | return true 95 | } 96 | 97 | //GetByName returns the element with the given name from a bin. Returns nil 98 | //if no element with the given name is found in the bin. 99 | //MT safe. Caller owns returned reference. 100 | //Parameters 101 | //bin 102 | //a GstBin 103 | //name 104 | //the element name to search for 105 | //Returns 106 | //the GstElement with the given name, or NULL. 107 | func (b *Bin) GetByName(name string) *Element { 108 | en := (*C.gchar)(C.CString(name)) 109 | defer C.free(unsafe.Pointer(en)) 110 | p := glib.Pointer(C.gst_bin_get_by_name(b.g(), en)) 111 | if p == nil { 112 | return nil 113 | } 114 | e := new(Element) 115 | e.SetPtr(p) 116 | return e 117 | } 118 | 119 | //Gets the element with the given name from this bin. If the element is not found, a recursion is performed on the parent bin. 120 | // 121 | //Returns NULL if: 122 | // 123 | //no element with the given name is found in the bin 124 | // 125 | //MT safe. Caller owns returned reference. 126 | //Parameters 127 | //bin 128 | //a GstBin 129 | //name 130 | //the element name to search for 131 | //Returns 132 | //the GstElement with the given name, or NULL. 133 | func (b *Bin) GetByNameRecurseUp(name string) *Element { 134 | en := (*C.gchar)(C.CString(name)) 135 | defer C.free(unsafe.Pointer(en)) 136 | p := glib.Pointer(C.gst_bin_get_by_name_recurse_up(b.g(), en)) 137 | if p == nil { 138 | return nil 139 | } 140 | e := new(Element) 141 | e.SetPtr(p) 142 | return e 143 | } 144 | 145 | //Looks for an element inside the bin that implements the given interface. 146 | //If such an element is found, it returns the element. You can cast this element to the given interface afterwards. 147 | //If you want all elements that implement the interface, use gst_bin_iterate_all_by_interface(). 148 | //This function recurses into child bins. 149 | // 150 | //MT safe. Caller owns returned reference. 151 | //Parameters 152 | //bin 153 | //a GstBin 154 | //iface 155 | //the GType of an interface 156 | //Returns 157 | //A GstElement inside the bin implementing the interface. 158 | func (b *Bin) GetByInterface(tp glib.Type) *Element { 159 | p := C.gst_bin_get_by_interface(b.g(), C.GType(tp)) 160 | if p == nil { 161 | return nil 162 | } 163 | e := new(Element) 164 | e.SetPtr(glib.Pointer(p)) 165 | return e 166 | } 167 | 168 | //Gets an iterator for the elements in this bin. 169 | // 170 | //MT safe. Caller owns returned value. 171 | //Parameters 172 | //bin 173 | //a GstBin 174 | //Returns 175 | //a GstIterator of GstElement, or NULL. 176 | func (b *Bin) IterateElements() *Iterator { 177 | p := C.gst_bin_iterate_elements(b.g()) 178 | if p == nil { 179 | return nil 180 | } 181 | return (*Iterator)(unsafe.Pointer(p)) 182 | } 183 | 184 | //Gets an iterator for the elements in this bin. This iterator recurses into GstBin children. 185 | // 186 | //MT safe. Caller owns returned value. 187 | //Parameters 188 | //bin 189 | //a GstBin 190 | //Returns 191 | //a GstIterator of GstElement, or NULL. 192 | func (b *Bin) IterateRecurse() *Iterator { 193 | p := C.gst_bin_iterate_recurse(b.g()) 194 | if p == nil { 195 | return nil 196 | } 197 | return (*Iterator)(unsafe.Pointer(p)) 198 | } 199 | 200 | //Gets an iterator for all elements in the bin that have the GST_ELEMENT_FLAG_SINK flag set. 201 | // 202 | //MT safe. Caller owns returned value. 203 | //Parameters 204 | //bin 205 | //a GstBin 206 | //Returns 207 | //a GstIterator of GstElement, or NULL. 208 | func (b *Bin) IterateSinks() *Iterator { 209 | p := C.gst_bin_iterate_sinks(b.g()) 210 | if p == nil { 211 | return nil 212 | } 213 | return (*Iterator)(unsafe.Pointer(p)) 214 | } 215 | 216 | //Gets an iterator for the elements in this bin in topologically sorted order. 217 | //This means that the elements are returned from the most downstream elements (sinks) to the sources. 218 | // 219 | //This function is used internally to perform the state changes of the bin elements and for clock selection. 220 | // 221 | //MT safe. Caller owns returned value. 222 | //Parameters 223 | //bin 224 | //a GstBin 225 | //Returns 226 | //a GstIterator of GstElement, or NULL. 227 | func (b *Bin) IterateSorted() *Iterator { 228 | p := C.gst_bin_iterate_sorted(b.g()) 229 | if p == nil { 230 | return nil 231 | } 232 | return (*Iterator)(unsafe.Pointer(p)) 233 | } 234 | 235 | //Gets an iterator for all elements in the bin that have the GST_ELEMENT_FLAG_SOURCE flag set. 236 | // 237 | //MT safe. Caller owns returned value. 238 | //Parameters 239 | //bin 240 | //a GstBin 241 | //Returns 242 | //a GstIterator of GstElement, or NULL. 243 | func (b *Bin) IterateSources() *Iterator { 244 | p := C.gst_bin_iterate_sources(b.g()) 245 | if p == nil { 246 | return nil 247 | } 248 | return (*Iterator)(unsafe.Pointer(p)) 249 | } 250 | 251 | //Looks for all elements inside the bin that implements the given interface. You can safely cast all returned elements to the given interface. 252 | //The function recurses inside child bins. The iterator will yield a series of GstElement that should be unreffed after use. 253 | // 254 | //MT safe. Caller owns returned value. 255 | //Parameters 256 | //bin 257 | //a GstBin 258 | //iface 259 | //the GType of an interface 260 | //Returns 261 | //a GstIterator of GstElement for all elements in the bin implementing the given interface, or NULL. 262 | func (b *Bin) IterateAllByInterface(tp glib.Type) *Iterator { 263 | p := C.gst_bin_iterate_all_by_interface(b.g(), C.GType(tp)) 264 | if p == nil { 265 | return nil 266 | } 267 | return (*Iterator)(unsafe.Pointer(p)) 268 | } 269 | 270 | //Query bin for the current latency using and reconfigures this latency to all the elements with a LATENCY event. 271 | // 272 | //This method is typically called on the pipeline when a GST_MESSAGE_LATENCY is posted on the bus. 273 | // 274 | //This function simply emits the 'do-latency' signal so any custom latency calculations will be performed. 275 | //Parameters 276 | //bin 277 | //a GstBin 278 | //Returns 279 | //TRUE if the latency could be queried and reconfigured. 280 | func (b *Bin) RecalculateLatency() bool { 281 | return C.gst_bin_recalculate_latency(b.g()) != 0 282 | } 283 | 284 | //Recursively looks for elements with an unlinked pad of the given direction within the specified bin and returns an unlinked pad if one is found, or NULL otherwise. If a pad is found, the caller owns a reference to it and should use gst_object_unref() on the pad when it is not needed any longer. 285 | //Parameters 286 | //bin 287 | //bin in which to look for elements with unlinked pads 288 | //direction 289 | //whether to look for an unlinked source or sink pad 290 | //Returns 291 | //unlinked pad of the given direction, NULL. 292 | func (b *Bin) FindUnlinkedPad(direction PadDirection) *Pad { 293 | p := C.gst_bin_find_unlinked_pad(b.g(), direction.g()) 294 | if p == nil { 295 | return nil 296 | } 297 | r := new(Pad) 298 | r.SetPtr(glib.Pointer(p)) 299 | return r 300 | } 301 | 302 | //Synchronizes the state of every child of bin with the state of bin . See also gst_element_sync_state_with_parent(). 303 | //Parameters 304 | //bin 305 | //a GstBin 306 | //Returns 307 | //TRUE if syncing the state was successful for all children, otherwise FALSE. 308 | //Since: 1.6 309 | func (b *Bin) SyncChildrenStates() bool { 310 | return C.gst_bin_sync_children_states(b.g()) != 0 311 | } 312 | 313 | //#define GST_BIN_IS_NO_RESYNC(bin) (GST_OBJECT_FLAG_IS_SET(bin,GST_BIN_FLAG_NO_RESYNC)) 314 | //Check if bin will resync its state change when elements are added and removed. 315 | //Parameters 316 | //bin 317 | //A GstBin 318 | //Since: 1.0.5 319 | func (b *Bin) IsNoResync() bool { 320 | return b.FlagIsSet(uint32(BIN_FLAG_NO_RESYNC)) 321 | } 322 | 323 | //#define GST_BIN_CHILDREN(bin) (GST_BIN_CAST(bin)->children) 324 | //Gets the list with children in a bin. 325 | //Parameters 326 | //bin 327 | //a GstBin 328 | func (b *Bin) Children() *glib.List { 329 | return glib.WrapList(uintptr(unsafe.Pointer(b.g().children))) 330 | } 331 | 332 | //#define GST_BIN_CHILDREN_COOKIE(bin) (GST_BIN_CAST(bin)->children_cookie) 333 | //Gets the children cookie that watches the children list. 334 | //Parameters 335 | //bin 336 | //a GstBin 337 | func (b *Bin) ChildrenCookie() uint32 { 338 | return uint32(b.g().children_cookie) 339 | } 340 | 341 | //#define GST_BIN_NUMCHILDREN(bin) (GST_BIN_CAST(bin)->numchildren) 342 | //Gets the number of children in a bin. 343 | //Parameters 344 | //bin 345 | //a GstBin 346 | func (b *Bin) NumChildren() int { 347 | return int(b.g().numchildren) 348 | } 349 | 350 | func (b *Bin) DebugToDotData(details DebugGraphDetails) string { 351 | return (C.GoString)((*C.char)(C.gst_debug_bin_to_dot_data(b.g(), (C.GstDebugGraphDetails)(details)))) 352 | } 353 | 354 | func (b *Bin) DebugToDotFile(filename string, details DebugGraphDetails) { 355 | s := (*C.gchar)(C.CString(filename)) 356 | defer C.free(unsafe.Pointer(s)) 357 | C.gst_debug_bin_to_dot_file(b.g(), (C.GstDebugGraphDetails)(details), s) 358 | } 359 | 360 | func (b *Bin) DebugToDotFileWithTs(filename string, details DebugGraphDetails) { 361 | s := (*C.gchar)(C.CString(filename)) 362 | defer C.free(unsafe.Pointer(s)) 363 | C.gst_debug_bin_to_dot_file_with_ts(b.g(), (C.GstDebugGraphDetails)(details), s) 364 | } 365 | -------------------------------------------------------------------------------- /bin.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 21/21 3 | ``` 4 | Y GstElement * gst_bin_new () 5 | Y gboolean gst_bin_add () 6 | Y gboolean gst_bin_remove () 7 | Y GstElement * gst_bin_get_by_name () 8 | Y GstElement * gst_bin_get_by_name_recurse_up () 9 | Y GstElement * gst_bin_get_by_interface () 10 | Y GstIterator * gst_bin_iterate_elements () 11 | Y GstIterator * gst_bin_iterate_recurse () 12 | Y GstIterator * gst_bin_iterate_sinks () 13 | Y GstIterator * gst_bin_iterate_sorted () 14 | Y GstIterator * gst_bin_iterate_sources () 15 | Y GstIterator * gst_bin_iterate_all_by_interface () 16 | Y gboolean gst_bin_recalculate_latency () 17 | * void gst_bin_add_many () 18 | * void gst_bin_remove_many () 19 | Y GstPad * gst_bin_find_unlinked_pad () 20 | Y gboolean gst_bin_sync_children_states () 21 | Y #define GST_BIN_IS_NO_RESYNC() 22 | Y #define GST_BIN_CHILDREN() 23 | Y #define GST_BIN_CHILDREN_COOKIE() 24 | Y #define GST_BIN_NUMCHILDREN() 25 | ``` 26 | the item mark * that means can be replaced by other calls -------------------------------------------------------------------------------- /buffer.go: -------------------------------------------------------------------------------- 1 | //GstBuffer — Data-passing buffer type 2 | package gst 3 | 4 | /* 5 | #include 6 | #include 7 | */ 8 | import "C" 9 | 10 | import ( 11 | //"errors" 12 | "github.com/lidouf/glib" 13 | //"time" 14 | //"unsafe" 15 | ) 16 | 17 | type Buffer struct { 18 | glib.Object 19 | } 20 | 21 | func (b *Buffer) g() *C.GstBuffer { 22 | return (*C.GstBuffer)(b.GetPtr()) 23 | } 24 | 25 | func (b *Buffer) AsBuffer() *Buffer { 26 | return b 27 | } 28 | -------------------------------------------------------------------------------- /buffer.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 0/71 3 | ``` 4 | #define GST_BUFFER_FLAGS() 5 | #define GST_BUFFER_FLAG_IS_SET() 6 | #define GST_BUFFER_FLAG_SET() 7 | #define GST_BUFFER_FLAG_UNSET() 8 | #define GST_BUFFER_PTS() 9 | #define GST_BUFFER_DTS() 10 | #define GST_BUFFER_DTS_OR_PTS() 11 | #define GST_BUFFER_DURATION() 12 | #define GST_BUFFER_OFFSET() 13 | #define GST_BUFFER_OFFSET_END() 14 | #define GST_BUFFER_DURATION_IS_VALID() 15 | #define GST_BUFFER_PTS_IS_VALID() 16 | #define GST_BUFFER_DTS_IS_VALID() 17 | #define GST_BUFFER_OFFSET_IS_VALID() 18 | #define GST_BUFFER_OFFSET_END_IS_VALID() 19 | #define GST_BUFFER_IS_DISCONT() 20 | GstBuffer * gst_buffer_new () 21 | GstBuffer * gst_buffer_new_allocate () 22 | GstBuffer * gst_buffer_new_wrapped () 23 | GstBuffer * gst_buffer_new_wrapped_full () 24 | GstBuffer * gst_buffer_ref () 25 | void gst_buffer_unref () 26 | gsize gst_buffer_get_sizes () 27 | gsize gst_buffer_get_size () 28 | gsize gst_buffer_get_sizes_range () 29 | gboolean gst_buffer_resize_range () 30 | void gst_buffer_resize () 31 | void gst_buffer_set_size () 32 | guint gst_buffer_get_max_memory () 33 | GstMemory * gst_buffer_peek_memory () 34 | guint gst_buffer_n_memory () 35 | void gst_buffer_insert_memory () 36 | void gst_buffer_replace_memory_range () 37 | GstMemory * gst_buffer_get_memory_range () 38 | void gst_buffer_remove_memory_range () 39 | gboolean gst_buffer_find_memory () 40 | void gst_buffer_prepend_memory () 41 | void gst_buffer_append_memory () 42 | void gst_buffer_replace_memory () 43 | void gst_buffer_replace_all_memory () 44 | GstMemory * gst_buffer_get_memory () 45 | GstMemory * gst_buffer_get_all_memory () 46 | void gst_buffer_remove_memory () 47 | void gst_buffer_remove_all_memory () 48 | gboolean gst_buffer_is_all_memory_writable () 49 | gboolean gst_buffer_is_memory_range_writable () 50 | gboolean gst_buffer_map () 51 | gboolean gst_buffer_map_range () 52 | void gst_buffer_unmap () 53 | gint gst_buffer_memcmp () 54 | gsize gst_buffer_extract () 55 | void gst_buffer_extract_dup () 56 | gsize gst_buffer_fill () 57 | gsize gst_buffer_memset () 58 | GstBuffer * gst_buffer_copy () 59 | gboolean gst_buffer_copy_into () 60 | GstBuffer * gst_buffer_copy_region () 61 | GstBuffer * gst_buffer_copy_deep () 62 | #define gst_buffer_is_writable() 63 | #define gst_buffer_make_writable() 64 | gboolean gst_buffer_replace () 65 | GstBuffer * gst_buffer_append () 66 | GstBuffer * gst_buffer_append_region () 67 | GstMeta * gst_buffer_get_meta () 68 | GstMeta * gst_buffer_add_meta () 69 | gboolean gst_buffer_remove_meta () 70 | GstMeta * gst_buffer_iterate_meta () 71 | gboolean (*GstBufferForeachMetaFunc) () 72 | gboolean gst_buffer_foreach_meta () 73 | GstParentBufferMeta * gst_buffer_add_parent_buffer_meta () 74 | #define gst_buffer_get_parent_buffer_meta() 75 | ``` -------------------------------------------------------------------------------- /buffer_list.go: -------------------------------------------------------------------------------- 1 | //GstBufferList — Lists of buffers for data-passing 2 | package gst 3 | 4 | /* 5 | #include 6 | #include 7 | */ 8 | import "C" 9 | 10 | import ( 11 | //"errors" 12 | "github.com/lidouf/glib" 13 | //"time" 14 | //"unsafe" 15 | ) 16 | 17 | type BufferList struct { 18 | glib.Object 19 | } 20 | 21 | func (b *BufferList) g() *C.GstBufferList { 22 | return (*C.GstBufferList)(b.GetPtr()) 23 | } 24 | 25 | func (b *BufferList) AsBuffer() *BufferList { 26 | return b 27 | } 28 | -------------------------------------------------------------------------------- /buffer_list.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 0/15 3 | ``` 4 | GstBufferList * gst_buffer_list_new () 5 | GstBufferList * gst_buffer_list_new_sized () 6 | guint gst_buffer_list_length () 7 | #define gst_buffer_list_add() 8 | void gst_buffer_list_insert () 9 | void gst_buffer_list_remove () 10 | GstBufferList * gst_buffer_list_ref () 11 | void gst_buffer_list_unref () 12 | GstBufferList * gst_buffer_list_copy () 13 | GstBufferList * gst_buffer_list_copy_deep () 14 | #define gst_buffer_list_is_writable() 15 | #define gst_buffer_list_make_writable() 16 | gboolean (*GstBufferListFunc) () 17 | gboolean gst_buffer_list_foreach () 18 | GstBuffer * gst_buffer_list_get () 19 | ``` -------------------------------------------------------------------------------- /bus.go: -------------------------------------------------------------------------------- 1 | package gst 2 | 3 | /* 4 | #include 5 | #include 6 | */ 7 | import "C" 8 | 9 | import ( 10 | "github.com/lidouf/glib" 11 | ) 12 | 13 | type Bus struct { 14 | GstObj 15 | } 16 | 17 | func (b *Bus) g() *C.GstBus { 18 | return (*C.GstBus)(b.GetPtr()) 19 | } 20 | 21 | func (b *Bus) AsBus() *Bus { 22 | return b 23 | } 24 | 25 | func (b *Bus) Post(msg *Message) bool { 26 | return C.gst_bus_post(b.g(), msg.g()) != 0 27 | } 28 | 29 | func (b *Bus) HavePending() bool { 30 | return C.gst_bus_have_pending(b.g()) != 0 31 | } 32 | 33 | func (b *Bus) Peek() *Message { 34 | r := new(Message) 35 | r.SetPtr(glib.Pointer(C.gst_bus_peek(b.g()))) 36 | return r 37 | } 38 | 39 | func (b *Bus) Pop() *Message { 40 | r := new(Message) 41 | r.SetPtr(glib.Pointer(C.gst_bus_pop(b.g()))) 42 | return r 43 | } 44 | 45 | func (b *Bus) PopFiltered(types MessageType) *Message { 46 | r := new(Message) 47 | r.SetPtr(glib.Pointer(C.gst_bus_pop_filtered(b.g(), C.GstMessageType(types)))) 48 | return r 49 | } 50 | 51 | func (b *Bus) TimedPop(timeout uint64) *Message { 52 | r := new(Message) 53 | r.SetPtr(glib.Pointer(C.gst_bus_timed_pop(b.g(), C.GstClockTime(timeout)))) 54 | return r 55 | } 56 | 57 | func (b *Bus) TimedPopFiltered(timeout uint64, types MessageType) *Message { 58 | r := new(Message) 59 | r.SetPtr(glib.Pointer(C.gst_bus_timed_pop_filtered(b.g(), C.GstClockTime(timeout), C.GstMessageType(types)))) 60 | return r 61 | } 62 | 63 | func (b *Bus) SetFlushing(flushing bool) { 64 | var f C.gboolean 65 | if flushing { 66 | f = 1 67 | } 68 | C.gst_bus_set_flushing(b.g(), f) 69 | } 70 | 71 | func (b *Bus) DisableSyncMessageEmission() { 72 | C.gst_bus_disable_sync_message_emission(b.g()) 73 | } 74 | 75 | func (b *Bus) EnableSyncMessageEmission() { 76 | C.gst_bus_enable_sync_message_emission(b.g()) 77 | } 78 | 79 | func (b *Bus) AddSignalWatch() { 80 | C.gst_bus_add_signal_watch(b.g()) 81 | } 82 | 83 | func (b *Bus) AddSignalWatchFull(priority int) { 84 | C.gst_bus_add_signal_watch_full(b.g(), C.gint(priority)) 85 | } 86 | 87 | func (b *Bus) RemoveSignalWatch() { 88 | C.gst_bus_remove_signal_watch(b.g()) 89 | } 90 | 91 | func (b *Bus) Poll(events MessageType, timeout int64) *Message { 92 | r := new(Message) 93 | r.SetPtr(glib.Pointer(C.gst_bus_poll(b.g(), C.GstMessageType(events), C.GstClockTime(timeout)))) 94 | return r 95 | } 96 | 97 | func NewBus() *Bus { 98 | b := new(Bus) 99 | b.SetPtr(glib.Pointer(C.gst_bus_new())) 100 | return b 101 | } 102 | -------------------------------------------------------------------------------- /bus.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 16/24 3 | ``` 4 | gboolean (*GstBusFunc) () 5 | GstBusSyncReply (*GstBusSyncHandler) () 6 | Y GstBus * gst_bus_new () 7 | Y gboolean gst_bus_post () 8 | Y gboolean gst_bus_have_pending () 9 | Y GstMessage * gst_bus_peek () 10 | Y GstMessage * gst_bus_pop () 11 | Y GstMessage * gst_bus_pop_filtered () 12 | Y GstMessage * gst_bus_timed_pop () 13 | Y GstMessage * gst_bus_timed_pop_filtered () 14 | Y void gst_bus_set_flushing () 15 | void gst_bus_set_sync_handler () 16 | GstBusSyncReply gst_bus_sync_signal_handler () 17 | GSource * gst_bus_create_watch () 18 | guint gst_bus_add_watch_full () 19 | guint gst_bus_add_watch () 20 | gboolean gst_bus_remove_watch () 21 | Y void gst_bus_disable_sync_message_emission () 22 | Y void gst_bus_enable_sync_message_emission () 23 | gboolean gst_bus_async_signal_func () 24 | Y void gst_bus_add_signal_watch () 25 | Y void gst_bus_add_signal_watch_full () 26 | Y void gst_bus_remove_signal_watch () 27 | Y GstMessage * gst_bus_poll () 28 | ``` -------------------------------------------------------------------------------- /caps.go: -------------------------------------------------------------------------------- 1 | package gst 2 | 3 | /* 4 | #include 5 | #include 6 | #include 7 | 8 | int capsRefCount(GstCaps *c) { 9 | return GST_CAPS_REFCOUNT(c); 10 | } 11 | */ 12 | import "C" 13 | 14 | import ( 15 | "github.com/lidouf/glib" 16 | "unsafe" 17 | ) 18 | 19 | //type Caps C.GstCaps 20 | type Caps struct { 21 | glib.Object 22 | } 23 | 24 | func (c *Caps) Type() glib.Type { 25 | return glib.TypeFromName("GstCaps") 26 | } 27 | 28 | func (c *Caps) Value() *glib.Value { 29 | v := glib.NewValue(c.Type()) 30 | C.gst_value_set_caps(v2g(v), c.g()) 31 | return v 32 | } 33 | 34 | func (c *Caps) g() *C.GstCaps { 35 | return (*C.GstCaps)(c.GetPtr()) 36 | } 37 | 38 | func (c *Caps) Ref() *Caps { 39 | r := new(Caps) 40 | r.SetPtr(glib.Pointer(C.gst_caps_ref(c.g()))) 41 | return r 42 | } 43 | 44 | func (c *Caps) Unref() { 45 | C.gst_caps_unref(c.g()) 46 | } 47 | 48 | func (c *Caps) RefCount() int { 49 | return int(C.capsRefCount(c.g())) 50 | } 51 | 52 | func (c *Caps) AppendStructure(media_type string, fields glib.Params) { 53 | C.gst_caps_append_structure(c.g(), makeGstStructure(media_type, fields)) 54 | } 55 | 56 | func (c *Caps) GetSize() int { 57 | return int(C.gst_caps_get_size(c.g())) 58 | } 59 | 60 | func (c *Caps) GetStructure(index uint) *Structure { 61 | r := new(Structure) 62 | r.SetPtr(glib.Pointer(C.gst_caps_get_structure(c.g(), C.guint(index)))) 63 | return r 64 | } 65 | 66 | func (c *Caps) String() string { 67 | s := (*C.char)(C.gst_caps_to_string(c.g())) 68 | defer C.free(unsafe.Pointer(s)) 69 | return C.GoString(s) 70 | } 71 | 72 | func (c *Caps) IsAny() bool { 73 | return C.gst_caps_is_any(c.g()) != 0 74 | } 75 | 76 | func (c *Caps) IsEmpty() bool { 77 | return C.gst_caps_is_empty(c.g()) != 0 78 | } 79 | 80 | func (c *Caps) IsFixed() bool { 81 | return C.gst_caps_is_fixed(c.g()) != 0 82 | } 83 | 84 | func (c *Caps) GetCodecDescription() string { 85 | return C.GoString((*C.char)(C.gst_pb_utils_get_codec_description(c.g()))) 86 | } 87 | 88 | func NewCapsAny() *Caps { 89 | r := new(Caps) 90 | r.SetPtr(glib.Pointer(C.gst_caps_new_any())) 91 | return r 92 | } 93 | 94 | func NewCapsEmpty() *Caps { 95 | r := new(Caps) 96 | r.SetPtr(glib.Pointer(C.gst_caps_new_empty())) 97 | return r 98 | } 99 | 100 | func NewCapsSimple(media_type string, fields glib.Params) *Caps { 101 | c := NewCapsEmpty() 102 | c.AppendStructure(media_type, fields) 103 | return c 104 | } 105 | 106 | func CapsFromString(s string) *Caps { 107 | cs := (*C.gchar)(C.CString(s)) 108 | defer C.free(unsafe.Pointer(cs)) 109 | r := new(Caps) 110 | r.SetPtr(glib.Pointer(C.gst_caps_from_string(cs))) 111 | return r 112 | } 113 | 114 | //type StaticCaps C.GstStaticCaps 115 | type StaticCaps struct { 116 | glib.Object 117 | } 118 | 119 | func (c *StaticCaps) g() *C.GstStaticCaps { 120 | return (*C.GstStaticCaps)(c.GetPtr()) 121 | } 122 | 123 | func (c *StaticCaps) Caps() *Caps { 124 | if c.g().caps == nil { 125 | return nil 126 | } 127 | r := new(Caps) 128 | r.SetPtr(glib.Pointer(c.g().caps)) 129 | return r 130 | } 131 | 132 | func (c *StaticCaps) Get() *Caps { 133 | r := new(Caps) 134 | r.SetPtr(glib.Pointer(C.gst_static_caps_get(c.g()))) 135 | return r 136 | } 137 | 138 | func (c *StaticCaps) String() string { 139 | return C.GoString(c.g().string) 140 | } 141 | -------------------------------------------------------------------------------- /caps.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 14/65 3 | ``` 4 | Y #define GST_CAPS_REFCOUNT() 5 | #define GST_CAPS_REFCOUNT_VALUE() 6 | #define GST_CAPS_IS_SIMPLE() 7 | #define GST_STATIC_CAPS() 8 | #define GST_CAPS_FLAGS() 9 | #define GST_CAPS_FLAG_IS_SET() 10 | #define GST_CAPS_FLAG_SET() 11 | #define GST_CAPS_FLAG_UNSET() 12 | gboolean (*GstCapsForeachFunc) () 13 | gboolean (*GstCapsMapFunc) () 14 | gboolean (*GstCapsFilterMapFunc) () 15 | Y GstCaps * gst_caps_new_empty () 16 | GstCaps * gst_caps_new_empty_simple () 17 | Y GstCaps * gst_caps_new_any () 18 | * GstCaps * gst_caps_new_simple () 19 | GstCaps * gst_caps_new_full () 20 | GstCaps * gst_caps_new_full_valist () 21 | #define gst_caps_is_writable() 22 | GstCaps * gst_caps_copy () 23 | GstCaps * gst_caps_copy_nth () 24 | GstCaps * gst_static_caps_get () 25 | void gst_static_caps_cleanup () 26 | void gst_caps_append () 27 | GstCaps * gst_caps_merge () 28 | Y void gst_caps_append_structure () 29 | void gst_caps_append_structure_full () 30 | void gst_caps_remove_structure () 31 | GstStructure * gst_caps_steal_structure () 32 | GstCaps * gst_caps_merge_structure () 33 | GstCaps * gst_caps_merge_structure_full () 34 | Y guint gst_caps_get_size () 35 | Y GstStructure * gst_caps_get_structure () 36 | GstCapsFeatures * gst_caps_get_features () 37 | void gst_caps_set_features () 38 | void gst_caps_set_value () 39 | void gst_caps_set_simple () 40 | void gst_caps_set_simple_valist () 41 | gboolean gst_caps_foreach () 42 | gboolean gst_caps_map_in_place () 43 | void gst_caps_filter_and_map_in_place () 44 | Y gboolean gst_caps_is_any () 45 | Y gboolean gst_caps_is_empty () 46 | Y gboolean gst_caps_is_fixed () 47 | gboolean gst_caps_is_equal () 48 | gboolean gst_caps_is_equal_fixed () 49 | gboolean gst_caps_is_strictly_equal () 50 | gboolean gst_caps_is_always_compatible () 51 | gboolean gst_caps_is_subset () 52 | gboolean gst_caps_is_subset_structure () 53 | gboolean gst_caps_is_subset_structure_full () 54 | gboolean gst_caps_can_intersect () 55 | GstCaps * gst_caps_intersect () 56 | GstCaps * gst_caps_intersect_full () 57 | GstCaps * gst_caps_normalize () 58 | GstCaps * gst_caps_simplify () 59 | gboolean gst_caps_replace () 60 | gboolean gst_caps_take () 61 | Y gchar * gst_caps_to_string () 62 | Y GstCaps * gst_caps_from_string () 63 | GstCaps * gst_caps_subtract () 64 | #define gst_caps_make_writable() 65 | GstCaps * gst_caps_truncate () 66 | GstCaps * gst_caps_fixate () 67 | Y GstCaps * gst_caps_ref () 68 | Y void gst_caps_unref () 69 | ``` -------------------------------------------------------------------------------- /clock.go: -------------------------------------------------------------------------------- 1 | package gst 2 | 3 | /* 4 | #include 5 | static gboolean clock_time_is_valid(gint64 t) { 6 | return GST_CLOCK_TIME_IS_VALID(t); 7 | } 8 | static gchar* clock_duration_output(GstClockTime t) { 9 | return g_strdup_printf("%" GST_TIME_FORMAT, GST_TIME_ARGS(t)); 10 | } 11 | */ 12 | import "C" 13 | 14 | type Clock struct { 15 | GstObj 16 | } 17 | 18 | func (c *Clock) g() *C.GstClock { 19 | return (*C.GstClock)(c.GetPtr()) 20 | } 21 | 22 | func (c *Clock) AsClock() *Clock { 23 | return c 24 | } 25 | 26 | type ClockTime C.GstClockTime 27 | 28 | func (t *ClockTime) g() *C.GstClockTime { 29 | return (*C.GstClockTime)(t) 30 | } 31 | 32 | func (t ClockTime) AsUint64() uint64 { 33 | return uint64(t) 34 | } 35 | 36 | func (t ClockTime) DurationOutput() string { 37 | return C.GoString((*C.char)(C.clock_duration_output(C.GstClockTime(t)))) 38 | } 39 | 40 | func ClockTimeIsValid(t int64) bool { 41 | return C.clock_time_is_valid((C.gint64)(t)) == 1 42 | } 43 | -------------------------------------------------------------------------------- /clock.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 1/49 3 | ``` 4 | Y #define GST_CLOCK_TIME_IS_VALID() 5 | #define GST_CLOCK_STIME_IS_VALID() 6 | #define GST_TIME_AS_SECONDS() 7 | #define GST_TIME_AS_MSECONDS() 8 | #define GST_TIME_AS_USECONDS() 9 | #define GST_TIME_AS_NSECONDS() 10 | #define GST_CLOCK_DIFF() 11 | #define GST_TIMEVAL_TO_TIME() 12 | #define GST_TIME_TO_TIMEVAL() 13 | #define GST_TIMESPEC_TO_TIME() 14 | #define GST_TIME_TO_TIMESPEC() 15 | gboolean (*GstClockCallback) () 16 | #define GST_CLOCK_ENTRY() 17 | #define GST_CLOCK_ENTRY_CLOCK() 18 | #define GST_CLOCK_ENTRY_TYPE() 19 | #define GST_CLOCK_ENTRY_TIME() 20 | #define GST_CLOCK_ENTRY_INTERVAL() 21 | #define GST_CLOCK_ENTRY_STATUS() 22 | #define GST_CLOCK_FLAGS() 23 | gboolean gst_clock_add_observation () 24 | gboolean gst_clock_add_observation_unapplied () 25 | gboolean gst_clock_set_master () 26 | GstClock * gst_clock_get_master () 27 | GstClockTime gst_clock_set_resolution () 28 | GstClockTime gst_clock_get_resolution () 29 | GstClockTime gst_clock_get_time () 30 | GstClockID gst_clock_new_single_shot_id () 31 | GstClockID gst_clock_new_periodic_id () 32 | gboolean gst_clock_single_shot_id_reinit () 33 | gboolean gst_clock_periodic_id_reinit () 34 | GstClockTime gst_clock_get_internal_time () 35 | GstClockTime gst_clock_adjust_unlocked () 36 | GstClockTime gst_clock_unadjust_unlocked () 37 | GstClockTime gst_clock_adjust_with_calibration () 38 | GstClockTime gst_clock_unadjust_with_calibration () 39 | void gst_clock_get_calibration () 40 | void gst_clock_set_calibration () 41 | GstClockTime gst_clock_get_timeout () 42 | void gst_clock_set_timeout () 43 | gboolean gst_clock_wait_for_sync () 44 | gboolean gst_clock_is_synced () 45 | void gst_clock_set_synced () 46 | GstClockTime gst_clock_id_get_time () 47 | GstClockReturn gst_clock_id_wait () 48 | GstClockReturn gst_clock_id_wait_async () 49 | void gst_clock_id_unschedule () 50 | gint gst_clock_id_compare_func () 51 | GstClockID gst_clock_id_ref () 52 | void gst_clock_id_unref () 53 | ``` -------------------------------------------------------------------------------- /common.go: -------------------------------------------------------------------------------- 1 | // Bindings for GStreamer API 2 | package gst 3 | 4 | /* 5 | #include 6 | #include 7 | 8 | char** _gst_init(int* argc, char** argv) { 9 | gst_init(argc, &argv); 10 | return argv; 11 | } 12 | 13 | typedef struct { 14 | const char *name; 15 | const GValue *val; 16 | } Field; 17 | 18 | typedef struct { 19 | Field* tab; 20 | int n; 21 | } Fields; 22 | 23 | gboolean _parse_field(GQuark id, const GValue* val, gpointer data) { 24 | Fields *f = (Fields*)(data); 25 | f->tab[f->n].name = g_quark_to_string(id); 26 | f->tab[f->n].val = val; 27 | ++f->n; 28 | return TRUE; 29 | } 30 | 31 | Fields _parse_struct(GstStructure *s) { 32 | int n = gst_structure_n_fields(s); 33 | Fields f = { malloc(n * sizeof(Field)), 0 }; 34 | gst_structure_foreach(s, _parse_field, (gpointer)(&f)); 35 | return f; 36 | } 37 | 38 | #cgo pkg-config: gstreamer-1.0 39 | */ 40 | import "C" 41 | 42 | import ( 43 | "os" 44 | "unsafe" 45 | 46 | "github.com/lidouf/glib" 47 | ) 48 | 49 | var TYPE_FOURCC, TYPE_INT_RANGE, TYPE_FRACTION glib.Type 50 | 51 | func init() { 52 | alen := C.int(len(os.Args)) 53 | argv := make([]*C.char, alen) 54 | for i, s := range os.Args { 55 | argv[i] = C.CString(s) 56 | } 57 | ret := C._gst_init(&alen, &argv[0]) 58 | argv = (*[1 << 16]*C.char)(unsafe.Pointer(ret))[:alen] 59 | os.Args = make([]string, alen) 60 | for i, s := range argv { 61 | os.Args[i] = C.GoString(s) 62 | } 63 | 64 | TYPE_INT_RANGE = glib.Type(C.gst_int_range_get_type()) 65 | TYPE_FRACTION = glib.Type(C.gst_fraction_get_type()) 66 | } 67 | 68 | func makeGstStructure(name string, fields glib.Params) *C.GstStructure { 69 | nm := (*C.gchar)(C.CString(name)) 70 | s := C.gst_structure_new_empty(nm) 71 | C.free(unsafe.Pointer(nm)) 72 | for k, v := range fields { 73 | n := (*C.gchar)(C.CString(k)) 74 | C.gst_structure_take_value(s, n, v2g(glib.ValueOf(v))) 75 | C.free(unsafe.Pointer(n)) 76 | } 77 | return s 78 | } 79 | 80 | func parseGstStructure(s *C.GstStructure) (name string, fields glib.Params) { 81 | name = C.GoString((*C.char)(C.gst_structure_get_name(s))) 82 | ps := C._parse_struct(s) 83 | n := (int)(ps.n) 84 | tab := (*[1 << 16]C.Field)(unsafe.Pointer(ps.tab))[:n] 85 | fields = make(glib.Params) 86 | for _, f := range tab { 87 | fields[C.GoString(f.name)] = g2v(f.val).Get() 88 | } 89 | return 90 | } 91 | 92 | func serializeGstStructure(s *C.GstStructure) glib.Params { 93 | ps := C._parse_struct(s) 94 | n := (int)(ps.n) 95 | tab := (*[1 << 16]C.Field)(unsafe.Pointer(ps.tab))[:n] 96 | fields := make(glib.Params) 97 | for _, f := range tab { 98 | fields[C.GoString(f.name)] = C.GoString((*C.char)(C.gst_value_serialize(f.val))) 99 | } 100 | return fields 101 | } 102 | 103 | func convertToGoSlice(ptr **C.gchar, length int) []string { 104 | tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(ptr))[:length:length] 105 | gostrings := make([]string, 0, length) 106 | for _, s := range tmpslice { 107 | if s == nil { 108 | break 109 | } 110 | gostrings = append(gostrings, C.GoString(s)) 111 | } 112 | 113 | return gostrings 114 | } 115 | 116 | var CLOCK_TIME_NONE int64 = -1 117 | -------------------------------------------------------------------------------- /context.go: -------------------------------------------------------------------------------- 1 | //GstContext — Lightweight objects to represent element contexts 2 | package gst 3 | 4 | /* 5 | #include 6 | #include 7 | */ 8 | import "C" 9 | 10 | import ( 11 | //"errors" 12 | "github.com/lidouf/glib" 13 | //"time" 14 | //"unsafe" 15 | ) 16 | 17 | type Context struct { 18 | glib.Object 19 | } 20 | 21 | func (o *Context) g() *C.GstContext { 22 | return (*C.GstContext)(o.GetPtr()) 23 | } 24 | 25 | func (o *Context) AsContext() *Context { 26 | return o 27 | } 28 | -------------------------------------------------------------------------------- /context.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 0/12 3 | ``` 4 | GstContext * gst_context_new () 5 | GstContext * gst_context_ref () 6 | void gst_context_unref () 7 | GstContext * gst_context_copy () 8 | const gchar * gst_context_get_context_type () 9 | gboolean gst_context_has_context_type () 10 | gboolean gst_context_is_persistent () 11 | const GstStructure * gst_context_get_structure () 12 | GstStructure * gst_context_writable_structure () 13 | #define gst_context_make_writable() 14 | #define gst_context_is_writable() 15 | gboolean gst_context_replace () 16 | ``` -------------------------------------------------------------------------------- /control_binding.go: -------------------------------------------------------------------------------- 1 | package gst 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "github.com/lidouf/glib" 10 | ) 11 | 12 | type ControlBinding struct { 13 | GstObj 14 | } 15 | 16 | func (d *ControlBinding) Type() glib.Type { 17 | return glib.TypeFromName("GstControlBinding") 18 | } 19 | 20 | func (c *ControlBinding) g() *C.GstControlBinding { 21 | return (*C.GstControlBinding)(c.GetPtr()) 22 | } 23 | 24 | func (c *ControlBinding) AsControlBinding() *ControlBinding { 25 | return c 26 | } 27 | 28 | //Sets the property of the object , according to the GstControlSources that handle them and for the given timestamp. 29 | //If this function fails, it is most likely the application developers fault. Most probably the control sources are not setup correctly. 30 | //Returns 31 | //TRUE if the controller value could be applied to the object property, FALSE otherwise 32 | func (c *ControlBinding) SyncValues(o *GstObj, timestamp, lastSync ClockTime) bool { 33 | return C.gst_control_binding_sync_values(c.g(), o.g(), C.GstClockTime(timestamp), C.GstClockTime(lastSync)) != 0 34 | } 35 | 36 | //This function is used to disable a control binding for some time, i.e. gst_object_sync_values() will do nothing. 37 | func (c *ControlBinding) SetDisabled(disabled bool) { 38 | C.gst_control_binding_set_disabled(c.g(), gBoolean(disabled)) 39 | } 40 | 41 | //Check if the control binding is disabled. 42 | //Returns 43 | //TRUE if the binding is inactive 44 | func (o *ControlBinding) IsDisabled() bool { 45 | return C.gst_control_binding_is_disabled(o.g()) != 0 46 | } 47 | -------------------------------------------------------------------------------- /control_binding.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 3/6 3 | ``` 4 | Y gboolean gst_control_binding_sync_values () 5 | GValue * gst_control_binding_get_value () 6 | gboolean gst_control_binding_get_value_array () 7 | gboolean gst_control_binding_get_g_value_array () 8 | Y void gst_control_binding_set_disabled () 9 | Y gboolean gst_control_binding_is_disabled () 10 | ``` -------------------------------------------------------------------------------- /discoverer.go: -------------------------------------------------------------------------------- 1 | package gst 2 | 3 | /* 4 | #cgo pkg-config: gstreamer-pbutils-1.0 5 | #include 6 | #include 7 | #include 8 | 9 | static gboolean is_discoverer_container_info(GstDiscovererStreamInfo* info) { 10 | return GST_IS_DISCOVERER_CONTAINER_INFO(info); 11 | } 12 | static GstDiscovererContainerInfo* to_discoverer_container_info(GstDiscovererStreamInfo* info) { 13 | return GST_DISCOVERER_CONTAINER_INFO(info); 14 | } 15 | */ 16 | import "C" 17 | 18 | import ( 19 | "github.com/lidouf/glib" 20 | 21 | "errors" 22 | "time" 23 | "unsafe" 24 | ) 25 | 26 | type DiscovererResult C.GstDiscovererResult 27 | 28 | const ( 29 | DISCOVERER_OK = DiscovererResult(C.GST_DISCOVERER_OK) 30 | DISCOVERER_URI_INVALID = DiscovererResult(C.GST_DISCOVERER_URI_INVALID) 31 | DISCOVERER_ERROR = DiscovererResult(C.GST_DISCOVERER_ERROR) 32 | DISCOVERER_TIMEOUT = DiscovererResult(C.GST_DISCOVERER_TIMEOUT) 33 | DISCOVERER_BUSY = DiscovererResult(C.GST_DISCOVERER_BUSY) 34 | DISCOVERER_MISSING_PLUGINS = DiscovererResult(C.GST_DISCOVERER_MISSING_PLUGINS) 35 | ) 36 | 37 | func (d *DiscovererResult) Type() glib.Type { 38 | return glib.TypeFromName("GstDiscovererResult") 39 | } 40 | 41 | func (d *DiscovererResult) g() *C.GstDiscovererResult { 42 | return (*C.GstDiscovererResult)(d) 43 | } 44 | 45 | type DiscovererStreamInfo C.GstDiscovererStreamInfo 46 | 47 | func (d *DiscovererStreamInfo) Type() glib.Type { 48 | return glib.TypeFromName("DiscovererStreamInfo") 49 | } 50 | 51 | func (d *DiscovererStreamInfo) g() *C.GstDiscovererStreamInfo { 52 | return (*C.GstDiscovererStreamInfo)(d) 53 | } 54 | 55 | func (d *DiscovererStreamInfo) GetCaps() *Caps { 56 | r := new(Caps) 57 | r.SetPtr(glib.Pointer(C.gst_discoverer_stream_info_get_caps(d.g()))) 58 | return r 59 | } 60 | 61 | func (d *DiscovererStreamInfo) GetTags() *TagList { 62 | return (*TagList)(unsafe.Pointer(C.gst_discoverer_stream_info_get_tags(d.g()))) 63 | } 64 | 65 | func (d *DiscovererStreamInfo) GetNext() *DiscovererStreamInfo { 66 | return (*DiscovererStreamInfo)(C.gst_discoverer_stream_info_get_next(d.g())) 67 | } 68 | 69 | func (d *DiscovererStreamInfo) GetPrevious() *DiscovererStreamInfo { 70 | return (*DiscovererStreamInfo)(C.gst_discoverer_stream_info_get_previous(d.g())) 71 | } 72 | 73 | func (d *DiscovererStreamInfo) GetStreamId() string { 74 | return C.GoString((*C.char)(C.gst_discoverer_stream_info_get_stream_id(d.g()))) 75 | } 76 | 77 | func (d *DiscovererStreamInfo) GetStreamTypeNick() string { 78 | return C.GoString((*C.char)(C.gst_discoverer_stream_info_get_stream_type_nick(d.g()))) 79 | } 80 | 81 | func (d *DiscovererStreamInfo) IsContainerInfo() bool { 82 | return C.is_discoverer_container_info(d.g()) != 0 83 | } 84 | 85 | func (d *DiscovererStreamInfo) AsContainerInfo() *DiscovererContainerInfo { 86 | return (*DiscovererContainerInfo)(unsafe.Pointer(C.to_discoverer_container_info(d.g()))) 87 | } 88 | 89 | type DiscovererContainerInfo C.GstDiscovererContainerInfo 90 | 91 | func (d *DiscovererContainerInfo) g() *C.GstDiscovererContainerInfo { 92 | return (*C.GstDiscovererContainerInfo)(d) 93 | } 94 | 95 | func DisCovererContainerInfoGetType() glib.Type { 96 | return glib.Type(C.gst_discoverer_container_info_get_type()) 97 | } 98 | 99 | func (d *DiscovererContainerInfo) GetStreams() *glib.List { 100 | return glib.WrapList(uintptr(unsafe.Pointer(C.gst_discoverer_container_info_get_streams(d.g())))) 101 | } 102 | 103 | type DiscovererInfo C.GstDiscovererInfo 104 | 105 | func (d *DiscovererInfo) Type() glib.Type { 106 | return glib.TypeFromName("GstDiscovererInfo") 107 | } 108 | 109 | func (d *DiscovererInfo) g() *C.GstDiscovererInfo { 110 | return (*C.GstDiscovererInfo)(d) 111 | } 112 | 113 | func (d *DiscovererInfo) GetUri() string { 114 | return C.GoString((*C.char)(C.gst_discoverer_info_get_uri(d.g()))) 115 | } 116 | 117 | func (d *DiscovererInfo) GetResult() DiscovererResult { 118 | return DiscovererResult(C.gst_discoverer_info_get_result(d.g())) 119 | } 120 | 121 | func (d *DiscovererInfo) GetMisc() *Structure { 122 | r := new(Structure) 123 | r.SetPtr(glib.Pointer(C.gst_discoverer_info_get_misc(d.g()))) 124 | return r 125 | } 126 | 127 | func (d *DiscovererInfo) GetDuration() ClockTime { 128 | return ClockTime(C.gst_discoverer_info_get_duration(d.g())) 129 | } 130 | 131 | func (d *DiscovererInfo) GetTags() *TagList { 132 | r := new(TagList) 133 | r.SetPtr(glib.Pointer(C.gst_discoverer_info_get_tags(d.g()))) 134 | return r 135 | } 136 | 137 | func (d *DiscovererInfo) GetSeekable() bool { 138 | return C.gst_discoverer_info_get_seekable(d.g()) != 0 139 | } 140 | 141 | func (d *DiscovererInfo) GetStreamInfo() *DiscovererStreamInfo { 142 | return (*DiscovererStreamInfo)(C.gst_discoverer_info_get_stream_info(d.g())) 143 | } 144 | 145 | func (d *DiscovererInfo) GetStreamList() *glib.List { 146 | return glib.WrapList(uintptr(unsafe.Pointer(C.gst_discoverer_info_get_stream_list(d.g())))) 147 | } 148 | 149 | type Discoverer struct { 150 | GstObj 151 | } 152 | 153 | func (d *Discoverer) g() *C.GstDiscoverer { 154 | return (*C.GstDiscoverer)(d.GetPtr()) 155 | } 156 | 157 | /* Asynchronous API */ 158 | func (d *Discoverer) Start() { 159 | C.gst_discoverer_start(d.g()) 160 | } 161 | 162 | func (d *Discoverer) Stop() { 163 | C.gst_discoverer_stop(d.g()) 164 | } 165 | 166 | func (d *Discoverer) DiscoverUriAsync(uri string) bool { 167 | s := (*C.gchar)(C.CString(uri)) 168 | defer C.free(unsafe.Pointer(s)) 169 | return C.gst_discoverer_discover_uri_async(d.g(), s) != 0 170 | } 171 | 172 | /* Synchronous API */ 173 | func (d *Discoverer) DiscoverUri(uri string) (*DiscovererInfo, error) { 174 | s := (*C.gchar)(C.CString(uri)) 175 | defer C.free(unsafe.Pointer(s)) 176 | var err *C.GError = nil 177 | 178 | res := C.gst_discoverer_discover_uri(d.g(), s, &err) 179 | if res == nil { 180 | defer C.g_error_free(err) 181 | return nil, errors.New(C.GoString((*C.char)(err.message))) 182 | } 183 | return (*DiscovererInfo)(res), nil 184 | } 185 | 186 | func NewDiscoverer(timeout time.Duration) (discoverer *Discoverer, err error) { 187 | var e, ret_e *C.GError 188 | cDiscoverer := C.gst_discoverer_new((C.GstClockTime)(uint64(timeout)), &e) 189 | discoverer = new(Discoverer) 190 | ret_e = new(C.GError) 191 | if e == nil && cDiscoverer != nil { 192 | discoverer.SetPtr(glib.Pointer(cDiscoverer)) 193 | return 194 | } 195 | 196 | err = (*glib.Error)(unsafe.Pointer(ret_e)) 197 | return 198 | } 199 | -------------------------------------------------------------------------------- /discoverer.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 20/54 3 | ``` 4 | Y GstDiscoverer * gst_discoverer_new () 5 | Y void gst_discoverer_start () 6 | Y void gst_discoverer_stop () 7 | Y GstDiscovererInfo * gst_discoverer_discover_uri () 8 | Y gboolean gst_discoverer_discover_uri_async () 9 | Y GstClockTime gst_discoverer_info_get_duration () 10 | Y const GstStructure * gst_discoverer_info_get_misc () 11 | Y GstDiscovererResult gst_discoverer_info_get_result () 12 | Y GstDiscovererStreamInfo * gst_discoverer_info_get_stream_info () 13 | Y GList * gst_discoverer_info_get_stream_list () 14 | Y const GstTagList * gst_discoverer_info_get_tags () 15 | const GstToc * gst_discoverer_info_get_toc () 16 | Y const gchar * gst_discoverer_info_get_uri () 17 | Y gboolean gst_discoverer_info_get_seekable () 18 | #define gst_discoverer_info_ref() 19 | #define gst_discoverer_info_unref() 20 | GVariant * gst_discoverer_info_to_variant () 21 | GstDiscovererInfo * gst_discoverer_info_from_variant () 22 | Y GstCaps * gst_discoverer_stream_info_get_caps () 23 | D const GstStructure * gst_discoverer_stream_info_get_misc () 24 | Y GstDiscovererStreamInfo * gst_discoverer_stream_info_get_next () 25 | Y GstDiscovererStreamInfo * gst_discoverer_stream_info_get_previous () 26 | Y const GstTagList * gst_discoverer_stream_info_get_tags () 27 | const GstToc * gst_discoverer_stream_info_get_toc () 28 | Y const gchar * gst_discoverer_stream_info_get_stream_id () 29 | #define gst_discoverer_stream_info_ref() 30 | #define gst_discoverer_stream_info_unref() 31 | void gst_discoverer_stream_info_list_free () 32 | Y const gchar * gst_discoverer_stream_info_get_stream_type_nick () 33 | const gchar ** gst_discoverer_info_get_missing_elements_installer_details () 34 | GList * gst_discoverer_info_get_audio_streams () 35 | GList * gst_discoverer_info_get_container_streams () 36 | GList * gst_discoverer_info_get_streams () 37 | GList * gst_discoverer_info_get_subtitle_streams () 38 | GList * gst_discoverer_info_get_video_streams () 39 | guint gst_discoverer_audio_info_get_bitrate () 40 | guint gst_discoverer_audio_info_get_channels () 41 | guint gst_discoverer_audio_info_get_depth () 42 | const gchar * gst_discoverer_audio_info_get_language () 43 | guint gst_discoverer_audio_info_get_max_bitrate () 44 | guint gst_discoverer_audio_info_get_sample_rate () 45 | Y GList * gst_discoverer_container_info_get_streams () 46 | const gchar * gst_discoverer_subtitle_info_get_language () 47 | guint gst_discoverer_video_info_get_bitrate () 48 | guint gst_discoverer_video_info_get_depth () 49 | guint gst_discoverer_video_info_get_framerate_denom () 50 | guint gst_discoverer_video_info_get_framerate_num () 51 | guint gst_discoverer_video_info_get_height () 52 | gboolean gst_discoverer_video_info_is_interlaced () 53 | gboolean gst_discoverer_video_info_is_image () 54 | guint gst_discoverer_video_info_get_max_bitrate () 55 | guint gst_discoverer_video_info_get_par_denom () 56 | guint gst_discoverer_video_info_get_par_num () 57 | guint gst_discoverer_video_info_get_width () 58 | ``` -------------------------------------------------------------------------------- /element.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 82/90 3 | ``` 4 | Y #define GST_STATE() 5 | Y #define GST_STATE_GET_NEXT() 6 | Y #define GST_STATE_NEXT() 7 | Y #define GST_STATE_PENDING() 8 | Y #define GST_STATE_RETURN() 9 | Y #define GST_STATE_TARGET() 10 | Y #define GST_STATE_TRANSITION() 11 | Y #define GST_STATE_TRANSITION_CURRENT() 12 | Y #define GST_STATE_TRANSITION_NEXT() 13 | #define GST_STATE_GET_LOCK() 14 | #define GST_STATE_GET_COND() 15 | * #define GST_ELEMENT_NAME() 16 | * #define GST_ELEMENT_PARENT() 17 | * #define GST_ELEMENT_BUS() 18 | * #define GST_ELEMENT_CLOCK() 19 | Y #define GST_ELEMENT_PADS() 20 | * #define GST_ELEMENT_START_TIME() 21 | #define GST_ELEMENT_ERROR() 22 | #define GST_ELEMENT_WARNING() 23 | #define GST_ELEMENT_INFO() 24 | Y #define GST_ELEMENT_IS_LOCKED_STATE() 25 | Y void gst_element_class_add_pad_template () 26 | Y void gst_element_class_add_static_pad_template () 27 | Y GstPadTemplate * gst_element_class_get_pad_template () 28 | Y GList * gst_element_class_get_pad_template_list () 29 | Y void gst_element_class_set_metadata () 30 | Y void gst_element_class_set_static_metadata () 31 | Y void gst_element_class_add_metadata () 32 | Y void gst_element_class_add_static_metadata () 33 | Y gboolean gst_element_add_pad () 34 | Y void gst_element_create_all_pads () 35 | Y GstPad * gst_element_get_compatible_pad () 36 | Y GstPadTemplate * gst_element_get_compatible_pad_template () 37 | Y GstPad * gst_element_get_request_pad () 38 | Y GstPad * gst_element_get_static_pad () 39 | Y GstPad * gst_element_request_pad () 40 | Y void gst_element_no_more_pads () 41 | Y void gst_element_release_request_pad () 42 | Y gboolean gst_element_remove_pad () 43 | GstIterator * gst_element_iterate_pads () 44 | GstIterator * gst_element_iterate_sink_pads () 45 | GstIterator * gst_element_iterate_src_pads () 46 | Y gboolean gst_element_link () 47 | Y void gst_element_unlink () 48 | * gboolean gst_element_link_many () 49 | * void gst_element_unlink_many () 50 | Y gboolean gst_element_link_pads () 51 | Y gboolean gst_element_link_pads_full () 52 | Y void gst_element_unlink_pads () 53 | Y gboolean gst_element_link_pads_filtered () 54 | Y gboolean gst_element_link_filtered () 55 | Y const gchar * gst_element_class_get_metadata () 56 | Y void gst_element_set_base_time () 57 | Y GstClockTime gst_element_get_base_time () 58 | Y void gst_element_set_start_time () 59 | Y GstClockTime gst_element_get_start_time () 60 | Y void gst_element_set_bus () 61 | Y GstBus * gst_element_get_bus () 62 | Y void gst_element_set_context () 63 | Y GstContext * gst_element_get_context () 64 | Y GstContext * gst_element_get_context_unlocked () 65 | Y GList * gst_element_get_contexts () 66 | Y GstElementFactory * gst_element_get_factory () 67 | * #define gst_element_set_name() 68 | * #define gst_element_get_name() 69 | * #define gst_element_set_parent() 70 | * #define gst_element_get_parent() 71 | Y gboolean gst_element_set_clock () 72 | Y GstClock * gst_element_get_clock () 73 | Y GstClock * gst_element_provide_clock () 74 | Y GstStateChangeReturn gst_element_set_state () 75 | Y GstStateChangeReturn gst_element_get_state () 76 | Y gboolean gst_element_set_locked_state () 77 | Y gboolean gst_element_is_locked_state () 78 | Y void gst_element_abort_state () 79 | Y GstStateChangeReturn gst_element_continue_state () 80 | Y void gst_element_lost_state () 81 | Y const gchar * gst_element_state_get_name () 82 | Y const gchar * gst_element_state_change_return_get_name () 83 | Y gboolean gst_element_sync_state_with_parent () 84 | Y GstStateChangeReturn gst_element_change_state () 85 | Y void gst_element_message_full () 86 | Y gboolean gst_element_post_message () 87 | Y gboolean gst_element_query () 88 | Y gboolean gst_element_query_convert () 89 | Y gboolean gst_element_query_position () 90 | Y gboolean gst_element_query_duration () 91 | Y gboolean gst_element_send_event () 92 | Y gboolean gst_element_seek_simple () 93 | Y gboolean gst_element_seek () 94 | ``` 95 | 1. `gst_element_link_many()` has been implementation in gst.Link. 96 | 2. `gst_element_unlink_many ()` has been implementation in gst.Unlink. 97 | 3. `gst_element_set_name()` -> gst_object_set_name 98 | 4. `gst_element_get_name()` -> gst_object_get_name 99 | 5. `gst_element_set_parent()` -> gst_object_set_parent 100 | 6. `gst_element_get_parent()` -> gst_object_get_parent -------------------------------------------------------------------------------- /element_factory.go: -------------------------------------------------------------------------------- 1 | package gst 2 | 3 | /* 4 | #include 5 | #include 6 | */ 7 | import "C" 8 | 9 | import ( 10 | "github.com/lidouf/glib" 11 | "unsafe" 12 | //"fmt" 13 | ) 14 | 15 | type ElementFactory struct { 16 | GstObj 17 | } 18 | 19 | func (f *ElementFactory) g() *C.GstElementFactory { 20 | return (*C.GstElementFactory)(f.GetPtr()) 21 | } 22 | 23 | func (f *ElementFactory) AsElementFactory() *ElementFactory { 24 | return f 25 | } 26 | 27 | // Get the GType for elements managed by this factory. The type can only be retrieved if the element factory is loaded, 28 | // which can be assured with gst_plugin_feature_load(). 29 | // Returns 30 | // the GType for elements managed by this factory or 0 if the factory is not loaded. 31 | func (f *ElementFactory) GetElementType() glib.Type { 32 | return glib.Type(C.gst_element_factory_get_element_type(f.g())) 33 | } 34 | 35 | func (f *ElementFactory) Create(name string) *Element { 36 | n := (*C.gchar)(C.CString(name)) 37 | defer C.free(unsafe.Pointer(n)) 38 | 39 | ge := C.gst_element_factory_create(f.g(), n) 40 | if ge == nil { 41 | return nil 42 | } 43 | e := new(Element) 44 | e.SetPtr(glib.Pointer(ge)) 45 | return e 46 | } 47 | 48 | /** 49 | Get metadata from ElementFactory 50 | */ 51 | func (f *ElementFactory) GetMetadataKeys() []string { 52 | k := C.gst_element_factory_get_metadata_keys(f.g()) 53 | if k == nil { 54 | return []string{} 55 | } 56 | defer C.free(unsafe.Pointer(k)) 57 | 58 | return convertToGoSlice(k, 6) 59 | } 60 | 61 | func (f *ElementFactory) GetLongName() string { 62 | return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_LONGNAME))))) 63 | } 64 | 65 | func (f *ElementFactory) GetKlass() string { 66 | return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_KLASS))))) 67 | } 68 | 69 | func (f *ElementFactory) GetDescription() string { 70 | return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_DESCRIPTION))))) 71 | } 72 | 73 | func (f *ElementFactory) GetAuthor() string { 74 | return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_AUTHOR))))) 75 | } 76 | 77 | func (f *ElementFactory) GetDocumentationUri() string { 78 | return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_DOC_URI))))) 79 | } 80 | 81 | func (f *ElementFactory) GetIconName() string { 82 | return C.GoString((*C.char)(C.gst_element_factory_get_metadata(f.g(), (*C.gchar)(C.CString(ELEMENT_METADATA_ICON_NAME))))) 83 | } 84 | 85 | func (f *ElementFactory) GetNumPadTemplates() uint { 86 | return uint(C.gst_element_factory_get_num_pad_templates(f.g())) 87 | } 88 | 89 | func (f *ElementFactory) GetStaticPadTemplates() []*StaticPadTemplate { 90 | clist := C.gst_element_factory_get_static_pad_templates(f.g()) 91 | 92 | padTemplates := make([]*StaticPadTemplate, 0) 93 | list := glib.WrapList(uintptr(unsafe.Pointer(clist))) 94 | for ; list != nil && list.Data() != nil; list = list.Next() { 95 | padTemplates = append(padTemplates, (*StaticPadTemplate)(list.Data().(unsafe.Pointer))) 96 | } 97 | 98 | return padTemplates 99 | } 100 | 101 | func ElementFactoryMake(factory_name, name string) *Element { 102 | fn := (*C.gchar)(C.CString(factory_name)) 103 | defer C.free(unsafe.Pointer(fn)) 104 | n := (*C.gchar)(C.CString(name)) 105 | defer C.free(unsafe.Pointer(n)) 106 | ge := C.gst_element_factory_make(fn, n) 107 | if ge == nil { 108 | return nil 109 | } 110 | e := new(Element) 111 | e.SetPtr(glib.Pointer(ge)) 112 | return e 113 | } 114 | 115 | func ElementFactoryFind(name string) *ElementFactory { 116 | n := (*C.gchar)(C.CString(name)) 117 | defer C.free(unsafe.Pointer(n)) 118 | 119 | gf := C.gst_element_factory_find(n) 120 | if gf == nil { 121 | return nil 122 | } 123 | 124 | f := new(ElementFactory) 125 | f.SetPtr(glib.Pointer(gf)) 126 | 127 | return f 128 | } 129 | -------------------------------------------------------------------------------- /element_factory.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 8/19 3 | ``` 4 | gboolean gst_element_register () 5 | Y GstElementFactory * gst_element_factory_find () 6 | Y GType gst_element_factory_get_element_type () 7 | Y const gchar * gst_element_factory_get_metadata () 8 | Y gchar ** gst_element_factory_get_metadata_keys () 9 | Y guint gst_element_factory_get_num_pad_templates () 10 | GstURIType gst_element_factory_get_uri_type () 11 | const gchar * const * gst_element_factory_get_uri_protocols () 12 | gboolean gst_element_factory_has_interface () 13 | Y GstElement * gst_element_factory_create () 14 | Y GstElement * gst_element_factory_make () 15 | gboolean gst_element_factory_can_sink_all_caps () 16 | gboolean gst_element_factory_can_src_all_caps () 17 | gboolean gst_element_factory_can_sink_any_caps () 18 | gboolean gst_element_factory_can_src_any_caps () 19 | Y const GList * gst_element_factory_get_static_pad_templates () 20 | GList * gst_element_factory_list_filter () 21 | GList * gst_element_factory_list_get_elements () 22 | gboolean gst_element_factory_list_is_type () 23 | ``` -------------------------------------------------------------------------------- /element_metadata.go: -------------------------------------------------------------------------------- 1 | package gst 2 | 3 | /* 4 | #include 5 | #include 6 | */ 7 | import "C" 8 | 9 | const ( 10 | ELEMENT_METADATA_LONGNAME = "long-name" 11 | ELEMENT_METADATA_KLASS = "klass" 12 | ELEMENT_METADATA_DESCRIPTION = "description" 13 | ELEMENT_METADATA_AUTHOR = "author" 14 | ELEMENT_METADATA_DOC_URI = "doc-uri" 15 | ELEMENT_METADATA_ICON_NAME = "icon-name" 16 | ) 17 | -------------------------------------------------------------------------------- /element_metadata.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 0/0 3 | ``` 4 | There's no API in this package. Only constant defined here. 5 | ``` -------------------------------------------------------------------------------- /event.go: -------------------------------------------------------------------------------- 1 | //GstEvent — Structure describing events that are passed up and down a pipeline 2 | package gst 3 | 4 | /* 5 | #include 6 | #include 7 | static inline 8 | GstEventType CALL_MACRO_GST_EVENT_TYPE(GstEvent *event) { 9 | return GST_EVENT_TYPE(event); 10 | } 11 | static inline 12 | gboolean CALL_MACRO_gst_event_is_writable(GstEvent *event) { 13 | return gst_event_is_writable(event); 14 | } 15 | static inline 16 | GstEvent* CALL_MACRO_gst_event_make_writable(GstEvent *event) { 17 | return gst_event_make_writable(event); 18 | } 19 | */ 20 | import "C" 21 | 22 | import ( 23 | //"errors" 24 | "github.com/lidouf/glib" 25 | //"time" 26 | "unsafe" 27 | ) 28 | 29 | type EventTypeFlags C.GstEventTypeFlags 30 | 31 | const ( 32 | EVENT_TYPE_UPSTREAM = EventTypeFlags(C.GST_EVENT_TYPE_UPSTREAM) 33 | EVENT_TYPE_DOWNSTREAM = EventTypeFlags(C.GST_EVENT_TYPE_DOWNSTREAM) 34 | EVENT_TYPE_SERIALIZED = EventTypeFlags(C.GST_EVENT_TYPE_SERIALIZED) 35 | EVENT_TYPE_STICKY = EventTypeFlags(C.GST_EVENT_TYPE_STICKY) 36 | EVENT_TYPE_STICKY_MULTI = EventTypeFlags(C.GST_EVENT_TYPE_STICKY_MULTI) 37 | ) 38 | 39 | type EventType C.GstEventType 40 | 41 | const ( 42 | EVENT_UNKNOWN = EventType(C.GST_EVENT_UNKNOWN) 43 | /* bidirectional events */ 44 | EVENT_FLUSH_START = EventType(C.GST_EVENT_FLUSH_START) 45 | EVENT_FLUSH_STOP = EventType(C.GST_EVENT_FLUSH_STOP) 46 | /* downstream serialized events */ 47 | EVENT_STREAM_START = EventType(C.GST_EVENT_STREAM_START) 48 | EVENT_CAPS = EventType(C.GST_EVENT_CAPS) 49 | EVENT_SEGMENT = EventType(C.GST_EVENT_SEGMENT) 50 | EVENT_TAG = EventType(C.GST_EVENT_TAG) 51 | EVENT_BUFFERSIZE = EventType(C.GST_EVENT_BUFFERSIZE) 52 | EVENT_SINK_MESSAGE = EventType(C.GST_EVENT_SINK_MESSAGE) 53 | EVENT_EOS = EventType(C.GST_EVENT_EOS) 54 | EVENT_TOC = EventType(C.GST_EVENT_TOC) 55 | EVENT_PROTECTION = EventType(C.GST_EVENT_PROTECTION) 56 | /* non-sticky downstream serialized */ 57 | EVENT_SEGMENT_DONE = EventType(C.GST_EVENT_SEGMENT_DONE) 58 | EVENT_GAP = EventType(C.GST_EVENT_GAP) 59 | /* upstream events */ 60 | EVENT_QOS = EventType(C.GST_EVENT_QOS) 61 | EVENT_SEEK = EventType(C.GST_EVENT_SEEK) 62 | EVENT_NAVIGATION = EventType(C.GST_EVENT_NAVIGATION) 63 | EVENT_LATENCY = EventType(C.GST_EVENT_LATENCY) 64 | EVENT_STEP = EventType(C.GST_EVENT_STEP) 65 | EVENT_RECONFIGURE = EventType(C.GST_EVENT_RECONFIGURE) 66 | EVENT_TOC_SELECT = EventType(C.GST_EVENT_TOC_SELECT) 67 | /* custom events start here */ 68 | EVENT_CUSTOM_UPSTREAM = EventType(C.GST_EVENT_CUSTOM_UPSTREAM) 69 | EVENT_CUSTOM_DOWNSTREAM = EventType(C.GST_EVENT_CUSTOM_DOWNSTREAM) 70 | EVENT_CUSTOM_DOWNSTREAM_OOB = EventType(C.GST_EVENT_CUSTOM_DOWNSTREAM_OOB) 71 | EVENT_CUSTOM_DOWNSTREAM_STICKY = EventType(C.GST_EVENT_CUSTOM_DOWNSTREAM_STICKY) 72 | EVENT_CUSTOM_BOTH = EventType(C.GST_EVENT_CUSTOM_BOTH) 73 | EVENT_CUSTOM_BOTH_OOB = EventType(C.GST_EVENT_CUSTOM_BOTH_OOB) 74 | ) 75 | 76 | //Gets the GstEventTypeFlags associated with type . 77 | //Parameters 78 | //type 79 | //a GstEventType 80 | //Returns 81 | //a GstEventTypeFlags. 82 | func (t EventType) Flags() EventTypeFlags { 83 | return EventTypeFlags(C.gst_event_type_get_flags(C.GstEventType(t))) 84 | } 85 | 86 | //Get a printable name for the given event type. Do not modify or free. 87 | //Parameters 88 | //type 89 | //the event type 90 | //Returns 91 | //a reference to the static name of the event. 92 | func (t EventType) GetName() string { 93 | return C.GoString((*C.char)(C.gst_event_type_get_name(C.GstEventType(t)))) 94 | } 95 | 96 | //Get the unique quark for the given event type. 97 | //Parameters 98 | //type 99 | //the event type 100 | //Returns 101 | //the quark associated with the event type 102 | func (t EventType) ToQuark() glib.Quark { 103 | return glib.Quark(C.gst_event_type_to_quark(C.GstEventType(t))) 104 | } 105 | 106 | const EVENT_NUM_SHIFT = 8 107 | 108 | //#define GST_EVENT_MAKE_TYPE(num,flags) 109 | //when making custom event types, use this macro with the num and the given flags 110 | //Parameters 111 | //num 112 | //the event number to create 113 | //flags 114 | //the event flags 115 | //#define GST_EVENT_MAKE_TYPE(num,flags) \ 116 | //(((num) << GST_EVENT_NUM_SHIFT) | (flags)) 117 | func MakeEventType(num int, flags EventTypeFlags) EventType { 118 | return EventType(num<type) 151 | //Get the GstEventType of the event. 152 | //Parameters 153 | //event 154 | //the event to query 155 | func (e *Event) GetType() EventType { 156 | return EventType(C.CALL_MACRO_GST_EVENT_TYPE(e.g())) 157 | } 158 | 159 | //#define GST_EVENT_TYPE_NAME(event) (gst_event_type_get_name(GST_EVENT_TYPE(event))) 160 | //Get a constant string representation of the GstEventType of the event. 161 | //Parameters 162 | //event 163 | //the event to query 164 | func (e *Event) GetTypeName() string { 165 | return e.GetType().GetName() 166 | } 167 | 168 | //#define GST_EVENT_TIMESTAMP(event) (GST_EVENT_CAST(event)->timestamp) 169 | //Get the GstClockTime timestamp of the event. This is the time when the event was created. 170 | //Parameters 171 | //event 172 | //the event to query 173 | func (e *Event) Timestamp() uint64 { 174 | return uint64(e.g().timestamp) 175 | } 176 | 177 | //#define GST_EVENT_SEQNUM(event) (GST_EVENT_CAST(event)->seqnum) 178 | //The sequence number of event . 179 | //Parameters 180 | //event 181 | //the event to query 182 | func (e *Event) SeqNum() uint32 { 183 | return uint32(e.g().seqnum) 184 | } 185 | 186 | //#define GST_EVENT_IS_UPSTREAM(ev) !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_UPSTREAM) 187 | //Check if an event can travel upstream. 188 | //Parameters 189 | //ev 190 | //the event to query 191 | func (e *Event) IsUpstream() bool { 192 | return int32(e.GetType())&int32(EVENT_TYPE_UPSTREAM) != 0 193 | } 194 | 195 | //#define GST_EVENT_IS_DOWNSTREAM(ev) !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_DOWNSTREAM) 196 | //Check if an event can travel downstream. 197 | //Parameters 198 | //ev 199 | //the event to query 200 | func (e *Event) IsDownstream() bool { 201 | return int32(e.GetType())&int32(EVENT_TYPE_DOWNSTREAM) != 0 202 | } 203 | 204 | //#define GST_EVENT_IS_SERIALIZED(ev) !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_SERIALIZED) 205 | //Check if an event is serialized with the data stream. 206 | //Parameters 207 | //ev 208 | //the event to query 209 | func (e *Event) IsSerialized() bool { 210 | return int32(e.GetType())&int32(EVENT_TYPE_SERIALIZED) != 0 211 | } 212 | 213 | //#define GST_EVENT_IS_STICKY(ev) !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_STICKY) 214 | //Check if an event is sticky on the pads. 215 | //Parameters 216 | //ev 217 | //the event to query 218 | func (e *Event) IsSticky() bool { 219 | return int32(e.GetType())&int32(EVENT_TYPE_STICKY) != 0 220 | } 221 | 222 | //Increase the refcount of this event. 223 | //Parameters 224 | //event 225 | //The event to refcount 226 | //Returns 227 | //event (for convenience when doing assignments). 228 | func (e *Event) Ref() *Event { 229 | r := new(Event) 230 | r.SetPtr(glib.Pointer(C.gst_event_ref(e.g()))) 231 | return r 232 | } 233 | 234 | //Decrease the refcount of an event, freeing it if the refcount reaches 0. 235 | //Parameters 236 | //event 237 | //the event to refcount. 238 | func (e *Event) Unref() { 239 | C.gst_event_unref(e.g()) 240 | } 241 | 242 | //Modifies a pointer to a GstEvent to point to a different GstEvent. 243 | //The modification is done atomically (so this is useful for ensuring thread safety in some cases), 244 | //and the reference counts are updated appropriately (the old event is unreffed, the new one is reffed). 245 | // 246 | //Either new_event or the GstEvent pointed to by old_event may be NULL. 247 | //Parameters 248 | //old_event 249 | //pointer to a pointer to a GstEvent to be replaced. 250 | //new_event 251 | //pointer to a GstEvent that will replace the event pointed to by old_event . 252 | //Returns 253 | //TRUE if new_event was different from old_event 254 | //func (e *Event) Replace(old_event *Event) bool { 255 | // return C.gst_event_replace(&old_event.g(), e.g()) 256 | //} 257 | 258 | //Copy the event using the event specific copy function. 259 | //Parameters 260 | //event 261 | //The event to copy 262 | //Returns 263 | //the new event. 264 | func (e *Event) Copy() *Event { 265 | r := new(Event) 266 | r.SetPtr(glib.Pointer(C.gst_event_copy(e.g()))) 267 | return r 268 | } 269 | 270 | //GstEvent * 271 | //gst_event_steal (GstEvent **old_event); 272 | 273 | //Atomically replace the GstEvent pointed to by old_event with NULL and return the original event. 274 | //Parameters 275 | //old_event 276 | //pointer to a pointer to a GstEvent to be stolen. 277 | //Returns 278 | //the GstEvent that was in old_event 279 | 280 | //gboolean 281 | //gst_event_take (GstEvent **old_event, 282 | //GstEvent *new_event); 283 | // 284 | //Modifies a pointer to a GstEvent to point to a different GstEvent. 285 | //This function is similar to gst_event_replace() except that it takes ownership of new_event . 286 | // 287 | //Either new_event or the GstEvent pointed to by old_event may be NULL. 288 | //Parameters 289 | //old_event 290 | //pointer to a pointer to a GstEvent to be stolen. 291 | //new_event 292 | //pointer to a GstEvent that will replace the event pointed to by old_event . 293 | //Returns 294 | //TRUE if new_event was different from old_event 295 | 296 | //#define gst_event_is_writable(ev) gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (ev)) 297 | //Tests if you can safely write data into a event's structure or validly modify the seqnum and timestamp field. 298 | //Parameters 299 | //ev 300 | //a GstEvent 301 | func (e *Event) IsWritable() bool { 302 | return C.CALL_MACRO_gst_event_is_writable(e.g()) != 0 303 | } 304 | 305 | //#define gst_event_make_writable(ev) GST_EVENT_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (ev))) 306 | //Makes a writable event from the given event. If the source event is already writable, this will simply return the same event. 307 | //A copy will otherwise be made using gst_event_copy(). 308 | //Parameters 309 | //ev 310 | //a GstEvent. 311 | //Returns 312 | //a writable event which may or may not be the same as ev . 313 | func (e *Event) MakeWritable() *Event { 314 | r := new(Event) 315 | r.SetPtr(glib.Pointer(C.CALL_MACRO_gst_event_make_writable(e.g()))) 316 | return r 317 | } 318 | 319 | //Get a writable version of the structure. 320 | //Parameters 321 | //event 322 | //The GstEvent. 323 | //Returns 324 | //The structure of the event. 325 | //The structure is still owned by the event, which means that you should not free it and that the pointer becomes invalid when you free the event. 326 | //This function checks if event is writable and will never return NULL. 327 | //MT safe. 328 | func (e *Event) WritableStructure() *Structure { 329 | r := new(Structure) 330 | r.SetPtr(glib.Pointer(C.gst_event_writable_structure(e.g()))) 331 | return r 332 | } 333 | 334 | //Create a new custom-typed event. This can be used for anything not handled by other event-specific functions to pass an event to another element. 335 | //Make sure to allocate an event type with the GST_EVENT_MAKE_TYPE macro, assigning a free number and filling in the correct direction and serialization flags. 336 | //New custom events can also be created by subclassing the event type if needed. 337 | //Parameters 338 | //type 339 | //The type of the new event 340 | //structure 341 | //the structure for the event. The event will take ownership of the structure. 342 | //Returns 343 | //the new custom event. 344 | func NewCustomEvent(tp EventType, structure *Structure) *Event { 345 | e := C.gst_event_new_custom(C.GstEventType(tp), structure.g()) 346 | if e == nil { 347 | return nil 348 | } 349 | r := new(Event) 350 | r.SetPtr(glib.Pointer(e)) 351 | return r 352 | } 353 | 354 | //Access the structure of the event. 355 | //Parameters 356 | //event 357 | //The GstEvent. 358 | //Returns 359 | //The structure of the event. 360 | //The structure is still owned by the event, which means that you should not free it and that the pointer becomes invalid when you free the event. 361 | //MT safe. 362 | func (e *Event) GetStructure() *Structure { 363 | r := new(Structure) 364 | r.SetPtr(glib.Pointer(C.gst_event_get_structure(e.g()))) 365 | return r 366 | } 367 | 368 | //Checks if event has the given name . This function is usually used to check the name of a custom event. 369 | //Parameters 370 | //event 371 | //The GstEvent. 372 | //name 373 | //name to check 374 | //Returns 375 | //TRUE if name matches the name of the event structure. 376 | func (e *Event) HasName(name string) bool { 377 | s := (*C.gchar)(C.CString(name)) 378 | defer C.free(unsafe.Pointer(s)) 379 | return C.gst_event_has_name(e.g(), s) != 0 380 | } 381 | 382 | //Retrieve the sequence number of a event. 383 | // 384 | //Events have ever-incrementing sequence numbers, which may also be set explicitly via gst_event_set_seqnum(). 385 | //Sequence numbers are typically used to indicate that a event corresponds to some other set of events or messages, 386 | //for example an EOS event corresponding to a SEEK event. 387 | //It is considered good practice to make this correspondence when possible, though it is not required. 388 | // 389 | //Note that events and messages share the same sequence number incrementor; 390 | //two events or messages will never have the same sequence number unless that correspondence was made explicitly. 391 | //Parameters 392 | //event 393 | //A GstEvent. 394 | //Returns 395 | //The event's sequence number. 396 | //MT safe. 397 | func (e *Event) GetSeqNum() uint32 { 398 | return uint32(C.gst_event_get_seqnum(e.g())) 399 | } 400 | 401 | //Set the sequence number of a event. 402 | // 403 | //This function might be called by the creator of a event to indicate that the event relates to other events or messages. 404 | //See gst_event_get_seqnum() for more information. 405 | //MT safe. 406 | //Parameters 407 | //event 408 | //A GstEvent. 409 | //seqnum 410 | //A sequence number. 411 | func (e *Event) SetSeqNum(seqnum uint32) { 412 | C.gst_event_set_seqnum(e.g(), C.guint32(seqnum)) 413 | } 414 | 415 | //Retrieve the accumulated running time offset of the event. 416 | // 417 | //Events passing through GstPads that have a running time offset set via gst_pad_set_offset() will get their offset adjusted according to the pad's offset. 418 | // 419 | //If the event contains any information that related to the running time, this information will need to be updated before usage with this offset. 420 | //Parameters 421 | //event 422 | //A GstEvent. 423 | //Returns 424 | //The event's running time offset 425 | //MT safe. 426 | //Since: 1.4 427 | func (e *Event) GetRunningTimeOffset() int64 { 428 | return int64(C.gst_event_get_running_time_offset(e.g())) 429 | } 430 | 431 | //Set the running time offset of a event. See gst_event_get_running_time_offset() for more information. 432 | //MT safe. 433 | //Parameters 434 | //event 435 | //A GstEvent. 436 | //offset 437 | //A the new running time offset 438 | //Since: 1.4 439 | func (e *Event) SetRunningTimeOffset(offset int64) { 440 | C.gst_event_set_running_time_offset(e.g(), C.gint64(offset)) 441 | } 442 | 443 | //Allocate a new flush start event. The flush start event can be sent upstream and downstream and travels out-of-bounds with the dataflow. 444 | // 445 | //It marks pads as being flushing and will make them return GST_FLOW_FLUSHING when used for data flow with 446 | //gst_pad_push(), gst_pad_chain(), gst_pad_get_range() and gst_pad_pull_range(). 447 | //Any event (except a GST_EVENT_FLUSH_STOP) received on a flushing pad will return FALSE immediately. 448 | // 449 | //Elements should unlock any blocking functions and exit their streaming functions as fast as possible when this event is received. 450 | // 451 | //This event is typically generated after a seek to flush out all queued data in the pipeline so that the new media is played as soon as possible. 452 | //Returns 453 | //a new flush start event. 454 | func NewFlushStartEvent() *Event { 455 | r := new(Event) 456 | r.SetPtr(glib.Pointer(C.gst_event_new_flush_start())) 457 | return r 458 | } 459 | 460 | //Allocate a new flush stop event. The flush stop event can be sent upstream and downstream and travels serialized with the dataflow. 461 | //It is typically sent after sending a FLUSH_START event to make the pads accept data again. 462 | // 463 | //Elements can process this event synchronized with the dataflow since the preceding FLUSH_START event stopped the dataflow. 464 | // 465 | //This event is typically generated to complete a seek and to resume dataflow. 466 | //Parameters 467 | //reset_time 468 | //if time should be reset 469 | //Returns 470 | //a new flush stop event. 471 | func NewFlushStopEvent(reset_time bool) *Event { 472 | r := new(Event) 473 | r.SetPtr(glib.Pointer(C.gst_event_new_flush_stop(gBoolean(reset_time)))) 474 | return r 475 | } 476 | 477 | //Parse the FLUSH_STOP event and retrieve the reset_time member. 478 | //Parameters 479 | //event 480 | //The event to parse 481 | //Return 482 | //reset_time 483 | //if time should be reset. 484 | func (e *Event) ParseFlushStop() bool { 485 | var reset_time C.gboolean 486 | C.gst_event_parse_flush_stop(e.g(), &reset_time) 487 | return reset_time != 0 488 | } 489 | 490 | //Create a new EOS event. The eos event can only travel downstream synchronized with the buffer flow. 491 | //Elements that receive the EOS event on a pad can return GST_FLOW_EOS as a GstFlowReturn when data after the EOS event arrives. 492 | // 493 | //The EOS event will travel down to the sink elements in the pipeline which will then post the GST_MESSAGE_EOS on the bus 494 | //after they have finished playing any buffered data. 495 | // 496 | //When all sinks have posted an EOS message, an EOS message is forwarded to the application. 497 | // 498 | //The EOS event itself will not cause any state transitions of the pipeline. 499 | //Returns 500 | //the new EOS event. 501 | func NewEosEvent() *Event { 502 | r := new(Event) 503 | r.SetPtr(glib.Pointer(C.gst_event_new_eos())) 504 | return r 505 | } 506 | 507 | //Create a new GAP event. 508 | //A gap event can be thought of as conceptually equivalent to a buffer to signal that there is no data for a certain amount of time. 509 | //This is useful to signal a gap to downstream elements which may wait for data, such as muxers or mixers or overlays, 510 | //especially for sparse streams such as subtitle streams. 511 | //Parameters 512 | //timestamp 513 | //the start time (pts) of the gap 514 | //duration 515 | //the duration of the gap 516 | //Returns 517 | //the new GAP event. 518 | func NewGapEvent(timestamp, duration ClockTime) *Event { 519 | r := new(Event) 520 | r.SetPtr(glib.Pointer(C.gst_event_new_gap(C.GstClockTime(timestamp), C.GstClockTime(duration)))) 521 | return r 522 | } 523 | 524 | //Extract timestamp and duration from a new GAP event. 525 | //Parameters 526 | //event 527 | //a GstEvent of type GST_EVENT_GAP 528 | //Return 529 | //timestamp 530 | //location where to store the start time (pts) of the gap, or NULL. 531 | //duration 532 | //location where to store the duration of the gap, or NULL. 533 | func (e *Event) ParseGap() (ClockTime, ClockTime) { 534 | var t, d C.GstClockTime 535 | C.gst_event_parse_gap(e.g(), &t, &d) 536 | return ClockTime(t), ClockTime(d) 537 | } 538 | 539 | //Create a new STREAM_START event. The stream start event can only travel downstream synchronized with the buffer flow. 540 | //It is expected to be the first event that is sent for a new stream. 541 | // 542 | //Source elements, demuxers and other elements that create new streams are supposed to send this event as the first event of a new stream. 543 | //It should not be sent after a flushing seek or in similar situations and is used to mark the beginning of a new logical stream. 544 | //Elements combining multiple streams must ensure that this event is only forwarded downstream once and not for every single input stream. 545 | // 546 | //The stream_id should be a unique string that consists of the upstream stream-id, / as separator and a unique stream-id for this specific stream. 547 | //A new stream-id should only be created for a stream if the upstream stream is split into (potentially) multiple new streams, e.g. 548 | //in a demuxer, but not for every single element in the pipeline. 549 | //gst_pad_create_stream_id() or gst_pad_create_stream_id_printf() can be used to create a stream-id. 550 | //There are no particular semantics for the stream-id, though it should be deterministic (to support stream matching) 551 | //and it might be used to order streams (besides any information conveyed by stream flags). 552 | // 553 | //Parameters 554 | //stream_id 555 | //Identifier for this stream 556 | //Returns 557 | //the new STREAM_START event. 558 | func NewStreamStartEvent(stream_id string) *Event { 559 | s := (*C.gchar)(C.CString(stream_id)) 560 | defer C.free(unsafe.Pointer(s)) 561 | r := new(Event) 562 | r.SetPtr(glib.Pointer(C.gst_event_new_stream_start(s))) 563 | return r 564 | } 565 | 566 | //Parse a stream-id event and store the result in the given stream_id location. 567 | //The string stored in stream_id must not be modified and will remain valid only until event gets freed. 568 | //Make a copy if you want to modify it or store it for later use. 569 | //Parameters 570 | //event 571 | //a stream-start event. 572 | //Return 573 | //stream_id 574 | //pointer to store the stream-id. 575 | func (e *Event) ParseStreamStart() string { 576 | var stream_id *C.gchar 577 | defer C.free(unsafe.Pointer(stream_id)) 578 | C.gst_event_parse_stream_start(e.g(), &stream_id) 579 | return C.GoString((*C.char)(stream_id)) 580 | } 581 | 582 | //Parameters 583 | //event 584 | //a stream-start event 585 | //flags 586 | //the stream flags to set 587 | //Since: 1.2 588 | func (e *Event) SetStreamFlags(flags StreamFlags) { 589 | C.gst_event_set_stream_flags(e.g(), C.GstStreamFlags(flags)) 590 | } 591 | 592 | //Parameters 593 | //event 594 | //a stream-start event 595 | //Return 596 | //flags 597 | //address of variable where to store the stream flags. 598 | //Since: 1.2 599 | func (e *Event) ParseStreamFlags() StreamFlags { 600 | var f C.GstStreamFlags 601 | C.gst_event_parse_stream_flags(e.g(), &f) 602 | return StreamFlags(f) 603 | } 604 | 605 | //All streams that have the same group id are supposed to be played together, 606 | //i.e. all streams inside a container file should have the same group id but different stream ids. 607 | //The group id should change each time the stream is started, resulting in different group ids each time a file is played for example. 608 | // 609 | //Use gst_util_group_id_next() to get a new group id. 610 | //Parameters 611 | //event 612 | //a stream-start event 613 | //group_id 614 | //the group id to set 615 | //Since: 1.2 616 | func (e *Event) SetGroupId(group_id uint) { 617 | C.gst_event_set_group_id(e.g(), C.guint(group_id)) 618 | } 619 | 620 | //Parameters 621 | //event 622 | //a stream-start event 623 | //Returns 624 | //group_id 625 | //address of variable where to store the group id. 626 | //TRUE if a group id was set on the event and could be parsed, FALSE otherwise. 627 | //Since: 1.2 628 | func (e *Event) ParseGroupId() (uint, bool) { 629 | var g C.guint 630 | ret := C.gst_event_parse_group_id(e.g(), &g) 631 | return uint(g), ret != 0 632 | } 633 | 634 | //Create a new SEGMENT event for segment . 635 | //The segment event can only travel downstream synchronized with the buffer flow and contains timing information 636 | //and playback properties for the buffers that will follow. 637 | // 638 | //The segment event marks the range of buffers to be processed. All data not within the segment range is not to be processed. 639 | //This can be used intelligently by plugins to apply more efficient methods of skipping unneeded data. 640 | //The valid range is expressed with the start and stop values. 641 | // 642 | //The time value of the segment is used in conjunction with the start value to convert the buffer timestamps into the stream time. 643 | //This is usually done in sinks to report the current stream_time. 644 | //time represents the stream_time of a buffer carrying a timestamp of start . time cannot be -1. 645 | // 646 | //start cannot be -1, stop can be -1. If there is a valid stop given, it must be greater or equal the start , 647 | //including when the indicated playback rate is < 0. 648 | // 649 | //The applied_rate value provides information about any rate adjustment that has already been made to the timestamps and content on the buffers of the stream. 650 | //(rate * applied_rate ) should always equal the rate that has been requested for playback. 651 | //For example, if an element has an input segment with intended playback rate of 2.0 and applied_rate of 1.0, 652 | //it can adjust incoming timestamps and buffer content by half and output a segment event with rate of 1.0 and applied_rate of 2.0 653 | // 654 | //After a segment event, the buffer stream time is calculated with: 655 | // 656 | //time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate) 657 | //Parameters 658 | //segment 659 | //a GstSegment. 660 | // 661 | //Returns 662 | //the new SEGMENT event. 663 | func NewSegmentEvent(segment *Segment) *Event { 664 | r := new(Event) 665 | r.SetPtr(glib.Pointer(C.gst_event_new_segment(segment.g()))) 666 | return r 667 | } 668 | 669 | //Parses a segment event and stores the result in the given segment location. segment remains valid only until the event is freed. 670 | //Don't modify the segment and make a copy if you want to modify it or store it for later use. 671 | //Parameters 672 | //event 673 | //The event to parse 674 | //Returns 675 | //segment 676 | //a pointer to a GstSegment. 677 | //Need to unref 678 | func (e *Event) ParseSegment() *Segment { 679 | var s *C.GstSegment 680 | C.gst_event_parse_segment(e.g(), &s) 681 | r := new(Segment) 682 | r.SetPtr(glib.Pointer(s)) 683 | return r 684 | } 685 | 686 | //Parses a segment event and copies the GstSegment into the location given by segment . 687 | //Parameters 688 | //event 689 | //The event to parse 690 | //Returns 691 | //segment 692 | //a pointer to a GstSegment 693 | func (e *Event) CopySegment() *Segment { 694 | var s *C.GstSegment 695 | C.gst_event_copy_segment(e.g(), s) 696 | r := new(Segment) 697 | r.SetPtr(glib.Pointer(&s)) 698 | return r 699 | } 700 | 701 | //Generates a metadata tag event from the given taglist . 702 | // 703 | //The scope of the taglist specifies if the taglist applies to the complete medium or only to this specific stream. 704 | //As the tag event is a sticky event, elements should merge tags received from upstream with a given scope with their own tags with the same scope 705 | //and create a new tag event from it. 706 | //Parameters 707 | //taglist 708 | //metadata list. The event will take ownership of the taglist. 709 | //Returns 710 | //a new GstEvent. 711 | func NewTagEvent(taglist *TagList) *Event { 712 | r := new(Event) 713 | r.SetPtr(glib.Pointer(C.gst_event_new_tag(taglist.g()))) 714 | return r 715 | } 716 | 717 | //Parses a tag event and stores the results in the given taglist location. 718 | //No reference to the taglist will be returned, it remains valid only until the event is freed. Don't modify or free the taglist, 719 | //make a copy if you want to modify it or store it for later use. 720 | //Parameters 721 | //event 722 | //a tag event 723 | //Returns 724 | //taglist 725 | //pointer to metadata list. 726 | func (e *Event) ParseTag() *TagList { 727 | var s *C.GstTagList 728 | C.gst_event_parse_tag(e.g(), &s) 729 | r := new(TagList) 730 | r.SetPtr(glib.Pointer(s)) 731 | return r 732 | } 733 | 734 | //Create a new buffersize event. 735 | //The event is sent downstream and notifies elements that they should provide a buffer of the specified dimensions. 736 | //When the async flag is set, a thread boundary is preferred. 737 | //Parameters 738 | //format 739 | //buffer format 740 | //minsize 741 | //minimum buffer size 742 | //maxsize 743 | //maximum buffer size 744 | //async 745 | //thread behavior 746 | //Returns 747 | //a new GstEvent. 748 | func NewBufferSizeEvent(format Format, minsize, maxsize int64, async bool) *Event { 749 | r := new(Event) 750 | r.SetPtr(glib.Pointer(C.gst_event_new_buffer_size(C.GstFormat(format), C.gint64(minsize), C.gint64(maxsize), gBoolean(async)))) 751 | return r 752 | } 753 | 754 | //Get the format, minsize, maxsize and async-flag in the buffersize event. 755 | //Parameters 756 | //event 757 | //The event to query 758 | //Returns 759 | //format 760 | //A pointer to store the format in. 761 | //minsize 762 | //A pointer to store the minsize in. 763 | //maxsize 764 | //A pointer to store the maxsize in. 765 | //async 766 | //A pointer to store the async-flag in. 767 | func (e *Event) ParseBufferSize() (Format, int64, int64, bool) { 768 | var format C.GstFormat 769 | var minsize, maxsize C.gint64 770 | var async C.gboolean 771 | C.gst_event_parse_buffer_size(e.g(), &format, &minsize, &maxsize, &async) 772 | return Format(format), int64(minsize), int64(maxsize), async != 0 773 | } 774 | 775 | //Allocate a new qos event with the given values. 776 | //The QOS event is generated in an element that wants an upstream element to either reduce or increase its rate 777 | //because of high/low CPU load or other resource usage such as network performance or throttling. 778 | //Typically sinks generate these events for each buffer they receive. 779 | // 780 | //type indicates the reason for the QoS event. 781 | //GST_QOS_TYPE_OVERFLOW is used when a buffer arrived in time or when the sink cannot keep up with the upstream datarate. 782 | //GST_QOS_TYPE_UNDERFLOW is when the sink is not receiving buffers fast enough and thus has to drop late buffers. 783 | //GST_QOS_TYPE_THROTTLE is used when the datarate is artificially limited by the application, for example to reduce power consumption. 784 | // 785 | //proportion indicates the real-time performance of the streaming in the element that generated the QoS event (usually the sink). 786 | //The value is generally computed based on more long term statistics about the streams timestamps compared to the clock. 787 | //A value < 1.0 indicates that the upstream element is producing data faster than real-time. 788 | //A value > 1.0 indicates that the upstream element is not producing data fast enough. 1.0 is the ideal proportion value. 789 | //The proportion value can safely be used to lower or increase the quality of the element. 790 | // 791 | //diff is the difference against the clock in running time of the last buffer that caused the element to generate the QOS event. 792 | //A negative value means that the buffer with timestamp arrived in time. 793 | //A positive value indicates how late the buffer with timestamp was. 794 | //When throttling is enabled, diff will be set to the requested throttling interval. 795 | // 796 | //timestamp is the timestamp of the last buffer that cause the element to generate the QOS event. 797 | //It is expressed in running time and thus an ever increasing value. 798 | // 799 | //The upstream element can use the diff and timestamp values to decide whether to process more buffers. 800 | //For positive diff , all buffers with timestamp <= timestamp + diff will certainly arrive late in the sink as well. 801 | //A (negative) diff value so that timestamp + diff would yield a result smaller than 0 is not allowed. 802 | // 803 | //The application can use general event probes to intercept the QoS event and implement custom application specific QoS handling. 804 | //Parameters 805 | //type 806 | //the QoS type 807 | //proportion 808 | //the proportion of the qos message 809 | //diff 810 | //The time difference of the last Clock sync 811 | //timestamp 812 | //The timestamp of the buffer 813 | //Returns 814 | //a new QOS event. 815 | func NewQOSEvent(tp QOSType, proportion float64, diff int64, timestamp ClockTime) *Event { 816 | r := new(Event) 817 | r.SetPtr(glib.Pointer(C.gst_event_new_qos(C.GstQOSType(tp), C.gdouble(proportion), C.GstClockTimeDiff(diff), C.GstClockTime(timestamp)))) 818 | return r 819 | } 820 | 821 | //Get the type, proportion, diff and timestamp in the qos event. See gst_event_new_qos() for more information about the different QoS values. 822 | //timestamp will be adjusted for any pad offsets of pads it was passing through. 823 | //Parameters 824 | //event 825 | //The event to query 826 | //Return 827 | //type 828 | //A pointer to store the QoS type in. 829 | //proportion 830 | //A pointer to store the proportion in. 831 | //diff 832 | //A pointer to store the diff in. 833 | //timestamp 834 | //A pointer to store the timestamp in. 835 | func (e *Event) ParseQOS() (QOSType, float64, int64, ClockTime) { 836 | var tp C.GstQOSType 837 | var proportion C.gdouble 838 | var diff C.GstClockTimeDiff 839 | var timestamp C.GstClockTime 840 | C.gst_event_parse_qos(e.g(), &tp, &proportion, &diff, ×tamp) 841 | return QOSType(tp), float64(proportion), int64(diff), ClockTime(timestamp) 842 | } 843 | 844 | //Allocate a new seek event with the given parameters. 845 | // 846 | //The seek event configures playback of the pipeline between start to stop at the speed given in rate , also called a playback segment. 847 | //The start and stop values are expressed in format . 848 | // 849 | //A rate of 1.0 means normal playback rate, 2.0 means double speed. Negatives values means backwards playback. 850 | //A value of 0.0 for the rate is not allowed and should be accomplished instead by PAUSING the pipeline. 851 | // 852 | //A pipeline has a default playback segment configured with a start position of 0, a stop position of -1 and a rate of 1.0. 853 | //The currently configured playback segment can be queried with GST_QUERY_SEGMENT. 854 | // 855 | //start_type and stop_type specify how to adjust the currently configured start and stop fields in playback segment. 856 | //Adjustments can be made relative or absolute to the last configured values. A type of GST_SEEK_TYPE_NONE means that the position should not be updated. 857 | // 858 | //When the rate is positive and start has been updated, playback will start from the newly configured start position. 859 | // 860 | //For negative rates, playback will start from the newly configured stop position (if any). 861 | //If the stop position is updated, it must be different from -1 (GST_CLOCK_TIME_NONE) for negative rates. 862 | // 863 | //It is not possible to seek relative to the current playback position, to do this, PAUSE the pipeline, 864 | //query the current playback position with GST_QUERY_POSITION and update the playback segment current position with a GST_SEEK_TYPE_SET to the desired position. 865 | //Parameters 866 | //rate 867 | //The new playback rate 868 | //format 869 | //The format of the seek values 870 | //flags 871 | //The optional seek flags 872 | //start_type 873 | //The type and flags for the new start position 874 | //start 875 | //The value of the new start position 876 | //stop_type 877 | //The type and flags for the new stop position 878 | //stop 879 | //The value of the new stop position 880 | //Returns 881 | //a new seek event. 882 | func NewSeekEvent(rate float64, format Format, flags SeekFlags, start_type SeekType, start int64, stop_type SeekType, stop int64) *Event { 883 | e := C.gst_event_new_seek(C.gdouble(rate), C.GstFormat(format), flags.g(), C.GstSeekType(start_type), C.gint64(start), C.GstSeekType(stop_type), C.gint64(stop)) 884 | if e == nil { 885 | return nil 886 | } 887 | r := new(Event) 888 | r.SetPtr(glib.Pointer(e)) 889 | return r 890 | } 891 | 892 | //Parses a seek event and stores the results in the given result locations. 893 | //Parameters 894 | //event 895 | //a seek event 896 | //Returns 897 | //rate 898 | //result location for the rate. 899 | //format 900 | //result location for the stream format. 901 | //flags 902 | //result location for the GstSeekFlags. 903 | //start_type 904 | //result location for the GstSeekType of the start position. 905 | //start 906 | //result location for the start position expressed in format . 907 | //stop_type 908 | //result location for the GstSeekType of the stop position. 909 | //stop 910 | //result location for the stop position expressed in format . 911 | func (e *Event) ParseSeek() (float64, Format, SeekFlags, SeekType, int64, SeekType, int64) { 912 | var rate C.gdouble 913 | var format C.GstFormat 914 | var flags C.GstSeekFlags 915 | var start_type, stop_type C.GstSeekType 916 | var start, stop C.gint64 917 | C.gst_event_parse_seek(e.g(), &rate, &format, &flags, &start_type, &start, &stop_type, &stop) 918 | return float64(rate), Format(format), SeekFlags(flags), SeekType(start_type), int64(start), SeekType(stop_type), int64(stop) 919 | } 920 | 921 | //Create a new navigation event from the given description. 922 | //Parameters 923 | //structure 924 | //description of the event. The event will take ownership of the structure. 925 | // 926 | //Returns 927 | //a new GstEvent. 928 | func NewNavigationEvent(structure *Structure) *Event { 929 | e := C.gst_event_new_navigation(structure.g()) 930 | if e == nil { 931 | return nil 932 | } 933 | r := new(Event) 934 | r.SetPtr(glib.Pointer(e)) 935 | return r 936 | } 937 | 938 | //Create a new latency event. 939 | //The event is sent upstream from the sinks and notifies elements that they should add an additional latency 940 | //to the running time before synchronising against the clock. 941 | // 942 | //The latency is mostly used in live sinks and is always expressed in the time format. 943 | //Parameters 944 | //latency 945 | //the new latency value 946 | //Returns 947 | //a new GstEvent. 948 | func NewLatencyEvent(latency ClockTime) *Event { 949 | e := C.gst_event_new_latency(C.GstClockTime(latency)) 950 | if e == nil { 951 | return nil 952 | } 953 | r := new(Event) 954 | r.SetPtr(glib.Pointer(e)) 955 | return r 956 | } 957 | 958 | //Get the latency in the latency event. 959 | //Parameters 960 | //event 961 | //The event to query 962 | //Returns 963 | //latency 964 | //A pointer to store the latency in. 965 | func (e *Event) ParseLatency() ClockTime { 966 | var latency C.GstClockTime 967 | C.gst_event_parse_latency(e.g(), &latency) 968 | return ClockTime(latency) 969 | } 970 | 971 | //Create a new step event. The purpose of the step event is to instruct a sink to skip amount (expressed in format ) of media. 972 | //It can be used to implement stepping through the video frame by frame or for doing fast trick modes. 973 | // 974 | //A rate of <= 0.0 is not allowed. 975 | //Pause the pipeline, for the effect of rate = 0.0 or first reverse the direction of playback using a seek event to get the same effect as rate < 0.0. 976 | // 977 | //The flush flag will clear any pending data in the pipeline before starting the step operation. 978 | // 979 | //The intermediate flag instructs the pipeline that this step operation is part of a larger step operation. 980 | //Parameters 981 | //format 982 | //the format of amount 983 | //amount 984 | //the amount of data to step 985 | //rate 986 | //the step rate 987 | //flush 988 | //flushing steps 989 | //intermediate 990 | //intermediate steps 991 | //Returns 992 | //a new GstEvent. 993 | func NewStepEvent(format Format, amount uint64, rate float64, flush bool, intermediate bool) *Event { 994 | e := C.gst_event_new_step(C.GstFormat(format), C.guint64(amount), C.gdouble(rate), gBoolean(flush), gBoolean(intermediate)) 995 | if e == nil { 996 | return nil 997 | } 998 | r := new(Event) 999 | r.SetPtr(glib.Pointer(e)) 1000 | return r 1001 | } 1002 | 1003 | //Parse the step event. 1004 | //Parameters 1005 | //event 1006 | //The event to query 1007 | //Returns 1008 | //format 1009 | //a pointer to store the format in. 1010 | //amount 1011 | //a pointer to store the amount in. 1012 | //rate 1013 | //a pointer to store the rate in. 1014 | //flush 1015 | //a pointer to store the flush boolean in. 1016 | //intermediate 1017 | //a pointer to store the intermediate boolean in. 1018 | func (e *Event) ParseStep() (Format, uint64, float64, bool, bool) { 1019 | var format C.GstFormat 1020 | var amount C.guint64 1021 | var rate C.gdouble 1022 | var flush, intermediate C.gboolean 1023 | C.gst_event_parse_step(e.g(), &format, &amount, &rate, &flush, &intermediate) 1024 | return Format(format), uint64(amount), float64(rate), flush != 0, intermediate != 0 1025 | } 1026 | 1027 | //Create a new sink-message event. 1028 | //The purpose of the sink-message event is to instruct a sink to post the message contained in the event synchronized with the stream. 1029 | // 1030 | //name is used to store multiple sticky events on one pad. 1031 | //Parameters 1032 | //name 1033 | //a name for the event 1034 | //msg 1035 | //the GstMessage to be posted. 1036 | //Returns 1037 | //a new GstEvent. 1038 | func NewSinkMessageEvent(name string, msg *Message) *Event { 1039 | s := (*C.gchar)(C.CString(name)) 1040 | defer C.free(unsafe.Pointer(s)) 1041 | e := C.gst_event_new_sink_message(s, msg.g()) 1042 | if e == nil { 1043 | return nil 1044 | } 1045 | r := new(Event) 1046 | r.SetPtr(glib.Pointer(e)) 1047 | return r 1048 | } 1049 | 1050 | //Parse the sink-message event. Unref msg after usage. 1051 | //Parameters 1052 | //event 1053 | //The event to query 1054 | //Returns 1055 | //msg 1056 | //a pointer to store the GstMessage in. 1057 | func (e *Event) ParseSinkMessage() *Message { 1058 | var msg *C.GstMessage 1059 | C.gst_event_parse_sink_message(e.g(), &msg) 1060 | r := new(Message) 1061 | r.SetPtr(glib.Pointer(msg)) 1062 | return r 1063 | } 1064 | 1065 | //Create a new reconfigure event. 1066 | //The purpose of the reconfigure event is to travel upstream and make elements renegotiate their caps or reconfigure their buffer pools. 1067 | //This is useful when changing properties on elements or changing the topology of the pipeline. 1068 | //Returns 1069 | //a new GstEvent. 1070 | func NewReconfigureEvent() *Event { 1071 | e := C.gst_event_new_reconfigure() 1072 | if e == nil { 1073 | return nil 1074 | } 1075 | r := new(Event) 1076 | r.SetPtr(glib.Pointer(e)) 1077 | return r 1078 | } 1079 | 1080 | //Create a new CAPS event for caps . 1081 | //The caps event can only travel downstream synchronized with the buffer flow and contains the format of the buffers that will follow after the event. 1082 | //Parameters 1083 | //caps 1084 | //a GstCaps. 1085 | //Returns 1086 | //the new CAPS event. 1087 | func NewCapsEvent(caps *Caps) *Event { 1088 | e := C.gst_event_new_caps(caps.g()) 1089 | if e == nil { 1090 | return nil 1091 | } 1092 | r := new(Event) 1093 | r.SetPtr(glib.Pointer(e)) 1094 | return r 1095 | } 1096 | 1097 | //Get the caps from event . The caps remains valid as long as event remains valid. 1098 | //Parameters 1099 | //event 1100 | //The event to parse 1101 | //Returns 1102 | //caps 1103 | //A pointer to the caps. 1104 | func (e *Event) ParseCaps() *Caps { 1105 | var caps *C.GstCaps 1106 | C.gst_event_parse_caps(e.g(), &caps) 1107 | r := new(Caps) 1108 | r.SetPtr(glib.Pointer(caps)) 1109 | return r 1110 | } 1111 | 1112 | //Generate a TOC event from the given toc . 1113 | //The purpose of the TOC event is to inform elements that some kind of the TOC was found. 1114 | //Parameters 1115 | //toc 1116 | //GstToc structure. 1117 | //updated 1118 | //whether toc was updated or not. 1119 | //Returns 1120 | //a new GstEvent. 1121 | func NewTOCEvent(toc *Toc, updated bool) *Event { 1122 | e := C.gst_event_new_toc(toc.g(), gBoolean(updated)) 1123 | if e == nil { 1124 | return nil 1125 | } 1126 | r := new(Event) 1127 | r.SetPtr(glib.Pointer(e)) 1128 | return r 1129 | } 1130 | 1131 | //Parse a TOC event and store the results in the given toc and updated locations. 1132 | //Parameters 1133 | //event 1134 | //a TOC event. 1135 | //Return 1136 | //toc 1137 | //pointer to GstToc structure. 1138 | //updated 1139 | //pointer to store TOC updated flag. 1140 | func (e *Event) ParseTOC() (*Toc, bool) { 1141 | var toc *C.GstToc 1142 | var updated C.gboolean 1143 | C.gst_event_parse_toc(e.g(), &toc, &updated) 1144 | r := new(Toc) 1145 | r.SetPtr(glib.Pointer(toc)) 1146 | return r, updated != 0 1147 | } 1148 | 1149 | //Generate a TOC select event with the given uid . T 1150 | //he purpose of the TOC select event is to start playback based on the TOC's entry with the given uid . 1151 | //Parameters 1152 | //uid 1153 | //UID in the TOC to start playback from. 1154 | //Returns 1155 | //a new GstEvent. 1156 | func NewTOCSelectEvent(uid string) *Event { 1157 | s := (*C.gchar)(C.CString(uid)) 1158 | defer C.free(unsafe.Pointer(s)) 1159 | e := C.gst_event_new_toc_select(s) 1160 | if e == nil { 1161 | return nil 1162 | } 1163 | r := new(Event) 1164 | r.SetPtr(glib.Pointer(e)) 1165 | return r 1166 | } 1167 | 1168 | //Parse a TOC select event and store the results in the given uid location. 1169 | //Parameters 1170 | //event 1171 | //a TOC select event. 1172 | //Returns 1173 | //uid 1174 | //storage for the selection UID. 1175 | func (e *Event) ParseTOCSelect() string { 1176 | var uid *C.gchar 1177 | defer C.free(unsafe.Pointer(uid)) 1178 | C.gst_event_parse_toc_select(e.g(), &uid) 1179 | return C.GoString((*C.char)(uid)) 1180 | } 1181 | 1182 | //Create a new segment-done event. 1183 | //This event is sent by elements that finish playback of a segment as a result of a segment seek. 1184 | //Parameters 1185 | //format 1186 | //The format of the position being done 1187 | //position 1188 | //The position of the segment being done 1189 | //Returns 1190 | //a new GstEvent. 1191 | func NewSegmentDoneEvent(format Format, position int64) *Event { 1192 | e := C.gst_event_new_segment_done(C.GstFormat(format), C.gint64(position)) 1193 | if e == nil { 1194 | return nil 1195 | } 1196 | r := new(Event) 1197 | r.SetPtr(glib.Pointer(e)) 1198 | return r 1199 | } 1200 | 1201 | //Extracts the position and format from the segment done message. 1202 | //Parameters 1203 | //event 1204 | //A valid GstEvent of type GST_EVENT_SEGMENT_DONE. 1205 | //Returns 1206 | //format 1207 | //Result location for the format, or NULL. 1208 | //position 1209 | //Result location for the position, or NULL. 1210 | func (e *Event) ParseSegmentDone() (Format, int64) { 1211 | var format C.GstFormat 1212 | var position C.gint64 1213 | C.gst_event_parse_segment_done(e.g(), &format, &position) 1214 | return Format(format), int64(position) 1215 | } 1216 | 1217 | //Creates a new event containing information specific to a particular protection system (uniquely identified by system_id ), 1218 | //by which that protection system can acquire key(s) to decrypt a protected stream. 1219 | // 1220 | //In order for a decryption element to decrypt media protected using a specific system, 1221 | //it first needs all the protection system specific information necessary to acquire the decryption key(s) for that stream. 1222 | //The functions defined here enable this information to be passed in events from elements 1223 | //that extract it (e.g., ISOBMFF demuxers, MPEG DASH demuxers) to protection decrypter elements that use it. 1224 | // 1225 | //Events containing protection system specific information are created using gst_event_new_protection, 1226 | //and they can be parsed by downstream elements using gst_event_parse_protection. 1227 | // 1228 | //In Common Encryption, protection system specific information may be located within ISOBMFF files, 1229 | //both in movie (moov) boxes and movie fragment (moof) boxes; it may also be contained in ContentProtection elements within MPEG DASH MPDs. 1230 | //The events created by gst_event_new_protection contain data identifying from which of these locations 1231 | //the encapsulated protection system specific information originated. 1232 | //This origin information is required as some protection systems use different encodings depending upon where the information originates. 1233 | // 1234 | //The events returned by gst_event_new_protection() are implemented in such a way as to ensure 1235 | //that the most recently-pushed protection info event of a particular origin and system_id will be stuck to the output pad of the sending element. 1236 | //Parameters 1237 | //system_id 1238 | //a string holding a UUID that uniquely identifies a protection system. 1239 | //data 1240 | //a GstBuffer holding protection system specific information. The reference count of the buffer will be incremented by one. 1241 | //origin 1242 | //a string indicating where the protection information carried in the event was extracted from. 1243 | //The allowed values of this string will depend upon the protection scheme. 1244 | //Returns 1245 | //a GST_EVENT_PROTECTION event, if successful; NULL if unsuccessful. 1246 | //Since: 1.6 1247 | func NewProtectionEvent(system_id string, data *Buffer, origin string) *Event { 1248 | s1 := (*C.gchar)(C.CString(system_id)) 1249 | defer C.free(unsafe.Pointer(s1)) 1250 | s2 := (*C.gchar)(C.CString(origin)) 1251 | defer C.free(unsafe.Pointer(s2)) 1252 | e := C.gst_event_new_protection(s1, data.g(), s2) 1253 | if e == nil { 1254 | return nil 1255 | } 1256 | r := new(Event) 1257 | r.SetPtr(glib.Pointer(e)) 1258 | return r 1259 | } 1260 | 1261 | //Parses an event containing protection system specific information and stores the results in system_id , data and origin . 1262 | //The data stored in system_id , origin and data are valid until event is released. 1263 | //Parameters 1264 | //event 1265 | //a GST_EVENT_PROTECTION event. 1266 | //Returns 1267 | //system_id 1268 | //pointer to store the UUID string uniquely identifying a content protection system. 1269 | //data 1270 | //pointer to store a GstBuffer holding protection system specific information. 1271 | //origin 1272 | //pointer to store a value that indicates where the protection information carried by event was extracted from. 1273 | //Since: 1.6 1274 | func (e *Event) ParseProtection() (string, *Buffer, string) { 1275 | var system_id, origin *C.gchar 1276 | defer C.free(unsafe.Pointer(system_id)) 1277 | defer C.free(unsafe.Pointer(origin)) 1278 | var data *C.GstBuffer 1279 | C.gst_event_parse_protection(e.g(), &system_id, &data, &origin) 1280 | r := new(Buffer) 1281 | r.SetPtr(glib.Pointer(data)) 1282 | return C.GoString((*C.char)(system_id)), r, C.GoString((*C.char)(origin)) 1283 | } 1284 | -------------------------------------------------------------------------------- /event.md: -------------------------------------------------------------------------------- 1 | **progress** 2 | 66/69 3 | ``` 4 | Y #define GST_EVENT_MAKE_TYPE() 5 | Y #define GST_EVENT_TYPE() 6 | Y #define GST_EVENT_TYPE_NAME() 7 | Y #define GST_EVENT_TIMESTAMP() 8 | Y #define GST_EVENT_SEQNUM() 9 | Y #define GST_EVENT_IS_UPSTREAM() 10 | Y #define GST_EVENT_IS_DOWNSTREAM() 11 | Y #define GST_EVENT_IS_SERIALIZED() 12 | Y #define GST_EVENT_IS_STICKY() 13 | Y GstEventTypeFlags gst_event_type_get_flags () 14 | Y const gchar * gst_event_type_get_name () 15 | Y GQuark gst_event_type_to_quark () 16 | Y GstEvent * gst_event_ref () 17 | Y void gst_event_unref () 18 | gboolean gst_event_replace () 19 | Y GstEvent * gst_event_copy () 20 | GstEvent * gst_event_steal () 21 | gboolean gst_event_take () 22 | Y #define gst_event_is_writable() 23 | Y #define gst_event_make_writable() 24 | Y GstStructure * gst_event_writable_structure () 25 | Y GstEvent * gst_event_new_custom () 26 | Y const GstStructure * gst_event_get_structure () 27 | Y gboolean gst_event_has_name () 28 | Y guint32 gst_event_get_seqnum () 29 | Y void gst_event_set_seqnum () 30 | Y gint64 gst_event_get_running_time_offset () 31 | Y void gst_event_set_running_time_offset () 32 | Y GstEvent * gst_event_new_flush_start () 33 | Y GstEvent * gst_event_new_flush_stop () 34 | Y void gst_event_parse_flush_stop () 35 | Y GstEvent * gst_event_new_eos () 36 | Y GstEvent * gst_event_new_gap () 37 | Y void gst_event_parse_gap () 38 | Y GstEvent * gst_event_new_stream_start () 39 | Y void gst_event_parse_stream_start () 40 | Y void gst_event_set_stream_flags () 41 | Y void gst_event_parse_stream_flags () 42 | Y void gst_event_set_group_id () 43 | Y gboolean gst_event_parse_group_id () 44 | Y GstEvent * gst_event_new_segment () 45 | Y void gst_event_parse_segment () 46 | Y void gst_event_copy_segment () 47 | Y GstEvent * gst_event_new_tag () 48 | Y void gst_event_parse_tag () 49 | Y GstEvent * gst_event_new_buffer_size () 50 | Y void gst_event_parse_buffer_size () 51 | Y GstEvent * gst_event_new_qos () 52 | Y void gst_event_parse_qos () 53 | Y GstEvent * gst_event_new_seek () 54 | Y void gst_event_parse_seek () 55 | Y GstEvent * gst_event_new_navigation () 56 | Y GstEvent * gst_event_new_latency () 57 | Y void gst_event_parse_latency () 58 | Y GstEvent * gst_event_new_step () 59 | Y void gst_event_parse_step () 60 | Y GstEvent * gst_event_new_sink_message () 61 | Y void gst_event_parse_sink_message () 62 | Y GstEvent * gst_event_new_reconfigure () 63 | Y GstEvent * gst_event_new_caps () 64 | Y void gst_event_parse_caps () 65 | Y GstEvent * gst_event_new_toc () 66 | Y void gst_event_parse_toc () 67 | Y GstEvent * gst_event_new_toc_select () 68 | Y void gst_event_parse_toc_select () 69 | Y GstEvent * gst_event_new_segment_done () 70 | Y void gst_event_parse_segment_done () 71 | Y GstEvent * gst_event_new_protection () 72 | Y void gst_event_parse_protection () 73 | ``` -------------------------------------------------------------------------------- /examples/dynamic_pads.go: -------------------------------------------------------------------------------- 1 | // This simple test application create live H264 (or WebM - see commented lines) 2 | // content from test source, decode it and display. 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/ziutek/glib" 10 | "github.com/ziutek/gst" 11 | ) 12 | 13 | func checkElem(e *gst.Element, name string) { 14 | if e == nil { 15 | fmt.Fprintln(os.Stderr, "can't make element: ", name) 16 | os.Exit(1) 17 | } 18 | } 19 | 20 | func main() { 21 | src := gst.ElementFactoryMake("videotestsrc", "Test source") 22 | checkElem(src, "videotestsrc") 23 | src.SetProperty("do-timestamp", true) 24 | src.SetProperty("pattern", 18) // ball 25 | 26 | encType := "mpeg2enc" 27 | //encType := "x264enc" 28 | enc := gst.ElementFactoryMake(encType, "Video encoder") 29 | checkElem(enc, encType) 30 | 31 | //muxType := "webmux" 32 | muxType := "matroskamux" 33 | mux := gst.ElementFactoryMake(muxType, "Muxer") 34 | checkElem(mux, muxType) 35 | mux.SetProperty("streamable", true) 36 | 37 | demux := gst.ElementFactoryMake("matroskademux", "Matroska demuxer") 38 | checkElem(demux, "matroskademux") 39 | 40 | decType := "mpeg2dec" 41 | //decType := "avdec_h264" 42 | dec := gst.ElementFactoryMake(decType, "Video decoder") 43 | checkElem(dec, decType) 44 | 45 | sink := gst.ElementFactoryMake("autovideosink", "Video display element") 46 | checkElem(sink, "autovideosink") 47 | 48 | pl := gst.NewPipeline("MyPipeline") 49 | 50 | pl.Add(src, enc, mux, demux, dec, sink) 51 | 52 | src.Link(enc, mux, demux) 53 | demux.ConnectNoi("pad-added", cbPadAdded, dec.GetStaticPad("sink")) 54 | dec.Link(sink) 55 | pl.SetState(gst.STATE_PLAYING) 56 | 57 | glib.NewMainLoop(nil).Run() 58 | } 59 | 60 | // Callback function for "pad-added" event 61 | func cbPadAdded(dec_sink_pad, demux_new_pad *gst.Pad) { 62 | fmt.Println("New pad:", demux_new_pad.GetName()) 63 | if demux_new_pad.CanLink(dec_sink_pad) { 64 | if demux_new_pad.Link(dec_sink_pad) != gst.PAD_LINK_OK { 65 | fmt.Fprintln(os.Stderr, "link error") 66 | } 67 | } else { 68 | fmt.Fprintln(os.Stderr, "can't link it with:", dec_sink_pad.GetName()) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /examples/images/logo-153x55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lidouf/gst/3d2545f6f76b79baec22efe4eaa85f977b3a1e54/examples/images/logo-153x55.png -------------------------------------------------------------------------------- /examples/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lidouf/gst/3d2545f6f76b79baec22efe4eaa85f977b3a1e54/examples/images/logo.png -------------------------------------------------------------------------------- /examples/live_webm.go: -------------------------------------------------------------------------------- 1 | // This simple test application serve live generated WebM content on webpage 2 | // using HTML5