format_cache.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  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 jpeg format.
  160. */
  161. struct ast_format *ast_format_jpeg;
  162. /*!
  163. * \brief Built-in cached png format.
  164. */
  165. struct ast_format *ast_format_png;
  166. /*!
  167. * \brief Built-in cached siren14 format.
  168. */
  169. struct ast_format *ast_format_siren14;
  170. /*!
  171. * \brief Built-in cached siren7 format.
  172. */
  173. struct ast_format *ast_format_siren7;
  174. /*!
  175. * \brief Built-in cached opus format.
  176. */
  177. struct ast_format *ast_format_opus;
  178. /*!
  179. * \brief Built-in cached t140 format.
  180. */
  181. struct ast_format *ast_format_t140;
  182. /*!
  183. * \brief Built-in cached t140 red format.
  184. */
  185. struct ast_format *ast_format_t140_red;
  186. /*!
  187. * \brief Built-in "null" format.
  188. */
  189. struct ast_format *ast_format_none;
  190. /*! \brief Number of buckets to use for the media format cache (should be prime for performance reasons) */
  191. #define CACHE_BUCKETS 53
  192. /*! \brief Cached formats */
  193. static struct ao2_container *formats;
  194. static int format_hash_cb(const void *obj, int flags)
  195. {
  196. const struct ast_format *format;
  197. const char *key;
  198. switch (flags & OBJ_SEARCH_MASK) {
  199. case OBJ_SEARCH_KEY:
  200. key = obj;
  201. return ast_str_case_hash(key);
  202. case OBJ_SEARCH_OBJECT:
  203. format = obj;
  204. return ast_str_case_hash(ast_format_get_name(format));
  205. default:
  206. /* Hash can only work on something with a full key. */
  207. ast_assert(0);
  208. return 0;
  209. }
  210. }
  211. static int format_cmp_cb(void *obj, void *arg, int flags)
  212. {
  213. const struct ast_format *left = obj;
  214. const struct ast_format *right = arg;
  215. const char *right_key = arg;
  216. int cmp;
  217. switch (flags & OBJ_SEARCH_MASK) {
  218. case OBJ_SEARCH_OBJECT:
  219. right_key = ast_format_get_name(right);
  220. /* Fall through */
  221. case OBJ_SEARCH_KEY:
  222. cmp = strcasecmp(ast_format_get_name(left), right_key);
  223. break;
  224. case OBJ_SEARCH_PARTIAL_KEY:
  225. cmp = strncasecmp(ast_format_get_name(left), right_key, strlen(right_key));
  226. break;
  227. default:
  228. ast_assert(0);
  229. cmp = 0;
  230. break;
  231. }
  232. if (cmp) {
  233. return 0;
  234. }
  235. return CMP_MATCH;
  236. }
  237. /*! \brief Function called when the process is shutting down */
  238. static void format_cache_shutdown(void)
  239. {
  240. ao2_cleanup(formats);
  241. formats = NULL;
  242. ao2_replace(ast_format_g723, NULL);
  243. ao2_replace(ast_format_ulaw, NULL);
  244. ao2_replace(ast_format_alaw, NULL);
  245. ao2_replace(ast_format_gsm, NULL);
  246. ao2_replace(ast_format_g726, NULL);
  247. ao2_replace(ast_format_g726_aal2, NULL);
  248. ao2_replace(ast_format_adpcm, NULL);
  249. ao2_replace(ast_format_slin, NULL);
  250. ao2_replace(ast_format_slin12, NULL);
  251. ao2_replace(ast_format_slin16, NULL);
  252. ao2_replace(ast_format_slin24, NULL);
  253. ao2_replace(ast_format_slin32, NULL);
  254. ao2_replace(ast_format_slin44, NULL);
  255. ao2_replace(ast_format_slin48, NULL);
  256. ao2_replace(ast_format_slin96, NULL);
  257. ao2_replace(ast_format_slin192, NULL);
  258. ao2_replace(ast_format_lpc10, NULL);
  259. ao2_replace(ast_format_g729, NULL);
  260. ao2_replace(ast_format_speex, NULL);
  261. ao2_replace(ast_format_speex16, NULL);
  262. ao2_replace(ast_format_speex32, NULL);
  263. ao2_replace(ast_format_ilbc, NULL);
  264. ao2_replace(ast_format_g722, NULL);
  265. ao2_replace(ast_format_siren7, NULL);
  266. ao2_replace(ast_format_siren14, NULL);
  267. ao2_replace(ast_format_testlaw, NULL);
  268. ao2_replace(ast_format_g719, NULL);
  269. ao2_replace(ast_format_opus, NULL);
  270. ao2_replace(ast_format_jpeg, NULL);
  271. ao2_replace(ast_format_png, NULL);
  272. ao2_replace(ast_format_h261, NULL);
  273. ao2_replace(ast_format_h263, NULL);
  274. ao2_replace(ast_format_h263p, NULL);
  275. ao2_replace(ast_format_h264, NULL);
  276. ao2_replace(ast_format_mp4, NULL);
  277. ao2_replace(ast_format_vp8, NULL);
  278. ao2_replace(ast_format_t140_red, NULL);
  279. ao2_replace(ast_format_t140, NULL);
  280. ao2_replace(ast_format_none, NULL);
  281. }
  282. int ast_format_cache_init(void)
  283. {
  284. formats = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CACHE_BUCKETS,
  285. format_hash_cb, format_cmp_cb);
  286. if (!formats) {
  287. return -1;
  288. }
  289. ast_register_cleanup(format_cache_shutdown);
  290. return 0;
  291. }
  292. static void set_cached_format(const char *name, struct ast_format *format)
  293. {
  294. if (!strcmp(name, "g723")) {
  295. ao2_replace(ast_format_g723, format);
  296. } else if (!strcmp(name, "ulaw")) {
  297. ao2_replace(ast_format_ulaw, format);
  298. } else if (!strcmp(name, "alaw")) {
  299. ao2_replace(ast_format_alaw, format);
  300. } else if (!strcmp(name, "gsm")) {
  301. ao2_replace(ast_format_gsm, format);
  302. } else if (!strcmp(name, "g726")) {
  303. ao2_replace(ast_format_g726, format);
  304. } else if (!strcmp(name, "g726aal2")) {
  305. ao2_replace(ast_format_g726_aal2, format);
  306. } else if (!strcmp(name, "adpcm")) {
  307. ao2_replace(ast_format_adpcm, format);
  308. } else if (!strcmp(name, "slin")) {
  309. ao2_replace(ast_format_slin, format);
  310. } else if (!strcmp(name, "slin12")) {
  311. ao2_replace(ast_format_slin12, format);
  312. } else if (!strcmp(name, "slin16")) {
  313. ao2_replace(ast_format_slin16, format);
  314. } else if (!strcmp(name, "slin24")) {
  315. ao2_replace(ast_format_slin24, format);
  316. } else if (!strcmp(name, "slin32")) {
  317. ao2_replace(ast_format_slin32, format);
  318. } else if (!strcmp(name, "slin44")) {
  319. ao2_replace(ast_format_slin44, format);
  320. } else if (!strcmp(name, "slin48")) {
  321. ao2_replace(ast_format_slin48, format);
  322. } else if (!strcmp(name, "slin96")) {
  323. ao2_replace(ast_format_slin96, format);
  324. } else if (!strcmp(name, "slin192")) {
  325. ao2_replace(ast_format_slin192, format);
  326. } else if (!strcmp(name, "lpc10")) {
  327. ao2_replace(ast_format_lpc10, format);
  328. } else if (!strcmp(name, "g729")) {
  329. ao2_replace(ast_format_g729, format);
  330. } else if (!strcmp(name, "speex")) {
  331. ao2_replace(ast_format_speex, format);
  332. } else if (!strcmp(name, "speex16")) {
  333. ao2_replace(ast_format_speex16, format);
  334. } else if (!strcmp(name, "speex32")) {
  335. ao2_replace(ast_format_speex32, format);
  336. } else if (!strcmp(name, "ilbc")) {
  337. ao2_replace(ast_format_ilbc, format);
  338. } else if (!strcmp(name, "g722")) {
  339. ao2_replace(ast_format_g722, format);
  340. } else if (!strcmp(name, "siren7")) {
  341. ao2_replace(ast_format_siren7, format);
  342. } else if (!strcmp(name, "siren14")) {
  343. ao2_replace(ast_format_siren14, format);
  344. } else if (!strcmp(name, "testlaw")) {
  345. ao2_replace(ast_format_testlaw, format);
  346. } else if (!strcmp(name, "g719")) {
  347. ao2_replace(ast_format_g719, format);
  348. } else if (!strcmp(name, "opus")) {
  349. ao2_replace(ast_format_opus, format);
  350. } else if (!strcmp(name, "jpeg")) {
  351. ao2_replace(ast_format_jpeg, format);
  352. } else if (!strcmp(name, "png")) {
  353. ao2_replace(ast_format_png, format);
  354. } else if (!strcmp(name, "h261")) {
  355. ao2_replace(ast_format_h261, format);
  356. } else if (!strcmp(name, "h263")) {
  357. ao2_replace(ast_format_h263, format);
  358. } else if (!strcmp(name, "h263p")) {
  359. ao2_replace(ast_format_h263p, format);
  360. } else if (!strcmp(name, "h264")) {
  361. ao2_replace(ast_format_h264, format);
  362. } else if (!strcmp(name, "mpeg4")) {
  363. ao2_replace(ast_format_mp4, format);
  364. } else if (!strcmp(name, "vp8")) {
  365. ao2_replace(ast_format_vp8, format);
  366. } else if (!strcmp(name, "red")) {
  367. ao2_replace(ast_format_t140_red, format);
  368. } else if (!strcmp(name, "t140")) {
  369. ao2_replace(ast_format_t140, format);
  370. } else if (!strcmp(name, "none")) {
  371. ao2_replace(ast_format_none, format);
  372. }
  373. }
  374. int ast_format_cache_set(struct ast_format *format)
  375. {
  376. SCOPED_AO2WRLOCK(lock, formats);
  377. struct ast_format *old_format;
  378. ast_assert(format != NULL);
  379. if (ast_strlen_zero(ast_format_get_name(format))) {
  380. return -1;
  381. }
  382. old_format = ao2_find(formats, ast_format_get_name(format), OBJ_SEARCH_KEY | OBJ_NOLOCK);
  383. if (old_format) {
  384. ao2_unlink_flags(formats, old_format, OBJ_NOLOCK);
  385. }
  386. ao2_link_flags(formats, format, OBJ_NOLOCK);
  387. set_cached_format(ast_format_get_name(format), format);
  388. ast_verb(2, "%s cached format with name '%s'\n",
  389. old_format ? "Updated" : "Created",
  390. ast_format_get_name(format));
  391. ao2_cleanup(old_format);
  392. return 0;
  393. }
  394. struct ast_format *__ast_format_cache_get(const char *name)
  395. {
  396. if (ast_strlen_zero(name)) {
  397. return NULL;
  398. }
  399. return ao2_find(formats, name, OBJ_SEARCH_KEY);
  400. }
  401. struct ast_format *__ast_format_cache_get_debug(const char *name, const char *tag, const char *file, int line, const char *func)
  402. {
  403. if (ast_strlen_zero(name)) {
  404. return NULL;
  405. }
  406. return __ao2_find_debug(formats, name, OBJ_SEARCH_KEY, S_OR(tag, "ast_format_cache_get"), file, line, func);
  407. }
  408. struct ast_format *ast_format_cache_get_slin_by_rate(unsigned int rate)
  409. {
  410. if (rate >= 192000) {
  411. return ast_format_slin192;
  412. } else if (rate >= 96000) {
  413. return ast_format_slin96;
  414. } else if (rate >= 48000) {
  415. return ast_format_slin48;
  416. } else if (rate >= 44100) {
  417. return ast_format_slin44;
  418. } else if (rate >= 32000) {
  419. return ast_format_slin32;
  420. } else if (rate >= 24000) {
  421. return ast_format_slin24;
  422. } else if (rate >= 16000) {
  423. return ast_format_slin16;
  424. } else if (rate >= 12000) {
  425. return ast_format_slin12;
  426. }
  427. return ast_format_slin;
  428. }
  429. int ast_format_cache_is_slinear(struct ast_format *format)
  430. {
  431. if ((ast_format_cmp(format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)
  432. || (ast_format_cmp(format, ast_format_slin12) == AST_FORMAT_CMP_EQUAL)
  433. || (ast_format_cmp(format, ast_format_slin16) == AST_FORMAT_CMP_EQUAL)
  434. || (ast_format_cmp(format, ast_format_slin24) == AST_FORMAT_CMP_EQUAL)
  435. || (ast_format_cmp(format, ast_format_slin32) == AST_FORMAT_CMP_EQUAL)
  436. || (ast_format_cmp(format, ast_format_slin44) == AST_FORMAT_CMP_EQUAL)
  437. || (ast_format_cmp(format, ast_format_slin48) == AST_FORMAT_CMP_EQUAL)
  438. || (ast_format_cmp(format, ast_format_slin96) == AST_FORMAT_CMP_EQUAL)
  439. || (ast_format_cmp(format, ast_format_slin192) == AST_FORMAT_CMP_EQUAL)) {
  440. return 1;
  441. }
  442. return 0;
  443. }