Files
mpp/utils/osd3_test.c
xiaoxu.chen 6fc87d071a fix[utils]: Fix osd test compilation warning
Change-Id: I9b3cf8c3646db28a9dd3b1410ae15f4ef2199b4a
Signed-off-by: xiaoxu.chen <xiaoxu.chen@rock-chips.com>
2025-10-22 10:48:30 +08:00

603 lines
19 KiB
C

/* SPDX-License-Identifier: Apache-2.0 */
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#define MODULE_TAG "OSD3_TEST"
#include "osd3_test.h"
#include "mpp_common.h"
#include "kmpp_buffer.h"
/**
* @brief Generate horizontal SMPTE test pattern in ARGB inteleaved format.
* Test pattern bar color:
* {255, 255, 255}, // White
* {254, 255, 0}, // Yelow
* {0, 254, 255}, // Cyan
* {255, 0, 0}, // Red
* {0, 255, 0}, // Green
* {0, 0, 255}, // Blue
* {191, 191, 191}, // 75% White
* {0, 0, 0,} // Black
* TODO Add RGB to YUV translation
*
* @param dst buffer should be at the size of (bar_width * bar_height * 8 * 4)
* @param bar_width each bar width
* @param bar_heigt each bar height
*/
MPP_RET osd3_gen_smpte_bar_argb(RK_U8 **dst)
{
MPP_RET ret = MPP_OK;
RK_U32 i, j, k = 0;
FILE *fp = NULL;
RK_U32 bar_width = OSD_PATTERN_WIDTH;
RK_U32 bar_height = OSD_PATTERN_HEIGHT / SMPTE_BAR_CNT;
RK_U8 smpte_bar[8][3] = {
{255, 255, 255}, // White
{254, 255, 0}, // Yelow
{0, 254, 255}, // Cyan
{255, 0, 0}, // Red
{0, 255, 0}, // Green
{0, 0, 255}, // Blue
{191, 191, 191}, // 75% White
{0, 0, 0,} // Black
};
RK_U8 *base = malloc(bar_width * bar_height * SMPTE_BAR_CNT * 4);
*dst = base;
fp = fopen("/userdata/wind_ABGR8888.ABGR8888", "rb");
if (!fp) {
for (k = 0; k < SMPTE_BAR_CNT; k++) {
for (j = 0; j < bar_height; j++) {
for (i = 0; i < bar_width; i++) {
base[i * 4] = 0xff;
base[i * 4 + 1] = smpte_bar[k][0];
base[i * 4 + 2] = smpte_bar[k][1];
base[i * 4 + 3] = smpte_bar[k][2];
}
base += bar_width * 4;
}
}
} else {
size_t read_size = OSD_PATTERN_WIDTH * OSD_PATTERN_HEIGHT * 4;
size_t fp_size;
fp_size = fread(base, 1, read_size, fp);
if (fp_size != read_size) {
mpp_err("fread failed, read_size: %zu, fp_size: %zu", read_size, fp_size);
free(base);
*dst = NULL;
ret = MPP_NOK;
}
fclose(fp);
}
return ret;
}
static MPP_RET translate_argb(RK_U8 *src, RK_U8 *dst, RK_U32 width, RK_U32 height,
RK_U32 fmt_idx, MppEncOSDRegion3 *cfg)
{
MPP_RET ret = MPP_OK;
RK_U32 i = 0;
RK_U32 j = 0;
RK_U16 *tmp_u16 = NULL;
RK_U8 tmp_r = 0;
RK_U8 tmp_g = 0;
RK_U8 tmp_b = 0;
if (fmt_idx == OSD_FMT_ARGB8888) {
cfg->fmt = MPP_FMT_ARGB8888;
cfg->alpha_cfg.alpha_swap = 1;
cfg->rbuv_swap = 1;
cfg->stride = width * 4;
memcpy(dst, src, width * height * 4);
} else if (fmt_idx == OSD_FMT_RGBA8888) {
cfg->fmt = MPP_FMT_RGBA8888;
cfg->alpha_cfg.alpha_swap = 1;
cfg->rbuv_swap = 0;
cfg->stride = width * 4;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
dst[j * width * 4 + i * 4 + 0] = src[j * width * 4 + i * 4 + 0];
dst[j * width * 4 + i * 4 + 1] = src[j * width * 4 + i * 4 + 3];
dst[j * width * 4 + i * 4 + 2] = src[j * width * 4 + i * 4 + 2];
dst[j * width * 4 + i * 4 + 3] = src[j * width * 4 + i * 4 + 1];
}
}
} else if (fmt_idx == OSD_FMT_BGRA8888) {
cfg->fmt = MPP_FMT_ARGB8888;
cfg->alpha_cfg.alpha_swap = 1;
cfg->alpha_cfg.alpha_swap = 0;
cfg->rbuv_swap = 0;
cfg->stride = width * 4;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
dst[j * width * 4 + i * 4 + 0] = src[j * width * 4 + i * 4 + 3];
dst[j * width * 4 + i * 4 + 1] = src[j * width * 4 + i * 4 + 2];
dst[j * width * 4 + i * 4 + 2] = src[j * width * 4 + i * 4 + 1];
dst[j * width * 4 + i * 4 + 3] = src[j * width * 4 + i * 4 + 0];
}
}
} else if (fmt_idx == OSD_FMT_ABGR8888) {
cfg->fmt = MPP_FMT_ABGR8888;
cfg->alpha_cfg.alpha_swap = 0;
cfg->rbuv_swap = 1;
cfg->stride = width * 4;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
dst[j * width * 4 + i * 4 + 0] = src[j * width * 4 + i * 4 + 1];
dst[j * width * 4 + i * 4 + 1] = src[j * width * 4 + i * 4 + 2];
dst[j * width * 4 + i * 4 + 2] = src[j * width * 4 + i * 4 + 3];
dst[j * width * 4 + i * 4 + 3] = src[j * width * 4 + i * 4 + 0];
}
}
} else if (fmt_idx == OSD_FMT_BGRA5551) {
cfg->fmt = MPP_FMT_ARGB1555;
cfg->alpha_cfg.alpha_swap = 0;
cfg->rbuv_swap = 0;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_r >> 3) << 10) +
((tmp_g >> 3) << 5) +
((tmp_b >> 3) | 0x8000);
}
}
} else if (fmt_idx == OSD_FMT_RGBA5551) {
cfg->fmt = MPP_FMT_ARGB1555;
cfg->alpha_cfg.alpha_swap = 0;
cfg->rbuv_swap = 1;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_b >> 3) << 10) +
((tmp_g >> 3) << 5) +
((tmp_r >> 3) | 0x8000);
}
}
} else if (fmt_idx == OSD_FMT_ABGR1555) {
cfg->fmt = MPP_FMT_ARGB1555;
cfg->alpha_cfg.alpha_swap = 1;
cfg->rbuv_swap = 0;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_r >> 3) << 11) +
((tmp_g >> 3) << 6) +
((tmp_b >> 3) << 1) + 1;
}
}
} else if (fmt_idx == OSD_FMT_ARGB1555) {
cfg->fmt = MPP_FMT_ARGB1555;
cfg->alpha_cfg.alpha_swap = 1;
cfg->rbuv_swap = 1;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_b >> 3) << 11) +
((tmp_g >> 3) << 6) +
((tmp_r >> 3) << 1) + 1;
}
}
} else if (fmt_idx == OSD_FMT_BGRA4444) {
cfg->fmt = MPP_FMT_ARGB4444;
cfg->alpha_cfg.alpha_swap = 0;
cfg->rbuv_swap = 0;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_r >> 4) << 8) +
((tmp_g >> 4) << 4) +
((tmp_b >> 4) | 0xf000);
}
}
} else if (fmt_idx == OSD_FMT_RGBA4444) {
cfg->fmt = MPP_FMT_ARGB4444;
cfg->alpha_cfg.alpha_swap = 0;
cfg->rbuv_swap = 1;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_b >> 4) << 8) +
((tmp_g >> 4) << 4) +
((tmp_r >> 4) | 0xf000);
}
}
} else if (fmt_idx == OSD_FMT_ABGR4444) {
cfg->fmt = MPP_FMT_ARGB4444;
cfg->alpha_cfg.alpha_swap = 1;
cfg->rbuv_swap = 0;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_r >> 4) << 12) +
((tmp_g >> 4) << 8) +
((tmp_b >> 4) << 4) + 0x0f;
}
}
} else if (fmt_idx == OSD_FMT_ARGB4444) {
cfg->fmt = MPP_FMT_ARGB4444;
cfg->alpha_cfg.alpha_swap = 1;
cfg->rbuv_swap = 1;
cfg->stride = width * 2;
tmp_u16 = (RK_U16 *)dst;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
tmp_r = src[j * width * 4 + i * 4 + 1];
tmp_g = src[j * width * 4 + i * 4 + 2];
tmp_b = src[j * width * 4 + i * 4 + 3];
tmp_u16[j * width + i] = ((tmp_b >> 4) << 12) +
((tmp_g >> 4) << 8) +
((tmp_r >> 4) << 4) + 0x0f;
}
}
} else if (fmt_idx == OSD_FMT_AYUV2BPP) {
cfg->fmt = MPP_FMT_AYUV2BPP;
cfg->rbuv_swap = 0;
cfg->alpha_cfg.alpha_swap = 0;
cfg->stride = width / 4;
for (j = 0; j < height; j++) {
RK_U32 is_black;
is_black = (j / SMPTE_BAR_CNT) % 2 ? 1 : 0;
for (i = 0; i < width; i++) {
if (is_black)
dst[j * width / 4 + i / 4] = (dst[j * width / 4 + i / 4] << 2) | 0;
else
dst[j * width / 4 + i / 4] = (dst[j * width / 4 + i / 4] << 2) | (1 << 1 | 1);
}
}
} else if (fmt_idx == OSD_FMT_AYUV1BPP) {
cfg->fmt = MPP_FMT_AYUV1BPP;
cfg->rbuv_swap = 0;
cfg->alpha_cfg.alpha_swap = 0;
cfg->stride = width / 8;
for (j = 0; j < height; j++) {
RK_U32 is_black;
is_black = (j / SMPTE_BAR_CNT) % 2 ? 1 : 0;
for (i = 0; i < width; i++) {
if (is_black)
dst[j * width / 8 + i / 8] = (dst[j * width / 8 + i / 8] << 1) | 0;
else
dst[j * width / 8 + i / 8] = (dst[j * width / 8 + i / 8] << 1) | 1;
}
}
}
return ret;
}
static RK_U32 get_frame_size_by_format(OsdFmt fmt, RK_U32 width, RK_U32 height)
{
switch (fmt) {
case OSD_FMT_ARGB8888:
case OSD_FMT_RGBA8888:
case OSD_FMT_BGRA8888:
case OSD_FMT_ABGR8888:
return width * height * 4;
case OSD_FMT_ARGB1555:
case OSD_FMT_ABGR1555:
case OSD_FMT_RGBA5551:
case OSD_FMT_BGRA5551:
case OSD_FMT_ARGB4444:
case OSD_FMT_ABGR4444:
case OSD_FMT_RGBA4444:
case OSD_FMT_BGRA4444:
return width * height * 2;
case OSD_FMT_AYUV2BPP:
return width * height / 4;
case OSD_FMT_AYUV1BPP:
return width * height / 8;
default:
return 0;
}
}
static MPP_RET osd3_test_case_fmt(MppEncOSDData3 *osd_data)
{
MppEncOSDRegion3 *region = &osd_data->region[0];
if (region->fmt == MPP_FMT_AYUV2BPP || region->fmt == MPP_FMT_AYUV1BPP)
region->alpha_cfg.fg_alpha_sel = FROM_LUT;
else
region->alpha_cfg.fg_alpha_sel = FROM_DDR;
return MPP_OK;
}
static MPP_RET osd3_test_case_fg_alpha_sel(MppEncOSDData3 *osd_data)
{
MppEncOSDRegion3 *region = &osd_data->region[0];
RK_U32 region_width = OSD_PATTERN_WIDTH;
region->alpha_cfg.fg_alpha_sel = FROM_DDR;
region = &osd_data->region[1];
memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
region->lt_x = (region_width + 16);
region->rb_x = region->lt_x + region_width - 1;
region->alpha_cfg.fg_alpha_sel = FROM_LUT;
region = &osd_data->region[2];
memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
region->lt_x = (region_width + 16) * 2;
region->rb_x = region->lt_x + region_width - 1;
region->alpha_cfg.fg_alpha_sel = FROM_REG;
region->alpha_cfg.fg_alpha = 0x80;
osd_data->num_region = 3;
return MPP_OK;
}
static MPP_RET osd3_test_case_ch_ds_mode(MppEncOSDData3 *osd_data)
{
MppEncOSDRegion3 *region = &osd_data->region[0];
RK_U32 region_width = OSD_PATTERN_WIDTH;
region->ch_ds_mode = AVERAGE;
region = &osd_data->region[1];
memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
region->lt_x = (region_width + 16);
region->rb_x = region->lt_x + region_width - 1;
region->ch_ds_mode = DROP;
osd_data->num_region = 2;
return MPP_OK;
}
static MPP_RET osd3_test_case_range_trns_sel(MppEncOSDData3 *osd_data)
{
MppEncOSDRegion3 *region = &osd_data->region[0];
RK_U32 region_width = OSD_PATTERN_WIDTH;
region->range_trns_sel = FULL_TO_LIMIT;
region->range_trns_en = 1;
region = &osd_data->region[1];
memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
region->lt_x = (region_width + 16);
region->rb_x = region->lt_x + region_width - 1;
region->range_trns_sel = LIMIT_TO_FULL;
osd_data->num_region = 2;
return MPP_OK;
}
static MPP_RET osd3_test_case_max_reginon_num(MppEncOSDData3 *osd_data)
{
MppEncOSDRegion3 *region = &osd_data->region[0];
RK_U32 region_width = OSD_PATTERN_WIDTH;
RK_U32 i;
for (i = 1; i < 8; i++) {
region = &osd_data->region[i];
memcpy(region, &osd_data->region[0], sizeof(MppEncOSDRegion3));
region->lt_x = (region_width + 16) * i;
region->rb_x = region->lt_x + region_width - 1;
}
osd_data->num_region = 8;
return MPP_OK;
}
static OsdCaseCfg osd3_test_cases[OSD_CASE_BUTT] = {
{
OSD_CASE_FMT_ARGB8888,
OSD_FMT_ARGB8888,
"osd argb8888",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_RGBA8888,
OSD_FMT_RGBA8888,
"osd rgba8888",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_BGRA8888,
OSD_FMT_BGRA8888,
"osd bgra8888",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_ABGR8888,
OSD_FMT_ABGR8888,
"osd abgr8888",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_ARGB1555,
OSD_FMT_ARGB1555,
"osd argb1555",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_ABGR1555,
OSD_FMT_ABGR1555,
"osd abgr1555",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_RGBA5551,
OSD_FMT_RGBA5551,
"osd rgba5551",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_BGRA5551,
OSD_FMT_BGRA5551,
"osd bgra5551",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_ARGB4444,
OSD_FMT_ARGB4444,
"osd argb4444",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_ABGR4444,
OSD_FMT_ABGR4444,
"osd abgr4444",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_RGBA4444,
OSD_FMT_RGBA4444,
"osd rgba4444",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_BGRA4444,
OSD_FMT_BGRA4444,
"osd bgra4444",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_AYUV2BPP,
OSD_FMT_AYUV2BPP,
"osd ayuv2bpp",
osd3_test_case_fmt,
},
{
OSD_CASE_FMT_AYUV1BPP,
OSD_FMT_AYUV1BPP,
"osd ayuv1bpp",
osd3_test_case_fmt,
},
{
OSD_CASE_FG_ALPAH_SEL,
OSD_FMT_ARGB8888,
"osd fg alpha sel",
osd3_test_case_fg_alpha_sel,
},
{
OSD_CASE_CH_DS_MODE,
OSD_FMT_ARGB8888,
"osd ch ds mode",
osd3_test_case_ch_ds_mode,
},
{
OSD_CASE_RANGE_TRNS_SEL,
OSD_FMT_ARGB8888,
"osd range trns sel",
osd3_test_case_range_trns_sel,
},
{
OSD_CASE_MAX_REGINON_NUM,
OSD_FMT_ARGB8888,
"osd max reginon num",
osd3_test_case_max_reginon_num,
}
};
MPP_RET osd3_get_test_case(MppEncOSDData3 *osd_data, RK_U8 *base_pattern, RK_U32 case_idx, KmppBuffer *osd_buffer)
{
KmppBufCfg osd_buf_cfg = NULL;
MPP_RET ret = MPP_OK;
RK_U32 buffer_size = 0;
KmppShmPtr osd_sptr;
RK_U8 *dst_ptr = NULL;
MppEncOSDRegion3 *region = NULL;
RK_U32 region_width = OSD_PATTERN_WIDTH;
RK_U32 region_height = OSD_PATTERN_HEIGHT;
if (!osd_data)
return MPP_ERR_NOMEM;
region = &osd_data->region[0];
memset(region, 0, sizeof(MppEncOSDRegion3));
if (*osd_buffer) {
kmpp_buffer_put(*osd_buffer);
*osd_buffer = NULL;
}
buffer_size = get_frame_size_by_format(osd3_test_cases[case_idx].fmt, region_width, region_height);
kmpp_buffer_get(osd_buffer);
if (!*osd_buffer)
return MPP_ERR_NOMEM;
osd_buf_cfg = kmpp_buffer_to_cfg(*osd_buffer);
if (!osd_buf_cfg)
return MPP_ERR_NOMEM;
kmpp_buf_cfg_set_size(osd_buf_cfg, MPP_ALIGN(buffer_size, 16));
kmpp_buffer_setup(*osd_buffer);
kmpp_buf_cfg_get_sptr(osd_buf_cfg, &osd_sptr);
dst_ptr = (RK_U8 *)(uintptr_t)osd_sptr.uaddr;
ret = translate_argb(base_pattern, dst_ptr, region_width, region_height, osd3_test_cases[case_idx].fmt, region);
region->osd_buf = *kmpp_obj_to_shm(*osd_buffer);
region->lt_x = 0;
region->lt_y = 0;
region->rb_x = region->lt_x + region_width - 1;
region->rb_y = region->lt_y + region_height - 1;
region->enable = 1;
osd_data->num_region = 1;
/* black: y=0, u=0x80, v=0x80, white: y=0xff, u=0x80 v=0x80 */
region->lut[0] = 0x80; // v0
region->lut[1] = 0x80; // u0
region->lut[2] = 0; // y0
region->lut[3] = 0x80; // v1
region->lut[4] = 0x80; // u1
region->lut[5] = 0xff; // y1
region->lut[6] = 0xff; // a0
region->lut[7] = 0xff; // a1
region->qp_cfg.qp_adj_en = 1;
region->qp_cfg.qp_adj_sel = QP_RELATIVE;
region->qp_cfg.qp_min = 10;
region->qp_cfg.qp_max = 51;
region->qp_cfg.qp = -1;
ret = osd3_test_cases[case_idx].func(osd_data);
mpp_log("osd case %d : %s done\n", case_idx, osd3_test_cases[case_idx].name);
return ret;
}