format_cache.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2014, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Media Format Cache API
  21. *
  22. * \author Joshua Colp <jcolp@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. #include "asterisk/logger.h"
  29. #include "asterisk/format.h"
  30. #include "asterisk/format_cache.h"
  31. #include "asterisk/astobj2.h"
  32. #include "asterisk/strings.h"
  33. /*!
  34. * \brief Built-in cached signed linear 8kHz format.
  35. */
  36. struct ast_format *ast_format_slin;
  37. /*!
  38. * \brief Built-in cached signed linear 12kHz format.
  39. */
  40. struct ast_format *ast_format_slin12;
  41. /*!
  42. * \brief Built-in cached signed linear 16kHz format.
  43. */
  44. struct ast_format *ast_format_slin16;
  45. /*!
  46. * \brief Built-in cached signed linear 24kHz format.
  47. */
  48. struct ast_format *ast_format_slin24;
  49. /*!
  50. * \brief Built-in cached signed linear 32kHz format.
  51. */
  52. struct ast_format *ast_format_slin32;
  53. /*!
  54. * \brief Built-in cached signed linear 44kHz format.
  55. */
  56. struct ast_format *ast_format_slin44;
  57. /*!
  58. * \brief Built-in cached signed linear 48kHz format.
  59. */
  60. struct ast_format *ast_format_slin48;
  61. /*!
  62. * \brief Built-in cached signed linear 96kHz format.
  63. */
  64. struct ast_format *ast_format_slin96;
  65. /*!
  66. * \brief Built-in cached signed linear 192kHz format.
  67. */
  68. struct ast_format *ast_format_slin192;
  69. /*!
  70. * \brief Built-in cached ulaw format.
  71. */
  72. struct ast_format *ast_format_ulaw;
  73. /*!
  74. * \brief Built-in cached alaw format.
  75. */
  76. struct ast_format *ast_format_alaw;
  77. /*!
  78. * \brief Built-in cached gsm format.
  79. */
  80. struct ast_format *ast_format_gsm;
  81. /*!
  82. * \brief Built-in cached adpcm format.
  83. */
  84. struct ast_format *ast_format_adpcm;
  85. /*!
  86. * \brief Built-in cached g722 format.
  87. */
  88. struct ast_format *ast_format_g722;
  89. /*!
  90. * \brief Built-in cached g726 format.
  91. */
  92. struct ast_format *ast_format_g726;
  93. /*!
  94. * \brief Built-in cached g726-aal2 format.
  95. */
  96. struct ast_format *ast_format_g726_aal2;
  97. /*!
  98. * \brief Built-in cached ilbc format.
  99. */
  100. struct ast_format *ast_format_ilbc;
  101. /*!
  102. * \brief Built-in cached ilbc format.
  103. */
  104. struct ast_format *ast_format_lpc10;
  105. /*!
  106. * \brief Built-in cached speex format.
  107. */
  108. struct ast_format *ast_format_speex;
  109. /*!
  110. * \brief Built-in cached speex at 16kHz format.
  111. */
  112. struct ast_format *ast_format_speex16;
  113. /*!
  114. * \brief Built-in cached speex at 32kHz format.
  115. */
  116. struct ast_format *ast_format_speex32;
  117. /*!
  118. * \brief Built-in cached g723.1 format.
  119. */
  120. struct ast_format *ast_format_g723;
  121. /*!
  122. * \brief Built-in cached g729 format.
  123. */
  124. struct ast_format *ast_format_g729;
  125. /*!
  126. * \brief Built-in cached g719 format.
  127. */
  128. struct ast_format *ast_format_g719;
  129. /*!
  130. * \brief Built-in cached h261 format.
  131. */
  132. struct ast_format *ast_format_h261;
  133. /*!
  134. * \brief Built-in cached h263 format.
  135. */
  136. struct ast_format *ast_format_h263;
  137. /*!
  138. * \brief Built-in cached h263 plus format.
  139. */
  140. struct ast_format *ast_format_h263p;
  141. /*!
  142. * \brief Built-in cached h264 format.
  143. */
  144. struct ast_format *ast_format_h264;
  145. /*!
  146. * \brief Built-in cached h265 format.
  147. */
  148. struct ast_format *ast_format_h265;
  149. /*!
  150. * \brief Built-in cached mp4 format.
  151. */
  152. struct ast_format *ast_format_mp4;
  153. /*!
  154. * \brief Built-in cached vp8 format.
  155. */
  156. struct ast_format *ast_format_vp8;
  157. /*!
  158. * \brief Built-in cached vp9 format.
  159. */
  160. struct ast_format *ast_format_vp9;
  161. /*!
  162. * \brief Built-in cached jpeg format.
  163. */
  164. struct ast_format *ast_format_jpeg;
  165. /*!
  166. * \brief Built-in cached png format.
  167. */
  168. struct ast_format *ast_format_png;
  169. /*!
  170. * \brief Built-in cached siren14 format.
  171. */
  172. struct ast_format *ast_format_siren14;
  173. /*!
  174. * \brief Built-in cached siren7 format.
  175. */
  176. struct ast_format *ast_format_siren7;
  177. /*!
  178. * \brief Built-in cached opus format.
  179. */
  180. struct ast_format *ast_format_opus;
  181. /*!
  182. * \brief Built-in cached codec2 format.
  183. */
  184. struct ast_format *ast_format_codec2;
  185. /*!
  186. * \brief Built-in cached t140 format.
  187. */
  188. struct ast_format *ast_format_t140;
  189. /*!
  190. * \brief Built-in cached t140 red format.
  191. */
  192. struct ast_format *ast_format_t140_red;
  193. /*!
  194. * \brief Built-in cached T.38 format.
  195. */
  196. struct ast_format *ast_format_t38;
  197. /*!
  198. * \brief Built-in "null" format.
  199. */
  200. struct ast_format *ast_format_none;
  201. /*!
  202. * \brief Built-in "silk" format
  203. */
  204. struct ast_format *ast_format_silk8;
  205. struct ast_format *ast_format_silk12;
  206. struct ast_format *ast_format_silk16;
  207. struct ast_format *ast_format_silk24;
  208. /*! \brief Number of buckets to use for the media format cache (should be prime for performance reasons) */
  209. #define CACHE_BUCKETS 53
  210. /*! \brief Cached formats */
  211. static struct ao2_container *formats;
  212. static int format_hash_cb(const void *obj, int flags)
  213. {
  214. const struct ast_format *format;
  215. const char *key;
  216. switch (flags & OBJ_SEARCH_MASK) {
  217. case OBJ_SEARCH_KEY:
  218. key = obj;
  219. return ast_str_case_hash(key);
  220. case OBJ_SEARCH_OBJECT:
  221. format = obj;
  222. return ast_str_case_hash(ast_format_get_name(format));
  223. default:
  224. /* Hash can only work on something with a full key. */
  225. ast_assert(0);
  226. return 0;
  227. }
  228. }
  229. static int format_cmp_cb(void *obj, void *arg, int flags)
  230. {
  231. const struct ast_format *left = obj;
  232. const struct ast_format *right = arg;
  233. const char *right_key = arg;
  234. int cmp;
  235. switch (flags & OBJ_SEARCH_MASK) {
  236. case OBJ_SEARCH_OBJECT:
  237. right_key = ast_format_get_name(right);
  238. /* Fall through */
  239. case OBJ_SEARCH_KEY:
  240. cmp = strcasecmp(ast_format_get_name(left), right_key);
  241. break;
  242. case OBJ_SEARCH_PARTIAL_KEY:
  243. cmp = strncasecmp(ast_format_get_name(left), right_key, strlen(right_key));
  244. break;
  245. default:
  246. ast_assert(0);
  247. cmp = 0;
  248. break;
  249. }
  250. if (cmp) {
  251. return 0;
  252. }
  253. return CMP_MATCH;
  254. }
  255. /*! \brief Function called when the process is shutting down */
  256. static void format_cache_shutdown(void)
  257. {
  258. ao2_cleanup(formats);
  259. formats = NULL;
  260. ao2_replace(ast_format_g723, NULL);
  261. ao2_replace(ast_format_ulaw, NULL);
  262. ao2_replace(ast_format_alaw, NULL);
  263. ao2_replace(ast_format_gsm, NULL);
  264. ao2_replace(ast_format_g726, NULL);
  265. ao2_replace(ast_format_g726_aal2, NULL);
  266. ao2_replace(ast_format_adpcm, NULL);
  267. ao2_replace(ast_format_slin, NULL);
  268. ao2_replace(ast_format_slin12, NULL);
  269. ao2_replace(ast_format_slin16, NULL);
  270. ao2_replace(ast_format_slin24, NULL);
  271. ao2_replace(ast_format_slin32, NULL);
  272. ao2_replace(ast_format_slin44, NULL);
  273. ao2_replace(ast_format_slin48, NULL);
  274. ao2_replace(ast_format_slin96, NULL);
  275. ao2_replace(ast_format_slin192, NULL);
  276. ao2_replace(ast_format_lpc10, NULL);
  277. ao2_replace(ast_format_g729, NULL);
  278. ao2_replace(ast_format_speex, NULL);
  279. ao2_replace(ast_format_speex16, NULL);
  280. ao2_replace(ast_format_speex32, NULL);
  281. ao2_replace(ast_format_ilbc, NULL);
  282. ao2_replace(ast_format_g722, NULL);
  283. ao2_replace(ast_format_siren7, NULL);
  284. ao2_replace(ast_format_siren14, NULL);
  285. ao2_replace(ast_format_g719, NULL);
  286. ao2_replace(ast_format_opus, NULL);
  287. ao2_replace(ast_format_codec2, NULL);
  288. ao2_replace(ast_format_jpeg, NULL);
  289. ao2_replace(ast_format_png, NULL);
  290. ao2_replace(ast_format_h261, NULL);
  291. ao2_replace(ast_format_h263, NULL);
  292. ao2_replace(ast_format_h263p, NULL);
  293. ao2_replace(ast_format_h264, NULL);
  294. ao2_replace(ast_format_h265, NULL);
  295. ao2_replace(ast_format_mp4, NULL);
  296. ao2_replace(ast_format_vp8, NULL);
  297. ao2_replace(ast_format_vp9, NULL);
  298. ao2_replace(ast_format_t140_red, NULL);
  299. ao2_replace(ast_format_t140, NULL);
  300. ao2_replace(ast_format_t38, NULL);
  301. ao2_replace(ast_format_none, NULL);
  302. ao2_replace(ast_format_silk8, NULL);
  303. ao2_replace(ast_format_silk12, NULL);
  304. ao2_replace(ast_format_silk16, NULL);
  305. ao2_replace(ast_format_silk24, NULL);
  306. }
  307. int ast_format_cache_init(void)
  308. {
  309. formats = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0, CACHE_BUCKETS,
  310. format_hash_cb, NULL, format_cmp_cb);
  311. if (!formats) {
  312. return -1;
  313. }
  314. ast_register_cleanup(format_cache_shutdown);
  315. return 0;
  316. }
  317. static void set_cached_format(const char *name, struct ast_format *format)
  318. {
  319. if (!strcmp(name, "codec2")) {
  320. ao2_replace(ast_format_codec2, format);
  321. } else if (!strcmp(name, "g723")) {
  322. ao2_replace(ast_format_g723, format);
  323. } else if (!strcmp(name, "ulaw")) {
  324. ao2_replace(ast_format_ulaw, format);
  325. } else if (!strcmp(name, "alaw")) {
  326. ao2_replace(ast_format_alaw, format);
  327. } else if (!strcmp(name, "gsm")) {
  328. ao2_replace(ast_format_gsm, format);
  329. } else if (!strcmp(name, "g726")) {
  330. ao2_replace(ast_format_g726, format);
  331. } else if (!strcmp(name, "g726aal2")) {
  332. ao2_replace(ast_format_g726_aal2, format);
  333. } else if (!strcmp(name, "adpcm")) {
  334. ao2_replace(ast_format_adpcm, format);
  335. } else if (!strcmp(name, "slin")) {
  336. ao2_replace(ast_format_slin, format);
  337. } else if (!strcmp(name, "slin12")) {
  338. ao2_replace(ast_format_slin12, format);
  339. } else if (!strcmp(name, "slin16")) {
  340. ao2_replace(ast_format_slin16, format);
  341. } else if (!strcmp(name, "slin24")) {
  342. ao2_replace(ast_format_slin24, format);
  343. } else if (!strcmp(name, "slin32")) {
  344. ao2_replace(ast_format_slin32, format);
  345. } else if (!strcmp(name, "slin44")) {
  346. ao2_replace(ast_format_slin44, format);
  347. } else if (!strcmp(name, "slin48")) {
  348. ao2_replace(ast_format_slin48, format);
  349. } else if (!strcmp(name, "slin96")) {
  350. ao2_replace(ast_format_slin96, format);
  351. } else if (!strcmp(name, "slin192")) {
  352. ao2_replace(ast_format_slin192, format);
  353. } else if (!strcmp(name, "lpc10")) {
  354. ao2_replace(ast_format_lpc10, format);
  355. } else if (!strcmp(name, "g729")) {
  356. ao2_replace(ast_format_g729, format);
  357. } else if (!strcmp(name, "speex")) {
  358. ao2_replace(ast_format_speex, format);
  359. } else if (!strcmp(name, "speex16")) {
  360. ao2_replace(ast_format_speex16, format);
  361. } else if (!strcmp(name, "speex32")) {
  362. ao2_replace(ast_format_speex32, format);
  363. } else if (!strcmp(name, "ilbc")) {
  364. ao2_replace(ast_format_ilbc, format);
  365. } else if (!strcmp(name, "g722")) {
  366. ao2_replace(ast_format_g722, format);
  367. } else if (!strcmp(name, "siren7")) {
  368. ao2_replace(ast_format_siren7, format);
  369. } else if (!strcmp(name, "siren14")) {
  370. ao2_replace(ast_format_siren14, format);
  371. } else if (!strcmp(name, "g719")) {
  372. ao2_replace(ast_format_g719, format);
  373. } else if (!strcmp(name, "opus")) {
  374. ao2_replace(ast_format_opus, format);
  375. } else if (!strcmp(name, "jpeg")) {
  376. ao2_replace(ast_format_jpeg, format);
  377. } else if (!strcmp(name, "png")) {
  378. ao2_replace(ast_format_png, format);
  379. } else if (!strcmp(name, "h261")) {
  380. ao2_replace(ast_format_h261, format);
  381. } else if (!strcmp(name, "h263")) {
  382. ao2_replace(ast_format_h263, format);
  383. } else if (!strcmp(name, "h263p")) {
  384. ao2_replace(ast_format_h263p, format);
  385. } else if (!strcmp(name, "h264")) {
  386. ao2_replace(ast_format_h264, format);
  387. } else if (!strcmp(name, "h265")) {
  388. ao2_replace(ast_format_h265, format);
  389. } else if (!strcmp(name, "mpeg4")) {
  390. ao2_replace(ast_format_mp4, format);
  391. } else if (!strcmp(name, "vp8")) {
  392. ao2_replace(ast_format_vp8, format);
  393. } else if (!strcmp(name, "vp9")) {
  394. ao2_replace(ast_format_vp9, format);
  395. } else if (!strcmp(name, "red")) {
  396. ao2_replace(ast_format_t140_red, format);
  397. } else if (!strcmp(name, "t140")) {
  398. ao2_replace(ast_format_t140, format);
  399. } else if (!strcmp(name, "t38")) {
  400. ao2_replace(ast_format_t38, format);
  401. } else if (!strcmp(name, "none")) {
  402. ao2_replace(ast_format_none, format);
  403. } else if (!strcmp(name, "silk8")) {
  404. ao2_replace(ast_format_silk8, format);
  405. } else if (!strcmp(name, "silk12")) {
  406. ao2_replace(ast_format_silk12, format);
  407. } else if (!strcmp(name, "silk16")) {
  408. ao2_replace(ast_format_silk16, format);
  409. } else if (!strcmp(name, "silk24")) {
  410. ao2_replace(ast_format_silk24, format);
  411. }
  412. }
  413. int ast_format_cache_set(struct ast_format *format)
  414. {
  415. SCOPED_AO2WRLOCK(lock, formats);
  416. struct ast_format *old_format;
  417. ast_assert(format != NULL);
  418. if (ast_strlen_zero(ast_format_get_name(format))) {
  419. return -1;
  420. }
  421. old_format = ao2_find(formats, ast_format_get_name(format), OBJ_SEARCH_KEY | OBJ_NOLOCK);
  422. if (old_format) {
  423. ao2_unlink_flags(formats, old_format, OBJ_NOLOCK);
  424. }
  425. ao2_link_flags(formats, format, OBJ_NOLOCK);
  426. set_cached_format(ast_format_get_name(format), format);
  427. ast_verb(5, "%s cached format with name '%s'\n",
  428. old_format ? "Updated" : "Created",
  429. ast_format_get_name(format));
  430. ao2_cleanup(old_format);
  431. return 0;
  432. }
  433. struct ast_format *__ast_format_cache_get(const char *name,
  434. const char *tag, const char *file, int line, const char *func)
  435. {
  436. if (ast_strlen_zero(name)) {
  437. return NULL;
  438. }
  439. return __ao2_find(formats, name, OBJ_SEARCH_KEY, tag, file, line, func);
  440. }
  441. struct ast_format *ast_format_cache_get_slin_by_rate(unsigned int rate)
  442. {
  443. if (rate >= 192000) {
  444. return ast_format_slin192;
  445. } else if (rate >= 96000) {
  446. return ast_format_slin96;
  447. } else if (rate >= 48000) {
  448. return ast_format_slin48;
  449. } else if (rate >= 44100) {
  450. return ast_format_slin44;
  451. } else if (rate >= 32000) {
  452. return ast_format_slin32;
  453. } else if (rate >= 24000) {
  454. return ast_format_slin24;
  455. } else if (rate >= 16000) {
  456. return ast_format_slin16;
  457. } else if (rate >= 12000) {
  458. return ast_format_slin12;
  459. }
  460. return ast_format_slin;
  461. }
  462. int ast_format_cache_is_slinear(struct ast_format *format)
  463. {
  464. if ((ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)
  465. || (ast_format_cmp(format, ast_format_slin12) == AST_FORMAT_CMP_EQUAL)
  466. || (ast_format_cmp(format, ast_format_slin16) == AST_FORMAT_CMP_EQUAL)
  467. || (ast_format_cmp(format, ast_format_slin24) == AST_FORMAT_CMP_EQUAL)
  468. || (ast_format_cmp(format, ast_format_slin32) == AST_FORMAT_CMP_EQUAL)
  469. || (ast_format_cmp(format, ast_format_slin44) == AST_FORMAT_CMP_EQUAL)
  470. || (ast_format_cmp(format, ast_format_slin48) == AST_FORMAT_CMP_EQUAL)
  471. || (ast_format_cmp(format, ast_format_slin96) == AST_FORMAT_CMP_EQUAL)
  472. || (ast_format_cmp(format, ast_format_slin192) == AST_FORMAT_CMP_EQUAL)) {
  473. return 1;
  474. }
  475. return 0;
  476. }
  477. struct ast_format *ast_format_cache_get_by_codec(const struct ast_codec *codec)
  478. {
  479. struct ast_format *format;
  480. struct ao2_iterator it;
  481. for (it = ao2_iterator_init(formats, 0);
  482. (format = ao2_iterator_next(&it));
  483. ao2_ref(format, -1)) {
  484. struct ast_codec *candidate = ast_format_get_codec(format);
  485. if (codec == candidate) {
  486. ao2_cleanup(candidate);
  487. ao2_iterator_destroy(&it);
  488. return format;
  489. }
  490. ao2_cleanup(candidate);
  491. }
  492. ao2_iterator_destroy(&it);
  493. return NULL;
  494. }