mirror of
				https://github.com/asticode/go-astiav.git
				synced 2025-10-31 19:43:10 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			175 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package astiav
 | |
| 
 | |
| //#include <libavfilter/avfilter.h>
 | |
| import "C"
 | |
| import (
 | |
| 	"strings"
 | |
| 	"unsafe"
 | |
| )
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html
 | |
| type FilterGraph struct {
 | |
| 	c *C.AVFilterGraph
 | |
| 	// We need to store filter contexts to clean classer once filter graph is freed
 | |
| 	fcs []*FilterContext
 | |
| }
 | |
| 
 | |
| func newFilterGraphFromC(c *C.AVFilterGraph) *FilterGraph {
 | |
| 	if c == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	g := &FilterGraph{c: c}
 | |
| 	classers.set(g)
 | |
| 	return g
 | |
| }
 | |
| 
 | |
| var _ Classer = (*FilterGraph)(nil)
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga6c778454b86f845805ffd814b4ce51d4
 | |
| func AllocFilterGraph() *FilterGraph {
 | |
| 	return newFilterGraphFromC(C.avfilter_graph_alloc())
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga871684449dac05050df238a18d0d493b
 | |
| func (g *FilterGraph) Free() {
 | |
| 	if g.c != nil {
 | |
| 		// Make sure to clone the classer before freeing the object since
 | |
| 		// the C free method may reset the pointer
 | |
| 		c := newClonedClasser(g)
 | |
| 		var cfcs []Classer
 | |
| 		for _, fc := range g.fcs {
 | |
| 			cfcs = append(cfcs, newClonedClasser(fc))
 | |
| 		}
 | |
| 		C.avfilter_graph_free(&g.c)
 | |
| 		// Make sure to remove from classers after freeing the object since
 | |
| 		// the C free method may use methods needing the classer
 | |
| 		for _, cfc := range cfcs {
 | |
| 			if cfc != nil {
 | |
| 				classers.del(cfc)
 | |
| 			}
 | |
| 		}
 | |
| 		if c != nil {
 | |
| 			classers.del(c)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#gadb442aca4e5a8c3ba740f6049f0a288b
 | |
| func (g *FilterGraph) String() string {
 | |
| 	return C.GoString(C.avfilter_graph_dump(g.c, nil))
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#af00925dd69b474fac48887efc0e1ac94
 | |
| func (g *FilterGraph) Class() *Class {
 | |
| 	return newClassFromC(unsafe.Pointer(g.c))
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#ac28dcbf76e6fdd800295a2738d41660e
 | |
| func (g *FilterGraph) ThreadCount() int {
 | |
| 	return int(g.c.nb_threads)
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#ac28dcbf76e6fdd800295a2738d41660e
 | |
| func (g *FilterGraph) SetThreadCount(threadCount int) {
 | |
| 	g.c.nb_threads = C.int(threadCount)
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#a7fd96bbd6d1a3b730681dc0bf5107a5e
 | |
| func (g *FilterGraph) ThreadType() ThreadType {
 | |
| 	return ThreadType(g.c.thread_type)
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#a7fd96bbd6d1a3b730681dc0bf5107a5e
 | |
| func (g *FilterGraph) SetThreadType(t ThreadType) {
 | |
| 	g.c.thread_type = C.int(t)
 | |
| }
 | |
| 
 | |
| type FilterArgs map[string]string
 | |
| 
 | |
| func (args FilterArgs) String() string {
 | |
| 	var ss []string
 | |
| 	for k, v := range args {
 | |
| 		ss = append(ss, k+"="+v)
 | |
| 	}
 | |
| 	return strings.Join(ss, ":")
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#gac0788a9ab6966dba9318b5d5c7524fea
 | |
| func (g *FilterGraph) NewFilterContext(f *Filter, name string, args FilterArgs) (*FilterContext, error) {
 | |
| 	ca := (*C.char)(nil)
 | |
| 	if len(args) > 0 {
 | |
| 		ca = C.CString(args.String())
 | |
| 		defer C.free(unsafe.Pointer(ca))
 | |
| 	}
 | |
| 	cn := C.CString(name)
 | |
| 	defer C.free(unsafe.Pointer(cn))
 | |
| 	var c *C.AVFilterContext
 | |
| 	if err := newError(C.avfilter_graph_create_filter(&c, f.c, cn, ca, nil, g.c)); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	fc := newFilterContext(c)
 | |
| 	g.fcs = append(g.fcs, fc)
 | |
| 	return fc, nil
 | |
| }
 | |
| 
 | |
| func (g *FilterGraph) NewBuffersinkFilterContext(f *Filter, name string, args FilterArgs) (*BuffersinkFilterContext, error) {
 | |
| 	fc, err := g.NewFilterContext(f, name, args)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return newBuffersinkFilterContext(fc), nil
 | |
| }
 | |
| 
 | |
| func (g *FilterGraph) NewBuffersrcFilterContext(f *Filter, name string, args FilterArgs) (*BuffersrcFilterContext, error) {
 | |
| 	fc, err := g.NewFilterContext(f, name, args)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return newBuffersrcFilterContext(fc), nil
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga34f4ff420bd58da6747a3ff1fbedd001
 | |
| func (g *FilterGraph) Parse(content string, inputs, outputs *FilterInOut) error {
 | |
| 	cc := C.CString(content)
 | |
| 	defer C.free(unsafe.Pointer(cc))
 | |
| 	var ic **C.AVFilterInOut
 | |
| 	if inputs != nil {
 | |
| 		ic = &inputs.c
 | |
| 	}
 | |
| 	var oc **C.AVFilterInOut
 | |
| 	if outputs != nil {
 | |
| 		oc = &outputs.c
 | |
| 	}
 | |
| 	return newError(C.avfilter_graph_parse_ptr(g.c, cc, ic, oc, nil))
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga2ecfd3667219b6cd1e37b7047cc0ef2b
 | |
| func (g *FilterGraph) ParseSegment(content string) (*FilterGraphSegment, error) {
 | |
| 	cc := C.CString(content)
 | |
| 	defer C.free(unsafe.Pointer(cc))
 | |
| 	var cs *C.AVFilterGraphSegment
 | |
| 	if err := newError(C.avfilter_graph_segment_parse(g.c, cc, 0, &cs)); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return newFilterGraphSegmentFromC(cs), nil
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga1896c46b7bc6ff1bdb1a4815faa9ad07
 | |
| func (g *FilterGraph) Configure() error {
 | |
| 	return newError(C.avfilter_graph_config(g.c, nil))
 | |
| }
 | |
| 
 | |
| // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#gaaad7850fb5fe26d35e5d371ca75b79e1
 | |
| func (g *FilterGraph) SendCommand(target, cmd, args string, f FilterCommandFlags) (response string, err error) {
 | |
| 	targetc := C.CString(target)
 | |
| 	defer C.free(unsafe.Pointer(targetc))
 | |
| 	cmdc := C.CString(cmd)
 | |
| 	defer C.free(unsafe.Pointer(cmdc))
 | |
| 	argsc := C.CString(args)
 | |
| 	defer C.free(unsafe.Pointer(argsc))
 | |
| 	response, err = stringFromC(255, func(buf *C.char, size C.size_t) error {
 | |
| 		return newError(C.avfilter_graph_send_command(g.c, targetc, cmdc, argsc, buf, C.int(size), C.int(f)))
 | |
| 	})
 | |
| 	return
 | |
| }
 | 
