Skip to content

Commit c0e675c

Browse files
committed
Added filters
1 parent 8f5aff2 commit c0e675c

File tree

7 files changed

+345
-0
lines changed

7 files changed

+345
-0
lines changed

sys/ffmpeg71/avfilter.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package ffmpeg
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
////////////////////////////////////////////////////////////////////////////////
9+
// CGO
10+
11+
/*
12+
#cgo pkg-config: libavfilter
13+
#include <libavfilter/avfilter.h>
14+
*/
15+
import "C"
16+
17+
////////////////////////////////////////////////////////////////////////////////
18+
// TYPES
19+
20+
type (
21+
AVFilterContext C.AVFilterContext
22+
AVFilter C.AVFilter
23+
AVFilterFlag C.int
24+
AVFilterGraph C.AVFilterGraph
25+
)
26+
27+
////////////////////////////////////////////////////////////////////////////////
28+
// GLOBALS
29+
30+
const (
31+
AVFILTER_FLAG_NONE AVFilterFlag = 0
32+
AVFILTER_FLAG_DYNAMIC_INPUTS AVFilterFlag = C.AVFILTER_FLAG_DYNAMIC_INPUTS
33+
AVFILTER_FLAG_DYNAMIC_OUTPUTS AVFilterFlag = C.AVFILTER_FLAG_DYNAMIC_OUTPUTS
34+
AVFILTER_FLAG_SLICE_THREADS AVFilterFlag = C.AVFILTER_FLAG_SLICE_THREADS
35+
AVFILTER_FLAG_METADATA_ONLY AVFilterFlag = C.AVFILTER_FLAG_METADATA_ONLY
36+
AVFILTER_FLAG_HWDEVICE AVFilterFlag = C.AVFILTER_FLAG_HWDEVICE
37+
AVFILTER_FLAG_SUPPORT_TIMELINE AVFilterFlag = C.AVFILTER_FLAG_SUPPORT_TIMELINE
38+
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC AVFilterFlag = C.AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
39+
AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL AVFilterFlag = C.AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
40+
AVFILTER_FLAG_MAX = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
41+
)
42+
43+
////////////////////////////////////////////////////////////////////////////////
44+
// STRINGIFY
45+
46+
func (ctx *AVFilter) MarshalJSON() ([]byte, error) {
47+
type j struct {
48+
Name string `json:"name"`
49+
Description string `json:"description"`
50+
Flags AVFilterFlag `json:"flags,omitzero"`
51+
Inputs uint `json:"inputs,omitempty"`
52+
Outputs uint `json:"outputs,omitempty"`
53+
}
54+
if ctx == nil {
55+
return json.Marshal(nil)
56+
}
57+
return json.Marshal(j{
58+
Name: ctx.Name(),
59+
Description: ctx.Description(),
60+
Flags: ctx.Flags(),
61+
Inputs: ctx.Inputs(),
62+
Outputs: ctx.Outputs(),
63+
})
64+
}
65+
66+
func (ctx *AVFilter) String() string {
67+
data, err := json.MarshalIndent(ctx, "", " ")
68+
if err != nil {
69+
return err.Error()
70+
}
71+
return string(data)
72+
}
73+
74+
////////////////////////////////////////////////////////////////////////////////
75+
// AVFilter
76+
77+
func (c *AVFilter) Name() string {
78+
return C.GoString(c.name)
79+
}
80+
81+
func (c *AVFilter) Description() string {
82+
return C.GoString(c.description)
83+
}
84+
85+
func (c *AVFilter) Flags() AVFilterFlag {
86+
return AVFilterFlag(c.flags)
87+
}
88+
89+
func (c *AVFilter) Inputs() uint {
90+
return AVFilter_inputs(c)
91+
}
92+
93+
func (c *AVFilter) Outputs() uint {
94+
return AVFilter_outputs(c)
95+
}
96+
97+
////////////////////////////////////////////////////////////////////////////////
98+
// AVFilterFlag
99+
100+
func (v AVFilterFlag) Is(f AVFilterFlag) bool {
101+
return v&f == f
102+
}
103+
104+
func (v AVFilterFlag) String() string {
105+
if v == AVFILTER_FLAG_NONE {
106+
return v.FlagString()
107+
}
108+
str := ""
109+
for i := AVFilterFlag(C.int(1)); i <= AVFILTER_FLAG_MAX; i <<= 1 {
110+
if v&i == i {
111+
str += "|" + i.FlagString()
112+
}
113+
}
114+
return str[1:]
115+
}
116+
117+
func (v AVFilterFlag) FlagString() string {
118+
switch v {
119+
case AVFILTER_FLAG_NONE:
120+
return "AVFILTER_FLAG_NONE"
121+
case AVFILTER_FLAG_DYNAMIC_INPUTS:
122+
return "AVFILTER_FLAG_DYNAMIC_INPUTS"
123+
case AVFILTER_FLAG_DYNAMIC_OUTPUTS:
124+
return "AVFILTER_FLAG_DYNAMIC_OUTPUTS"
125+
case AVFILTER_FLAG_SLICE_THREADS:
126+
return "AVFILTER_FLAG_SLICE_THREADS"
127+
case AVFILTER_FLAG_METADATA_ONLY:
128+
return "AVFILTER_FLAG_METADATA_ONLY"
129+
case AVFILTER_FLAG_HWDEVICE:
130+
return "AVFILTER_FLAG_HWDEVICE"
131+
case AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC:
132+
return "AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC"
133+
case AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL:
134+
return "AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL"
135+
default:
136+
return fmt.Sprintf("AVFilterFlag(0x%08X)", uint32(v))
137+
}
138+
}

