mirror of
https://github.com/asticode/go-astiav.git
synced 2025-09-26 20:21:15 +08:00
Added filter ParseSegment()
This commit is contained in:
26
filter.go
26
filter.go
@@ -2,7 +2,9 @@ package astiav
|
||||
|
||||
//#include <libavfilter/avfilter.h>
|
||||
import "C"
|
||||
import "unsafe"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// https://github.com/FFmpeg/FFmpeg/blob/n5.0/libavfilter/avfilter.h#L165
|
||||
type Filter struct {
|
||||
@@ -29,3 +31,25 @@ func (f *Filter) Name() string {
|
||||
func (f *Filter) String() string {
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
func (f *Filter) NbInputs() int {
|
||||
return int(f.c.nb_inputs)
|
||||
}
|
||||
|
||||
func (f *Filter) NbOutputs() int {
|
||||
return int(f.c.nb_outputs)
|
||||
}
|
||||
|
||||
func (f *Filter) Inputs() (ps []*FilterPad) {
|
||||
for idx := 0; idx < f.NbInputs(); idx++ {
|
||||
ps = append(ps, newFilterPad(MediaType(C.avfilter_pad_get_type(f.c.inputs, C.int(idx)))))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *Filter) Outputs() (ps []*FilterPad) {
|
||||
for idx := 0; idx < f.NbOutputs(); idx++ {
|
||||
ps = append(ps, newFilterPad(MediaType(C.avfilter_pad_get_type(f.c.outputs, C.int(idx)))))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
32
filter_chain.go
Normal file
32
filter_chain.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package astiav
|
||||
|
||||
//#include <libavfilter/avfilter.h>
|
||||
import "C"
|
||||
import (
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// https://github.com/FFmpeg/FFmpeg/blob/n7.0/libavfilter/avfilter.h#L1142
|
||||
type FilterChain struct {
|
||||
c *C.AVFilterChain
|
||||
}
|
||||
|
||||
func newFilterChainFromC(c *C.AVFilterChain) *FilterChain {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return &FilterChain{c: c}
|
||||
}
|
||||
|
||||
func (fc *FilterChain) Filters() (fs []*FilterParams) {
|
||||
fcs := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.AVFilterParams)(nil))](*C.AVFilterParams))(unsafe.Pointer(fc.c.filters))
|
||||
for i := 0; i < fc.NbFilters(); i++ {
|
||||
fs = append(fs, newFilterParamsFromC(fcs[i]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (fc *FilterChain) NbFilters() int {
|
||||
return int(fc.c.nb_filters)
|
||||
}
|
@@ -97,6 +97,16 @@ func (g *FilterGraph) Parse(content string, inputs, outputs *FilterInOut) error
|
||||
return newError(C.avfilter_graph_parse_ptr(g.c, cc, ic, oc, nil))
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (g *FilterGraph) Configure() error {
|
||||
return newError(C.avfilter_graph_config(g.c, nil))
|
||||
}
|
||||
|
36
filter_graph_segment.go
Normal file
36
filter_graph_segment.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package astiav
|
||||
|
||||
//#include <libavfilter/avfilter.h>
|
||||
import "C"
|
||||
import (
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// https://github.com/FFmpeg/FFmpeg/blob/n7.0/libavfilter/avfilter.h#L1156
|
||||
type FilterGraphSegment struct {
|
||||
c *C.AVFilterGraphSegment
|
||||
}
|
||||
|
||||
func newFilterGraphSegmentFromC(c *C.AVFilterGraphSegment) *FilterGraphSegment {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return &FilterGraphSegment{c: c}
|
||||
}
|
||||
|
||||
func (fgs *FilterGraphSegment) Free() {
|
||||
C.avfilter_graph_segment_free(&fgs.c)
|
||||
}
|
||||
|
||||
func (fgs *FilterGraphSegment) Chains() (cs []*FilterChain) {
|
||||
ccs := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.AVFilterChain)(nil))](*C.AVFilterChain))(unsafe.Pointer(fgs.c.chains))
|
||||
for i := 0; i < fgs.NbChains(); i++ {
|
||||
cs = append(cs, newFilterChainFromC(ccs[i]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (fgs *FilterGraphSegment) NbChains() int {
|
||||
return int(fgs.c.nb_chains)
|
||||
}
|
@@ -97,13 +97,13 @@ func TestFilterGraph(t *testing.T) {
|
||||
channelLayout: ChannelLayoutStereo,
|
||||
mediaType: MediaTypeAudio,
|
||||
sampleFormat: SampleFormatS16,
|
||||
sampleRate: 4,
|
||||
sampleRate: 3,
|
||||
timeBase: NewRational(1, 4),
|
||||
},
|
||||
buffersinkName: "abuffersink",
|
||||
buffersrcName: "abuffer",
|
||||
content: "[input_1]aformat=sample_fmts=s16:channel_layouts=stereo:sample_rates=4,asettb=1/4",
|
||||
s: " +---------------+\nParsed_asettb_1:default--[4Hz s16:stereo]--default| filter_out |\n | (abuffersink) |\n +---------------+\n\n+-------------+\n| filter_in_1 |default--[2Hz fltp:mono]--auto_aresample_0:default\n| (abuffer) |\n+-------------+\n\n +------------------+\nauto_aresample_0:default--[4Hz s16:stereo]--default| Parsed_aformat_0 |default--[4Hz s16:stereo]--Parsed_asettb_1:default\n | (aformat) |\n +------------------+\n\n +-----------------+\nParsed_aformat_0:default--[4Hz s16:stereo]--default| Parsed_asettb_1 |default--[4Hz s16:stereo]--filter_out:default\n | (asettb) |\n +-----------------+\n\n +------------------+\nfilter_in_1:default--[2Hz fltp:mono]--default| auto_aresample_0 |default--[4Hz s16:stereo]--Parsed_aformat_0:default\n | (aresample) |\n +------------------+\n\n",
|
||||
content: "[input_1]aformat=sample_fmts=s16:channel_layouts=stereo:sample_rates=3,asettb=1/4",
|
||||
s: " +---------------+\nParsed_asettb_1:default--[3Hz s16:stereo]--default| filter_out |\n | (abuffersink) |\n +---------------+\n\n+-------------+\n| filter_in_1 |default--[2Hz fltp:mono]--auto_aresample_0:default\n| (abuffer) |\n+-------------+\n\n +------------------+\nauto_aresample_0:default--[3Hz s16:stereo]--default| Parsed_aformat_0 |default--[3Hz s16:stereo]--Parsed_asettb_1:default\n | (aformat) |\n +------------------+\n\n +-----------------+\nParsed_aformat_0:default--[3Hz s16:stereo]--default| Parsed_asettb_1 |default--[3Hz s16:stereo]--filter_out:default\n | (asettb) |\n +-----------------+\n\n +------------------+\nfilter_in_1:default--[2Hz fltp:mono]--default| auto_aresample_0 |default--[3Hz s16:stereo]--Parsed_aformat_0:default\n | (aresample) |\n +------------------+\n\n",
|
||||
sources: []FilterArgs{
|
||||
{
|
||||
"channel_layout": ChannelLayoutMono.String(),
|
||||
@@ -201,6 +201,26 @@ func TestFilterGraph(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
fg2 := AllocFilterGraph()
|
||||
require.NotNil(t, fg2)
|
||||
defer fg2.Free()
|
||||
fgs, err := fg2.ParseSegment("anullsrc")
|
||||
require.NoError(t, err)
|
||||
defer fgs.Free()
|
||||
require.Equal(t, 1, fgs.NbChains())
|
||||
cs := fgs.Chains()
|
||||
require.Equal(t, 1, len(cs))
|
||||
require.Equal(t, 1, cs[0].NbFilters())
|
||||
fs := cs[0].Filters()
|
||||
require.Equal(t, 1, len(fs))
|
||||
f := FindFilterByName(fs[0].FilterName())
|
||||
require.NotNil(t, f)
|
||||
require.Equal(t, 0, f.NbInputs())
|
||||
require.Equal(t, 1, f.NbOutputs())
|
||||
os := f.Outputs()
|
||||
require.Equal(t, 1, len(os))
|
||||
require.Equal(t, MediaTypeAudio, os[0].MediaType())
|
||||
|
||||
// TODO Test BuffersrcAddFrame
|
||||
// TODO Test BuffersinkGetFrame
|
||||
}
|
||||
|
14
filter_pad.go
Normal file
14
filter_pad.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package astiav
|
||||
|
||||
// Struct attributes are internal but there are C functions to get some of them
|
||||
type FilterPad struct {
|
||||
mediaType MediaType
|
||||
}
|
||||
|
||||
func newFilterPad(mediaType MediaType) *FilterPad {
|
||||
return &FilterPad{mediaType: mediaType}
|
||||
}
|
||||
|
||||
func (fp *FilterPad) MediaType() MediaType {
|
||||
return fp.mediaType
|
||||
}
|
20
filter_params.go
Normal file
20
filter_params.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package astiav
|
||||
|
||||
//#include <libavfilter/avfilter.h>
|
||||
import "C"
|
||||
|
||||
// https://github.com/FFmpeg/FFmpeg/blob/n7.0/libavfilter/avfilter.h#L1075
|
||||
type FilterParams struct {
|
||||
c *C.AVFilterParams
|
||||
}
|
||||
|
||||
func newFilterParamsFromC(c *C.AVFilterParams) *FilterParams {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return &FilterParams{c: c}
|
||||
}
|
||||
|
||||
func (fp *FilterParams) FilterName() string {
|
||||
return C.GoString(fp.c.filter_name)
|
||||
}
|
Reference in New Issue
Block a user