add convenience error poster for GstBus that auto gathers go runtime debug info

This commit is contained in:
tinyzimmer
2020-10-04 18:49:50 +03:00
parent 440a4649f9
commit 0077dc812c
2 changed files with 28 additions and 13 deletions

View File

@@ -3,7 +3,6 @@
package main package main
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
"image" "image"
@@ -62,9 +61,7 @@ func encodeGif(mainLoop *gst.MainLoop) error {
// Build out the rest of the elements for the pipeline pipeline. // Build out the rest of the elements for the pipeline pipeline.
elements, err := gst.NewElementMany("queue", "videoconvert", "videoscale", "videorate", "jpegenc") elements, err := gst.NewElementMany("queue", "videoconvert", "videoscale", "videorate", "jpegenc")
if err != nil { if err != nil {
err := gst.NewGError(2, err) pipeline.GetPipelineBus().PostError(self, "Failed to build elements for the linked pipeline", err)
pipeline.GetPipelineBus().
Post(gst.NewErrorMessage(self, err, "", nil))
return return
} }
@@ -97,9 +94,7 @@ func encodeGif(mainLoop *gst.MainLoop) error {
// use this value to calculate the total number of frames we expect to produce. // use this value to calculate the total number of frames we expect to produce.
query := gst.NewDurationQuery(gst.FormatTime) query := gst.NewDurationQuery(gst.FormatTime)
if ok := self.Query(query); !ok { if ok := self.Query(query); !ok {
err := gst.NewGError(3, errors.New("Failed to query video duration from decodebin")) pipeline.GetPipelineBus().PostError(self, "Failed to query video duration from decodebin", nil)
pipeline.GetPipelineBus().
Post(gst.NewErrorMessage(self, err, "", nil))
return return
} }
@@ -115,10 +110,6 @@ func encodeGif(mainLoop *gst.MainLoop) error {
var frameNum int var frameNum int
appSink.SetCallbacks(&app.SinkCallbacks{ appSink.SetCallbacks(&app.SinkCallbacks{
NewSampleFunc: func(sink *app.Sink) gst.FlowReturn { NewSampleFunc: func(sink *app.Sink) gst.FlowReturn {
// We can retrieve a reader with the raw bytes of the image directly from the
// sink.
imgReader := sink.PullSample().GetBuffer().Reader()
// Increment the frame number counter // Increment the frame number counter
frameNum++ frameNum++
@@ -131,9 +122,13 @@ func encodeGif(mainLoop *gst.MainLoop) error {
fmt.Printf("\033[2K\rProcessing image frame %d/%d", frameNum, totalFrames) fmt.Printf("\033[2K\rProcessing image frame %d/%d", frameNum, totalFrames)
// We can retrieve a reader with the raw bytes of the image directly from the
// sink.
imgReader := sink.PullSample().GetBuffer().Reader()
img, err := jpeg.Decode(imgReader) img, err := jpeg.Decode(imgReader)
if err != nil { if err != nil {
fmt.Println("Error decoding jpeg frame:", err) pipeline.GetPipelineBus().PostError(sink, "Error decoding jpeg frame", err)
return gst.FlowError return gst.FlowError
} }
@@ -170,7 +165,8 @@ func encodeGif(mainLoop *gst.MainLoop) error {
err := msg.ParseError() err := msg.ParseError()
fmt.Println("ERROR:", err.Error()) fmt.Println("ERROR:", err.Error())
if debug := err.DebugString(); debug != "" { if debug := err.DebugString(); debug != "" {
fmt.Println("DEBUG:", debug) fmt.Println("DEBUG")
fmt.Println(debug)
} }
mainLoop.Quit() mainLoop.Quit()
isError = true isError = true

View File

@@ -20,7 +20,10 @@ GstBusSyncReply cgoBusSyncHandler (GstBus * bus, GstMessage * message, gpointer
import "C" import "C"
import ( import (
"errors"
"fmt"
"reflect" "reflect"
"runtime/debug"
"sync" "sync"
"time" "time"
"unsafe" "unsafe"
@@ -315,6 +318,22 @@ func (b *Bus) Post(msg *Message) bool {
return gobool(C.gst_bus_post(b.Instance(), msg.Instance())) return gobool(C.gst_bus_post(b.Instance(), msg.Instance()))
} }
// PostError is a wrapper for creating a new error mesesage and then posting it to the bus.
// It gathers stack info from the caller and appends it to the debug info in the error. And optional
// error object can be provided and will be added to the structure of the error.
func (b *Bus) PostError(src interface{}, msg string, err error) bool {
gerr := NewGError(1, errors.New(msg))
var st *Structure
if err != nil {
st = NewStructure("go-error")
if addErr := st.SetValue("error", err.Error()); addErr != nil {
fmt.Println("go-gst-warning: failed to set error message to structure")
}
}
gstMsg := NewErrorMessage(src, gerr, string(debug.Stack()), st)
return b.Post(gstMsg)
}
// SetFlushing sets whether to flush out and unref any messages queued in the bus. Releases references to the message origin // SetFlushing sets whether to flush out and unref any messages queued in the bus. Releases references to the message origin
// objects. Will flush future messages until SetFlushing sets flushing to FALSE. // objects. Will flush future messages until SetFlushing sets flushing to FALSE.
func (b *Bus) SetFlushing(flushing bool) { C.gst_bus_set_flushing(b.Instance(), gboolean(flushing)) } func (b *Bus) SetFlushing(flushing bool) { C.gst_bus_set_flushing(b.Instance(), gboolean(flushing)) }