@@ -73,6 +73,42 @@ func ptr(buf []byte) *C.uint8_t {
73
73
return (* C .uint8_t )(unsafe .Pointer (h .Data ))
74
74
}
75
75
76
+ // SetFrameFromImgMacroAlign sets the frame from the given image.YCbCr adding
77
+ // line padding to the image to ensure that the data is aligned to the given boundary.
78
+ // For example see alignment requirements for the Raspberry Pi GPU codec:
79
+ // https://github.com/raspberrypi/linux/blob/rpi-6.1.y/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c#L174
80
+ func (f * Frame ) SetFrameFromImgMacroAlign (img * image.YCbCr , boundary int ) {
81
+ // Calculating padded strides
82
+ // Rounding up to next multiple of boundary value
83
+ paddedYStride := ((img .YStride + boundary - 1 ) / boundary ) * boundary
84
+ // UV half the Y stride for 4:2:0
85
+ paddedCbCrStride := paddedYStride / 2
86
+
87
+ // Allocate new buffers with padding
88
+ // These will be freed by the GC
89
+ paddedY := make ([]byte , paddedYStride * img .Rect .Dy ())
90
+ paddedCb := make ([]byte , paddedCbCrStride * img .Rect .Dy ()/ 2 )
91
+ paddedCr := make ([]byte , paddedCbCrStride * img .Rect .Dy ()/ 2 )
92
+
93
+ // Copy data from img to padded buffers line by line
94
+ for i := 0 ; i < img .Rect .Dy (); i ++ {
95
+ copy (paddedY [i * paddedYStride :(i + 1 )* paddedYStride ], img .Y [i * img .YStride :])
96
+ }
97
+ for i := 0 ; i < img .Rect .Dy ()/ 2 ; i ++ {
98
+ copy (paddedCb [i * paddedCbCrStride :(i + 1 )* paddedCbCrStride ], img .Cb [i * img .CStride :])
99
+ copy (paddedCr [i * paddedCbCrStride :(i + 1 )* paddedCbCrStride ], img .Cr [i * img .CStride :])
100
+ }
101
+
102
+ // Update AVFrame data pointers and linesize
103
+ // Casting from go slice to C array without changing memory
104
+ f .data [0 ] = (* C .uchar )(unsafe .Pointer (& paddedY [0 ]))
105
+ f .data [1 ] = (* C .uchar )(unsafe .Pointer (& paddedCb [0 ]))
106
+ f .data [2 ] = (* C .uchar )(unsafe .Pointer (& paddedCr [0 ]))
107
+ f .linesize [0 ] = C .int (paddedYStride )
108
+ f .linesize [1 ] = C .int (paddedCbCrStride )
109
+ f .linesize [2 ] = C .int (paddedCbCrStride )
110
+ }
111
+
76
112
// SetFrameFromImg sets the frame from the given image.YCbCr
77
113
func (f * Frame ) SetFrameFromImg (img * image.YCbCr ) {
78
114
f .data [0 ] = ptr (img .Y )
0 commit comments