From 89578faef193318b3532955162e8cb87c4dac2ba Mon Sep 17 00:00:00 2001 From: Quentin Renard Date: Fri, 26 Jan 2024 11:49:24 +0100 Subject: [PATCH] Unexported NewFrameData and FrameDataFrame --- frame.go | 2 +- frame_data.go | 94 ++++++------ frame_data_internal_test.go | 285 ++++++++++++++++++++++++++++++++++++ frame_data_test.go | 278 +---------------------------------- input_format_test.go | 4 +- 5 files changed, 337 insertions(+), 326 deletions(-) create mode 100644 frame_data_internal_test.go diff --git a/frame.go b/frame.go index 16e9e01..ddd04e7 100644 --- a/frame.go +++ b/frame.go @@ -59,7 +59,7 @@ func (f *Frame) SetColorRange(r ColorRange) { } func (f *Frame) Data() *FrameData { - return NewFrameData(newFrameDataFrame(f)) + return newFrameData(newFrameDataFrame(f)) } func (f *Frame) Height() int { diff --git a/frame_data.go b/frame_data.go index 0b9c047..34d22db 100644 --- a/frame_data.go +++ b/frame_data.go @@ -9,7 +9,11 @@ import ( "strings" ) -type FrameDataFrame interface { +type FrameData struct { + f frameDataFramer +} + +type frameDataFramer interface { Height() int ImageBufferSize(align int) (int, error) ImageCopyToBuffer(b []byte, align int) (int, error) @@ -19,52 +23,7 @@ type FrameDataFrame interface { Width() int } -var _ FrameDataFrame = (*frameDataFrame)(nil) - -type frameDataFrame struct { - f *Frame -} - -func newFrameDataFrame(f *Frame) *frameDataFrame { - return &frameDataFrame{f: f} -} - -func (f *frameDataFrame) Height() int { - return f.f.Height() -} - -func (f *frameDataFrame) ImageBufferSize(align int) (int, error) { - return f.f.ImageBufferSize(align) -} - -func (f *frameDataFrame) ImageCopyToBuffer(b []byte, align int) (int, error) { - return f.f.ImageCopyToBuffer(b, align) -} - -func (f *frameDataFrame) Linesize(i int) int { - return f.f.Linesize()[i] -} - -func (f *frameDataFrame) PixelFormat() PixelFormat { - return f.f.PixelFormat() -} - -func (f *frameDataFrame) PlaneBytes(i int) []byte { - return bytesFromC(func(size *cUlong) *C.uint8_t { - *size = cUlong(int(f.f.c.linesize[i]) * f.f.Height()) - return f.f.c.data[i] - }) -} - -func (f *frameDataFrame) Width() int { - return f.f.Width() -} - -type FrameData struct { - f FrameDataFrame -} - -func NewFrameData(f FrameDataFrame) *FrameData { +func newFrameData(f frameDataFramer) *FrameData { return &FrameData{f: f} } @@ -213,3 +172,44 @@ func (d *FrameData) ToImage(dst image.Image) error { } return nil } + +var _ frameDataFramer = (*frameDataFrame)(nil) + +type frameDataFrame struct { + f *Frame +} + +func newFrameDataFrame(f *Frame) *frameDataFrame { + return &frameDataFrame{f: f} +} + +func (f *frameDataFrame) Height() int { + return f.f.Height() +} + +func (f *frameDataFrame) ImageBufferSize(align int) (int, error) { + return f.f.ImageBufferSize(align) +} + +func (f *frameDataFrame) ImageCopyToBuffer(b []byte, align int) (int, error) { + return f.f.ImageCopyToBuffer(b, align) +} + +func (f *frameDataFrame) Linesize(i int) int { + return f.f.Linesize()[i] +} + +func (f *frameDataFrame) PixelFormat() PixelFormat { + return f.f.PixelFormat() +} + +func (f *frameDataFrame) PlaneBytes(i int) []byte { + return bytesFromC(func(size *cUlong) *C.uint8_t { + *size = cUlong(int(f.f.c.linesize[i]) * f.f.Height()) + return f.f.c.data[i] + }) +} + +func (f *frameDataFrame) Width() int { + return f.f.Width() +} diff --git a/frame_data_internal_test.go b/frame_data_internal_test.go new file mode 100644 index 0000000..544c36e --- /dev/null +++ b/frame_data_internal_test.go @@ -0,0 +1,285 @@ +package astiav + +import ( + "image" + "testing" + + "github.com/stretchr/testify/require" +) + +type mockedFrameDataFrame struct { + height int + imageBytes []byte + linesizes []int + pixelFormat PixelFormat + planesBytes [][]byte + width int +} + +var _ frameDataFramer = (*mockedFrameDataFrame)(nil) + +func (f *mockedFrameDataFrame) Height() int { + return f.height +} + +func (f *mockedFrameDataFrame) ImageBufferSize(align int) (int, error) { + return len(f.imageBytes), nil +} + +func (f *mockedFrameDataFrame) ImageCopyToBuffer(b []byte, align int) (int, error) { + copy(b, f.imageBytes) + return len(f.imageBytes), nil +} + +func (f *mockedFrameDataFrame) Linesize(i int) int { + return f.linesizes[i] +} + +func (f *mockedFrameDataFrame) PixelFormat() PixelFormat { + return f.pixelFormat +} + +func (f *mockedFrameDataFrame) PlaneBytes(i int) []byte { + return f.planesBytes[i] +} + +func (f *mockedFrameDataFrame) Width() int { + return f.width +} + +func TestFrameDataInternal(t *testing.T) { + fdf := &mockedFrameDataFrame{} + fd := newFrameData(fdf) + + for _, v := range []struct { + err bool + i image.Image + pfs []PixelFormat + }{ + { + i: &image.Gray{}, + pfs: []PixelFormat{PixelFormatGray8}, + }, + { + i: &image.Gray16{}, + pfs: []PixelFormat{PixelFormatGray16Be}, + }, + { + i: &image.RGBA{}, + pfs: []PixelFormat{ + PixelFormatRgb0, + PixelFormat0Rgb, + PixelFormatRgb4, + PixelFormatRgb8, + }, + }, + { + i: &image.NRGBA{}, + pfs: []PixelFormat{PixelFormatRgba}, + }, + { + i: &image.NRGBA64{}, + pfs: []PixelFormat{PixelFormatRgba64Be}, + }, + { + i: &image.NYCbCrA{}, + pfs: []PixelFormat{ + PixelFormatYuva420P, + PixelFormatYuva422P, + PixelFormatYuva444P, + }, + }, + { + i: &image.YCbCr{}, + pfs: []PixelFormat{ + PixelFormatYuv410P, + PixelFormatYuv411P, + PixelFormatYuvj411P, + PixelFormatYuv420P, + PixelFormatYuvj420P, + PixelFormatYuv422P, + PixelFormatYuvj422P, + PixelFormatYuv440P, + PixelFormatYuvj440P, + PixelFormatYuv444P, + PixelFormatYuvj444P, + }, + }, + { + err: true, + pfs: []PixelFormat{PixelFormatAbgr}, + }, + } { + for _, pf := range v.pfs { + fdf.pixelFormat = pf + i, err := fd.GuessImageFormat() + if v.err { + require.Error(t, err) + } else { + require.IsType(t, v.i, i) + } + } + } + + fdf.imageBytes = []byte{0, 1, 2, 3} + _, err := fd.Bytes(0) + require.Error(t, err) + fdf.height = 1 + fdf.width = 2 + b, err := fd.Bytes(0) + require.NoError(t, err) + require.Equal(t, fdf.imageBytes, b) + + for _, v := range []struct { + e image.Image + err bool + i image.Image + linesizes []int + pixelFormat PixelFormat + planesBytes [][]byte + }{ + { + e: &image.Alpha{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.Alpha{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.Alpha16{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.Alpha16{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.CMYK{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.CMYK{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.Gray{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.Gray{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.Gray16{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.Gray16{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.NRGBA{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.NRGBA{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.NRGBA64{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.NRGBA64{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.NYCbCrA{ + A: []byte{6, 7}, + AStride: 4, + YCbCr: image.YCbCr{ + Y: []byte{0, 1}, + Cb: []byte{2, 3}, + Cr: []byte{4, 5}, + YStride: 1, + CStride: 2, + SubsampleRatio: image.YCbCrSubsampleRatio444, + Rect: image.Rect(0, 0, 2, 1), + }, + }, + i: &image.NYCbCrA{}, + linesizes: []int{1, 2, 3, 4}, + pixelFormat: PixelFormatYuv444P, + planesBytes: [][]byte{{0, 1}, {2, 3}, {4, 5}, {6, 7}}, + }, + { + e: &image.RGBA{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.RGBA{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.RGBA64{ + Pix: []byte{0, 1, 2, 3}, + Stride: 1, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.RGBA64{}, + linesizes: []int{1}, + pixelFormat: PixelFormatRgba, + planesBytes: [][]byte{{0, 1, 2, 3}}, + }, + { + e: &image.YCbCr{ + Y: []byte{0, 1}, + Cb: []byte{2, 3}, + Cr: []byte{4, 5}, + YStride: 1, + CStride: 2, + SubsampleRatio: image.YCbCrSubsampleRatio420, + Rect: image.Rect(0, 0, 2, 1), + }, + i: &image.YCbCr{}, + linesizes: []int{1, 2, 3}, + pixelFormat: PixelFormatYuv420P, + planesBytes: [][]byte{{0, 1}, {2, 3}, {4, 5}}, + }, + } { + fdf.linesizes = v.linesizes + fdf.pixelFormat = v.pixelFormat + fdf.planesBytes = v.planesBytes + err = fd.ToImage(v.i) + if v.err { + require.Error(t, err) + } else { + require.Equal(t, v.e, v.i) + } + } +} diff --git a/frame_data_test.go b/frame_data_test.go index 39fc920..fc9c12f 100644 --- a/frame_data_test.go +++ b/frame_data_test.go @@ -1,7 +1,6 @@ package astiav_test import ( - "image" "image/png" "os" "testing" @@ -10,289 +9,14 @@ import ( "github.com/stretchr/testify/require" ) -type frameDataFrame struct { - height int - imageBytes []byte - linesizes []int - pixelFormat astiav.PixelFormat - planesBytes [][]byte - width int -} - -var _ astiav.FrameDataFrame = (*frameDataFrame)(nil) - -func (f *frameDataFrame) Height() int { - return f.height -} - -func (f *frameDataFrame) ImageBufferSize(align int) (int, error) { - return len(f.imageBytes), nil -} - -func (f *frameDataFrame) ImageCopyToBuffer(b []byte, align int) (int, error) { - copy(b, f.imageBytes) - return len(f.imageBytes), nil -} - -func (f *frameDataFrame) Linesize(i int) int { - return f.linesizes[i] -} - -func (f *frameDataFrame) PixelFormat() astiav.PixelFormat { - return f.pixelFormat -} - -func (f *frameDataFrame) PlaneBytes(i int) []byte { - return f.planesBytes[i] -} - -func (f *frameDataFrame) Width() int { - return f.width -} - func TestFrameData(t *testing.T) { - fdf := &frameDataFrame{} - fd := astiav.NewFrameData(fdf) - - for _, v := range []struct { - err bool - i image.Image - pfs []astiav.PixelFormat - }{ - { - i: &image.Gray{}, - pfs: []astiav.PixelFormat{astiav.PixelFormatGray8}, - }, - { - i: &image.Gray16{}, - pfs: []astiav.PixelFormat{astiav.PixelFormatGray16Be}, - }, - { - i: &image.RGBA{}, - pfs: []astiav.PixelFormat{ - astiav.PixelFormatRgb0, - astiav.PixelFormat0Rgb, - astiav.PixelFormatRgb4, - astiav.PixelFormatRgb8, - }, - }, - { - i: &image.NRGBA{}, - pfs: []astiav.PixelFormat{astiav.PixelFormatRgba}, - }, - { - i: &image.NRGBA64{}, - pfs: []astiav.PixelFormat{astiav.PixelFormatRgba64Be}, - }, - { - i: &image.NYCbCrA{}, - pfs: []astiav.PixelFormat{ - astiav.PixelFormatYuva420P, - astiav.PixelFormatYuva422P, - astiav.PixelFormatYuva444P, - }, - }, - { - i: &image.YCbCr{}, - pfs: []astiav.PixelFormat{ - astiav.PixelFormatYuv410P, - astiav.PixelFormatYuv411P, - astiav.PixelFormatYuvj411P, - astiav.PixelFormatYuv420P, - astiav.PixelFormatYuvj420P, - astiav.PixelFormatYuv422P, - astiav.PixelFormatYuvj422P, - astiav.PixelFormatYuv440P, - astiav.PixelFormatYuvj440P, - astiav.PixelFormatYuv444P, - astiav.PixelFormatYuvj444P, - }, - }, - { - err: true, - pfs: []astiav.PixelFormat{astiav.PixelFormatAbgr}, - }, - } { - for _, pf := range v.pfs { - fdf.pixelFormat = pf - i, err := fd.GuessImageFormat() - if v.err { - require.Error(t, err) - } else { - require.IsType(t, v.i, i) - } - } - } - - fdf.imageBytes = []byte{0, 1, 2, 3} - _, err := fd.Bytes(0) - require.Error(t, err) - fdf.height = 1 - fdf.width = 2 - b, err := fd.Bytes(0) - require.NoError(t, err) - require.Equal(t, fdf.imageBytes, b) - - for _, v := range []struct { - e image.Image - err bool - i image.Image - linesizes []int - pixelFormat astiav.PixelFormat - planesBytes [][]byte - }{ - { - e: &image.Alpha{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.Alpha{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.Alpha16{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.Alpha16{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.CMYK{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.CMYK{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.Gray{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.Gray{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.Gray16{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.Gray16{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.NRGBA{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.NRGBA{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.NRGBA64{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.NRGBA64{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.NYCbCrA{ - A: []byte{6, 7}, - AStride: 4, - YCbCr: image.YCbCr{ - Y: []byte{0, 1}, - Cb: []byte{2, 3}, - Cr: []byte{4, 5}, - YStride: 1, - CStride: 2, - SubsampleRatio: image.YCbCrSubsampleRatio444, - Rect: image.Rect(0, 0, 2, 1), - }, - }, - i: &image.NYCbCrA{}, - linesizes: []int{1, 2, 3, 4}, - pixelFormat: astiav.PixelFormatYuv444P, - planesBytes: [][]byte{{0, 1}, {2, 3}, {4, 5}, {6, 7}}, - }, - { - e: &image.RGBA{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.RGBA{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.RGBA64{ - Pix: []byte{0, 1, 2, 3}, - Stride: 1, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.RGBA64{}, - linesizes: []int{1}, - pixelFormat: astiav.PixelFormatRgba, - planesBytes: [][]byte{{0, 1, 2, 3}}, - }, - { - e: &image.YCbCr{ - Y: []byte{0, 1}, - Cb: []byte{2, 3}, - Cr: []byte{4, 5}, - YStride: 1, - CStride: 2, - SubsampleRatio: image.YCbCrSubsampleRatio420, - Rect: image.Rect(0, 0, 2, 1), - }, - i: &image.YCbCr{}, - linesizes: []int{1, 2, 3}, - pixelFormat: astiav.PixelFormatYuv420P, - planesBytes: [][]byte{{0, 1}, {2, 3}, {4, 5}}, - }, - } { - fdf.linesizes = v.linesizes - fdf.pixelFormat = v.pixelFormat - fdf.planesBytes = v.planesBytes - err = fd.ToImage(v.i) - if v.err { - require.Error(t, err) - } else { - require.Equal(t, v.e, v.i) - } - } - const ( name = "image-rgba" ext = "png" ) f, err := globalHelper.inputLastFrame(name+"."+ext, astiav.MediaTypeVideo) require.NoError(t, err) - fd = f.Data() + fd := f.Data() b1, err := fd.Bytes(1) require.NoError(t, err) diff --git a/input_format_test.go b/input_format_test.go index c1d00b5..4e1fdd4 100644 --- a/input_format_test.go +++ b/input_format_test.go @@ -11,5 +11,7 @@ func TestInputFormat(t *testing.T) { formatName := "rawvideo" inputFormat := astiav.FindInputFormat(formatName) require.NotNil(t, inputFormat) - require.True(t, inputFormat.Name() == formatName) + require.Equal(t, formatName, inputFormat.Name()) + require.Equal(t, formatName, inputFormat.String()) + require.Equal(t, "raw video", inputFormat.LongName()) }