diff --git a/codec_context.go b/codec_context.go index 85058c3..1eb7e88 100644 --- a/codec_context.go +++ b/codec_context.go @@ -28,6 +28,7 @@ static inline void astiavResetCodecContextGetFormat(AVCodecContext *ctx) */ import "C" import ( + "fmt" "sync" "unsafe" ) @@ -208,6 +209,37 @@ func (cc *CodecContext) SetSampleAspectRatio(r Rational) { cc.c.sample_aspect_ratio = r.c } +func (cc *CodecContext) ExtraData() []byte { + return bytesFromC(func(size *C.size_t) *C.uint8_t { + if cc.c.extradata == nil { + *size = C.size_t(0) + return nil + } + *size = C.size_t(cc.c.extradata_size) + return cc.c.extradata + }) +} + +func (cc *CodecContext) SetExtraData(extraData []byte) error { + if len(extraData) == 0 { + return nil + } + + if cc.c.extradata != nil { + C.av_freep(unsafe.Pointer(&cc.c.extradata)) + cc.c.extradata_size = 0 + } + + extradataSize := len(extraData) + if cc.c.extradata = (*C.uint8_t)(C.av_mallocz(C.size_t(extradataSize + C.AV_INPUT_BUFFER_PADDING_SIZE))); cc.c.extradata == nil { + return fmt.Errorf("astiav: allocation is nil") + } + + C.memcpy(unsafe.Pointer(cc.c.extradata), unsafe.Pointer(&extraData[0]), C.size_t(extradataSize)) + cc.c.extradata_size = C.int(extradataSize) + return nil +} + func (cc *CodecContext) SampleFormat() SampleFormat { return SampleFormat(cc.c.sample_fmt) } diff --git a/codec_context_test.go b/codec_context_test.go index 5a54f3e..63c6f08 100644 --- a/codec_context_test.go +++ b/codec_context_test.go @@ -132,6 +132,12 @@ func TestCodecContext(t *testing.T) { require.NoError(t, err) require.Equal(t, 2, cp1.Channels()) + cc6 := AllocCodecContext(nil) + require.NotNil(t, cc5) + extraBytes := []byte{0, 0, 0, 1} + require.NoError(t, cc6.SetExtraData(extraBytes)) + require.Equal(t, extraBytes, cc6.ExtraData()) + // TODO Test ReceivePacket // TODO Test SendPacket // TODO Test ReceiveFrame diff --git a/codec_parameters.go b/codec_parameters.go index f77b20a..604061c 100644 --- a/codec_parameters.go +++ b/codec_parameters.go @@ -3,6 +3,10 @@ package astiav //#cgo pkg-config: libavcodec //#include import "C" +import ( + "fmt" + "unsafe" +) // https://github.com/FFmpeg/FFmpeg/blob/n5.0/libavcodec/codec_par.h#L52 type CodecParameters struct { @@ -141,6 +145,37 @@ func (cp *CodecParameters) SetSampleAspectRatio(r Rational) { cp.c.sample_aspect_ratio = r.c } +func (cp *CodecParameters) ExtraData() []byte { + return bytesFromC(func(size *C.size_t) *C.uint8_t { + if cp.c.extradata == nil { + *size = C.size_t(0) + return nil + } + *size = C.size_t(cp.c.extradata_size) + return cp.c.extradata + }) +} + +func (cp *CodecParameters) SetExtraData(extraData []byte) error { + if len(extraData) == 0 { + return nil + } + + if cp.c.extradata != nil { + C.av_freep(unsafe.Pointer(&cp.c.extradata)) + cp.c.extradata_size = 0 + } + + extradataSize := len(extraData) + if cp.c.extradata = (*C.uint8_t)(C.av_mallocz(C.size_t(extradataSize + C.AV_INPUT_BUFFER_PADDING_SIZE))); cp.c.extradata == nil { + return fmt.Errorf("astiav: allocation is nil") + } + + C.memcpy(unsafe.Pointer(cp.c.extradata), unsafe.Pointer(&extraData[0]), C.size_t(extradataSize)) + cp.c.extradata_size = C.int(extradataSize) + return nil +} + func (cp *CodecParameters) SampleFormat() SampleFormat { return SampleFormat(cp.c.format) } diff --git a/codec_parameters_test.go b/codec_parameters_test.go index 711b14e..c3c3da1 100644 --- a/codec_parameters_test.go +++ b/codec_parameters_test.go @@ -95,4 +95,8 @@ func TestCodecParameters(t *testing.T) { require.Equal(t, 4, cp6.SampleRate()) cp6.SetWidth(2) require.Equal(t, 2, cp6.Width()) + + extraBytes := []byte{0, 0, 0, 1} + require.NoError(t, cp6.SetExtraData(extraBytes)) + require.Equal(t, extraBytes, cp6.ExtraData()) }