您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

129 行
3.4KB

  1. // RFC3550 6.5 SDES: Source Description RTCP Packet
  2. #include "rtp-internal.h"
  3. #include "rtp-util.h"
  4. void rtcp_sdes_unpack(struct rtp_context *ctx, const rtcp_header_t *header, const uint8_t* ptr, size_t bytes)
  5. {
  6. uint32_t i;
  7. struct rtcp_msg_t msg;
  8. struct rtp_member *member;
  9. const unsigned char *p, *end;
  10. p = ptr;
  11. end = ptr + bytes;
  12. assert(header->length >= header->rc);
  13. for (i = 0; i < header->rc && p + 8 /*4-ssrc + 1-PT*/ <= end; i++)
  14. {
  15. msg.ssrc = nbo_r32(p);
  16. member = rtp_member_fetch(ctx, msg.ssrc);
  17. if (!member) {
  18. //continue;
  19. }
  20. p += 4;
  21. while(p + 2 <= end && RTCP_SDES_END != p[0] /*PT*/)
  22. {
  23. msg.u.sdes.pt = p[0];
  24. msg.u.sdes.len = p[1];
  25. msg.u.sdes.data = (unsigned char*)(p+2);
  26. if (p + 2 + msg.u.sdes.len > end)
  27. {
  28. assert(0);
  29. return; // error
  30. }
  31. ctx->handler.on_rtcp(ctx->cbparam, &msg);
  32. switch(msg.u.sdes.pt)
  33. {
  34. case RTCP_SDES_CNAME:
  35. case RTCP_SDES_NAME:
  36. case RTCP_SDES_EMAIL:
  37. case RTCP_SDES_PHONE:
  38. case RTCP_SDES_LOC:
  39. case RTCP_SDES_TOOL:
  40. case RTCP_SDES_NOTE:
  41. rtp_member_setvalue(member, msg.u.sdes.pt, msg.u.sdes.data, msg.u.sdes.len);
  42. break;
  43. case RTCP_SDES_PRIVATE:
  44. //assert(0);
  45. break;
  46. default:
  47. //assert(0);
  48. break;
  49. }
  50. // RFC3550 6.5 SDES: Source Description RTCP Packet
  51. // Items are contiguous, i.e., items are not individually padded to a 32-bit boundary.
  52. // Text is not null terminated because some multi-octet encodings include null octets.
  53. p += 2 + msg.u.sdes.len;
  54. }
  55. // RFC3550 6.5 SDES: Source Description RTCP Packet
  56. // The list of items in each chunk must be terminated by one or more null octets,
  57. // the first of which is interpreted as an item type of zero to denote the end of the list.
  58. // No length octet follows the null item type octet,
  59. // but additional null octets must be included if needed to pad until the next 32-bit boundary.
  60. // offset sizeof(SSRC) + sizeof(chunk type) + sizeof(chunk length)
  61. p = (const unsigned char *)((p - (const unsigned char *)0 + 3) / 4 * 4);
  62. }
  63. }
  64. static size_t rtcp_sdes_append_item(unsigned char *ptr, size_t bytes, rtcp_sdes_item_t *sdes)
  65. {
  66. assert(sdes->data);
  67. if(bytes >= (size_t)sdes->len+2)
  68. {
  69. ptr[0] = sdes->pt;
  70. ptr[1] = sdes->len;
  71. memcpy(ptr+2,sdes->data, sdes->len);
  72. }
  73. return sdes->len+2;
  74. }
  75. int rtcp_sdes_pack(struct rtp_context *ctx, uint8_t* ptr, int bytes)
  76. {
  77. int n;
  78. rtcp_header_t header;
  79. // must have CNAME
  80. if(!ctx->self->sdes[RTCP_SDES_CNAME].data)
  81. return 0;
  82. header.v = 2;
  83. header.p = 0;
  84. header.pt = RTCP_SDES;
  85. header.rc = 1; // self only
  86. header.length = 0;
  87. n = (int)rtcp_sdes_append_item(ptr+8, bytes-8, &ctx->self->sdes[RTCP_SDES_CNAME]);
  88. if(bytes < 8 + n)
  89. return 8 + n;
  90. // RFC3550 6.3.9 Allocation of Source Description Bandwidth (p29)
  91. // Every third interval (15 seconds), one extra item would be included in the SDES packet
  92. if(0 == ctx->rtcp_cycle % 3 && ctx->rtcp_cycle/3 > 0) // skip CNAME
  93. {
  94. assert(ctx->rtcp_cycle/3 < RTCP_SDES_PRIVATE);
  95. if(ctx->self->sdes[ctx->rtcp_cycle/3+1].data) // skip RTCP_SDES_END
  96. {
  97. n += (int)rtcp_sdes_append_item(ptr+8+n, bytes-n-8, &ctx->self->sdes[ctx->rtcp_cycle/3+1]);
  98. if(n + 8 > bytes)
  99. return n + 8;
  100. }
  101. }
  102. ctx->rtcp_cycle = (ctx->rtcp_cycle+1) % 24; // 3 * SDES item number
  103. header.length = (uint16_t)((n+4+3)/4); // see 6.4.1 SR: Sender Report RTCP Packet
  104. nbo_write_rtcp_header(ptr, &header);
  105. nbo_w32(ptr+4, ctx->self->ssrc);
  106. return (header.length+1)*4;
  107. }