sys/ffmpeg71/avfilter_filter.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ffmpeg
2+
3+
import "unsafe"
4+
5+
////////////////////////////////////////////////////////////////////////////////
6+
// CGO
7+
8+
/*
9+
#cgo pkg-config: libavfilter
10+
#include <libavfilter/avfilter.h>
11+
*/
12+
import "C"
13+
14+
////////////////////////////////////////////////////////////////////////////////
15+
// PUBLIC METHODS
16+
17+
// Iterate over all registered filters.
18+
func AVFilter_iterate(opaque *uintptr) *AVFilter {
19+
return (*AVFilter)(C.av_filter_iterate((*unsafe.Pointer)(unsafe.Pointer(opaque))))
20+
}
21+
22+
// Get a filter definition matching the given name.
23+
func AVFilter_get_by_name(name string) *AVFilter {
24+
cStr := C.CString(name)
25+
defer C.free(unsafe.Pointer(cStr))
26+
return (*AVFilter)(C.avfilter_get_by_name(cStr))
27+
}
28+
29+
// Return number of input pads for a filter.
30+
func AVFilter_inputs(filter *AVFilter) uint {
31+
ctx := (*C.AVFilter)(filter)
32+
return uint(C.avfilter_filter_pad_count(ctx, 0))
33+
}
34+
35+
// Return number of output pads for a filter.
36+
func AVFilter_outputs(filter *AVFilter) uint {
37+
ctx := (*C.AVFilter)(filter)
38+
return uint(C.avfilter_filter_pad_count(ctx, 1))
39+
}
40+
41+
// Free a filter context. This will also remove the filter from graph's list of filters.
42+
func AVFilter_free(filter *AVFilterContext) {
43+
ctx := (*C.AVFilterContext)(filter)
44+
C.avfilter_free(ctx)
45+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package ffmpeg_test
2+
3+
import (
4+
"testing"
5+
6+
// Packages
7+
ff "github.com/mutablelogic/go-media/sys/ffmpeg71"
8+
assert "github.com/stretchr/testify/assert"
9+
)
10+
11+
func Test_avfilter_filter_000(t *testing.T) {
12+
//assert := assert.New(t)
13+
14+
// Iterate over all filters
15+
var opaque uintptr
16+
for {
17+
filter := ff.AVFilter_iterate(&opaque)
18+
if filter == nil {
19+
break
20+
}
21+
22+
t.Log("filter=", filter)
23+
}
24+
}
25+
26+
func Test_avfilter_filter_001(t *testing.T) {
27+
assert := assert.New(t)
28+
29+
// Iterate over all filters
30+
var opaque uintptr
31+
for {
32+
filter := ff.AVFilter_iterate(&opaque)
33+
if filter == nil {
34+
break
35+
}
36+
filter2 := ff.AVFilter_get_by_name(filter.Name())
37+
assert.NotNil(filter2)
38+
assert.Equal(filter, filter2)
39+
}
40+
}

sys/ffmpeg71/avfilter_graph.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package ffmpeg
2+
3+
////////////////////////////////////////////////////////////////////////////////
4+
// CGO
5+
6+
/*
7+
#cgo pkg-config: libavfilter
8+
#include <libavfilter/avfilter.h>
9+
*/
10+
import "C"
11+
import (
12+
"fmt"
13+
"unsafe"
14+
)
15+
16+
////////////////////////////////////////////////////////////////////////////////
17+
// PUBLIC METHODS
18+
19+
func AVFilterGraph_alloc() *AVFilterGraph {
20+
return (*AVFilterGraph)(C.avfilter_graph_alloc())
21+
}
22+
23+
func AVFilterGraph_free(graph *AVFilterGraph) {
24+
ctx := (*C.AVFilterGraph)(graph)
25+
C.avfilter_graph_free(&ctx)
26+
}
27+
28+
// Allocates and initializes a filter in a single step.
29+
// The filter instance is created from the filter and inited with the parameter args.
30+
func AVFilterGraph_create_filter(graph *AVFilterGraph, filter *AVFilter, name, args string) (*AVFilterContext, error) {
31+
var ctx *C.AVFilterContext
32+
graph_ctx := (*C.AVFilterGraph)(graph)
33+
cName, cArgs := C.CString(name), C.CString(args)
34+
defer C.free(unsafe.Pointer(cName))
35+
defer C.free(unsafe.Pointer(cArgs))
36+
if err := AVError(C.avfilter_graph_create_filter(&ctx, (*C.AVFilter)(filter), cName, cArgs, nil, graph_ctx)); err != 0 {
37+
return nil, fmt.Errorf("avfilter_graph_create_filter: %w", err)
38+
}
39+
return (*AVFilterContext)(ctx), nil
40+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package ffmpeg_test
2+
3+
import (
4+
"testing"
5+
6+
// Packages
7+
ff "github.com/mutablelogic/go-media/sys/ffmpeg71"
8+
assert "github.com/stretchr/testify/assert"
9+
)
10+
11+
func Test_avfilter_graph_000(t *testing.T) {
12+
assert := assert.New(t)
13+
graph := ff.AVFilterGraph_alloc()
14+
assert.NotNil(graph)
15+
ff.AVFilterGraph_free(graph)
16+
}
17+
18+
func Test_avfilter_graph_001(t *testing.T) {
19+
assert := assert.New(t)
20+
graph := ff.AVFilterGraph_alloc()
21+
assert.NotNil(graph)
22+
defer ff.AVFilterGraph_free(graph)
23+
24+
// Create a filter
25+
filter := ff.AVFilter_get_by_name("null")
26+
assert.NotNil(filter)
27+
28+
// Create a filter context
29+
ctx, err := ff.AVFilterGraph_create_filter(graph, filter, "null", "")
30+
assert.NoError(err)
31+
assert.NotNil(ctx)
32+
33+
// We don't need to free the filter context, as it is freed when the graph is freed
34+
}

sys/ffmpeg71/avfilter_version.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ffmpeg
2+
3+
////////////////////////////////////////////////////////////////////////////////
4+
// CGO
5+
6+
/*
7+
#cgo pkg-config: libavfilter
8+
#include <libavfilter/avfilter.h>
9+
*/
10+
import "C"
11+
12+
////////////////////////////////////////////////////////////////////////////////
13+
// PUBLIC METHODS
14+
15+
// Return the LIBAVFILTER_VERSION_INT constant.
16+
func AVFilter_version() uint {
17+
return uint(C.avfilter_version())
18+
}
19+
20+
// Return the libavfilter build-time configuration.
21+
func AVFilter_configuration() string {
22+
return C.GoString(C.avfilter_configuration())
23+
}
24+
25+
// Return the libavfilter license.
26+
func AVFilter_license() string {
27+
return C.GoString(C.avfilter_license())
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ffmpeg_test
2+
3+
import (
4+
"testing"
5+
6+
// Namespace imports
7+
. "github.com/mutablelogic/go-media/sys/ffmpeg71"
8+
)
9+
10+
func Test_avfilter_version_000(t *testing.T) {
11+
t.Log("avfilter_version=", AVFilter_version())
12+
}
13+
14+
func Test_avfilter_version_001(t *testing.T) {
15+
t.Log("avfilter_configuration=", AVFilter_configuration())
16+
}
17+
18+
func Test_avfilter_version_002(t *testing.T) {
19+
t.Log("avfilter_license=", AVFilter_license())
20+
}

0 commit comments

Comments
 (0)