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_decode.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 << "\nvideo_decode <in-file> <in-format> [options]\n\n"
00053 "Supported formats:\n"
00054 "\tH264\n"
00055 "\tH265\n\n"
00056 "OPTIONS:\n"
00057 "\t-h,--help Prints this text\n"
00058 "\t--dbg-level <level> Sets the debug level [Values 0-3]\n\n"
00059 "\t--stats Report profiling data for the app\n\n"
00060 "\t--disable-rendering Disable rendering\n"
00061 "\t--fullscreen Fullscreen playback [Default = disabled]\n"
00062 "\t-ww <width> Window width in pixels [Default = video-width]\n"
00063 "\t-wh <height> Window height in pixels [Default = video-height]\n"
00064 "\t-wx <x-offset> Horizontal window offset [Default = 0]\n"
00065 "\t-wy <y-offset> Vertical window offset [Default = 0]\n\n"
00066 "\t-fps <fps> Display rate in frames per second [Default = 30]\n\n"
00067 "\t-o <out-file> Write to output file\n\n"
00068 "\t-f <out_pixfmt> 1 NV12, 2 I420 [Default = 1]\n\n"
00069 "\t-sf <value> Skip frames while decoding [Default = 0]\n\n"
00070 "\t--input-nalu Input to the decoder will be nal units\n"
00071 "\t--input-chunks Input to the decoder will be a chunk of bytes [Default]\n\n"
00072 "\t--report-metadata Enable metadata reporting\n\n"
00073 "Allowed values for the skip-frames parameter:\n"
00074 "0 = Decode all frames\n"
00075 "1 = Skip non-reference frames\n"
00076 "2 = Decode only key frames\n\n";
00077 }
00078
00079 static uint32_t
00080 get_decoder_type(char *arg)
00081 {
00082 if (!strcmp(arg, "H264"))
00083 return V4L2_PIX_FMT_H264;
00084 if (!strcmp(arg, "H265"))
00085 return V4L2_PIX_FMT_H265;
00086 return 0;
00087 }
00088
00089 static int32_t
00090 get_dbg_level(char *arg)
00091 {
00092 int32_t log_level = atoi(arg);
00093
00094 if (log_level < 0)
00095 {
00096 cout << "Warning: invalid log level input, defaulting to setting 0" << endl;
00097 return 0;
00098 }
00099
00100 if (log_level > 3)
00101 {
00102 cout << "Warning: invalid log level input, defaulting to setting 3" << endl;
00103 return 3;
00104 }
00105
00106 return log_level;
00107 }
00108
00109 int
00110 parse_csv_args(context_t * ctx, int argc, char *argv[])
00111 {
00112 char **argp = argv;
00113 char *arg = *(++argp);
00114
00115 if (argc == 1 || (arg && (!strcmp(arg, "-h") || !strcmp(arg, "--help"))))
00116 {
00117 print_help();
00118 exit(EXIT_SUCCESS);
00119 }
00120
00121 CSV_PARSE_CHECK_ERROR(argc < 3, "Insufficient arguments");
00122
00123 ctx->in_file_path = strdup(*argp);
00124 CSV_PARSE_CHECK_ERROR(!ctx->in_file_path, "Input file not specified");
00125
00126 ctx->decoder_pixfmt = get_decoder_type(*(++argp));
00127 CSV_PARSE_CHECK_ERROR(ctx->decoder_pixfmt == 0,
00128 "Incorrect input format");
00129
00130 while ((arg = *(++argp)))
00131 {
00132 if (!strcmp(arg, "-o"))
00133 {
00134 argp++;
00135 CHECK_OPTION_VALUE(argp);
00136 ctx->out_file_path = strdup(*argp);
00137 CSV_PARSE_CHECK_ERROR(!ctx->out_file_path,
00138 "Output file not specified");
00139 }
00140 else if (!strcmp(arg, "-f"))
00141 {
00142 argp++;
00143 CHECK_OPTION_VALUE(argp);
00144 ctx->out_pixfmt = atoi(*argp);
00145 CSV_PARSE_CHECK_ERROR((ctx->out_pixfmt < 1 || ctx->out_pixfmt > 2),
00146 "format shoud be 1(NV12), 2(I420)");
00147 }
00148 else if (!strcmp(arg, "--stats"))
00149 {
00150 ctx->stats = true;
00151 }
00152 else if (!strcmp(arg, "--disable-rendering"))
00153 {
00154 ctx->disable_rendering = true;
00155 }
00156 else if (!strcmp(arg, "--disable-dpb"))
00157 {
00158 ctx->disable_dpb = true;
00159 }
00160 else if (!strcmp(arg, "--fullscreen"))
00161 {
00162 ctx->fullscreen = true;
00163 }
00164 else if (!strcmp(arg, "-wh"))
00165 {
00166 argp++;
00167 CHECK_OPTION_VALUE(argp);
00168 ctx->window_height = atoi(*argp);
00169 CSV_PARSE_CHECK_ERROR(ctx->window_height == 0,
00170 "Window height should be > 0");
00171 }
00172 else if (!strcmp(arg, "-ww"))
00173 {
00174 argp++;
00175 CHECK_OPTION_VALUE(argp);
00176 ctx->window_width = atoi(*argp);
00177 CSV_PARSE_CHECK_ERROR(ctx->window_width == 0,
00178 "Window width should be > 0");
00179 }
00180 else if (!strcmp(arg, "-wx"))
00181 {
00182 argp++;
00183 CHECK_OPTION_VALUE(argp);
00184 ctx->window_x = atoi(*argp);
00185 }
00186 else if (!strcmp(arg, "-wy"))
00187 {
00188 argp++;
00189 CHECK_OPTION_VALUE(argp);
00190 ctx->window_y = atoi(*argp);
00191 }
00192 else if (!strcmp(arg, "-fps"))
00193 {
00194 argp++;
00195 CHECK_OPTION_VALUE(argp);
00196 ctx->fps = atof(*argp);
00197 CSV_PARSE_CHECK_ERROR(ctx->fps == 0, "FPS should be > 0");
00198 }
00199 else if (!strcmp(arg, "--input-nalu"))
00200 {
00201 ctx->input_nalu = true;
00202 }
00203 else if (!strcmp(arg, "--input-chunks"))
00204 {
00205 ctx->input_nalu = false;
00206 }
00207 else if (!strcmp(arg, "--report-metadata"))
00208 {
00209 ctx->enable_metadata = true;
00210 }
00211 else if (!strcmp(arg, "-sf"))
00212 {
00213 argp++;
00214 CHECK_OPTION_VALUE(argp);
00215 ctx->skip_frames = (enum v4l2_skip_frames_type) atoi(*argp);
00216 CSV_PARSE_CHECK_ERROR(
00217 (ctx->skip_frames > V4L2_SKIP_FRAMES_TYPE_DECODE_IDR_ONLY ||
00218 ctx->skip_frames < V4L2_SKIP_FRAMES_TYPE_NONE),
00219 "Unsupported values for skip frames: " << *argp);
00220 }
00221 else if (!strcmp(arg, "--dbg-level"))
00222 {
00223 argp++;
00224 CHECK_OPTION_VALUE(argp);
00225 log_level = get_dbg_level(*argp);
00226 }
00227 else if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
00228 {
00229 print_help();
00230 exit(EXIT_SUCCESS);
00231 }
00232 else
00233 {
00234 CSV_PARSE_CHECK_ERROR(ctx->out_file_path, "Unknown option " << arg);
00235 }
00236 }
00237
00238 return 0;
00239
00240 error:
00241 print_help();
00242 return -1;
00243 }