From c490911853b858d528ece49a5be41cf3bd2e7939 Mon Sep 17 00:00:00 2001 From: Quentin Renard Date: Sat, 30 Mar 2024 15:10:01 +0100 Subject: [PATCH] Now compatible with n6.1.1 --- .github/workflows/test.yml | 2 +- Makefile | 2 +- README.md | 24 +++---- channel_layout.go | 128 ++++++++++++++++++--------------- channel_layout_test.go | 2 +- codec_context_flag.go | 21 +++--- codec_parameters.go | 4 ++ codec_parameters_test.go | 5 +- codec_test.go | 4 ++ format_context_flag.go | 1 - format_context_test.go | 6 +- internal/test/arm/7/Dockerfile | 2 +- packet.go | 18 +---- packet_side_data.go | 50 +++++++++++++ packet_side_data_test.go | 16 +++++ packet_side_data_type.go | 8 +++ packet_side_data_type_test.go | 12 ++++ packet_test.go | 5 +- stream.go | 24 ------- stream_test.go | 3 - 20 files changed, 204 insertions(+), 133 deletions(-) create mode 100644 packet_side_data.go create mode 100644 packet_side_data_test.go create mode 100644 packet_side_data_type_test.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7e2b815..08cf51a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] env: - FFMPEG_VERSION: n5.1.2 + FFMPEG_VERSION: n6.1.1 runs-on: ${{ matrix.os }} steps: diff --git a/Makefile b/Makefile index eeca90b..32ddff4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -version=n5.1.2 +version=n6.1.1 srcPath=tmp/$(version)/src patchPath= platform= diff --git a/README.md b/README.md index 80def99..9e8e0b9 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ `astiav` is a Golang library providing C bindings for [ffmpeg](https://github.com/FFmpeg/FFmpeg) -It's only compatible with `ffmpeg` `n5.1.2`. +It's only compatible with `ffmpeg` `n6.1.1`. Its main goals are to: @@ -14,21 +14,21 @@ Its main goals are to: - typed constants and flags - struct-based functions - ... -- [x] provide the GO version of [ffmpeg examples](https://github.com/FFmpeg/FFmpeg/tree/n5.1.2/doc/examples) +- [x] provide the GO version of [ffmpeg examples](https://github.com/FFmpeg/FFmpeg/tree/n6.1.1/doc/examples) - [x] be fully tested # Examples -Examples are located in the [examples](examples) directory and mirror as much as possible the [ffmpeg examples](https://github.com/FFmpeg/FFmpeg/tree/n5.1.2/doc/examples). +Examples are located in the [examples](examples) directory and mirror as much as possible the [ffmpeg examples](https://github.com/FFmpeg/FFmpeg/tree/n6.1.1/doc/examples). |name|astiav|ffmpeg| |---|---|---| -|Demuxing/Decoding|[see](examples/demuxing_decoding/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/doc/examples/demuxing_decoding.c) -|Filtering|[see](examples/filtering/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/doc/examples/filtering_video.c) -|Hardware Decoding|[see](examples/hardware_decoding/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/doc/examples/hw_decode.c) -|Remuxing|[see](examples/remuxing/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/doc/examples/remuxing.c) -|Scaling|[see](examples/scaling/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/doc/examples/scaling_video.c) -|Transcoding|[see](examples/transcoding/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n5.1.2/doc/examples/transcoding.c) +|Demuxing/Decoding|[see](examples/demuxing_decoding/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/doc/examples/demuxing_decoding.c) +|Filtering|[see](examples/filtering/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/doc/examples/filtering_video.c) +|Hardware Decoding|[see](examples/hardware_decoding/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/doc/examples/hw_decode.c) +|Remuxing|[see](examples/remuxing/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/doc/examples/remuxing.c) +|Scaling|[see](examples/scaling/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/doc/examples/scaling_video.c) +|Transcoding|[see](examples/transcoding/main.go)|[see](https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/doc/examples/transcoding.c) *Tip: you can use the video sample located in the `testdata` directory for your tests* @@ -47,9 +47,9 @@ For your GO code to pick up `ffmpeg` dependency automatically, you'll need to ad (don't forget to replace `{{ path to your working directory }}` with the absolute path to your working directory) ```sh -export CGO_LDFLAGS="-L{{ path to your working directory }}/tmp/n5.1.2/lib/", -export CGO_CFLAGS="-I{{ path to your working directory }}/tmp/n5.1.2/include/", -export PKG_CONFIG_PATH="{{ path to your working directory }}/tmp/n5.1.2/lib/pkgconfig", +export CGO_LDFLAGS="-L{{ path to your working directory }}/tmp/n6.1.1/lib/", +export CGO_CFLAGS="-I{{ path to your working directory }}/tmp/n6.1.1/include/", +export PKG_CONFIG_PATH="{{ path to your working directory }}/tmp/n6.1.1/lib/pkgconfig", ``` # Why astiav? diff --git a/channel_layout.go b/channel_layout.go index 06dae28..e877f91 100644 --- a/channel_layout.go +++ b/channel_layout.go @@ -6,34 +6,42 @@ package astiav // Calling C.AV_CHANNEL_LAYOUT_* in Go gives a "could not determine kind of name for X" error // therefore we need to bridge the channel layout values -AVChannelLayout *c2goChannelLayoutMono = &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; -AVChannelLayout *c2goChannelLayoutStereo = &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; -AVChannelLayout *c2goChannelLayout2Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_2POINT1; -AVChannelLayout *c2goChannelLayout21 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_1; -AVChannelLayout *c2goChannelLayoutSurround = &(AVChannelLayout)AV_CHANNEL_LAYOUT_SURROUND; -AVChannelLayout *c2goChannelLayout3Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_3POINT1; -AVChannelLayout *c2goChannelLayout4Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT0; -AVChannelLayout *c2goChannelLayout4Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT1; -AVChannelLayout *c2goChannelLayout22 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_2; -AVChannelLayout *c2goChannelLayoutQuad = &(AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD; -AVChannelLayout *c2goChannelLayout5Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0; -AVChannelLayout *c2goChannelLayout5Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1; -AVChannelLayout *c2goChannelLayout5Point0Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0_BACK; -AVChannelLayout *c2goChannelLayout5Point1Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK; -AVChannelLayout *c2goChannelLayout6Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT0; -AVChannelLayout *c2goChannelLayout6Point0Front = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT0_FRONT; -AVChannelLayout *c2goChannelLayoutHexagonal = &(AVChannelLayout)AV_CHANNEL_LAYOUT_HEXAGONAL; -AVChannelLayout *c2goChannelLayout6Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1; -AVChannelLayout *c2goChannelLayout6Point1Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1_BACK; -AVChannelLayout *c2goChannelLayout6Point1Front = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1_FRONT; -AVChannelLayout *c2goChannelLayout7Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT0; -AVChannelLayout *c2goChannelLayout7Point0Front = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT0_FRONT; -AVChannelLayout *c2goChannelLayout7Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1; -AVChannelLayout *c2goChannelLayout7Point1Wide = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1_WIDE; -AVChannelLayout *c2goChannelLayout7Point1WideBack = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK; -AVChannelLayout *c2goChannelLayoutOctagonal = &(AVChannelLayout)AV_CHANNEL_LAYOUT_OCTAGONAL; -AVChannelLayout *c2goChannelLayoutHexadecagonal = &(AVChannelLayout)AV_CHANNEL_LAYOUT_HEXADECAGONAL; -AVChannelLayout *c2goChannelLayoutStereoDownmix = &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX; +AVChannelLayout *c2goChannelLayoutMono = &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; +AVChannelLayout *c2goChannelLayoutStereo = &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; +AVChannelLayout *c2goChannelLayout2Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_2POINT1; +AVChannelLayout *c2goChannelLayout21 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_1; +AVChannelLayout *c2goChannelLayoutSurround = &(AVChannelLayout)AV_CHANNEL_LAYOUT_SURROUND; +AVChannelLayout *c2goChannelLayout3Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_3POINT1; +AVChannelLayout *c2goChannelLayout4Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT0; +AVChannelLayout *c2goChannelLayout4Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT1; +AVChannelLayout *c2goChannelLayout22 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_2; +AVChannelLayout *c2goChannelLayoutQuad = &(AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD; +AVChannelLayout *c2goChannelLayout5Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0; +AVChannelLayout *c2goChannelLayout5Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1; +AVChannelLayout *c2goChannelLayout5Point0Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0_BACK; +AVChannelLayout *c2goChannelLayout5Point1Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK; +AVChannelLayout *c2goChannelLayout6Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT0; +AVChannelLayout *c2goChannelLayout6Point0Front = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT0_FRONT; +AVChannelLayout *c2goChannelLayoutHexagonal = &(AVChannelLayout)AV_CHANNEL_LAYOUT_HEXAGONAL; +AVChannelLayout *c2goChannelLayout3Point1Point2 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_3POINT1POINT2; +AVChannelLayout *c2goChannelLayout6Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1; +AVChannelLayout *c2goChannelLayout6Point1Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1_BACK; +AVChannelLayout *c2goChannelLayout6Point1Front = &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1_FRONT; +AVChannelLayout *c2goChannelLayout7Point0 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT0; +AVChannelLayout *c2goChannelLayout7Point0Front = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT0_FRONT; +AVChannelLayout *c2goChannelLayout7Point1 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1; +AVChannelLayout *c2goChannelLayout7Point1Wide = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1_WIDE; +AVChannelLayout *c2goChannelLayout7Point1WideBack = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK; +AVChannelLayout *c2goChannelLayout5Point1Point2Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1POINT2_BACK; +AVChannelLayout *c2goChannelLayoutOctagonal = &(AVChannelLayout)AV_CHANNEL_LAYOUT_OCTAGONAL; +AVChannelLayout *c2goChannelLayoutCube = &(AVChannelLayout)AV_CHANNEL_LAYOUT_CUBE; +AVChannelLayout *c2goChannelLayout5Point1Point4Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1POINT4_BACK; +AVChannelLayout *c2goChannelLayout7Point1Point2 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1POINT2; +AVChannelLayout *c2goChannelLayout7Point1Point4Back = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK; +AVChannelLayout *c2goChannelLayoutHexadecagonal = &(AVChannelLayout)AV_CHANNEL_LAYOUT_HEXADECAGONAL; +AVChannelLayout *c2goChannelLayoutStereoDownmix = &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX; +AVChannelLayout *c2goChannelLayout22Point2 = &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2; +AVChannelLayout *c2goChannelLayout7Point1TopBack = &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK; */ import "C" @@ -41,34 +49,42 @@ import "unsafe" // https://github.com/FFmpeg/FFmpeg/blob/n5.0/libavutil/channel_layout.h#L90 var ( - ChannelLayoutMono = newChannelLayoutFromC(C.c2goChannelLayoutMono) - ChannelLayoutStereo = newChannelLayoutFromC(C.c2goChannelLayoutStereo) - ChannelLayout2Point1 = newChannelLayoutFromC(C.c2goChannelLayout2Point1) - ChannelLayout21 = newChannelLayoutFromC(C.c2goChannelLayout21) - ChannelLayoutSurround = newChannelLayoutFromC(C.c2goChannelLayoutSurround) - ChannelLayout3Point1 = newChannelLayoutFromC(C.c2goChannelLayout3Point1) - ChannelLayout4Point0 = newChannelLayoutFromC(C.c2goChannelLayout4Point0) - ChannelLayout4Point1 = newChannelLayoutFromC(C.c2goChannelLayout4Point1) - ChannelLayout22 = newChannelLayoutFromC(C.c2goChannelLayout22) - ChannelLayoutQuad = newChannelLayoutFromC(C.c2goChannelLayoutQuad) - ChannelLayout5Point0 = newChannelLayoutFromC(C.c2goChannelLayout5Point0) - ChannelLayout5Point1 = newChannelLayoutFromC(C.c2goChannelLayout5Point1) - ChannelLayout5Point0Back = newChannelLayoutFromC(C.c2goChannelLayout5Point0Back) - ChannelLayout5Point1Back = newChannelLayoutFromC(C.c2goChannelLayout5Point1Back) - ChannelLayout6Point0 = newChannelLayoutFromC(C.c2goChannelLayout6Point0) - ChannelLayout6Point0Front = newChannelLayoutFromC(C.c2goChannelLayout6Point0Front) - ChannelLayoutHexagonal = newChannelLayoutFromC(C.c2goChannelLayoutHexagonal) - ChannelLayout6Point1 = newChannelLayoutFromC(C.c2goChannelLayout6Point1) - ChannelLayout6Point1Back = newChannelLayoutFromC(C.c2goChannelLayout6Point1Back) - ChannelLayout6Point1Front = newChannelLayoutFromC(C.c2goChannelLayout6Point1Front) - ChannelLayout7Point0 = newChannelLayoutFromC(C.c2goChannelLayout7Point0) - ChannelLayout7Point0Front = newChannelLayoutFromC(C.c2goChannelLayout7Point0Front) - ChannelLayout7Point1 = newChannelLayoutFromC(C.c2goChannelLayout7Point1) - ChannelLayout7Point1Wide = newChannelLayoutFromC(C.c2goChannelLayout7Point1Wide) - ChannelLayout7Point1WideBack = newChannelLayoutFromC(C.c2goChannelLayout7Point1WideBack) - ChannelLayoutOctagonal = newChannelLayoutFromC(C.c2goChannelLayoutOctagonal) - ChannelLayoutHexadecagonal = newChannelLayoutFromC(C.c2goChannelLayoutHexadecagonal) - ChannelLayoutStereoDownmix = newChannelLayoutFromC(C.c2goChannelLayoutStereoDownmix) + ChannelLayoutMono = newChannelLayoutFromC(C.c2goChannelLayoutMono) + ChannelLayoutStereo = newChannelLayoutFromC(C.c2goChannelLayoutStereo) + ChannelLayout2Point1 = newChannelLayoutFromC(C.c2goChannelLayout2Point1) + ChannelLayout21 = newChannelLayoutFromC(C.c2goChannelLayout21) + ChannelLayoutSurround = newChannelLayoutFromC(C.c2goChannelLayoutSurround) + ChannelLayout3Point1 = newChannelLayoutFromC(C.c2goChannelLayout3Point1) + ChannelLayout4Point0 = newChannelLayoutFromC(C.c2goChannelLayout4Point0) + ChannelLayout4Point1 = newChannelLayoutFromC(C.c2goChannelLayout4Point1) + ChannelLayout22 = newChannelLayoutFromC(C.c2goChannelLayout22) + ChannelLayoutQuad = newChannelLayoutFromC(C.c2goChannelLayoutQuad) + ChannelLayout5Point0 = newChannelLayoutFromC(C.c2goChannelLayout5Point0) + ChannelLayout5Point1 = newChannelLayoutFromC(C.c2goChannelLayout5Point1) + ChannelLayout5Point0Back = newChannelLayoutFromC(C.c2goChannelLayout5Point0Back) + ChannelLayout5Point1Back = newChannelLayoutFromC(C.c2goChannelLayout5Point1Back) + ChannelLayout6Point0 = newChannelLayoutFromC(C.c2goChannelLayout6Point0) + ChannelLayout6Point0Front = newChannelLayoutFromC(C.c2goChannelLayout6Point0Front) + ChannelLayoutHexagonal = newChannelLayoutFromC(C.c2goChannelLayoutHexagonal) + ChannelLayout3Point1Point2 = newChannelLayoutFromC(C.c2goChannelLayout3Point1Point2) + ChannelLayout6Point1 = newChannelLayoutFromC(C.c2goChannelLayout6Point1) + ChannelLayout6Point1Back = newChannelLayoutFromC(C.c2goChannelLayout6Point1Back) + ChannelLayout6Point1Front = newChannelLayoutFromC(C.c2goChannelLayout6Point1Front) + ChannelLayout7Point0 = newChannelLayoutFromC(C.c2goChannelLayout7Point0) + ChannelLayout7Point0Front = newChannelLayoutFromC(C.c2goChannelLayout7Point0Front) + ChannelLayout7Point1 = newChannelLayoutFromC(C.c2goChannelLayout7Point1) + ChannelLayout7Point1Wide = newChannelLayoutFromC(C.c2goChannelLayout7Point1Wide) + ChannelLayout7Point1WideBack = newChannelLayoutFromC(C.c2goChannelLayout7Point1WideBack) + ChannelLayout5Point1Point2Back = newChannelLayoutFromC(C.c2goChannelLayout5Point1Point2Back) + ChannelLayoutOctagonal = newChannelLayoutFromC(C.c2goChannelLayoutOctagonal) + ChannelLayoutCube = newChannelLayoutFromC(C.c2goChannelLayoutCube) + ChannelLayout5Point1Point4Back = newChannelLayoutFromC(C.c2goChannelLayout5Point1Point4Back) + ChannelLayout7Point1Point2 = newChannelLayoutFromC(C.c2goChannelLayout7Point1Point2) + ChannelLayout7Point1Point4Back = newChannelLayoutFromC(C.c2goChannelLayout7Point1Point4Back) + ChannelLayoutHexadecagonal = newChannelLayoutFromC(C.c2goChannelLayoutHexadecagonal) + ChannelLayoutStereoDownmix = newChannelLayoutFromC(C.c2goChannelLayoutStereoDownmix) + ChannelLayout22Point2 = newChannelLayoutFromC(C.c2goChannelLayout22Point2) + ChannelLayout7Point1TopBack = newChannelLayoutFromC(C.c2goChannelLayout7Point1TopBack) ) type ChannelLayout struct { diff --git a/channel_layout_test.go b/channel_layout_test.go index 1d907de..b6a04f5 100644 --- a/channel_layout_test.go +++ b/channel_layout_test.go @@ -9,7 +9,7 @@ import ( func TestChannelLayout(t *testing.T) { cl := ChannelLayoutStereo require.Equal(t, 2, cl.NbChannels()) - require.Equal(t, "stereo", cl.String()) + require.Equal(t, "stereo\x00", cl.String()) require.True(t, cl.Valid()) require.True(t, cl.Equal(ChannelLayoutStereo)) require.False(t, cl.Equal(ChannelLayoutMono)) diff --git a/codec_context_flag.go b/codec_context_flag.go index 2bda433..51c888e 100644 --- a/codec_context_flag.go +++ b/codec_context_flag.go @@ -18,7 +18,6 @@ const ( CodecContextFlagLoopFilter = CodecContextFlag(C.AV_CODEC_FLAG_LOOP_FILTER) CodecContextFlagGray = CodecContextFlag(C.AV_CODEC_FLAG_GRAY) CodecContextFlagPsnr = CodecContextFlag(C.AV_CODEC_FLAG_PSNR) - CodecContextFlagTruncated = CodecContextFlag(C.AV_CODEC_FLAG_TRUNCATED) CodecContextFlagInterlacedDct = CodecContextFlag(C.AV_CODEC_FLAG_INTERLACED_DCT) CodecContextFlagLowDelay = CodecContextFlag(C.AV_CODEC_FLAG_LOW_DELAY) CodecContextFlagGlobalHeader = CodecContextFlag(C.AV_CODEC_FLAG_GLOBAL_HEADER) @@ -32,14 +31,14 @@ type CodecContextFlag2 int64 // https://github.com/FFmpeg/FFmpeg/blob/n5.0/libavcodec/avcodec.h#L287 const ( - CodecFlag2Fast = CodecContextFlag2(C.AV_CODEC_FLAG2_FAST) - CodecFlag2NoOutput = CodecContextFlag2(C.AV_CODEC_FLAG2_NO_OUTPUT) - CodecFlag2LocalHeader = CodecContextFlag2(C.AV_CODEC_FLAG2_LOCAL_HEADER) - CodecFlag2DropFrameTimecode = CodecContextFlag2(C.AV_CODEC_FLAG2_DROP_FRAME_TIMECODE) - CodecFlag2Chunks = CodecContextFlag2(C.AV_CODEC_FLAG2_CHUNKS) - CodecFlag2IgnoreCrop = CodecContextFlag2(C.AV_CODEC_FLAG2_IGNORE_CROP) - CodecFlag2ShowAll = CodecContextFlag2(C.AV_CODEC_FLAG2_SHOW_ALL) - CodecFlag2ExportMvs = CodecContextFlag2(C.AV_CODEC_FLAG2_EXPORT_MVS) - CodecFlag2SkipManual = CodecContextFlag2(C.AV_CODEC_FLAG2_SKIP_MANUAL) - CodecFlag2RoFlushNoop = CodecContextFlag2(C.AV_CODEC_FLAG2_RO_FLUSH_NOOP) + CodecFlag2Fast = CodecContextFlag2(C.AV_CODEC_FLAG2_FAST) + CodecFlag2NoOutput = CodecContextFlag2(C.AV_CODEC_FLAG2_NO_OUTPUT) + CodecFlag2LocalHeader = CodecContextFlag2(C.AV_CODEC_FLAG2_LOCAL_HEADER) + CodecFlag2Chunks = CodecContextFlag2(C.AV_CODEC_FLAG2_CHUNKS) + CodecFlag2IgnoreCrop = CodecContextFlag2(C.AV_CODEC_FLAG2_IGNORE_CROP) + CodecFlag2ShowAll = CodecContextFlag2(C.AV_CODEC_FLAG2_SHOW_ALL) + CodecFlag2ExportMvs = CodecContextFlag2(C.AV_CODEC_FLAG2_EXPORT_MVS) + CodecFlag2SkipManual = CodecContextFlag2(C.AV_CODEC_FLAG2_SKIP_MANUAL) + CodecFlag2RoFlushNoop = CodecContextFlag2(C.AV_CODEC_FLAG2_RO_FLUSH_NOOP) + CodecFlag2IccProfiles = CodecContextFlag2(C.AV_CODEC_FLAG2_ICC_PROFILES) ) diff --git a/codec_parameters.go b/codec_parameters.go index 604061c..fd0155b 100644 --- a/codec_parameters.go +++ b/codec_parameters.go @@ -176,6 +176,10 @@ func (cp *CodecParameters) SetExtraData(extraData []byte) error { return nil } +func (cp *CodecParameters) SideData() *PacketSideData { + return newPacketSideDataFromC(&cp.c.coded_side_data, &cp.c.nb_coded_side_data) +} + func (cp *CodecParameters) SampleFormat() SampleFormat { return SampleFormat(cp.c.format) } diff --git a/codec_parameters_test.go b/codec_parameters_test.go index c3c3da1..dbdec73 100644 --- a/codec_parameters_test.go +++ b/codec_parameters_test.go @@ -95,8 +95,11 @@ 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()) + b := []byte("test") + sd := cp6.SideData() + require.NoError(t, sd.Add(PacketSideDataTypeDisplaymatrix, b)) + require.Equal(t, b, sd.Get(PacketSideDataTypeDisplaymatrix)) } diff --git a/codec_test.go b/codec_test.go index 8562123..ab6e951 100644 --- a/codec_test.go +++ b/codec_test.go @@ -28,6 +28,10 @@ func TestCodec(t *testing.T) { ChannelLayout5Point0Back, ChannelLayout5Point1Back, ChannelLayout7Point1WideBack, + ChannelLayout6Point1Back, + ChannelLayout7Point1, + ChannelLayout22Point2, + ChannelLayout5Point1Point2Back, } gls := c.ChannelLayouts() require.Len(t, gls, len(els)) diff --git a/format_context_flag.go b/format_context_flag.go index 119d57a..7f5b0e9 100644 --- a/format_context_flag.go +++ b/format_context_flag.go @@ -20,7 +20,6 @@ const ( FormatContextFlagFlushPackets = FormatContextFlag(C.AVFMT_FLAG_FLUSH_PACKETS) FormatContextFlagBitexact = FormatContextFlag(C.AVFMT_FLAG_BITEXACT) FormatContextFlagSortDts = FormatContextFlag(C.AVFMT_FLAG_SORT_DTS) - FormatContextFlagPrivOpt = FormatContextFlag(C.AVFMT_FLAG_PRIV_OPT) FormatContextFlagFastSeek = FormatContextFlag(C.AVFMT_FLAG_FAST_SEEK) FormatContextFlagShortest = FormatContextFlag(C.AVFMT_FLAG_SHORTEST) FormatContextFlagAutoBsf = FormatContextFlag(C.AVFMT_FLAG_AUTO_BSF) diff --git a/format_context_test.go b/format_context_test.go index 4485e78..f3dca42 100644 --- a/format_context_test.go +++ b/format_context_test.go @@ -13,9 +13,9 @@ func TestFormatContext(t *testing.T) { require.Len(t, ss, 2) s1 := ss[0] - require.Equal(t, int64(607583), fc1.BitRate()) + require.Equal(t, int64(607664), fc1.BitRate()) require.Equal(t, NewFormatContextCtxFlags(0), fc1.CtxFlags()) - require.Equal(t, int64(5014000), fc1.Duration()) + require.Equal(t, int64(5013333), fc1.Duration()) require.True(t, fc1.EventFlags().Has(FormatEventFlagMetadataUpdated)) require.True(t, fc1.Flags().Has(FormatContextFlagAutoBsf)) require.Equal(t, NewRational(24, 1), fc1.GuessFrameRate(s1, nil)) @@ -33,7 +33,7 @@ func TestFormatContext(t *testing.T) { sdp, err := fc1.SDPCreate() require.NoError(t, err) - require.Equal(t, "v=0\r\no=- 0 0 IN IP4 127.0.0.1\r\ns=Big Buck Bunny\r\nt=0 0\r\na=tool:libavformat LIBAVFORMAT_VERSION\r\nm=video 0 RTP/AVP 96\r\nb=AS:441\r\na=rtpmap:96 H264/90000\r\na=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z0LADasgKDPz4CIAAAMAAgAAAwBhHihUkA==,aM48gA==; profile-level-id=42C00D\r\na=control:streamid=0\r\nm=audio 0 RTP/AVP 97\r\nb=AS:161\r\na=rtpmap:97 MPEG4-GENERIC/48000/2\r\na=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=1190\r\na=control:streamid=1\r\n", sdp) + require.Equal(t, "v=0\r\no=- 0 0 IN IP4 127.0.0.1\r\ns=Big Buck Bunny\r\nt=0 0\r\na=tool:libavformat 60.16.100\r\nm=video 0 RTP/AVP 96\r\nb=AS:441\r\na=rtpmap:96 H264/90000\r\na=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z0LADasgKDPz4CIAAAMAAgAAAwBhHihUkA==,aM48gA==; profile-level-id=42C00D\r\na=control:streamid=0\r\nm=audio 0 RTP/AVP 97\r\nb=AS:161\r\na=rtpmap:97 MPEG4-GENERIC/48000/2\r\na=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=1190\r\na=control:streamid=1\r\n", sdp) fc2, err := AllocOutputFormatContext(nil, "", "/tmp/test.mp4") require.NoError(t, err) diff --git a/internal/test/arm/7/Dockerfile b/internal/test/arm/7/Dockerfile index 7299e85..a148d59 100644 --- a/internal/test/arm/7/Dockerfile +++ b/internal/test/arm/7/Dockerfile @@ -15,7 +15,7 @@ WORKDIR /opt/ffmpeg/src RUN \ git clone https://github.com/FFmpeg/FFmpeg /opt/ffmpeg/src && \ - git checkout n5.1.2 + git checkout n6.1.1 RUN \ ./configure --prefix=.. && \ diff --git a/packet.go b/packet.go index 43b6a75..a5c8e93 100644 --- a/packet.go +++ b/packet.go @@ -74,22 +74,8 @@ func (p *Packet) SetPts(v int64) { p.c.pts = C.int64_t(v) } -func (p *Packet) AddSideData(t PacketSideDataType, data []byte) error { - // Create buf - buf := (*C.uint8_t)(C.av_malloc(C.size_t(len(data)))) - if buf == nil { - return errors.New("astiav: allocating buffer failed") - } - C.memcpy(unsafe.Pointer(buf), unsafe.Pointer(&data[0]), C.size_t(len(data))) - - // Add - return newError(C.av_packet_add_side_data(p.c, (C.enum_AVPacketSideDataType)(t), buf, C.size_t(len(data)))) -} - -func (p *Packet) SideData(t PacketSideDataType) []byte { - return bytesFromC(func(size *C.size_t) *C.uint8_t { - return C.av_packet_get_side_data(p.c, (C.enum_AVPacketSideDataType)(t), size) - }) +func (p *Packet) SideData() *PacketSideData { + return newPacketSideDataFromC(&p.c.side_data, &p.c.side_data_elems) } func (p *Packet) Size() int { diff --git a/packet_side_data.go b/packet_side_data.go new file mode 100644 index 0000000..a2c269b --- /dev/null +++ b/packet_side_data.go @@ -0,0 +1,50 @@ +package astiav + +//#cgo pkg-config: libavcodec +//#include +import "C" +import ( + "errors" + "unsafe" +) + +// https://github.com/FFmpeg/FFmpeg/blob/n6.1.1/libavcodec/packet.h#L342 +type PacketSideData struct { + sd **C.struct_AVPacketSideData + size *C.int +} + +func newPacketSideDataFromC(sd **C.struct_AVPacketSideData, size *C.int) *PacketSideData { + return &PacketSideData{ + sd: sd, + size: size, + } +} + +func (d *PacketSideData) Add(t PacketSideDataType, b []byte) error { + if len(b) == 0 { + return nil + } + + sd := C.av_packet_side_data_new(d.sd, d.size, (C.enum_AVPacketSideDataType)(t), C.size_t(len(b)), 0) + if sd == nil { + return errors.New("astiav: nil pointer") + } + + C.memcpy(unsafe.Pointer(sd.data), unsafe.Pointer(&b[0]), C.size_t(len(b))) + return nil +} + +func (d *PacketSideData) Get(t PacketSideDataType) []byte { + return bytesFromC(func(size *C.size_t) *C.uint8_t { + if d.sd == nil || d.size == nil { + return nil + } + sd := C.av_packet_side_data_get(*d.sd, *d.size, (C.enum_AVPacketSideDataType)(t)) + if sd == nil { + return nil + } + *size = sd.size + return sd.data + }) +} diff --git a/packet_side_data_test.go b/packet_side_data_test.go new file mode 100644 index 0000000..faec347 --- /dev/null +++ b/packet_side_data_test.go @@ -0,0 +1,16 @@ +package astiav + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPacketSideData(t *testing.T) { + cp := AllocCodecParameters() + defer cp.Free() + b := []byte("test") + sd := cp.SideData() + require.NoError(t, sd.Add(PacketSideDataTypeDisplaymatrix, b)) + require.Equal(t, b, sd.Get(PacketSideDataTypeDisplaymatrix)) +} diff --git a/packet_side_data_type.go b/packet_side_data_type.go index f5aa78c..a4db4ea 100644 --- a/packet_side_data_type.go +++ b/packet_side_data_type.go @@ -37,3 +37,11 @@ const ( PacketSideDataTypeWebvttIdentifier = PacketSideDataType(C.AV_PKT_DATA_WEBVTT_IDENTIFIER) PacketSideDataTypeWebvttSettings = PacketSideDataType(C.AV_PKT_DATA_WEBVTT_SETTINGS) ) + +func (t PacketSideDataType) Name() string { + return C.GoString(C.av_packet_side_data_name((C.enum_AVPacketSideDataType)(t))) +} + +func (t PacketSideDataType) String() string { + return t.Name() +} diff --git a/packet_side_data_type_test.go b/packet_side_data_type_test.go new file mode 100644 index 0000000..bb11e97 --- /dev/null +++ b/packet_side_data_type_test.go @@ -0,0 +1,12 @@ +package astiav + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPacketSideDataType(t *testing.T) { + require.Equal(t, "Display Matrix", PacketSideDataTypeDisplaymatrix.Name()) + require.Equal(t, "Display Matrix", PacketSideDataTypeDisplaymatrix.String()) +} diff --git a/packet_test.go b/packet_test.go index 9a335f4..7fad441 100644 --- a/packet_test.go +++ b/packet_test.go @@ -75,8 +75,9 @@ func TestPacket(t *testing.T) { require.NotNil(t, pkt5) defer pkt5.Free() b = []byte{1, 2, 3, 4} - require.NoError(t, pkt5.AddSideData(PacketSideDataTypeAudioServiceType, b)) - require.Equal(t, b, pkt5.SideData(PacketSideDataTypeAudioServiceType)) + sd := pkt5.SideData() + require.NoError(t, sd.Add(PacketSideDataTypeAudioServiceType, b)) + require.Equal(t, b, sd.Get(PacketSideDataTypeAudioServiceType)) pkt6 := AllocPacket() require.NotNil(t, pkt6) diff --git a/stream.go b/stream.go index 453dfc1..e86fa70 100644 --- a/stream.go +++ b/stream.go @@ -3,10 +3,6 @@ package astiav //#cgo pkg-config: libavformat //#include import "C" -import ( - "errors" - "unsafe" -) // https://github.com/FFmpeg/FFmpeg/blob/n5.0/libavformat/avformat.h#L937 type Stream struct { @@ -80,26 +76,6 @@ func (s *Stream) SetSampleAspectRatio(r Rational) { s.c.sample_aspect_ratio = r.c } -func (s *Stream) SideData(t PacketSideDataType) []byte { - return bytesFromC(func(size *C.size_t) *C.uint8_t { - return C.av_stream_get_side_data(s.c, (C.enum_AVPacketSideDataType)(t), size) - }) -} - -func (s *Stream) AddSideData(t PacketSideDataType, d []byte) error { - if len(d) == 0 { - return nil - } - - ptr := C.av_stream_new_side_data(s.c, (C.enum_AVPacketSideDataType)(t), C.size_t(len(d))) - if ptr == nil { - return errors.New("astiav: nil pointer") - } - - C.memcpy(unsafe.Pointer(ptr), unsafe.Pointer(&d[0]), C.size_t(len(d))) - return nil -} - func (s *Stream) StartTime() int64 { return int64(s.c.start_time) } diff --git a/stream_test.go b/stream_test.go index 7e90ce6..e374b8f 100644 --- a/stream_test.go +++ b/stream_test.go @@ -23,7 +23,6 @@ func TestStream(t *testing.T) { require.Equal(t, int64(120), s1.NbFrames()) require.Equal(t, NewRational(24, 1), s1.RFrameRate()) require.Equal(t, NewRational(1, 1), s1.SampleAspectRatio()) - require.Equal(t, []byte{}, s1.SideData(PacketSideDataTypeNb)) require.Equal(t, int64(0), s1.StartTime()) require.Equal(t, NewRational(1, 12288), s1.TimeBase()) @@ -44,8 +43,6 @@ func TestStream(t *testing.T) { require.Equal(t, NewRational(2, 1), s1.RFrameRate()) s1.SetSampleAspectRatio(NewRational(2, 1)) require.Equal(t, NewRational(2, 1), s1.SampleAspectRatio()) - require.NoError(t, s1.AddSideData(PacketSideDataTypeEncryptionInfo, []byte("test"))) - require.Equal(t, []byte("test"), s1.SideData(PacketSideDataTypeEncryptionInfo)) s1.SetTimeBase(NewRational(1, 1)) require.Equal(t, NewRational(1, 1), s1.TimeBase()) }