From 5ada918ab783aad3afc8b0221b565dae04952abc Mon Sep 17 00:00:00 2001 From: "terry.rong" Date: Sat, 23 Dec 2023 05:26:07 +0800 Subject: [PATCH] feat(image): add YUV format enum and adapter yuv for vglite GPU (#5080) Signed-off-by: rongyichang --- src/draw/lv_image_buf.h | 18 ++++++++++++++++++ src/draw/vg_lite/lv_vg_lite_decoder.c | 9 +++++---- src/draw/vg_lite/lv_vg_lite_utils.c | 19 ++++++++++++++----- src/misc/lv_color.h | 17 +++++++++++++++++ 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/draw/lv_image_buf.h b/src/draw/lv_image_buf.h index c2774db91..26ca95f1e 100644 --- a/src/draw/lv_image_buf.h +++ b/src/draw/lv_image_buf.h @@ -122,6 +122,24 @@ typedef struct { } lv_image_header_t; #endif +typedef struct { + void * buf; + uint32_t stride; /*Number of bytes in a row*/ +} lv_yuv_plane_t; + +typedef union { + lv_yuv_plane_t yuv; /*packed format*/ + struct { + lv_yuv_plane_t y; + lv_yuv_plane_t u; + lv_yuv_plane_t v; + } planar; /*planar format with 3 plane*/ + struct { + lv_yuv_plane_t y; + lv_yuv_plane_t uv; + } semi_planar; /*planar format with 2 plane*/ +} lv_yuv_buf_t; + /** * Struct to describe an image. Both decoded and raw image can share * the same struct. diff --git a/src/draw/vg_lite/lv_vg_lite_decoder.c b/src/draw/vg_lite/lv_vg_lite_decoder.c index 5d9b05223..c68dc5830 100644 --- a/src/draw/vg_lite/lv_vg_lite_decoder.c +++ b/src/draw/vg_lite/lv_vg_lite_decoder.c @@ -312,6 +312,7 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_ bool has_alpha = lv_color_format_has_alpha(cf); bool is_indexed = LV_COLOR_FORMAT_IS_INDEXED(cf); + bool is_yuv = LV_COLOR_FORMAT_IS_YUV(cf); bool is_addr_aligned = (image_data == lv_draw_buf_align((void *)image_data, cf)) ? true : false; uint32_t stride = lv_draw_buf_width_to_stride(width, cf); @@ -320,10 +321,10 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_ /* When the following conditions are met, * there is no need to copy image resource preprocessing. */ - if(is_addr_aligned - && is_stride_aligned - && !is_indexed - && (!has_alpha || (has_alpha && support_blend_normal))) { + if((is_addr_aligned + && is_stride_aligned + && !is_indexed + && (!has_alpha || (has_alpha && support_blend_normal))) || is_yuv) { /*add cache*/ lv_cache_lock(); diff --git a/src/draw/vg_lite/lv_vg_lite_utils.c b/src/draw/vg_lite/lv_vg_lite_utils.c index eb0679867..6392b432f 100644 --- a/src/draw/vg_lite/lv_vg_lite_utils.c +++ b/src/draw/vg_lite/lv_vg_lite_utils.c @@ -396,6 +396,7 @@ bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf) case LV_COLOR_FORMAT_RGB888: case LV_COLOR_FORMAT_ARGB8888: case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_NV12: return true; default: break; @@ -442,6 +443,9 @@ vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf) case LV_COLOR_FORMAT_XRGB8888: return VG_LITE_BGRX8888; + case LV_COLOR_FORMAT_NV12: + return VG_LITE_NV12; + default: LV_LOG_ERROR("unsupport color format: %d", cf); break; @@ -584,16 +588,21 @@ bool lv_vg_lite_buffer_init( buffer->height = height; lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align); buffer->stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align); - buffer->memory = (void *)ptr; - buffer->address = (uintptr_t)ptr; if(format == VG_LITE_NV12) { + lv_yuv_buf_t * frame_p = (lv_yuv_buf_t *)ptr; + buffer->memory = (void *)frame_p->semi_planar.y.buf; + buffer->address = (uintptr_t)frame_p->semi_planar.y.buf; buffer->yuv.swizzle = VG_LITE_SWIZZLE_UV; - buffer->yuv.uv_stride = buffer->stride; buffer->yuv.alpha_stride = buffer->stride; buffer->yuv.uv_height = buffer->height / 2; - buffer->yuv.uv_memory = (uint8_t *)ptr + (buffer->stride * buffer->height); - buffer->yuv.uv_planar = (uint32_t)(uintptr_t)buffer->yuv.uv_memory; + buffer->yuv.uv_memory = (void *)frame_p->semi_planar.uv.buf; + buffer->yuv.uv_planar = (uint32_t)(uintptr_t)frame_p->semi_planar.uv.buf; + buffer->yuv.uv_stride = frame_p->semi_planar.uv.stride; + } + else { + buffer->memory = (void *)ptr; + buffer->address = (uintptr_t)ptr; } return true; diff --git a/src/misc/lv_color.h b/src/misc/lv_color.h index ee2603fed..0d24dc7ec 100644 --- a/src/misc/lv_color.h +++ b/src/misc/lv_color.h @@ -139,6 +139,22 @@ enum _lv_color_format_t { LV_COLOR_FORMAT_A2 = 0x0C, LV_COLOR_FORMAT_A4 = 0x0D, + /* reference to https://wiki.videolan.org/YUV/ */ + /*YUV planar formats*/ + LV_COLOR_FORMAT_YUV_START = 0x20, + LV_COLOR_FORMAT_I420 = LV_COLOR_FORMAT_YUV_START, /*YUV420 planar(3 plane)*/ + LV_COLOR_FORMAT_I422 = 0x21, /*YUV422 planar(3 plane)*/ + LV_COLOR_FORMAT_I444 = 0x22, /*YUV444 planar(3 plane)*/ + LV_COLOR_FORMAT_I400 = 0x23, /*YUV400 no chroma channel*/ + LV_COLOR_FORMAT_NV21 = 0x24, /*YUV420 planar(2 plane), UV plane in 'V, U, V, U'*/ + LV_COLOR_FORMAT_NV12 = 0x25, /*YUV420 planar(2 plane), UV plane in 'U, V, U, V'*/ + + /*YUV packed formats*/ + LV_COLOR_FORMAT_YUY2 = 0x26, /*YUV422 packed like 'Y U Y V'*/ + LV_COLOR_FORMAT_UYVY = 0x27, /*YUV422 packed like 'U Y V Y'*/ + + LV_COLOR_FORMAT_YUV_END = LV_COLOR_FORMAT_UYVY, + /*Color formats in which LVGL can render*/ #if LV_COLOR_DEPTH == 8 LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_L8, @@ -162,6 +178,7 @@ typedef uint8_t lv_color_format_t; #define LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf) ((cf) >= LV_COLOR_FORMAT_A1 && (cf) <= LV_COLOR_FORMAT_A8) #define LV_COLOR_FORMAT_IS_INDEXED(cf) ((cf) >= LV_COLOR_FORMAT_I1 && (cf) <= LV_COLOR_FORMAT_I8) +#define LV_COLOR_FORMAT_IS_YUV(cf) ((cf) >= LV_COLOR_FORMAT_YUV_START && (cf) <= LV_COLOR_FORMAT_YUV_END) #define LV_COLOR_INDEXED_PALETTE_SIZE(cf) ((cf) == LV_COLOR_FORMAT_I1 ? 2 :\ (cf) == LV_COLOR_FORMAT_I2 ? 4 :\ (cf) == LV_COLOR_FORMAT_I4 ? 16 :\