mirror of
https://github.com/asticode/go-astiav.git
synced 2025-10-05 08:06:59 +08:00
Removed FilterLink and added BuffersinkFilterContext and BuffersrcFilterContext
This commit is contained in:
4
BREAKING_CHANGES.md
Normal file
4
BREAKING_CHANGES.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# v0.24.0
|
||||
|
||||
- use `FilterGraph`.`NewBuffersinkFilterContext` and `FilterGraph`.`NewBuffersrcFilterContext` instead of `FilterGraph`.`NewFilterContext` when creating `buffersink` and `buffersrc` filter contexts and use `BuffersinkFilterContext`.`GetFrame` and `BuffersrcFilterContext`.`AddFrame` to manipulate them. Use `BuffersinkFilterContext`.`FilterContext` and `BuffersrcFilterContext`.`FilterContext` in `FilterInOut`.`SetFilterContext`.
|
||||
- `FilterLink` has been removed and methods like `BuffersinkFilterContext`.`ChannelLayout` have been added instead
|
@@ -58,3 +58,7 @@ export PKG_CONFIG_PATH="{{ path to your working directory }}/tmp/n7.0/lib/pkgcon
|
||||
# Why astiav?
|
||||
|
||||
After maintaining for several years the most starred [fork](https://github.com/asticode/goav) of [goav](https://github.com/giorgisio/goav), I've decided to write from scratch my own C bindings to fix most of the problems I still encountered using `goav`.
|
||||
|
||||
# Breaking changes
|
||||
|
||||
You can see the list of breaking changes [here](BREAKING_CHANGES.md).
|
@@ -23,8 +23,8 @@ var (
|
||||
)
|
||||
|
||||
type stream struct {
|
||||
buffersinkContext *astiav.FilterContext
|
||||
buffersrcContext *astiav.FilterContext
|
||||
buffersinkContext *astiav.BuffersinkFilterContext
|
||||
buffersrcContext *astiav.BuffersrcFilterContext
|
||||
decCodec *astiav.Codec
|
||||
decCodecContext *astiav.CodecContext
|
||||
decFrame *astiav.Frame
|
||||
@@ -232,7 +232,7 @@ func initFilter() (err error) {
|
||||
}
|
||||
|
||||
// Create filter contexts
|
||||
if s.buffersrcContext, err = s.filterGraph.NewFilterContext(buffersrc, "in", astiav.FilterArgs{
|
||||
if s.buffersrcContext, err = s.filterGraph.NewBuffersrcFilterContext(buffersrc, "in", astiav.FilterArgs{
|
||||
"pix_fmt": strconv.Itoa(int(s.decCodecContext.PixelFormat())),
|
||||
"pixel_aspect": s.decCodecContext.SampleAspectRatio().String(),
|
||||
"time_base": s.inputStream.TimeBase().String(),
|
||||
@@ -241,20 +241,20 @@ func initFilter() (err error) {
|
||||
err = fmt.Errorf("main: creating buffersrc context failed: %w", err)
|
||||
return
|
||||
}
|
||||
if s.buffersinkContext, err = s.filterGraph.NewFilterContext(buffersink, "in", nil); err != nil {
|
||||
if s.buffersinkContext, err = s.filterGraph.NewBuffersinkFilterContext(buffersink, "in", nil); err != nil {
|
||||
err = fmt.Errorf("main: creating buffersink context failed: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Update outputs
|
||||
outputs.SetName("in")
|
||||
outputs.SetFilterContext(s.buffersrcContext)
|
||||
outputs.SetFilterContext(s.buffersrcContext.FilterContext())
|
||||
outputs.SetPadIdx(0)
|
||||
outputs.SetNext(nil)
|
||||
|
||||
// Update inputs
|
||||
inputs.SetName("out")
|
||||
inputs.SetFilterContext(s.buffersinkContext)
|
||||
inputs.SetFilterContext(s.buffersinkContext.FilterContext())
|
||||
inputs.SetPadIdx(0)
|
||||
inputs.SetNext(nil)
|
||||
|
||||
@@ -278,7 +278,7 @@ func initFilter() (err error) {
|
||||
|
||||
func filterFrame(f *astiav.Frame, s *stream) (err error) {
|
||||
// Add frame
|
||||
if err = s.buffersrcContext.BuffersrcAddFrame(f, astiav.NewBuffersrcFlags(astiav.BuffersrcFlagKeepRef)); err != nil {
|
||||
if err = s.buffersrcContext.AddFrame(f, astiav.NewBuffersrcFlags(astiav.BuffersrcFlagKeepRef)); err != nil {
|
||||
err = fmt.Errorf("main: adding frame failed: %w", err)
|
||||
return
|
||||
}
|
||||
@@ -289,7 +289,7 @@ func filterFrame(f *astiav.Frame, s *stream) (err error) {
|
||||
s.filterFrame.Unref()
|
||||
|
||||
// Get frame
|
||||
if err = s.buffersinkContext.BuffersinkGetFrame(s.filterFrame, astiav.NewBuffersinkFlags()); err != nil {
|
||||
if err = s.buffersinkContext.GetFrame(s.filterFrame, astiav.NewBuffersinkFlags()); err != nil {
|
||||
if errors.Is(err, astiav.ErrEof) || errors.Is(err, astiav.ErrEagain) {
|
||||
err = nil
|
||||
break
|
||||
|
@@ -25,8 +25,8 @@ var (
|
||||
)
|
||||
|
||||
type stream struct {
|
||||
buffersinkContext *astiav.FilterContext
|
||||
buffersrcContext *astiav.FilterContext
|
||||
buffersinkContext *astiav.BuffersinkFilterContext
|
||||
buffersrcContext *astiav.BuffersrcFilterContext
|
||||
decCodec *astiav.Codec
|
||||
decCodecContext *astiav.CodecContext
|
||||
decFrame *astiav.Frame
|
||||
@@ -395,24 +395,24 @@ func initFilters() (err error) {
|
||||
}
|
||||
|
||||
// Create filter contexts
|
||||
if s.buffersrcContext, err = s.filterGraph.NewFilterContext(buffersrc, "in", args); err != nil {
|
||||
if s.buffersrcContext, err = s.filterGraph.NewBuffersrcFilterContext(buffersrc, "in", args); err != nil {
|
||||
err = fmt.Errorf("main: creating buffersrc context failed: %w", err)
|
||||
return
|
||||
}
|
||||
if s.buffersinkContext, err = s.filterGraph.NewFilterContext(buffersink, "out", nil); err != nil {
|
||||
if s.buffersinkContext, err = s.filterGraph.NewBuffersinkFilterContext(buffersink, "out", nil); err != nil {
|
||||
err = fmt.Errorf("main: creating buffersink context failed: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Update outputs
|
||||
outputs.SetName("in")
|
||||
outputs.SetFilterContext(s.buffersrcContext)
|
||||
outputs.SetFilterContext(s.buffersrcContext.FilterContext())
|
||||
outputs.SetPadIdx(0)
|
||||
outputs.SetNext(nil)
|
||||
|
||||
// Update inputs
|
||||
inputs.SetName("out")
|
||||
inputs.SetFilterContext(s.buffersinkContext)
|
||||
inputs.SetFilterContext(s.buffersinkContext.FilterContext())
|
||||
inputs.SetPadIdx(0)
|
||||
inputs.SetNext(nil)
|
||||
|
||||
@@ -441,7 +441,7 @@ func initFilters() (err error) {
|
||||
|
||||
func filterEncodeWriteFrame(f *astiav.Frame, s *stream) (err error) {
|
||||
// Add frame
|
||||
if err = s.buffersrcContext.BuffersrcAddFrame(f, astiav.NewBuffersrcFlags(astiav.BuffersrcFlagKeepRef)); err != nil {
|
||||
if err = s.buffersrcContext.AddFrame(f, astiav.NewBuffersrcFlags(astiav.BuffersrcFlagKeepRef)); err != nil {
|
||||
err = fmt.Errorf("main: adding frame failed: %w", err)
|
||||
return
|
||||
}
|
||||
@@ -452,7 +452,7 @@ func filterEncodeWriteFrame(f *astiav.Frame, s *stream) (err error) {
|
||||
s.filterFrame.Unref()
|
||||
|
||||
// Get frame
|
||||
if err = s.buffersinkContext.BuffersinkGetFrame(s.filterFrame, astiav.NewBuffersinkFlags()); err != nil {
|
||||
if err = s.buffersinkContext.GetFrame(s.filterFrame, astiav.NewBuffersinkFlags()); err != nil {
|
||||
if errors.Is(err, astiav.ErrEof) || errors.Is(err, astiav.ErrEagain) {
|
||||
err = nil
|
||||
break
|
||||
|
@@ -6,7 +6,6 @@ package astiav
|
||||
//#include <libavutil/frame.h>
|
||||
import "C"
|
||||
import (
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -38,46 +37,96 @@ func (fc *FilterContext) Free() {
|
||||
}
|
||||
}
|
||||
|
||||
func (fc *FilterContext) BuffersrcAddFrame(f *Frame, fs BuffersrcFlags) error {
|
||||
var cf *C.AVFrame
|
||||
if f != nil {
|
||||
cf = f.c
|
||||
}
|
||||
return newError(C.av_buffersrc_add_frame_flags(fc.c, cf, C.int(fs)))
|
||||
}
|
||||
|
||||
func (fc *FilterContext) BuffersinkGetFrame(f *Frame, fs BuffersinkFlags) error {
|
||||
var cf *C.AVFrame
|
||||
if f != nil {
|
||||
cf = f.c
|
||||
}
|
||||
return newError(C.av_buffersink_get_frame_flags(fc.c, cf, C.int(fs)))
|
||||
}
|
||||
|
||||
func (fc *FilterContext) Class() *Class {
|
||||
return newClassFromC(unsafe.Pointer(fc.c))
|
||||
}
|
||||
|
||||
func (fc *FilterContext) NbInputs() int {
|
||||
return int(fc.c.nb_inputs)
|
||||
type BuffersinkFilterContext struct {
|
||||
fc *FilterContext
|
||||
}
|
||||
|
||||
func (fc *FilterContext) NbOutputs() int {
|
||||
return int(fc.c.nb_outputs)
|
||||
func newBuffersinkFilterContext(fc *FilterContext) *BuffersinkFilterContext {
|
||||
return &BuffersinkFilterContext{fc: fc}
|
||||
}
|
||||
|
||||
func (fc *FilterContext) Inputs() (ls []*FilterLink) {
|
||||
lcs := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.AVFilterLink)(nil))](*C.AVFilterLink))(unsafe.Pointer(fc.c.inputs))
|
||||
for i := 0; i < fc.NbInputs(); i++ {
|
||||
ls = append(ls, newFilterLinkFromC(lcs[i]))
|
||||
func (bfc *BuffersinkFilterContext) ChannelLayout() ChannelLayout {
|
||||
var cl C.AVChannelLayout
|
||||
C.av_buffersink_get_ch_layout(bfc.fc.c, &cl)
|
||||
return newChannelLayoutFromC(&cl)
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) ColorRange() ColorRange {
|
||||
return ColorRange(C.av_buffersink_get_color_range(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) ColorSpace() ColorSpace {
|
||||
return ColorSpace(C.av_buffersink_get_colorspace(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) FilterContext() *FilterContext {
|
||||
return bfc.fc
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) FrameRate() Rational {
|
||||
return newRationalFromC(C.av_buffersink_get_frame_rate(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) GetFrame(f *Frame, fs BuffersinkFlags) error {
|
||||
var cf *C.AVFrame
|
||||
if f != nil {
|
||||
cf = f.c
|
||||
}
|
||||
return
|
||||
return newError(C.av_buffersink_get_frame_flags(bfc.fc.c, cf, C.int(fs)))
|
||||
}
|
||||
|
||||
func (fc *FilterContext) Outputs() (ls []*FilterLink) {
|
||||
lcs := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.AVFilterLink)(nil))](*C.AVFilterLink))(unsafe.Pointer(fc.c.outputs))
|
||||
for i := 0; i < fc.NbOutputs(); i++ {
|
||||
ls = append(ls, newFilterLinkFromC(lcs[i]))
|
||||
}
|
||||
return
|
||||
func (bfc *BuffersinkFilterContext) Height() int {
|
||||
return int(C.av_buffersink_get_h(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) MediaType() MediaType {
|
||||
return MediaType(C.av_buffersink_get_type(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) PixelFormat() PixelFormat {
|
||||
return PixelFormat(C.av_buffersink_get_format(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) SampleAspectRatio() Rational {
|
||||
return newRationalFromC(C.av_buffersink_get_sample_aspect_ratio(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) SampleFormat() SampleFormat {
|
||||
return SampleFormat(C.av_buffersink_get_format(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) SampleRate() int {
|
||||
return int(C.av_buffersink_get_sample_rate(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) TimeBase() Rational {
|
||||
return newRationalFromC(C.av_buffersink_get_time_base(bfc.fc.c))
|
||||
}
|
||||
|
||||
func (bfc *BuffersinkFilterContext) Width() int {
|
||||
return int(C.av_buffersink_get_w(bfc.fc.c))
|
||||
}
|
||||
|
||||
type BuffersrcFilterContext struct {
|
||||
fc *FilterContext
|
||||
}
|
||||
|
||||
func newBuffersrcFilterContext(fc *FilterContext) *BuffersrcFilterContext {
|
||||
return &BuffersrcFilterContext{fc: fc}
|
||||
}
|
||||
|
||||
func (bfc *BuffersrcFilterContext) AddFrame(f *Frame, fs BuffersrcFlags) error {
|
||||
var cf *C.AVFrame
|
||||
if f != nil {
|
||||
cf = f.c
|
||||
}
|
||||
return newError(C.av_buffersrc_add_frame_flags(bfc.fc.c, cf, C.int(fs)))
|
||||
}
|
||||
|
||||
func (bfc *BuffersrcFilterContext) FilterContext() *FilterContext {
|
||||
return bfc.fc
|
||||
}
|
||||
|
@@ -103,6 +103,22 @@ func (g *FilterGraph) NewFilterContext(f *Filter, name string, args FilterArgs)
|
||||
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
|
||||
}
|
||||
|
||||
func (g *FilterGraph) Parse(content string, inputs, outputs *FilterInOut) error {
|
||||
cc := C.CString(content)
|
||||
defer C.free(unsafe.Pointer(cc))
|
||||
|
@@ -31,13 +31,14 @@ func TestFilterGraph(t *testing.T) {
|
||||
target string
|
||||
withError bool
|
||||
}
|
||||
type link struct {
|
||||
type buffersink struct {
|
||||
channelLayout ChannelLayout
|
||||
colorRange ColorRange
|
||||
colorSpace ColorSpace
|
||||
frameRate Rational
|
||||
height int
|
||||
mediaType MediaType
|
||||
name string
|
||||
pixelFormat PixelFormat
|
||||
sampleAspectRatio Rational
|
||||
sampleFormat SampleFormat
|
||||
@@ -45,30 +46,32 @@ func TestFilterGraph(t *testing.T) {
|
||||
timeBase Rational
|
||||
width int
|
||||
}
|
||||
type buffersrc struct {
|
||||
name string
|
||||
}
|
||||
type graph struct {
|
||||
buffersinkExpectedInput link
|
||||
buffersinkName string
|
||||
buffersrcName string
|
||||
commands []command
|
||||
content string
|
||||
s string
|
||||
sources []FilterArgs
|
||||
buffersink buffersink
|
||||
buffersrc buffersrc
|
||||
commands []command
|
||||
content string
|
||||
s string
|
||||
sources []FilterArgs
|
||||
}
|
||||
for _, v := range []graph{
|
||||
{
|
||||
buffersinkExpectedInput: link{
|
||||
buffersink: buffersink{
|
||||
colorRange: ColorRangeUnspecified,
|
||||
colorSpace: ColorSpaceUnspecified,
|
||||
frameRate: NewRational(4, 1),
|
||||
height: 8,
|
||||
mediaType: MediaTypeVideo,
|
||||
name: "buffersink",
|
||||
pixelFormat: PixelFormatYuv420P,
|
||||
sampleAspectRatio: NewRational(2, 1),
|
||||
timeBase: NewRational(1, 4),
|
||||
width: 4,
|
||||
},
|
||||
buffersinkName: "buffersink",
|
||||
buffersrcName: "buffer",
|
||||
buffersrc: buffersrc{name: "buffer"},
|
||||
commands: []command{
|
||||
{
|
||||
args: "a",
|
||||
@@ -97,17 +100,17 @@ func TestFilterGraph(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
buffersinkExpectedInput: link{
|
||||
buffersink: buffersink{
|
||||
channelLayout: ChannelLayoutStereo,
|
||||
mediaType: MediaTypeAudio,
|
||||
name: "abuffersink",
|
||||
sampleFormat: SampleFormatS16,
|
||||
sampleRate: 3,
|
||||
timeBase: NewRational(1, 4),
|
||||
},
|
||||
buffersinkName: "abuffersink",
|
||||
buffersrcName: "abuffer",
|
||||
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",
|
||||
buffersrc: buffersrc{name: "abuffer"},
|
||||
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(),
|
||||
@@ -122,21 +125,21 @@ func TestFilterGraph(t *testing.T) {
|
||||
require.NotNil(t, fg)
|
||||
defer fg.Free()
|
||||
|
||||
buffersrc := FindFilterByName(v.buffersrcName)
|
||||
buffersrc := FindFilterByName(v.buffersrc.name)
|
||||
require.NotNil(t, buffersrc)
|
||||
buffersink := FindFilterByName(v.buffersinkName)
|
||||
buffersink := FindFilterByName(v.buffersink.name)
|
||||
require.NotNil(t, buffersink)
|
||||
|
||||
buffersinkContext, err := fg.NewFilterContext(buffersink, "filter_out", nil)
|
||||
buffersinkContext, err := fg.NewBuffersinkFilterContext(buffersink, "filter_out", nil)
|
||||
require.NoError(t, err)
|
||||
cl = buffersinkContext.Class()
|
||||
cl = buffersinkContext.FilterContext().Class()
|
||||
require.NotNil(t, cl)
|
||||
require.Equal(t, "AVFilter", cl.Name())
|
||||
|
||||
inputs := AllocFilterInOut()
|
||||
defer inputs.Free()
|
||||
inputs.SetName("out")
|
||||
inputs.SetFilterContext(buffersinkContext)
|
||||
inputs.SetFilterContext(buffersinkContext.FilterContext())
|
||||
inputs.SetPadIdx(0)
|
||||
inputs.SetNext(nil)
|
||||
|
||||
@@ -147,15 +150,15 @@ func TestFilterGraph(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
|
||||
var buffersrcContexts []*FilterContext
|
||||
var buffersrcContexts []*BuffersrcFilterContext
|
||||
for idx, src := range v.sources {
|
||||
buffersrcContext, err := fg.NewFilterContext(buffersrc, fmt.Sprintf("filter_in_%d", idx+1), src)
|
||||
buffersrcContext, err := fg.NewBuffersrcFilterContext(buffersrc, fmt.Sprintf("filter_in_%d", idx+1), src)
|
||||
require.NoError(t, err)
|
||||
buffersrcContexts = append(buffersrcContexts, buffersrcContext)
|
||||
|
||||
o := AllocFilterInOut()
|
||||
o.SetName(fmt.Sprintf("input_%d", idx+1))
|
||||
o.SetFilterContext(buffersrcContext)
|
||||
o.SetFilterContext(buffersrcContext.FilterContext())
|
||||
o.SetPadIdx(0)
|
||||
o.SetNext(outputs)
|
||||
|
||||
@@ -165,33 +168,21 @@ func TestFilterGraph(t *testing.T) {
|
||||
require.NoError(t, fg.Parse(v.content, inputs, outputs))
|
||||
require.NoError(t, fg.Configure())
|
||||
|
||||
require.Equal(t, 1, buffersinkContext.NbInputs())
|
||||
links := buffersinkContext.Inputs()
|
||||
require.Equal(t, 1, len(links))
|
||||
e, g := v.buffersinkExpectedInput, links[0]
|
||||
require.Equal(t, e.frameRate, g.FrameRate())
|
||||
require.Equal(t, e.mediaType, g.MediaType())
|
||||
require.Equal(t, e.timeBase, g.TimeBase())
|
||||
switch e.mediaType {
|
||||
require.Equal(t, v.buffersink.frameRate, buffersinkContext.FrameRate())
|
||||
require.Equal(t, v.buffersink.mediaType, buffersinkContext.MediaType())
|
||||
require.Equal(t, v.buffersink.timeBase, buffersinkContext.TimeBase())
|
||||
switch v.buffersink.mediaType {
|
||||
case MediaTypeAudio:
|
||||
require.True(t, e.channelLayout.Equal(g.ChannelLayout()))
|
||||
require.Equal(t, e.sampleFormat, g.SampleFormat())
|
||||
require.Equal(t, e.sampleRate, g.SampleRate())
|
||||
require.True(t, v.buffersink.channelLayout.Equal(buffersinkContext.ChannelLayout()))
|
||||
require.Equal(t, v.buffersink.sampleFormat, buffersinkContext.SampleFormat())
|
||||
require.Equal(t, v.buffersink.sampleRate, buffersinkContext.SampleRate())
|
||||
default:
|
||||
require.Equal(t, e.colorRange, g.ColorRange())
|
||||
require.Equal(t, e.colorSpace, g.ColorSpace())
|
||||
require.Equal(t, e.height, g.Height())
|
||||
require.Equal(t, e.pixelFormat, g.PixelFormat())
|
||||
require.Equal(t, e.sampleAspectRatio, g.SampleAspectRatio())
|
||||
require.Equal(t, e.width, g.Width())
|
||||
}
|
||||
|
||||
for _, buffersrcContext := range buffersrcContexts {
|
||||
require.Equal(t, 0, buffersrcContext.NbInputs())
|
||||
require.Equal(t, 1, buffersrcContext.NbOutputs())
|
||||
links := buffersrcContext.Outputs()
|
||||
require.Equal(t, 1, len(links))
|
||||
require.Equal(t, v.buffersinkExpectedInput.mediaType, links[0].MediaType())
|
||||
require.Equal(t, v.buffersink.colorRange, buffersinkContext.ColorRange())
|
||||
require.Equal(t, v.buffersink.colorSpace, buffersinkContext.ColorSpace())
|
||||
require.Equal(t, v.buffersink.height, buffersinkContext.Height())
|
||||
require.Equal(t, v.buffersink.pixelFormat, buffersinkContext.PixelFormat())
|
||||
require.Equal(t, v.buffersink.sampleAspectRatio, buffersinkContext.SampleAspectRatio())
|
||||
require.Equal(t, v.buffersink.width, buffersinkContext.Width())
|
||||
}
|
||||
|
||||
require.Equal(t, v.s, fg.String())
|
||||
|
@@ -1,65 +0,0 @@
|
||||
package astiav
|
||||
|
||||
//#include <libavfilter/avfilter.h>
|
||||
import "C"
|
||||
|
||||
// https://github.com/FFmpeg/FFmpeg/blob/n5.0/libavfilter/avfilter.h#L471
|
||||
type FilterLink struct {
|
||||
c *C.AVFilterLink
|
||||
}
|
||||
|
||||
func newFilterLinkFromC(c *C.AVFilterLink) *FilterLink {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return &FilterLink{c: c}
|
||||
}
|
||||
|
||||
func (l *FilterLink) ChannelLayout() ChannelLayout {
|
||||
v, _ := newChannelLayoutFromC(&l.c.ch_layout).clone()
|
||||
return v
|
||||
}
|
||||
|
||||
func (l *FilterLink) ColorRange() ColorRange {
|
||||
return ColorRange(l.c.color_range)
|
||||
}
|
||||
|
||||
func (l *FilterLink) ColorSpace() ColorSpace {
|
||||
return ColorSpace(l.c.colorspace)
|
||||
}
|
||||
|
||||
func (l *FilterLink) FrameRate() Rational {
|
||||
return newRationalFromC(l.c.frame_rate)
|
||||
}
|
||||
|
||||
func (l *FilterLink) Height() int {
|
||||
return int(l.c.h)
|
||||
}
|
||||
|
||||
func (l *FilterLink) MediaType() MediaType {
|
||||
return MediaType(l.c._type)
|
||||
}
|
||||
|
||||
func (l *FilterLink) PixelFormat() PixelFormat {
|
||||
return PixelFormat(l.c.format)
|
||||
}
|
||||
|
||||
func (l *FilterLink) SampleAspectRatio() Rational {
|
||||
return newRationalFromC(l.c.sample_aspect_ratio)
|
||||
}
|
||||
|
||||
func (l *FilterLink) SampleFormat() SampleFormat {
|
||||
return SampleFormat(l.c.format)
|
||||
}
|
||||
|
||||
func (l *FilterLink) SampleRate() int {
|
||||
return int(l.c.sample_rate)
|
||||
}
|
||||
|
||||
func (l *FilterLink) TimeBase() Rational {
|
||||
return newRationalFromC(l.c.time_base)
|
||||
}
|
||||
|
||||
func (l *FilterLink) Width() int {
|
||||
return int(l.c.w)
|
||||
}
|
Reference in New Issue
Block a user