00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030 #include <cstdlib>
00031 #include <cstring>
00032
00033 #include "video_convert.h"
00034
00035 #define CHECK_OPTION_VALUE(argp) if(!*argp || (*argp)[0] == '-') \
00036 { \
00037 cerr << "Error: value not specified for option " << arg << endl; \
00038 goto error; \
00039 }
00040
00041 #define CSV_PARSE_CHECK_ERROR(condition, str) \
00042 if (condition) {\
00043 cerr << "Error: " << str << endl; \
00044 goto error; \
00045 }
00046
00047 using namespace std;
00048
00049 static void
00050 print_help(void)
00051 {
00052 cerr <<
00053 "\nvideo-convert <in-file> <in-width> <in-height> <in-format> <out-file> <out-width> <out-height> <out-format> [OPTIONS]\n\n"
00054 "Supported formats:\n"
00055 "\tYUV420M\n"
00056 "\tYVU420M\n"
00057 "\tNV12M\n"
00058 "\tYUV444M\n"
00059 "\tYUV422M\n"
00060 "\tYUYV\n"
00061 "\tYVYU\n"
00062 "\tUYVY\n"
00063 "\tVYUY\n"
00064 "\tABGR32\n"
00065 "\tXRGB32\n"
00066 "\tGREY\n\n"
00067 "OPTIONS:\n"
00068 "\t-h,--help Prints this text\n"
00069 "\t--dbg-level <level> Sets the debug level [Values 0-3]\n\n"
00070 "\t--input-raw Input will be raw buffer\n"
00071 "\t--input-nvpl Input will be NV PL buffer [Default]\n"
00072 "\t--input-nvbl Input will be NV BL buffer\n"
00073 "\t--output-raw Output will be raw buffer\n"
00074 "\t--output-nvpl Output will be NV PL buffer [Default]\n"
00075 "\t--output-nvbl Output will be NV BL buffer\n\n"
00076 "\t-cr <left> <top> <width> <height> Set the cropping rectangle [Default = 0 0 0 0]\n"
00077 "\t-fm <method> Flip method to use [Default = 0]\n"
00078 "\t-im <method> Interpolation method to use [Default = 1]\n"
00079 "\t-tnr <algo> TNR algorithm to use [Default = 0]\n\n"
00080 "NOTE: TNR is supported for YUV420M, NV12M, YUYV and UYVY formats\n\n"
00081 "Allowed values for flip method:\n"
00082 "0 = Identity(no rotation) 1 = 90 degree counter-clockwise rotation\n"
00083 "2 = 180 degree rotation 3 = 90 degree clockwise rotation\n"
00084 "4 = Horizontal flip 5 = Flip across upper right/lower left diagonal\n"
00085 "6 = Vertical flip 7 = Flip across upper left/lower right diagonal\n\n"
00086 "Allowed values for interpolation method:\n"
00087 "1 = nearest 2 = linear\n"
00088 "3 = smart 4 = bilinear\n\n"
00089 "Allowed values for tnr:\n"
00090 "0 = Original 1 = Outdoor low light\n"
00091 "2 = Outdoor medium light 3 = Outdoor high light\n"
00092 "4 = Indoor low light 5 = Indoor medium light\n"
00093 "6 = Indoor high light\n\n";
00094 }
00095
00096 static uint32_t
00097 get_pixelformat(char *arg)
00098 {
00099 if (!strcmp(arg, "YUV420M"))
00100 return V4L2_PIX_FMT_YUV420M;
00101
00102 if (!strcmp(arg, "YVU420M"))
00103 return V4L2_PIX_FMT_YVU420M;
00104
00105 if (!strcmp(arg, "NV12M"))
00106 return V4L2_PIX_FMT_NV12M;
00107
00108 if (!strcmp(arg, "YUV444M"))
00109 return V4L2_PIX_FMT_YUV444M;
00110
00111 if (!strcmp(arg, "YUV422M"))
00112 return V4L2_PIX_FMT_YUV422M;
00113
00114 if (!strcmp(arg, "YUYV"))
00115 return V4L2_PIX_FMT_YUYV;
00116
00117 if (!strcmp(arg, "YVYU"))
00118 return V4L2_PIX_FMT_YVYU;
00119
00120 if (!strcmp(arg, "UYVY"))
00121 return V4L2_PIX_FMT_UYVY;
00122
00123 if (!strcmp(arg, "VYUY"))
00124 return V4L2_PIX_FMT_VYUY;
00125
00126 if (!strcmp(arg, "ABGR32"))
00127 return V4L2_PIX_FMT_ABGR32;
00128
00129 if (!strcmp(arg, "XRGB32"))
00130 return V4L2_PIX_FMT_XRGB32;
00131
00132 if (!strcmp(arg, "GREY"))
00133 return V4L2_PIX_FMT_GREY;
00134
00135 return 0;
00136 }
00137
00138 static int32_t
00139 get_dbg_level(char *arg)
00140 {
00141 int32_t log_level = atoi(arg);
00142
00143 if (log_level < 0)
00144 {
00145 cout<<"log level too small, set to 0"<<endl;
00146 return 0;
00147 }
00148
00149 if (log_level > 3)
00150 {
00151 cout<<"log level too high, set to 3"<<endl;
00152 return 3;
00153 }
00154
00155 return log_level;
00156 }
00157
00158 int
00159 parse_csv_args(context_t * ctx, int argc, char *argv[])
00160 {
00161 char **argp = argv;
00162 char *arg = *(++argp);
00163
00164 if (argc == 1 || (arg && (!strcmp(arg, "-h") || !strcmp(arg, "--help"))))
00165 {
00166 print_help();
00167 exit(EXIT_SUCCESS);
00168 }
00169
00170 CSV_PARSE_CHECK_ERROR(argc < 9, "Insufficient arguments");
00171
00172 ctx->in_file_path = strdup(*argp);
00173 CSV_PARSE_CHECK_ERROR(!ctx->in_file_path, "Input file not specified");
00174
00175 ctx->in_width = atoi(*(++argp));
00176 CSV_PARSE_CHECK_ERROR(ctx->in_width == 0, "Input width should be > 0");
00177
00178 ctx->in_height = atoi(*(++argp));
00179 CSV_PARSE_CHECK_ERROR(ctx->in_height == 0, "Input height should be > 0");
00180
00181 ctx->in_pixfmt = get_pixelformat(*(++argp));
00182 CSV_PARSE_CHECK_ERROR(ctx->in_pixfmt == 0, "Incorrect input format");
00183
00184 ctx->out_file_path = strdup(*(++argp));
00185 CSV_PARSE_CHECK_ERROR(!ctx->out_file_path, "Output file not specified");
00186
00187 ctx->out_width = atoi(*(++argp));
00188 CSV_PARSE_CHECK_ERROR(ctx->out_width == 0, "Output width should be > 0");
00189
00190 ctx->out_height = atoi(*(++argp));
00191 CSV_PARSE_CHECK_ERROR(ctx->out_height == 0, "Output height should be > 0");
00192
00193 ctx->out_pixfmt = get_pixelformat(*(++argp));
00194 CSV_PARSE_CHECK_ERROR(ctx->out_pixfmt == 0, "Incorrect output format");
00195
00196 while ((arg = *(++argp)))
00197 {
00198 if (!strcmp(arg, "--dbg-level"))
00199 {
00200 argp++;
00201 CHECK_OPTION_VALUE(argp);
00202 log_level = get_dbg_level(*argp);
00203 }
00204 else if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
00205 {
00206 print_help();
00207 exit(EXIT_SUCCESS);
00208 }
00209 else if (!strcmp(arg, "--input-raw"))
00210 {
00211 ctx->in_buftype = BUF_TYPE_RAW;
00212 }
00213 else if (!strcmp(arg, "--input-nvpl"))
00214 {
00215 ctx->in_buftype = BUF_TYPE_NVPL;
00216 }
00217 else if (!strcmp(arg, "--input-nvbl"))
00218 {
00219 ctx->in_buftype = BUF_TYPE_NVBL;
00220 }
00221 else if (!strcmp(arg, "--output-raw"))
00222 {
00223 ctx->out_buftype = BUF_TYPE_RAW;
00224 }
00225 else if (!strcmp(arg, "--output-nvpl"))
00226 {
00227 ctx->out_buftype = BUF_TYPE_NVPL;
00228 }
00229 else if (!strcmp(arg, "--output-nvbl"))
00230 {
00231 ctx->out_buftype = BUF_TYPE_NVBL;
00232 }
00233 else if (!strcmp(arg, "-fm"))
00234 {
00235 argp++;
00236 CHECK_OPTION_VALUE(argp);
00237 ctx->flip_method = (enum v4l2_flip_method) atoi(*argp);
00238 CSV_PARSE_CHECK_ERROR((ctx->flip_method > V4L2_FLIP_METHOD_TRANS ||
00239 ctx->flip_method < V4L2_FLIP_METHOD_IDENTITY),
00240 "Unsupported value for flip-method: " << *argp);
00241 }
00242 else if (!strcmp(arg, "-im"))
00243 {
00244 argp++;
00245 CHECK_OPTION_VALUE(argp);
00246 ctx->interpolation_method =
00247 (enum v4l2_interpolation_method) atoi(*argp);
00248 CSV_PARSE_CHECK_ERROR(
00249 (ctx->interpolation_method < V4L2_INTERPOLATION_NEAREST ||
00250 ctx->interpolation_method > V4L2_INTERPOLATION_BILINEAR),
00251 "Unsupported value for interpolation-method: " << *argp);
00252 }
00253 else if (!strcmp(arg, "-tnr"))
00254 {
00255 argp++;
00256 CHECK_OPTION_VALUE(argp);
00257 ctx->tnr_algorithm = (enum v4l2_tnr_algorithm) atoi(*argp);
00258 CSV_PARSE_CHECK_ERROR(
00259 (ctx->tnr_algorithm > V4L2_TNR_ALGO_INDOOR_HIGH_LIGHT ||
00260 ctx->tnr_algorithm < V4L2_TNR_ALGO_ORIGINAL),
00261 "Unsupported value for tnr algorithm: " << *argp);
00262 }
00263 else if (!strcmp(arg, "-cr"))
00264 {
00265 argp++;
00266 CHECK_OPTION_VALUE(argp);
00267 ctx->crop_rect.left = atoi(*argp);
00268 CSV_PARSE_CHECK_ERROR((ctx->crop_rect.left < 0 ||
00269 ctx->crop_rect.left >= (int32_t) ctx->in_width),
00270 "Crop left param out of bounds");
00271
00272 argp++;
00273 CHECK_OPTION_VALUE(argp);
00274 ctx->crop_rect.top = atoi(*argp);
00275 CSV_PARSE_CHECK_ERROR((ctx->crop_rect.top < 0 ||
00276 ctx->crop_rect.top >= (int32_t) ctx->in_height),
00277 "Crop top param out of bounds");
00278
00279 argp++;
00280 CHECK_OPTION_VALUE(argp);
00281 ctx->crop_rect.width = atoi(*argp);
00282 CSV_PARSE_CHECK_ERROR((ctx->crop_rect.width <= 0 ||
00283 ctx->crop_rect.left + ctx->crop_rect.width >
00284 ctx->in_width),
00285 "Crop width param out of bounds");
00286
00287 argp++;
00288 CHECK_OPTION_VALUE(argp);
00289 ctx->crop_rect.height = atoi(*argp);
00290 CSV_PARSE_CHECK_ERROR((ctx->crop_rect.height <= 0 ||
00291 ctx->crop_rect.top + ctx->crop_rect.height >
00292 ctx->in_height),
00293 "Crop height param out of bounds");
00294 }
00295 else
00296 {
00297 CSV_PARSE_CHECK_ERROR(ctx->out_file_path, "Unknown option " << arg);
00298 }
00299 CSV_PARSE_CHECK_ERROR(ctx->tnr_algorithm >= V4L2_TNR_ALGO_ORIGINAL &&
00300 ! (ctx->out_pixfmt == V4L2_PIX_FMT_YUV420M ||
00301 ctx->out_pixfmt == V4L2_PIX_FMT_YUYV ||
00302 ctx->out_pixfmt == V4L2_PIX_FMT_UYVY ||
00303 ctx->out_pixfmt == V4L2_PIX_FMT_NV12M),
00304 "Unsupported format for TNR");
00305 }
00306
00307 return 0;
00308
00309 error:
00310 print_help();
00311 return -1;
00312 }