Removed args from NewXXXFilterContext()

This commit is contained in:
Quentin Renard
2024-12-19 16:20:19 +01:00
parent ab81ca0faf
commit 4b35c9a741
10 changed files with 286 additions and 89 deletions

View File

@@ -1,3 +1,8 @@
# v0.29.0
- `NewFilterContext` has been removed, use `NewBuffersinkFilterContext` or `NewBuffersrcFilterContext` instead
- `args` has been removed from `NewBuffersinkFilterContext` and `NewBuffersrcFilterContext`. Instead, after calling `NewBuffersrcFilterContext`, you need to use `BuffersrcFilterContext`.`SetParameters` then `BuffersrcFilterContext`.`Initialize`. You don't need to use anything else after calling `NewBuffersinkFilterContext`
# v0.27.0 # v0.27.0
- make sure to call the `IOInterrupter`.`Free` method after using `NewIOInterrupter` - make sure to call the `IOInterrupter`.`Free` method after using `NewIOInterrupter`

View File

@@ -24,6 +24,11 @@ func (bfc *BuffersrcFilterContext) FilterContext() *FilterContext {
return bfc.fc return bfc.fc
} }
// https://ffmpeg.org/doxygen/7.0/group__lavfi.html#ga8c15af28902395399fe455f6f8236848
func (bfc *BuffersrcFilterContext) Initialize() error {
return newError(C.avfilter_init_dict(bfc.fc.c, nil))
}
// https://ffmpeg.org/doxygen/7.0/group__lavfi__buffersrc.html#ga398cd2a84f8b4a588197ab9d90135048 // https://ffmpeg.org/doxygen/7.0/group__lavfi__buffersrc.html#ga398cd2a84f8b4a588197ab9d90135048
func (bfc *BuffersrcFilterContext) SetParameters(bfcp *BuffersrcFilterContextParameters) error { func (bfc *BuffersrcFilterContext) SetParameters(bfcp *BuffersrcFilterContextParameters) error {
return newError(C.av_buffersrc_parameters_set(bfc.fc.c, bfcp.c)) return newError(C.av_buffersrc_parameters_set(bfc.fc.c, bfcp.c))

View File

@@ -30,6 +30,47 @@ func (bfcp *BuffersrcFilterContextParameters) Free() {
} }
} }
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a5267368bf88b4f2a65a5e06ac3f9ecd4
func (bfcp *BuffersrcFilterContextParameters) ChannelLayout() ChannelLayout {
l, _ := newChannelLayoutFromC(&bfcp.c.ch_layout).clone()
return l
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a5267368bf88b4f2a65a5e06ac3f9ecd4
func (bfcp *BuffersrcFilterContextParameters) SetChannelLayout(l ChannelLayout) {
l.copy(&bfcp.c.ch_layout) //nolint: errcheck
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a442add2b039f416dd7c92ccf1ccd0d3b
func (bfcp *BuffersrcFilterContextParameters) ColorRange() ColorRange {
return ColorRange(bfcp.c.color_range)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a442add2b039f416dd7c92ccf1ccd0d3b
func (bfcp *BuffersrcFilterContextParameters) SetColorRange(r ColorRange) {
bfcp.c.color_range = C.enum_AVColorRange(r)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a700226626af70f787c930d7506554757
func (bfcp *BuffersrcFilterContextParameters) ColorSpace() ColorSpace {
return ColorSpace(bfcp.c.color_space)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a700226626af70f787c930d7506554757
func (bfcp *BuffersrcFilterContextParameters) SetColorSpace(s ColorSpace) {
bfcp.c.color_space = C.enum_AVColorSpace(s)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a032a202496206e18449c66233058647a
func (bfcp *BuffersrcFilterContextParameters) Framerate() Rational {
return newRationalFromC(bfcp.c.frame_rate)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a032a202496206e18449c66233058647a
func (bfcp *BuffersrcFilterContextParameters) SetFramerate(f Rational) {
bfcp.c.frame_rate = f.c
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a86c49b4202433037c9e2b0b6ae541534 // https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a86c49b4202433037c9e2b0b6ae541534
func (bfcp *BuffersrcFilterContextParameters) SetHardwareFrameContext(hfc *HardwareFrameContext) { func (bfcp *BuffersrcFilterContextParameters) SetHardwareFrameContext(hfc *HardwareFrameContext) {
if bfcp.c.hw_frames_ctx != nil { if bfcp.c.hw_frames_ctx != nil {
@@ -41,3 +82,73 @@ func (bfcp *BuffersrcFilterContextParameters) SetHardwareFrameContext(hfc *Hardw
bfcp.c.hw_frames_ctx = nil bfcp.c.hw_frames_ctx = nil
} }
} }
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a89783d603b84908fb1998bbbea981b70
func (bfcp *BuffersrcFilterContextParameters) Height() int {
return int(bfcp.c.height)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a89783d603b84908fb1998bbbea981b70
func (bfcp *BuffersrcFilterContextParameters) SetHeight(height int) {
bfcp.c.height = C.int(height)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a56f28f81f1a86cecc39a8d61674912b8
func (bfcp *BuffersrcFilterContextParameters) PixelFormat() PixelFormat {
return PixelFormat(bfcp.c.format)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a56f28f81f1a86cecc39a8d61674912b8
func (bfcp *BuffersrcFilterContextParameters) SetPixelFormat(f PixelFormat) {
bfcp.c.format = C.int(f)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#ae47c141ea7a7770351613242229f951a
func (bfcp *BuffersrcFilterContextParameters) SampleAspectRatio() Rational {
return newRationalFromC(bfcp.c.sample_aspect_ratio)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#ae47c141ea7a7770351613242229f951a
func (bfcp *BuffersrcFilterContextParameters) SetSampleAspectRatio(r Rational) {
bfcp.c.sample_aspect_ratio = r.c
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a56f28f81f1a86cecc39a8d61674912b8
func (bfcp *BuffersrcFilterContextParameters) SampleFormat() SampleFormat {
return SampleFormat(bfcp.c.format)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a56f28f81f1a86cecc39a8d61674912b8
func (bfcp *BuffersrcFilterContextParameters) SetSampleFormat(f SampleFormat) {
bfcp.c.format = C.int(f)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a34a1613f1e80f8520c159fac59e29834
func (bfcp *BuffersrcFilterContextParameters) SampleRate() int {
return int(bfcp.c.sample_rate)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a34a1613f1e80f8520c159fac59e29834
func (bfcp *BuffersrcFilterContextParameters) SetSampleRate(sampleRate int) {
bfcp.c.sample_rate = C.int(sampleRate)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a7767325c1259942a33586f05c90e38b0
func (bfcp *BuffersrcFilterContextParameters) TimeBase() Rational {
return newRationalFromC(bfcp.c.time_base)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a7767325c1259942a33586f05c90e38b0
func (bfcp *BuffersrcFilterContextParameters) SetTimeBase(r Rational) {
bfcp.c.time_base = r.c
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a6c6f3d9ed8b427070e9055e7ac61263f
func (bfcp *BuffersrcFilterContextParameters) Width() int {
return int(bfcp.c.width)
}
// https://ffmpeg.org/doxygen/7.0/structAVBufferSrcParameters.html#a6c6f3d9ed8b427070e9055e7ac61263f
func (bfcp *BuffersrcFilterContextParameters) SetWidth(width int) {
bfcp.c.width = C.int(width)
}

View File

@@ -0,0 +1,34 @@
package astiav
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestBuffersrcFilterContextParameters(t *testing.T) {
p := AllocBuffersrcFilterContextParameters()
defer p.Free()
p.SetChannelLayout(ChannelLayoutStereo)
require.Equal(t, ChannelLayoutStereo, p.ChannelLayout())
p.SetColorRange(ColorRangeMpeg)
require.Equal(t, ColorRangeMpeg, p.ColorRange())
p.SetColorSpace(ColorSpaceBt470Bg)
require.Equal(t, ColorSpaceBt470Bg, p.ColorSpace())
p.SetFramerate(NewRational(1, 2))
require.Equal(t, NewRational(1, 2), p.Framerate())
p.SetHeight(1)
require.Equal(t, 1, p.Height())
p.SetPixelFormat(PixelFormatRgba)
require.Equal(t, PixelFormatRgba, p.PixelFormat())
p.SetSampleAspectRatio(NewRational(3, 4))
require.Equal(t, NewRational(3, 4), p.SampleAspectRatio())
p.SetSampleFormat(SampleFormatDblp)
require.Equal(t, SampleFormatDblp, p.SampleFormat())
p.SetSampleRate(2)
require.Equal(t, 2, p.SampleRate())
p.SetTimeBase(NewRational(5, 6))
require.Equal(t, NewRational(5, 6), p.TimeBase())
p.SetWidth(3)
require.Equal(t, 3, p.Width())
}

View File

@@ -40,9 +40,9 @@ func TestClassers(t *testing.T) {
require.NotNil(t, cc) require.NotNil(t, cc)
bufferSink := FindFilterByName("buffersink") bufferSink := FindFilterByName("buffersink")
require.NotNil(t, bufferSink) require.NotNil(t, bufferSink)
fc1, err := f1.NewFilterContext(bufferSink, "filter_out", nil) bfc1, err := f1.NewBuffersinkFilterContext(bufferSink, "filter_out")
require.NoError(t, err) require.NoError(t, err)
_, err = f2.NewFilterContext(bufferSink, "filter_out", nil) _, err = f2.NewBuffersinkFilterContext(bufferSink, "filter_out")
require.NoError(t, err) require.NoError(t, err)
fmc1 := AllocFormatContext() fmc1 := AllocFormatContext()
fmc2 := AllocFormatContext() fmc2 := AllocFormatContext()
@@ -64,7 +64,7 @@ func TestClassers(t *testing.T) {
bfc.Free() bfc.Free()
cc.Free() cc.Free()
fc1.Free() bfc1.FilterContext().Free()
f1.Free() f1.Free()
f2.Free() f2.Free()
fmc1.Free() fmc1.Free()

View File

@@ -5,7 +5,6 @@ import (
"flag" "flag"
"fmt" "fmt"
"log" "log"
"strconv"
"strings" "strings"
"github.com/asticode/go-astiav" "github.com/asticode/go-astiav"
@@ -250,20 +249,36 @@ func initFilter() (err error) {
} }
// Create filter contexts // Create filter contexts
if s.buffersrcContext, err = s.filterGraph.NewBuffersrcFilterContext(buffersrc, "in", astiav.FilterArgs{ if s.buffersrcContext, err = s.filterGraph.NewBuffersrcFilterContext(buffersrc, "in"); err != nil {
"pix_fmt": strconv.Itoa(int(s.decCodecContext.PixelFormat())),
"pixel_aspect": s.decCodecContext.SampleAspectRatio().String(),
"time_base": s.inputStream.TimeBase().String(),
"video_size": strconv.Itoa(s.decCodecContext.Width()) + "x" + strconv.Itoa(s.decCodecContext.Height()),
}); err != nil {
err = fmt.Errorf("main: creating buffersrc context failed: %w", err) err = fmt.Errorf("main: creating buffersrc context failed: %w", err)
return return
} }
if s.buffersinkContext, err = s.filterGraph.NewBuffersinkFilterContext(buffersink, "in", nil); err != nil { if s.buffersinkContext, err = s.filterGraph.NewBuffersinkFilterContext(buffersink, "in"); err != nil {
err = fmt.Errorf("main: creating buffersink context failed: %w", err) err = fmt.Errorf("main: creating buffersink context failed: %w", err)
return return
} }
// Create buffersrc context parameters
buffersrcContextParameters := astiav.AllocBuffersrcFilterContextParameters()
defer buffersrcContextParameters.Free()
buffersrcContextParameters.SetHeight(s.decCodecContext.Height())
buffersrcContextParameters.SetPixelFormat(s.decCodecContext.PixelFormat())
buffersrcContextParameters.SetSampleAspectRatio(s.decCodecContext.SampleAspectRatio())
buffersrcContextParameters.SetTimeBase(s.inputStream.TimeBase())
buffersrcContextParameters.SetWidth(s.decCodecContext.Width())
// Set buffersrc context parameters
if err = s.buffersrcContext.SetParameters(buffersrcContextParameters); err != nil {
err = fmt.Errorf("main: setting buffersrc context parameters failed: %w", err)
return
}
// Initialize buffersrc context
if err = s.buffersrcContext.Initialize(); err != nil {
err = fmt.Errorf("main: initializing buffersrc context failed: %w", err)
return
}
// Update outputs // Update outputs
outputs.SetName("in") outputs.SetName("in")
outputs.SetFilterContext(s.buffersrcContext.FilterContext()) outputs.SetFilterContext(s.buffersrcContext.FilterContext())

View File

@@ -5,7 +5,6 @@ import (
"flag" "flag"
"fmt" "fmt"
"log" "log"
"strconv"
"strings" "strings"
"github.com/asticode/go-astiav" "github.com/asticode/go-astiav"
@@ -294,28 +293,34 @@ func initFilter() (err error) {
} }
// Create filter contexts // Create filter contexts
if buffersrcContext, err = filterGraph.NewBuffersrcFilterContext(buffersrc, "in", astiav.FilterArgs{ if buffersrcContext, err = filterGraph.NewBuffersrcFilterContext(buffersrc, "in"); err != nil {
"pix_fmt": strconv.Itoa(int(decCodecContext.PixelFormat())),
"pixel_aspect": decCodecContext.SampleAspectRatio().String(),
"time_base": inputStream.TimeBase().String(),
"video_size": strconv.Itoa(decCodecContext.Width()) + "x" + strconv.Itoa(decCodecContext.Height()),
}); err != nil {
err = fmt.Errorf("main: creating buffersrc context failed: %w", err) err = fmt.Errorf("main: creating buffersrc context failed: %w", err)
return return
} }
if buffersinkContext, err = filterGraph.NewBuffersinkFilterContext(buffersink, "in", nil); err != nil { if buffersinkContext, err = filterGraph.NewBuffersinkFilterContext(buffersink, "in"); err != nil {
err = fmt.Errorf("main: creating buffersink context failed: %w", err) err = fmt.Errorf("main: creating buffersink context failed: %w", err)
return return
} }
// Create buffersrc parameters // Create buffersrc context parameters
bfcp := astiav.AllocBuffersrcFilterContextParameters() buffersrcContextParameters := astiav.AllocBuffersrcFilterContextParameters()
defer bfcp.Free() defer buffersrcContextParameters.Free()
bfcp.SetHardwareFrameContext(decCodecContext.HardwareFrameContext()) buffersrcContextParameters.SetHardwareFrameContext(decCodecContext.HardwareFrameContext())
buffersrcContextParameters.SetHeight(decCodecContext.Height())
buffersrcContextParameters.SetPixelFormat(decCodecContext.PixelFormat())
buffersrcContextParameters.SetSampleAspectRatio(decCodecContext.SampleAspectRatio())
buffersrcContextParameters.SetTimeBase(inputStream.TimeBase())
buffersrcContextParameters.SetWidth(decCodecContext.Width())
// Set buffersrc parameters // Set buffersrc context parameters
if err = buffersrcContext.SetParameters(bfcp); err != nil { if err = buffersrcContext.SetParameters(buffersrcContextParameters); err != nil {
err = fmt.Errorf("main: setting buffersrc parameters failed: %w", err) err = fmt.Errorf("main: setting buffersrc context parameters failed: %w", err)
return
}
// Initialize buffersrc context
if err = buffersrcContext.Initialize(); err != nil {
err = fmt.Errorf("main: initializing buffersrc context failed: %w", err)
return return
} }

View File

@@ -5,7 +5,6 @@ import (
"flag" "flag"
"fmt" "fmt"
"log" "log"
"strconv"
"strings" "strings"
"github.com/asticode/go-astiav" "github.com/asticode/go-astiav"
@@ -378,29 +377,29 @@ func initFilters() (err error) {
} }
c.Add(inputs.Free) c.Add(inputs.Free)
// Create buffersrc context parameters
buffersrcContextParameters := astiav.AllocBuffersrcFilterContextParameters()
defer buffersrcContextParameters.Free()
// Switch on media type // Switch on media type
var args astiav.FilterArgs
var buffersrc, buffersink *astiav.Filter var buffersrc, buffersink *astiav.Filter
var content string var content string
switch s.decCodecContext.MediaType() { switch s.decCodecContext.MediaType() {
case astiav.MediaTypeAudio: case astiav.MediaTypeAudio:
args = astiav.FilterArgs{
"channel_layout": s.decCodecContext.ChannelLayout().String(),
"sample_fmt": s.decCodecContext.SampleFormat().Name(),
"sample_rate": strconv.Itoa(s.decCodecContext.SampleRate()),
"time_base": s.decCodecContext.TimeBase().String(),
}
buffersrc = astiav.FindFilterByName("abuffer") buffersrc = astiav.FindFilterByName("abuffer")
buffersrcContextParameters.SetChannelLayout(s.decCodecContext.ChannelLayout())
buffersrcContextParameters.SetSampleFormat(s.decCodecContext.SampleFormat())
buffersrcContextParameters.SetSampleRate(s.decCodecContext.SampleRate())
buffersrcContextParameters.SetTimeBase(s.decCodecContext.TimeBase())
buffersink = astiav.FindFilterByName("abuffersink") buffersink = astiav.FindFilterByName("abuffersink")
content = fmt.Sprintf("aformat=sample_fmts=%s:channel_layouts=%s", s.encCodecContext.SampleFormat().Name(), s.encCodecContext.ChannelLayout().String()) content = fmt.Sprintf("aformat=sample_fmts=%s:channel_layouts=%s", s.encCodecContext.SampleFormat().Name(), s.encCodecContext.ChannelLayout().String())
default: default:
args = astiav.FilterArgs{
"pix_fmt": strconv.Itoa(int(s.decCodecContext.PixelFormat())),
"pixel_aspect": s.decCodecContext.SampleAspectRatio().String(),
"time_base": s.inputStream.TimeBase().String(),
"video_size": strconv.Itoa(s.decCodecContext.Width()) + "x" + strconv.Itoa(s.decCodecContext.Height()),
}
buffersrc = astiav.FindFilterByName("buffer") buffersrc = astiav.FindFilterByName("buffer")
buffersrcContextParameters.SetHeight(s.decCodecContext.Height())
buffersrcContextParameters.SetPixelFormat(s.decCodecContext.PixelFormat())
buffersrcContextParameters.SetSampleAspectRatio(s.decCodecContext.SampleAspectRatio())
buffersrcContextParameters.SetTimeBase(s.inputStream.TimeBase())
buffersrcContextParameters.SetWidth(s.decCodecContext.Width())
buffersink = astiav.FindFilterByName("buffersink") buffersink = astiav.FindFilterByName("buffersink")
content = fmt.Sprintf("format=pix_fmts=%s", s.encCodecContext.PixelFormat().Name()) content = fmt.Sprintf("format=pix_fmts=%s", s.encCodecContext.PixelFormat().Name())
} }
@@ -416,15 +415,27 @@ func initFilters() (err error) {
} }
// Create filter contexts // Create filter contexts
if s.buffersrcContext, err = s.filterGraph.NewBuffersrcFilterContext(buffersrc, "in", args); err != nil { if s.buffersrcContext, err = s.filterGraph.NewBuffersrcFilterContext(buffersrc, "in"); err != nil {
err = fmt.Errorf("main: creating buffersrc context failed: %w", err) err = fmt.Errorf("main: creating buffersrc context failed: %w", err)
return return
} }
if s.buffersinkContext, err = s.filterGraph.NewBuffersinkFilterContext(buffersink, "out", nil); err != nil { if s.buffersinkContext, err = s.filterGraph.NewBuffersinkFilterContext(buffersink, "out"); err != nil {
err = fmt.Errorf("main: creating buffersink context failed: %w", err) err = fmt.Errorf("main: creating buffersink context failed: %w", err)
return return
} }
// Set buffersrc context parameters
if err = s.buffersrcContext.SetParameters(buffersrcContextParameters); err != nil {
err = fmt.Errorf("main: setting buffersrc context parameters failed: %w", err)
return
}
// Initialize buffersrc context
if err = s.buffersrcContext.Initialize(); err != nil {
err = fmt.Errorf("main: initializing buffersrc context failed: %w", err)
return
}
// Update outputs // Update outputs
outputs.SetName("in") outputs.SetName("in")
outputs.SetFilterContext(s.buffersrcContext.FilterContext()) outputs.SetFilterContext(s.buffersrcContext.FilterContext())

View File

@@ -3,7 +3,7 @@ package astiav
//#include <libavfilter/avfilter.h> //#include <libavfilter/avfilter.h>
import "C" import "C"
import ( import (
"strings" "errors"
"unsafe" "unsafe"
) )
@@ -84,47 +84,29 @@ func (g *FilterGraph) SetThreadType(t ThreadType) {
g.c.thread_type = C.int(t) 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 // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#gac0788a9ab6966dba9318b5d5c7524fea
func (g *FilterGraph) NewFilterContext(f *Filter, name string, args FilterArgs) (*FilterContext, error) { func (g *FilterGraph) NewBuffersinkFilterContext(f *Filter, name string) (*BuffersinkFilterContext, error) {
ca := (*C.char)(nil) cname := C.CString(name)
if len(args) > 0 { defer C.free(unsafe.Pointer(cname))
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 var c *C.AVFilterContext
if err := newError(C.avfilter_graph_create_filter(&c, f.c, cn, ca, nil, g.c)); err != nil { if err := newError(C.avfilter_graph_create_filter(&c, f.c, cname, nil, nil, g.c)); err != nil {
return nil, err return nil, err
} }
fc := newFilterContext(c) fc := newFilterContext(c)
g.fcs = append(g.fcs, fc) 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 return newBuffersinkFilterContext(fc), nil
} }
func (g *FilterGraph) NewBuffersrcFilterContext(f *Filter, name string, args FilterArgs) (*BuffersrcFilterContext, error) { // https://ffmpeg.org/doxygen/7.0/group__lavfi.html#gaa9af17ecf4c5c87307b57cf08411088b
fc, err := g.NewFilterContext(f, name, args) func (g *FilterGraph) NewBuffersrcFilterContext(f *Filter, name string) (*BuffersrcFilterContext, error) {
if err != nil { cname := C.CString(name)
return nil, err 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 return newBuffersrcFilterContext(fc), nil
} }

View File

@@ -5,7 +5,6 @@ package astiav
import ( import (
"fmt" "fmt"
"strconv"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -49,13 +48,24 @@ func TestFilterGraph(t *testing.T) {
type buffersrc struct { type buffersrc struct {
name string name string
} }
type buffersrcParameters struct {
channelLayout ChannelLayout
height int
mediaType MediaType
pixelFormat PixelFormat
sampleAspectRatio Rational
sampleFormat SampleFormat
sampleRate int
timeBase Rational
width int
}
type graph struct { type graph struct {
buffersink buffersink buffersink buffersink
buffersrc buffersrc buffersrc buffersrc
commands []command commands []command
content string content string
s string s string
sources []FilterArgs sources []buffersrcParameters
} }
for _, v := range []graph{ for _, v := range []graph{
{ {
@@ -89,13 +99,14 @@ func TestFilterGraph(t *testing.T) {
}, },
content: "[input_1]scale=4x8,settb=1/4,fps=fps=4/1,format=pix_fmts=yuv420p,setsar=2/1", content: "[input_1]scale=4x8,settb=1/4,fps=fps=4/1,format=pix_fmts=yuv420p,setsar=2/1",
s: " +--------------+\nParsed_setsar_4:default--[4x8 2:1 yuv420p]--default| filter_out |\n | (buffersink) |\n +--------------+\n\n+-------------+\n| filter_in_1 |default--[2x4 1:2 rgba]--Parsed_scale_0:default\n| (buffer) |\n+-------------+\n\n +----------------+\nfilter_in_1:default--[2x4 1:2 rgba]--default| Parsed_scale_0 |default--[4x8 1:2 yuv420p]--Parsed_settb_1:default\n | (scale) |\n +----------------+\n\n +----------------+\nParsed_scale_0:default--[4x8 1:2 yuv420p]--default| Parsed_settb_1 |default--[4x8 1:2 yuv420p]--Parsed_fps_2:default\n | (settb) |\n +----------------+\n\n +--------------+\nParsed_settb_1:default--[4x8 1:2 yuv420p]--default| Parsed_fps_2 |default--[4x8 1:2 yuv420p]--Parsed_format_3:default\n | (fps) |\n +--------------+\n\n +-----------------+\nParsed_fps_2:default--[4x8 1:2 yuv420p]--default| Parsed_format_3 |default--[4x8 1:2 yuv420p]--Parsed_setsar_4:default\n | (format) |\n +-----------------+\n\n +-----------------+\nParsed_format_3:default--[4x8 1:2 yuv420p]--default| Parsed_setsar_4 |default--[4x8 2:1 yuv420p]--filter_out:default\n | (setsar) |\n +-----------------+\n\n", s: " +--------------+\nParsed_setsar_4:default--[4x8 2:1 yuv420p]--default| filter_out |\n | (buffersink) |\n +--------------+\n\n+-------------+\n| filter_in_1 |default--[2x4 1:2 rgba]--Parsed_scale_0:default\n| (buffer) |\n+-------------+\n\n +----------------+\nfilter_in_1:default--[2x4 1:2 rgba]--default| Parsed_scale_0 |default--[4x8 1:2 yuv420p]--Parsed_settb_1:default\n | (scale) |\n +----------------+\n\n +----------------+\nParsed_scale_0:default--[4x8 1:2 yuv420p]--default| Parsed_settb_1 |default--[4x8 1:2 yuv420p]--Parsed_fps_2:default\n | (settb) |\n +----------------+\n\n +--------------+\nParsed_settb_1:default--[4x8 1:2 yuv420p]--default| Parsed_fps_2 |default--[4x8 1:2 yuv420p]--Parsed_format_3:default\n | (fps) |\n +--------------+\n\n +-----------------+\nParsed_fps_2:default--[4x8 1:2 yuv420p]--default| Parsed_format_3 |default--[4x8 1:2 yuv420p]--Parsed_setsar_4:default\n | (format) |\n +-----------------+\n\n +-----------------+\nParsed_format_3:default--[4x8 1:2 yuv420p]--default| Parsed_setsar_4 |default--[4x8 2:1 yuv420p]--filter_out:default\n | (setsar) |\n +-----------------+\n\n",
sources: []FilterArgs{ sources: []buffersrcParameters{
{ {
"height": "4", height: 4,
"pix_fmt": strconv.Itoa(int(PixelFormatRgba)), mediaType: MediaTypeVideo,
"sar": "1/2", pixelFormat: PixelFormatRgba,
"time_base": "1/2", sampleAspectRatio: NewRational(1, 2),
"width": "2", timeBase: NewRational(1, 2),
width: 2,
}, },
}, },
}, },
@@ -111,12 +122,13 @@ func TestFilterGraph(t *testing.T) {
buffersrc: buffersrc{name: "abuffer"}, buffersrc: buffersrc{name: "abuffer"},
content: "[input_1]aformat=sample_fmts=s16:channel_layouts=stereo:sample_rates=3,asettb=1/4", 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", 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{ sources: []buffersrcParameters{
{ {
"channel_layout": ChannelLayoutMono.String(), channelLayout: ChannelLayoutMono,
"sample_fmt": strconv.Itoa(int(SampleFormatFltp)), mediaType: MediaTypeAudio,
"sample_rate": "2", sampleFormat: SampleFormatFltp,
"time_base": "1/2", sampleRate: 2,
timeBase: NewRational(1, 2),
}, },
}, },
}, },
@@ -130,7 +142,7 @@ func TestFilterGraph(t *testing.T) {
buffersink := FindFilterByName(v.buffersink.name) buffersink := FindFilterByName(v.buffersink.name)
require.NotNil(t, buffersink) require.NotNil(t, buffersink)
buffersinkContext, err := fg.NewBuffersinkFilterContext(buffersink, "filter_out", nil) buffersinkContext, err := fg.NewBuffersinkFilterContext(buffersink, "filter_out")
require.NoError(t, err) require.NoError(t, err)
cl = buffersinkContext.FilterContext().Class() cl = buffersinkContext.FilterContext().Class()
require.NotNil(t, cl) require.NotNil(t, cl)
@@ -152,8 +164,25 @@ func TestFilterGraph(t *testing.T) {
var buffersrcContexts []*BuffersrcFilterContext var buffersrcContexts []*BuffersrcFilterContext
for idx, src := range v.sources { for idx, src := range v.sources {
buffersrcContext, err := fg.NewBuffersrcFilterContext(buffersrc, fmt.Sprintf("filter_in_%d", idx+1), src) buffersrcContext, err := fg.NewBuffersrcFilterContext(buffersrc, fmt.Sprintf("filter_in_%d", idx+1))
require.NoError(t, err) require.NoError(t, err)
buffersrcContextParameters := AllocBuffersrcFilterContextParameters()
defer buffersrcContextParameters.Free()
switch src.mediaType {
case MediaTypeAudio:
buffersrcContextParameters.SetChannelLayout(src.channelLayout)
buffersrcContextParameters.SetSampleFormat(src.sampleFormat)
buffersrcContextParameters.SetSampleRate(src.sampleRate)
buffersrcContextParameters.SetTimeBase(src.timeBase)
default:
buffersrcContextParameters.SetHeight(src.height)
buffersrcContextParameters.SetPixelFormat(src.pixelFormat)
buffersrcContextParameters.SetSampleAspectRatio(src.sampleAspectRatio)
buffersrcContextParameters.SetTimeBase(src.timeBase)
buffersrcContextParameters.SetWidth(src.width)
}
buffersrcContext.SetParameters(buffersrcContextParameters)
require.NoError(t, buffersrcContext.Initialize())
buffersrcContexts = append(buffersrcContexts, buffersrcContext) buffersrcContexts = append(buffersrcContexts, buffersrcContext)
o := AllocFilterInOut() o := AllocFilterInOut()