From 15c6928fe31b021e031431a16b3baf7e8b12be79 Mon Sep 17 00:00:00 2001 From: Maizer Date: Fri, 23 May 2025 22:01:02 +0800 Subject: [PATCH] Add AVPixFmtDescriptor to retrieve flags for AVPixelFormat (#154) * 1. Adds hardware_frames_constraints to retrieve valid HWPixelFormats and SWPixelFormats for specific hardware frame configurations. 2. Implements a HardwareFramesConstraints method in hardware_device_context to obtain these constraints for a given hardware frames context. * Add AVPixFmtDescriptor to retrieve flags for AVPixelFormat feat(PixelFormat): Expose `AVPixFmtDescriptor` via `Descriptor()` method This commit introduces support for `AVPixFmtDescriptor`, which provides detailed information about an `AVPixelFormat`, including its flags. A new `Descriptor()` method has been added to the `PixelFormat` type (or class) to retrieve its corresponding `AVPixFmtDescriptor`. This allows for easier access to extended properties of pixel formats. --- flags.go | 20 ++++++++++++++++++++ flags_test.go | 9 +++++++++ internal/cmd/flags/main.go | 1 + pixel_format.go | 4 ++++ pixel_format_descriptor.go | 26 ++++++++++++++++++++++++++ pixel_format_descriptor_flag.go | 20 ++++++++++++++++++++ pixel_format_descriptor_test.go | 15 +++++++++++++++ pixel_format_test.go | 3 +++ 8 files changed, 98 insertions(+) create mode 100644 pixel_format_descriptor.go create mode 100644 pixel_format_descriptor_flag.go create mode 100644 pixel_format_descriptor_test.go diff --git a/flags.go b/flags.go index 8d64cf2..108a929 100644 --- a/flags.go +++ b/flags.go @@ -305,6 +305,26 @@ func (fs PacketFlags) Del(f PacketFlag) PacketFlags { func (fs PacketFlags) Has(f PacketFlag) bool { return astikit.BitFlags(fs).Has(uint64(f)) } +type PixelFormatDescriptorFlags astikit.BitFlags + +func NewPixelFormatDescriptorFlags(fs ...PixelFormatDescriptorFlag) PixelFormatDescriptorFlags { + o := PixelFormatDescriptorFlags(0) + for _, f := range fs { + o = o.Add(f) + } + return o +} + +func (fs PixelFormatDescriptorFlags) Add(f PixelFormatDescriptorFlag) PixelFormatDescriptorFlags { + return PixelFormatDescriptorFlags(astikit.BitFlags(fs).Add(uint64(f))) +} + +func (fs PixelFormatDescriptorFlags) Del(f PixelFormatDescriptorFlag) PixelFormatDescriptorFlags { + return PixelFormatDescriptorFlags(astikit.BitFlags(fs).Del(uint64(f))) +} + +func (fs PixelFormatDescriptorFlags) Has(f PixelFormatDescriptorFlag) bool { return astikit.BitFlags(fs).Has(uint64(f)) } + type SeekFlags astikit.BitFlags func NewSeekFlags(fs ...SeekFlag) SeekFlags { diff --git a/flags_test.go b/flags_test.go index ce93e69..28a1710 100644 --- a/flags_test.go +++ b/flags_test.go @@ -141,6 +141,15 @@ func TestPacketFlags(t *testing.T) { require.False(t, fs.Has(PacketFlag(2))) } +func TestPixelFormatDescriptorFlags(t *testing.T) { + fs := NewPixelFormatDescriptorFlags(PixelFormatDescriptorFlag(1)) + require.True(t, fs.Has(PixelFormatDescriptorFlag(1))) + fs = fs.Add(PixelFormatDescriptorFlag(2)) + require.True(t, fs.Has(PixelFormatDescriptorFlag(2))) + fs = fs.Del(PixelFormatDescriptorFlag(2)) + require.False(t, fs.Has(PixelFormatDescriptorFlag(2))) +} + func TestSeekFlags(t *testing.T) { fs := NewSeekFlags(SeekFlag(1)) require.True(t, fs.Has(SeekFlag(1))) diff --git a/internal/cmd/flags/main.go b/internal/cmd/flags/main.go index b710a45..af54ba5 100644 --- a/internal/cmd/flags/main.go +++ b/internal/cmd/flags/main.go @@ -29,6 +29,7 @@ var list = []listItem{ {Name: "IOFormat"}, {Name: "OptionSearch"}, {Name: "Packet"}, + {Name: "PixelFormatDescriptor"}, {Name: "Seek"}, {Name: "SoftwareScaleContext"}, {Name: "StreamEvent"}, diff --git a/pixel_format.go b/pixel_format.go index f796153..90da49d 100644 --- a/pixel_format.go +++ b/pixel_format.go @@ -211,6 +211,10 @@ func (f PixelFormat) String() string { return f.Name() } +func (f PixelFormat) Descriptor() *PixelFormatDescriptor { + return newPixelFormatDescriptorFromC(C.av_pix_fmt_desc_get((C.enum_AVPixelFormat)(f))) +} + // https://ffmpeg.org/doxygen/7.0/pixdesc_8c.html#a925ef18d69c24c3be8c53d5a7dc0660e func FindPixelFormatByName(name string) PixelFormat { cn := C.CString(name) diff --git a/pixel_format_descriptor.go b/pixel_format_descriptor.go new file mode 100644 index 0000000..094d52f --- /dev/null +++ b/pixel_format_descriptor.go @@ -0,0 +1,26 @@ +package astiav + +//#include +import "C" + +// https://ffmpeg.org/doxygen/7.0/structAVPixFmtDescriptor.html +type PixelFormatDescriptor struct { + c *C.AVPixFmtDescriptor +} + +func newPixelFormatDescriptorFromC(c *C.AVPixFmtDescriptor) *PixelFormatDescriptor { + if c == nil { + return nil + } + return &PixelFormatDescriptor{c: c} +} + +// https://ffmpeg.org/doxygen/7.0/structAVPixFmtDescriptor.html#a10736c3f1288eb87b23ede3ffdefb435 +func (pfd *PixelFormatDescriptor) Name() string { + return C.GoString(pfd.c.name) +} + +// https://ffmpeg.org/doxygen/7.0/structAVPixFmtDescriptor.html#a5047d1e6b045f637345dbc305bf4357d +func (pfd *PixelFormatDescriptor) Flags() PixelFormatDescriptorFlags { + return PixelFormatDescriptorFlags(pfd.c.flags) +} diff --git a/pixel_format_descriptor_flag.go b/pixel_format_descriptor_flag.go new file mode 100644 index 0000000..e504f8f --- /dev/null +++ b/pixel_format_descriptor_flag.go @@ -0,0 +1,20 @@ +package astiav + +//#include +import "C" + +// https://ffmpeg.org/doxygen/7.0/pixdesc_8h.html#ac7c7d0be16fb9b6f05b3e0d463cd037b +type PixelFormatDescriptorFlag int64 + +const ( + PixelFormatDescriptorFlagBe = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_BE) + PixelFormatDescriptorFlagPal = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_PAL) + PixelFormatDescriptorFlagBitStream = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_BITSTREAM) + PixelFormatDescriptorFlagHwAccel = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_HWACCEL) + PixelFormatDescriptorFlagPlanar = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_PLANAR) + PixelFormatDescriptorFlagRgb = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_RGB) + PixelFormatDescriptorFlagAlpha = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_ALPHA) + PixelFormatDescriptorFlagBayer = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_BAYER) + PixelFormatDescriptorFlagFloat = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_FLOAT) + PixelFormatDescriptorFlagXyz = PixelFormatDescriptorFlag(C.AV_PIX_FMT_FLAG_XYZ) +) diff --git a/pixel_format_descriptor_test.go b/pixel_format_descriptor_test.go new file mode 100644 index 0000000..ac0fc28 --- /dev/null +++ b/pixel_format_descriptor_test.go @@ -0,0 +1,15 @@ +package astiav + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestPixelFormatDescriptor(t *testing.T) { + p := PixelFormatCuda + d := p.Descriptor() + require.NotNil(t, d) + require.Equal(t, d.Name(), p.String()) + require.True(t, d.Flags().Has(PixelFormatDescriptorFlagHwAccel)) +} diff --git a/pixel_format_test.go b/pixel_format_test.go index 9ce4c2a..ea3577e 100644 --- a/pixel_format_test.go +++ b/pixel_format_test.go @@ -10,4 +10,7 @@ func TestPixelFormat(t *testing.T) { p := FindPixelFormatByName("yuv420p") require.Equal(t, PixelFormatYuv420P, p) require.Equal(t, "yuv420p", p.String()) + d := p.Descriptor() + require.NotNil(t, d) + require.Equal(t, d.Name(), p.String()) }