NvEncoderCLIOptions.h 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /*
  2. * Copyright 2017-2020 NVIDIA Corporation. All rights reserved.
  3. *
  4. * Please refer to the NVIDIA end user license agreement (EULA) associated
  5. * with this source code for terms and conditions that govern your use of
  6. * this software. Any use, reproduction, disclosure, or distribution of
  7. * this software and related documentation outside the terms of the EULA
  8. * is strictly prohibited.
  9. *
  10. */
  11. #pragma once
  12. #include <vector>
  13. #include <string>
  14. #include <algorithm>
  15. #include <stdexcept>
  16. #include <sstream>
  17. #include <iterator>
  18. #include <cstring>
  19. #include <functional>
  20. #include "Logger.h"
  21. extern simplelogger::Logger *logger;
  22. #ifndef _WIN32
  23. inline bool operator==(const GUID &guid1, const GUID &guid2) {
  24. return !memcmp(&guid1, &guid2, sizeof(GUID));
  25. }
  26. inline bool operator!=(const GUID &guid1, const GUID &guid2) {
  27. return !(guid1 == guid2);
  28. }
  29. #endif
  30. /*
  31. * Helper class for parsing generic encoder options and preparing encoder
  32. * initialization parameters. This class also provides some utility methods
  33. * which generate verbose descriptions of the provided set of encoder
  34. * initialization parameters.
  35. */
  36. class NvEncoderInitParam {
  37. public:
  38. NvEncoderInitParam(const char *szParam = "",
  39. std::function<void(NV_ENC_INITIALIZE_PARAMS *pParams)> *pfuncInit = NULL, bool _bLowLatency = false)
  40. : strParam(szParam), bLowLatency(_bLowLatency)
  41. {
  42. if (pfuncInit) {
  43. funcInit = *pfuncInit;
  44. }
  45. std::transform(strParam.begin(), strParam.end(), strParam.begin(), tolower);
  46. std::istringstream ss(strParam);
  47. tokens = std::vector<std::string> {
  48. std::istream_iterator<std::string>(ss),
  49. std::istream_iterator<std::string>()
  50. };
  51. for (unsigned i = 0; i < tokens.size(); i++)
  52. {
  53. if (tokens[i] == "-codec" && ++i != tokens.size())
  54. {
  55. ParseString("-codec", tokens[i], vCodec, szCodecNames, &guidCodec);
  56. continue;
  57. }
  58. if (tokens[i] == "-preset" && ++i != tokens.size()) {
  59. ParseString("-preset", tokens[i], vPreset, szPresetNames, &guidPreset);
  60. continue;
  61. }
  62. if (tokens[i] == "-tuninginfo" && ++i != tokens.size())
  63. {
  64. ParseString("-tuninginfo", tokens[i], vTuningInfo, szTuningInfoNames, &m_TuningInfo);
  65. continue;
  66. }
  67. }
  68. }
  69. virtual ~NvEncoderInitParam() {}
  70. virtual bool IsCodecH264() {
  71. return GetEncodeGUID() == NV_ENC_CODEC_H264_GUID;
  72. }
  73. virtual bool IsCodecHEVC() {
  74. return GetEncodeGUID() == NV_ENC_CODEC_HEVC_GUID;
  75. }
  76. std::string GetHelpMessage(bool bMeOnly = false, bool bUnbuffered = false, bool bHide444 = false, bool bOutputInVidMem = false)
  77. {
  78. std::ostringstream oss;
  79. if (bOutputInVidMem && bMeOnly)
  80. {
  81. oss << "-codec Codec: " << "h264" << std::endl;
  82. }
  83. else
  84. {
  85. oss << "-codec Codec: " << szCodecNames << std::endl;
  86. }
  87. oss << "-preset Preset: " << szPresetNames << std::endl
  88. << "-profile H264: " << szH264ProfileNames;
  89. if (bOutputInVidMem && bMeOnly)
  90. {
  91. oss << std::endl;
  92. }
  93. else
  94. {
  95. oss << "; HEVC: " << szHevcProfileNames << std::endl;
  96. }
  97. if (!bMeOnly)
  98. {
  99. if (bLowLatency == false)
  100. oss << "-tuninginfo TuningInfo: " << szTuningInfoNames << std::endl;
  101. else
  102. oss << "-tuninginfo TuningInfo: " << szLowLatencyTuningInfoNames << std::endl;
  103. oss << "-multipass Multipass: " << szMultipass << std::endl;
  104. }
  105. if (!bHide444 && !bLowLatency)
  106. {
  107. oss << "-444 (Only for RGB input) YUV444 encode" << std::endl;
  108. }
  109. if (bMeOnly) return oss.str();
  110. oss << "-rc Rate control mode: " << szRcModeNames << std::endl
  111. << "-fps Frame rate" << std::endl
  112. << "-gop Length of GOP (Group of Pictures)" << std::endl;
  113. if (!bUnbuffered && !bLowLatency)
  114. {
  115. oss << "-bf Number of consecutive B-frames" << std::endl;
  116. }
  117. oss << "-bitrate Average bit rate, can be in unit of 1, K, M" << std::endl
  118. << "-maxbitrate Max bit rate, can be in unit of 1, K, M" << std::endl
  119. << "-vbvbufsize VBV buffer size in bits, can be in unit of 1, K, M" << std::endl
  120. << "-vbvinit VBV initial delay in bits, can be in unit of 1, K, M" << std::endl;
  121. if (!bLowLatency)
  122. {
  123. oss << "-aq Enable spatial AQ and set its stength (range 1-15, 0-auto)" << std::endl
  124. << "-temporalaq (No value) Enable temporal AQ" << std::endl;
  125. }
  126. if (!bUnbuffered && !bLowLatency)
  127. {
  128. oss << "-lookahead Maximum depth of lookahead (range 0-(31 - number of B frames))" << std::endl;
  129. }
  130. oss << "-cq Target constant quality level for VBR mode (range 1-51, 0-auto)" << std::endl
  131. << "-qmin Min QP value" << std::endl
  132. << "-qmax Max QP value" << std::endl
  133. << "-initqp Initial QP value" << std::endl;
  134. if (!bLowLatency)
  135. {
  136. oss << "-constqp QP value for constqp rate control mode" << std::endl
  137. << "Note: QP value can be in the form of qp_of_P_B_I or qp_P,qp_B,qp_I (no space)" << std::endl;
  138. }
  139. if (bUnbuffered && !bLowLatency)
  140. {
  141. oss << "Note: Options -bf and -lookahead are unavailable for this app" << std::endl;
  142. }
  143. return oss.str();
  144. }
  145. /**
  146. * @brief Generate and return a string describing the values of the main/common
  147. * encoder initialization parameters
  148. */
  149. std::string MainParamToString(const NV_ENC_INITIALIZE_PARAMS *pParams) {
  150. std::ostringstream os;
  151. os
  152. << "Encoding Parameters:"
  153. << std::endl << "\tcodec : " << ConvertValueToString(vCodec, szCodecNames, pParams->encodeGUID)
  154. << std::endl << "\tpreset : " << ConvertValueToString(vPreset, szPresetNames, pParams->presetGUID);
  155. if (pParams->tuningInfo)
  156. {
  157. os << std::endl << "\ttuningInfo : " << ConvertValueToString(vTuningInfo, szTuningInfoNames, pParams->tuningInfo);
  158. }
  159. os
  160. << std::endl << "\tprofile : " << ConvertValueToString(vProfile, szProfileNames, pParams->encodeConfig->profileGUID)
  161. << std::endl << "\tchroma : " << ConvertValueToString(vChroma, szChromaNames, (pParams->encodeGUID == NV_ENC_CODEC_H264_GUID) ? pParams->encodeConfig->encodeCodecConfig.h264Config.chromaFormatIDC : pParams->encodeConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC)
  162. << std::endl << "\tbitdepth : " << ((pParams->encodeGUID == NV_ENC_CODEC_H264_GUID) ? 0 : pParams->encodeConfig->encodeCodecConfig.hevcConfig.pixelBitDepthMinus8) + 8
  163. << std::endl << "\trc : " << ConvertValueToString(vRcMode, szRcModeNames, pParams->encodeConfig->rcParams.rateControlMode)
  164. ;
  165. if (pParams->encodeConfig->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CONSTQP) {
  166. os << " (P,B,I=" << pParams->encodeConfig->rcParams.constQP.qpInterP << "," << pParams->encodeConfig->rcParams.constQP.qpInterB << "," << pParams->encodeConfig->rcParams.constQP.qpIntra << ")";
  167. }
  168. os
  169. << std::endl << "\tfps : " << pParams->frameRateNum << "/" << pParams->frameRateDen
  170. << std::endl << "\tgop : " << (pParams->encodeConfig->gopLength == NVENC_INFINITE_GOPLENGTH ? "INF" : std::to_string(pParams->encodeConfig->gopLength))
  171. << std::endl << "\tbf : " << pParams->encodeConfig->frameIntervalP - 1
  172. << std::endl << "\tmultipass : " << pParams->encodeConfig->rcParams.multiPass
  173. << std::endl << "\tsize : " << pParams->encodeWidth << "x" << pParams->encodeHeight
  174. << std::endl << "\tbitrate : " << pParams->encodeConfig->rcParams.averageBitRate
  175. << std::endl << "\tmaxbitrate : " << pParams->encodeConfig->rcParams.maxBitRate
  176. << std::endl << "\tvbvbufsize : " << pParams->encodeConfig->rcParams.vbvBufferSize
  177. << std::endl << "\tvbvinit : " << pParams->encodeConfig->rcParams.vbvInitialDelay
  178. << std::endl << "\taq : " << (pParams->encodeConfig->rcParams.enableAQ ? (pParams->encodeConfig->rcParams.aqStrength ? std::to_string(pParams->encodeConfig->rcParams.aqStrength) : "auto") : "disabled")
  179. << std::endl << "\ttemporalaq : " << (pParams->encodeConfig->rcParams.enableTemporalAQ ? "enabled" : "disabled")
  180. << std::endl << "\tlookahead : " << (pParams->encodeConfig->rcParams.enableLookahead ? std::to_string(pParams->encodeConfig->rcParams.lookaheadDepth) : "disabled")
  181. << std::endl << "\tcq : " << (unsigned int)pParams->encodeConfig->rcParams.targetQuality
  182. << std::endl << "\tqmin : P,B,I=" << (int)pParams->encodeConfig->rcParams.minQP.qpInterP << "," << (int)pParams->encodeConfig->rcParams.minQP.qpInterB << "," << (int)pParams->encodeConfig->rcParams.minQP.qpIntra
  183. << std::endl << "\tqmax : P,B,I=" << (int)pParams->encodeConfig->rcParams.maxQP.qpInterP << "," << (int)pParams->encodeConfig->rcParams.maxQP.qpInterB << "," << (int)pParams->encodeConfig->rcParams.maxQP.qpIntra
  184. << std::endl << "\tinitqp : P,B,I=" << (int)pParams->encodeConfig->rcParams.initialRCQP.qpInterP << "," << (int)pParams->encodeConfig->rcParams.initialRCQP.qpInterB << "," << (int)pParams->encodeConfig->rcParams.initialRCQP.qpIntra
  185. ;
  186. return os.str();
  187. }
  188. public:
  189. virtual GUID GetEncodeGUID() { return guidCodec; }
  190. virtual GUID GetPresetGUID() { return guidPreset; }
  191. virtual NV_ENC_TUNING_INFO GetTuningInfo() { return m_TuningInfo; }
  192. /*
  193. * @brief Set encoder initialization parameters based on input options
  194. * This method parses the tokens formed from the command line options
  195. * provided to the application and sets the fields from NV_ENC_INITIALIZE_PARAMS
  196. * based on the supplied values.
  197. */
  198. virtual void SetInitParams(NV_ENC_INITIALIZE_PARAMS *pParams, NV_ENC_BUFFER_FORMAT eBufferFormat)
  199. {
  200. NV_ENC_CONFIG &config = *pParams->encodeConfig;
  201. for (unsigned i = 0; i < tokens.size(); i++)
  202. {
  203. if (
  204. tokens[i] == "-codec" && ++i ||
  205. tokens[i] == "-preset" && ++i ||
  206. tokens[i] == "-tuninginfo" && ++i ||
  207. tokens[i] == "-multipass" && ++i != tokens.size() && ParseString("-multipass", tokens[i], vMultiPass, szMultipass, &config.rcParams.multiPass) ||
  208. tokens[i] == "-profile" && ++i != tokens.size() && (IsCodecH264() ?
  209. ParseString("-profile", tokens[i], vH264Profile, szH264ProfileNames, &config.profileGUID) :
  210. ParseString("-profile", tokens[i], vHevcProfile, szHevcProfileNames, &config.profileGUID)) ||
  211. tokens[i] == "-rc" && ++i != tokens.size() && ParseString("-rc", tokens[i], vRcMode, szRcModeNames, &config.rcParams.rateControlMode) ||
  212. tokens[i] == "-fps" && ++i != tokens.size() && ParseInt("-fps", tokens[i], &pParams->frameRateNum) ||
  213. tokens[i] == "-bf" && ++i != tokens.size() && ParseInt("-bf", tokens[i], &config.frameIntervalP) && ++config.frameIntervalP ||
  214. tokens[i] == "-bitrate" && ++i != tokens.size() && ParseBitRate("-bitrate", tokens[i], &config.rcParams.averageBitRate) ||
  215. tokens[i] == "-maxbitrate" && ++i != tokens.size() && ParseBitRate("-maxbitrate", tokens[i], &config.rcParams.maxBitRate) ||
  216. tokens[i] == "-vbvbufsize" && ++i != tokens.size() && ParseBitRate("-vbvbufsize", tokens[i], &config.rcParams.vbvBufferSize) ||
  217. tokens[i] == "-vbvinit" && ++i != tokens.size() && ParseBitRate("-vbvinit", tokens[i], &config.rcParams.vbvInitialDelay) ||
  218. tokens[i] == "-cq" && ++i != tokens.size() && ParseInt("-cq", tokens[i], &config.rcParams.targetQuality) ||
  219. tokens[i] == "-initqp" && ++i != tokens.size() && ParseQp("-initqp", tokens[i], &config.rcParams.initialRCQP) && (config.rcParams.enableInitialRCQP = true) ||
  220. tokens[i] == "-qmin" && ++i != tokens.size() && ParseQp("-qmin", tokens[i], &config.rcParams.minQP) && (config.rcParams.enableMinQP = true) ||
  221. tokens[i] == "-qmax" && ++i != tokens.size() && ParseQp("-qmax", tokens[i], &config.rcParams.maxQP) && (config.rcParams.enableMaxQP = true) ||
  222. tokens[i] == "-constqp" && ++i != tokens.size() && ParseQp("-constqp", tokens[i], &config.rcParams.constQP) ||
  223. tokens[i] == "-temporalaq" && (config.rcParams.enableTemporalAQ = true)
  224. )
  225. {
  226. continue;
  227. }
  228. if (tokens[i] == "-lookahead" && ++i != tokens.size() && ParseInt("-lookahead", tokens[i], &config.rcParams.lookaheadDepth))
  229. {
  230. config.rcParams.enableLookahead = config.rcParams.lookaheadDepth > 0;
  231. continue;
  232. }
  233. int aqStrength;
  234. if (tokens[i] == "-aq" && ++i != tokens.size() && ParseInt("-aq", tokens[i], &aqStrength)) {
  235. config.rcParams.enableAQ = true;
  236. config.rcParams.aqStrength = aqStrength;
  237. continue;
  238. }
  239. if (tokens[i] == "-gop" && ++i != tokens.size() && ParseInt("-gop", tokens[i], &config.gopLength))
  240. {
  241. if (IsCodecH264())
  242. {
  243. config.encodeCodecConfig.h264Config.idrPeriod = config.gopLength;
  244. }
  245. else
  246. {
  247. config.encodeCodecConfig.hevcConfig.idrPeriod = config.gopLength;
  248. }
  249. continue;
  250. }
  251. if (tokens[i] == "-444")
  252. {
  253. if (IsCodecH264())
  254. {
  255. config.encodeCodecConfig.h264Config.chromaFormatIDC = 3;
  256. } else
  257. {
  258. config.encodeCodecConfig.hevcConfig.chromaFormatIDC = 3;
  259. }
  260. continue;
  261. }
  262. std::ostringstream errmessage;
  263. errmessage << "Incorrect parameter: " << tokens[i] << std::endl;
  264. errmessage << "Re-run the application with the -h option to get a list of the supported options.";
  265. errmessage << std::endl;
  266. throw std::invalid_argument(errmessage.str());
  267. }
  268. if (IsCodecHEVC())
  269. {
  270. if (eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT)
  271. {
  272. config.encodeCodecConfig.hevcConfig.pixelBitDepthMinus8 = 2;
  273. }
  274. }
  275. funcInit(pParams);
  276. LOG(INFO) << NvEncoderInitParam().MainParamToString(pParams);
  277. LOG(TRACE) << NvEncoderInitParam().FullParamToString(pParams);
  278. }
  279. private:
  280. /*
  281. * Helper methods for parsing tokens (generated by splitting the command line)
  282. * and performing conversions to the appropriate target type/value.
  283. */
  284. template<typename T>
  285. bool ParseString(const std::string &strName, const std::string &strValue, const std::vector<T> &vValue, const std::string &strValueNames, T *pValue) {
  286. std::vector<std::string> vstrValueName = split(strValueNames, ' ');
  287. auto it = std::find(vstrValueName.begin(), vstrValueName.end(), strValue);
  288. if (it == vstrValueName.end()) {
  289. LOG(ERROR) << strName << " options: " << strValueNames;
  290. return false;
  291. }
  292. *pValue = vValue[it - vstrValueName.begin()];
  293. return true;
  294. }
  295. template<typename T>
  296. std::string ConvertValueToString(const std::vector<T> &vValue, const std::string &strValueNames, T value) {
  297. auto it = std::find(vValue.begin(), vValue.end(), value);
  298. if (it == vValue.end()) {
  299. LOG(ERROR) << "Invalid value. Can't convert to one of " << strValueNames;
  300. return std::string();
  301. }
  302. return split(strValueNames, ' ')[it - vValue.begin()];
  303. }
  304. bool ParseBitRate(const std::string &strName, const std::string &strValue, unsigned *pBitRate) {
  305. try {
  306. size_t l;
  307. double r = std::stod(strValue, &l);
  308. char c = strValue[l];
  309. if (c != 0 && c != 'k' && c != 'm') {
  310. LOG(ERROR) << strName << " units: 1, K, M (lower case also allowed)";
  311. }
  312. *pBitRate = (unsigned)((c == 'm' ? 1000000 : (c == 'k' ? 1000 : 1)) * r);
  313. } catch (std::invalid_argument) {
  314. return false;
  315. }
  316. return true;
  317. }
  318. template<typename T>
  319. bool ParseInt(const std::string &strName, const std::string &strValue, T *pInt) {
  320. try {
  321. *pInt = std::stoi(strValue);
  322. } catch (std::invalid_argument) {
  323. LOG(ERROR) << strName << " need a value of positive number";
  324. return false;
  325. }
  326. return true;
  327. }
  328. bool ParseQp(const std::string &strName, const std::string &strValue, NV_ENC_QP *pQp) {
  329. std::vector<std::string> vQp = split(strValue, ',');
  330. try {
  331. if (vQp.size() == 1) {
  332. unsigned qp = (unsigned)std::stoi(vQp[0]);
  333. *pQp = {qp, qp, qp};
  334. } else if (vQp.size() == 3) {
  335. *pQp = {(unsigned)std::stoi(vQp[0]), (unsigned)std::stoi(vQp[1]), (unsigned)std::stoi(vQp[2])};
  336. } else {
  337. LOG(ERROR) << strName << " qp_for_P_B_I or qp_P,qp_B,qp_I (no space is allowed)";
  338. return false;
  339. }
  340. } catch (std::invalid_argument) {
  341. return false;
  342. }
  343. return true;
  344. }
  345. std::vector<std::string> split(const std::string &s, char delim) {
  346. std::stringstream ss(s);
  347. std::string token;
  348. std::vector<std::string> tokens;
  349. while (getline(ss, token, delim)) {
  350. tokens.push_back(token);
  351. }
  352. return tokens;
  353. }
  354. private:
  355. std::string strParam;
  356. std::function<void(NV_ENC_INITIALIZE_PARAMS *pParams)> funcInit = [](NV_ENC_INITIALIZE_PARAMS *pParams){};
  357. std::vector<std::string> tokens;
  358. GUID guidCodec = NV_ENC_CODEC_H264_GUID;
  359. GUID guidPreset = NV_ENC_PRESET_P3_GUID;
  360. NV_ENC_TUNING_INFO m_TuningInfo = NV_ENC_TUNING_INFO_HIGH_QUALITY;
  361. bool bLowLatency = false;
  362. const char *szCodecNames = "h264 hevc";
  363. std::vector<GUID> vCodec = std::vector<GUID> {
  364. NV_ENC_CODEC_H264_GUID,
  365. NV_ENC_CODEC_HEVC_GUID
  366. };
  367. const char *szChromaNames = "yuv420 yuv444";
  368. std::vector<uint32_t> vChroma = std::vector<uint32_t>
  369. {
  370. 1, 3
  371. };
  372. const char *szPresetNames = "p1 p2 p3 p4 p5 p6 p7";
  373. std::vector<GUID> vPreset = std::vector<GUID> {
  374. NV_ENC_PRESET_P1_GUID,
  375. NV_ENC_PRESET_P2_GUID,
  376. NV_ENC_PRESET_P3_GUID,
  377. NV_ENC_PRESET_P4_GUID,
  378. NV_ENC_PRESET_P5_GUID,
  379. NV_ENC_PRESET_P6_GUID,
  380. NV_ENC_PRESET_P7_GUID,
  381. };
  382. const char *szH264ProfileNames = "baseline main high high444";
  383. std::vector<GUID> vH264Profile = std::vector<GUID> {
  384. NV_ENC_H264_PROFILE_BASELINE_GUID,
  385. NV_ENC_H264_PROFILE_MAIN_GUID,
  386. NV_ENC_H264_PROFILE_HIGH_GUID,
  387. NV_ENC_H264_PROFILE_HIGH_444_GUID,
  388. };
  389. const char *szHevcProfileNames = "main main10 frext";
  390. std::vector<GUID> vHevcProfile = std::vector<GUID> {
  391. NV_ENC_HEVC_PROFILE_MAIN_GUID,
  392. NV_ENC_HEVC_PROFILE_MAIN10_GUID,
  393. NV_ENC_HEVC_PROFILE_FREXT_GUID,
  394. };
  395. const char *szProfileNames = "(default) auto baseline(h264) main(h264) high(h264) high444(h264)"
  396. " stereo(h264) svc_temporal_scalability(h264) progressiv_high(h264) constrained_high(h264)"
  397. " main(hevc) main10(hevc) frext(hevc)";
  398. std::vector<GUID> vProfile = std::vector<GUID> {
  399. GUID{},
  400. NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID,
  401. NV_ENC_H264_PROFILE_BASELINE_GUID,
  402. NV_ENC_H264_PROFILE_MAIN_GUID,
  403. NV_ENC_H264_PROFILE_HIGH_GUID,
  404. NV_ENC_H264_PROFILE_HIGH_444_GUID,
  405. NV_ENC_H264_PROFILE_STEREO_GUID,
  406. NV_ENC_H264_PROFILE_SVC_TEMPORAL_SCALABILTY,
  407. NV_ENC_H264_PROFILE_PROGRESSIVE_HIGH_GUID,
  408. NV_ENC_H264_PROFILE_CONSTRAINED_HIGH_GUID,
  409. NV_ENC_HEVC_PROFILE_MAIN_GUID,
  410. NV_ENC_HEVC_PROFILE_MAIN10_GUID,
  411. NV_ENC_HEVC_PROFILE_FREXT_GUID,
  412. };
  413. const char *szLowLatencyTuningInfoNames = "lowlatency ultralowlatency";
  414. const char *szTuningInfoNames = "hq lowlatency ultralowlatency lossless";
  415. std::vector<NV_ENC_TUNING_INFO> vTuningInfo = std::vector<NV_ENC_TUNING_INFO>{
  416. NV_ENC_TUNING_INFO_HIGH_QUALITY,
  417. NV_ENC_TUNING_INFO_LOW_LATENCY,
  418. NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY,
  419. NV_ENC_TUNING_INFO_LOSSLESS
  420. };
  421. const char *szRcModeNames = "constqp vbr cbr";
  422. std::vector<NV_ENC_PARAMS_RC_MODE> vRcMode = std::vector<NV_ENC_PARAMS_RC_MODE> {
  423. NV_ENC_PARAMS_RC_CONSTQP,
  424. NV_ENC_PARAMS_RC_VBR,
  425. NV_ENC_PARAMS_RC_CBR,
  426. };
  427. const char *szMultipass = "disabled qres fullres";
  428. std::vector<NV_ENC_MULTI_PASS> vMultiPass = std::vector<NV_ENC_MULTI_PASS>{
  429. NV_ENC_MULTI_PASS_DISABLED,
  430. NV_ENC_TWO_PASS_QUARTER_RESOLUTION,
  431. NV_ENC_TWO_PASS_FULL_RESOLUTION,
  432. };
  433. const char *szQpMapModeNames = "disabled emphasis_level_map delta_qp_map qp_map";
  434. std::vector<NV_ENC_QP_MAP_MODE> vQpMapMode = std::vector<NV_ENC_QP_MAP_MODE> {
  435. NV_ENC_QP_MAP_DISABLED,
  436. NV_ENC_QP_MAP_EMPHASIS,
  437. NV_ENC_QP_MAP_DELTA,
  438. NV_ENC_QP_MAP,
  439. };
  440. public:
  441. /*
  442. * Generates and returns a string describing the values for each field in
  443. * the NV_ENC_INITIALIZE_PARAMS structure (i.e. a description of the entire
  444. * set of initialization parameters supplied to the API).
  445. */
  446. std::string FullParamToString(const NV_ENC_INITIALIZE_PARAMS *pInitializeParams) {
  447. std::ostringstream os;
  448. os << "NV_ENC_INITIALIZE_PARAMS:" << std::endl
  449. << "encodeGUID: " << ConvertValueToString(vCodec, szCodecNames, pInitializeParams->encodeGUID) << std::endl
  450. << "presetGUID: " << ConvertValueToString(vPreset, szPresetNames, pInitializeParams->presetGUID) << std::endl;
  451. if (pInitializeParams->tuningInfo)
  452. {
  453. os << "tuningInfo: " << ConvertValueToString(vTuningInfo, szTuningInfoNames, pInitializeParams->tuningInfo) << std::endl;
  454. }
  455. os
  456. << "encodeWidth: " << pInitializeParams->encodeWidth << std::endl
  457. << "encodeHeight: " << pInitializeParams->encodeHeight << std::endl
  458. << "darWidth: " << pInitializeParams->darWidth << std::endl
  459. << "darHeight: " << pInitializeParams->darHeight << std::endl
  460. << "frameRateNum: " << pInitializeParams->frameRateNum << std::endl
  461. << "frameRateDen: " << pInitializeParams->frameRateDen << std::endl
  462. << "enableEncodeAsync: " << pInitializeParams->enableEncodeAsync << std::endl
  463. << "reportSliceOffsets: " << pInitializeParams->reportSliceOffsets << std::endl
  464. << "enableSubFrameWrite: " << pInitializeParams->enableSubFrameWrite << std::endl
  465. << "enableExternalMEHints: " << pInitializeParams->enableExternalMEHints << std::endl
  466. << "enableMEOnlyMode: " << pInitializeParams->enableMEOnlyMode << std::endl
  467. << "enableWeightedPrediction: " << pInitializeParams->enableWeightedPrediction << std::endl
  468. << "maxEncodeWidth: " << pInitializeParams->maxEncodeWidth << std::endl
  469. << "maxEncodeHeight: " << pInitializeParams->maxEncodeHeight << std::endl
  470. << "maxMEHintCountsPerBlock: " << pInitializeParams->maxMEHintCountsPerBlock << std::endl
  471. ;
  472. NV_ENC_CONFIG *pConfig = pInitializeParams->encodeConfig;
  473. os << "NV_ENC_CONFIG:" << std::endl
  474. << "profile: " << ConvertValueToString(vProfile, szProfileNames, pConfig->profileGUID) << std::endl
  475. << "gopLength: " << pConfig->gopLength << std::endl
  476. << "frameIntervalP: " << pConfig->frameIntervalP << std::endl
  477. << "monoChromeEncoding: " << pConfig->monoChromeEncoding << std::endl
  478. << "frameFieldMode: " << pConfig->frameFieldMode << std::endl
  479. << "mvPrecision: " << pConfig->mvPrecision << std::endl
  480. << "NV_ENC_RC_PARAMS:" << std::endl
  481. << " rateControlMode: 0x" << std::hex << pConfig->rcParams.rateControlMode << std::dec << std::endl
  482. << " constQP: " << pConfig->rcParams.constQP.qpInterP << ", " << pConfig->rcParams.constQP.qpInterB << ", " << pConfig->rcParams.constQP.qpIntra << std::endl
  483. << " averageBitRate: " << pConfig->rcParams.averageBitRate << std::endl
  484. << " maxBitRate: " << pConfig->rcParams.maxBitRate << std::endl
  485. << " vbvBufferSize: " << pConfig->rcParams.vbvBufferSize << std::endl
  486. << " vbvInitialDelay: " << pConfig->rcParams.vbvInitialDelay << std::endl
  487. << " enableMinQP: " << pConfig->rcParams.enableMinQP << std::endl
  488. << " enableMaxQP: " << pConfig->rcParams.enableMaxQP << std::endl
  489. << " enableInitialRCQP: " << pConfig->rcParams.enableInitialRCQP << std::endl
  490. << " enableAQ: " << pConfig->rcParams.enableAQ << std::endl
  491. << " qpMapMode: " << ConvertValueToString(vQpMapMode, szQpMapModeNames, pConfig->rcParams.qpMapMode) << std::endl
  492. << " multipass: " << ConvertValueToString(vMultiPass, szMultipass, pConfig->rcParams.multiPass) << std::endl
  493. << " enableLookahead: " << pConfig->rcParams.enableLookahead << std::endl
  494. << " disableIadapt: " << pConfig->rcParams.disableIadapt << std::endl
  495. << " disableBadapt: " << pConfig->rcParams.disableBadapt << std::endl
  496. << " enableTemporalAQ: " << pConfig->rcParams.enableTemporalAQ << std::endl
  497. << " zeroReorderDelay: " << pConfig->rcParams.zeroReorderDelay << std::endl
  498. << " enableNonRefP: " << pConfig->rcParams.enableNonRefP << std::endl
  499. << " strictGOPTarget: " << pConfig->rcParams.strictGOPTarget << std::endl
  500. << " aqStrength: " << pConfig->rcParams.aqStrength << std::endl
  501. << " minQP: " << pConfig->rcParams.minQP.qpInterP << ", " << pConfig->rcParams.minQP.qpInterB << ", " << pConfig->rcParams.minQP.qpIntra << std::endl
  502. << " maxQP: " << pConfig->rcParams.maxQP.qpInterP << ", " << pConfig->rcParams.maxQP.qpInterB << ", " << pConfig->rcParams.maxQP.qpIntra << std::endl
  503. << " initialRCQP: " << pConfig->rcParams.initialRCQP.qpInterP << ", " << pConfig->rcParams.initialRCQP.qpInterB << ", " << pConfig->rcParams.initialRCQP.qpIntra << std::endl
  504. << " temporallayerIdxMask: " << pConfig->rcParams.temporallayerIdxMask << std::endl
  505. << " temporalLayerQP: " << (int)pConfig->rcParams.temporalLayerQP[0] << ", " << (int)pConfig->rcParams.temporalLayerQP[1] << ", " << (int)pConfig->rcParams.temporalLayerQP[2] << ", " << (int)pConfig->rcParams.temporalLayerQP[3] << ", " << (int)pConfig->rcParams.temporalLayerQP[4] << ", " << (int)pConfig->rcParams.temporalLayerQP[5] << ", " << (int)pConfig->rcParams.temporalLayerQP[6] << ", " << (int)pConfig->rcParams.temporalLayerQP[7] << std::endl
  506. << " targetQuality: " << pConfig->rcParams.targetQuality << std::endl
  507. << " lookaheadDepth: " << pConfig->rcParams.lookaheadDepth << std::endl;
  508. if (pInitializeParams->encodeGUID == NV_ENC_CODEC_H264_GUID) {
  509. os
  510. << "NV_ENC_CODEC_CONFIG (H264):" << std::endl
  511. << " enableStereoMVC: " << pConfig->encodeCodecConfig.h264Config.enableStereoMVC << std::endl
  512. << " hierarchicalPFrames: " << pConfig->encodeCodecConfig.h264Config.hierarchicalPFrames << std::endl
  513. << " hierarchicalBFrames: " << pConfig->encodeCodecConfig.h264Config.hierarchicalBFrames << std::endl
  514. << " outputBufferingPeriodSEI: " << pConfig->encodeCodecConfig.h264Config.outputBufferingPeriodSEI << std::endl
  515. << " outputPictureTimingSEI: " << pConfig->encodeCodecConfig.h264Config.outputPictureTimingSEI << std::endl
  516. << " outputAUD: " << pConfig->encodeCodecConfig.h264Config.outputAUD << std::endl
  517. << " disableSPSPPS: " << pConfig->encodeCodecConfig.h264Config.disableSPSPPS << std::endl
  518. << " outputFramePackingSEI: " << pConfig->encodeCodecConfig.h264Config.outputFramePackingSEI << std::endl
  519. << " outputRecoveryPointSEI: " << pConfig->encodeCodecConfig.h264Config.outputRecoveryPointSEI << std::endl
  520. << " enableIntraRefresh: " << pConfig->encodeCodecConfig.h264Config.enableIntraRefresh << std::endl
  521. << " enableConstrainedEncoding: " << pConfig->encodeCodecConfig.h264Config.enableConstrainedEncoding << std::endl
  522. << " repeatSPSPPS: " << pConfig->encodeCodecConfig.h264Config.repeatSPSPPS << std::endl
  523. << " enableVFR: " << pConfig->encodeCodecConfig.h264Config.enableVFR << std::endl
  524. << " enableLTR: " << pConfig->encodeCodecConfig.h264Config.enableLTR << std::endl
  525. << " qpPrimeYZeroTransformBypassFlag: " << pConfig->encodeCodecConfig.h264Config.qpPrimeYZeroTransformBypassFlag << std::endl
  526. << " useConstrainedIntraPred: " << pConfig->encodeCodecConfig.h264Config.useConstrainedIntraPred << std::endl
  527. << " level: " << pConfig->encodeCodecConfig.h264Config.level << std::endl
  528. << " idrPeriod: " << pConfig->encodeCodecConfig.h264Config.idrPeriod << std::endl
  529. << " separateColourPlaneFlag: " << pConfig->encodeCodecConfig.h264Config.separateColourPlaneFlag << std::endl
  530. << " disableDeblockingFilterIDC: " << pConfig->encodeCodecConfig.h264Config.disableDeblockingFilterIDC << std::endl
  531. << " numTemporalLayers: " << pConfig->encodeCodecConfig.h264Config.numTemporalLayers << std::endl
  532. << " spsId: " << pConfig->encodeCodecConfig.h264Config.spsId << std::endl
  533. << " ppsId: " << pConfig->encodeCodecConfig.h264Config.ppsId << std::endl
  534. << " adaptiveTransformMode: " << pConfig->encodeCodecConfig.h264Config.adaptiveTransformMode << std::endl
  535. << " fmoMode: " << pConfig->encodeCodecConfig.h264Config.fmoMode << std::endl
  536. << " bdirectMode: " << pConfig->encodeCodecConfig.h264Config.bdirectMode << std::endl
  537. << " entropyCodingMode: " << pConfig->encodeCodecConfig.h264Config.entropyCodingMode << std::endl
  538. << " stereoMode: " << pConfig->encodeCodecConfig.h264Config.stereoMode << std::endl
  539. << " intraRefreshPeriod: " << pConfig->encodeCodecConfig.h264Config.intraRefreshPeriod << std::endl
  540. << " intraRefreshCnt: " << pConfig->encodeCodecConfig.h264Config.intraRefreshCnt << std::endl
  541. << " maxNumRefFrames: " << pConfig->encodeCodecConfig.h264Config.maxNumRefFrames << std::endl
  542. << " sliceMode: " << pConfig->encodeCodecConfig.h264Config.sliceMode << std::endl
  543. << " sliceModeData: " << pConfig->encodeCodecConfig.h264Config.sliceModeData << std::endl
  544. << " NV_ENC_CONFIG_H264_VUI_PARAMETERS:" << std::endl
  545. << " overscanInfoPresentFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.overscanInfoPresentFlag << std::endl
  546. << " overscanInfo: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.overscanInfo << std::endl
  547. << " videoSignalTypePresentFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoSignalTypePresentFlag << std::endl
  548. << " videoFormat: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoFormat << std::endl
  549. << " videoFullRangeFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoFullRangeFlag << std::endl
  550. << " colourDescriptionPresentFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.colourDescriptionPresentFlag << std::endl
  551. << " colourPrimaries: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.colourPrimaries << std::endl
  552. << " transferCharacteristics: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.transferCharacteristics << std::endl
  553. << " colourMatrix: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.colourMatrix << std::endl
  554. << " chromaSampleLocationFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.chromaSampleLocationFlag << std::endl
  555. << " chromaSampleLocationTop: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.chromaSampleLocationTop << std::endl
  556. << " chromaSampleLocationBot: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.chromaSampleLocationBot << std::endl
  557. << " bitstreamRestrictionFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.bitstreamRestrictionFlag << std::endl
  558. << " ltrNumFrames: " << pConfig->encodeCodecConfig.h264Config.ltrNumFrames << std::endl
  559. << " ltrTrustMode: " << pConfig->encodeCodecConfig.h264Config.ltrTrustMode << std::endl
  560. << " chromaFormatIDC: " << pConfig->encodeCodecConfig.h264Config.chromaFormatIDC << std::endl
  561. << " maxTemporalLayers: " << pConfig->encodeCodecConfig.h264Config.maxTemporalLayers << std::endl;
  562. } else if (pInitializeParams->encodeGUID == NV_ENC_CODEC_HEVC_GUID) {
  563. os
  564. << "NV_ENC_CODEC_CONFIG (HEVC):" << std::endl
  565. << " level: " << pConfig->encodeCodecConfig.hevcConfig.level << std::endl
  566. << " tier: " << pConfig->encodeCodecConfig.hevcConfig.tier << std::endl
  567. << " minCUSize: " << pConfig->encodeCodecConfig.hevcConfig.minCUSize << std::endl
  568. << " maxCUSize: " << pConfig->encodeCodecConfig.hevcConfig.maxCUSize << std::endl
  569. << " useConstrainedIntraPred: " << pConfig->encodeCodecConfig.hevcConfig.useConstrainedIntraPred << std::endl
  570. << " disableDeblockAcrossSliceBoundary: " << pConfig->encodeCodecConfig.hevcConfig.disableDeblockAcrossSliceBoundary << std::endl
  571. << " outputBufferingPeriodSEI: " << pConfig->encodeCodecConfig.hevcConfig.outputBufferingPeriodSEI << std::endl
  572. << " outputPictureTimingSEI: " << pConfig->encodeCodecConfig.hevcConfig.outputPictureTimingSEI << std::endl
  573. << " outputAUD: " << pConfig->encodeCodecConfig.hevcConfig.outputAUD << std::endl
  574. << " enableLTR: " << pConfig->encodeCodecConfig.hevcConfig.enableLTR << std::endl
  575. << " disableSPSPPS: " << pConfig->encodeCodecConfig.hevcConfig.disableSPSPPS << std::endl
  576. << " repeatSPSPPS: " << pConfig->encodeCodecConfig.hevcConfig.repeatSPSPPS << std::endl
  577. << " enableIntraRefresh: " << pConfig->encodeCodecConfig.hevcConfig.enableIntraRefresh << std::endl
  578. << " chromaFormatIDC: " << pConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC << std::endl
  579. << " pixelBitDepthMinus8: " << pConfig->encodeCodecConfig.hevcConfig.pixelBitDepthMinus8 << std::endl
  580. << " idrPeriod: " << pConfig->encodeCodecConfig.hevcConfig.idrPeriod << std::endl
  581. << " intraRefreshPeriod: " << pConfig->encodeCodecConfig.hevcConfig.intraRefreshPeriod << std::endl
  582. << " intraRefreshCnt: " << pConfig->encodeCodecConfig.hevcConfig.intraRefreshCnt << std::endl
  583. << " maxNumRefFramesInDPB: " << pConfig->encodeCodecConfig.hevcConfig.maxNumRefFramesInDPB << std::endl
  584. << " ltrNumFrames: " << pConfig->encodeCodecConfig.hevcConfig.ltrNumFrames << std::endl
  585. << " vpsId: " << pConfig->encodeCodecConfig.hevcConfig.vpsId << std::endl
  586. << " spsId: " << pConfig->encodeCodecConfig.hevcConfig.spsId << std::endl
  587. << " ppsId: " << pConfig->encodeCodecConfig.hevcConfig.ppsId << std::endl
  588. << " sliceMode: " << pConfig->encodeCodecConfig.hevcConfig.sliceMode << std::endl
  589. << " sliceModeData: " << pConfig->encodeCodecConfig.hevcConfig.sliceModeData << std::endl
  590. << " maxTemporalLayersMinus1: " << pConfig->encodeCodecConfig.hevcConfig.maxTemporalLayersMinus1 << std::endl
  591. << " NV_ENC_CONFIG_HEVC_VUI_PARAMETERS:" << std::endl
  592. << " overscanInfoPresentFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.overscanInfoPresentFlag << std::endl
  593. << " overscanInfo: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.overscanInfo << std::endl
  594. << " videoSignalTypePresentFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoSignalTypePresentFlag << std::endl
  595. << " videoFormat: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFormat << std::endl
  596. << " videoFullRangeFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFullRangeFlag << std::endl
  597. << " colourDescriptionPresentFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.colourDescriptionPresentFlag << std::endl
  598. << " colourPrimaries: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.colourPrimaries << std::endl
  599. << " transferCharacteristics: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.transferCharacteristics << std::endl
  600. << " colourMatrix: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.colourMatrix << std::endl
  601. << " chromaSampleLocationFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.chromaSampleLocationFlag << std::endl
  602. << " chromaSampleLocationTop: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.chromaSampleLocationTop << std::endl
  603. << " chromaSampleLocationBot: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.chromaSampleLocationBot << std::endl
  604. << " bitstreamRestrictionFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.bitstreamRestrictionFlag << std::endl
  605. << " ltrTrustMode: " << pConfig->encodeCodecConfig.hevcConfig.ltrTrustMode << std::endl;
  606. }
  607. return os.str();
  608. }
  609. };