@@ -479,35 +479,56 @@ READ_LINE(R8_read_line, px, u8, argb_u16_from_gray8, *px)
479479 * - Convert YUV and YVU with the same function (a column swap is needed when setting up
480480 * plane->conversion_matrix)
481481 */
482- static void semi_planar_yuv_read_line (const struct vkms_plane_state * plane , int x_start ,
483- int y_start , enum pixel_read_direction direction , int count ,
484- struct pixel_argb_u16 out_pixel [])
485- {
486- u8 * y_plane ;
487- u8 * uv_plane ;
488-
489- packed_pixels_addr_1x1 (plane -> frame_info , x_start , y_start , 0 ,
490- & y_plane );
491- packed_pixels_addr_1x1 (plane -> frame_info ,
492- x_start / plane -> frame_info -> fb -> format -> hsub ,
493- y_start / plane -> frame_info -> fb -> format -> vsub , 1 ,
494- & uv_plane );
495- int step_y = get_block_step_bytes (plane -> frame_info -> fb , direction , 0 );
496- int step_uv = get_block_step_bytes (plane -> frame_info -> fb , direction , 1 );
497- int subsampling = get_subsampling (plane -> frame_info -> fb -> format , direction );
498- int subsampling_offset = get_subsampling_offset (direction , x_start , y_start );
499- const struct conversion_matrix * conversion_matrix = & plane -> conversion_matrix ;
500482
501- for (int i = 0 ; i < count ; i ++ ) {
502- * out_pixel = argb_u16_from_yuv161616 (conversion_matrix , y_plane [0 ] * 257 ,
503- uv_plane [0 ] * 257 , uv_plane [1 ] * 257 );
504- out_pixel += 1 ;
505- y_plane += step_y ;
506- if ((i + subsampling_offset + 1 ) % subsampling == 0 )
507- uv_plane += step_uv ;
508- }
483+ /**
484+ * READ_LINE_YUV_SEMIPLANAR() - Generic generator for a read_line function which can be used for yuv
485+ * formats with two planes and block_w == block_h == 1.
486+ *
487+ * @function_name: Function name to generate
488+ * @pixel_1_name: temporary pixel name for the first plane used in the @__VA_ARGS__ parameters
489+ * @pixel_2_name: temporary pixel name for the second plane used in the @__VA_ARGS__ parameters
490+ * @pixel_1_type: Used to specify the type you want to cast the pixel pointer on the plane 1
491+ * @pixel_2_type: Used to specify the type you want to cast the pixel pointer on the plane 2
492+ * @callback: Callback to call for each pixels. This function should take
493+ * (struct conversion_matrix*, @__VA_ARGS__) as parameter and return a pixel_argb_u16
494+ * __VA_ARGS__: Argument to pass inside the callback. You can use @pixel_1_name and @pixel_2_name
495+ * to access current pixel values
496+ */
497+ #define READ_LINE_YUV_SEMIPLANAR (function_name , pixel_1_name , pixel_2_name , pixel_1_type , \
498+ pixel_2_type , callback , ...) \
499+ static void function_name(const struct vkms_plane_state *plane, int x_start, \
500+ int y_start, enum pixel_read_direction direction, int count, \
501+ struct pixel_argb_u16 out_pixel[]) \
502+ { \
503+ u8 *plane_1; \
504+ u8 *plane_2; \
505+ \
506+ packed_pixels_addr_1x1(plane->frame_info, x_start, y_start, 0, \
507+ &plane_1); \
508+ packed_pixels_addr_1x1(plane->frame_info, \
509+ x_start / plane->frame_info->fb->format->hsub, \
510+ y_start / plane->frame_info->fb->format->vsub, 1, \
511+ &plane_2); \
512+ int step_1 = get_block_step_bytes(plane->frame_info->fb, direction, 0); \
513+ int step_2 = get_block_step_bytes(plane->frame_info->fb, direction, 1); \
514+ int subsampling = get_subsampling(plane->frame_info->fb->format, direction); \
515+ int subsampling_offset = get_subsampling_offset(direction, x_start, y_start); \
516+ const struct conversion_matrix *conversion_matrix = &plane->conversion_matrix; \
517+ \
518+ for (int i = 0; i < count; i++) { \
519+ pixel_1_type *(pixel_1_name) = (pixel_1_type *)plane_1; \
520+ pixel_2_type *(pixel_2_name) = (pixel_2_type *)plane_2; \
521+ *out_pixel = (callback)(conversion_matrix, __VA_ARGS__); \
522+ out_pixel += 1; \
523+ plane_1 += step_1; \
524+ if ((i + subsampling_offset + 1) % subsampling == 0) \
525+ plane_2 += step_2; \
526+ } \
509527}
510528
529+ READ_LINE_YUV_SEMIPLANAR (YUV888_semiplanar_read_line , y , uv , u8 , u8 , argb_u16_from_yuv161616 ,
530+ y [0 ] * 257 , uv [0 ] * 257 , uv [1 ] * 257 )
531+
511532/*
512533 * This callback can be used for YUV format where each color component is
513534 * stored in a different plane (often called planar formats). It will
@@ -703,7 +724,7 @@ pixel_read_line_t get_pixel_read_line_function(u32 format)
703724 case DRM_FORMAT_NV21 :
704725 case DRM_FORMAT_NV61 :
705726 case DRM_FORMAT_NV42 :
706- return & semi_planar_yuv_read_line ;
727+ return & YUV888_semiplanar_read_line ;
707728 case DRM_FORMAT_YUV420 :
708729 case DRM_FORMAT_YUV422 :
709730 case DRM_FORMAT_YUV444 :
0 commit comments