ffmpeg_init.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. //
  2. #include "ffmpeg_init.h"
  3. #if !NDEBUG
  4. #define OPEN_FFMPEG_LOG 1
  5. #else
  6. #define OPEN_FFMPEG_LOG 0
  7. #endif
  8. #define PRINT_LIB_INFO(libname, LIBNAME) \
  9. if (true) \
  10. { \
  11. const char* indent = " "; \
  12. unsigned int version = libname##_version(); \
  13. qInfo("%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d", indent, #libname, \
  14. LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, \
  15. LIB##LIBNAME##_VERSION_MICRO, AV_VERSION_MAJOR(version), \
  16. AV_VERSION_MINOR(version), AV_VERSION_MICRO(version)); \
  17. }
  18. #define BUFF_MAXLEN 256
  19. static void log_callback(void* ptr, int level, const char* fmt, va_list vl)
  20. {
  21. if (level > av_log_get_level())
  22. return;
  23. va_list vl2;
  24. char line[1024];
  25. static int print_prefix = 1;
  26. va_copy(vl2, vl);
  27. av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
  28. va_end(vl2);
  29. #if OPEN_FFMPEG_LOG
  30. qInfo("FFMPEG:%s", line);
  31. #endif
  32. }
  33. int ffmpeg_init()
  34. {
  35. av_log_set_flags(AV_LOG_SKIP_REPEATED);
  36. av_log_set_level(AV_LOG_INFO);
  37. av_log_set_callback(log_callback);
  38. // print_ffmpeg_info(AV_LOG_INFO);
  39. check_error(-22);
  40. return 0;
  41. }
  42. void check_error(int error)
  43. {
  44. char errorStr[256] = {0};
  45. qDebug("ENOMEM: %d", AVERROR(ENOMEM));
  46. qDebug("ENOMEM: %d", AVERROR(EINVAL));
  47. qDebug("ENOMEM: %d", AVERROR_OPTION_NOT_FOUND);
  48. av_strerror(error, errorStr, sizeof(errorStr));
  49. }
  50. void print_ffmpeg_info()
  51. {
  52. // ffmpeg-snapshot_0401
  53. qInfo("%s version %s", "ffmpeg", FFMPEG_VERSION);
  54. PRINT_LIB_INFO(avutil, AVUTIL);
  55. PRINT_LIB_INFO(avcodec, AVCODEC);
  56. PRINT_LIB_INFO(avformat, AVFORMAT);
  57. // PRINT_LIB_INFO(avdevice, AVDEVICE);
  58. // PRINT_LIB_INFO(avfilter, AVFILTER);
  59. PRINT_LIB_INFO(swscale, SWSCALE);
  60. PRINT_LIB_INFO(swresample, SWRESAMPLE);
  61. qInfo("");
  62. }
  63. QString dump_format(AVFormatContext* ic, int index, const char* url, int is_output)
  64. {
  65. QString str;
  66. char tmp[BUFF_MAXLEN];
  67. const char* indent = " ";
  68. uint8_t* printed = nullptr;
  69. if (!ic)
  70. {
  71. qErrnoWarning("invalid parameter!");
  72. goto fail;
  73. }
  74. if (!url || !url[0])
  75. {
  76. qErrnoWarning("url is invalid!");
  77. goto fail;
  78. }
  79. printed = ic->nb_streams ? (uint8_t*)av_mallocz(ic->nb_streams) : nullptr;
  80. if (ic->nb_streams && !printed)
  81. goto fail;
  82. snprintf(tmp, sizeof(tmp), "%s #%d, %s, %s '%s':",
  83. is_output ? "Output" : "Input", index,
  84. is_output ? ic->oformat->name : ic->iformat->name,
  85. is_output ? "to" : "from", url);
  86. str += tmp;
  87. str += "\n";
  88. str += dump_metadata(ic->metadata, indent);
  89. if (!is_output)
  90. {
  91. snprintf(tmp, sizeof(tmp), "%sDuration: ", indent);
  92. str += tmp;
  93. if (ic->duration != AV_NOPTS_VALUE)
  94. {
  95. int64_t hours, mins, secs, us;
  96. int64_t duration =
  97. ic->duration + (ic->duration <= INT64_MAX - 5000 ? 5000 : 0);
  98. secs = duration / AV_TIME_BASE;
  99. us = duration % AV_TIME_BASE;
  100. mins = secs / 60;
  101. secs %= 60;
  102. hours = mins / 60;
  103. mins %= 60;
  104. snprintf(tmp, sizeof(tmp), "%02lld:%02lld:%02lld.%02lld", hours, mins,
  105. secs, (100 * us) / AV_TIME_BASE);
  106. str += tmp;
  107. }
  108. else
  109. {
  110. str += "N/A";
  111. }
  112. if (ic->start_time != AV_NOPTS_VALUE)
  113. {
  114. int secs, us;
  115. secs = llabs(ic->start_time / AV_TIME_BASE);
  116. us = llabs(ic->start_time % AV_TIME_BASE);
  117. // av_log(nullptr, AV_LOG_INFO, ", start: %s%d.%06d",
  118. // ic->start_time >= 0 ? "" : "-", secs, (int)av_rescale(us, 1000000,
  119. // AV_TIME_BASE));
  120. snprintf(tmp, sizeof(tmp), ", start: %s%d.%06d",
  121. ic->start_time >= 0 ? "" : "-", secs,
  122. (int)av_rescale(us, 1000000, AV_TIME_BASE));
  123. str += tmp;
  124. }
  125. str += ", bitrate: ";
  126. if (ic->bit_rate)
  127. {
  128. snprintf(tmp, sizeof(tmp), "%lld kb/s", ic->bit_rate / 1000);
  129. str += tmp;
  130. }
  131. else
  132. str += "N/A";
  133. str += "\n";
  134. }
  135. if (ic->nb_chapters)
  136. {
  137. snprintf(tmp, sizeof(tmp), "%sChapters:\n", indent);
  138. str += tmp;
  139. }
  140. for (unsigned int i = 0; i < ic->nb_chapters; i++)
  141. {
  142. const AVChapter* ch = ic->chapters[i];
  143. snprintf(tmp, sizeof(tmp), " Chapter #%d:%d: start %f, end %f\n", index,
  144. i, ch->start * av_q2d(ch->time_base),
  145. ch->end * av_q2d(ch->time_base));
  146. str += tmp;
  147. str += dump_metadata(ch->metadata, " ");
  148. }
  149. if (ic->nb_programs)
  150. {
  151. unsigned int j, k, total = 0;
  152. for (j = 0; j < ic->nb_programs; j++)
  153. {
  154. const AVProgram* program = ic->programs[j];
  155. const AVDictionaryEntry* name =
  156. av_dict_get(program->metadata, "name", nullptr, 0);
  157. snprintf(tmp, sizeof(tmp), " Program %d %s\n", program->id,
  158. name ? name->value : "");
  159. str += tmp;
  160. str += dump_metadata(program->metadata, " ");
  161. for (k = 0; k < program->nb_stream_indexes; k++)
  162. {
  163. str +=
  164. dump_stream_format(ic, program->stream_index[k], index, is_output);
  165. printed[program->stream_index[k]] = 1;
  166. }
  167. total += program->nb_stream_indexes;
  168. }
  169. if (total < ic->nb_streams)
  170. {
  171. str += " No Program\n";
  172. }
  173. }
  174. str += "\n";
  175. for (unsigned int i = 0; i < ic->nb_streams; i++)
  176. {
  177. if (!printed[i])
  178. {
  179. str += dump_stream_format(ic, i, index, is_output);
  180. str += "\n";
  181. }
  182. }
  183. return str;
  184. fail:
  185. return QString("");
  186. }
  187. QString dump_metadata(const AVDictionary* m, const char* indent)
  188. {
  189. QString str;
  190. char tmp[BUFF_MAXLEN];
  191. if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", nullptr, 0)))
  192. {
  193. const AVDictionaryEntry* tag = nullptr;
  194. snprintf(tmp, sizeof(tmp), "%sMetadata:\n", indent);
  195. str += tmp;
  196. while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX)))
  197. {
  198. if (strcmp("language", tag->key))
  199. {
  200. const char* p = tag->value;
  201. // av_log(ctx, AV_LOG_INFO,"%s %-16s: ", indent, tag->key);
  202. snprintf(tmp, sizeof(tmp), "%s %-16s: ", indent, tag->key);
  203. str += tmp;
  204. while (*p)
  205. {
  206. char tmp_str[256];
  207. size_t len = strcspn(p, "\x8\xa\xb\xc\xd");
  208. av_strlcpy(tmp_str, p, FFMIN(sizeof(tmp_str), len + 1));
  209. // str += "%s", tmp);
  210. snprintf(tmp, sizeof(tmp), "%s", tmp_str);
  211. str += tmp;
  212. p += len;
  213. if (*p == 0xd)
  214. str += " ";
  215. if (*p == 0xa)
  216. str += "\n%s %-16s: ";
  217. if (*p)
  218. p++;
  219. }
  220. str += "\n";
  221. }
  222. }
  223. }
  224. return str;
  225. }
  226. QString dump_stream_format(const AVFormatContext* ic, int i, int index, int is_output)
  227. {
  228. QString str;
  229. char tmp[BUFF_MAXLEN];
  230. char buf[256];
  231. int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
  232. const AVStream* st = ic->streams[i];
  233. // const FFStream* const sti = cffstream(st);
  234. const AVDictionaryEntry* lang =
  235. av_dict_get(st->metadata, "language", nullptr, 0);
  236. const char* separator = (const char*)ic->dump_separator;
  237. AVCodecContext* avctx;
  238. // AVCodecContext* st_avctx = (AVCodecContext*)st->priv_data;
  239. int ret;
  240. avctx = avcodec_alloc_context3(nullptr);
  241. if (!avctx)
  242. goto fail;
  243. ret = avcodec_parameters_to_context(avctx, st->codecpar);
  244. if (ret < 0)
  245. {
  246. avcodec_free_context(&avctx);
  247. goto fail;
  248. }
  249. // Fields which are missing from AVCodecParameters need to be taken from the
  250. // AVCodecContext
  251. /*
  252. avctx->properties = st_avctx->properties;
  253. avctx->codec = st_avctx->codec;
  254. avctx->qmin = st_avctx->qmin;
  255. avctx->qmax = st_avctx->qmax;
  256. avctx->coded_width = st_avctx->coded_width;
  257. avctx->coded_height = st_avctx->coded_height;
  258. if (separator)
  259. av_opt_set(avctx, "dump_separator", separator, 0);*/
  260. avcodec_string(buf, sizeof(buf), avctx, is_output);
  261. avcodec_free_context(&avctx);
  262. snprintf(tmp, sizeof(tmp), " Stream #%d:%d", index, i);
  263. str += tmp;
  264. if (flags & AVFMT_SHOW_IDS)
  265. {
  266. snprintf(tmp, sizeof(tmp), "[0x%x]", st->id);
  267. str += tmp;
  268. }
  269. if (lang)
  270. {
  271. snprintf(tmp, sizeof(tmp), "(%s)", lang->value);
  272. str += tmp;
  273. }
  274. snprintf(tmp, sizeof(tmp), ": %s", buf);
  275. str += tmp;
  276. if (st->sample_aspect_ratio.num &&
  277. av_cmp_q(st->sample_aspect_ratio, st->codecpar->sample_aspect_ratio))
  278. {
  279. AVRational display_aspect_ratio;
  280. av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
  281. st->codecpar->width * (int64_t)st->sample_aspect_ratio.num,
  282. st->codecpar->height * (int64_t)st->sample_aspect_ratio.den,
  283. 1024 * 1024);
  284. snprintf(tmp, sizeof(tmp), ", SAR %d:%d DAR %d:%d",
  285. st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
  286. display_aspect_ratio.num, display_aspect_ratio.den);
  287. str += tmp;
  288. }
  289. if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
  290. {
  291. int fps = st->avg_frame_rate.den && st->avg_frame_rate.num;
  292. int tbr = st->r_frame_rate.den && st->r_frame_rate.num;
  293. int tbn = st->time_base.den && st->time_base.num;
  294. if (fps || tbr || tbn)
  295. {
  296. snprintf(tmp, sizeof(tmp), "%s", separator);
  297. str += tmp;
  298. }
  299. if (fps)
  300. str +=
  301. print_fps(av_q2d(st->avg_frame_rate), tbr || tbn ? "fps, " : "fps");
  302. if (tbr)
  303. str += print_fps(av_q2d(st->r_frame_rate), tbn ? "tbr, " : "tbr");
  304. if (tbn)
  305. str += print_fps(1 / av_q2d(st->time_base), "tbn");
  306. }
  307. if (st->disposition & AV_DISPOSITION_DEFAULT)
  308. str += " (default)";
  309. if (st->disposition & AV_DISPOSITION_DUB)
  310. str += " (dub)";
  311. if (st->disposition & AV_DISPOSITION_ORIGINAL)
  312. str += " (original)";
  313. if (st->disposition & AV_DISPOSITION_COMMENT)
  314. str += " (comment)";
  315. if (st->disposition & AV_DISPOSITION_LYRICS)
  316. str += " (lyrics)";
  317. if (st->disposition & AV_DISPOSITION_KARAOKE)
  318. str += " (karaoke)";
  319. if (st->disposition & AV_DISPOSITION_FORCED)
  320. str += " (forced)";
  321. if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
  322. str += " (hearing impaired)";
  323. if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
  324. str += " (visual impaired)";
  325. if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
  326. str += " (clean effects)";
  327. if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
  328. str += " (attached pic)";
  329. if (st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS)
  330. str += " (timed thumbnails)";
  331. if (st->disposition & AV_DISPOSITION_CAPTIONS)
  332. str += " (captions)";
  333. if (st->disposition & AV_DISPOSITION_DESCRIPTIONS)
  334. str += " (descriptions)";
  335. if (st->disposition & AV_DISPOSITION_METADATA)
  336. str += " (metadata)";
  337. if (st->disposition & AV_DISPOSITION_DEPENDENT)
  338. str += " (dependent)";
  339. if (st->disposition & AV_DISPOSITION_STILL_IMAGE)
  340. str += " (still image)";
  341. str += "\n";
  342. str += dump_metadata(st->metadata, " ");
  343. str += dump_sidedata(st, " ");
  344. return str;
  345. fail:
  346. return QString("");
  347. }
  348. QString print_fps(double d, const char* postfix)
  349. {
  350. char tmp[BUFF_MAXLEN];
  351. uint64_t v = lrintf(d * 100);
  352. if (!v)
  353. {
  354. snprintf(tmp, sizeof(tmp), "%1.4f %s", d, postfix);
  355. }
  356. else if (v % 100)
  357. {
  358. snprintf(tmp, sizeof(tmp), "%3.2f %s", d, postfix);
  359. }
  360. else if (v % (100 * 1000))
  361. {
  362. snprintf(tmp, sizeof(tmp), "%1.0f %s", d, postfix);
  363. }
  364. else
  365. {
  366. snprintf(tmp, sizeof(tmp), "%1.0fk %s", d / 1000, postfix);
  367. }
  368. return QString(tmp);
  369. }
  370. QString dump_sidedata(const AVStream* st, const char* indent)
  371. {
  372. QString str;
  373. char tmp[BUFF_MAXLEN];
  374. if (!st->codecpar)
  375. return str;
  376. if (st->codecpar->nb_coded_side_data)
  377. {
  378. snprintf(tmp, sizeof(tmp), "%sSide data:\n", indent);
  379. str += tmp;
  380. }
  381. for (int i = 0; i < st->codecpar->nb_coded_side_data; i++)
  382. {
  383. const AVPacketSideData* sd = &st->codecpar->coded_side_data[i];
  384. snprintf(tmp, sizeof(tmp), "%s ", indent);
  385. str += tmp;
  386. switch (sd->type)
  387. {
  388. case AV_PKT_DATA_PALETTE:
  389. str += "palette";
  390. break;
  391. case AV_PKT_DATA_NEW_EXTRADATA:
  392. str += "new extradata";
  393. break;
  394. case AV_PKT_DATA_PARAM_CHANGE:
  395. str += "paramchange: ";
  396. // dump_paramchange(ctx, sd);
  397. break;
  398. case AV_PKT_DATA_H263_MB_INFO:
  399. str += "H.263 macroblock info";
  400. break;
  401. case AV_PKT_DATA_REPLAYGAIN:
  402. str += "replaygain: ";
  403. // dump_replaygain(ctx, sd);
  404. break;
  405. case AV_PKT_DATA_DISPLAYMATRIX:
  406. {
  407. snprintf(tmp, sizeof(tmp), "displaymatrix: rotation of %.2f degrees",
  408. av_display_rotation_get((const int32_t*)sd->data));
  409. str += tmp;
  410. }
  411. break;
  412. case AV_PKT_DATA_STEREO3D:
  413. str += "stereo3d: ";
  414. // dump_stereo3d(ctx, sd);
  415. break;
  416. case AV_PKT_DATA_AUDIO_SERVICE_TYPE:
  417. str += "audio service type: ";
  418. // dump_audioservicetype(ctx, sd);
  419. break;
  420. case AV_PKT_DATA_QUALITY_STATS:
  421. {
  422. snprintf(tmp, sizeof(tmp), "quality factor: %p, pict_type: %c", sd->data,
  423. av_get_picture_type_char(AVPictureType(sd->data[4])));
  424. str += tmp;
  425. }
  426. break;
  427. case AV_PKT_DATA_CPB_PROPERTIES:
  428. str += "cpb: ";
  429. // dump_cpb(ctx, sd);
  430. break;
  431. case AV_PKT_DATA_MASTERING_DISPLAY_METADATA:
  432. // dump_mastering_display_metadata(ctx, sd);
  433. break;
  434. case AV_PKT_DATA_SPHERICAL:
  435. str += "spherical: ";
  436. // dump_spherical(ctx, st->codecpar, sd);
  437. break;
  438. case AV_PKT_DATA_CONTENT_LIGHT_LEVEL:
  439. // dump_content_light_metadata(ctx, sd);
  440. break;
  441. case AV_PKT_DATA_ICC_PROFILE:
  442. str += "ICC Profile";
  443. break;
  444. case AV_PKT_DATA_DOVI_CONF:
  445. str += "DOVI configuration record: ";
  446. // dump_dovi_conf(ctx, sd);
  447. break;
  448. case AV_PKT_DATA_S12M_TIMECODE:
  449. str += "SMPTE ST 12-1:2014: ";
  450. // dump_s12m_timecode(ctx, st, sd);
  451. break;
  452. default:
  453. {
  454. snprintf(tmp, sizeof(tmp), "unknown side data type %d, size:%llu bytes",
  455. sd->type, sd->size);
  456. str += tmp;
  457. }
  458. break;
  459. }
  460. str += "\n";
  461. }
  462. return str;
  463. }