format_cache.c 14 KB

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