mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-05 16:06:55 +08:00
305 lines
6.7 KiB
Go
305 lines
6.7 KiB
Go
// Inspect is a simplified version of gst-inspect-<version>. It parses
|
|
// the name of a plugin on the command line and dumps the element's properties
|
|
// to stdout.
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"text/tabwriter"
|
|
|
|
"github.com/gotk3/gotk3/glib"
|
|
"github.com/tinyzimmer/go-gst/gst"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) == 1 {
|
|
fmt.Println("You must provide an element to inspect")
|
|
os.Exit(1)
|
|
}
|
|
|
|
gst.Init(nil)
|
|
|
|
if err := inspect(os.Args[1]); err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(2)
|
|
}
|
|
}
|
|
|
|
func inspect(name string) error {
|
|
// load the registry
|
|
registry := gst.GetRegistry()
|
|
// get the factory for the element
|
|
factory := gst.Find(name)
|
|
|
|
if factory == nil {
|
|
return fmt.Errorf("Could not get details for factory '%s'", name)
|
|
}
|
|
defer factory.Unref()
|
|
|
|
// assume it's an element for now, can implement more later
|
|
elem, err := gst.NewElement(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer elem.Unref()
|
|
|
|
var maxLevel int
|
|
|
|
// dump info about the element
|
|
|
|
printFactoryDetails(registry, factory)
|
|
printPluginDetails(registry, factory)
|
|
printHierarchy(elem.TypeFromInstance(), 0, &maxLevel)
|
|
printInterfaces(elem)
|
|
printPadTemplates(elem)
|
|
printClockingInfo(elem)
|
|
printURIHandlerInfo(elem)
|
|
printPadInfo(elem)
|
|
printElementPropertiesInfo(elem)
|
|
printSignalInfo(elem)
|
|
printChildrenInfo(elem)
|
|
printPresentList(elem)
|
|
|
|
return nil
|
|
}
|
|
|
|
func printFactoryDetails(registry *gst.Registry, factory *gst.ElementFactory) {
|
|
|
|
// initialize tabwriter
|
|
w := new(tabwriter.Writer)
|
|
buf := new(bytes.Buffer)
|
|
|
|
w.Init(
|
|
buf,
|
|
40, // minwidth
|
|
30, // tabwith
|
|
0, // padding
|
|
' ', // padchar
|
|
0, // flags
|
|
)
|
|
|
|
colorOrange.fprint(w, "Factory Details:\n")
|
|
for _, key := range factory.GetMetadataKeys() {
|
|
colorBlue.fprintfIndent(w, 2, "%s \t ", strings.Title(key))
|
|
colorLightGray.fprint(w, factory.GetMetadata(key))
|
|
colorReset.fprint(w, "\n")
|
|
}
|
|
|
|
w.Flush()
|
|
fmt.Print(buf.String())
|
|
fmt.Println()
|
|
}
|
|
|
|
func printPluginDetails(registry *gst.Registry, factory *gst.ElementFactory) {
|
|
|
|
// initialize tabwriter
|
|
w := new(tabwriter.Writer)
|
|
buf := new(bytes.Buffer)
|
|
|
|
w.Init(
|
|
buf,
|
|
40, // minwidth
|
|
30, // tabwith
|
|
0, // padding
|
|
' ', // padchar
|
|
0, // flags
|
|
)
|
|
|
|
pluginFeature, err := registry.LookupFeature(factory.Name())
|
|
if err != nil {
|
|
return
|
|
}
|
|
plugin := pluginFeature.GetPlugin()
|
|
if plugin == nil {
|
|
return
|
|
}
|
|
|
|
defer pluginFeature.Unref()
|
|
defer plugin.Unref()
|
|
|
|
colorOrange.fprint(w, "Plugin Details:\n")
|
|
|
|
colorBlue.fprintIndent(w, 2, "Name \t ")
|
|
colorLightGray.fprintf(w, "%s\n", pluginFeature.GetPluginName())
|
|
|
|
colorBlue.fprintIndent(w, 2, "Description \t ")
|
|
colorLightGray.fprintf(w, "%s\n", plugin.Description())
|
|
|
|
colorBlue.fprintIndent(w, 2, "Filename \t ")
|
|
colorLightGray.fprintf(w, "%s\n", plugin.Filename())
|
|
|
|
colorBlue.fprintIndent(w, 2, "Version \t ")
|
|
colorLightGray.fprintf(w, "%s\n", plugin.Version())
|
|
|
|
colorBlue.fprintIndent(w, 2, "License \t ")
|
|
colorLightGray.fprintf(w, "%s\n", plugin.License())
|
|
|
|
colorBlue.fprintIndent(w, 2, "Source module \t ")
|
|
colorLightGray.fprintf(w, "%s\n", plugin.Source())
|
|
|
|
colorBlue.fprintIndent(w, 2, "Binary package \t ")
|
|
colorLightGray.fprintf(w, "%s\n", plugin.Package())
|
|
|
|
colorBlue.fprintIndent(w, 2, "Origin URLs \t ")
|
|
colorLightGray.fprintf(w, "%s\n", plugin.Origin())
|
|
|
|
w.Flush()
|
|
fmt.Print(buf.String())
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func printHierarchy(gtype glib.Type, level int, maxLevel *int) {
|
|
parent := gtype.Parent()
|
|
|
|
*maxLevel = *maxLevel + 1
|
|
level++
|
|
|
|
if parent > 0 {
|
|
printHierarchy(parent, level, maxLevel)
|
|
}
|
|
|
|
for i := 1; i < *maxLevel-level; i++ {
|
|
colorReset.print(" ")
|
|
}
|
|
|
|
if *maxLevel-level > 0 {
|
|
colorLightPurple.print(" +----")
|
|
}
|
|
|
|
colorGreen.printf("%s\n", gtype.Name())
|
|
|
|
}
|
|
|
|
func printInterfaces(elem *gst.Element) {
|
|
fmt.Println()
|
|
|
|
if ifaces := elem.Interfaces(); len(ifaces) > 0 {
|
|
colorOrange.print("Implemented Interfaces:")
|
|
for _, iface := range ifaces {
|
|
colorGreen.printfIndent(2, "%s\n", iface)
|
|
}
|
|
}
|
|
}
|
|
|
|
func printPadTemplates(elem *gst.Element) {
|
|
fmt.Println()
|
|
|
|
tmpls := elem.GetPadTemplates()
|
|
if len(tmpls) == 0 {
|
|
return
|
|
}
|
|
colorOrange.print("Pad templates:\n")
|
|
for _, tmpl := range tmpls {
|
|
colorBlue.printfIndent(2, "%s template", strings.ToUpper(tmpl.Name()))
|
|
colorReset.print(": ")
|
|
colorBlue.printf("'%s'\n", strings.ToLower(tmpl.Direction().String()))
|
|
|
|
colorBlue.printIndent(4, "Availability")
|
|
colorReset.print(": ")
|
|
colorLightGray.print(strings.Title(tmpl.Presence().String()))
|
|
colorReset.print("\n")
|
|
|
|
colorBlue.printIndent(4, "Capabilities")
|
|
colorReset.print(": ")
|
|
|
|
printCaps(tmpl.Caps(), 6)
|
|
}
|
|
fmt.Println()
|
|
fmt.Println()
|
|
}
|
|
|
|
func printClockingInfo(elem *gst.Element) {
|
|
if !elem.Has(gst.ElementFlagRequireClock) && !elem.Has(gst.ElementFlagProvideClock) {
|
|
colorLightGray.print("Element has no clocking capabilities.\n")
|
|
return
|
|
}
|
|
fmt.Printf("%sClocking Interactions:%s\n", colorOrange, colorReset)
|
|
|
|
if elem.Has(gst.ElementFlagRequireClock) {
|
|
colorLightGray.printIndent(2, "element requires a clock\n")
|
|
}
|
|
|
|
if elem.Has(gst.ElementFlagProvideClock) {
|
|
clock := elem.GetClock()
|
|
if clock == nil {
|
|
colorLightGray.printIndent(2, "element is supposed to provide a clock but returned NULL%s\n")
|
|
} else {
|
|
defer clock.Unref()
|
|
colorLightGray.printIndent(2, "element provides a clock: ")
|
|
colorCyan.printf(clock.Name())
|
|
}
|
|
}
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func printURIHandlerInfo(elem *gst.Element) {
|
|
if !elem.IsURIHandler() {
|
|
colorLightGray.print("Element has no URI handling capabilities.\n")
|
|
fmt.Println()
|
|
}
|
|
|
|
uriHandler := elem.URIHandler()
|
|
|
|
colorOrange.print("URI handling capabilities:\n")
|
|
colorLightGray.printfIndent(2, "Element can act as %s.\n", strings.ToLower(uriHandler.GetURIType().String()))
|
|
|
|
protos := uriHandler.GetURIProtocols()
|
|
|
|
if len(protos) == 0 {
|
|
fmt.Println()
|
|
return
|
|
}
|
|
|
|
colorLightGray.printIndent(2, "Supported URI protocols:\n")
|
|
|
|
for _, proto := range protos {
|
|
colorCyan.printfIndent(4, "%s\n", proto)
|
|
}
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func printPadInfo(elem *gst.Element) {
|
|
|
|
colorOrange.print("Pads:\n")
|
|
pads := elem.GetPads()
|
|
if len(pads) == 0 {
|
|
colorCyan.printIndent(2, "none\n")
|
|
return
|
|
}
|
|
for _, pad := range elem.GetPads() {
|
|
defer pad.Unref()
|
|
|
|
colorBlue.printIndent(2, strings.ToUpper(pad.Direction().String()))
|
|
colorReset.print(": ")
|
|
colorLightGray.printf("'%s'\n", pad.Name())
|
|
|
|
if tmpl := pad.Template(); tmpl != nil {
|
|
defer tmpl.Unref()
|
|
colorBlue.printIndent(4, "Pad Template")
|
|
colorReset.print(": ")
|
|
colorLightGray.printf("'%s'\n", tmpl.Name())
|
|
}
|
|
|
|
if caps := pad.CurrentCaps(); caps != nil {
|
|
colorBlue.printIndent(2, "Capabilities:\n")
|
|
printCaps(caps, 4)
|
|
}
|
|
}
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
func printElementPropertiesInfo(elem *gst.Element) {
|
|
printObjectPropertiesInfo(elem.Object, "Element Properties")
|
|
}
|
|
|
|
func printSignalInfo(elem *gst.Element) {}
|
|
func printChildrenInfo(elem *gst.Element) {}
|
|
func printPresentList(elem *gst.Element) {}
|