format.c 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2010, Digium, Inc.
  5. *
  6. * David Vossel <dvossel@digium.com>
  7. * Mark Spencer <markster@digium.com>
  8. *
  9. * See http://www.asterisk.org for more information about
  10. * the Asterisk project. Please do not directly contact
  11. * any of the maintainers of this project for assistance;
  12. * the project provides a web site, mailing lists and IRC
  13. * channels for your use.
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License Version 2. See the LICENSE file
  17. * at the top of the source tree.
  18. */
  19. /*!
  20. * \file
  21. * \brief Format API
  22. *
  23. * \author David Vossel <dvossel@digium.com>
  24. * \author Mark Spencer <markster@digium.com>
  25. */
  26. /*** MODULEINFO
  27. <support_level>core</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
  31. #include "asterisk/_private.h"
  32. #include "asterisk/format.h"
  33. #include "asterisk/astobj2.h"
  34. #include "asterisk/lock.h"
  35. #include "asterisk/frame.h"
  36. #include "asterisk/utils.h"
  37. #include "asterisk/cli.h"
  38. #include "asterisk/rtp_engine.h"
  39. #include "asterisk/config.h"
  40. #define FORMAT_CONFIG "codecs.conf"
  41. /*!
  42. * \brief Container for all the format attribute interfaces.
  43. * \note This container uses RWLOCKs instead of MUTEX locks. .
  44. * \note An ao2 container was chosen for fast lookup.
  45. */
  46. static struct ao2_container *interfaces;
  47. /*! a wrapper is used put interfaces into the ao2 container. */
  48. struct interface_ao2_wrapper {
  49. enum ast_format_id id;
  50. const struct ast_format_attr_interface *interface;
  51. };
  52. /*! \brief Format List container, This container is never directly accessed outside
  53. * of this file, and It only exists for building the format_list_array. */
  54. static struct ao2_container *format_list;
  55. /*! \brief Format List array is a read only array protected by a read write lock.
  56. * This array may be used outside this file with the use of reference counting to
  57. * guarantee safety for access by multiple threads. */
  58. static struct ast_format_list *format_list_array;
  59. static size_t format_list_array_len = 0;
  60. /*! \brief Locks the format list array so a reference can be taken safely. */
  61. static ast_rwlock_t format_list_array_lock;
  62. static int interface_cmp_cb(void *obj, void *arg, int flags)
  63. {
  64. struct interface_ao2_wrapper *wrapper1 = obj;
  65. struct interface_ao2_wrapper *wrapper2 = arg;
  66. return (wrapper2->id == wrapper1->id) ? CMP_MATCH | CMP_STOP : 0;
  67. }
  68. static int interface_hash_cb(const void *obj, const int flags)
  69. {
  70. const struct interface_ao2_wrapper *wrapper = obj;
  71. return wrapper->id;
  72. }
  73. void ast_format_copy(struct ast_format *dst, const struct ast_format *src)
  74. {
  75. *dst = *src;
  76. }
  77. void ast_format_set_video_mark(struct ast_format *format)
  78. {
  79. format->fattr.rtp_marker_bit = 1;
  80. }
  81. int ast_format_get_video_mark(const struct ast_format *format)
  82. {
  83. return format->fattr.rtp_marker_bit;
  84. }
  85. static struct interface_ao2_wrapper *find_interface(const struct ast_format *format)
  86. {
  87. struct interface_ao2_wrapper tmp_wrapper = {
  88. .id = format->id,
  89. };
  90. return ao2_find(interfaces, &tmp_wrapper, OBJ_POINTER);
  91. }
  92. static int has_interface(const struct ast_format *format)
  93. {
  94. struct interface_ao2_wrapper *wrapper;
  95. wrapper = find_interface(format);
  96. if (!wrapper) {
  97. return 0;
  98. }
  99. ao2_ref(wrapper, -1);
  100. return 1;
  101. }
  102. int ast_format_sdp_parse(struct ast_format *format, const char *attributes)
  103. {
  104. struct interface_ao2_wrapper *wrapper;
  105. int res;
  106. if (!(wrapper = find_interface(format))) {
  107. return 0;
  108. }
  109. ao2_rdlock(wrapper);
  110. if (!wrapper->interface || !wrapper->interface->format_attr_sdp_parse) {
  111. ao2_unlock(wrapper);
  112. ao2_ref(wrapper, -1);
  113. return 0;
  114. }
  115. res = wrapper->interface->format_attr_sdp_parse(&format->fattr, attributes);
  116. ao2_unlock(wrapper);
  117. ao2_ref(wrapper, -1);
  118. return res;
  119. }
  120. void ast_format_sdp_generate(const struct ast_format *format, unsigned int payload, struct ast_str **str)
  121. {
  122. struct interface_ao2_wrapper *wrapper;
  123. if (!(wrapper = find_interface(format))) {
  124. return;
  125. }
  126. ao2_rdlock(wrapper);
  127. if (!wrapper->interface || !wrapper->interface->format_attr_sdp_generate) {
  128. ao2_unlock(wrapper);
  129. ao2_ref(wrapper, -1);
  130. return;
  131. }
  132. wrapper->interface->format_attr_sdp_generate(&format->fattr, payload, str);
  133. ao2_unlock(wrapper);
  134. ao2_ref(wrapper, -1);
  135. }
  136. /*! \internal
  137. * \brief set format attributes using an interface
  138. */
  139. static int format_set_helper(struct ast_format *format, va_list ap)
  140. {
  141. struct interface_ao2_wrapper *wrapper;
  142. if (!(wrapper = find_interface(format))) {
  143. ast_log(LOG_WARNING, "Could not find format interface to set.\n");
  144. return -1;
  145. }
  146. ao2_rdlock(wrapper);
  147. if (!wrapper->interface || !wrapper->interface->format_attr_set) {
  148. ao2_unlock(wrapper);
  149. ao2_ref(wrapper, -1);
  150. return -1;
  151. }
  152. wrapper->interface->format_attr_set(&format->fattr, ap);
  153. ao2_unlock(wrapper);
  154. ao2_ref(wrapper, -1);
  155. return 0;
  156. }
  157. struct ast_format *ast_format_append(struct ast_format *format, ... )
  158. {
  159. va_list ap;
  160. va_start(ap, format);
  161. format_set_helper(format, ap);
  162. va_end(ap);
  163. return format;
  164. }
  165. struct ast_format *ast_format_set(struct ast_format *format, enum ast_format_id id, int set_attributes, ... )
  166. {
  167. /* initialize the structure before setting it. */
  168. ast_format_clear(format);
  169. format->id = id;
  170. if (set_attributes) {
  171. va_list ap;
  172. va_start(ap, set_attributes);
  173. format_set_helper(format, ap);
  174. va_end(ap);
  175. }
  176. return format;
  177. }
  178. void ast_format_clear(struct ast_format *format)
  179. {
  180. format->id = 0;
  181. memset(&format->fattr, 0, sizeof(format->fattr));
  182. }
  183. /*! \internal
  184. * \brief determine if a list of attribute key value pairs are set on a format
  185. */
  186. static int format_isset_helper(const struct ast_format *format, va_list ap)
  187. {
  188. int res;
  189. struct interface_ao2_wrapper *wrapper;
  190. struct ast_format tmp = {
  191. .id = format->id,
  192. .fattr = { { 0, }, },
  193. };
  194. if (!(wrapper = find_interface(format))) {
  195. return -1;
  196. }
  197. ao2_rdlock(wrapper);
  198. if (!wrapper->interface ||
  199. !wrapper->interface->format_attr_set ||
  200. !wrapper->interface->format_attr_cmp) {
  201. ao2_unlock(wrapper);
  202. ao2_ref(wrapper, -1);
  203. return -1;
  204. }
  205. /* if isset is present, use that function, else just build a new
  206. * format and use the cmp function */
  207. if (wrapper->interface->format_attr_isset) {
  208. res = wrapper->interface->format_attr_isset(&format->fattr, ap);
  209. } else {
  210. wrapper->interface->format_attr_set(&tmp.fattr, ap);
  211. /* use our tmp structure to tell if the attributes are set or not */
  212. res = wrapper->interface->format_attr_cmp(&tmp.fattr, &format->fattr);
  213. res = (res == AST_FORMAT_CMP_NOT_EQUAL) ? -1 : 0;
  214. }
  215. ao2_unlock(wrapper);
  216. ao2_ref(wrapper, -1);
  217. return res;
  218. }
  219. int ast_format_isset(const struct ast_format *format, ... )
  220. {
  221. va_list ap;
  222. int res;
  223. va_start(ap, format);
  224. res = format_isset_helper(format, ap);
  225. va_end(ap);
  226. return res;
  227. }
  228. int ast_format_get_value(const struct ast_format *format, int key, void *value)
  229. {
  230. int res = 0;
  231. struct interface_ao2_wrapper *wrapper;
  232. if (!(wrapper = find_interface(format))) {
  233. return -1;
  234. }
  235. ao2_rdlock(wrapper);
  236. if (!wrapper->interface ||
  237. !wrapper->interface->format_attr_get_val) {
  238. ao2_unlock(wrapper);
  239. ao2_ref(wrapper, -1);
  240. return -1;
  241. }
  242. res = wrapper->interface->format_attr_get_val(&format->fattr, key, value);
  243. ao2_unlock(wrapper);
  244. ao2_ref(wrapper, -1);
  245. return res;
  246. }
  247. /*! \internal
  248. * \brief cmp format attributes using an interface
  249. */
  250. static enum ast_format_cmp_res format_cmp_helper(const struct ast_format *format1, const struct ast_format *format2)
  251. {
  252. enum ast_format_cmp_res res = AST_FORMAT_CMP_EQUAL;
  253. struct interface_ao2_wrapper *wrapper;
  254. if (!(wrapper = find_interface(format1))) {
  255. return res;
  256. }
  257. ao2_rdlock(wrapper);
  258. if (!wrapper->interface || !wrapper->interface->format_attr_cmp) {
  259. ao2_unlock(wrapper);
  260. ao2_ref(wrapper, -1);
  261. return res;
  262. }
  263. res = wrapper->interface->format_attr_cmp(&format1->fattr, &format2->fattr);
  264. ao2_unlock(wrapper);
  265. ao2_ref(wrapper, -1);
  266. return res;
  267. }
  268. enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
  269. {
  270. if (format1->id != format2->id) {
  271. return AST_FORMAT_CMP_NOT_EQUAL;
  272. }
  273. return format_cmp_helper(format1, format2);
  274. }
  275. /*! \internal
  276. * \brief get joint format attributes using an interface
  277. */
  278. static int format_joint_helper(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result)
  279. {
  280. int res = 0;
  281. struct interface_ao2_wrapper *wrapper;
  282. if (!(wrapper = find_interface(format1))) {
  283. /* if no interface is present, we assume formats are joint by id alone */
  284. return res;
  285. }
  286. ao2_rdlock(wrapper);
  287. if (wrapper->interface && wrapper->interface->format_attr_get_joint) {
  288. res = wrapper->interface->format_attr_get_joint(&format1->fattr, &format2->fattr, &result->fattr);
  289. }
  290. ao2_unlock(wrapper);
  291. ao2_ref(wrapper, -1);
  292. return res;
  293. }
  294. int ast_format_joint(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result)
  295. {
  296. if (format1->id != format2->id) {
  297. return -1;
  298. }
  299. result->id = format1->id;
  300. return format_joint_helper(format1, format2, result);
  301. }
  302. uint64_t ast_format_id_to_old_bitfield(enum ast_format_id id)
  303. {
  304. switch (id) {
  305. /*! G.723.1 compression */
  306. case AST_FORMAT_G723_1:
  307. return (1ULL << 0);
  308. /*! GSM compression */
  309. case AST_FORMAT_GSM:
  310. return (1ULL << 1);
  311. /*! Raw mu-law data (G.711) */
  312. case AST_FORMAT_ULAW:
  313. return (1ULL << 2);
  314. /*! Raw A-law data (G.711) */
  315. case AST_FORMAT_ALAW:
  316. return (1ULL << 3);
  317. /*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
  318. case AST_FORMAT_G726_AAL2:
  319. return (1ULL << 4);
  320. /*! ADPCM (IMA) */
  321. case AST_FORMAT_ADPCM:
  322. return (1ULL << 5);
  323. /*! Raw 16-bit Signed Linear (8000 Hz) PCM */
  324. case AST_FORMAT_SLINEAR:
  325. return (1ULL << 6);
  326. /*! LPC10, 180 samples/frame */
  327. case AST_FORMAT_LPC10:
  328. return (1ULL << 7);
  329. /*! G.729A audio */
  330. case AST_FORMAT_G729A:
  331. return (1ULL << 8);
  332. /*! SpeeX Free Compression */
  333. case AST_FORMAT_SPEEX:
  334. return (1ULL << 9);
  335. /*! iLBC Free Compression */
  336. case AST_FORMAT_ILBC:
  337. return (1ULL << 10);
  338. /*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
  339. case AST_FORMAT_G726:
  340. return (1ULL << 11);
  341. /*! G.722 */
  342. case AST_FORMAT_G722:
  343. return (1ULL << 12);
  344. /*! G.722.1 (also known as Siren7, 32kbps assumed) */
  345. case AST_FORMAT_SIREN7:
  346. return (1ULL << 13);
  347. /*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
  348. case AST_FORMAT_SIREN14:
  349. return (1ULL << 14);
  350. /*! Raw 16-bit Signed Linear (16000 Hz) PCM */
  351. case AST_FORMAT_SLINEAR16:
  352. return (1ULL << 15);
  353. /*! G.719 (64 kbps assumed) */
  354. case AST_FORMAT_G719:
  355. return (1ULL << 32);
  356. /*! SpeeX Wideband (16kHz) Free Compression */
  357. case AST_FORMAT_SPEEX16:
  358. return (1ULL << 33);
  359. /*! Opus audio (8kHz, 16kHz, 24kHz, 48Khz) */
  360. case AST_FORMAT_OPUS:
  361. return (1ULL << 34);
  362. /*! Raw mu-law data (G.711) */
  363. case AST_FORMAT_TESTLAW:
  364. return (1ULL << 47);
  365. /*! H.261 Video */
  366. case AST_FORMAT_H261:
  367. return (1ULL << 18);
  368. /*! H.263 Video */
  369. case AST_FORMAT_H263:
  370. return (1ULL << 19);
  371. /*! H.263+ Video */
  372. case AST_FORMAT_H263_PLUS:
  373. return (1ULL << 20);
  374. /*! H.264 Video */
  375. case AST_FORMAT_H264:
  376. return (1ULL << 21);
  377. /*! MPEG4 Video */
  378. case AST_FORMAT_MP4_VIDEO:
  379. return (1ULL << 22);
  380. /*! VP8 Video */
  381. case AST_FORMAT_VP8:
  382. return (1ULL << 23);
  383. /*! JPEG Images */
  384. case AST_FORMAT_JPEG:
  385. return (1ULL << 16);
  386. /*! PNG Images */
  387. case AST_FORMAT_PNG:
  388. return (1ULL << 17);
  389. /*! T.140 RED Text format RFC 4103 */
  390. case AST_FORMAT_T140RED:
  391. return (1ULL << 26);
  392. /*! T.140 Text format - ITU T.140, RFC 4103 */
  393. case AST_FORMAT_T140:
  394. return (1ULL << 27);
  395. default:
  396. return 0; /* not supported by old bitfield. */
  397. }
  398. return 0;
  399. }
  400. uint64_t ast_format_to_old_bitfield(const struct ast_format *format)
  401. {
  402. return ast_format_id_to_old_bitfield(format->id);
  403. }
  404. struct ast_format *ast_format_from_old_bitfield(struct ast_format *dst, uint64_t src)
  405. {
  406. switch (src) {
  407. /*! G.723.1 compression */
  408. case (1ULL << 0):
  409. return ast_format_set(dst, AST_FORMAT_G723_1, 0);
  410. /*! GSM compression */
  411. case (1ULL << 1):
  412. return ast_format_set(dst, AST_FORMAT_GSM, 0);
  413. /*! Raw mu-law data (G.711) */
  414. case (1ULL << 2):
  415. return ast_format_set(dst, AST_FORMAT_ULAW, 0);
  416. /*! Raw A-law data (G.711) */
  417. case (1ULL << 3):
  418. return ast_format_set(dst, AST_FORMAT_ALAW, 0);
  419. /*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
  420. case (1ULL << 4):
  421. return ast_format_set(dst, AST_FORMAT_G726_AAL2, 0);
  422. /*! ADPCM (IMA) */
  423. case (1ULL << 5):
  424. return ast_format_set(dst, AST_FORMAT_ADPCM, 0);
  425. /*! Raw 16-bit Signed Linear (8000 Hz) PCM */
  426. case (1ULL << 6):
  427. return ast_format_set(dst, AST_FORMAT_SLINEAR, 0);
  428. /*! LPC10, 180 samples/frame */
  429. case (1ULL << 7):
  430. return ast_format_set(dst, AST_FORMAT_LPC10, 0);
  431. /*! G.729A audio */
  432. case (1ULL << 8):
  433. return ast_format_set(dst, AST_FORMAT_G729A, 0);
  434. /*! SpeeX Free Compression */
  435. case (1ULL << 9):
  436. return ast_format_set(dst, AST_FORMAT_SPEEX, 0);
  437. /*! iLBC Free Compression */
  438. case (1ULL << 10):
  439. return ast_format_set(dst, AST_FORMAT_ILBC, 0);
  440. /*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
  441. case (1ULL << 11):
  442. return ast_format_set(dst, AST_FORMAT_G726, 0);
  443. /*! G.722 */
  444. case (1ULL << 12):
  445. return ast_format_set(dst, AST_FORMAT_G722, 0);
  446. /*! G.722.1 (also known as Siren7, 32kbps assumed) */
  447. case (1ULL << 13):
  448. return ast_format_set(dst, AST_FORMAT_SIREN7, 0);
  449. /*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
  450. case (1ULL << 14):
  451. return ast_format_set(dst, AST_FORMAT_SIREN14, 0);
  452. /*! Raw 16-bit Signed Linear (16000 Hz) PCM */
  453. case (1ULL << 15):
  454. return ast_format_set(dst, AST_FORMAT_SLINEAR16, 0);
  455. /*! G.719 (64 kbps assumed) */
  456. case (1ULL << 32):
  457. return ast_format_set(dst, AST_FORMAT_G719, 0);
  458. /*! SpeeX Wideband (16kHz) Free Compression */
  459. case (1ULL << 33):
  460. return ast_format_set(dst, AST_FORMAT_SPEEX16, 0);
  461. /*! Opus audio (8kHz, 16kHz, 24kHz, 48Khz) */
  462. case (1ULL << 34):
  463. return ast_format_set(dst, AST_FORMAT_OPUS, 0);
  464. /*! Raw mu-law data (G.711) */
  465. case (1ULL << 47):
  466. return ast_format_set(dst, AST_FORMAT_TESTLAW, 0);
  467. /*! H.261 Video */
  468. case (1ULL << 18):
  469. return ast_format_set(dst, AST_FORMAT_H261, 0);
  470. /*! H.263 Video */
  471. case (1ULL << 19):
  472. return ast_format_set(dst, AST_FORMAT_H263, 0);
  473. /*! H.263+ Video */
  474. case (1ULL << 20):
  475. return ast_format_set(dst, AST_FORMAT_H263_PLUS, 0);
  476. /*! H.264 Video */
  477. case (1ULL << 21):
  478. return ast_format_set(dst, AST_FORMAT_H264, 0);
  479. /*! MPEG4 Video */
  480. case (1ULL << 22):
  481. return ast_format_set(dst, AST_FORMAT_MP4_VIDEO, 0);
  482. /*! VP8 Video */
  483. case (1ULL << 23):
  484. return ast_format_set(dst, AST_FORMAT_VP8, 0);
  485. /*! JPEG Images */
  486. case (1ULL << 16):
  487. return ast_format_set(dst, AST_FORMAT_JPEG, 0);
  488. /*! PNG Images */
  489. case (1ULL << 17):
  490. return ast_format_set(dst, AST_FORMAT_PNG, 0);
  491. /*! T.140 RED Text format RFC 4103 */
  492. case (1ULL << 26):
  493. return ast_format_set(dst, AST_FORMAT_T140RED, 0);
  494. /*! T.140 Text format - ITU T.140, RFC 4103 */
  495. case (1ULL << 27):
  496. return ast_format_set(dst, AST_FORMAT_T140, 0);
  497. }
  498. ast_format_clear(dst);
  499. return NULL;
  500. }
  501. enum ast_format_id ast_format_id_from_old_bitfield(uint64_t src)
  502. {
  503. struct ast_format dst;
  504. if (ast_format_from_old_bitfield(&dst, src)) {
  505. return dst.id;
  506. }
  507. return 0;
  508. }
  509. int ast_format_is_slinear(const struct ast_format *format)
  510. {
  511. if (format->id == AST_FORMAT_SLINEAR ||
  512. format->id == AST_FORMAT_SLINEAR12 ||
  513. format->id == AST_FORMAT_SLINEAR16 ||
  514. format->id == AST_FORMAT_SLINEAR24 ||
  515. format->id == AST_FORMAT_SLINEAR32 ||
  516. format->id == AST_FORMAT_SLINEAR44 ||
  517. format->id == AST_FORMAT_SLINEAR48 ||
  518. format->id == AST_FORMAT_SLINEAR96 ||
  519. format->id == AST_FORMAT_SLINEAR192) {
  520. return 1;
  521. }
  522. return 0;
  523. }
  524. enum ast_format_id ast_format_slin_by_rate(unsigned int rate)
  525. {
  526. if (rate >= 192000) {
  527. return AST_FORMAT_SLINEAR192;
  528. } else if (rate >= 96000) {
  529. return AST_FORMAT_SLINEAR96;
  530. } else if (rate >= 48000) {
  531. return AST_FORMAT_SLINEAR48;
  532. } else if (rate >= 44100) {
  533. return AST_FORMAT_SLINEAR44;
  534. } else if (rate >= 32000) {
  535. return AST_FORMAT_SLINEAR32;
  536. } else if (rate >= 24000) {
  537. return AST_FORMAT_SLINEAR24;
  538. } else if (rate >= 16000) {
  539. return AST_FORMAT_SLINEAR16;
  540. } else if (rate >= 12000) {
  541. return AST_FORMAT_SLINEAR12;
  542. }
  543. return AST_FORMAT_SLINEAR;
  544. }
  545. const char* ast_getformatname(const struct ast_format *format)
  546. {
  547. int x;
  548. const char *ret = "unknown";
  549. size_t f_len;
  550. const struct ast_format_list *f_list = ast_format_list_get(&f_len);
  551. for (x = 0; x < f_len; x++) {
  552. if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) {
  553. ret = f_list[x].name;
  554. break;
  555. }
  556. }
  557. f_list = ast_format_list_destroy(f_list);
  558. return ret;
  559. }
  560. char *ast_getformatname_multiple_byid(char *buf, size_t size, enum ast_format_id id)
  561. {
  562. int x;
  563. unsigned len;
  564. char *start, *end = buf;
  565. size_t f_len;
  566. const struct ast_format_list *f_list = ast_format_list_get(&f_len);
  567. if (!size) {
  568. f_list = ast_format_list_destroy(f_list);
  569. return buf;
  570. }
  571. snprintf(end, size, "(");
  572. len = strlen(end);
  573. end += len;
  574. size -= len;
  575. start = end;
  576. for (x = 0; x < f_len; x++) {
  577. if (f_list[x].format.id == id) {
  578. snprintf(end, size, "%s|", f_list[x].name);
  579. len = strlen(end);
  580. end += len;
  581. size -= len;
  582. }
  583. }
  584. if (start == end) {
  585. ast_copy_string(start, "nothing)", size);
  586. } else if (size > 1) {
  587. *(end - 1) = ')';
  588. }
  589. f_list = ast_format_list_destroy(f_list);
  590. return buf;
  591. }
  592. static struct ast_codec_alias_table {
  593. const char *alias;
  594. const char *realname;
  595. } ast_codec_alias_table[] = {
  596. { "slinear", "slin"},
  597. { "slinear16", "slin16"},
  598. { "g723.1", "g723"},
  599. { "g722.1", "siren7"},
  600. { "g722.1c", "siren14"},
  601. };
  602. static const char *ast_expand_codec_alias(const char *in)
  603. {
  604. int x;
  605. for (x = 0; x < ARRAY_LEN(ast_codec_alias_table); x++) {
  606. if (!strcmp(in,ast_codec_alias_table[x].alias))
  607. return ast_codec_alias_table[x].realname;
  608. }
  609. return in;
  610. }
  611. struct ast_format *ast_getformatbyname(const char *name, struct ast_format *result)
  612. {
  613. int x;
  614. size_t f_len;
  615. const struct ast_format_list *f_list = ast_format_list_get(&f_len);
  616. for (x = 0; x < f_len; x++) {
  617. if (!strcasecmp(f_list[x].name, name) ||
  618. !strcasecmp(f_list[x].name, ast_expand_codec_alias(name))) {
  619. ast_format_copy(result, &f_list[x].format);
  620. f_list = ast_format_list_destroy(f_list);
  621. return result;
  622. }
  623. }
  624. f_list = ast_format_list_destroy(f_list);
  625. return NULL;
  626. }
  627. const char *ast_codec2str(struct ast_format *format)
  628. {
  629. int x;
  630. const char *ret = "unknown";
  631. size_t f_len;
  632. const struct ast_format_list *f_list = ast_format_list_get(&f_len);
  633. for (x = 0; x < f_len; x++) {
  634. if (ast_format_cmp(&f_list[x].format, format) == AST_FORMAT_CMP_EQUAL) {
  635. ret = f_list[x].desc;
  636. break;
  637. }
  638. }
  639. f_list = ast_format_list_destroy(f_list);
  640. return ret;
  641. }
  642. int ast_format_rate(const struct ast_format *format)
  643. {
  644. switch (format->id) {
  645. case AST_FORMAT_SLINEAR12:
  646. return 12000;
  647. case AST_FORMAT_SLINEAR24:
  648. return 24000;
  649. case AST_FORMAT_SLINEAR32:
  650. return 32000;
  651. case AST_FORMAT_SLINEAR44:
  652. return 44100;
  653. case AST_FORMAT_SLINEAR48:
  654. return 48000;
  655. case AST_FORMAT_SLINEAR96:
  656. return 96000;
  657. case AST_FORMAT_SLINEAR192:
  658. return 192000;
  659. case AST_FORMAT_G722:
  660. case AST_FORMAT_SLINEAR16:
  661. case AST_FORMAT_SIREN7:
  662. case AST_FORMAT_SPEEX16:
  663. return 16000;
  664. case AST_FORMAT_SIREN14:
  665. case AST_FORMAT_SPEEX32:
  666. return 32000;
  667. case AST_FORMAT_G719:
  668. return 48000;
  669. case AST_FORMAT_SILK:
  670. if (!(ast_format_isset(format,
  671. SILK_ATTR_KEY_SAMP_RATE,
  672. SILK_ATTR_VAL_SAMP_24KHZ,
  673. AST_FORMAT_ATTR_END))) {
  674. return 24000;
  675. } else if (!(ast_format_isset(format,
  676. SILK_ATTR_KEY_SAMP_RATE,
  677. SILK_ATTR_VAL_SAMP_16KHZ,
  678. AST_FORMAT_ATTR_END))) {
  679. return 16000;
  680. } else if (!(ast_format_isset(format,
  681. SILK_ATTR_KEY_SAMP_RATE,
  682. SILK_ATTR_VAL_SAMP_12KHZ,
  683. AST_FORMAT_ATTR_END))) {
  684. return 12000;
  685. } else {
  686. return 8000;
  687. }
  688. case AST_FORMAT_CELT:
  689. {
  690. int samplerate;
  691. if (!(ast_format_get_value(format,
  692. CELT_ATTR_KEY_SAMP_RATE,
  693. &samplerate))) {
  694. return samplerate;
  695. }
  696. }
  697. /* Opus */
  698. case AST_FORMAT_OPUS:
  699. return 48000;
  700. default:
  701. return 8000;
  702. }
  703. }
  704. static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  705. {
  706. int x, found=0;
  707. size_t f_len;
  708. const struct ast_format_list *f_list;
  709. switch (cmd) {
  710. case CLI_INIT:
  711. e->command = "core show codecs [audio|video|image|text]";
  712. e->usage =
  713. "Usage: core show codecs [audio|video|image|text]\n"
  714. " Displays codec mapping\n";
  715. return NULL;
  716. case CLI_GENERATE:
  717. return NULL;
  718. }
  719. if ((a->argc < 3) || (a->argc > 4)) {
  720. return CLI_SHOWUSAGE;
  721. }
  722. f_list = ast_format_list_get(&f_len);
  723. if (!ast_opt_dont_warn) {
  724. ast_cli(a->fd, "Disclaimer: this command is for informational purposes only.\n"
  725. "\tIt does not indicate anything about your configuration.\n");
  726. }
  727. ast_cli(a->fd, "%8s %5s %8s %s\n","ID","TYPE","NAME","DESCRIPTION");
  728. ast_cli(a->fd, "-----------------------------------------------------------------------------------\n");
  729. for (x = 0; x < f_len; x++) {
  730. if (a->argc == 4) {
  731. if (!strcasecmp(a->argv[3], "audio")) {
  732. if (AST_FORMAT_GET_TYPE(f_list[x].format.id) != AST_FORMAT_TYPE_AUDIO) {
  733. continue;
  734. }
  735. } else if (!strcasecmp(a->argv[3], "video")) {
  736. if (AST_FORMAT_GET_TYPE(f_list[x].format.id) != AST_FORMAT_TYPE_VIDEO) {
  737. continue;
  738. }
  739. } else if (!strcasecmp(a->argv[3], "image")) {
  740. if (AST_FORMAT_GET_TYPE(f_list[x].format.id) != AST_FORMAT_TYPE_IMAGE) {
  741. continue;
  742. }
  743. } else if (!strcasecmp(a->argv[3], "text")) {
  744. if (AST_FORMAT_GET_TYPE(f_list[x].format.id) != AST_FORMAT_TYPE_TEXT) {
  745. continue;
  746. }
  747. } else {
  748. continue;
  749. }
  750. }
  751. ast_cli(a->fd, "%8u %5s %8s (%s)\n",
  752. f_list[x].format.id,
  753. (AST_FORMAT_GET_TYPE(f_list[x].format.id) == AST_FORMAT_TYPE_AUDIO) ? "audio" :
  754. (AST_FORMAT_GET_TYPE(f_list[x].format.id) == AST_FORMAT_TYPE_IMAGE) ? "image" :
  755. (AST_FORMAT_GET_TYPE(f_list[x].format.id) == AST_FORMAT_TYPE_VIDEO) ? "video" :
  756. (AST_FORMAT_GET_TYPE(f_list[x].format.id) == AST_FORMAT_TYPE_TEXT) ? "text" :
  757. "(unk)",
  758. f_list[x].name,
  759. f_list[x].desc);
  760. found = 1;
  761. }
  762. f_list = ast_format_list_destroy(f_list);
  763. if (!found) {
  764. return CLI_SHOWUSAGE;
  765. } else {
  766. return CLI_SUCCESS;
  767. }
  768. }
  769. static char *show_codec_n(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  770. {
  771. enum ast_format_id format_id;
  772. int x, found = 0;
  773. int type_punned_codec;
  774. size_t f_len;
  775. const struct ast_format_list *f_list;
  776. switch (cmd) {
  777. case CLI_INIT:
  778. e->command = "core show codec";
  779. e->usage =
  780. "Usage: core show codec <number>\n"
  781. " Displays codec mapping\n";
  782. return NULL;
  783. case CLI_GENERATE:
  784. return NULL;
  785. }
  786. if (a->argc != 4) {
  787. return CLI_SHOWUSAGE;
  788. }
  789. if (sscanf(a->argv[3], "%30d", &type_punned_codec) != 1) {
  790. return CLI_SHOWUSAGE;
  791. }
  792. format_id = type_punned_codec;
  793. f_list = ast_format_list_get(&f_len);
  794. for (x = 0; x < f_len; x++) {
  795. if (f_list[x].format.id == format_id) {
  796. found = 1;
  797. ast_cli(a->fd, "%11u %s\n", (unsigned int) format_id, f_list[x].desc);
  798. }
  799. }
  800. if (!found) {
  801. ast_cli(a->fd, "Codec %d not found\n", format_id);
  802. }
  803. f_list = ast_format_list_destroy(f_list);
  804. return CLI_SUCCESS;
  805. }
  806. /* Builtin Asterisk CLI-commands for debugging */
  807. static struct ast_cli_entry my_clis[] = {
  808. AST_CLI_DEFINE(show_codecs, "Displays a list of codecs"),
  809. AST_CLI_DEFINE(show_codec_n, "Shows a specific codec"),
  810. };
  811. static int format_list_add_custom(struct ast_format_list *new)
  812. {
  813. RAII_VAR(struct ast_format_list *, entry, NULL, ao2_cleanup);
  814. if (!(entry = ao2_alloc(sizeof(*entry), NULL))) {
  815. return -1;
  816. }
  817. memcpy(entry, new, sizeof(struct ast_format_list));
  818. entry->custom_entry = 1;
  819. ao2_link(format_list, entry);
  820. return 0;
  821. }
  822. static int format_list_add_static(
  823. const struct ast_format *format,
  824. const char *name,
  825. int samplespersecond,
  826. const char *description,
  827. int fr_len,
  828. int min_ms,
  829. int max_ms,
  830. int inc_ms,
  831. int def_ms,
  832. unsigned int flags,
  833. int cur_ms)
  834. {
  835. struct ast_format_list *entry;
  836. if (!(entry = ao2_alloc(sizeof(*entry), NULL))) {
  837. return -1;
  838. }
  839. ast_format_copy(&entry->format, format);
  840. ast_copy_string(entry->name, name, sizeof(entry->name));
  841. ast_copy_string(entry->desc, description, sizeof(entry->desc));
  842. entry->samplespersecond = samplespersecond;
  843. entry->fr_len = fr_len;
  844. entry->min_ms = min_ms;
  845. entry->max_ms = max_ms;
  846. entry->inc_ms = inc_ms;
  847. entry->def_ms = def_ms;
  848. entry->flags = flags;
  849. entry->cur_ms = cur_ms;
  850. entry->custom_entry = 0;
  851. ao2_link(format_list, entry);
  852. ao2_ref(entry, -1);
  853. return 0;
  854. }
  855. static int list_all_custom(void *obj, void *arg, int flag)
  856. {
  857. struct ast_format_list *entry = obj;
  858. return entry->custom_entry ? CMP_MATCH : 0;
  859. }
  860. static int list_cmp_cb(void *obj, void *arg, int flags)
  861. {
  862. struct ast_format_list *entry1 = obj;
  863. struct ast_format_list *entry2 = arg;
  864. return (ast_format_cmp(&entry1->format, &entry2->format) == AST_FORMAT_CMP_EQUAL) ? CMP_MATCH | CMP_STOP : 0;
  865. }
  866. static int list_hash_cb(const void *obj, const int flags)
  867. {
  868. return ao2_container_count(format_list);
  869. }
  870. const struct ast_format_list *ast_format_list_get(size_t *size)
  871. {
  872. struct ast_format_list *list;
  873. ast_rwlock_rdlock(&format_list_array_lock);
  874. ao2_ref(format_list_array, 1);
  875. list = format_list_array;
  876. *size = format_list_array_len;
  877. ast_rwlock_unlock(&format_list_array_lock);
  878. return list;
  879. }
  880. const struct ast_format_list *ast_format_list_destroy(const struct ast_format_list *list)
  881. {
  882. ao2_ref((void *) list, -1);
  883. return NULL;
  884. }
  885. static int build_format_list_array(void)
  886. {
  887. struct ast_format_list *tmp;
  888. size_t arraysize = sizeof(struct ast_format_list) * ao2_container_count(format_list);
  889. int i = 0;
  890. struct ao2_iterator it;
  891. ast_rwlock_wrlock(&format_list_array_lock);
  892. tmp = format_list_array;
  893. if (!(format_list_array = ao2_alloc(arraysize, NULL))) {
  894. format_list_array = tmp;
  895. ast_rwlock_unlock(&format_list_array_lock);
  896. return -1;
  897. }
  898. format_list_array_len = ao2_container_count(format_list);
  899. if (tmp) {
  900. ao2_ref(tmp, -1);
  901. }
  902. /* walk through the container adding elements to the static array */
  903. it = ao2_iterator_init(format_list, 0);
  904. while ((tmp = ao2_iterator_next(&it)) && (i < format_list_array_len)) {
  905. memcpy(&format_list_array[i], tmp, sizeof(struct ast_format_list));
  906. ao2_ref(tmp, -1);
  907. i++;
  908. }
  909. ao2_iterator_destroy(&it);
  910. ast_rwlock_unlock(&format_list_array_lock);
  911. return 0;
  912. }
  913. static int format_list_init(void)
  914. {
  915. struct ast_format tmpfmt;
  916. if (!(format_list = ao2_container_alloc(283, list_hash_cb, list_cmp_cb))) {
  917. return -1;
  918. }
  919. /* initiate static entries XXX DO NOT CHANGE THIS ORDER! */
  920. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0), "g723", 8000, "G.723.1", 20, 30, 300, 30, 30, 0, 0); /*!< G723.1 */
  921. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0), "gsm", 8000, "GSM", 33, 20, 300, 20, 20, 0, 0); /*!< codec_gsm.c */
  922. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0), "ulaw", 8000, "G.711 u-law", 80, 10, 150, 10, 20, 0, 0); /*!< codec_ulaw.c */
  923. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0), "alaw", 8000, "G.711 A-law", 80, 10, 150, 10, 20, 0, 0); /*!< codec_alaw.c */
  924. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_G726, 0), "g726", 8000, "G.726 RFC3551", 40, 10, 300, 10, 20, 0, 0); /*!< codec_g726.c */
  925. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_ADPCM, 0), "adpcm" , 8000, "ADPCM", 40, 10, 300, 10, 20, 0, 0); /*!< codec_adpcm.c */
  926. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0), "slin", 8000, "16 bit Signed Linear PCM", 160, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0); /*!< Signed linear */
  927. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_LPC10, 0), "lpc10", 8000, "LPC10", 7, 20, 20, 20, 20, 0, 0); /*!< codec_lpc10.c */
  928. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0), "g729", 8000, "G.729A", 10, 10, 230, 10, 20, AST_SMOOTHER_FLAG_G729, 0); /*!< Binary commercial distribution */
  929. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SPEEX, 0), "speex", 8000, "SpeeX", 10, 10, 60, 10, 20, 0, 0); /*!< codec_speex.c */
  930. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SPEEX16, 0), "speex16", 16000, "SpeeX 16khz", 10, 10, 60, 10, 20, 0, 0); /*!< codec_speex.c */
  931. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_ILBC, 0), "ilbc", 8000, "iLBC", 50, 30, 30, 30, 30, 0, 0); /*!< codec_ilbc.c */ /* inc=30ms - workaround */
  932. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_G726_AAL2, 0), "g726aal2", 8000, "G.726 AAL2", 40, 10, 300, 10, 20, 0, 0); /*!< codec_g726.c */
  933. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_G722, 0), "g722", 16000, "G722", 80, 10, 150, 10, 20, 0, 0); /*!< codec_g722.c */
  934. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0), "slin16", 16000, "16 bit Signed Linear PCM (16kHz)", 320, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (16kHz) */
  935. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_JPEG, 0), "jpeg", 0, "JPEG image", 0, 0, 0, 0 ,0 ,0 ,0); /*!< See format_jpeg.c */
  936. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_PNG, 0), "png", 0, "PNG image", 0, 0, 0, 0 ,0 ,0 ,0); /*!< PNG Image format */
  937. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_H261, 0), "h261", 0, "H.261 Video", 0, 0, 0, 0 ,0 ,0 ,0); /*!< H.261 Video Passthrough */
  938. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_H263, 0), "h263", 0, "H.263 Video", 0, 0, 0, 0 ,0 ,0 ,0); /*!< H.263 Passthrough support, see format_h263.c */
  939. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_H263_PLUS, 0), "h263p", 0, "H.263+ Video", 0, 0, 0,0 ,0 ,0, 0); /*!< H.263plus passthrough support See format_h263.c */
  940. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_H264, 0), "h264", 0, "H.264 Video", 0, 0, 0, 0 ,0 ,0, 0); /*!< Passthrough support, see format_h263.c */
  941. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_MP4_VIDEO, 0), "mpeg4", 0, "MPEG4 Video", 0, 0, 0, 0, 0 ,0, 0); /*!< Passthrough support for MPEG4 */
  942. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_T140RED, 0), "red", 1, "T.140 Realtime Text with redundancy", 0, 0, 0,0 ,0 ,0, 0); /*!< Redundant T.140 Realtime Text */
  943. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_T140, 0), "t140", 0, "Passthrough T.140 Realtime Text", 0, 0, 0, 0 ,0 ,0, 0); /*!< Passthrough support for T.140 Realtime Text */
  944. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SIREN7, 0), "siren7", 16000, "ITU G.722.1 (Siren7, licensed from Polycom)", 80, 20, 80, 20, 20, 0, 0); /*!< Binary commercial distribution */
  945. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SIREN14, 0), "siren14", 32000, "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)", 120, 20, 80, 20, 20, 0, 0); /*!< Binary commercial distribution */
  946. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_TESTLAW, 0), "testlaw", 8000, "G.711 test-law", 80, 10, 150, 10, 20, 0, 0); /*!< codec_ulaw.c */
  947. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_G719, 0), "g719", 48000, "ITU G.719", 160, 20, 80, 20, 20, 0, 0);
  948. /* ORDER MAY CHANGE AFTER THIS POINT IN THE LIST */
  949. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SPEEX32, 0), "speex32", 32000, "SpeeX 32khz", 10, 10, 60, 10, 20, 0, 0); /*!< codec_speex.c */
  950. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR12, 0), "slin12", 12000, "16 bit Signed Linear PCM (12kHz)", 240, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (12kHz) */
  951. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR24, 0), "slin24", 24000, "16 bit Signed Linear PCM (24kHz)", 480, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (24kHz) */
  952. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR32, 0), "slin32", 32000, "16 bit Signed Linear PCM (32kHz)", 640, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (32kHz) */
  953. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR44, 0), "slin44", 44100, "16 bit Signed Linear PCM (44kHz)", 882, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (44.1kHz) */
  954. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR48, 0), "slin48", 48000, "16 bit Signed Linear PCM (48kHz)", 960, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (48kHz) */
  955. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR96, 0), "slin96", 96000, "16 bit Signed Linear PCM (96kHz)", 1920, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (96kHz) */
  956. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR192, 0), "slin192", 192000, "16 bit Signed Linear PCM (192kHz)", 3840, 10, 70, 10, 20, AST_SMOOTHER_FLAG_BE, 0);/*!< Signed linear (192kHz) */
  957. /* Opus (FIXME: real min is 3/5/10, real max is 120...) */
  958. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_OPUS, 0), "opus", 48000, "Opus Codec", 10, 20, 60, 20, 20, 0, 0); /*!< codec_opus.c */
  959. /* VP8 (passthrough) */
  960. format_list_add_static(ast_format_set(&tmpfmt, AST_FORMAT_VP8, 0), "vp8", 0, "VP8 Video", 0, 0, 0, 0 ,0 ,0, 0); /*!< Passthrough support, see format_h263.c */
  961. return 0;
  962. }
  963. /*!
  964. * \internal
  965. * \brief Clean up resources on Asterisk shutdown
  966. */
  967. static void format_list_shutdown(void)
  968. {
  969. ast_rwlock_destroy(&format_list_array_lock);
  970. if (format_list) {
  971. ao2_t_ref(format_list, -1, "Unref format_list container in shutdown");
  972. format_list = NULL;
  973. }
  974. if (format_list_array) {
  975. ao2_t_ref(format_list_array, -1, "Unref format_list_array in shutdown");
  976. format_list_array = NULL;
  977. }
  978. }
  979. int ast_format_list_init(void)
  980. {
  981. if (ast_rwlock_init(&format_list_array_lock)) {
  982. return -1;
  983. }
  984. if (format_list_init()) {
  985. goto init_list_cleanup;
  986. }
  987. if (build_format_list_array()) {
  988. goto init_list_cleanup;
  989. }
  990. ast_register_atexit(format_list_shutdown);
  991. return 0;
  992. init_list_cleanup:
  993. format_list_shutdown();
  994. return -1;
  995. }
  996. /*!
  997. * \internal
  998. * \brief Clean up resources on Asterisk shutdown
  999. */
  1000. static void format_attr_shutdown(void)
  1001. {
  1002. ast_cli_unregister_multiple(my_clis, ARRAY_LEN(my_clis));
  1003. if (interfaces) {
  1004. ao2_ref(interfaces, -1);
  1005. interfaces = NULL;
  1006. }
  1007. }
  1008. int ast_format_attr_init(void)
  1009. {
  1010. interfaces = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK,
  1011. 283, interface_hash_cb, interface_cmp_cb);
  1012. if (!interfaces) {
  1013. return -1;
  1014. }
  1015. ast_cli_register_multiple(my_clis, ARRAY_LEN(my_clis));
  1016. ast_register_cleanup(format_attr_shutdown);
  1017. return 0;
  1018. }
  1019. static int custom_celt_format(struct ast_format_list *entry, unsigned int maxbitrate, unsigned int framesize)
  1020. {
  1021. if (!entry->samplespersecond) {
  1022. ast_log(LOG_WARNING, "Custom CELT format definition '%s' requires sample rate to be defined.\n", entry->name);
  1023. }
  1024. ast_format_set(&entry->format, AST_FORMAT_CELT, 0);
  1025. if (!has_interface(&entry->format)) {
  1026. return -1;
  1027. }
  1028. snprintf(entry->desc, sizeof(entry->desc), "CELT Custom Format %dkhz", entry->samplespersecond/1000);
  1029. ast_format_append(&entry->format,
  1030. CELT_ATTR_KEY_SAMP_RATE, entry->samplespersecond,
  1031. CELT_ATTR_KEY_MAX_BITRATE, maxbitrate,
  1032. CELT_ATTR_KEY_FRAME_SIZE, framesize,
  1033. AST_FORMAT_ATTR_END);
  1034. entry->fr_len = 80;
  1035. entry->min_ms = 20;
  1036. entry->max_ms = 20;
  1037. entry->inc_ms = 20;
  1038. entry->def_ms = 20;
  1039. return 0;
  1040. }
  1041. static int custom_silk_format(struct ast_format_list *entry, unsigned int maxbitrate, int usedtx, int usefec, int packetloss_percentage)
  1042. {
  1043. if (!entry->samplespersecond) {
  1044. ast_log(LOG_WARNING, "Custom SILK format definition '%s' requires sample rate to be defined.\n", entry->name);
  1045. }
  1046. ast_format_set(&entry->format, AST_FORMAT_SILK, 0);
  1047. if (!has_interface(&entry->format)) {
  1048. return -1;
  1049. }
  1050. switch (entry->samplespersecond) {
  1051. case 8000:
  1052. ast_copy_string(entry->desc, "SILK Custom Format 8khz", sizeof(entry->desc));
  1053. ast_format_append(&entry->format,
  1054. SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_8KHZ,
  1055. AST_FORMAT_ATTR_END);
  1056. break;
  1057. case 12000:
  1058. ast_copy_string(entry->desc, "SILK Custom Format 12khz", sizeof(entry->desc));
  1059. ast_format_append(&entry->format,
  1060. SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_12KHZ,
  1061. AST_FORMAT_ATTR_END);
  1062. break;
  1063. case 16000:
  1064. ast_copy_string(entry->desc, "SILK Custom Format 16khz", sizeof(entry->desc));
  1065. ast_format_append(&entry->format,
  1066. SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_16KHZ,
  1067. AST_FORMAT_ATTR_END);
  1068. break;
  1069. case 24000:
  1070. ast_copy_string(entry->desc, "SILK Custom Format 24khz", sizeof(entry->desc));
  1071. ast_format_append(&entry->format,
  1072. SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_24KHZ,
  1073. AST_FORMAT_ATTR_END);
  1074. break;
  1075. default:
  1076. ast_log(LOG_WARNING, "Custom SILK format definition '%s' can not support sample rate %d\n", entry->name, entry->samplespersecond);
  1077. return -1;
  1078. }
  1079. ast_format_append(&entry->format,
  1080. SILK_ATTR_KEY_MAX_BITRATE, maxbitrate,
  1081. SILK_ATTR_KEY_DTX, usedtx ? 1 : 0,
  1082. SILK_ATTR_KEY_FEC, usefec ? 1 : 0,
  1083. SILK_ATTR_KEY_PACKETLOSS_PERCENTAGE, packetloss_percentage,
  1084. AST_FORMAT_ATTR_END);
  1085. entry->fr_len = 80;
  1086. entry->min_ms = 20;
  1087. entry->max_ms = 20;
  1088. entry->inc_ms = 20;
  1089. entry->def_ms = 20;
  1090. return 0;
  1091. }
  1092. static int conf_process_format_name(const char *name, enum ast_format_id *id)
  1093. {
  1094. if (!strcasecmp(name, "silk")) {
  1095. *id = AST_FORMAT_SILK;
  1096. } else if (!strcasecmp(name, "celt")) {
  1097. *id = AST_FORMAT_CELT;
  1098. } else {
  1099. *id = 0;
  1100. return -1;
  1101. }
  1102. return 0;
  1103. }
  1104. static int conf_process_sample_rate(const char *rate, unsigned int *result)
  1105. {
  1106. if (!strcasecmp(rate, "8000")) {
  1107. *result = 8000;
  1108. } else if (!strcasecmp(rate, "12000")) {
  1109. *result = 12000;
  1110. } else if (!strcasecmp(rate, "16000")) {
  1111. *result = 16000;
  1112. } else if (!strcasecmp(rate, "24000")) {
  1113. *result = 24000;
  1114. } else if (!strcasecmp(rate, "32000")) {
  1115. *result = 32000;
  1116. } else if (!strcasecmp(rate, "44100")) {
  1117. *result = 44100;
  1118. } else if (!strcasecmp(rate, "48000")) {
  1119. *result = 48000;
  1120. } else if (!strcasecmp(rate, "96000")) {
  1121. *result = 96000;
  1122. } else if (!strcasecmp(rate, "192000")) {
  1123. *result = 192000;
  1124. } else {
  1125. *result = 0;
  1126. return -1;
  1127. }
  1128. return 0;
  1129. }
  1130. static int load_format_config(void)
  1131. {
  1132. struct ast_flags config_flags = { 0, };
  1133. struct ast_config *cfg = ast_config_load(FORMAT_CONFIG, config_flags);
  1134. struct ast_format_list entry;
  1135. struct ast_variable *var;
  1136. char *cat = NULL;
  1137. int add_it = 0;
  1138. struct {
  1139. enum ast_format_id id;
  1140. unsigned int maxbitrate;
  1141. unsigned int framesize;
  1142. unsigned int packetloss_percentage;
  1143. int usefec;
  1144. int usedtx;
  1145. } settings;
  1146. if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
  1147. return 0;
  1148. }
  1149. /* remove all custom formats from the AO2 Container. Note, this has no affect on the
  1150. * global format list until the list is rebuild. That is why this is okay to do while
  1151. * reloading the config. */
  1152. ao2_callback(format_list, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, list_all_custom, NULL);
  1153. while ((cat = ast_category_browse(cfg, cat))) {
  1154. memset(&entry, 0, sizeof(entry));
  1155. memset(&settings, 0, sizeof(settings));
  1156. add_it = 0;
  1157. if (!(ast_variable_retrieve(cfg, cat, "type"))) {
  1158. continue;
  1159. }
  1160. ast_copy_string(entry.name, cat, sizeof(entry.name));
  1161. var = ast_variable_browse(cfg, cat);
  1162. for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
  1163. if (!strcasecmp(var->name, "type") && conf_process_format_name(var->value, &settings.id)) {
  1164. ast_log(LOG_WARNING, "Can not make custom format type for '%s' at line %d of %s\n",
  1165. var->value, var->lineno, FORMAT_CONFIG);
  1166. continue;
  1167. } else if (!strcasecmp(var->name, "samprate") && conf_process_sample_rate(var->value, &entry.samplespersecond)) {
  1168. ast_log(LOG_WARNING, "Sample rate '%s' at line %d of %s is not supported.\n",
  1169. var->value, var->lineno, FORMAT_CONFIG);
  1170. } else if (!strcasecmp(var->name, "maxbitrate")) {
  1171. if (sscanf(var->value, "%30u", &settings.maxbitrate) != 1) {
  1172. ast_log(LOG_WARNING, "maxbitrate '%s' at line %d of %s is not supported.\n",
  1173. var->value, var->lineno, FORMAT_CONFIG);
  1174. }
  1175. } else if (!strcasecmp(var->name, "framesize")) {
  1176. if (sscanf(var->value, "%30u", &settings.framesize) != 1) {
  1177. ast_log(LOG_WARNING, "framesize '%s' at line %d of %s is not supported.\n",
  1178. var->value, var->lineno, FORMAT_CONFIG);
  1179. }
  1180. } else if (!strcasecmp(var->name, "dtx")) {
  1181. settings.usedtx = ast_true(var->value) ? 1 : 0;
  1182. } else if (!strcasecmp(var->name, "fec")) {
  1183. settings.usefec = ast_true(var->value) ? 1 : 0;
  1184. } else if (!strcasecmp(var->name, "packetloss_percentage")) {
  1185. if ((sscanf(var->value, "%30u", &settings.packetloss_percentage) != 1) || (settings.packetloss_percentage > 100)) {
  1186. ast_log(LOG_WARNING, "packetloss_percentage '%s' at line %d of %s is not supported.\n",
  1187. var->value, var->lineno, FORMAT_CONFIG);
  1188. }
  1189. }
  1190. }
  1191. switch (settings.id) {
  1192. case AST_FORMAT_SILK:
  1193. if (!(custom_silk_format(&entry, settings.maxbitrate, settings.usedtx, settings.usefec, settings.packetloss_percentage))) {
  1194. add_it = 1;
  1195. }
  1196. break;
  1197. case AST_FORMAT_CELT:
  1198. if (!(custom_celt_format(&entry, settings.maxbitrate, settings.framesize))) {
  1199. add_it = 1;
  1200. }
  1201. break;
  1202. default:
  1203. ast_log(LOG_WARNING, "Can not create custom format %s\n", entry.name);
  1204. }
  1205. if (add_it) {
  1206. format_list_add_custom(&entry);
  1207. }
  1208. }
  1209. ast_config_destroy(cfg);
  1210. build_format_list_array();
  1211. return 0;
  1212. }
  1213. int ast_format_attr_reg_interface(const struct ast_format_attr_interface *interface)
  1214. {
  1215. int x;
  1216. size_t f_len;
  1217. const struct ast_format_list *f_list;
  1218. struct interface_ao2_wrapper *wrapper;
  1219. struct interface_ao2_wrapper tmp_wrapper = {
  1220. .id = interface->id,
  1221. };
  1222. /*
  1223. * Grab the write lock before checking for duplicates in
  1224. * anticipation of adding a new interface and to prevent a
  1225. * duplicate from sneaking in between the check and add.
  1226. */
  1227. ao2_wrlock(interfaces);
  1228. /* check for duplicates first*/
  1229. if ((wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_NOLOCK)))) {
  1230. ao2_unlock(interfaces);
  1231. ast_log(LOG_WARNING, "Can not register attribute interface for format id %d, interface already exists.\n", interface->id);
  1232. ao2_ref(wrapper, -1);
  1233. return -1;
  1234. }
  1235. wrapper = ao2_alloc_options(sizeof(*wrapper), NULL, AO2_ALLOC_OPT_LOCK_RWLOCK);
  1236. if (!wrapper) {
  1237. ao2_unlock(interfaces);
  1238. return -1;
  1239. }
  1240. wrapper->interface = interface;
  1241. wrapper->id = interface->id;
  1242. /* The write lock is already held. */
  1243. ao2_link_flags(interfaces, wrapper, OBJ_NOLOCK);
  1244. ao2_unlock(interfaces);
  1245. ao2_ref(wrapper, -1);
  1246. /* This will find all custom formats in codecs.conf for this new registered interface */
  1247. load_format_config();
  1248. /* update the RTP engine to all custom formats created for this interface */
  1249. f_list = ast_format_list_get(&f_len);
  1250. for (x = 0; x < f_len; x++) {
  1251. if (f_list[x].format.id == tmp_wrapper.id) {
  1252. ast_rtp_engine_load_format(&f_list[x].format);
  1253. }
  1254. }
  1255. f_list = ast_format_list_destroy(f_list);
  1256. return 0;
  1257. }
  1258. int ast_format_attr_unreg_interface(const struct ast_format_attr_interface *interface)
  1259. {
  1260. int x;
  1261. size_t f_len;
  1262. const struct ast_format_list *f_list;
  1263. struct interface_ao2_wrapper *wrapper;
  1264. struct interface_ao2_wrapper tmp_wrapper = {
  1265. .id = interface->id,
  1266. };
  1267. if (!(wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_UNLINK)))) {
  1268. return -1;
  1269. }
  1270. ao2_wrlock(wrapper);
  1271. wrapper->interface = NULL;
  1272. ao2_unlock(wrapper);
  1273. ao2_ref(wrapper, -1);
  1274. /* update the RTP engine to remove all custom formats created for this interface */
  1275. f_list = ast_format_list_get(&f_len);
  1276. for (x = 0; x < f_len; x++) {
  1277. if (f_list[x].format.id == tmp_wrapper.id) {
  1278. ast_rtp_engine_unload_format(&f_list[x].format);
  1279. }
  1280. }
  1281. /* This will remove all custom formats previously created for this interface */
  1282. load_format_config();
  1283. f_list = ast_format_list_destroy(f_list);
  1284. return 0;
  1285. }