mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-04 07:36:41 +08:00
171 lines
5.3 KiB
Go
171 lines
5.3 KiB
Go
package gst
|
|
|
|
// #include "gst.go.h"
|
|
import "C"
|
|
|
|
import (
|
|
"fmt"
|
|
"unsafe"
|
|
|
|
"github.com/gotk3/gotk3/glib"
|
|
)
|
|
|
|
// Element is a Go wrapper around a GstElement.
|
|
type Element struct{ *Object }
|
|
|
|
// ElementLinkMany is a go implementation of `gst_element_link_many` to compensate for
|
|
// no variadic functions in cgo.
|
|
func ElementLinkMany(elems ...*Element) error {
|
|
for idx, elem := range elems {
|
|
if idx == 0 {
|
|
// skip the first one as the loop always links previous to current
|
|
continue
|
|
}
|
|
if err := elems[idx-1].Link(elem); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Instance returns the underlying GstElement instance.
|
|
func (e *Element) Instance() *C.GstElement { return C.toGstElement(e.unsafe()) }
|
|
|
|
// Link wraps gst_element_link and links this element to the given one.
|
|
func (e *Element) Link(elem *Element) error {
|
|
if ok := C.gst_element_link((*C.GstElement)(e.Instance()), (*C.GstElement)(elem.Instance())); !gobool(ok) {
|
|
return fmt.Errorf("Failed to link %s to %s", e.Name(), elem.Name())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// LinkFiltered wraps gst_element_link_filtered and link this element to the given one
|
|
// using the provided sink caps.
|
|
func (e *Element) LinkFiltered(elem *Element, caps *Caps) error {
|
|
if ok := C.gst_element_link_filtered((*C.GstElement)(e.Instance()), (*C.GstElement)(elem.Instance()), (*C.GstCaps)(caps.Instance())); !gobool(ok) {
|
|
return fmt.Errorf("Failed to link %s to %s with provider caps", e.Name(), elem.Name())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetBus returns the GstBus for retrieving messages from this element. This function returns
|
|
// nil unless the element is a Pipeline.
|
|
func (e *Element) GetBus() *Bus {
|
|
bus := C.gst_element_get_bus((*C.GstElement)(e.Instance()))
|
|
if bus == nil {
|
|
return nil
|
|
}
|
|
return wrapBus(glib.Take(unsafe.Pointer(bus)))
|
|
}
|
|
|
|
// GetClock returns the Clock for this element. This is the clock as was last set with gst_element_set_clock.
|
|
// Elements in a pipeline will only have their clock set when the pipeline is in the PLAYING state.
|
|
func (e *Element) GetClock() *Clock {
|
|
cClock := C.gst_element_get_clock((*C.GstElement)(e.Instance()))
|
|
if cClock == nil {
|
|
return nil
|
|
}
|
|
return wrapClock(glib.Take(unsafe.Pointer(cClock)))
|
|
}
|
|
|
|
// GetState returns the current state of this element.
|
|
func (e *Element) GetState() State {
|
|
return State(e.Instance().current_state)
|
|
}
|
|
|
|
// SetState sets the target state for this element.
|
|
func (e *Element) SetState(state State) error {
|
|
stateRet := C.gst_element_set_state((*C.GstElement)(e.Instance()), C.GstState(state))
|
|
if stateRet == C.GST_STATE_CHANGE_FAILURE {
|
|
return fmt.Errorf("Failed to change state to %s", state.String())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BlockSetState is like SetState except it will block until the transition
|
|
// is complete.
|
|
func (e *Element) BlockSetState(state State) error {
|
|
stateRet := C.gst_element_set_state((*C.GstElement)(e.Instance()), C.GST_STATE_PLAYING)
|
|
if stateRet == C.GST_STATE_CHANGE_FAILURE {
|
|
return fmt.Errorf("Failed to change state to %s", state.String())
|
|
}
|
|
var curState C.GstState
|
|
C.gst_element_get_state(
|
|
(*C.GstElement)(e.Instance()),
|
|
(*C.GstState)(unsafe.Pointer(&curState)),
|
|
(*C.GstState)(unsafe.Pointer(&state)),
|
|
C.GST_CLOCK_TIME_NONE,
|
|
)
|
|
return nil
|
|
}
|
|
|
|
// GetFactory returns the factory that created this element. No refcounting is needed.
|
|
func (e *Element) GetFactory() *ElementFactory {
|
|
factory := C.gst_element_get_factory((*C.GstElement)(e.Instance()))
|
|
if factory == nil {
|
|
return nil
|
|
}
|
|
return wrapElementFactory(glib.Take(unsafe.Pointer(factory)))
|
|
}
|
|
|
|
// GetPads retrieves a list of pads associated with the element.
|
|
func (e *Element) GetPads() []*Pad {
|
|
goList := glib.WrapList(uintptr(unsafe.Pointer(e.Instance().pads)))
|
|
out := make([]*Pad, 0)
|
|
goList.Foreach(func(item interface{}) {
|
|
pt := item.(unsafe.Pointer)
|
|
out = append(out, wrapPad(glib.Take(pt)))
|
|
})
|
|
return out
|
|
}
|
|
|
|
// GetPadTemplates retrieves a list of the pad templates associated with this element.
|
|
// The list must not be modified by the calling code.
|
|
func (e *Element) GetPadTemplates() []*PadTemplate {
|
|
glist := C.gst_element_get_pad_template_list((*C.GstElement)(e.Instance()))
|
|
if glist == nil {
|
|
return nil
|
|
}
|
|
goList := glib.WrapList(uintptr(unsafe.Pointer(glist)))
|
|
out := make([]*PadTemplate, 0)
|
|
goList.Foreach(func(item interface{}) {
|
|
pt := item.(unsafe.Pointer)
|
|
out = append(out, wrapPadTemplate(glib.Take(pt)))
|
|
})
|
|
return out
|
|
}
|
|
|
|
// Has returns true if this element has the given flags.
|
|
func (e *Element) Has(flags ElementFlags) bool {
|
|
return gobool(C.gstObjectFlagIsSet(C.toGstObject(e.unsafe()), C.GstElementFlags(flags)))
|
|
}
|
|
|
|
// IsURIHandler returns true if this element can handle URIs.
|
|
func (e *Element) IsURIHandler() bool {
|
|
return gobool(C.gstElementIsURIHandler(e.Instance()))
|
|
}
|
|
|
|
func (e *Element) uriHandler() *C.GstURIHandler { return C.toGstURIHandler(e.unsafe()) }
|
|
|
|
// GetURIType returns the type of URI this element can handle.
|
|
func (e *Element) GetURIType() URIType {
|
|
if !e.IsURIHandler() {
|
|
return URIUnknown
|
|
}
|
|
ty := C.gst_uri_handler_get_uri_type((*C.GstURIHandler)(e.uriHandler()))
|
|
return URIType(ty)
|
|
}
|
|
|
|
// GetURIProtocols returns the protocols this element can handle.
|
|
func (e *Element) GetURIProtocols() []string {
|
|
if !e.IsURIHandler() {
|
|
return nil
|
|
}
|
|
protocols := C.gst_uri_handler_get_protocols((*C.GstURIHandler)(e.uriHandler()))
|
|
if protocols == nil {
|
|
return nil
|
|
}
|
|
size := C.sizeOfGCharArray(protocols)
|
|
return goStrings(size, protocols)
|
|
}
|