translate.c 14 KB

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