translate.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, 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. */
  23. #include <sys/types.h>
  24. #include <sys/socket.h>
  25. #include <sys/time.h>
  26. #include <unistd.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <stdio.h>
  30. #include "asterisk.h"
  31. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  32. #include "asterisk/lock.h"
  33. #include "asterisk/channel.h"
  34. #include "asterisk/logger.h"
  35. #include "asterisk/translate.h"
  36. #include "asterisk/options.h"
  37. #include "asterisk/frame.h"
  38. #include "asterisk/sched.h"
  39. #include "asterisk/cli.h"
  40. #include "asterisk/term.h"
  41. #define MAX_RECALC 200 /* max sample recalc */
  42. /*! \note
  43. This could all be done more efficiently *IF* we chained packets together
  44. by default, but it would also complicate virtually every application. */
  45. AST_MUTEX_DEFINE_STATIC(list_lock);
  46. static struct ast_translator *list = NULL;
  47. struct ast_translator_dir {
  48. struct ast_translator *step; /*!< Next step translator */
  49. unsigned int cost; /*!< Complete cost to destination */
  50. unsigned int multistep; /*!< Multiple conversions required for this translation */
  51. };
  52. struct ast_frame_delivery {
  53. struct ast_frame *f;
  54. struct ast_channel *chan;
  55. int fd;
  56. struct translator_pvt *owner;
  57. struct ast_frame_delivery *prev;
  58. struct ast_frame_delivery *next;
  59. };
  60. static struct ast_translator_dir tr_matrix[MAX_FORMAT][MAX_FORMAT];
  61. struct ast_trans_pvt {
  62. struct ast_translator *step;
  63. struct ast_translator_pvt *state;
  64. struct ast_trans_pvt *next;
  65. struct timeval nextin;
  66. struct timeval nextout;
  67. };
  68. static int powerof(int d)
  69. {
  70. int x;
  71. for (x = 0; x < 32; x++)
  72. if ((1 << x) & d)
  73. return x;
  74. ast_log(LOG_WARNING, "Powerof %d: No power??\n", d);
  75. return -1;
  76. }
  77. void ast_translator_free_path(struct ast_trans_pvt *p)
  78. {
  79. struct ast_trans_pvt *pl, *pn;
  80. pn = p;
  81. while(pn) {
  82. pl = pn;
  83. pn = pn->next;
  84. if (pl->state && pl->step->destroy)
  85. pl->step->destroy(pl->state);
  86. free(pl);
  87. }
  88. }
  89. /*! Build a set of translators based upon the given source and destination formats */
  90. struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
  91. {
  92. struct ast_trans_pvt *tmpr = NULL, *tmp = NULL;
  93. source = powerof(source);
  94. dest = powerof(dest);
  95. while(source != dest) {
  96. if (!tr_matrix[source][dest].step) {
  97. /* We shouldn't have allocated any memory */
  98. ast_log(LOG_WARNING, "No translator path from %s to %s\n",
  99. ast_getformatname(source), ast_getformatname(dest));
  100. return NULL;
  101. }
  102. if (tmp) {
  103. tmp->next = malloc(sizeof(*tmp));
  104. tmp = tmp->next;
  105. } else
  106. tmp = malloc(sizeof(*tmp));
  107. if (!tmp) {
  108. ast_log(LOG_WARNING, "Out of memory\n");
  109. if (tmpr)
  110. ast_translator_free_path(tmpr);
  111. return NULL;
  112. }
  113. /* Set the root, if it doesn't exist yet... */
  114. if (!tmpr)
  115. tmpr = tmp;
  116. tmp->next = NULL;
  117. tmp->nextin = tmp->nextout = ast_tv(0, 0);
  118. tmp->step = tr_matrix[source][dest].step;
  119. tmp->state = tmp->step->newpvt();
  120. if (!tmp->state) {
  121. ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
  122. ast_translator_free_path(tmpr);
  123. return NULL;
  124. }
  125. /* Keep going if this isn't the final destination */
  126. source = tmp->step->dstfmt;
  127. }
  128. return tmpr;
  129. }
  130. struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
  131. {
  132. struct ast_trans_pvt *p;
  133. struct ast_frame *out;
  134. struct timeval delivery;
  135. p = path;
  136. /* Feed the first frame into the first translator */
  137. p->step->framein(p->state, f);
  138. if (!ast_tvzero(f->delivery)) {
  139. if (!ast_tvzero(path->nextin)) {
  140. /* Make sure this is in line with what we were expecting */
  141. if (!ast_tveq(path->nextin, f->delivery)) {
  142. /* The time has changed between what we expected and this
  143. most recent time on the new packet. If we have a
  144. valid prediction adjust our output time appropriately */
  145. if (!ast_tvzero(path->nextout)) {
  146. path->nextout = ast_tvadd(path->nextout,
  147. ast_tvsub(f->delivery, path->nextin));
  148. }
  149. path->nextin = f->delivery;
  150. }
  151. } else {
  152. /* This is our first pass. Make sure the timing looks good */
  153. path->nextin = f->delivery;
  154. path->nextout = f->delivery;
  155. }
  156. /* Predict next incoming sample */
  157. path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 8000));
  158. }
  159. delivery = f->delivery;
  160. if (consume)
  161. ast_frfree(f);
  162. while(p) {
  163. out = p->step->frameout(p->state);
  164. /* If we get nothing out, return NULL */
  165. if (!out)
  166. return NULL;
  167. /* If there is a next state, feed it in there. If not,
  168. return this frame */
  169. if (p->next)
  170. p->next->step->framein(p->next->state, out);
  171. else {
  172. if (!ast_tvzero(delivery)) {
  173. /* Regenerate prediction after a discontinuity */
  174. if (ast_tvzero(path->nextout))
  175. path->nextout = ast_tvnow();
  176. /* Use next predicted outgoing timestamp */
  177. out->delivery = path->nextout;
  178. /* Predict next outgoing timestamp from samples in this
  179. frame. */
  180. path->nextout = ast_tvadd(path->nextout, ast_samp2tv( out->samples, 8000));
  181. } else {
  182. out->delivery = ast_tv(0, 0);
  183. }
  184. /* Invalidate prediction if we're entering a silence period */
  185. if (out->frametype == AST_FRAME_CNG)
  186. path->nextout = ast_tv(0, 0);
  187. return out;
  188. }
  189. p = p->next;
  190. }
  191. ast_log(LOG_WARNING, "I should never get here...\n");
  192. return NULL;
  193. }
  194. static void calc_cost(struct ast_translator *t, int samples)
  195. {
  196. int sofar=0;
  197. struct ast_translator_pvt *pvt;
  198. struct ast_frame *f, *out;
  199. struct timeval start;
  200. int cost;
  201. if(!samples)
  202. samples = 1;
  203. /* If they don't make samples, give them a terrible score */
  204. if (!t->sample) {
  205. ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name);
  206. t->cost = 99999;
  207. return;
  208. }
  209. pvt = t->newpvt();
  210. if (!pvt) {
  211. ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
  212. t->cost = 99999;
  213. return;
  214. }
  215. start = ast_tvnow();
  216. /* Call the encoder until we've processed one second of time */
  217. while(sofar < samples * 8000) {
  218. f = t->sample();
  219. if (!f) {
  220. ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
  221. t->destroy(pvt);
  222. t->cost = 99999;
  223. return;
  224. }
  225. t->framein(pvt, f);
  226. ast_frfree(f);
  227. while((out = t->frameout(pvt))) {
  228. sofar += out->samples;
  229. ast_frfree(out);
  230. }
  231. }
  232. cost = ast_tvdiff_ms(ast_tvnow(), start);
  233. t->destroy(pvt);
  234. t->cost = cost / samples;
  235. if (!t->cost)
  236. t->cost = 1;
  237. }
  238. /*! \brief Use the list of translators to build a translation matrix */
  239. static void rebuild_matrix(int samples)
  240. {
  241. struct ast_translator *t;
  242. int changed;
  243. int x, y, z;
  244. if (option_debug)
  245. ast_log(LOG_DEBUG, "Resetting translation matrix\n");
  246. bzero(tr_matrix, sizeof(tr_matrix));
  247. for (t = list; t; t = t->next) {
  248. if (samples)
  249. calc_cost(t, samples);
  250. if (!tr_matrix[t->srcfmt][t->dstfmt].step ||
  251. tr_matrix[t->srcfmt][t->dstfmt].cost > t->cost) {
  252. tr_matrix[t->srcfmt][t->dstfmt].step = t;
  253. tr_matrix[t->srcfmt][t->dstfmt].cost = t->cost;
  254. }
  255. }
  256. do {
  257. changed = 0;
  258. /* Don't you just love O(N^3) operations? */
  259. for (x = 0; x< MAX_FORMAT; x++) { /* For each source format */
  260. for (y = 0; y < MAX_FORMAT; y++) { /* And each destination format */
  261. if (x == y) /* Except ourselves, of course */
  262. continue;
  263. for (z=0; z < MAX_FORMAT; z++) { /* And each format it might convert to */
  264. if ((x == z) || (y == z)) /* Don't ever convert back to us */
  265. continue;
  266. if (tr_matrix[x][y].step && /* We can convert from x to y */
  267. tr_matrix[y][z].step && /* And from y to z and... */
  268. (!tr_matrix[x][z].step || /* Either there isn't an x->z conversion */
  269. (tr_matrix[x][y].cost +
  270. tr_matrix[y][z].cost < /* Or we're cheaper than the existing */
  271. tr_matrix[x][z].cost) /* solution */
  272. )) {
  273. /* We can get from x to z via y with a cost that
  274. is the sum of the transition from x to y and
  275. from y to z */
  276. tr_matrix[x][z].step = tr_matrix[x][y].step;
  277. tr_matrix[x][z].cost = tr_matrix[x][y].cost +
  278. tr_matrix[y][z].cost;
  279. tr_matrix[x][z].multistep = 1;
  280. if (option_debug)
  281. ast_log(LOG_DEBUG, "Discovered %d cost path from %s to %s, via %d\n", tr_matrix[x][z].cost, ast_getformatname(x), ast_getformatname(z), y);
  282. changed++;
  283. }
  284. }
  285. }
  286. }
  287. } while (changed);
  288. }
  289. /*! \brief CLI "show translation" command handler */
  290. static int show_translation(int fd, int argc, char *argv[])
  291. {
  292. #define SHOW_TRANS 11
  293. int x, y, z;
  294. char line[80];
  295. if (argc > 4)
  296. return RESULT_SHOWUSAGE;
  297. ast_mutex_lock(&list_lock);
  298. if (argv[2] && !strcasecmp(argv[2],"recalc")) {
  299. z = argv[3] ? atoi(argv[3]) : 1;
  300. if (z <= 0) {
  301. ast_cli(fd," C'mon let's be serious here... defaulting to 1.\n");
  302. z = 1;
  303. }
  304. if (z > MAX_RECALC) {
  305. ast_cli(fd," Maximum limit of recalc exceeded by %d, truncating value to %d\n",z-MAX_RECALC,MAX_RECALC);
  306. z = MAX_RECALC;
  307. }
  308. ast_cli(fd," Recalculating Codec Translation (number of sample seconds: %d)\n\n",z);
  309. rebuild_matrix(z);
  310. }
  311. ast_cli(fd, " Translation times between formats (in milliseconds)\n");
  312. ast_cli(fd, " Source Format (Rows) Destination Format(Columns)\n\n");
  313. for (x = -1; x < SHOW_TRANS; x++) {
  314. /* next 2 lines run faster than using strcpy() */
  315. line[0] = ' ';
  316. line[1] = '\0';
  317. for (y=-1;y<SHOW_TRANS;y++) {
  318. if (x >= 0 && y >= 0 && tr_matrix[x][y].step)
  319. snprintf(line + strlen(line), sizeof(line) - strlen(line), " %5d", tr_matrix[x][y].cost >= 99999 ? tr_matrix[x][y].cost-99999 : tr_matrix[x][y].cost);
  320. else
  321. if (((x == -1 && y >= 0) || (y == -1 && x >= 0))) {
  322. snprintf(line + strlen(line), sizeof(line) - strlen(line),
  323. " %5s", ast_getformatname(1<<(x+y+1)) );
  324. } else if (x != -1 && y != -1) {
  325. snprintf(line + strlen(line), sizeof(line) - strlen(line), " -");
  326. } else {
  327. snprintf(line + strlen(line), sizeof(line) - strlen(line), " ");
  328. }
  329. }
  330. snprintf(line + strlen(line), sizeof(line) - strlen(line), "\n");
  331. ast_cli(fd, line);
  332. }
  333. ast_mutex_unlock(&list_lock);
  334. return RESULT_SUCCESS;
  335. }
  336. static int added_cli = 0;
  337. static char show_trans_usage[] =
  338. "Usage: show translation [recalc] [<recalc seconds>]\n"
  339. " Displays known codec translators and the cost associated\n"
  340. "with each conversion. If the argument 'recalc' is supplied along\n"
  341. "with optional number of seconds to test a new test will be performed\n"
  342. "as the chart is being displayed.\n";
  343. static struct ast_cli_entry show_trans =
  344. { { "show", "translation", NULL }, show_translation, "Display translation matrix", show_trans_usage };
  345. int ast_register_translator(struct ast_translator *t)
  346. {
  347. char tmp[80];
  348. t->srcfmt = powerof(t->srcfmt);
  349. t->dstfmt = powerof(t->dstfmt);
  350. if (t->srcfmt >= MAX_FORMAT) {
  351. ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
  352. return -1;
  353. }
  354. if (t->dstfmt >= MAX_FORMAT) {
  355. ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt));
  356. return -1;
  357. }
  358. calc_cost(t,1);
  359. if (option_verbose > 1)
  360. ast_verbose(VERBOSE_PREFIX_2 "Registered translator '%s' from format %s to %s, cost %d\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt), t->cost);
  361. ast_mutex_lock(&list_lock);
  362. if (!added_cli) {
  363. ast_cli_register(&show_trans);
  364. added_cli++;
  365. }
  366. t->next = list;
  367. list = t;
  368. rebuild_matrix(0);
  369. ast_mutex_unlock(&list_lock);
  370. return 0;
  371. }
  372. /*! \brief unregister codec translator */
  373. int ast_unregister_translator(struct ast_translator *t)
  374. {
  375. char tmp[80];
  376. struct ast_translator *u, *ul = NULL;
  377. ast_mutex_lock(&list_lock);
  378. u = list;
  379. while(u) {
  380. if (u == t) {
  381. if (ul)
  382. ul->next = u->next;
  383. else
  384. list = u->next;
  385. if (option_verbose > 1)
  386. ast_verbose(VERBOSE_PREFIX_2 "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt));
  387. break;
  388. }
  389. ul = u;
  390. u = u->next;
  391. }
  392. rebuild_matrix(0);
  393. ast_mutex_unlock(&list_lock);
  394. return (u ? 0 : -1);
  395. }
  396. /*! \brief Calculate our best translator source format, given costs, and a desired destination */
  397. int ast_translator_best_choice(int *dst, int *srcs)
  398. {
  399. int x,y;
  400. int best = -1;
  401. int bestdst = 0;
  402. int cur = 1;
  403. int besttime = INT_MAX;
  404. int beststeps = INT_MAX;
  405. int common;
  406. if ((common = (*dst) & (*srcs))) {
  407. /* We have a format in common */
  408. for (y = 0; y < MAX_FORMAT; y++) {
  409. if (cur & common) {
  410. /* This is a common format to both. Pick it if we don't have one already */
  411. bestdst = cur;
  412. best = cur;
  413. }
  414. cur = cur << 1;
  415. }
  416. } else {
  417. /* We will need to translate */
  418. ast_mutex_lock(&list_lock);
  419. for (y = 0; y < MAX_FORMAT; y++) {
  420. if (!(cur & *dst)) {
  421. cur = cur << 1;
  422. continue;
  423. }
  424. for (x = 0; x < MAX_FORMAT; x++) {
  425. if ((*srcs & (1 << x)) && /* x is a valid source format */
  426. tr_matrix[x][y].step) { /* There's a step */
  427. if (tr_matrix[x][y].cost > besttime)
  428. continue; /* It's more expensive, skip it */
  429. if (tr_matrix[x][y].cost == besttime &&
  430. tr_matrix[x][y].multistep >= beststeps)
  431. continue; /* It requires the same (or more) steps,
  432. skip it */
  433. /* It's better than what we have so far */
  434. best = 1 << x;
  435. bestdst = cur;
  436. besttime = tr_matrix[x][y].cost;
  437. beststeps = tr_matrix[x][y].multistep;
  438. }
  439. }
  440. cur = cur << 1;
  441. }
  442. ast_mutex_unlock(&list_lock);
  443. }
  444. if (best > -1) {
  445. *srcs = best;
  446. *dst = bestdst;
  447. best = 0;
  448. }
  449. return best;
  450. }