video_decode_csvparser.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of NVIDIA CORPORATION nor the names of its
  13. * contributors may be used to endorse or promote products derived
  14. * from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  20. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  21. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  22. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  23. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  24. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #include <iostream>
  29. #include <cstdlib>
  30. #include <cstring>
  31. #include "video_decode.h"
  32. #define CHECK_OPTION_VALUE(argp) if(!*argp || (*argp)[0] == '-') \
  33. { \
  34. cerr << "Error: value not specified for option " << arg << endl; \
  35. goto error; \
  36. }
  37. #define CSV_PARSE_CHECK_ERROR(condition, str) \
  38. if (condition) {\
  39. cerr << "Error: " << str << endl; \
  40. goto error; \
  41. }
  42. using namespace std;
  43. static void
  44. print_help(void)
  45. {
  46. cerr << "\nvideo_decode <in-format> [options] <in-file>\n\n"
  47. "Supported formats:\n"
  48. "\tVP9\n"
  49. "\tVP8\n"
  50. "\tH264\n"
  51. "\tH265\n"
  52. "\tMPEG2\n"
  53. "\tMPEG4\n\n"
  54. "OPTIONS:\n"
  55. "\t-h,--help Prints this text\n"
  56. "\t--dbg-level <level> Sets the debug level [Values 0-3]\n\n"
  57. "\t--stats Report profiling data for the app\n\n"
  58. "\tNOTE: this should not be used alongside -o option as it decreases the FPS value shown in --stats\n"
  59. "\t--disable-rendering Disable rendering\n"
  60. "\t--max-perf Enable maximum Performance \n"
  61. "\tNOTE: this should be set only for platform T194 or above\n"
  62. "\t--fullscreen Fullscreen playback [Default = disabled]\n"
  63. "\t-ww <width> Window width in pixels [Default = video-width]\n"
  64. "\t-wh <height> Window height in pixels [Default = video-height]\n"
  65. "\t-loop <count> Playback in a loop.[count = 1,2,...,n times looping , 0 = infinite looping]\n"
  66. "\t-queue [<file1> <file2> ....] Files are played in a queue manner\n"
  67. "\tNOTE: -queue should be the last option mentioned in the command line no other option should be mentioned after that.\n"
  68. "\t-wx <x-offset> Horizontal window offset [Default = 0]\n"
  69. "\t-wy <y-offset> Vertical window offset [Default = 0]\n\n"
  70. "\t-fps <fps> Display rate in frames per second [Default = 30]\n\n"
  71. "\t-o <out-file> Write to output file\n\n"
  72. "\tNOTE: Not to be used along-side -loop and -queue option.\n"
  73. "\t-f <out_pixfmt> 1 NV12, 2 I420, 3 NV16, 4 NV24 [Default = 1]\n\n"
  74. "\t-sf <value> Skip frames while decoding [Default = 0]\n"
  75. "\tAllowed values for the skip-frames parameter:\n"
  76. "\t0 = Decode all frames\n"
  77. "\t1 = Skip non-reference frames\n"
  78. "\t2 = Decode only key frames\n\n"
  79. "\t--input-nalu Input to the decoder will be nal units\n"
  80. "\t--input-chunks Input to the decoder will be a chunk of bytes [Default]\n\n"
  81. "\t--copy-timestamp <st> <fps> Enable copy timestamp with start timestamp(st) in seconds for decode fps(fps) (for input-nalu mode)\n"
  82. "\tNOTE: copy-timestamp used to demonstrate how timestamp can be associated with an individual H264/H265 frame to achieve video-synchronization.\n"
  83. "\t currenly only supported for H264 & H265 video encode using MM APIs and is only for demonstration purpose.\n"
  84. "\t--report-metadata Enable metadata reporting\n\n"
  85. "\t--blocking-mode <val> Set blocking mode, 0 is non-blocking, 1 for blocking (Default) \n\n"
  86. "\t--report-input-metadata Enable metadata reporting for input header parsing error\n\n"
  87. "\t-v4l2-memory-out-plane <num> Specify memory type to be used on Output Plane [1 = V4L2_MEMORY_MMAP, 2 = V4L2_MEMORY_USERPTR], Default = V4L2_MEMORY_MMAP\n\n"
  88. "\t-v4l2-memory-cap-plane <num> Specify memory type to be used on Capture Plane [1 = V4L2_MEMORY_MMAP, 2 = V4L2_MEMORY_DMABUF], Default = V4L2_MEMORY_DMABUF\n\n"
  89. "\t-s <loop-count> Stress test [Default = 1]\n\n"
  90. "\t-extra_cap_plane_buffer <num> Specify extra capture plane buffers (Default=1, MAX=32) to be allocated\n"
  91. #ifndef USE_NVBUF_TRANSFORM_API
  92. "\t--do-yuv-rescale Rescale decoded YUV from full range to limited range\n\n"
  93. #endif
  94. ;
  95. }
  96. static uint32_t
  97. get_decoder_type(char *arg)
  98. {
  99. if (!strcmp(arg, "H264"))
  100. return V4L2_PIX_FMT_H264;
  101. if (!strcmp(arg, "H265"))
  102. return V4L2_PIX_FMT_H265;
  103. if (!strcmp(arg, "VP9"))
  104. return V4L2_PIX_FMT_VP9;
  105. if (!strcmp(arg, "VP8"))
  106. return V4L2_PIX_FMT_VP8;
  107. if (!strcmp(arg, "MPEG2"))
  108. return V4L2_PIX_FMT_MPEG2;
  109. if (!strcmp(arg, "MPEG4"))
  110. return V4L2_PIX_FMT_MPEG4;
  111. return 0;
  112. }
  113. static int32_t
  114. get_dbg_level(char *arg)
  115. {
  116. int32_t log_level = atoi(arg);
  117. if (log_level < 0)
  118. {
  119. cout << "Warning: invalid log level input, defaulting to setting 0" << endl;
  120. return 0;
  121. }
  122. if (log_level > 3)
  123. {
  124. cout << "Warning: invalid log level input, defaulting to setting 3" << endl;
  125. return 3;
  126. }
  127. return log_level;
  128. }
  129. int
  130. parse_csv_args(context_t * ctx, int argc, char *argv[])
  131. {
  132. char **argp = argv;
  133. char *arg = *(++argp);
  134. if (argc == 1 || (arg && (!strcmp(arg, "-h") || !strcmp(arg, "--help"))))
  135. {
  136. print_help();
  137. exit(EXIT_SUCCESS);
  138. }
  139. CSV_PARSE_CHECK_ERROR(argc < 3, "Insufficient arguments");
  140. ctx->decoder_pixfmt = get_decoder_type(*(argp));
  141. CSV_PARSE_CHECK_ERROR(ctx->decoder_pixfmt == 0,
  142. "Incorrect input format");
  143. while ((arg = *(++argp)))
  144. {
  145. if (!strcmp(arg, "-o"))
  146. {
  147. argp++;
  148. CHECK_OPTION_VALUE(argp);
  149. ctx->out_file_path = strdup(*argp);
  150. CSV_PARSE_CHECK_ERROR(!ctx->out_file_path,
  151. "Output file not specified");
  152. }
  153. else if (!strcmp(arg, "-f"))
  154. {
  155. argp++;
  156. CHECK_OPTION_VALUE(argp);
  157. ctx->out_pixfmt = atoi(*argp);
  158. CSV_PARSE_CHECK_ERROR((ctx->out_pixfmt < 1 || ctx->out_pixfmt > 4),
  159. "format shoud be 1(NV12), 2(I420), 3(NV16), 4(NV24)");
  160. }
  161. else if (!strcmp(arg, "--stats"))
  162. {
  163. ctx->stats = true;
  164. }
  165. else if (!strcmp(arg, "--disable-rendering"))
  166. {
  167. ctx->disable_rendering = true;
  168. }
  169. else if (!strcmp(arg, "--disable-dpb"))
  170. {
  171. ctx->disable_dpb = true;
  172. }
  173. else if (!strcmp(arg, "--fullscreen"))
  174. {
  175. ctx->fullscreen = true;
  176. }
  177. else if (!strcmp(arg, "-wh"))
  178. {
  179. argp++;
  180. CHECK_OPTION_VALUE(argp);
  181. ctx->window_height = atoi(*argp);
  182. CSV_PARSE_CHECK_ERROR(ctx->window_height == 0,
  183. "Window height should be > 0");
  184. }
  185. else if (!strcmp(arg, "-ww"))
  186. {
  187. argp++;
  188. CHECK_OPTION_VALUE(argp);
  189. ctx->window_width = atoi(*argp);
  190. CSV_PARSE_CHECK_ERROR(ctx->window_width == 0,
  191. "Window width should be > 0");
  192. }
  193. else if (!strcmp(arg, "-wx"))
  194. {
  195. argp++;
  196. CHECK_OPTION_VALUE(argp);
  197. ctx->window_x = atoi(*argp);
  198. }
  199. else if (!strcmp(arg, "-wy"))
  200. {
  201. argp++;
  202. CHECK_OPTION_VALUE(argp);
  203. ctx->window_y = atoi(*argp);
  204. }
  205. else if (!strcmp(arg, "-fps"))
  206. {
  207. argp++;
  208. CHECK_OPTION_VALUE(argp);
  209. ctx->fps = atof(*argp);
  210. CSV_PARSE_CHECK_ERROR(ctx->fps == 0, "FPS should be > 0");
  211. }
  212. else if (!strcmp(arg, "--input-nalu"))
  213. {
  214. ctx->input_nalu = true;
  215. }
  216. else if (!strcmp(arg, "--input-chunks"))
  217. {
  218. ctx->input_nalu = false;
  219. }
  220. else if (!strcmp(arg, "--copy-timestamp"))
  221. {
  222. argp++;
  223. CHECK_OPTION_VALUE(argp);
  224. ctx->start_ts = atoi(*argp);
  225. CSV_PARSE_CHECK_ERROR(ctx->start_ts < 0, "start timestamp should be >= 0");
  226. argp++;
  227. CHECK_OPTION_VALUE(argp);
  228. ctx->dec_fps = atof(*argp);
  229. CSV_PARSE_CHECK_ERROR(ctx->dec_fps <= 0, "decode fps should be > 0");
  230. ctx->copy_timestamp = true;
  231. }
  232. else if (!strcmp(arg, "--report-metadata"))
  233. {
  234. ctx->enable_metadata = true;
  235. }
  236. else if (!strcmp(arg, "--report-input-metadata"))
  237. {
  238. ctx->enable_input_metadata = true;
  239. }
  240. else if (!strcmp(arg, "-s"))
  241. {
  242. argp++;
  243. CHECK_OPTION_VALUE(argp);
  244. ctx->stress_test = atoi(*argp);
  245. CSV_PARSE_CHECK_ERROR(ctx->stress_test <= 0,
  246. "stress times should be bigger than 0");
  247. }
  248. else if(!strcmp(arg, "-v4l2-memory-out-plane"))
  249. {
  250. argp++;
  251. CHECK_OPTION_VALUE(argp);
  252. ctx->output_plane_mem_type = (enum v4l2_memory) atoi(*argp);
  253. CSV_PARSE_CHECK_ERROR(
  254. (ctx->output_plane_mem_type > V4L2_MEMORY_USERPTR ||
  255. ctx->output_plane_mem_type < V4L2_MEMORY_MMAP),
  256. "Unsupported v4l2 memory type: " << *argp);
  257. }
  258. else if(!strcmp(arg, "--max-perf"))
  259. {
  260. ctx->max_perf = 1;
  261. }
  262. else if(!strcmp(arg, "-extra_cap_plane_buffer"))
  263. {
  264. argp++;
  265. CHECK_OPTION_VALUE(argp);
  266. ctx->extra_cap_plane_buffer = atoi(*argp);;
  267. CSV_PARSE_CHECK_ERROR((ctx->extra_cap_plane_buffer < 1 || ctx->extra_cap_plane_buffer > 32),
  268. "extra capture plane buffer should be greater than 0 & less than 33");
  269. }
  270. else if (!strcmp(arg, "-sf"))
  271. {
  272. argp++;
  273. CHECK_OPTION_VALUE(argp);
  274. ctx->skip_frames = (enum v4l2_skip_frames_type) atoi(*argp);
  275. CSV_PARSE_CHECK_ERROR(
  276. (ctx->skip_frames > V4L2_SKIP_FRAMES_TYPE_DECODE_IDR_ONLY ||
  277. ctx->skip_frames < V4L2_SKIP_FRAMES_TYPE_NONE),
  278. "Unsupported values for skip frames: " << *argp);
  279. }
  280. else if (!strcmp(arg, "--dbg-level"))
  281. {
  282. argp++;
  283. CHECK_OPTION_VALUE(argp);
  284. log_level = get_dbg_level(*argp);
  285. }
  286. else if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
  287. {
  288. print_help();
  289. exit(EXIT_SUCCESS);
  290. }
  291. else if (!strcmp(arg, "-loop"))
  292. {
  293. ctx->bLoop = true;
  294. argp++;
  295. CHECK_OPTION_VALUE(argp);
  296. ctx->loop_count = atoi(*argp);
  297. }
  298. else if (!strcmp(arg, "-queue"))
  299. {
  300. ctx->bQueue = true;
  301. break;
  302. }
  303. else if (!strcmp(arg, "-v4l2-memory-cap-plane"))
  304. {
  305. argp++;
  306. CHECK_OPTION_VALUE(argp);
  307. int num = (uint32_t) atoi(*argp);
  308. switch(num)
  309. {
  310. case 1 :ctx->capture_plane_mem_type = V4L2_MEMORY_MMAP;
  311. break;
  312. case 2 :ctx->capture_plane_mem_type = V4L2_MEMORY_DMABUF;
  313. break;
  314. }
  315. CSV_PARSE_CHECK_ERROR(!(num > 0 && num < 3),
  316. "Memory type selection should be > 0 and < 3");
  317. }
  318. else if (!strcmp(arg, "--blocking-mode"))
  319. {
  320. argp++;
  321. CHECK_OPTION_VALUE(argp);
  322. ctx->blocking_mode = atoi(*argp);
  323. }
  324. #ifndef USE_NVBUF_TRANSFORM_API
  325. else if (!strcmp(arg, "--do-yuv-rescale"))
  326. {
  327. ctx->rescale_method = V4L2_YUV_RESCALE_EXT_TO_STD;
  328. }
  329. #endif
  330. else
  331. {
  332. CSV_PARSE_CHECK_ERROR(ctx->in_file_path, "Unknown option " << arg);
  333. }
  334. }
  335. if(ctx->bQueue)
  336. {
  337. ctx->file_count=0;
  338. while((arg = *(++argp)))
  339. {
  340. ctx->file_count++;
  341. }
  342. int i = ctx->file_count+1;
  343. while(i--)
  344. {
  345. --argp;
  346. }
  347. ctx->in_file_path = (char **)malloc(sizeof(char *)*ctx->file_count);
  348. i=0;
  349. while((arg = *(++argp)))
  350. {
  351. ctx->in_file_path[i++] = strdup(*argp);
  352. CSV_PARSE_CHECK_ERROR(!ctx->in_file_path, "Input file not specified");
  353. }
  354. }
  355. else
  356. {
  357. ctx->in_file_path = (char **)malloc(sizeof(char *)*1);
  358. ctx->in_file_path[0] = strdup(*--argp);
  359. CSV_PARSE_CHECK_ERROR(!ctx->in_file_path, "Input file not specified");
  360. }
  361. return 0;
  362. error:
  363. print_help();
  364. return -1;
  365. }