目录
在调用程序时可以通过执行命令后边加参数对程序进行配置
例如:程序名为 test_mpi_vi
,可以通过以下方式在命令行中设置捕获通道的宽度
./test_mpi_vi -w 1920
./test_mpi_vi --width=1920
整个命令行配置流程如下,需要包含对应都是头文件:
struct argparse_option options[] = {
OPT_HELP(),
OPT_GROUP("basic options:"),
OPT_INTEGER('w', "width", &(ctx->width),
"set capture channel width(required, default 0)", NULL, 0, 0),
OPT_INTEGER('h', "height", &(ctx->height),
"set capture channel height(required, default 0)", NULL, 0, 0),
OPT_INTEGER('d', "dev", &(ctx->devId),
"set dev id(default 0)", NULL, 0, 0),
OPT_INTEGER('p', "pipe", &(ctx->pipeId),
"set pipe id(default 0)", NULL, 0, 0),
OPT_INTEGER('c', "channel", &(ctx->channelId),
"set channel id(default 1)", NULL, 0, 0),
OPT_INTEGER('l', "loopcount", &(ctx->loopCountSet),
"set capture frame count(default 100)", NULL, 0, 0),
OPT_INTEGER('C', "compressmode", &(ctx->enCompressMode),
"set capture compressmode(default 0; 0:MODE_NONE 1:AFBC_16x16)", NULL, 0, 0),
OPT_INTEGER('o', "output", &(ctx->stDebugFile.bCfg),
"save output file, file at /data/test_<devid>_<pipeid>_<channelid>.bin"
" (default 0; 0:no save 1:save)", NULL, 0, 0),
OPT_INTEGER('m', "mode", &(ctx->enMode),
"test mode(default 1; 0:vi get&release frame 1:vi bind one venc(h264) \n\t"
"2:vi bind two venc(h264)) 3:vi bind vpss bind venc \n\t"
"4:vi bind vo 5:multi vi 6:vi get&release stream \n\t"
"7:vi bind vdec bind vo", NULL, 0, 0),
OPT_INTEGER('t', "memorytype", &(ctx->stChnAttr.stIspOpt.enMemoryType),
"set the buf memorytype(required, default 4; 1:mmap(hdmiin/bt1120/sensor input) "
"2:userptr(invalid) 3:overlay(invalid) 4:dma(sensor))", NULL, 0, 0),
OPT_STRING('n', "name", &(ctx->aEntityName),
"set the entityName (required, default null;\n\t"
"rv1126 sensor:rkispp_m_bypass rkispp_scale0 rkispp_scale1 rkispp_scale2;\n\t"
"rv1126 hdmiin/bt1120/sensor:/dev/videox such as /dev/video19 /dev/video20;\n\t"
"rk356x hdmiin/bt1120/sensor:/dev/videox such as /dev/video0 /dev/video1", NULL, 0, 0),
OPT_INTEGER('D', "depth", &(ctx->stChnAttr.u32Depth),
"channel output depth, default{u32BufCount(not bind) or 0(bind venc/vpss/...)}", NULL, 0, 0),
OPT_INTEGER('f', "format", &(ctx->stChnAttr.enPixelFormat),
"set the format(default 0; 0:RK_FMT_YUV420SP 10:RK_FMT_YUV422_UYVY"
"131080:RK_FMT_RGB_BAYER_SBGGR_12BPP)", NULL, 0, 0),
OPT_INTEGER('\0', "freeze", &(ctx->bFreeze),
"freeze output(default 0; 0:disable freeze 1:enable freeze)", NULL, 0, 0),
OPT_INTEGER('\0', "src_rate", &(ctx->stChnAttr.stFrameRate.s32SrcFrameRate),
"src frame rate(default -1; -1:not control; other:1-max_fps<isp_out_fps>)", NULL, 0, 0),
OPT_INTEGER('\0', "dst_rate", &(ctx->stChnAttr.stFrameRate.s32DstFrameRate),
"dst frame rate(default -1; -1:not control; other:1-src_fps<src_rate>)", NULL, 0, 0),
OPT_INTEGER('\0', "buf_count", &(ctx->stChnAttr.stIspOpt.u32BufCount),
"out buf count, range[1-8] default(3)", NULL, 0, 0),
OPT_INTEGER('U', "user_pic", &(ctx->bUserPicEnabled),
"enable using user specify picture as vi input.", NULL, 0, 0),
OPT_INTEGER('\0', "rgn_type", &(ctx->rgnType),
"rgn type. 0:overlay, 1:overlayEx,2:cover,3:coverEx,4:mosaic,5:moscaiEx", NULL, 0, 0),
OPT_INTEGER('\0', "rgn_cnt", &(ctx->s32RgnCnt),
"rgn count. default(1),max:8", NULL, 0, 0),
OPT_INTEGER('\0', "en_rgn", &(ctx->bEnRgn),
"enable rgn. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "get_connect_info", &(ctx->bGetConnecInfo),
"get connect info. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "get_edid", &(ctx->bGetEdid),
"get edid. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "set_edid", &(ctx->bSetEdid),
"set edid. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "stream_codec", &(ctx->enCodecId),
"stream codec(0:disable 8:h264, 9:mjpeg, 12:h265). default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "bNoUseLibv4l2", &(ctx->bNoUseLibv4l2), "vi if no use libv4l2, 0: use, 1: no use."
"dafault(0)", NULL, 0, 0),
OPT_INTEGER('\0', "en_swcac", &(ctx->bEnSwcac),
"enable swcac. default(0)", NULL, 0, 0),
OPT_END(),
};
struct argparse argparse;
argparse_init(&argparse, options, usages, 0);
argparse_describe(&argparse, "\nselect a test case to run.",
"\nuse --help for details.");
argc = argparse_parse(&argparse, argc, argv);
if (!ctx->width || !ctx->height) {
argparse_usage(&argparse);
goto __FAILED2;
}
常用的命令配置函数初始化:
1.定义一个整数类型的命令行选项
OPT_INTEGER(short_option, long_option, pointer_to_variable, description, NULL, min_value, max_value)
short_option
:短选项字符(如'w'
)。long_option
:长选项字符串(如"width"
)。pointer_to_variable
:指向存储解析结果的变量的指针。description
:选项的描述信息,用于帮助信息。NULL
:通常为NULL
,保留参数。- 最后两位一般是0,0
2、用于定义一个字符串类型的命令行选项
OPT_STRING(short_option, long_option, pointer_to_variable, description, NULL, min_length, max_length)
short_option
:短选项字符(如'n'
)。long_option
:长选项字符串(如"name"
)。pointer_to_variable
:指向存储解析结果的字符数组或字符串指针。description
:选项的描述信息,用于帮助信息。NULL
:通常为NULL
,保留参数。- 最后两位一般是0,0
ps:如果short_option为'/0' ,说明该功能被禁用,只能长选项来配置参数
完整流程如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "argparse.h"
#include "test_common.h" // 假设包含 ctx 结构体定义和其他必要的头文件
// 定义命令行选项
struct argparse_option options[] = {
OPT_HELP(),
OPT_GROUP("basic options:"),
OPT_INTEGER('w', "width", &(ctx->width),
"set capture channel width(required, default 0)", NULL, 0, 0),
OPT_INTEGER('h', "height", &(ctx->height),
"set capture channel height(required, default 0)", NULL, 0, 0),
OPT_INTEGER('d', "dev", &(ctx->devId),
"set dev id(default 0)", NULL, 0, 0),
OPT_INTEGER('p', "pipe", &(ctx->pipeId),
"set pipe id(default 0)", NULL, 0, 0),
OPT_INTEGER('c', "channel", &(ctx->channelId),
"set channel id(default 1)", NULL, 0, 0),
OPT_INTEGER('l', "loopcount", &(ctx->loopCountSet),
"set capture frame count(default 100)", NULL, 0, 0),
OPT_INTEGER('C', "compressmode", &(ctx->enCompressMode),
"set capture compressmode(default 0; 0:MODE_NONE 1:AFBC_16x16)", NULL, 0, 0),
OPT_INTEGER('o', "output", &(ctx->stDebugFile.bCfg),
"save output file, file at /data/test_<devid>_<pipeid>_<channelid>.bin"
" (default 0; 0:no save 1:save)", NULL, 0, 0),
OPT_INTEGER('m', "mode", &(ctx->enMode),
"test mode(default 1; 0:vi get&release frame 1:vi bind one venc(h264) \n\t"
"2:vi bind two venc(h264)) 3:vi bind vpss bind venc \n\t"
"4:vi bind vo 5:multi vi 6:vi get&release stream \n\t"
"7:vi bind vdec bind vo", NULL, 0, 0),
OPT_INTEGER('t', "memorytype", &(ctx->stChnAttr.stIspOpt.enMemoryType),
"set the buf memorytype(required, default 4; 1:mmap(hdmiin/bt1120/sensor input) "
"2:userptr(invalid) 3:overlay(invalid) 4:dma(sensor))", NULL, 0, 0),
OPT_STRING('n', "name", &(ctx->aEntityName),
"set the entityName (required, default null;\n\t"
"rv1126 sensor:rkispp_m_bypass rkispp_scale0 rkispp_scale1 rkispp_scale2;\n\t"
"rv1126 hdmiin/bt1120/sensor:/dev/videox such as /dev/video19 /dev/video20;\n\t"
"rk356x hdmiin/bt1120/sensor:/dev/videox such as /dev/video0 /dev/video1", NULL, 0, 0),
OPT_INTEGER('D', "depth", &(ctx->stChnAttr.u32Depth),
"channel output depth, default{u32BufCount(not bind) or 0(bind venc/vpss/...)}", NULL, 0, 0),
OPT_INTEGER('f', "format", &(ctx->stChnAttr.enPixelFormat),
"set the format(default 0; 0:RK_FMT_YUV420SP 10:RK_FMT_YUV422_UYVY"
"131080:RK_FMT_RGB_BAYER_SBGGR_12BPP)", NULL, 0, 0),
OPT_INTEGER('\0', "freeze", &(ctx->bFreeze),
"freeze output(default 0; 0:disable freeze 1:enable freeze)", NULL, 0, 0),
OPT_INTEGER('\0', "src_rate", &(ctx->stChnAttr.stFrameRate.s32SrcFrameRate),
"src frame rate(default -1; -1:not control; other:1-max_fps<isp_out_fps>)", NULL, 0, 0),
OPT_INTEGER('\0', "dst_rate", &(ctx->stChnAttr.stFrameRate.s32DstFrameRate),
"dst frame rate(default -1; -1:not control; other:1-src_fps<src_rate>)", NULL, 0, 0),
OPT_INTEGER('\0', "buf_count", &(ctx->stChnAttr.stIspOpt.u32BufCount),
"out buf count, range[1-8] default(3)", NULL, 0, 0),
OPT_INTEGER('U', "user_pic", &(ctx->bUserPicEnabled),
"enable using user specify picture as vi input.", NULL, 0, 0),
OPT_INTEGER('\0', "rgn_type", &(ctx->rgnType),
"rgn type. 0:overlay, 1:overlayEx,2:cover,3:coverEx,4:mosaic,5:moscaiEx", NULL, 0, 0),
OPT_INTEGER('\0', "rgn_cnt", &(ctx->s32RgnCnt),
"rgn count. default(1),max:8", NULL, 0, 0),
OPT_INTEGER('\0', "en_rgn", &(ctx->bEnRgn),
"enable rgn. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "get_connect_info", &(ctx->bGetConnecInfo),
"get connect info. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "get_edid", &(ctx->bGetEdid),
"get edid. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "set_edid", &(ctx->bSetEdid),
"set edid. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "stream_codec", &(ctx->enCodecId),
"stream codec(0:disable 8:h264, 9:mjpeg, 12:h265). default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "bNoUseLibv4l2", &(ctx->bNoUseLibv4l2), "vi if no use libv4l2, 0: use, 1: no use."
"dafault(0)", NULL, 0, 0),
OPT_INTEGER('\0', "en_swcac", &(ctx->bEnSwcac),
"enable swcac. default(0)", NULL, 0, 0),
OPT_END(),
};
int parse_command_line_arguments(int argc, const char **argv, TEST_VI_CTX_S *ctx) {
struct argparse argparse;
const char *usages[] = {
"test_mpi_vi [options]",
NULL,
};
// 初始化 argparse
argparse_init(&argparse, options, usages, 0);
argparse_describe(&argparse, "\nselect a test case to run.",
"\nuse --help for details.");
// 解析命令行参数
int ret = argparse_parse(&argparse, argc, argv);
if (ret != 0) {
fprintf(stderr, "Error parsing command line arguments\n");
return -1;
}
// 验证必要参数
if (!ctx->width || !ctx->height) {
argparse_usage(&argparse);
return -1;
}
// 处理特殊选项(如 --help)
if (argparse_is_set(&argparse, 'h')) {
argparse_help(&argparse);
return 0;
}
// 其他必要的验证和初始化逻辑可以在这里添加
return 0;
}
int main(int argc, const char **argv) {
TEST_VI_CTX_S ctx = {0}; // 初始化上下文结构体
// 解析命令行参数
if (parse_command_line_arguments(argc, argv, &ctx) != 0) {
return EXIT_FAILURE;
}
// 继续主程序逻辑
// ...
return EXIT_SUCCESS;
}