-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathfilter_graph.go
171 lines (151 loc) · 5.43 KB
/
filter_graph.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package astiav
//#include <libavfilter/avfilter.h>
import "C"
import (
"errors"
"math"
"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)
}
// https://ffmpeg.org/doxygen/7.0/group__lavfi.html#gac0788a9ab6966dba9318b5d5c7524fea
func (g *FilterGraph) NewBuffersinkFilterContext(f *Filter, name string) (*BuffersinkFilterContext, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
var c *C.AVFilterContext
if err := newError(C.avfilter_graph_create_filter(&c, f.c, cname, nil, nil, g.c)); err != nil {
return nil, err
}
fc := newFilterContext(c)
g.fcs = append(g.fcs, fc)
return newBuffersinkFilterContext(fc), nil
}
// https://ffmpeg.org/doxygen/7.0/group__lavfi.html#gaa9af17ecf4c5c87307b57cf08411088b
func (g *FilterGraph) NewBuffersrcFilterContext(f *Filter, name string) (*BuffersrcFilterContext, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
c := C.avfilter_graph_alloc_filter(g.c, f.c, cname)
if c == nil {
return nil, errors.New("astiav: allocating filter context failed")
}
fc := newFilterContext(c)
g.fcs = append(g.fcs, fc)
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
}
// https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#a0ba5c820c760788ea5f8e40c476f9704
func (g *FilterGraph) NbFilters() int {
return int(g.c.nb_filters)
}
// https://ffmpeg.org/doxygen/7.0/structAVFilterGraph.html#a1dafd3d239f7c2f5e3ac109578ef926d
func (g *FilterGraph) Filters() (fs []*FilterContext) {
fcs := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.AVFilterContext)(nil))](*C.AVFilterContext))(unsafe.Pointer(g.c.filters))
for i := 0; i < g.NbFilters(); i++ {
fs = append(fs, newFilterContext(fcs[i]))
}
return
}