Skip to content

Commit

Permalink
Removed FilterLink and added BuffersinkFilterContext and BuffersrcFil…
Browse files Browse the repository at this point in the history
…terContext
  • Loading branch information
asticode committed Oct 18, 2024
1 parent c8b4cbe commit cd2a16d
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 157 deletions.
4 changes: 4 additions & 0 deletions BREAKING_CHANGES.md
Original file line number Diff line number Diff line change
@@ -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
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ 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`.
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).
16 changes: 8 additions & 8 deletions examples/filtering/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(),
Expand All @@ -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)

Expand All @@ -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
}
Expand All @@ -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
Expand Down
16 changes: 8 additions & 8 deletions examples/transcoding/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
}
Expand All @@ -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
Expand Down
101 changes: 75 additions & 26 deletions filter_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package astiav
//#include <libavutil/frame.h>
import "C"
import (
"math"
"unsafe"
)

Expand Down Expand Up @@ -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) Class() *Class {
return newClassFromC(unsafe.Pointer(fc.c))
}

type BuffersinkFilterContext struct {
fc *FilterContext
}

func newBuffersinkFilterContext(fc *FilterContext) *BuffersinkFilterContext {
return &BuffersinkFilterContext{fc: fc}
}

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 (fc *FilterContext) BuffersinkGetFrame(f *Frame, fs BuffersinkFlags) error {
func (bfc *BuffersinkFilterContext) GetFrame(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)))
return newError(C.av_buffersink_get_frame_flags(bfc.fc.c, cf, C.int(fs)))
}

func (fc *FilterContext) Class() *Class {
return newClassFromC(unsafe.Pointer(fc.c))
func (bfc *BuffersinkFilterContext) Height() int {
return int(C.av_buffersink_get_h(bfc.fc.c))
}

func (fc *FilterContext) NbInputs() int {
return int(fc.c.nb_inputs)
func (bfc *BuffersinkFilterContext) MediaType() MediaType {
return MediaType(C.av_buffersink_get_type(bfc.fc.c))
}

func (fc *FilterContext) NbOutputs() int {
return int(fc.c.nb_outputs)
func (bfc *BuffersinkFilterContext) PixelFormat() PixelFormat {
return PixelFormat(C.av_buffersink_get_format(bfc.fc.c))
}

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]))
}
return
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 (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]))
func (bfc *BuffersrcFilterContext) AddFrame(f *Frame, fs BuffersrcFlags) error {
var cf *C.AVFrame
if f != nil {
cf = f.c
}
return
return newError(C.av_buffersrc_add_frame_flags(bfc.fc.c, cf, C.int(fs)))
}

func (bfc *BuffersrcFilterContext) FilterContext() *FilterContext {
return bfc.fc
}
16 changes: 16 additions & 0 deletions filter_graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Loading

0 comments on commit cd2a16d

Please sign in to comment.