rtpenc_amr.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * RTP packetization for AMR audio
  3. * Copyright (c) 2007 Luca Abeni
  4. * Copyright (c) 2009 Martin Storsjo
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include "avformat.h"
  23. #include "rtpenc.h"
  24. /**
  25. * Packetize AMR frames into RTP packets according to RFC 3267,
  26. * in octet-aligned mode.
  27. */
  28. void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size)
  29. {
  30. RTPMuxContext *s = s1->priv_data;
  31. int max_header_toc_size = 1 + s->max_frames_per_packet;
  32. uint8_t *p;
  33. int len;
  34. /* Test if the packet must be sent. */
  35. len = s->buf_ptr - s->buf;
  36. if (s->num_frames == s->max_frames_per_packet || (len && len + size - 1 > s->max_payload_size)) {
  37. int header_size = s->num_frames + 1;
  38. p = s->buf + max_header_toc_size - header_size;
  39. if (p != s->buf)
  40. memmove(p, s->buf, header_size);
  41. ff_rtp_send_data(s1, p, s->buf_ptr - p, 1);
  42. s->num_frames = 0;
  43. }
  44. if (!s->num_frames) {
  45. s->buf[0] = 0xf0;
  46. s->buf_ptr = s->buf + max_header_toc_size;
  47. s->timestamp = s->cur_timestamp;
  48. } else {
  49. /* Mark the previous TOC entry as having more entries following. */
  50. s->buf[1 + s->num_frames - 1] |= 0x80;
  51. }
  52. /* Copy the frame type and quality bits. */
  53. s->buf[1 + s->num_frames++] = buff[0] & 0x7C;
  54. buff++;
  55. size--;
  56. memcpy(s->buf_ptr, buff, size);
  57. s->buf_ptr += size;
  58. }