rtpenc_h263.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * RTP packetization for H.263 video
  3. * Copyright (c) 2009 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. static const uint8_t *find_resync_marker_reverse(const uint8_t *restrict start,
  25. const uint8_t *restrict end)
  26. {
  27. const uint8_t *p = end - 1;
  28. start += 1; /* Make sure we never return the original start. */
  29. for (; p > start; p -= 2) {
  30. if (!*p) {
  31. if (!p[ 1] && p[2]) return p;
  32. else if (!p[-1] && p[1]) return p - 1;
  33. }
  34. }
  35. return end;
  36. }
  37. /**
  38. * Packetize H.263 frames into RTP packets according to RFC 4629
  39. */
  40. void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size)
  41. {
  42. RTPMuxContext *s = s1->priv_data;
  43. int len, max_packet_size;
  44. uint8_t *q;
  45. max_packet_size = s->max_payload_size;
  46. while (size > 0) {
  47. q = s->buf;
  48. if (size >= 2 && (buf1[0] == 0) && (buf1[1] == 0)) {
  49. *q++ = 0x04;
  50. buf1 += 2;
  51. size -= 2;
  52. } else {
  53. *q++ = 0;
  54. }
  55. *q++ = 0;
  56. len = FFMIN(max_packet_size - 2, size);
  57. /* Look for a better place to split the frame into packets. */
  58. if (len < size) {
  59. const uint8_t *end = find_resync_marker_reverse(buf1, buf1 + len);
  60. len = end - buf1;
  61. }
  62. memcpy(q, buf1, len);
  63. q += len;
  64. /* 90 KHz time stamp */
  65. s->timestamp = s->cur_timestamp;
  66. ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size));
  67. buf1 += len;
  68. size -= len;
  69. }
  70. }