1218 lines
42 KiB
C
1218 lines
42 KiB
C
/*
|
|
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
#include <signal.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/prctl.h>
|
|
#include <fcntl.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include "sample_comm.h"
|
|
#include "loadbmp.h"
|
|
|
|
#define SAMPLE_VGS_READ_PATH "./data/input/1920_1080_p420.yuv"
|
|
#define SAMPLE_VGS_READ_TILE_PATH "./data/input/Tile_1280x720_P420.yuv"
|
|
#define SAMPLE_VGS_SAVE_PATH "./data/output"
|
|
#define SAMPLE_VGS_BITMAP_PATH "./data/input/mm.bmp"
|
|
#define FILE_NAME_LENGTH 128 /* max filename length is 128 */
|
|
#define MAX_LUMA_NUM 4
|
|
|
|
typedef enum {
|
|
SAMPLE_VGS_OSD_NORM = 0,
|
|
SAMPLE_VGS_OSD_CLUT2,
|
|
SAMPLE_VGS_OSD_CLUT4,
|
|
SAMPLE_VGS_OSD_BUTT
|
|
} sample_vgs_osd_type;
|
|
|
|
typedef struct {
|
|
td_bool scale;
|
|
td_bool cover;
|
|
td_bool osd;
|
|
td_bool draw_line;
|
|
td_bool rotate;
|
|
td_bool luma;
|
|
|
|
ot_vgs_scale_coef_mode *vgs_scl_coef_mode;
|
|
ot_cover *vgs_add_cover;
|
|
ot_vgs_osd *vgs_add_osd;
|
|
ot_vgs_line *vgs_draw_line;
|
|
ot_rotation *rotation_angle;
|
|
td_u32 luma_num;
|
|
ot_rect *luma_rect;
|
|
td_u64 *luma_data;
|
|
|
|
ot_rgn_handle *rgn_handle[SAMPLE_VGS_OSD_BUTT];
|
|
sample_vb_base_info *in_img_vb_info;
|
|
sample_vb_base_info *out_img_vb_info;
|
|
td_s32 sample_num;
|
|
} sample_vgs_func_param;
|
|
|
|
typedef struct {
|
|
ot_vb_blk vb_handle;
|
|
td_void *virt_addr;
|
|
td_u32 vb_size;
|
|
td_bool vb_used;
|
|
} sample_vgs_vb_info;
|
|
|
|
typedef struct {
|
|
td_bool fill_en;
|
|
td_u32 fill_color;
|
|
ot_size osd_size;
|
|
td_u32 stride;
|
|
ot_pixel_format img_pixel_format;
|
|
} sample_vgs_osd_load_bmp_info;
|
|
|
|
sample_vgs_vb_info g_in_img_vb_info;
|
|
sample_vgs_vb_info g_out_img_vb_info;
|
|
static td_u32 g_vgs_sample_signal_flag = 0;
|
|
|
|
/* function : show usage */
|
|
td_void sample_vgs_usage(td_char *s_prg_nm)
|
|
{
|
|
printf("\n/*****************************************/\n");
|
|
printf("usage: %s <index>\n", s_prg_nm);
|
|
printf("index:\n");
|
|
printf("\t0) FILE -> VGS(scale) -> FILE.\n");
|
|
printf("\t1) FILE -> VGS(cover+OSD+clut) -> FILE.\n");
|
|
printf("\t2) FILE -> VGS(draw_line) -> FILE.\n");
|
|
printf("\t3) FILE -> VGS(rotate) -> FILE.\n");
|
|
printf("\t4) FILE -> VGS(luma) -> FILE + data.\n");
|
|
printf("/*****************************************/\n");
|
|
return;
|
|
}
|
|
|
|
/* function : to process abnormal case */
|
|
void sample_vgs_handle_sig(int signo)
|
|
{
|
|
if (signo == SIGINT || signo == SIGTERM) {
|
|
g_vgs_sample_signal_flag = 1;
|
|
}
|
|
}
|
|
|
|
static td_void sample_vgs_get_yuv_buffer_cfg(const sample_vb_base_info *vb_base_info, ot_vb_calc_cfg *vb_cal_config)
|
|
{
|
|
ot_pic_buf_attr buf_attr;
|
|
buf_attr.width = vb_base_info->width;
|
|
buf_attr.height = vb_base_info->height;
|
|
buf_attr.pixel_format = vb_base_info->pixel_format;
|
|
buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
|
|
buf_attr.compress_mode = vb_base_info->compress_mode;
|
|
buf_attr.align = vb_base_info->align;
|
|
ot_common_get_pic_buf_cfg(&buf_attr, vb_cal_config);
|
|
return;
|
|
}
|
|
|
|
static td_void sample_vgs_set_frame_info(const ot_vb_calc_cfg *vb_cal_config, const sample_vb_base_info *vb_info,
|
|
const sample_vgs_vb_info *vgs_vb_info, td_phys_addr_t phys_addr, ot_video_frame_info *frame_info)
|
|
{
|
|
frame_info->mod_id = OT_ID_VGS;
|
|
frame_info->pool_id = ss_mpi_vb_handle_to_pool_id(vgs_vb_info->vb_handle);
|
|
|
|
frame_info->video_frame.width = vb_info->width;
|
|
frame_info->video_frame.height = vb_info->height;
|
|
frame_info->video_frame.field = OT_VIDEO_FIELD_FRAME;
|
|
frame_info->video_frame.pixel_format = vb_info->pixel_format;
|
|
frame_info->video_frame.video_format = vb_info->video_format;
|
|
frame_info->video_frame.compress_mode = vb_info->compress_mode;
|
|
frame_info->video_frame.dynamic_range = OT_DYNAMIC_RANGE_SDR8;
|
|
frame_info->video_frame.color_gamut = OT_COLOR_GAMUT_BT601;
|
|
|
|
frame_info->video_frame.header_stride[0] = vb_cal_config->head_stride;
|
|
frame_info->video_frame.header_stride[1] = vb_cal_config->head_stride;
|
|
frame_info->video_frame.header_phys_addr[0] = phys_addr;
|
|
frame_info->video_frame.header_phys_addr[1] = frame_info->video_frame.header_phys_addr[0] +
|
|
vb_cal_config->head_y_size;
|
|
frame_info->video_frame.header_virt_addr[0] = vgs_vb_info->virt_addr;
|
|
frame_info->video_frame.header_virt_addr[1] = frame_info->video_frame.header_virt_addr[0] +
|
|
vb_cal_config->head_y_size;
|
|
|
|
frame_info->video_frame.stride[0] = vb_cal_config->main_stride;
|
|
frame_info->video_frame.stride[1] = vb_cal_config->main_stride;
|
|
frame_info->video_frame.phys_addr[0] = frame_info->video_frame.header_phys_addr[0] + vb_cal_config->head_size;
|
|
frame_info->video_frame.phys_addr[1] = frame_info->video_frame.phys_addr[0] + vb_cal_config->main_y_size;
|
|
frame_info->video_frame.virt_addr[0] = frame_info->video_frame.header_virt_addr[0] + vb_cal_config->head_size;
|
|
frame_info->video_frame.virt_addr[1] = frame_info->video_frame.virt_addr[0] + vb_cal_config->main_y_size;
|
|
|
|
return;
|
|
}
|
|
|
|
static td_s32 sample_vgs_get_frame_vb(const sample_vb_base_info *vb_info, const ot_vb_calc_cfg *vb_cal_config,
|
|
ot_video_frame_info *frame_info, sample_vgs_vb_info *vgs_vb_info)
|
|
{
|
|
td_phys_addr_t phys_addr;
|
|
|
|
vgs_vb_info->vb_handle = ss_mpi_vb_get_blk(OT_VB_INVALID_POOL_ID, vb_cal_config->vb_size, TD_NULL);
|
|
if (vgs_vb_info->vb_handle == OT_VB_INVALID_HANDLE) {
|
|
sample_print("mpi_vb_get_block failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
vgs_vb_info->vb_used = TD_TRUE;
|
|
|
|
phys_addr = ss_mpi_vb_handle_to_phys_addr(vgs_vb_info->vb_handle);
|
|
if (phys_addr == 0) {
|
|
sample_print("mpi_vb_handle2_phys_addr failed!\n");
|
|
ss_mpi_vb_release_blk(vgs_vb_info->vb_handle);
|
|
vgs_vb_info->vb_used = TD_FALSE;
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
vgs_vb_info->virt_addr = (td_u8*)ss_mpi_sys_mmap(phys_addr, vb_cal_config->vb_size);
|
|
if (vgs_vb_info->virt_addr == TD_NULL) {
|
|
sample_print("mpi_sys_mmap failed!\n");
|
|
ss_mpi_vb_release_blk(vgs_vb_info->vb_handle);
|
|
vgs_vb_info->vb_used = TD_FALSE;
|
|
return TD_FAILURE;
|
|
}
|
|
vgs_vb_info->vb_size = vb_cal_config->vb_size;
|
|
|
|
sample_vgs_set_frame_info(vb_cal_config, vb_info, vgs_vb_info, phys_addr, frame_info);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_convert_chroma_planar_to_sp42x(FILE *file, td_u8 *chroma_data,
|
|
td_u32 luma_stride, td_u32 chroma_width, td_u32 chroma_height)
|
|
{
|
|
td_u32 chroma_stride = luma_stride >> 1;
|
|
td_u8 *planar_buffer = TD_NULL;
|
|
td_u8 *dst = TD_NULL;
|
|
td_u32 row, list;
|
|
|
|
planar_buffer = (td_u8*)malloc(chroma_stride);
|
|
if (planar_buffer == TD_NULL) {
|
|
sample_print("vgs malloc failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (memset_s(planar_buffer, chroma_stride, 0, chroma_stride) != EOK) {
|
|
sample_print("vgs memset_s failed!\n");
|
|
free(planar_buffer);
|
|
planar_buffer = TD_NULL;
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
/* U */
|
|
dst = chroma_data + 1;
|
|
for (row = 0; row < chroma_height; ++row) {
|
|
fread(planar_buffer, chroma_width, 1, file); /* sp420 U-component data starts 1/2 way from the beginning */
|
|
for (list = 0; list < chroma_stride; ++list) {
|
|
*dst = *(planar_buffer + list);
|
|
dst += 2; /* traverse 2 steps away to the next U-component data */
|
|
}
|
|
dst = chroma_data + 1;
|
|
dst += (row + 1) * luma_stride;
|
|
}
|
|
|
|
/* V */
|
|
dst = chroma_data;
|
|
for (row = 0; row < chroma_height; ++row) {
|
|
fread(planar_buffer, chroma_width, 1, file); /* sp420 V-component data starts 1/2 way from the beginning */
|
|
for (list = 0; list < chroma_stride; ++list) {
|
|
*dst = *(planar_buffer + list);
|
|
dst += 2; /* traverse 2 steps away to the next V-component data */
|
|
}
|
|
dst = chroma_data;
|
|
dst += (row + 1) * luma_stride;
|
|
}
|
|
|
|
free(planar_buffer);
|
|
planar_buffer = TD_NULL;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_read_file_to_sp42_x(FILE *file, ot_video_frame *frame)
|
|
{
|
|
td_u8 *luma = (td_u8*)(td_uintptr_t)frame->virt_addr[0];
|
|
td_u8 *chroma = (td_u8*)(td_uintptr_t)frame->virt_addr[1];
|
|
td_u32 luma_width = frame->width;
|
|
td_u32 chroma_width = luma_width >> 1;
|
|
td_u32 luma_height = frame->height;
|
|
td_u32 chroma_height = luma_height;
|
|
td_u32 luma_stride = frame->stride[0];
|
|
|
|
td_u8 *dst = TD_NULL;
|
|
td_u32 row;
|
|
|
|
if (frame->video_format == OT_VIDEO_FORMAT_LINEAR) {
|
|
/* Y */
|
|
dst = luma;
|
|
for (row = 0; row < luma_height; ++row) {
|
|
fread(dst, luma_width, 1, file);
|
|
dst += luma_stride;
|
|
}
|
|
|
|
if (OT_PIXEL_FORMAT_YUV_400 == frame->pixel_format) {
|
|
return TD_SUCCESS;
|
|
} else if (OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420 == frame->pixel_format) {
|
|
chroma_height = chroma_height >> 1;
|
|
}
|
|
if (sample_vgs_convert_chroma_planar_to_sp42x(
|
|
file, chroma, luma_stride, chroma_width, chroma_height) != TD_SUCCESS) {
|
|
return TD_FAILURE;
|
|
}
|
|
} else {
|
|
fread(luma, luma_stride * luma_height * 3 / 2, 1, file); /* Tile 64x16 size = stride x height * 3 / 2 */
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_get_frame_from_file(sample_vgs_func_param *param, ot_vb_calc_cfg *in_img_vb_cal_config,
|
|
ot_video_frame_info *frame_info)
|
|
{
|
|
td_s32 ret = TD_FAILURE;
|
|
td_char sz_in_file_name[FILE_NAME_LENGTH] = SAMPLE_VGS_READ_PATH;
|
|
FILE *file_read = TD_NULL;
|
|
|
|
if (param->in_img_vb_info->video_format == OT_VIDEO_FORMAT_TILE_64x16) {
|
|
if (snprintf_s(sz_in_file_name, FILE_NAME_LENGTH, FILE_NAME_LENGTH - 1,
|
|
"%s", SAMPLE_VGS_READ_TILE_PATH) == -1) {
|
|
sample_print("set input file name fail\n");
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
file_read = fopen(sz_in_file_name, "rb");
|
|
if (file_read == TD_NULL) {
|
|
sample_print("can't open file %s\n", sz_in_file_name);
|
|
goto EXIT;
|
|
}
|
|
|
|
ret = sample_vgs_get_frame_vb(param->in_img_vb_info, in_img_vb_cal_config, frame_info, &g_in_img_vb_info);
|
|
if (ret != TD_SUCCESS) {
|
|
goto EXIT1;
|
|
}
|
|
|
|
ret = sample_vgs_read_file_to_sp42_x(file_read, &frame_info->video_frame);
|
|
if (ret != TD_SUCCESS) {
|
|
goto EXIT2;
|
|
} else {
|
|
goto EXIT1;
|
|
}
|
|
|
|
EXIT2:
|
|
ss_mpi_sys_munmap(frame_info->video_frame.header_virt_addr[0], in_img_vb_cal_config->vb_size);
|
|
ss_mpi_vb_release_blk(g_in_img_vb_info.vb_handle);
|
|
g_in_img_vb_info.vb_used = TD_FALSE;
|
|
EXIT1:
|
|
fclose(file_read);
|
|
EXIT:
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_vgs_convert_chroma_sp42x_to_planar(FILE *file, td_u8 *chroma_data,
|
|
td_u32 luma_stride, td_u32 chroma_width, td_u32 chroma_height)
|
|
{
|
|
td_u8 *planar_buffer = TD_NULL;
|
|
td_u8 *dst = TD_NULL;
|
|
td_u32 row, list;
|
|
|
|
planar_buffer = (td_u8*)malloc(chroma_width);
|
|
if (planar_buffer == TD_NULL) {
|
|
sample_print("vgs malloc failed!.\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (memset_s(planar_buffer, chroma_width, 0, chroma_width) != EOK) {
|
|
sample_print("vgs memset_s failed!\n");
|
|
free(planar_buffer);
|
|
planar_buffer = TD_NULL;
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
/* U */
|
|
for (row = 0; row < chroma_height; ++row) {
|
|
dst = chroma_data + row * luma_stride + 1;
|
|
for (list = 0; list < chroma_width; ++list) {
|
|
*(planar_buffer + list) = *dst;
|
|
dst += 2; /* traverse 2 steps away to the next U-component data */
|
|
}
|
|
fwrite(planar_buffer, 1, chroma_width, file);
|
|
}
|
|
|
|
/* V */
|
|
for (row = 0; row < chroma_height; ++row) {
|
|
dst = chroma_data + row * luma_stride;
|
|
for (list = 0; list < chroma_width; ++list) {
|
|
*(planar_buffer + list) = *dst;
|
|
dst += 2; /* traverse 2 steps away to the next V-component data */
|
|
}
|
|
fwrite(planar_buffer, 1, chroma_width, file);
|
|
}
|
|
|
|
free(planar_buffer);
|
|
planar_buffer = TD_NULL;
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_save_sp42_x_to_planar(FILE *file, ot_video_frame *frame)
|
|
{
|
|
td_u32 luma_width = frame->width;
|
|
td_u32 chroma_width = luma_width >> 1;
|
|
td_u32 luma_height = frame->height;
|
|
td_u32 chroma_height = luma_height;
|
|
td_u32 luma_stride = frame->stride[0];
|
|
td_u8 *luma = (td_u8*)(td_uintptr_t)frame->virt_addr[0];
|
|
td_u8 *chroma = (td_u8*)(td_uintptr_t)frame->virt_addr[1];
|
|
|
|
td_u8 *dst = TD_NULL;
|
|
td_u32 row;
|
|
|
|
/* Y */
|
|
dst = luma;
|
|
for (row = 0; row < luma_height; ++row) {
|
|
fwrite(dst, 1, luma_width, file);
|
|
dst += luma_stride;
|
|
}
|
|
|
|
if (OT_PIXEL_FORMAT_YUV_400 == frame->pixel_format) {
|
|
return TD_SUCCESS;
|
|
} else if (OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420 == frame->pixel_format) {
|
|
chroma_height = chroma_height >> 1;
|
|
}
|
|
|
|
if (sample_vgs_convert_chroma_sp42x_to_planar(
|
|
file, chroma, luma_stride, chroma_width, chroma_height) != TD_SUCCESS) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_set_color_format(ot_pixel_format pixel_format, osd_surface *surface)
|
|
{
|
|
if (OT_PIXEL_FORMAT_ARGB_1555 == pixel_format) {
|
|
surface->color_format = OSD_COLOR_FORMAT_RGB1555;
|
|
} else if (OT_PIXEL_FORMAT_ARGB_4444 == pixel_format) {
|
|
surface->color_format = OSD_COLOR_FORMAT_RGB4444;
|
|
} else if (OT_PIXEL_FORMAT_ARGB_8888 == pixel_format) {
|
|
surface->color_format = OSD_COLOR_FORMAT_RGB8888;
|
|
} else {
|
|
sample_print("pixel format is not support!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_load_bmp(const td_char *sz_file_name, ot_bmp *bitmap,
|
|
const sample_vgs_osd_load_bmp_info *load_info)
|
|
{
|
|
osd_surface surface;
|
|
osd_bit_map_file_header bmp_file_header;
|
|
osd_bit_map_info bmp_info;
|
|
td_u32 i, j;
|
|
td_u16 *temp = TD_NULL;
|
|
canvas_size_info canvas_size;
|
|
|
|
canvas_size.height = load_info->osd_size.height;
|
|
canvas_size.width = load_info->osd_size.width;
|
|
canvas_size.stride = load_info->stride;
|
|
|
|
if (get_bmp_info(sz_file_name, &bmp_file_header, &bmp_info) < 0) {
|
|
sample_print("get_bmp_info err!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (bitmap->data == TD_NULL) {
|
|
sample_print("bitmap's data is null!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (sample_vgs_set_color_format(load_info->img_pixel_format, &surface) < 0) {
|
|
sample_print("pixel format is not support!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (create_surface_by_canvas(sz_file_name, &surface, (td_u8*)bitmap->data, &canvas_size)) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
bitmap->width = surface.width;
|
|
bitmap->height = surface.height;
|
|
bitmap->pixel_format = load_info->img_pixel_format;
|
|
|
|
temp = (td_u16*)bitmap->data;
|
|
|
|
if (load_info->fill_en != TD_TRUE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
for (i = 0; i < bitmap->height; ++i) {
|
|
for (j = 0; j < bitmap->width; ++j) {
|
|
if (load_info->fill_color == *temp) {
|
|
*temp &= 0x7FFF;
|
|
}
|
|
temp++;
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_prepare_osd_info(ot_vgs_osd *vgs_add_osd, ot_rgn_handle *rgn_handle)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ot_rgn_attr rgn_attr;
|
|
ot_rgn_canvas_info rgn_canvas_info;
|
|
ot_bmp bitmap;
|
|
sample_vgs_osd_load_bmp_info load_info = {0};
|
|
|
|
rgn_attr.type = OT_RGN_OVERLAYEX;
|
|
rgn_attr.attr.overlayex.pixel_format = vgs_add_osd->pixel_format;
|
|
rgn_attr.attr.overlayex.bg_color = vgs_add_osd->bg_color;
|
|
rgn_attr.attr.overlayex.size.width = vgs_add_osd->rect.width;
|
|
rgn_attr.attr.overlayex.size.height = vgs_add_osd->rect.height;
|
|
rgn_attr.attr.overlayex.canvas_num = 2; /* 2 canvas */
|
|
ret = ss_mpi_rgn_create(*rgn_handle, &rgn_attr);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_rgn_create failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = ss_mpi_rgn_get_canvas_info(*rgn_handle, &rgn_canvas_info);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_rgn_get_canvas_info failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
bitmap.data = rgn_canvas_info.virt_addr;
|
|
load_info.fill_en = TD_FALSE;
|
|
load_info.fill_color = 0x0;
|
|
load_info.osd_size.width = vgs_add_osd->rect.width;
|
|
load_info.osd_size.height = vgs_add_osd->rect.height;
|
|
load_info.stride = rgn_canvas_info.stride;
|
|
load_info.img_pixel_format = vgs_add_osd->pixel_format;
|
|
ret = sample_vgs_load_bmp(SAMPLE_VGS_BITMAP_PATH, &bitmap, &load_info);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sample_vgs_load_bmp failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = ss_mpi_rgn_update_canvas(*rgn_handle);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_rgn_update_canvas failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
vgs_add_osd->phys_addr = rgn_canvas_info.phys_addr;
|
|
vgs_add_osd->stride = rgn_canvas_info.stride;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_void sample_vgs_get_clut_data(td_u32 i, td_u32 j, td_u8 clut_value, td_u8 *clut_data)
|
|
{
|
|
if ((i > 50 && i < 150) && (j > 50 && j < 150)) { /* 50-150 set alpha 255 */
|
|
*clut_data = 0xFF; /* alpha 255 */
|
|
} else {
|
|
*clut_data = clut_value;
|
|
}
|
|
return;
|
|
}
|
|
|
|
static td_s32 sample_vgs_get_clut2_data(const ot_rgn_canvas_info rgn_canvas_info)
|
|
{
|
|
td_u8 *clut_data = TD_NULL;
|
|
td_u8 clut_value;
|
|
td_u32 i, j;
|
|
|
|
if ((rgn_canvas_info.size.height - 1) * rgn_canvas_info.stride + (rgn_canvas_info.size.width - 1) / 4 > /* para 4 */
|
|
rgn_canvas_info.size.height * rgn_canvas_info.stride) {
|
|
printf("osd info exceeds canvas buffer size!");
|
|
return OT_INVALID_VALUE;
|
|
}
|
|
|
|
for (i = 0; i < rgn_canvas_info.size.height; i++) {
|
|
for (j = 0; j < rgn_canvas_info.size.width; j++) {
|
|
clut_value = ((j / 64) << 6) + ((j / 64) << 4) + ((j / 64) << 2) + j / 64; /* 2,4,6,64 are params */
|
|
clut_data = rgn_canvas_info.virt_addr + i * rgn_canvas_info.stride + j / 4; /* 4: CLut2 2Bit */
|
|
sample_vgs_get_clut_data(i, j, clut_value, clut_data);
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_get_clut4_data(const ot_rgn_canvas_info rgn_canvas_info)
|
|
{
|
|
td_u8 *clut_data = TD_NULL;
|
|
td_u8 clut_value;
|
|
td_u32 i, j;
|
|
|
|
if ((rgn_canvas_info.size.height - 1) * rgn_canvas_info.stride + (rgn_canvas_info.size.width - 1) / 2 > /* para 2 */
|
|
rgn_canvas_info.size.height * rgn_canvas_info.stride) {
|
|
printf("osd info exceeds canvas buffer size!");
|
|
return OT_INVALID_VALUE;
|
|
}
|
|
|
|
for (i = 0; i < rgn_canvas_info.size.height; i++) {
|
|
for (j = 0; j < rgn_canvas_info.size.width; j++) {
|
|
clut_value = ((j / 16) << 4) + j / 16; /* 4,16 are parameters */
|
|
clut_data = rgn_canvas_info.virt_addr + i * rgn_canvas_info.stride + j / 2; /* 2: CLut4 4Bit */
|
|
sample_vgs_get_clut_data(i, j, clut_value, clut_data);
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_set_osd_info(const ot_rgn_canvas_info rgn_canvas_info, ot_vgs_osd *vgs_add_osd)
|
|
{
|
|
if (vgs_add_osd->pixel_format == OT_PIXEL_FORMAT_ARGB_CLUT2) {
|
|
vgs_add_osd->clut[0] = 0xFF0000FF;
|
|
vgs_add_osd->clut[1] = 0x8000FF00;
|
|
vgs_add_osd->clut[2] = 0x80FF0000; /* OSD clut 2 */
|
|
vgs_add_osd->clut[3] = 0x00FFFFFF; /* OSD clut 3 */
|
|
|
|
return sample_vgs_get_clut2_data(rgn_canvas_info);
|
|
} else { /* color data transformation parameters */
|
|
vgs_add_osd->clut[0] = 0xFFFF0000;
|
|
vgs_add_osd->clut[1] = 0xFF00FF00;
|
|
vgs_add_osd->clut[2] = 0xFF0000FF; /* 2 OSD clut data index */
|
|
vgs_add_osd->clut[3] = 0xFFFFFF00; /* 3 OSD clut data index */
|
|
vgs_add_osd->clut[4] = 0xFFFF00FF; /* 4 OSD clut data index */
|
|
vgs_add_osd->clut[5] = 0xFF00FFFF; /* 5 OSD clut data index */
|
|
vgs_add_osd->clut[6] = 0x7FFF0000; /* 6 OSD clut data index */
|
|
vgs_add_osd->clut[7] = 0x7F00FF00; /* 7 OSD clut data index */
|
|
vgs_add_osd->clut[8] = 0x7F0000FF; /* 8 OSD clut data index */
|
|
vgs_add_osd->clut[9] = 0x7F7F7F00; /* 9 OSD clut data index */
|
|
vgs_add_osd->clut[10] = 0x7F7F007F; /* 10 OSD clut data index */
|
|
vgs_add_osd->clut[11] = 0x7F007F7F; /* 11 OSD clut data index */
|
|
vgs_add_osd->clut[12] = 0x7FFFFFFF; /* 12 OSD clut data index */
|
|
vgs_add_osd->clut[13] = 0x7F7F7F7F; /* 13 OSD clut data index */
|
|
vgs_add_osd->clut[14] = 0xFFFFFFFF; /* 14 OSD clut data index */
|
|
vgs_add_osd->clut[15] = 0x00FFFFFF; /* 15 OSD clut data index */
|
|
|
|
return sample_vgs_get_clut4_data(rgn_canvas_info);
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_vgs_prepare_osd_clut_info(ot_vgs_osd *vgs_add_osd, ot_rgn_handle *rgn_handle)
|
|
{
|
|
td_s32 ret;
|
|
ot_rgn_attr rgn_attr;
|
|
ot_rgn_canvas_info rgn_canvas_info;
|
|
ot_size size;
|
|
|
|
size.width = vgs_add_osd->rect.width;
|
|
size.height = vgs_add_osd->rect.height;
|
|
|
|
rgn_attr.type = OT_RGN_OVERLAYEX;
|
|
rgn_attr.attr.overlayex.pixel_format = vgs_add_osd->pixel_format;
|
|
rgn_attr.attr.overlayex.bg_color = vgs_add_osd->bg_color;
|
|
rgn_attr.attr.overlayex.size.width = size.width;
|
|
rgn_attr.attr.overlayex.size.height = size.height;
|
|
rgn_attr.attr.overlayex.canvas_num = 1;
|
|
|
|
ret = ss_mpi_rgn_create(*rgn_handle, &rgn_attr);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_rgn_create failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = ss_mpi_rgn_get_canvas_info(*rgn_handle, &rgn_canvas_info);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_rgn_get_canvas_info failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_vgs_set_osd_info(rgn_canvas_info, vgs_add_osd);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_rgn_set_osd_info failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = ss_mpi_rgn_update_canvas(*rgn_handle);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_rgn_update_canvas failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
vgs_add_osd->phys_addr = rgn_canvas_info.phys_addr;
|
|
vgs_add_osd->stride = rgn_canvas_info.stride;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_vgs_add_osd_task(const sample_vgs_func_param *param, ot_vgs_handle h_handle,
|
|
ot_vgs_task_attr *vgs_task_attr)
|
|
{
|
|
td_s32 ret;
|
|
ret = sample_vgs_prepare_osd_info(¶m->vgs_add_osd[SAMPLE_VGS_OSD_NORM],
|
|
param->rgn_handle[SAMPLE_VGS_OSD_NORM]);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sample_vgs_prepare_osd_info failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_vgs_prepare_osd_clut_info(¶m->vgs_add_osd[SAMPLE_VGS_OSD_CLUT2],
|
|
param->rgn_handle[SAMPLE_VGS_OSD_CLUT2]);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sample_vgs_prepare_osd_clut2 failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = sample_vgs_prepare_osd_clut_info(¶m->vgs_add_osd[SAMPLE_VGS_OSD_CLUT4],
|
|
param->rgn_handle[SAMPLE_VGS_OSD_CLUT4]);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sample_vgs_prepare_osd_clut4 failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = ss_mpi_vgs_add_osd_task(h_handle, vgs_task_attr, param->vgs_add_osd, 3); /* add 3 OSD task */
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_vgs_add_osd_task failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_add_task(const sample_vgs_func_param *param, ot_vgs_handle h_handle,
|
|
ot_vgs_task_attr *vgs_task_attr)
|
|
{
|
|
td_s32 ret;
|
|
if (param->scale) {
|
|
ret = ss_mpi_vgs_add_scale_task(h_handle, vgs_task_attr, *param->vgs_scl_coef_mode);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_vgs_add_scale_task failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (param->cover) {
|
|
ret = ss_mpi_vgs_add_cover_task(h_handle, vgs_task_attr, param->vgs_add_cover, 1);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_vgs_add_cover_task failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (param->osd) {
|
|
ret = sample_vgs_add_osd_task(param, h_handle, vgs_task_attr);
|
|
if (ret != TD_SUCCESS) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (param->draw_line) {
|
|
ret = ss_mpi_vgs_add_draw_line_task(h_handle, vgs_task_attr, param->vgs_draw_line, 1);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_vgs_add_draw_line_task failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (param->rotate) {
|
|
ret = ss_mpi_vgs_add_rotation_task(h_handle, vgs_task_attr, *param->rotation_angle);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_vgs_add_rotation_task failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (param->luma) {
|
|
ret = ss_mpi_vgs_add_luma_task(h_handle, vgs_task_attr, param->luma_rect, param->luma_num, param->luma_data);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_vgs_add_draw_line_task failed, ret:0x%x", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_get_in_out_frame(sample_vgs_func_param *param,
|
|
ot_vgs_task_attr *vgs_task_attr, td_bool same_vb)
|
|
{
|
|
ot_vb_calc_cfg in_img_vb_cal_config = {0};
|
|
ot_vb_calc_cfg out_img_vb_cal_config = {0};
|
|
td_s32 ret;
|
|
|
|
sample_vgs_get_yuv_buffer_cfg(param->in_img_vb_info, &in_img_vb_cal_config);
|
|
ret = sample_vgs_get_frame_from_file(param, &in_img_vb_cal_config, &vgs_task_attr->img_in);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sample_vgs_get_frame_from_file failed, ret:0x%x\n", ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (same_vb) {
|
|
if (memcpy_s(&vgs_task_attr->img_out, sizeof(ot_video_frame_info),
|
|
&vgs_task_attr->img_in, sizeof(ot_video_frame_info)) != EOK) {
|
|
sample_print("memcpy_s failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
} else {
|
|
sample_vgs_get_yuv_buffer_cfg(param->out_img_vb_info, &out_img_vb_cal_config);
|
|
ret = sample_vgs_get_frame_vb(param->out_img_vb_info, &out_img_vb_cal_config,
|
|
&vgs_task_attr->img_out, &g_out_img_vb_info);
|
|
if (ret != TD_SUCCESS) {
|
|
return ret;
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 sample_vgs_init_sys_and_vb(const sample_vgs_func_param *param,
|
|
td_bool same_vb, FILE **file_write)
|
|
{
|
|
ot_vb_calc_cfg in_img_vb_cal_config = {0};
|
|
ot_vb_calc_cfg out_img_vb_cal_config = {0};
|
|
td_char sz_out_file_name[FILE_NAME_LENGTH];
|
|
ot_vb_cfg vb_conf = {0};
|
|
td_s32 ret;
|
|
|
|
vb_conf.max_pool_cnt = same_vb ? 1 : 2; /* there are 2 pools in 1 vb */
|
|
sample_vgs_get_yuv_buffer_cfg(param->in_img_vb_info, &in_img_vb_cal_config);
|
|
vb_conf.common_pool[0].blk_size = in_img_vb_cal_config.vb_size;
|
|
vb_conf.common_pool[0].blk_cnt = 2; /* there are 2 blks in 1 pool */
|
|
|
|
if (!same_vb) {
|
|
sample_vgs_get_yuv_buffer_cfg(param->out_img_vb_info, &out_img_vb_cal_config);
|
|
vb_conf.common_pool[1].blk_size = out_img_vb_cal_config.vb_size;
|
|
vb_conf.common_pool[1].blk_cnt = 2; /* there are 2 blks in 1 pool */
|
|
}
|
|
|
|
ret = sample_comm_sys_init(&vb_conf);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sample_comm_sys_init failed, ret:0x%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
if (same_vb) {
|
|
if (snprintf_s(sz_out_file_name, FILE_NAME_LENGTH, FILE_NAME_LENGTH - 1,
|
|
"%s/vgs_sample%d_%dx%d_p420.yuv", SAMPLE_VGS_SAVE_PATH,
|
|
param->sample_num, param->in_img_vb_info->width, param->in_img_vb_info->height) == -1) {
|
|
sample_print("set output file name fail!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
} else {
|
|
if (snprintf_s(sz_out_file_name, FILE_NAME_LENGTH, FILE_NAME_LENGTH - 1,
|
|
"%s/vgs_sample%d_%dx%d_p420.yuv", SAMPLE_VGS_SAVE_PATH,
|
|
param->sample_num, param->out_img_vb_info->width, param->out_img_vb_info->height) == -1) {
|
|
sample_print("set output file name fail!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
*file_write = fopen(sz_out_file_name, "w+");
|
|
if (*file_write == TD_NULL) {
|
|
sample_print("can't open file %s\n", sz_out_file_name);
|
|
return TD_FAILURE;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_void sample_vgs_common_function_exit_release(const sample_vgs_func_param *param,
|
|
ot_vgs_task_attr *vgs_task_attr, td_bool same_vb, FILE **file_write)
|
|
{
|
|
td_u32 i;
|
|
ot_vb_calc_cfg in_img_vb_cal_config = {0};
|
|
ot_vb_calc_cfg out_img_vb_cal_config = {0};
|
|
if (!same_vb && g_out_img_vb_info.vb_used == TD_TRUE) {
|
|
sample_vgs_get_yuv_buffer_cfg(param->out_img_vb_info, &out_img_vb_cal_config);
|
|
ss_mpi_sys_munmap(vgs_task_attr->img_out.video_frame.header_virt_addr[0], out_img_vb_cal_config.vb_size);
|
|
ss_mpi_vb_release_blk(g_out_img_vb_info.vb_handle);
|
|
g_out_img_vb_info.vb_used = TD_FALSE;
|
|
}
|
|
if (*file_write != TD_NULL) {
|
|
fclose(*file_write);
|
|
*file_write = TD_NULL;
|
|
}
|
|
if (g_in_img_vb_info.vb_used == TD_TRUE) {
|
|
sample_vgs_get_yuv_buffer_cfg(param->in_img_vb_info, &in_img_vb_cal_config);
|
|
ss_mpi_sys_munmap(vgs_task_attr->img_in.video_frame.header_virt_addr[0], in_img_vb_cal_config.vb_size);
|
|
ss_mpi_vb_release_blk(g_in_img_vb_info.vb_handle);
|
|
g_in_img_vb_info.vb_used = TD_FALSE;
|
|
}
|
|
for (i = 0; i < SAMPLE_VGS_OSD_BUTT; i++) {
|
|
if (param->rgn_handle[i] != TD_NULL) {
|
|
ss_mpi_rgn_destroy(*param->rgn_handle[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_vgs_common_function(sample_vgs_func_param *param)
|
|
{
|
|
td_s32 ret;
|
|
td_bool same_vb = TD_FALSE;
|
|
ot_vgs_handle h_handle = -1;
|
|
ot_vgs_task_attr vgs_task_attr = {0};
|
|
FILE *file_write = TD_NULL;
|
|
|
|
if (param == TD_NULL || param->in_img_vb_info == TD_NULL) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (param->in_img_vb_info != TD_NULL && param->out_img_vb_info == TD_NULL) {
|
|
same_vb = TD_TRUE;
|
|
}
|
|
|
|
/* step1: init SYS and common VB */
|
|
ret = sample_vgs_init_sys_and_vb(param, same_vb, &file_write);
|
|
if (ret != TD_SUCCESS) {
|
|
goto exit_and_release;
|
|
}
|
|
|
|
/* step2: get frame */
|
|
ret = sample_vgs_get_in_out_frame(param, &vgs_task_attr, same_vb);
|
|
if (ret != TD_SUCCESS) {
|
|
goto exit_and_release;
|
|
}
|
|
|
|
/* step3: create VGS job */
|
|
ret = ss_mpi_vgs_begin_job(&h_handle);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("mpi_vgs_begin_job failed, ret:0x%x", ret);
|
|
goto exit_and_release;
|
|
}
|
|
|
|
/* step4: add VGS task */
|
|
ret = sample_vgs_add_task(param, h_handle, &vgs_task_attr);
|
|
if (ret != TD_SUCCESS) {
|
|
ss_mpi_vgs_cancel_job(h_handle);
|
|
goto exit_and_release;
|
|
}
|
|
|
|
/* step5: start VGS work */
|
|
ret = ss_mpi_vgs_end_job(h_handle);
|
|
if (ret != TD_SUCCESS) {
|
|
ss_mpi_vgs_cancel_job(h_handle);
|
|
sample_print("mpi_vgs_end_job failed, ret:0x%x", ret);
|
|
goto exit_and_release;
|
|
}
|
|
|
|
/* step6: save the frame to file */
|
|
ret = sample_vgs_save_sp42_x_to_planar(file_write, &vgs_task_attr.img_out.video_frame);
|
|
if (ret != TD_SUCCESS) {
|
|
goto exit_and_release;
|
|
}
|
|
fflush(file_write);
|
|
|
|
/* step7: exit */
|
|
exit_and_release:
|
|
sample_vgs_common_function_exit_release(param, &vgs_task_attr, same_vb, &file_write);
|
|
sample_comm_sys_exit();
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_vgs_scale(td_void)
|
|
{
|
|
td_s32 ret;
|
|
sample_vgs_func_param vgs_func_param = {0};
|
|
sample_vb_base_info in_img_vb_info;
|
|
sample_vb_base_info out_img_vb_info;
|
|
ot_vgs_scale_coef_mode vgs_scl_coef_mode = OT_VGS_SCALE_COEF_NORM;
|
|
|
|
in_img_vb_info.video_format = OT_VIDEO_FORMAT_TILE_64x16;
|
|
in_img_vb_info.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
|
in_img_vb_info.width = 1280; /* 1280:720P width */
|
|
in_img_vb_info.height = 720; /* 720:720P height */
|
|
in_img_vb_info.align = 0;
|
|
in_img_vb_info.compress_mode = OT_COMPRESS_MODE_NONE;
|
|
|
|
if (memcpy_s(&out_img_vb_info, sizeof(sample_vb_base_info), &in_img_vb_info, sizeof(sample_vb_base_info)) != EOK) {
|
|
sample_print("memcpy_s failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
out_img_vb_info.video_format = OT_VIDEO_FORMAT_LINEAR;
|
|
out_img_vb_info.width = 720; /* 720:D1 width */
|
|
out_img_vb_info.height = 576; /* 576:D1 height */
|
|
|
|
vgs_func_param.scale = TD_TRUE;
|
|
vgs_func_param.vgs_scl_coef_mode = &vgs_scl_coef_mode;
|
|
vgs_func_param.in_img_vb_info = &in_img_vb_info;
|
|
vgs_func_param.out_img_vb_info = &out_img_vb_info;
|
|
vgs_func_param.sample_num = 0;
|
|
|
|
ret = sample_vgs_common_function(&vgs_func_param);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("VGS sample %d failed, ret:0x%x", vgs_func_param.sample_num, ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_void sample_vgs_case2_set_osd_stat(ot_vgs_osd *vgs_add_osd, td_u32 max_osd_cnt,
|
|
ot_rgn_handle *rgn_handle, td_u32 handle_cnt)
|
|
{
|
|
td_u32 i;
|
|
|
|
for (i = 0; i < max_osd_cnt && i < handle_cnt; i++) {
|
|
vgs_add_osd[i].rect.x = 500 + i * 300; /* cover x-component starts from 500 at a step of 300 */
|
|
vgs_add_osd[i].rect.y = 100 + i * 200; /* cover y-component starts from 100 at a step of 200 */
|
|
vgs_add_osd[i].rect.width = 256; /* cover's size is 256x200 */
|
|
vgs_add_osd[i].rect.height = 200; /* cover's size is 256x200 */
|
|
vgs_add_osd[i].bg_color = 0x0;
|
|
vgs_add_osd[i].pixel_format = OT_PIXEL_FORMAT_ARGB_CLUT2;
|
|
vgs_add_osd[i].phys_addr = 0;
|
|
vgs_add_osd[i].stride = 0;
|
|
vgs_add_osd[i].bg_alpha = 255; /* alpha 255 */
|
|
vgs_add_osd[i].fg_alpha = 128; /* alpha 128 */
|
|
rgn_handle[i] = i;
|
|
switch (i) {
|
|
case SAMPLE_VGS_OSD_NORM:
|
|
vgs_add_osd[i].rect.width = 180; /* cover's size is 180x144 */
|
|
vgs_add_osd[i].rect.height = 144; /* cover's size is 180x144 */
|
|
vgs_add_osd[i].bg_color = 0xFF0000;
|
|
vgs_add_osd[i].pixel_format = OT_PIXEL_FORMAT_ARGB_8888;
|
|
break;
|
|
case SAMPLE_VGS_OSD_CLUT2:
|
|
vgs_add_osd[i].rect.width = 256; /* cover's size is 256x200 */
|
|
vgs_add_osd[i].rect.height = 200; /* cover's size is 256x200 */
|
|
vgs_add_osd[i].bg_color = 0x0;
|
|
vgs_add_osd[i].pixel_format = OT_PIXEL_FORMAT_ARGB_CLUT2;
|
|
break;
|
|
case SAMPLE_VGS_OSD_CLUT4:
|
|
vgs_add_osd[i].rect.width = 256; /* cover's size is 256x200 */
|
|
vgs_add_osd[i].rect.height = 200; /* cover's size is 256x200 */
|
|
vgs_add_osd[i].bg_color = 0x0;
|
|
vgs_add_osd[i].pixel_format = OT_PIXEL_FORMAT_ARGB_CLUT4;
|
|
break;
|
|
default:
|
|
printf("OSD type error!");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_vgs_cover_osd(td_void)
|
|
{
|
|
td_s32 ret;
|
|
ot_rgn_handle rgn_handle[SAMPLE_VGS_OSD_BUTT];
|
|
sample_vgs_func_param vgs_func_param = {0};
|
|
sample_vb_base_info in_img_vb_info;
|
|
ot_vgs_osd vgs_add_osd[SAMPLE_VGS_OSD_BUTT];
|
|
ot_cover vgs_add_cover;
|
|
|
|
in_img_vb_info.video_format = OT_VIDEO_FORMAT_LINEAR;
|
|
in_img_vb_info.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
|
in_img_vb_info.width = 1920; /* 1920:1080P width */
|
|
in_img_vb_info.height = 1080; /* 1080:1080P height */
|
|
in_img_vb_info.align = 0;
|
|
in_img_vb_info.compress_mode = OT_COMPRESS_MODE_NONE;
|
|
|
|
vgs_add_cover.type = OT_COVER_RECT;
|
|
vgs_add_cover.color = 0x00FF00;
|
|
vgs_add_cover.rect.x = 200; /* cover x-component is 200 */
|
|
vgs_add_cover.rect.y = 300; /* cover y-component is 300 */
|
|
vgs_add_cover.rect.width = 400; /* cover's size is 400x300 */
|
|
vgs_add_cover.rect.height = 300; /* cover's size is 400x300 */
|
|
|
|
sample_vgs_case2_set_osd_stat(vgs_add_osd, SAMPLE_VGS_OSD_BUTT, rgn_handle, SAMPLE_VGS_OSD_BUTT);
|
|
|
|
vgs_func_param.cover = TD_TRUE;
|
|
vgs_func_param.vgs_add_cover = &vgs_add_cover;
|
|
vgs_func_param.osd = TD_TRUE;
|
|
vgs_func_param.vgs_add_osd = vgs_add_osd;
|
|
vgs_func_param.rgn_handle[SAMPLE_VGS_OSD_NORM] = &rgn_handle[SAMPLE_VGS_OSD_NORM];
|
|
vgs_func_param.rgn_handle[SAMPLE_VGS_OSD_CLUT2] = &rgn_handle[SAMPLE_VGS_OSD_CLUT2];
|
|
vgs_func_param.rgn_handle[SAMPLE_VGS_OSD_CLUT4] = &rgn_handle[SAMPLE_VGS_OSD_CLUT4];
|
|
vgs_func_param.in_img_vb_info = &in_img_vb_info;
|
|
vgs_func_param.out_img_vb_info = TD_NULL;
|
|
vgs_func_param.sample_num = 1;
|
|
|
|
ret = sample_vgs_common_function(&vgs_func_param);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("VGS sample %d failed, ret:0x%x", vgs_func_param.sample_num, ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_vgs_draw_line(td_void)
|
|
{
|
|
td_s32 ret;
|
|
sample_vgs_func_param vgs_func_param = {0};
|
|
sample_vb_base_info in_img_vb_info;
|
|
ot_vgs_line vgs_draw_line;
|
|
|
|
in_img_vb_info.video_format = OT_VIDEO_FORMAT_LINEAR;
|
|
in_img_vb_info.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
|
in_img_vb_info.width = 1920; /* 1920:1080P width */
|
|
in_img_vb_info.height = 1080; /* 1080:1080P height */
|
|
in_img_vb_info.align = 0;
|
|
in_img_vb_info.compress_mode = OT_COMPRESS_MODE_NONE;
|
|
|
|
vgs_draw_line.start_point.x = 50; /* line starts from 50,50 */
|
|
vgs_draw_line.start_point.y = 50; /* line starts from 50,50 */
|
|
vgs_draw_line.end_point.x = 1600; /* line ends at 1600,900 */
|
|
vgs_draw_line.end_point.y = 900; /* line ends at 1600,900 */
|
|
vgs_draw_line.thick = 2; /* line width 2 */
|
|
vgs_draw_line.color = 0x0000FF;
|
|
|
|
vgs_func_param.draw_line = TD_TRUE;
|
|
vgs_func_param.vgs_draw_line = &vgs_draw_line;
|
|
vgs_func_param.in_img_vb_info = &in_img_vb_info;
|
|
vgs_func_param.out_img_vb_info = TD_NULL;
|
|
vgs_func_param.sample_num = 2; /* line width 2 */
|
|
|
|
ret = sample_vgs_common_function(&vgs_func_param);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("VGS sample %d failed, ret:0x%x", vgs_func_param.sample_num, ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_vgs_luma(td_void)
|
|
{
|
|
td_s32 ret;
|
|
sample_vgs_func_param vgs_func_param = {0};
|
|
sample_vb_base_info in_img_vb_info;
|
|
td_u32 i;
|
|
ot_rect luma_rect[MAX_LUMA_NUM];
|
|
td_u64 luma_data[MAX_LUMA_NUM];
|
|
in_img_vb_info.video_format = OT_VIDEO_FORMAT_LINEAR;
|
|
in_img_vb_info.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
|
in_img_vb_info.width = 1920; /* 1920:1080P width */
|
|
in_img_vb_info.height = 1080; /* 1080:1080P height */
|
|
in_img_vb_info.align = 0;
|
|
in_img_vb_info.compress_mode = OT_COMPRESS_MODE_NONE;
|
|
|
|
for (i = 0; i < MAX_LUMA_NUM; i++) {
|
|
luma_rect[i].x = 100 + 50 * i; /* luma x-component starts from 100 at a step of 50 */
|
|
luma_rect[i].y = 100 + 50 * i; /* luma y-component starts from 100 at a step of 50 */
|
|
luma_rect[i].width = 40; /* 40x40 luma region */
|
|
luma_rect[i].height = 40; /* 40x40 luma region */
|
|
}
|
|
if (memset_s(luma_data, sizeof(td_u64) * MAX_LUMA_NUM, 0, sizeof(td_u64) * MAX_LUMA_NUM) != EOK) {
|
|
sample_print("vgs memset_s failed!\n");
|
|
return TD_FAILURE;
|
|
};
|
|
vgs_func_param.luma = TD_TRUE;
|
|
vgs_func_param.luma_rect = luma_rect;
|
|
vgs_func_param.luma_data = luma_data;
|
|
vgs_func_param.luma_num = MAX_LUMA_NUM;
|
|
vgs_func_param.in_img_vb_info = &in_img_vb_info;
|
|
vgs_func_param.out_img_vb_info = TD_NULL;
|
|
vgs_func_param.sample_num = 4; /* 4 is parameter */
|
|
|
|
ret = sample_vgs_common_function(&vgs_func_param);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("VGS sample %d failed, ret:0x%x", vgs_func_param.sample_num, ret);
|
|
}
|
|
for (i = 0; i < MAX_LUMA_NUM; i++) {
|
|
sample_print("VGS sample luma_rect: %d,luma_data:%llu\n", i, luma_data[i]);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_vgs_rotate(td_void)
|
|
{
|
|
td_s32 ret;
|
|
sample_vgs_func_param vgs_func_param = {0};
|
|
ot_rotation rotation_angle = OT_ROTATION_90;
|
|
sample_vb_base_info in_img_vb_info;
|
|
sample_vb_base_info out_img_vb_info;
|
|
|
|
in_img_vb_info.video_format = OT_VIDEO_FORMAT_LINEAR;
|
|
in_img_vb_info.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
|
in_img_vb_info.width = 1920; /* 1920:1080P width */
|
|
in_img_vb_info.height = 1080; /* 1080:1080P height */
|
|
in_img_vb_info.align = 0;
|
|
in_img_vb_info.compress_mode = OT_COMPRESS_MODE_NONE;
|
|
|
|
if (memcpy_s(&out_img_vb_info, sizeof(sample_vb_base_info), &in_img_vb_info, sizeof(sample_vb_base_info)) != EOK) {
|
|
sample_print("memcpy_s failed\n");
|
|
return TD_FAILURE;
|
|
};
|
|
out_img_vb_info.width = 1080; /* 1080:1080P height */
|
|
out_img_vb_info.height = 1920; /* 1920:1080P width */
|
|
|
|
vgs_func_param.rotate = TD_TRUE;
|
|
vgs_func_param.rotation_angle = &rotation_angle;
|
|
vgs_func_param.in_img_vb_info = &in_img_vb_info;
|
|
vgs_func_param.out_img_vb_info = &out_img_vb_info;
|
|
vgs_func_param.sample_num = 3; /* 3 rotation task */
|
|
|
|
ret = sample_vgs_common_function(&vgs_func_param);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("VGS sample %d failed, ret:0x%x", vgs_func_param.sample_num, ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 sample_vgs_proc_task(td_s32 task_index)
|
|
{
|
|
td_s32 ret;
|
|
switch (task_index) {
|
|
case 0: /* 0 scale sample */
|
|
ret = sample_vgs_scale();
|
|
break;
|
|
case 1: /* 1 cover and osd sample */
|
|
ret = sample_vgs_cover_osd();
|
|
break;
|
|
case 2: /* 2 draw line sample */
|
|
ret = sample_vgs_draw_line();
|
|
break;
|
|
case 3: /* 3 rotate sample */
|
|
ret = sample_vgs_rotate();
|
|
break;
|
|
case 4: /* 4 luma sample */
|
|
ret = sample_vgs_luma();
|
|
break;
|
|
default:
|
|
ret = TD_FAILURE;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* function : main()
|
|
* description : video vgs sample
|
|
*/
|
|
#ifdef __LITEOS__
|
|
td_s32 app_main(td_s32 argc, td_char *argv[])
|
|
#else
|
|
td_s32 main(td_s32 argc, td_char *argv[])
|
|
#endif
|
|
{
|
|
td_s32 ret = TD_FAILURE;
|
|
td_s32 index;
|
|
|
|
if (argc != 2) { /* 2:arv num */
|
|
sample_vgs_usage(argv[0]);
|
|
return ret;
|
|
}
|
|
|
|
if (!strncmp(argv[1], "-h", 2)) { /* 2:arv len */
|
|
sample_vgs_usage(argv[0]);
|
|
return TD_SUCCESS;
|
|
}
|
|
if ((strlen(argv[1]) > 1) ||
|
|
(strncmp(argv[1], "0", 1) && strncmp(argv[1], "1", 1) && strncmp(argv[1], "2", 1) &&
|
|
strncmp(argv[1], "3", 1) && strncmp(argv[1], "4", 1))) {
|
|
sample_print("the index is invalid!\n");
|
|
sample_vgs_usage(argv[0]);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_vgs_sample_signal_flag = 0;
|
|
|
|
sample_sys_signal(&sample_vgs_handle_sig);
|
|
|
|
index = atoi(argv[1]);
|
|
ret = sample_vgs_proc_task(index);
|
|
|
|
if (g_vgs_sample_signal_flag == 1) {
|
|
printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
|
|
exit(-1);
|
|
}
|
|
|
|
if (ret == TD_SUCCESS) {
|
|
sample_print("vgs sample %d exit normally!\n", index);
|
|
} else {
|
|
sample_print("vgs sample %d exit abnormally!\n", index);
|
|
}
|
|
return ret;
|
|
}
|