translate.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2006, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@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 Translate via the use of pseudo channels
  21. *
  22. * \author Mark Spencer <markster@digium.com>
  23. */
  24. /*** MODULEINFO
  25. <support_level>core</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  29. #include <sys/time.h>
  30. #include <sys/resource.h>
  31. #include <math.h>
  32. #include "asterisk/lock.h"
  33. #include "asterisk/channel.h"
  34. #include "asterisk/translate.h"
  35. #include "asterisk/module.h"
  36. #include "asterisk/frame.h"
  37. #include "asterisk/sched.h"
  38. #include "asterisk/cli.h"
  39. #include "asterisk/term.h"
  40. /*! \todo
  41. * TODO: sample frames for each supported input format.
  42. * We build this on the fly, by taking an SLIN frame and using
  43. * the existing converter to play with it.
  44. */
  45. /*! max sample recalc */
  46. #define MAX_RECALC 1000
  47. /*! \brief the list of translators */
  48. static AST_RWLIST_HEAD_STATIC(translators, ast_translator);
  49. struct translator_path {
  50. struct ast_translator *step; /*!< Next step translator */
  51. uint32_t table_cost; /*!< Complete table cost to destination */
  52. uint8_t multistep; /*!< Multiple conversions required for this translation */
  53. };
  54. /*!
  55. * \brief a matrix that, for any pair of supported formats,
  56. * indicates the total cost of translation and the first step.
  57. * The full path can be reconstricted iterating on the matrix
  58. * until step->dstfmt == desired_format.
  59. *
  60. * Array indexes are 'src' and 'dest', in that order.
  61. *
  62. * Note: the lock in the 'translators' list is also used to protect
  63. * this structure.
  64. */
  65. static struct translator_path **__matrix;
  66. /*!
  67. * \brief table for converting index to format id values.
  68. *
  69. * \note this table is protected by the table_lock.
  70. */
  71. static int *__indextable;
  72. /*! protects the __indextable for resizing */
  73. static ast_rwlock_t tablelock;
  74. /* index size starts at this*/
  75. #define INIT_INDEX 32
  76. /* index size grows by this as necessary */
  77. #define GROW_INDEX 16
  78. /*! the current largest index used by the __matrix and __indextable arrays*/
  79. static int cur_max_index;
  80. /*! the largest index that can be used in either the __indextable or __matrix before resize must occur */
  81. static int index_size;
  82. static void matrix_rebuild(int samples);
  83. /*!
  84. * \internal
  85. * \brief converts format id to index value.
  86. */
  87. static int format2index(enum ast_format_id id)
  88. {
  89. int x;
  90. ast_rwlock_rdlock(&tablelock);
  91. for (x = 0; x < cur_max_index; x++) {
  92. if (__indextable[x] == id) {
  93. /* format already exists in index2format table */
  94. ast_rwlock_unlock(&tablelock);
  95. return x;
  96. }
  97. }
  98. ast_rwlock_unlock(&tablelock);
  99. return -1; /* not found */
  100. }
  101. /*!
  102. * \internal
  103. * \brief add a new format to the matrix and index table structures.
  104. *
  105. * \note it is perfectly safe to call this on formats already indexed.
  106. *
  107. * \retval 0, success
  108. * \retval -1, matrix and index table need to be resized
  109. */
  110. static int add_format2index(enum ast_format_id id)
  111. {
  112. if (format2index(id) != -1) {
  113. /* format is already already indexed */
  114. return 0;
  115. }
  116. ast_rwlock_wrlock(&tablelock);
  117. if (cur_max_index == (index_size)) {
  118. ast_rwlock_unlock(&tablelock);
  119. return -1; /* hit max length */
  120. }
  121. __indextable[cur_max_index] = id;
  122. cur_max_index++;
  123. ast_rwlock_unlock(&tablelock);
  124. return 0;
  125. }
  126. /*!
  127. * \internal
  128. * \brief converts index value back to format id
  129. */
  130. static enum ast_format_id index2format(int index)
  131. {
  132. enum ast_format_id format_id;
  133. if (index >= cur_max_index) {
  134. return 0;
  135. }
  136. ast_rwlock_rdlock(&tablelock);
  137. format_id = __indextable[index];
  138. ast_rwlock_unlock(&tablelock);
  139. return format_id;
  140. }
  141. /*!
  142. * \internal
  143. * \brief resize both the matrix and index table so they can represent
  144. * more translators
  145. *
  146. * \note _NO_ locks can be held prior to calling this function
  147. *
  148. * \retval 0, success
  149. * \retval -1, failure. Old matrix and index table can still be used though
  150. */
  151. static int matrix_resize(int init)
  152. {
  153. struct translator_path **tmp_matrix = NULL;
  154. int *tmp_table = NULL;
  155. int old_index;
  156. int x;
  157. AST_RWLIST_WRLOCK(&translators);
  158. ast_rwlock_wrlock(&tablelock);
  159. old_index = index_size;
  160. if (init) {
  161. index_size += INIT_INDEX;
  162. } else {
  163. index_size += GROW_INDEX;
  164. }
  165. /* make new 2d array of translator_path structures */
  166. if (!(tmp_matrix = ast_calloc(1, sizeof(struct translator_path *) * (index_size)))) {
  167. goto resize_cleanup;
  168. }
  169. for (x = 0; x < index_size; x++) {
  170. if (!(tmp_matrix[x] = ast_calloc(1, sizeof(struct translator_path) * (index_size)))) {
  171. goto resize_cleanup;
  172. }
  173. }
  174. /* make new index table */
  175. if (!(tmp_table = ast_calloc(1, sizeof(int) * index_size))) {
  176. goto resize_cleanup;
  177. }
  178. /* if everything went well this far, free the old and use the new */
  179. if (!init) {
  180. for (x = 0; x < old_index; x++) {
  181. ast_free(__matrix[x]);
  182. }
  183. ast_free(__matrix);
  184. memcpy(tmp_table, __indextable, sizeof(int) * old_index);
  185. ast_free(__indextable);
  186. }
  187. /* now copy them over */
  188. __matrix = tmp_matrix;
  189. __indextable = tmp_table;
  190. matrix_rebuild(0);
  191. ast_rwlock_unlock(&tablelock);
  192. AST_RWLIST_UNLOCK(&translators);
  193. return 0;
  194. resize_cleanup:
  195. ast_rwlock_unlock(&tablelock);
  196. AST_RWLIST_UNLOCK(&translators);
  197. if (tmp_matrix) {
  198. for (x = 0; x < index_size; x++) {
  199. ast_free(tmp_matrix[x]);
  200. }
  201. ast_free(tmp_matrix);
  202. }
  203. ast_free(tmp_table);
  204. return -1;
  205. }
  206. /*!
  207. * \internal
  208. * \brief reinitialize the __matrix during matrix rebuild
  209. *
  210. * \note must be protected by the translators list lock
  211. */
  212. static void matrix_clear(void)
  213. {
  214. int x;
  215. for (x = 0; x < index_size; x++) {
  216. memset(__matrix[x], '\0', sizeof(struct translator_path) * (index_size));
  217. }
  218. }
  219. /*!
  220. * \internal
  221. * \brief get a matrix entry
  222. *
  223. * \note This function must be protected by the translators list lock
  224. */
  225. static struct translator_path *matrix_get(unsigned int x, unsigned int y)
  226. {
  227. if (!(x >= 0 && y >= 0)) {
  228. return NULL;
  229. }
  230. return __matrix[x] + y;
  231. }
  232. /*
  233. * wrappers around the translator routines.
  234. */
  235. /*!
  236. * \brief Allocate the descriptor, required outbuf space,
  237. * and possibly desc.
  238. */
  239. static void *newpvt(struct ast_translator *t, const struct ast_format *explicit_dst)
  240. {
  241. struct ast_trans_pvt *pvt;
  242. int len;
  243. char *ofs;
  244. /*
  245. * compute the required size adding private descriptor,
  246. * buffer, AST_FRIENDLY_OFFSET.
  247. */
  248. len = sizeof(*pvt) + t->desc_size;
  249. if (t->buf_size)
  250. len += AST_FRIENDLY_OFFSET + t->buf_size;
  251. pvt = ast_calloc(1, len);
  252. if (!pvt) {
  253. return NULL;
  254. }
  255. pvt->t = t;
  256. ofs = (char *)(pvt + 1); /* pointer to data space */
  257. if (t->desc_size) { /* first comes the descriptor */
  258. pvt->pvt = ofs;
  259. ofs += t->desc_size;
  260. }
  261. if (t->buf_size) {/* finally buffer and header */
  262. pvt->outbuf.c = ofs + AST_FRIENDLY_OFFSET;
  263. }
  264. /* if a explicit destination format is provided, set that on the pvt so the
  265. * translator will process it. */
  266. if (explicit_dst) {
  267. ast_format_copy(&pvt->explicit_dst, explicit_dst);
  268. }
  269. /* call local init routine, if present */
  270. if (t->newpvt && t->newpvt(pvt)) {
  271. ast_free(pvt);
  272. return NULL;
  273. }
  274. ast_module_ref(t->module);
  275. return pvt;
  276. }
  277. static void destroy(struct ast_trans_pvt *pvt)
  278. {
  279. struct ast_translator *t = pvt->t;
  280. if (t->destroy)
  281. t->destroy(pvt);
  282. ast_free(pvt);
  283. ast_module_unref(t->module);
  284. }
  285. /*! \brief framein wrapper, deals with bound checks. */
  286. static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
  287. {
  288. int ret;
  289. int samples = pvt->samples; /* initial value */
  290. /* Copy the last in jb timing info to the pvt */
  291. ast_copy_flags(&pvt->f, f, AST_FRFLAG_HAS_TIMING_INFO);
  292. pvt->f.ts = f->ts;
  293. pvt->f.len = f->len;
  294. pvt->f.seqno = f->seqno;
  295. if (f->samples == 0) {
  296. ast_log(LOG_WARNING, "no samples for %s\n", pvt->t->name);
  297. }
  298. if (pvt->t->buffer_samples) { /* do not pass empty frames to callback */
  299. if (f->datalen == 0) { /* perform native PLC if available */
  300. /* If the codec has native PLC, then do that */
  301. if (!pvt->t->native_plc)
  302. return 0;
  303. }
  304. if (pvt->samples + f->samples > pvt->t->buffer_samples) {
  305. ast_log(LOG_WARNING, "Out of buffer space\n");
  306. return -1;
  307. }
  308. }
  309. /* we require a framein routine, wouldn't know how to do
  310. * it otherwise.
  311. */
  312. ret = pvt->t->framein(pvt, f);
  313. /* diagnostic ... */
  314. if (pvt->samples == samples)
  315. ast_log(LOG_WARNING, "%s did not update samples %d\n",
  316. pvt->t->name, pvt->samples);
  317. return ret;
  318. }
  319. /*! \brief generic frameout routine.
  320. * If samples and datalen are 0, take whatever is in pvt
  321. * and reset them, otherwise take the values in the caller and
  322. * leave alone the pvt values.
  323. */
  324. struct ast_frame *ast_trans_frameout(struct ast_trans_pvt *pvt,
  325. int datalen, int samples)
  326. {
  327. struct ast_frame *f = &pvt->f;
  328. if (samples) {
  329. f->samples = samples;
  330. } else {
  331. if (pvt->samples == 0)
  332. return NULL;
  333. f->samples = pvt->samples;
  334. pvt->samples = 0;
  335. }
  336. if (datalen) {
  337. f->datalen = datalen;
  338. } else {
  339. f->datalen = pvt->datalen;
  340. pvt->datalen = 0;
  341. }
  342. f->frametype = AST_FRAME_VOICE;
  343. ast_format_copy(&f->subclass.format, &pvt->t->dst_format);
  344. f->mallocd = 0;
  345. f->offset = AST_FRIENDLY_OFFSET;
  346. f->src = pvt->t->name;
  347. f->data.ptr = pvt->outbuf.c;
  348. return ast_frisolate(f);
  349. }
  350. static struct ast_frame *default_frameout(struct ast_trans_pvt *pvt)
  351. {
  352. return ast_trans_frameout(pvt, 0, 0);
  353. }
  354. /* end of callback wrappers and helpers */
  355. void ast_translator_free_path(struct ast_trans_pvt *p)
  356. {
  357. struct ast_trans_pvt *pn = p;
  358. while ( (p = pn) ) {
  359. pn = p->next;
  360. destroy(p);
  361. }
  362. }
  363. /*! \brief Build a chain of translators based upon the given source and dest formats */
  364. struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct ast_format *src)
  365. {
  366. struct ast_trans_pvt *head = NULL, *tail = NULL;
  367. int src_index, dst_index;
  368. struct ast_format tmp_fmt1;
  369. struct ast_format tmp_fmt2;
  370. src_index = format2index(src->id);
  371. dst_index = format2index(dst->id);
  372. if (src_index == -1 || dst_index == -1) {
  373. ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src_index == -1 ? "starting" : "ending");
  374. return NULL;
  375. }
  376. AST_RWLIST_RDLOCK(&translators);
  377. while (src_index != dst_index) {
  378. struct ast_trans_pvt *cur;
  379. struct ast_format *explicit_dst = NULL;
  380. struct ast_translator *t = matrix_get(src_index, dst_index)->step;
  381. if (!t) {
  382. int src_id = index2format(src_index);
  383. int dst_id = index2format(dst_index);
  384. ast_log(LOG_WARNING, "No translator path from %s to %s\n",
  385. ast_getformatname(ast_format_set(&tmp_fmt1, src_id, 0)),
  386. ast_getformatname(ast_format_set(&tmp_fmt2, dst_id, 0)));
  387. AST_RWLIST_UNLOCK(&translators);
  388. return NULL;
  389. }
  390. if (dst_index == t->dst_fmt_index) {
  391. explicit_dst = dst;
  392. }
  393. if (!(cur = newpvt(t, explicit_dst))) {
  394. int src_id = index2format(src_index);
  395. int dst_id = index2format(dst_index);
  396. ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n",
  397. ast_getformatname(ast_format_set(&tmp_fmt1, src_id, 0)),
  398. ast_getformatname(ast_format_set(&tmp_fmt2, dst_id, 0)));
  399. if (head) {
  400. ast_translator_free_path(head);
  401. }
  402. AST_RWLIST_UNLOCK(&translators);
  403. return NULL;
  404. }
  405. if (!head) {
  406. head = cur;
  407. } else {
  408. tail->next = cur;
  409. }
  410. tail = cur;
  411. cur->nextin = cur->nextout = ast_tv(0, 0);
  412. /* Keep going if this isn't the final destination */
  413. src_index = cur->t->dst_fmt_index;
  414. }
  415. AST_RWLIST_UNLOCK(&translators);
  416. return head;
  417. }
  418. /*! \brief do the actual translation */
  419. struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
  420. {
  421. struct ast_trans_pvt *p = path;
  422. struct ast_frame *out;
  423. struct timeval delivery;
  424. int has_timing_info;
  425. long ts;
  426. long len;
  427. int seqno;
  428. has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO);
  429. ts = f->ts;
  430. len = f->len;
  431. seqno = f->seqno;
  432. if (!ast_tvzero(f->delivery)) {
  433. if (!ast_tvzero(path->nextin)) {
  434. /* Make sure this is in line with what we were expecting */
  435. if (!ast_tveq(path->nextin, f->delivery)) {
  436. /* The time has changed between what we expected and this
  437. most recent time on the new packet. If we have a
  438. valid prediction adjust our output time appropriately */
  439. if (!ast_tvzero(path->nextout)) {
  440. path->nextout = ast_tvadd(path->nextout,
  441. ast_tvsub(f->delivery, path->nextin));
  442. }
  443. path->nextin = f->delivery;
  444. }
  445. } else {
  446. /* This is our first pass. Make sure the timing looks good */
  447. path->nextin = f->delivery;
  448. path->nextout = f->delivery;
  449. }
  450. /* Predict next incoming sample */
  451. path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, ast_format_rate(&f->subclass.format)));
  452. }
  453. delivery = f->delivery;
  454. for (out = f; out && p ; p = p->next) {
  455. framein(p, out);
  456. if (out != f) {
  457. ast_frfree(out);
  458. }
  459. out = p->t->frameout(p);
  460. }
  461. if (consume) {
  462. ast_frfree(f);
  463. }
  464. if (out == NULL) {
  465. return NULL;
  466. }
  467. /* we have a frame, play with times */
  468. if (!ast_tvzero(delivery)) {
  469. /* Regenerate prediction after a discontinuity */
  470. if (ast_tvzero(path->nextout)) {
  471. path->nextout = ast_tvnow();
  472. }
  473. /* Use next predicted outgoing timestamp */
  474. out->delivery = path->nextout;
  475. /* Predict next outgoing timestamp from samples in this
  476. frame. */
  477. path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format)));
  478. } else {
  479. out->delivery = ast_tv(0, 0);
  480. ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
  481. if (has_timing_info) {
  482. out->ts = ts;
  483. out->len = len;
  484. out->seqno = seqno;
  485. }
  486. }
  487. /* Invalidate prediction if we're entering a silence period */
  488. if (out->frametype == AST_FRAME_CNG) {
  489. path->nextout = ast_tv(0, 0);
  490. }
  491. return out;
  492. }
  493. /*!
  494. * \internal
  495. * \brief Compute the computational cost of a single translation step.
  496. *
  497. * \note This function is only used to decide which translation path to
  498. * use between two translators with identical src and dst formats. Computational
  499. * cost acts only as a tie breaker. This is done so hardware translators
  500. * can naturally have precedence over software translators.
  501. */
  502. static void generate_computational_cost(struct ast_translator *t, int seconds)
  503. {
  504. int num_samples = 0;
  505. struct ast_trans_pvt *pvt;
  506. struct rusage start;
  507. struct rusage end;
  508. int cost;
  509. int out_rate = ast_format_rate(&t->dst_format);
  510. if (!seconds) {
  511. seconds = 1;
  512. }
  513. /* If they don't make samples, give them a terrible score */
  514. if (!t->sample) {
  515. ast_debug(3, "Translator '%s' does not produce sample frames.\n", t->name);
  516. t->comp_cost = 999999;
  517. return;
  518. }
  519. pvt = newpvt(t, NULL);
  520. if (!pvt) {
  521. ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
  522. t->comp_cost = 999999;
  523. return;
  524. }
  525. getrusage(RUSAGE_SELF, &start);
  526. /* Call the encoder until we've processed the required number of samples */
  527. while (num_samples < seconds * out_rate) {
  528. struct ast_frame *f = t->sample();
  529. if (!f) {
  530. ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
  531. destroy(pvt);
  532. t->comp_cost = 999999;
  533. return;
  534. }
  535. framein(pvt, f);
  536. ast_frfree(f);
  537. while ((f = t->frameout(pvt))) {
  538. num_samples += f->samples;
  539. ast_frfree(f);
  540. }
  541. }
  542. getrusage(RUSAGE_SELF, &end);
  543. cost = ((end.ru_utime.tv_sec - start.ru_utime.tv_sec) * 1000000) + end.ru_utime.tv_usec - start.ru_utime.tv_usec;
  544. cost += ((end.ru_stime.tv_sec - start.ru_stime.tv_sec) * 1000000) + end.ru_stime.tv_usec - start.ru_stime.tv_usec;
  545. destroy(pvt);
  546. t->comp_cost = cost / seconds;
  547. if (!t->comp_cost) {
  548. t->comp_cost = 1;
  549. }
  550. }
  551. /*!
  552. * \internal
  553. *
  554. * \brief If no table cost value was pre set by the translator. An attempt is made to
  555. * automatically generate that cost value from the cost table based on our src and
  556. * dst formats.
  557. *
  558. * \note This function allows older translators built before the translation cost
  559. * changed away from using onely computational time to continue to be registered
  560. * correctly. It is expected that translators built after the introduction of this
  561. * function will manually assign their own table cost value.
  562. *
  563. * \note This function is safe to use on any audio formats that used to be defined in the
  564. * first 64 bits of the old bit field codec representation.
  565. *
  566. * \retval Table Cost value greater than 0.
  567. * \retval 0 on error.
  568. */
  569. static int generate_table_cost(struct ast_format *src, struct ast_format *dst)
  570. {
  571. int src_rate = ast_format_rate(src);
  572. int src_ll = 0;
  573. int dst_rate = ast_format_rate(dst);
  574. int dst_ll = 0;
  575. if ((AST_FORMAT_GET_TYPE(src->id) != AST_FORMAT_TYPE_AUDIO) || (AST_FORMAT_GET_TYPE(dst->id) != AST_FORMAT_TYPE_AUDIO)) {
  576. /* This method of generating table cost is limited to audio.
  577. * Translators for media other than audio must manually set their
  578. * table cost. */
  579. return 0;
  580. }
  581. src_ll = ast_format_is_slinear(src);
  582. dst_ll = ast_format_is_slinear(dst);
  583. if (src_ll) {
  584. if (dst_ll && (src_rate == dst_rate)) {
  585. return AST_TRANS_COST_LL_LL_ORIGSAMP;
  586. } else if (!dst_ll && (src_rate == dst_rate)) {
  587. return AST_TRANS_COST_LL_LY_ORIGSAMP;
  588. } else if (dst_ll && (src_rate < dst_rate)) {
  589. return AST_TRANS_COST_LL_LL_UPSAMP;
  590. } else if (!dst_ll && (src_rate < dst_rate)) {
  591. return AST_TRANS_COST_LL_LY_UPSAMP;
  592. } else if (dst_ll && (src_rate > dst_rate)) {
  593. return AST_TRANS_COST_LL_LL_DOWNSAMP;
  594. } else if (!dst_ll && (src_rate > dst_rate)) {
  595. return AST_TRANS_COST_LL_LY_DOWNSAMP;
  596. } else {
  597. return AST_TRANS_COST_LL_UNKNOWN;
  598. }
  599. } else {
  600. if (dst_ll && (src_rate == dst_rate)) {
  601. return AST_TRANS_COST_LY_LL_ORIGSAMP;
  602. } else if (!dst_ll && (src_rate == dst_rate)) {
  603. return AST_TRANS_COST_LY_LY_ORIGSAMP;
  604. } else if (dst_ll && (src_rate < dst_rate)) {
  605. return AST_TRANS_COST_LY_LL_UPSAMP;
  606. } else if (!dst_ll && (src_rate < dst_rate)) {
  607. return AST_TRANS_COST_LY_LY_UPSAMP;
  608. } else if (dst_ll && (src_rate > dst_rate)) {
  609. return AST_TRANS_COST_LY_LL_DOWNSAMP;
  610. } else if (!dst_ll && (src_rate > dst_rate)) {
  611. return AST_TRANS_COST_LY_LY_DOWNSAMP;
  612. } else {
  613. return AST_TRANS_COST_LY_UNKNOWN;
  614. }
  615. }
  616. }
  617. /*!
  618. * \brief rebuild a translation matrix.
  619. * \note This function expects the list of translators to be locked
  620. */
  621. static void matrix_rebuild(int samples)
  622. {
  623. struct ast_translator *t;
  624. int newtablecost;
  625. int x; /* source format index */
  626. int y; /* intermediate format index */
  627. int z; /* destination format index */
  628. ast_debug(1, "Resetting translation matrix\n");
  629. matrix_clear();
  630. /* first, compute all direct costs */
  631. AST_RWLIST_TRAVERSE(&translators, t, list) {
  632. if (!t->active) {
  633. continue;
  634. }
  635. x = t->src_fmt_index;
  636. z = t->dst_fmt_index;
  637. if (samples) {
  638. generate_computational_cost(t, samples);
  639. }
  640. /* This new translator is the best choice if any of the below are true.
  641. * 1. no translation path is set between x and z yet.
  642. * 2. the new table cost is less.
  643. * 3. the new computational cost is less. Computational cost is only used
  644. * to break a tie between two identical translation paths.
  645. */
  646. if (!matrix_get(x, z)->step ||
  647. (t->table_cost < matrix_get(x, z)->step->table_cost) ||
  648. (t->comp_cost < matrix_get(x, z)->step->comp_cost)) {
  649. matrix_get(x, z)->step = t;
  650. matrix_get(x, z)->table_cost = t->table_cost;
  651. }
  652. }
  653. /*
  654. * For each triple x, y, z of distinct formats, check if there is
  655. * a path from x to z through y which is cheaper than what is
  656. * currently known, and in case, update the matrix.
  657. * Repeat until the matrix is stable.
  658. */
  659. for (;;) {
  660. int changed = 0;
  661. for (x = 0; x < cur_max_index; x++) { /* source format */
  662. for (y = 0; y < cur_max_index; y++) { /* intermediate format */
  663. if (x == y) { /* skip ourselves */
  664. continue;
  665. }
  666. for (z = 0; z < cur_max_index; z++) { /* dst format */
  667. if ((z == x || z == y) || /* skip null conversions */
  668. !matrix_get(x, y)->step || /* no path from x to y */
  669. !matrix_get(y, z)->step) { /* no path from y to z */
  670. continue;
  671. }
  672. /* calculate table cost from x->y->z */
  673. newtablecost = matrix_get(x, y)->table_cost + matrix_get(y, z)->table_cost;
  674. /* if no step already exists between x and z OR the new cost of using the intermediate
  675. * step is cheaper, use this step. */
  676. if (!matrix_get(x, z)->step || (newtablecost < matrix_get(x, z)->table_cost)) {
  677. struct ast_format tmpx;
  678. struct ast_format tmpy;
  679. struct ast_format tmpz;
  680. matrix_get(x, z)->step = matrix_get(x, y)->step;
  681. matrix_get(x, z)->table_cost = newtablecost;
  682. matrix_get(x, z)->multistep = 1;
  683. changed++;
  684. ast_debug(3, "Discovered %d cost path from %s to %s, via %s\n",
  685. matrix_get(x, z)->table_cost,
  686. ast_getformatname(ast_format_set(&tmpx, index2format(x), 0)),
  687. ast_getformatname(ast_format_set(&tmpy, index2format(z), 0)),
  688. ast_getformatname(ast_format_set(&tmpz, index2format(y), 0)));
  689. }
  690. }
  691. }
  692. }
  693. if (!changed) {
  694. break;
  695. }
  696. }
  697. }
  698. const char *ast_translate_path_to_str(struct ast_trans_pvt *p, struct ast_str **str)
  699. {
  700. struct ast_trans_pvt *pn = p;
  701. char tmp[256];
  702. if (!p || !p->t) {
  703. return "";
  704. }
  705. ast_str_set(str, 0, "%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), p->t->src_format.id));
  706. while ( (p = pn) ) {
  707. pn = p->next;
  708. ast_str_append(str, 0, "->%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), p->t->dst_format.id));
  709. }
  710. return ast_str_buffer(*str);
  711. }
  712. static char *complete_trans_path_choice(const char *line, const char *word, int pos, int state)
  713. {
  714. int which = 0;
  715. int wordlen = strlen(word);
  716. int i;
  717. char *ret = NULL;
  718. size_t len = 0;
  719. const struct ast_format_list *format_list = ast_format_list_get(&len);
  720. for (i = 0; i < len; i++) {
  721. if (AST_FORMAT_GET_TYPE(format_list[i].format.id) != AST_FORMAT_TYPE_AUDIO) {
  722. continue;
  723. }
  724. if (!strncasecmp(word, format_list[i].name, wordlen) && ++which > state) {
  725. ret = ast_strdup(format_list[i].name);
  726. break;
  727. }
  728. }
  729. ast_format_list_destroy(format_list);
  730. return ret;
  731. }
  732. static void handle_cli_recalc(struct ast_cli_args *a)
  733. {
  734. int time = a->argv[4] ? atoi(a->argv[4]) : 1;
  735. if (time <= 0) {
  736. ast_cli(a->fd, " Recalc must be greater than 0. Defaulting to 1.\n");
  737. time = 1;
  738. }
  739. if (time > MAX_RECALC) {
  740. ast_cli(a->fd, " Maximum limit of recalc exceeded by %d, truncating value to %d\n", time - MAX_RECALC, MAX_RECALC);
  741. time = MAX_RECALC;
  742. }
  743. ast_cli(a->fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", time);
  744. AST_RWLIST_WRLOCK(&translators);
  745. matrix_rebuild(time);
  746. AST_RWLIST_UNLOCK(&translators);
  747. }
  748. static char *handle_show_translation_table(struct ast_cli_args *a)
  749. {
  750. int x;
  751. int y;
  752. int i;
  753. int k;
  754. int curlen = 0;
  755. int longest = 0;
  756. int f_len;
  757. size_t f_size = 0;
  758. const struct ast_format_list *f_list = ast_format_list_get(&f_size);
  759. struct ast_str *out = ast_str_create(1024);
  760. f_len = f_size;
  761. AST_RWLIST_RDLOCK(&translators);
  762. ast_cli(a->fd, " Translation times between formats (in microseconds) for one second of data\n");
  763. ast_cli(a->fd, " Source Format (Rows) Destination Format (Columns)\n\n");
  764. /* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
  765. for (i = 0; i < f_len; i++) {
  766. /* translation only applies to audio right now. */
  767. if (AST_FORMAT_GET_TYPE(f_list[i].format.id) != AST_FORMAT_TYPE_AUDIO)
  768. continue;
  769. curlen = strlen(ast_getformatname(&f_list[i].format));
  770. if (curlen > longest) {
  771. longest = curlen;
  772. }
  773. }
  774. for (i = -1; i < f_len; i++) {
  775. x = -1;
  776. if ((i >= 0) && ((x = format2index(f_list[i].format.id)) == -1)) {
  777. continue;
  778. }
  779. /* translation only applies to audio right now. */
  780. if (i >= 0 && (AST_FORMAT_GET_TYPE(f_list[i].format.id) != AST_FORMAT_TYPE_AUDIO)) {
  781. continue;
  782. }
  783. /*Go ahead and move to next iteration if dealing with an unknown codec*/
  784. if (i >= 0 && !strcmp(ast_getformatname(&f_list[i].format), "unknown")) {
  785. continue;
  786. }
  787. ast_str_set(&out, 0, " ");
  788. for (k = -1; k < f_len; k++) {
  789. y = -1;
  790. if ((k >= 0) && ((y = format2index(f_list[k].format.id)) == -1)) {
  791. continue;
  792. }
  793. /* translation only applies to audio right now. */
  794. if (k >= 0 && (AST_FORMAT_GET_TYPE(f_list[k].format.id) != AST_FORMAT_TYPE_AUDIO)) {
  795. continue;
  796. }
  797. /*Go ahead and move to next iteration if dealing with an unknown codec*/
  798. if (k >= 0 && !strcmp(ast_getformatname(&f_list[k].format), "unknown")) {
  799. continue;
  800. }
  801. if (k >= 0) {
  802. curlen = strlen(ast_getformatname(&f_list[k].format));
  803. }
  804. if (curlen < 5) {
  805. curlen = 5;
  806. }
  807. if (x >= 0 && y >= 0 && matrix_get(x, y)->step) {
  808. /* Actual codec output */
  809. ast_str_append(&out, 0, "%*d", curlen + 1, (matrix_get(x, y)->table_cost/100));
  810. } else if (i == -1 && k >= 0) {
  811. /* Top row - use a dynamic size */
  812. ast_str_append(&out, 0, "%*s", curlen + 1, ast_getformatname(&f_list[k].format));
  813. } else if (k == -1 && i >= 0) {
  814. /* Left column - use a static size. */
  815. ast_str_append(&out, 0, "%*s", longest, ast_getformatname(&f_list[i].format));
  816. } else if (x >= 0 && y >= 0) {
  817. /* Codec not supported */
  818. ast_str_append(&out, 0, "%*s", curlen + 1, "-");
  819. } else {
  820. /* Upper left hand corner */
  821. ast_str_append(&out, 0, "%*s", longest, "");
  822. }
  823. }
  824. ast_str_append(&out, 0, "\n");
  825. ast_cli(a->fd, "%s", ast_str_buffer(out));
  826. }
  827. ast_free(out);
  828. AST_RWLIST_UNLOCK(&translators);
  829. ast_format_list_destroy(f_list);
  830. return CLI_SUCCESS;
  831. }
  832. static char *handle_show_translation_path(struct ast_cli_args *a)
  833. {
  834. struct ast_format input_src_format;
  835. size_t len = 0;
  836. int i;
  837. const struct ast_format_list *format_list = ast_format_list_get(&len);
  838. struct ast_str *str = ast_str_alloca(1024);
  839. struct ast_translator *step;
  840. char tmp[256];
  841. ast_format_clear(&input_src_format);
  842. for (i = 0; i < len; i++) {
  843. if (AST_FORMAT_GET_TYPE(format_list[i].format.id) != AST_FORMAT_TYPE_AUDIO) {
  844. continue;
  845. }
  846. if (!strncasecmp(format_list[i].name, a->argv[4], strlen(format_list[i].name))) {
  847. ast_format_copy(&input_src_format, &format_list[i].format);
  848. }
  849. }
  850. if (!input_src_format.id) {
  851. ast_cli(a->fd, "Source codec \"%s\" is not found.\n", a->argv[4]);
  852. ast_format_list_destroy(format_list);
  853. return CLI_FAILURE;
  854. }
  855. AST_RWLIST_RDLOCK(&translators);
  856. ast_cli(a->fd, "--- Translation paths SRC Codec \"%s\" sample rate %d ---\n", a->argv[4], ast_format_rate(&input_src_format));
  857. for (i = 0; i < len; i++) {
  858. int src;
  859. int dst;
  860. if ((AST_FORMAT_GET_TYPE(format_list[i].format.id) != AST_FORMAT_TYPE_AUDIO) || (format_list[i].format.id == input_src_format.id)) {
  861. continue;
  862. }
  863. dst = format2index(format_list[i].format.id);
  864. src = format2index(input_src_format.id);
  865. ast_str_reset(str);
  866. if ((len >= cur_max_index) && (src != -1) && (dst != -1) && matrix_get(src, dst)->step) {
  867. ast_str_append(&str, 0, "%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), matrix_get(src, dst)->step->src_format.id));
  868. while (src != dst) {
  869. step = matrix_get(src, dst)->step;
  870. if (!step) {
  871. ast_str_reset(str);
  872. break;
  873. }
  874. ast_str_append(&str, 0, "->%s", ast_getformatname_multiple_byid(tmp, sizeof(tmp), step->dst_format.id));
  875. src = step->dst_fmt_index;
  876. }
  877. }
  878. if (ast_strlen_zero(ast_str_buffer(str))) {
  879. ast_str_set(&str, 0, "No Translation Path");
  880. }
  881. ast_cli(a->fd, "\t%-10.10s To %-10.10s: %-60.60s\n", a->argv[4], format_list[i].name, ast_str_buffer(str));
  882. }
  883. AST_RWLIST_UNLOCK(&translators);
  884. ast_format_list_destroy(format_list);
  885. return CLI_SUCCESS;
  886. }
  887. static char *handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  888. {
  889. static const char * const option[] = { "recalc", "paths", NULL };
  890. switch (cmd) {
  891. case CLI_INIT:
  892. e->command = "core show translation";
  893. e->usage =
  894. "Usage: 'core show translation' can be used in two ways.\n"
  895. " 1. 'core show translation [recalc [<recalc seconds>]]\n"
  896. " Displays known codec translators and the cost associated\n"
  897. " with each conversion. If the argument 'recalc' is supplied along\n"
  898. " with optional number of seconds to test a new test will be performed\n"
  899. " as the chart is being displayed.\n"
  900. " 2. 'core show translation paths [codec]'\n"
  901. " This will display all the translation paths associated with a codec\n";
  902. return NULL;
  903. case CLI_GENERATE:
  904. if (a->pos == 3) {
  905. return ast_cli_complete(a->word, option, a->n);
  906. }
  907. if (a->pos == 4 && !strcasecmp(a->argv[3], option[1])) {
  908. return complete_trans_path_choice(a->line, a->word, a->pos, a->n);
  909. }
  910. return NULL;
  911. }
  912. if (a->argc > 5)
  913. return CLI_SHOWUSAGE;
  914. if (a->argv[3] && !strcasecmp(a->argv[3], option[1]) && a->argc == 5) { /* show paths */
  915. return handle_show_translation_path(a);
  916. } else if (a->argv[3] && !strcasecmp(a->argv[3], option[0])) { /* recalc and then fall through to show table */
  917. handle_cli_recalc(a);
  918. } else if (a->argc > 3) { /* wrong input */
  919. return CLI_SHOWUSAGE;
  920. }
  921. return handle_show_translation_table(a);
  922. }
  923. static struct ast_cli_entry cli_translate[] = {
  924. AST_CLI_DEFINE(handle_cli_core_show_translation, "Display translation matrix")
  925. };
  926. /*! \brief register codec translator */
  927. int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
  928. {
  929. struct ast_translator *u;
  930. char tmp[80];
  931. if (add_format2index(t->src_format.id) || add_format2index(t->dst_format.id)) {
  932. if (matrix_resize(0)) {
  933. ast_log(LOG_WARNING, "Translator matrix can not represent any more translators. Out of resources.\n");
  934. return -1;
  935. }
  936. add_format2index(t->src_format.id);
  937. add_format2index(t->dst_format.id);
  938. }
  939. if (!mod) {
  940. ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n");
  941. return -1;
  942. }
  943. if (!t->buf_size) {
  944. ast_log(LOG_WARNING, "empty buf size, you need to supply one\n");
  945. return -1;
  946. }
  947. if (!t->table_cost && !(t->table_cost = generate_table_cost(&t->src_format, &t->dst_format))) {
  948. ast_log(LOG_WARNING, "Table cost could not be generated for %s, "
  949. "Please set table_cost variable on translator.\n", t->name);
  950. return -1;
  951. }
  952. t->module = mod;
  953. t->src_fmt_index = format2index(t->src_format.id);
  954. t->dst_fmt_index = format2index(t->dst_format.id);
  955. t->active = 1;
  956. if (t->src_fmt_index == -1 || t->dst_fmt_index == -1) {
  957. ast_log(LOG_WARNING, "Invalid translator path: (%s codec is not valid)\n", t->src_fmt_index == -1 ? "starting" : "ending");
  958. return -1;
  959. }
  960. if (t->src_fmt_index >= cur_max_index) {
  961. ast_log(LOG_WARNING, "Source format %s is larger than cur_max_index\n", ast_getformatname(&t->src_format));
  962. return -1;
  963. }
  964. if (t->dst_fmt_index >= cur_max_index) {
  965. ast_log(LOG_WARNING, "Destination format %s is larger than cur_max_index\n", ast_getformatname(&t->dst_format));
  966. return -1;
  967. }
  968. if (t->buf_size) {
  969. /*
  970. * Align buf_size properly, rounding up to the machine-specific
  971. * alignment for pointers.
  972. */
  973. struct _test_align { void *a, *b; } p;
  974. int align = (char *)&p.b - (char *)&p.a;
  975. t->buf_size = ((t->buf_size + align - 1) / align) * align;
  976. }
  977. if (t->frameout == NULL) {
  978. t->frameout = default_frameout;
  979. }
  980. generate_computational_cost(t, 1);
  981. ast_verb(2, "Registered translator '%s' from format %s to %s, table cost, %d, computational cost %d\n",
  982. term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
  983. ast_getformatname(&t->src_format), ast_getformatname(&t->dst_format), t->table_cost, t->comp_cost);
  984. AST_RWLIST_WRLOCK(&translators);
  985. /* find any existing translators that provide this same srcfmt/dstfmt,
  986. and put this one in order based on computational cost */
  987. AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
  988. if ((u->src_fmt_index == t->src_fmt_index) &&
  989. (u->dst_fmt_index == t->dst_fmt_index) &&
  990. (u->comp_cost > t->comp_cost)) {
  991. AST_RWLIST_INSERT_BEFORE_CURRENT(t, list);
  992. t = NULL;
  993. break;
  994. }
  995. }
  996. AST_RWLIST_TRAVERSE_SAFE_END;
  997. /* if no existing translator was found for this format combination,
  998. add it to the beginning of the list */
  999. if (t) {
  1000. AST_RWLIST_INSERT_HEAD(&translators, t, list);
  1001. }
  1002. matrix_rebuild(0);
  1003. AST_RWLIST_UNLOCK(&translators);
  1004. return 0;
  1005. }
  1006. /*! \brief unregister codec translator */
  1007. int ast_unregister_translator(struct ast_translator *t)
  1008. {
  1009. char tmp[80];
  1010. struct ast_translator *u;
  1011. int found = 0;
  1012. AST_RWLIST_WRLOCK(&translators);
  1013. AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
  1014. if (u == t) {
  1015. AST_RWLIST_REMOVE_CURRENT(list);
  1016. ast_verb(2, "Unregistered translator '%s' from format %s to %s\n",
  1017. term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
  1018. ast_getformatname(&t->src_format),
  1019. ast_getformatname(&t->dst_format));
  1020. found = 1;
  1021. break;
  1022. }
  1023. }
  1024. AST_RWLIST_TRAVERSE_SAFE_END;
  1025. if (found) {
  1026. matrix_rebuild(0);
  1027. }
  1028. AST_RWLIST_UNLOCK(&translators);
  1029. return (u ? 0 : -1);
  1030. }
  1031. void ast_translator_activate(struct ast_translator *t)
  1032. {
  1033. AST_RWLIST_WRLOCK(&translators);
  1034. t->active = 1;
  1035. matrix_rebuild(0);
  1036. AST_RWLIST_UNLOCK(&translators);
  1037. }
  1038. void ast_translator_deactivate(struct ast_translator *t)
  1039. {
  1040. AST_RWLIST_WRLOCK(&translators);
  1041. t->active = 0;
  1042. matrix_rebuild(0);
  1043. AST_RWLIST_UNLOCK(&translators);
  1044. }
  1045. /*! \brief Calculate our best translator source format, given costs, and a desired destination */
  1046. int ast_translator_best_choice(struct ast_format_cap *dst_cap,
  1047. struct ast_format_cap *src_cap,
  1048. struct ast_format *dst_fmt_out,
  1049. struct ast_format *src_fmt_out)
  1050. {
  1051. unsigned int besttablecost = INT_MAX;
  1052. unsigned int beststeps = INT_MAX;
  1053. struct ast_format best;
  1054. struct ast_format bestdst;
  1055. struct ast_format_cap *joint_cap = ast_format_cap_joint(dst_cap, src_cap);
  1056. ast_format_clear(&best);
  1057. ast_format_clear(&bestdst);
  1058. if (joint_cap) { /* yes, pick one and return */
  1059. struct ast_format tmp_fmt;
  1060. ast_format_cap_iter_start(joint_cap);
  1061. while (!ast_format_cap_iter_next(joint_cap, &tmp_fmt)) {
  1062. /* We are guaranteed to find one common format. */
  1063. if (!best.id) {
  1064. ast_format_copy(&best, &tmp_fmt);
  1065. continue;
  1066. }
  1067. /* If there are multiple common formats, pick the one with the highest sample rate */
  1068. if (ast_format_rate(&best) < ast_format_rate(&tmp_fmt)) {
  1069. ast_format_copy(&best, &tmp_fmt);
  1070. continue;
  1071. }
  1072. }
  1073. ast_format_cap_iter_end(joint_cap);
  1074. /* We are done, this is a common format to both. */
  1075. ast_format_copy(dst_fmt_out, &best);
  1076. ast_format_copy(src_fmt_out, &best);
  1077. ast_format_cap_destroy(joint_cap);
  1078. return 0;
  1079. } else { /* No, we will need to translate */
  1080. struct ast_format cur_dst;
  1081. struct ast_format cur_src;
  1082. AST_RWLIST_RDLOCK(&translators);
  1083. ast_format_cap_iter_start(dst_cap);
  1084. while (!ast_format_cap_iter_next(dst_cap, &cur_dst)) {
  1085. ast_format_cap_iter_start(src_cap);
  1086. while (!ast_format_cap_iter_next(src_cap, &cur_src)) {
  1087. int x = format2index(cur_src.id);
  1088. int y = format2index(cur_dst.id);
  1089. if (x < 0 || y < 0) {
  1090. continue;
  1091. }
  1092. if (!matrix_get(x, y) || !(matrix_get(x, y)->step)) {
  1093. continue;
  1094. }
  1095. if (((matrix_get(x, y)->table_cost < besttablecost) || (matrix_get(x, y)->multistep < beststeps))) {
  1096. /* better than what we have so far */
  1097. ast_format_copy(&best, &cur_src);
  1098. ast_format_copy(&bestdst, &cur_dst);
  1099. besttablecost = matrix_get(x, y)->table_cost;
  1100. beststeps = matrix_get(x, y)->multistep;
  1101. }
  1102. }
  1103. ast_format_cap_iter_end(src_cap);
  1104. }
  1105. ast_format_cap_iter_end(dst_cap);
  1106. AST_RWLIST_UNLOCK(&translators);
  1107. if (best.id) {
  1108. ast_format_copy(dst_fmt_out, &bestdst);
  1109. ast_format_copy(src_fmt_out, &best);
  1110. return 0;
  1111. }
  1112. return -1;
  1113. }
  1114. }
  1115. unsigned int ast_translate_path_steps(struct ast_format *dst_format, struct ast_format *src_format)
  1116. {
  1117. unsigned int res = -1;
  1118. int src, dest;
  1119. /* convert bitwise format numbers into array indices */
  1120. src = format2index(src_format->id);
  1121. dest = format2index(dst_format->id);
  1122. if (src == -1 || dest == -1) {
  1123. ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src == -1 ? "starting" : "ending");
  1124. return -1;
  1125. }
  1126. AST_RWLIST_RDLOCK(&translators);
  1127. if (matrix_get(src, dest)->step) {
  1128. res = matrix_get(src, dest)->multistep + 1;
  1129. }
  1130. AST_RWLIST_UNLOCK(&translators);
  1131. return res;
  1132. }
  1133. void ast_translate_available_formats(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result)
  1134. {
  1135. struct ast_format tmp_fmt;
  1136. struct ast_format cur_src;
  1137. int src_audio = 0;
  1138. int src_video = 0;
  1139. int index;
  1140. ast_format_cap_copy(result, dest);
  1141. /* if we don't have a source format, we just have to try all
  1142. possible destination formats */
  1143. if (!src) {
  1144. return;
  1145. }
  1146. ast_format_cap_iter_start(src);
  1147. while (!ast_format_cap_iter_next(src, &cur_src)) {
  1148. /* If we have a source audio format, get its format index */
  1149. if (AST_FORMAT_GET_TYPE(cur_src.id) == AST_FORMAT_TYPE_AUDIO) {
  1150. src_audio = format2index(cur_src.id);
  1151. }
  1152. /* If we have a source video format, get its format index */
  1153. if (AST_FORMAT_GET_TYPE(cur_src.id) == AST_FORMAT_TYPE_VIDEO) {
  1154. src_video = format2index(cur_src.id);
  1155. }
  1156. AST_RWLIST_RDLOCK(&translators);
  1157. /* For a given source audio format, traverse the list of
  1158. known audio formats to determine whether there exists
  1159. a translation path from the source format to the
  1160. destination format. */
  1161. for (index = 0; (src_audio >= 0) && index < cur_max_index; index++) {
  1162. ast_format_set(&tmp_fmt, index2format(index), 0);
  1163. if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_AUDIO) {
  1164. continue;
  1165. }
  1166. /* if this is not a desired format, nothing to do */
  1167. if (!ast_format_cap_iscompatible(dest, &tmp_fmt)) {
  1168. continue;
  1169. }
  1170. /* if the source is supplying this format, then
  1171. we can leave it in the result */
  1172. if (ast_format_cap_iscompatible(src, &tmp_fmt)) {
  1173. continue;
  1174. }
  1175. /* if we don't have a translation path from the src
  1176. to this format, remove it from the result */
  1177. if (!matrix_get(src_audio, index)->step) {
  1178. ast_format_cap_remove_byid(result, tmp_fmt.id);
  1179. continue;
  1180. }
  1181. /* now check the opposite direction */
  1182. if (!matrix_get(index, src_audio)->step) {
  1183. ast_format_cap_remove_byid(result, tmp_fmt.id);
  1184. }
  1185. }
  1186. /* For a given source video format, traverse the list of
  1187. known video formats to determine whether there exists
  1188. a translation path from the source format to the
  1189. destination format. */
  1190. for (index = 0; (src_video >= 0) && index < cur_max_index; index++) {
  1191. ast_format_set(&tmp_fmt, index2format(index), 0);
  1192. if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_VIDEO) {
  1193. continue;
  1194. }
  1195. /* if this is not a desired format, nothing to do */
  1196. if (!ast_format_cap_iscompatible(dest, &tmp_fmt)) {
  1197. continue;
  1198. }
  1199. /* if the source is supplying this format, then
  1200. we can leave it in the result */
  1201. if (ast_format_cap_iscompatible(src, &tmp_fmt)) {
  1202. continue;
  1203. }
  1204. /* if we don't have a translation path from the src
  1205. to this format, remove it from the result */
  1206. if (!matrix_get(src_video, index)->step) {
  1207. ast_format_cap_remove_byid(result, tmp_fmt.id);
  1208. continue;
  1209. }
  1210. /* now check the opposite direction */
  1211. if (!matrix_get(index, src_video)->step) {
  1212. ast_format_cap_remove_byid(result, tmp_fmt.id);
  1213. }
  1214. }
  1215. AST_RWLIST_UNLOCK(&translators);
  1216. }
  1217. ast_format_cap_iter_end(src);
  1218. }
  1219. int ast_translate_init(void)
  1220. {
  1221. int res = 0;
  1222. ast_rwlock_init(&tablelock);
  1223. res = matrix_resize(1);
  1224. res |= ast_cli_register_multiple(cli_translate, ARRAY_LEN(cli_translate));
  1225. return res;
  1226. }