fixedjitterbuf.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /*
  2. * Copyright (C) 2005, Attractel OOD
  3. *
  4. * Contributors:
  5. * Slav Klenov <slav@securax.org>
  6. *
  7. * See http://www.asterisk.org for more information about
  8. * the Asterisk project. Please do not directly contact
  9. * any of the maintainers of this project for assistance;
  10. * the project provides a web site, mailing lists and IRC
  11. * channels for your use.
  12. *
  13. * This program is free software, distributed under the terms of
  14. * the GNU General Public License Version 2. See the LICENSE file
  15. * at the top of the source tree.
  16. *
  17. * A license has been granted to Digium (via disclaimer) for the use of
  18. * this code.
  19. */
  20. /*! \file
  21. *
  22. * \brief Jitterbuffering algorithm.
  23. *
  24. * \author Slav Klenov <slav@securax.org>
  25. */
  26. /*** MODULEINFO
  27. <support_level>core</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  31. #include <assert.h>
  32. #include "asterisk/utils.h"
  33. #include "fixedjitterbuf.h"
  34. #undef FIXED_JB_DEBUG
  35. #ifdef FIXED_JB_DEBUG
  36. #define ASSERT(a)
  37. #else
  38. #define ASSERT(a) assert(a)
  39. #endif
  40. /*! \brief private fixed_jb structure */
  41. struct fixed_jb
  42. {
  43. struct fixed_jb_frame *frames;
  44. struct fixed_jb_frame *tail;
  45. struct fixed_jb_conf conf;
  46. long rxcore;
  47. long delay;
  48. long next_delivery;
  49. int force_resynch;
  50. };
  51. static struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb);
  52. static void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame);
  53. static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame);
  54. static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now);
  55. static inline struct fixed_jb_frame *alloc_jb_frame(struct fixed_jb *jb)
  56. {
  57. return ast_calloc(1, sizeof(*jb));
  58. }
  59. static inline void release_jb_frame(struct fixed_jb *jb, struct fixed_jb_frame *frame)
  60. {
  61. ast_free(frame);
  62. }
  63. static void get_jb_head(struct fixed_jb *jb, struct fixed_jb_frame *frame)
  64. {
  65. struct fixed_jb_frame *fr;
  66. /* unlink the frame */
  67. fr = jb->frames;
  68. jb->frames = fr->next;
  69. if (jb->frames) {
  70. jb->frames->prev = NULL;
  71. } else {
  72. /* the jb is empty - update tail */
  73. jb->tail = NULL;
  74. }
  75. /* update next */
  76. jb->next_delivery = fr->delivery + fr->ms;
  77. /* copy the destination */
  78. memcpy(frame, fr, sizeof(struct fixed_jb_frame));
  79. /* and release the frame */
  80. release_jb_frame(jb, fr);
  81. }
  82. struct fixed_jb *fixed_jb_new(struct fixed_jb_conf *conf)
  83. {
  84. struct fixed_jb *jb;
  85. if (!(jb = ast_calloc(1, sizeof(*jb))))
  86. return NULL;
  87. /* First copy our config */
  88. memcpy(&jb->conf, conf, sizeof(struct fixed_jb_conf));
  89. /* we don't need the passed config anymore - continue working with the saved one */
  90. conf = &jb->conf;
  91. /* validate the configuration */
  92. if (conf->jbsize < 1)
  93. conf->jbsize = FIXED_JB_SIZE_DEFAULT;
  94. if (conf->resync_threshold < 1)
  95. conf->resync_threshold = FIXED_JB_RESYNCH_THRESHOLD_DEFAULT;
  96. /* Set the constant delay to the jitterbuf */
  97. jb->delay = conf->jbsize;
  98. return jb;
  99. }
  100. void fixed_jb_destroy(struct fixed_jb *jb)
  101. {
  102. /* jitterbuf MUST be empty before it can be destroyed */
  103. ASSERT(jb->frames == NULL);
  104. ast_free(jb);
  105. }
  106. static int resynch_jb(struct fixed_jb *jb, void *data, long ms, long ts, long now)
  107. {
  108. long diff, offset;
  109. struct fixed_jb_frame *frame;
  110. /* If jb is empty, just reinitialize the jb */
  111. if (!jb->frames) {
  112. /* debug check: tail should also be NULL */
  113. ASSERT(jb->tail == NULL);
  114. return fixed_jb_put_first(jb, data, ms, ts, now);
  115. }
  116. /* Adjust all jb state just as the new frame is with delivery = the delivery of the last
  117. frame (e.g. this one with max delivery) + the length of the last frame. */
  118. /* Get the diff in timestamps */
  119. diff = ts - jb->tail->ts;
  120. /* Ideally this should be just the length of the last frame. The deviation is the desired
  121. offset */
  122. offset = diff - jb->tail->ms;
  123. /* Do we really need to resynch, or this is just a frame for dropping? */
  124. if (!jb->force_resynch && (offset < jb->conf.resync_threshold && offset > -jb->conf.resync_threshold))
  125. return FIXED_JB_DROP;
  126. /* Reset the force resynch flag */
  127. jb->force_resynch = 0;
  128. /* apply the offset to the jb state */
  129. jb->rxcore -= offset;
  130. frame = jb->frames;
  131. while (frame) {
  132. frame->ts += offset;
  133. frame = frame->next;
  134. }
  135. /* now jb_put() should add the frame at a last position */
  136. return fixed_jb_put(jb, data, ms, ts, now);
  137. }
  138. void fixed_jb_set_force_resynch(struct fixed_jb *jb)
  139. {
  140. jb->force_resynch = 1;
  141. }
  142. int fixed_jb_put_first(struct fixed_jb *jb, void *data, long ms, long ts, long now)
  143. {
  144. /* this is our first frame - set the base of the receivers time */
  145. jb->rxcore = now - ts;
  146. /* init next for a first time - it should be the time the first frame should be played */
  147. jb->next_delivery = now + jb->delay;
  148. /* put the frame */
  149. return fixed_jb_put(jb, data, ms, ts, now);
  150. }
  151. int fixed_jb_put(struct fixed_jb *jb, void *data, long ms, long ts, long now)
  152. {
  153. struct fixed_jb_frame *frame, *next, *newframe;
  154. long delivery;
  155. /* debug check the validity of the input params */
  156. ASSERT(data != NULL);
  157. /* do not allow frames shorter than 2 ms */
  158. ASSERT(ms >= 2);
  159. ASSERT(ts >= 0);
  160. ASSERT(now >= 0);
  161. delivery = jb->rxcore + jb->delay + ts;
  162. /* check if the new frame is not too late */
  163. if (delivery < jb->next_delivery) {
  164. /* should drop the frame, but let first resynch_jb() check if this is not a jump in ts, or
  165. the force resynch flag was not set. */
  166. return resynch_jb(jb, data, ms, ts, now);
  167. }
  168. /* what if the delivery time is bigger than next + delay? Seems like a frame for the future.
  169. However, allow more resync_threshold ms in advance */
  170. if (delivery > jb->next_delivery + jb->delay + jb->conf.resync_threshold) {
  171. /* should drop the frame, but let first resynch_jb() check if this is not a jump in ts, or
  172. the force resynch flag was not set. */
  173. return resynch_jb(jb, data, ms, ts, now);
  174. }
  175. /* find the right place in the frames list, sorted by delivery time */
  176. frame = jb->tail;
  177. while (frame && frame->delivery > delivery) {
  178. frame = frame->prev;
  179. }
  180. /* Check if the new delivery time is not covered already by the chosen frame */
  181. if (frame && (frame->delivery == delivery ||
  182. delivery < frame->delivery + frame->ms ||
  183. (frame->next && delivery + ms > frame->next->delivery)))
  184. {
  185. /* TODO: Should we check for resynch here? Be careful to do not allow threshold smaller than
  186. the size of the jb */
  187. /* should drop the frame, but let first resynch_jb() check if this is not a jump in ts, or
  188. the force resynch flag was not set. */
  189. return resynch_jb(jb, data, ms, ts, now);
  190. }
  191. /* Reset the force resynch flag */
  192. jb->force_resynch = 0;
  193. /* Get a new frame */
  194. newframe = alloc_jb_frame(jb);
  195. newframe->data = data;
  196. newframe->ts = ts;
  197. newframe->ms = ms;
  198. newframe->delivery = delivery;
  199. /* and insert it right on place */
  200. if (frame) {
  201. next = frame->next;
  202. frame->next = newframe;
  203. if (next) {
  204. newframe->next = next;
  205. next->prev = newframe;
  206. } else {
  207. /* insert after the last frame - should update tail */
  208. jb->tail = newframe;
  209. newframe->next = NULL;
  210. }
  211. newframe->prev = frame;
  212. return FIXED_JB_OK;
  213. } else if (!jb->frames) {
  214. /* the frame list is empty or thats just the first frame ever */
  215. /* tail should also be NULL is that case */
  216. ASSERT(jb->tail == NULL);
  217. jb->frames = jb->tail = newframe;
  218. newframe->next = NULL;
  219. newframe->prev = NULL;
  220. return FIXED_JB_OK;
  221. } else {
  222. /* insert on a first position - should update frames head */
  223. newframe->next = jb->frames;
  224. newframe->prev = NULL;
  225. jb->frames->prev = newframe;
  226. jb->frames = newframe;
  227. return FIXED_JB_OK;
  228. }
  229. }
  230. int fixed_jb_get(struct fixed_jb *jb, struct fixed_jb_frame *frame, long now, long interpl)
  231. {
  232. ASSERT(now >= 0);
  233. ASSERT(interpl >= 2);
  234. if (now < jb->next_delivery) {
  235. /* too early for the next frame */
  236. return FIXED_JB_NOFRAME;
  237. }
  238. /* Is the jb empty? */
  239. if (!jb->frames) {
  240. /* should interpolate a frame */
  241. /* update next */
  242. jb->next_delivery += interpl;
  243. return FIXED_JB_INTERP;
  244. }
  245. /* Isn't it too late for the first frame available in the jb? */
  246. if (now > jb->frames->delivery + jb->frames->ms) {
  247. /* yes - should drop this frame and update next to point the next frame (get_jb_head() does it) */
  248. get_jb_head(jb, frame);
  249. return FIXED_JB_DROP;
  250. }
  251. /* isn't it too early to play the first frame available? */
  252. if (now < jb->frames->delivery) {
  253. /* yes - should interpolate one frame */
  254. /* update next */
  255. jb->next_delivery += interpl;
  256. return FIXED_JB_INTERP;
  257. }
  258. /* we have a frame for playing now (get_jb_head() updates next) */
  259. get_jb_head(jb, frame);
  260. return FIXED_JB_OK;
  261. }
  262. long fixed_jb_next(struct fixed_jb *jb)
  263. {
  264. return jb->next_delivery;
  265. }
  266. int fixed_jb_remove(struct fixed_jb *jb, struct fixed_jb_frame *frameout)
  267. {
  268. if (!jb->frames)
  269. return FIXED_JB_NOFRAME;
  270. get_jb_head(jb, frameout);
  271. return FIXED_JB_OK;
  272. }
  273. int fixed_jb_is_late(struct fixed_jb *jb, long ts)
  274. {
  275. return jb->rxcore + jb->delay + ts < jb->next_delivery;
  276. }