26
26
27
27
28
28
#include "encoder.h"
29
-
29
+ #include "../../../libs/logging.h"
30
30
31
31
typedef struct {
32
32
struct jpeg_destination_mgr mgr ; // Default manager
@@ -38,6 +38,7 @@ typedef struct {
38
38
static void _jpeg_set_dest_frame (j_compress_ptr jpeg , us_frame_s * frame );
39
39
40
40
static void _jpeg_write_scanlines_yuv (struct jpeg_compress_struct * jpeg , const us_frame_s * frame );
41
+ static void _jpeg_write_scanlines_yuv_planar (struct jpeg_compress_struct * jpeg , const us_frame_s * frame );
41
42
static void _jpeg_write_scanlines_rgb565 (struct jpeg_compress_struct * jpeg , const us_frame_s * frame );
42
43
static void _jpeg_write_scanlines_rgb24 (struct jpeg_compress_struct * jpeg , const us_frame_s * frame );
43
44
#ifndef JCS_EXTENSIONS
@@ -69,9 +70,13 @@ void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, unsigned q
69
70
switch (src -> format ) {
70
71
case V4L2_PIX_FMT_YUYV :
71
72
case V4L2_PIX_FMT_YVYU :
72
- case V4L2_PIX_FMT_UYVY : jpeg .in_color_space = JCS_YCbCr ; break ;
73
+ case V4L2_PIX_FMT_UYVY :
74
+ case V4L2_PIX_FMT_YUV410 :
75
+ case V4L2_PIX_FMT_YVU410 :
76
+ case V4L2_PIX_FMT_YUV420 :
77
+ case V4L2_PIX_FMT_YVU420 : jpeg .in_color_space = JCS_YCbCr ; break ;
73
78
# ifdef JCS_EXTENSIONS
74
- case V4L2_PIX_FMT_BGR24 : jpeg .in_color_space = JCS_EXT_BGR ; break ;
79
+ case V4L2_PIX_FMT_BGR24 : jpeg .in_color_space = JCS_EXT_BGR ; break ;
75
80
# endif
76
81
default : jpeg .in_color_space = JCS_RGB ; break ;
77
82
}
@@ -85,7 +90,11 @@ void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, unsigned q
85
90
// https://www.fourcc.org/yuv.php
86
91
case V4L2_PIX_FMT_YUYV :
87
92
case V4L2_PIX_FMT_YVYU :
88
- case V4L2_PIX_FMT_UYVY : _jpeg_write_scanlines_yuv (& jpeg , src ); break ;
93
+ case V4L2_PIX_FMT_UYVY : _jpeg_write_scanlines_yuv (& jpeg , src ); break ;
94
+ case V4L2_PIX_FMT_YUV410 :
95
+ case V4L2_PIX_FMT_YVU410 :
96
+ case V4L2_PIX_FMT_YUV420 :
97
+ case V4L2_PIX_FMT_YVU420 : _jpeg_write_scanlines_yuv_planar (& jpeg , src ); break ;
89
98
case V4L2_PIX_FMT_RGB565 : _jpeg_write_scanlines_rgb565 (& jpeg , src ); break ;
90
99
case V4L2_PIX_FMT_RGB24 : _jpeg_write_scanlines_rgb24 (& jpeg , src ); break ;
91
100
case V4L2_PIX_FMT_BGR24 :
@@ -167,6 +176,64 @@ static void _jpeg_write_scanlines_yuv(struct jpeg_compress_struct *jpeg, const u
167
176
free (line_buf );
168
177
}
169
178
179
+ static void _jpeg_write_scanlines_yuv_planar (struct jpeg_compress_struct * jpeg , const us_frame_s * frame ) {
180
+ uint8_t * line_buf ;
181
+ US_CALLOC (line_buf , frame -> width * 3 );
182
+
183
+ US_LOG_DEBUG ("Using Planar Encoder" );
184
+ const unsigned padding = us_frame_get_padding (frame );
185
+ const uint image_size = frame -> width * frame -> height ;
186
+ const uint chroma_array_size = (frame -> used - image_size ) / 2 ;
187
+ const uint chroma_matrix_order = (image_size / chroma_array_size ) == 16 ? 4 : 2 ;
188
+ US_LOG_DEBUG ("Planar data: Image Size %u, Chroma Array Size %u, Chroma Matrix Order %u" , image_size , chroma_array_size , chroma_matrix_order );
189
+ const uint8_t * data = frame -> data ;
190
+ const uint8_t * chroma1_data = frame -> data + image_size ;
191
+ const uint8_t * chroma2_data = frame -> data + image_size + chroma_array_size ;
192
+
193
+ while (jpeg -> next_scanline < frame -> height ) {
194
+ uint8_t * ptr = line_buf ;
195
+
196
+ for (unsigned x = 0 ; x < frame -> width ; ++ x ) {
197
+ // See also: https://www.kernel.org/doc/html/v4.8/media/uapi/v4l/pixfmt-yuv420.html
198
+ uint8_t y = data [x ], u , v ;
199
+ uint chroma_position = x / chroma_matrix_order ;
200
+
201
+ switch (frame -> format ) {
202
+ case V4L2_PIX_FMT_YUV420 :
203
+ case V4L2_PIX_FMT_YUV410 :
204
+ u = chroma1_data [chroma_position ];
205
+ v = chroma2_data [chroma_position ];
206
+ break ;
207
+ case V4L2_PIX_FMT_YVU420 :
208
+ case V4L2_PIX_FMT_YVU410 :
209
+ u = chroma2_data [chroma_position ];
210
+ v = chroma1_data [chroma_position ];
211
+ break ;
212
+ default :
213
+ assert (0 && "Unsupported pixel format" );
214
+ return ; // Makes linter happy
215
+ }
216
+
217
+ ptr [0 ] = y ;
218
+ ptr [1 ] = u ;
219
+ ptr [2 ] = v ;
220
+ ptr += 3 ;
221
+ }
222
+
223
+ data += frame -> width + padding ;
224
+
225
+ if ( jpeg -> next_scanline > 0 && jpeg -> next_scanline % chroma_matrix_order == 0 ){
226
+ chroma1_data += (frame -> width + padding ) / chroma_matrix_order ;
227
+ chroma2_data += (frame -> width + padding ) / chroma_matrix_order ;
228
+ }
229
+
230
+ JSAMPROW scanlines [1 ] = {line_buf };
231
+ jpeg_write_scanlines (jpeg , scanlines , 1 );
232
+ }
233
+
234
+ free (line_buf );
235
+ }
236
+
170
237
static void _jpeg_write_scanlines_rgb565 (struct jpeg_compress_struct * jpeg , const us_frame_s * frame ) {
171
238
uint8_t * line_buf ;
172
239
US_CALLOC (line_buf , frame -> width * 3 );
0 commit comments