sdk-hwV1.3/external/fast-user-adapter/rt_media/api_adapter/aw_util.c

727 lines
23 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <pthread.h>
#include "aw_util.h"
//#include "uapi_rt_media.h"
#include "aw_message_queue.h"
argument_t ArgumentMapping[] =
{
{ "-h", "--help", HELP,
"Print this help" },
{ "-n", "--encode_frame_num", ENCODE_FRAME_NUM,
"After encoder n frames, encoder stop" },
{ "-f0", "--encode_format0", ENCODE_FORMAT_0,
"0:h264 encoder, 1:jpeg_encoder, 2:h265 encoder" },
{ "-f1", "--encode_format1", ENCODE_FORMAT_1,
"0:h264 encoder, 1:jpeg_encoder, 2:h265 encoder" },
{ "-s0", "--srcsize", SRC_SIZE_0,
"src_size,can be 1920x1080 or 2160,1080,720,480,288" },
{ "-ds0", "--dstsize", DST_SIZE_0,
"dst_size,can be 1920x1080 or 2160,1080,720,480,288" },
{ "-s1", "--srcsize", SRC_SIZE_1,
"src_size,can be 1920x1080 or 2160,1080,720,480,288" },
{ "-b0", "--bitrate", BIT_RATE_0,
"bitRate:bps" },
{ "-b1", "--bitrate", BIT_RATE_1,
"bitRate:kbps" },
{ "-in", "--inputfile", INPUT_FILE_NAME,
"inputfile: It is better to provide absolute paths" },
{ "-out", "--outputfile", OUTPUT_FILE_NAME,
"outputfile: It is better to provide absolute paths" },
{ "-snd", "--second", SUPPORT_SECOND_CHANNEL,
"second: support second channel, use to encode sub channel" },
{ "-trd", "--third", SUPPORT_THIRD_CHANNEL,
"third: support third channel, use to save yuv" },
{ "-local", "--local", ENCODE_LOCAL_YUV,
"local: only encode local yuv, disable isp" },
{ "-pf", "--pxlformat", PIXEL_FORMAT,
"pxlformat:set input yuv format NV12 = 0, NV21 = 1, YV12 = 2, YV21 = 3, LBC_25X = 4" },
{ "-pf1", "--pxlformat1", PIXEL_FORMAT_1,
"pxlformat:set input yuv format NV12 = 0, NV21 = 1, YV12 = 2, YV21 = 3, LBC_25X = 4" },
{ "-pf2", "--pxlformat2", PIXEL_FORMAT_2,
"pxlformat:set input yuv format NV12 = 0, NV21 = 1, YV12 = 2, YV21 = 3, LBC_25X = 4" },
{ "-vn", "--vippnum", USE_VIPP_NUM,
"vippnum: set channel 0 use vipp num" },
{ "-vn1", "--vippnum1", USE_VIPP_NUM_1,
"vippnum: set channel 1 use vipp num" },
{ "-vn2", "--vippnum1", USE_VIPP_NUM_2,
"vippnum: set channel 2 use vipp num" },
{ "-sp", "--sharp", ENABLE_SHARP,
"test sharp func" },
{ "-js", "--jpgsize", JPG_SIZE,
"set jpg size" },
{ "-online", "--online_mode", ONLINE_MODE,
"online mode" },
{ "-sbn", "--share_buf", SHARE_BUF_NUM,
"set online share buf num: 1 2" },
{ "-roi", "--roi", ENABLE_ROI,
"on/off roi" },
{ "-fi", "--force_i", ENABLE_FORCE_I_FRAME,
"on/off roi" },
{ "-ms", "--motion", ENABLE_MOTION_SEARCH,
"on/off motion_search" },
{ "-osd", "--osd", ENABLE_OSD,
"on/off osd" },
{ "-orl", "--orl", ENABLE_ORL,
"on/off orl" },
{ "-rs", "--reset", ENABLE_RESET_SIZE,
"on/off reset size" },
{ "-gdc", "--gdc", ENABLE_GDC,
"on/off gdc" },
{ "-cs", "--colorspace", COLOR_SPACE,
"set color space" },
{ "-ra", "--rotate", ROTATE_ANGEL,
"set rotate angle, 0/90/180/270, other angel is not set"},
{ "-vb", "--vinbuf", VIN_BUF_NUM,
"for channel 1 set vin buf num, should set >= 3"},
{ "-crop", "--crop", ENABLE_CROP,
"crop test, default coordinate is, x:80, y:64, width:640, high:320"},
{ "-gray", "--gray", ENABLE_GRAY,
"gray test, enalbe to make stream gray"},
{ "-wbyuv", "--wbyuv", ENABLE_WB_YUV_TEST,
"setting wbyuv test"},
{ "-pir", "--pir", P_INTRA_REFRESH,
"P Frame Intra refresh test"},
{ "-nr", "--nr", EN_2D_3D_NR_TEST,
"2d/3d nr test"},
{ "-dfps", "--dstfps", DST_FPS,
"dst fps, to venc"},
{ "-aiisp", "--aiisp", ENABLE_AIISP,
"enable aiisp"},
{ "-aiispmode", "--aiispmode", AIISP_MODE,
"aiisp mode"},
{ "-tdmbuf", "--tdmbuf", TDM_RXBUF_CNT,
"tdm rx buf cnt"},
{ "-aiispauto", "--aiispauto", AIISP_AUTO_SWITCH,
"aiisp auto switch by isp ae param"},
{ "-aiispintv", "--aiispintv", AIISP_SWITCH_INTERVAL,
"aiisp switch interval"},
{ "-aiisp_bin", "--isp_aiisp_bin_path", ISP_AIISP_BIN_PATH,
"set isp aiisp bin path when aiisp test"},
{ "-day_bin", "--isp_day_bin_path", ISP_DAY_BIN_PATH,
"set isp day bin path when aiisp test"},
{ "-npu_lut_model", "--npu_lut_model_file_path", NPU_LUT_MODEL_FILE_PATH,
"set npu lut model file path when aiisp test"},
{ "-npu_model", "--npu_model_file_path", NPU_MODEL_FILE_PATH,
"set npu model file path when aiisp test"},
{ "-argb_type", "--argb_type", ARGB_TYPE,
"set argb_type"},
};
int check_param(demo_video_param *pparam)
{
if(pparam->c0_src_w <=0 || pparam->c0_src_h <= 0)
{
pparam->c0_src_w = 2560;
pparam->c0_src_h = 1440;
}
if(pparam->c0_dst_w <=0 || pparam->c0_dst_h <= 0)
{
pparam->c0_dst_w = pparam->c0_src_w;
pparam->c0_dst_h = pparam->c0_src_h;
}
if(pparam->c0_bitrate <= 0)
pparam->c0_bitrate = 1.5*1024*1024;
if(pparam->c0_encoder_format < 0)
pparam->c0_encoder_format = 0;
if(pparam->c1_src_w <=0 || pparam->c1_src_h <= 0)
{
pparam->c1_src_w = 640;
pparam->c1_src_h = 480;
}
if(pparam->c1_bitrate <= 0)
pparam->c1_bitrate = 256*1024;
if(pparam->c1_encoder_format < 0)
pparam->c1_encoder_format = 0;
return 0;
}
ARGUMENT_T GetArgument(char *name)
{
int i = 0;
int num = sizeof(ArgumentMapping) / sizeof(argument_t);
while(i < num)
{
aw_logv("input_name:%s, i:%d, name:%s, short:%s, argument:%d, num:%d\n",
name,
i,
ArgumentMapping[i].Name,
ArgumentMapping[i].Short,
ArgumentMapping[i].argument,
num);
if((0 == strcmp(ArgumentMapping[i].Name, name)) ||
((0 == strcmp(ArgumentMapping[i].Short, name)) &&
(0 != strcmp(ArgumentMapping[i].Short, "--"))))
{
return ArgumentMapping[i].argument;
}
i++;
}
return INVALID;
}
void PrintDemoUsage(void)
{
int i = 0;
int num = sizeof(ArgumentMapping) / sizeof(argument_t);
aw_logd("Usage:");
while(i < num)
{
aw_logd("%-12s %-32s %s", ArgumentMapping[i].Short, ArgumentMapping[i].Name,
ArgumentMapping[i].Description);
aw_logd("\n");
i++;
}
}
void ParseArgument(demo_video_param *param, char *argument, char *value)
{
ARGUMENT_T arg;
arg = GetArgument(argument);
switch(arg)
{
case HELP:
PrintDemoUsage();
break;
case ENABLE_GDC:
sscanf(value, "%32u", &param->enable_gdc);
aw_logd("enable_gdc:%u\n", param->enable_gdc);
break;
case ENABLE_RESET_SIZE:
sscanf(value, "%32u", &param->enable_reset_size);
aw_logd("enable_reset_size:%u\n", param->enable_reset_size);
break;
case ENABLE_ORL:
sscanf(value, "%32u", &param->enable_orl);
aw_logd("enable_orl:%u\n", param->enable_orl);
break;
case ENABLE_OSD:
sscanf(value, "%32u", &param->enable_osd);
aw_logd("enable_osd:%u\n", param->enable_osd);
break;
case ENABLE_FORCE_I_FRAME:
sscanf(value, "%32u", &param->enable_force_key_frame);
aw_logd("enable_force_key_frame:%u\n", param->enable_force_key_frame);
break;
case ENABLE_MOTION_SEARCH:
sscanf(value, "%32u", &param->enable_motion_search);
aw_logd("enable_motion_search:%u\n", param->enable_motion_search);
break;
case ENABLE_ROI:
sscanf(value, "%32u", &param->enable_roi);
aw_logd("enable_roi:%u\n", param->enable_roi);
break;
case JPG_SIZE:
if(strlen(value) > 5)
{
sscanf(value, "%32ux%32u", &param->jpg_width,&param->jpg_heigh);
}
else
{
param->jpg_width = 640;
param->jpg_heigh = 368;
}
aw_logd("jpg_size: %dx%d\n", param->jpg_width, param->jpg_heigh);
break;
case ENABLE_SHARP:
sscanf(value, "%32u", &param->enable_sharp);
aw_logd("enable_sharp:%u\n", param->enable_sharp);
break;
case ONLINE_MODE:
sscanf(value, "%32u", &param->bonline_channel);
aw_logd("bonline_channel:%u\n", param->bonline_channel);
break;
case SHARE_BUF_NUM:
sscanf(value, "%32u", &param->share_buf_num);
aw_logd("share_buf_num:%u\n", param->share_buf_num);
break;
case USE_VIPP_NUM:
sscanf(value, "%32u", &param->use_vipp_num);
aw_logd("use_vipp_num:%u\n", param->use_vipp_num);
break;
case USE_VIPP_NUM_1:
sscanf(value, "%32u", &param->use_vipp_num_1);
aw_logd("use_vipp_num_1:%u\n", param->use_vipp_num_1);
break;
case USE_VIPP_NUM_2:
sscanf(value, "%32u", &param->use_vipp_num_2);
aw_logd("use_vipp_num_2:%u\n", param->use_vipp_num_2);
break;
case PIXEL_FORMAT:
sscanf(value, "%32u", &param->pixelformat);
aw_logd("pixelformat:%u\n", param->pixelformat);
break;
case PIXEL_FORMAT_1:
sscanf(value, "%32u", &param->pixelformat_1);
aw_logd("pixelformat_1:%u\n", param->pixelformat_1);
break;
case PIXEL_FORMAT_2:
sscanf(value, "%32u", &param->pixelformat_2);
aw_logd("pixelformat_2:%u\n", param->pixelformat_2);
break;
case ENCODE_LOCAL_YUV:
sscanf(value, "%32u", &param->encode_local_yuv);
aw_logd("encode_local_yuv:%u\n", param->encode_local_yuv);
break;
case SUPPORT_SECOND_CHANNEL:
sscanf(value, "%32u", &param->en_second_channel);
aw_logd("en_second_channel:%u\n", param->en_second_channel);
break;
case SUPPORT_THIRD_CHANNEL:
sscanf(value, "%32u", &param->en_third_channel);
aw_logd("en_third_channel:%u\n", param->en_third_channel);
break;
case ENCODE_FRAME_NUM:
sscanf(value, "%32u", &param->encoder_num);
aw_logd("encode:%u frames\n", param->encoder_num);
break;
case INPUT_FILE_NAME:
memset(param->InputFileName, 0, sizeof(param->InputFileName));
sscanf(value, "%127s", param->InputFileName);
aw_logd("input file name: %s\n", param->InputFileName);
break;
case OUTPUT_FILE_NAME:
memset(param->OutputFilePath, 0, sizeof(param->OutputFilePath));
sscanf(value, "%127s", param->OutputFilePath);
aw_logd("output file path: %s\n", param->OutputFilePath);
break;
case ENCODE_FORMAT_0:
sscanf(value, "%32u", &param->c0_encoder_format);
aw_logd("c0_encode_format:%u 0:h264,1:jpeg,3:h265\n", param->c0_encoder_format);
break;
case ENCODE_FORMAT_1:
sscanf(value, "%32u", &param->c1_encoder_format);
aw_logd("c1_encode_format:%u 0:h264,1:jpeg,3:h265\n", param->c1_encoder_format);
break;
case SRC_SIZE_0:
if(strlen(value) > 5)
{
sscanf(value, "%32ux%32u", &param->c0_src_w,&param->c0_src_h);
}
else
{
sscanf(value, "%32u", &param->c0_src_size);
if(param->c0_src_size == 1080)
{
param->c0_src_w = 1920;
param->c0_src_h = 1080;
}
else if(param->c0_src_size == 1088)
{
param->c0_src_w = 1920;
param->c0_src_h = 1088;
}
else if(param->c0_src_size == 720)
{
param->c0_src_w = 1280;
param->c0_src_h = 720;
}
else if(param->c0_src_size == 480)
{
param->c0_src_w = 640;
param->c0_src_h = 480;
}
}
break;
case DST_SIZE_0:
if(strlen(value) > 5)
{
sscanf(value, "%32ux%32u", &param->c0_dst_w,&param->c0_dst_h);
}
else
{
sscanf(value, "%32u", &param->c0_dst_size);
if(param->c0_dst_size == 1080)
{
param->c0_dst_w = 1920;
param->c0_dst_h = 1080;
}
else if(param->c0_dst_size == 1088)
{
param->c0_dst_w = 1920;
param->c0_dst_h = 1088;
}
else if(param->c0_dst_size == 720)
{
param->c0_dst_w = 1280;
param->c0_dst_h = 720;
}
else if(param->c0_dst_size == 480)
{
param->c0_dst_w = 640;
param->c0_dst_h = 480;
}
}
break;
case SRC_SIZE_1:
if(strlen(value) > 5)
{
sscanf(value, "%32ux%32u", &param->c1_src_w,&param->c1_src_h);
}
else
{
sscanf(value, "%32u", &param->c1_src_size);
if(param->c1_src_size == 1080)
{
param->c1_src_w = 1920;
param->c1_src_h = 1080;
}
else if(param->c1_src_size == 1088)
{
param->c1_src_w = 1920;
param->c1_src_h = 1088;
}
else if(param->c1_src_size == 720)
{
param->c1_src_w = 1280;
param->c1_src_h = 720;
}
else if(param->c1_src_size == 480)
{
param->c1_src_w = 640;
param->c1_src_h = 480;
}
}
break;
case BIT_RATE_0:
sscanf(value, "%32u", &param->c0_bitrate);
aw_logd("c0_bitrate:%u \n", param->c0_bitrate);
break;
case BIT_RATE_1:
sscanf(value, "%32u", &param->c1_bitrate);
aw_logd("c1_bitrate:%u \n", param->c1_bitrate);
break;
case COLOR_SPACE:
{
sscanf(value, "%32u", &param->color_space);
aw_logd("color space:%u \n", param->color_space);
break;
}
case ROTATE_ANGEL:
{
sscanf(value, "%32u", &param->rotate_angle);
aw_logd("rotate angle:%u \n", param->rotate_angle);
break;
}
case VIN_BUF_NUM:
{
sscanf(value, "%32u", &param->vin_buf_num);
aw_logd("vin_buf_num:%u \n", param->vin_buf_num);
break;
}
case ENABLE_CROP:
{
sscanf(value, "%32u", &param->enable_crop);
aw_logd("enable_crop:%u \n", param->enable_crop);
break;
}
case ENABLE_GRAY:
{
sscanf(value, "%32u", &param->enable_gray);
aw_logd("enable_gray:%u \n", param->enable_gray);
break;
}
case ENABLE_WB_YUV_TEST:
{
sscanf(value, "%32u", &param->enable_wbyuv);
aw_logd("enable_wbyuv:%u \n", param->enable_wbyuv);
break;
}
case P_INTRA_REFRESH:
{
sscanf(value, "%32u", &param->enable_p_intra_refresh);
aw_logd("enable_p_intra_refresh:%u \n", param->enable_p_intra_refresh);
break;
}
case EN_2D_3D_NR_TEST:
{
sscanf(value, "%32u", &param->en_2d_3d_nr);
aw_logd("en_2d_3d_nr:%u \n", param->en_2d_3d_nr);
break;
}
case DST_FPS:
{
sscanf(value, "%32u", &param->dst_fps);
aw_logd("DST_FPS:%u \n", param->dst_fps);
break;
}
case ENABLE_AIISP:
{
sscanf(value, "%32u", &param->enable_aiisp);
aw_logd("enable_aiisp:%u \n", param->enable_aiisp);
break;
}
case ARGB_TYPE:
{
sscanf(value, "%32u", &param->argb_type);
aw_logd("argb_type:%u \n", param->argb_type);
break;
}
case AIISP_MODE:
{
sscanf(value, "%32u", &param->aiisp_mode);
aw_logd("aiisp_mode:%u \n", param->aiisp_mode);
break;
}
case TDM_RXBUF_CNT:
{
sscanf(value, "%32u", &param->tdm_rxbuf_cnt);
aw_logd("tdm_rxbuf_cnt:%u \n", param->tdm_rxbuf_cnt);
break;
}
case AIISP_AUTO_SWITCH:
{
sscanf(value, "%32u", &param->aiisp_auto_switch);
aw_logd("aiisp auto switch:%u \n", param->aiisp_auto_switch);
break;
}
case AIISP_SWITCH_INTERVAL:
{
sscanf(value, "%32u", &param->aiisp_switch_interval);
aw_logd("aiisp switch interval:%u \n", param->aiisp_switch_interval);
break;
}
case ISP_AIISP_BIN_PATH:
memset(param->isp_aiisp_bin_path, 0, sizeof(param->isp_aiisp_bin_path));
strncpy(param->isp_aiisp_bin_path, value, sizeof(param->isp_aiisp_bin_path) - 1);
aw_logd("isp aiisp bin path: %s\n", param->isp_aiisp_bin_path);
break;
case ISP_DAY_BIN_PATH:
memset(param->isp_day_bin_path, 0, sizeof(param->isp_day_bin_path));
strncpy(param->isp_day_bin_path, value, sizeof(param->isp_day_bin_path) - 1);
aw_logd("isp day bin path: %s\n", param->isp_day_bin_path);
break;
case NPU_LUT_MODEL_FILE_PATH:
memset(param->npu_lut_model_file_path, 0, sizeof(param->npu_lut_model_file_path));
strncpy(param->npu_lut_model_file_path, value, sizeof(param->npu_lut_model_file_path) - 1);
aw_logd("npu lut model file path: %s\n", param->npu_lut_model_file_path);
break;
case NPU_MODEL_FILE_PATH:
memset(param->npu_model_file_path, 0, sizeof(param->npu_model_file_path));
strncpy(param->npu_model_file_path, value, sizeof(param->npu_model_file_path) - 1);
aw_logd("npu model file path: %s\n", param->npu_model_file_path);
break;
case INVALID:
default:
aw_logd("unknowed argument : %s\n", argument);
break;
}
}
int rt_is_format422(rt_pixelformat_type pixelformat)
{
if (pixelformat >= RT_PIXEL_YUV422SP && pixelformat <= RT_PIXEL_VYUY422)
return 1;
else
return 0;
}
int rt_cal_input_buffer_size(int w, int h, rt_pixelformat_type pixelformat, int read_file)
{
int buf_size = w*h*3/2;
int y_stride = 0;
int yc_stride = 0;
int pic_width_32align = ALIGN_XXB(32, w);
int pic_width_16align = ALIGN_XXB(16, w);
int pic_height_16align = ALIGN_XXB(16, h);
if (pixelformat == RT_PIXEL_LBC_25X || pixelformat == RT_PIXEL_LBC_2X) {
if (pixelformat == RT_PIXEL_LBC_2X) {
y_stride = ((LBC_2X_COM_RATIO_EVEN * pic_width_32align * LBC_BIT_DEPTH / 1000 + 511) & (~511)) >> 3;
yc_stride = ((LBC_2X_COM_RATIO_ODD * pic_width_32align * LBC_BIT_DEPTH / 500 + 511) & (~511)) >> 3;
} else if (pixelformat == RT_PIXEL_LBC_25X) {
y_stride = ((LBC_2_5X_COM_RATIO_EVEN * pic_width_32align * LBC_BIT_DEPTH / 1000 + 511) & (~511)) >> 3;
yc_stride = ((LBC_2_5X_COM_RATIO_ODD * pic_width_32align * LBC_BIT_DEPTH / 500 + 511) & (~511)) >> 3;
} else {
y_stride = ((pic_width_32align * LBC_BIT_DEPTH + pic_width_32align / 16 * 2 + 511) & (~511)) >> 3;
yc_stride = ((pic_width_32align * LBC_BIT_DEPTH * 2 + pic_width_32align / 16 * 4 + 511) & (~511)) >> 3;
}
buf_size = (y_stride + yc_stride) * pic_height_16align / 2;
//* add more 1KB to fix ve-lbc-error
buf_size += LBC_EXT_SIZE;
} else if (rt_is_format422(pixelformat)) {
if (read_file) {
buf_size = w * h * 2;
} else {
buf_size = pic_width_16align * pic_height_16align * 2;
if (pic_width_16align % 64 != 0)
buf_size += 64;
}
} else {//default as yuv420, add other format please additionally add
if (read_file) {
buf_size = w * h * 3 / 2;
} else {
buf_size = pic_width_16align * pic_height_16align * 3 / 2;
if (pic_width_16align % 64 != 0)
buf_size += 64;
}
}
return buf_size;
}
int bmp_32_to_argb8888(unsigned char* imageData, uint32_t* argbData, struct DIBHeader *dibHeader)
{
int argb_idx = 0, pixel_num = 0;
int width = dibHeader->width, height = dibHeader->height;
int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4;
for (int y = height - 1; y >= 0; y--) {
for (int x = 0; x < width; x++) {
pixel_num = y * rowSize + x * 4;
uint8_t b = imageData[pixel_num];
uint8_t g = imageData[pixel_num + 1];
uint8_t r = imageData[pixel_num + 2];
uint8_t a = imageData[pixel_num + 3];
argbData[argb_idx++] = (a << 24) | (r << 16) | (g << 8) | b;
}
}
}
int bmp_24_to_argb8888(unsigned char* imageData, uint32_t* argbData, struct DIBHeader *dibHeader)
{
int argb_idx = 0, pixel_num = 0;
int width = dibHeader->width, height = dibHeader->height;
int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4;
rowSize = ((width * dibHeader->bitsPerPixel + 23) / 24) * 3;
for (int y = height - 1; y >= 0; y--) {
for (int x = 0; x < width; x++) {
pixel_num = y * rowSize + x * 3;
uint8_t b = imageData[pixel_num];
uint8_t g = imageData[pixel_num + 1];
uint8_t r = imageData[pixel_num + 2];
argbData[argb_idx++] = (0xFF << 24) | (r << 16) | (g << 8) | b;
}
}
}
int bmp_32_to_argb1555(unsigned char* imageData, uint16_t *argbData, struct DIBHeader *dibHeader)
{
int argb_idx = 0, pixel_num = 0;
int width = dibHeader->width, height = dibHeader->height;
int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4;
for (int y = height - 1; y >= 0; y--) {
for (int x = 0; x < width; x++) {
pixel_num = y * rowSize + x * 4;
uint8_t b = imageData[pixel_num] >> 3;
uint8_t g = imageData[pixel_num + 1] >> 3;
uint8_t r = imageData[pixel_num + 2] >> 3;
uint8_t a = (imageData[pixel_num + 3] >= 128) ? 1 : 0;
argbData[argb_idx++] = (a << 15) | (r << 10) | (g << 5) | b;
}
}
}
int bmp_24_to_argb1555(unsigned char* imageData, uint16_t* argbData, struct DIBHeader *dibHeader, int alpha)
{
int argb_idx = 0, pixel_num = 0;
int width = dibHeader->width, height = dibHeader->height;
int rowSize = ((width * dibHeader->bitsPerPixel + 31) / 32) * 4;
rowSize = ((width * dibHeader->bitsPerPixel + 23) / 24) * 3;
for (int y = height - 1; y >= 0; y--) {
for (int x = 0; x < width; x++) {
pixel_num = y * rowSize + x * 3;
uint8_t b = imageData[pixel_num] >> 3;
uint8_t g = imageData[pixel_num + 1] >> 3;
uint8_t r = imageData[pixel_num + 2] >> 3;
argbData[argb_idx++] = (alpha << 15) | (r << 10) | (g << 5) | b;
}
}
}
unsigned char *deal_bmp_data(FILE* fd, VideoInputOSD *pOverlayInfo, int index)
{
struct BMPHeader bmpHeader;
struct DIBHeader dibHeader;
int width = pOverlayInfo->item_info[index].widht;
int height = pOverlayInfo->item_info[index].height;
unsigned char* imageData = NULL;
int argb_size = 0;
uint32_t* argbData = NULL;
fread(&bmpHeader, sizeof(struct BMPHeader), 1, fd);
fread(&dibHeader, sizeof(struct DIBHeader), 1, fd);
if (dibHeader.bitsPerPixel != 32 && dibHeader.bitsPerPixel != 24) {
aw_logw("not support bitcount %d", dibHeader.bitsPerPixel);
return NULL;
}
width = pOverlayInfo->item_info[index].widht = dibHeader.width;
height = pOverlayInfo->item_info[index].height = dibHeader.height;
if (pOverlayInfo->argb_type == OVERLAY_ARGB8888)
argb_size = width * height * 4;
else
argb_size = width * height * 2;
aw_logw("The file is a BMP file. width %d height %d argb_type %d\n", width, height, pOverlayInfo->argb_type);
fseek(fd, bmpHeader.dataOffset, SEEK_SET);
if (dibHeader.imageSize == 0) {
if (dibHeader.bitsPerPixel == 32)
dibHeader.imageSize = width * height * 4;
else if (dibHeader.bitsPerPixel == 24)
dibHeader.imageSize = width * height * 3;
}
imageData = (unsigned char*)malloc(dibHeader.imageSize);
if (!imageData) {
aw_loge("malloc imageData failed!");
return NULL;
}
fread(imageData, dibHeader.imageSize, 1, fd);
aw_logd("fileSize %d dataOffset %d", bmpHeader.fileSize, bmpHeader.dataOffset);
aw_logd("argb_size %d imageSize %d width %d height %d\n", argb_size,\
dibHeader.imageSize, width, height);
aw_logd("bitsPerPixel %d compression %d\n", dibHeader.bitsPerPixel, dibHeader.compression);
argbData = (unsigned char *)malloc(argb_size);
if (!argbData) {
aw_loge("malloc argbData failed!");
return NULL;
}
if (dibHeader.bitsPerPixel == 32) {
if (pOverlayInfo->argb_type == OVERLAY_ARGB8888)
bmp_32_to_argb8888(imageData, argbData, &dibHeader);
else if (pOverlayInfo->argb_type == OVERLAY_ARGB1555) {
uint16_t *argbData_1555 = (uint16_t *)argbData;
bmp_32_to_argb1555(imageData, argbData_1555, &dibHeader);
}
else
aw_loge("not support %d", pOverlayInfo->argb_type);
} else if (dibHeader.bitsPerPixel == 24) {
if (pOverlayInfo->argb_type == OVERLAY_ARGB8888)
bmp_24_to_argb8888(imageData, argbData, &dibHeader);
else if (pOverlayInfo->argb_type == OVERLAY_ARGB1555) {
uint16_t *argbData_1555 = (uint16_t *)argbData;
bmp_24_to_argb1555(imageData, argbData_1555, &dibHeader, 1);
}
else
aw_loge("not support %d", pOverlayInfo->argb_type);
} else {
aw_logw("Unsupported image data format\n");
}
#if 0//for debug save argb data.
FILE *argbFile = fopen("output.argb", "wb");
if (!argbFile) {
aw_loge("Failed to create output file\n");
return -1;
}
fwrite(argbData, argb_size, 1, argbFile);
fclose(argbFile);
#endif
free(imageData);
return (unsigned char *)argbData;
}