Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

852 linhas
26KB

  1. #include "rtp-internal.h"
  2. #include "rtp-util.h"
  3. #include <errno.h>
  4. static int rtcp_psfb_pli_pack(uint8_t* ptr, uint32_t bytes);
  5. static int rtcp_psfb_sli_pack(const rtcp_sli_t* sli, int count, uint8_t* ptr, uint32_t bytes);
  6. static int rtcp_psfb_rpsi_pack(uint8_t pt, const uint8_t* payload, uint32_t bits, uint8_t* ptr, uint32_t bytes);
  7. static int rtcp_psfb_fir_pack(const rtcp_fir_t* fir, int count, uint8_t* ptr, uint32_t bytes);
  8. static int rtcp_psfb_tstr_pack(const rtcp_fir_t* fir, int count, uint8_t* ptr, uint32_t bytes);
  9. static int rtcp_psfb_tstn_pack(const rtcp_fir_t* fir, int count, uint8_t* ptr, uint32_t bytes);
  10. static int rtcp_psfb_vbcm_pack(const rtcp_vbcm_t* vbcm, uint8_t* ptr, uint32_t bytes);
  11. static int rtcp_psfb_pslei_pack(const uint32_t* ssrc, int count, uint8_t* ptr, uint32_t bytes);
  12. static int rtcp_psfb_lrr_pack(const rtcp_lrr_t* lrr, int count, uint8_t* ptr, uint32_t bytes);
  13. static int rtcp_psfb_remb_pack(const rtcp_remb_t* remb, int count, uint8_t* ptr, uint32_t bytes);
  14. static int rtcp_psfb_pli_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  15. static int rtcp_psfb_sli_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  16. static int rtcp_psfb_rpsi_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  17. static int rtcp_psfb_fir_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  18. static int rtcp_psfb_tstr_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  19. static int rtcp_psfb_tstn_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  20. static int rtcp_psfb_vbcm_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  21. static int rtcp_psfb_pslei_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  22. static int rtcp_psfb_lrr_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  23. static int rtcp_psfb_roi_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  24. static int rtcp_psfb_afb_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  25. // https://datatracker.ietf.org/doc/html/rfc4585#section-6.3.1
  26. static int rtcp_psfb_pli_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  27. {
  28. // 1. There MUST be exactly one PLI contained in the FCI field.
  29. // 2. PLI does not require parameters. Therefore, the length field MUST be 2, and there MUST NOT be any Feedback Control Information.
  30. assert(0 == bytes);
  31. ctx->handler.on_rtcp(ctx->cbparam, msg);
  32. (void)ctx, (void)header, (void)ptr;
  33. return 0;
  34. }
  35. static int rtcp_psfb_pli_pack(uint8_t* ptr, uint32_t bytes)
  36. {
  37. (void)ptr, (void)bytes;
  38. return 0;
  39. }
  40. // https://datatracker.ietf.org/doc/html/rfc4585#section-6.3.2
  41. /*
  42. 0 1 2 3
  43. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  44. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  45. | First | Number | PictureID |
  46. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  47. */
  48. static int rtcp_psfb_sli_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  49. {
  50. size_t i;
  51. rtcp_sli_t* sli, sli0[32];
  52. if (bytes / 4 > sizeof(sli0) / sizeof(sli0[0]))
  53. {
  54. sli = calloc(bytes / 4, sizeof(*sli));
  55. if (!sli) return -ENOMEM;
  56. }
  57. else
  58. {
  59. sli = sli0;
  60. memset(sli, 0, sizeof(sli[0]) * (bytes / 4));
  61. }
  62. for (i = 0; i < bytes / 4; i++)
  63. {
  64. sli[i].first = (ptr[0] << 5) | (ptr[1] >> 3);
  65. sli[i].number = ((ptr[1] & 0x07) << 10) | (ptr[2] << 2) | (ptr[3] >> 6);
  66. sli[i].picture_id = ptr[3] & 0x3F;
  67. ptr += 4;
  68. }
  69. msg->u.psfb.u.sli.sli = sli;
  70. msg->u.psfb.u.sli.count = (int)i;
  71. ctx->handler.on_rtcp(ctx->cbparam, msg);
  72. (void)ctx, (void)header;
  73. if (sli && sli != sli0)
  74. free(sli);
  75. return 0;
  76. }
  77. static int rtcp_psfb_sli_pack(const rtcp_sli_t* sli, int count, uint8_t* ptr, uint32_t bytes)
  78. {
  79. int i;
  80. for (i = 0; i < count && bytes >= 4; i++)
  81. {
  82. nbo_w32(ptr, ((sli->first & 0x1FFFF) << 19) | ((sli->number & 0x1FFFF) << 6) | (sli->picture_id & 0x3F));
  83. bytes -= 4;
  84. ptr += 4;
  85. }
  86. return i * 4;
  87. }
  88. // https://datatracker.ietf.org/doc/html/rfc4585#section-6.3.3
  89. /*
  90. 0 1 2 3
  91. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  92. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  93. | PB |0| Payload Type| Native RPSI bit string |
  94. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  95. | defined per codec ... | Padding (0) |
  96. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  97. */
  98. static int rtcp_psfb_rpsi_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  99. {
  100. uint8_t pb;
  101. uint8_t pt;
  102. if (bytes < 4)
  103. return -1;
  104. pb = ptr[0];
  105. pt = ptr[1] & 0x7F;
  106. msg->u.psfb.u.rpsi.pt = pt;
  107. msg->u.psfb.u.rpsi.len = (uint32_t)bytes * 8 - pb;
  108. msg->u.psfb.u.rpsi.payload = (uint8_t*)ptr + 2;
  109. ctx->handler.on_rtcp(ctx->cbparam, msg);
  110. (void)ctx, (void)header;
  111. return 0;
  112. }
  113. static int rtcp_psfb_rpsi_pack(uint8_t pt, const uint8_t* payload, uint32_t bits, uint8_t* ptr, uint32_t bytes)
  114. {
  115. uint32_t len;
  116. len = (bits + 7) / 8;
  117. if (bytes < (2 + len + 3) / 4 * 4)
  118. return -1;
  119. ptr[0] = (uint8_t)((2 + len + 3) / 4 * 4 * 8 - (2 * 8 + bits));
  120. ptr[1] = pt;
  121. memcpy(ptr + 2, payload, len);
  122. return (2 + len + 3) / 4 * 4;
  123. }
  124. // https://www.rfc-editor.org/rfc/rfc5104.html#section-4.3.1
  125. /*
  126. 0 1 2 3
  127. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  128. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  129. | SSRC |
  130. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  131. | Seq nr. | Reserved |
  132. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  133. */
  134. static int rtcp_psfb_fir_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  135. {
  136. size_t i;
  137. rtcp_fir_t *fir, fir0[32];
  138. if (bytes / 8 > sizeof(fir0) / sizeof(fir0[0]))
  139. {
  140. fir = calloc(bytes / 8, sizeof(*fir));
  141. if (!fir) return -ENOMEM;
  142. }
  143. else
  144. {
  145. fir = fir0;
  146. memset(fir, 0, sizeof(fir[0]) * (bytes / 8));
  147. }
  148. for (i = 0; i < bytes / 8; i++)
  149. {
  150. fir[i].ssrc = nbo_r32(ptr);
  151. fir[i].sn = ptr[4];
  152. ptr += 8;
  153. }
  154. msg->u.psfb.u.fir.fir = fir;
  155. msg->u.psfb.u.fir.count = (int)i;
  156. ctx->handler.on_rtcp(ctx->cbparam, msg);
  157. (void)ctx, (void)header;
  158. if (fir && fir != fir0)
  159. free(fir);
  160. return 0;
  161. }
  162. static int rtcp_psfb_fir_pack(const rtcp_fir_t* fir, int count, uint8_t* ptr, uint32_t bytes)
  163. {
  164. int i;
  165. for (i = 0; i < count && bytes >= 8; i++)
  166. {
  167. nbo_w32(ptr, fir[i].ssrc);
  168. nbo_w32(ptr + 4, fir[i].sn << 24);
  169. bytes -= 8;
  170. ptr += 8;
  171. }
  172. return i * 8;
  173. }
  174. // https://www.rfc-editor.org/rfc/rfc5104.html#section-4.3.2
  175. /*
  176. 0 1 2 3
  177. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  178. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  179. | SSRC |
  180. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  181. | Seq nr. | Reserved | Index |
  182. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  183. */
  184. static int rtcp_psfb_tstr_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  185. {
  186. size_t i;
  187. rtcp_fir_t* fir, fir0[32];
  188. if (bytes / 8 > sizeof(fir0) / sizeof(fir0[0]))
  189. {
  190. fir = calloc(bytes / 8, sizeof(*fir));
  191. if (!fir) return -ENOMEM;
  192. }
  193. else
  194. {
  195. fir = fir0;
  196. memset(fir, 0, sizeof(fir[0]) * (bytes / 8));
  197. }
  198. for (i = 0; i < bytes / 8; i++)
  199. {
  200. fir[i].ssrc = nbo_r32(ptr);
  201. fir[i].sn = ptr[4];
  202. fir[i].index = ptr[7] & 0x1F;
  203. ptr += 8;
  204. }
  205. msg->u.psfb.u.fir.fir = fir;
  206. msg->u.psfb.u.fir.count = (int)i;
  207. ctx->handler.on_rtcp(ctx->cbparam, msg);
  208. (void)ctx, (void)header;
  209. if (fir && fir != fir0)
  210. free(fir);
  211. return 0;
  212. }
  213. static int rtcp_psfb_tstr_pack(const rtcp_fir_t* fir, int count, uint8_t* ptr, uint32_t bytes)
  214. {
  215. int i;
  216. for (i = 0; i < count && bytes >= 8; i++)
  217. {
  218. nbo_w32(ptr, fir[i].ssrc);
  219. nbo_w32(ptr + 4, (fir[i].sn << 24) | fir[i].index);
  220. bytes -= 8;
  221. ptr += 8;
  222. }
  223. return i * 8;
  224. }
  225. // https://www.rfc-editor.org/rfc/rfc5104.html#section-4.3.3
  226. /*
  227. 0 1 2 3
  228. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  229. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  230. | SSRC |
  231. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  232. | Seq nr. | Reserved | Index |
  233. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  234. */
  235. static int rtcp_psfb_tstn_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  236. {
  237. size_t i;
  238. rtcp_fir_t* fir, fir0[32];
  239. if (bytes / 8 > sizeof(fir0) / sizeof(fir0[0]))
  240. {
  241. fir = calloc(bytes / 8, sizeof(*fir));
  242. if (!fir) return -ENOMEM;
  243. }
  244. else
  245. {
  246. fir = fir0;
  247. memset(fir, 0, sizeof(fir[0]) * (bytes / 8));
  248. }
  249. for (i = 0; i < bytes / 8; i++)
  250. {
  251. fir[i].ssrc = nbo_r32(ptr);
  252. fir[i].sn = ptr[4];
  253. fir[i].index = ptr[7] & 0x1F;
  254. ptr += 8;
  255. }
  256. msg->u.psfb.u.fir.fir = fir;
  257. msg->u.psfb.u.fir.count = (int)i;
  258. ctx->handler.on_rtcp(ctx->cbparam, msg);
  259. (void)ctx, (void)header;
  260. if (fir && fir != fir0)
  261. free(fir);
  262. return 0;
  263. }
  264. static int rtcp_psfb_tstn_pack(const rtcp_fir_t* fir, int count, uint8_t* ptr, uint32_t bytes)
  265. {
  266. return rtcp_psfb_tstr_pack(fir, count, ptr, bytes);
  267. }
  268. // https://www.rfc-editor.org/rfc/rfc5104.html#section-4.3.4
  269. /*
  270. 0 1 2 3
  271. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  272. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  273. | SSRC |
  274. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  275. | Seq nr. |0| Payload Type| Length |
  276. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  277. | VBCM Octet String.... | Padding |
  278. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  279. */
  280. static int rtcp_psfb_vbcm_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  281. {
  282. rtcp_vbcm_t vbcm;
  283. while(bytes > 8)
  284. {
  285. vbcm.ssrc = nbo_r32(ptr);
  286. vbcm.sn = ptr[4];
  287. vbcm.pt = ptr[5] & 0x7F;
  288. vbcm.len = nbo_r16(ptr + 6);
  289. if (vbcm.len + 8 > bytes)
  290. return -1;
  291. vbcm.payload = (uint8_t*)ptr + 8;
  292. bytes -= 8 + (vbcm.len + 3) / 4 * 4;
  293. ptr += 8 + (vbcm.len + 3) / 4 * 4;
  294. memcpy(&msg->u.psfb.u.vbcm, &vbcm, sizeof(vbcm));
  295. ctx->handler.on_rtcp(ctx->cbparam, msg);
  296. }
  297. (void)ctx, (void)header;
  298. return 0;
  299. }
  300. static int rtcp_psfb_vbcm_pack(const rtcp_vbcm_t* vbcm, uint8_t* ptr, uint32_t bytes)
  301. {
  302. if (bytes < 8 + (uint32_t)(vbcm->len + 3) / 4 * 4)
  303. return -1;
  304. nbo_w32(ptr, vbcm->ssrc);
  305. ptr[4] = (uint8_t)vbcm->sn;
  306. ptr[5] = (uint8_t)vbcm->pt;
  307. nbo_w16(ptr + 6, (uint16_t)vbcm->len);
  308. memcpy(ptr + 8, vbcm->payload, vbcm->len);
  309. return 8 + (vbcm->len + 3) / 4 * 4;
  310. }
  311. // https://www.rfc-editor.org/rfc/rfc6642.html#section-5.2
  312. /*
  313. 0 1 2 3
  314. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  315. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  316. | SSRC |
  317. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  318. */
  319. static int rtcp_psfb_pslei_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  320. {
  321. size_t i;
  322. uint32_t* v, v0[32];
  323. if (bytes / 4 > sizeof(v0) / sizeof(v0[0]))
  324. {
  325. v = calloc(bytes / 4, sizeof(*v));
  326. if (!v) return -ENOMEM;
  327. }
  328. else
  329. {
  330. v = v0;
  331. memset(v, 0, sizeof(v[0]) * (bytes / 4));
  332. }
  333. for (i = 0; i < bytes / 4; i++)
  334. {
  335. v[i] = nbo_r32(ptr);
  336. ptr += 4;
  337. }
  338. msg->u.psfb.u.pslei.ssrc = v;
  339. msg->u.psfb.u.pslei.count = (int)i;
  340. ctx->handler.on_rtcp(ctx->cbparam, msg);
  341. (void)ctx, (void)header;
  342. if (v && v != v0)
  343. free(v);
  344. return 0;
  345. }
  346. static int rtcp_psfb_pslei_pack(const uint32_t* ssrc, int count, uint8_t* ptr, uint32_t bytes)
  347. {
  348. int i;
  349. for (i = 0; i < count && bytes >= 4; i++)
  350. {
  351. nbo_w32(ptr, ssrc[i]);
  352. bytes -= 4;
  353. ptr += 4;
  354. }
  355. return i * 4;
  356. }
  357. // https://datatracker.ietf.org/doc/html/draft-ietf-avtext-lrr-07#section-3.1
  358. /*
  359. 0 1 2 3
  360. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  361. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  362. | SSRC |
  363. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  364. | Seq nr. |C| Payload Type| Reserved |
  365. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  366. | RES | TTID| TLID | RES | CTID| CLID |
  367. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  368. */
  369. static int rtcp_psfb_lrr_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  370. {
  371. size_t i;
  372. rtcp_lrr_t* lrr, lrr0[32];
  373. if (bytes / 12 > sizeof(lrr0) / sizeof(lrr0[0]))
  374. {
  375. lrr = calloc(bytes / 12, sizeof(*lrr));
  376. if (!lrr) return -ENOMEM;
  377. }
  378. else
  379. {
  380. lrr = lrr0;
  381. memset(lrr, 0, sizeof(lrr[0]) * (bytes / 12));
  382. }
  383. for (i = 0; i < bytes / 12; i++)
  384. {
  385. lrr[i].ssrc = nbo_r32(ptr);
  386. lrr[i].sn = ptr[4];
  387. lrr[i].c = (ptr[5] >> 7) & 0x01;
  388. lrr[i].payload = ptr[5] & 0x7F;
  389. lrr[i].ttid = ptr[8] & 0x07;
  390. lrr[i].tlid = ptr[9];
  391. lrr[i].ctid = ptr[10] & 0x07;
  392. lrr[i].clid = ptr[11];
  393. ptr += 12;
  394. }
  395. msg->u.psfb.u.lrr.lrr = lrr;
  396. msg->u.psfb.u.lrr.count = (int)i;
  397. ctx->handler.on_rtcp(ctx->cbparam, msg);
  398. (void)ctx, (void)header;
  399. if (lrr && lrr != lrr0)
  400. free(lrr);
  401. return 0;
  402. }
  403. static int rtcp_psfb_lrr_pack(const rtcp_lrr_t* lrr, int count, uint8_t* ptr, uint32_t bytes)
  404. {
  405. int i;
  406. for (i = 0; i < count && bytes >= 12; i++)
  407. {
  408. nbo_w32(ptr, lrr[i].ssrc);
  409. nbo_w32(ptr, (lrr[i].sn << 24) | ((lrr[i].c & 0x01) << 23) | ((lrr[i].payload & 0x7F) << 16));
  410. nbo_w32(ptr, ((lrr[i].ttid & 0x07) << 24) | ((lrr[i].tlid & 0xFF) << 16) | ((lrr[i].ctid & 0x07) << 8) | ((lrr[i].clid & 0xFF) << 0));
  411. bytes -= 12;
  412. ptr += 12;
  413. }
  414. return i * 12;
  415. }
  416. // https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1404
  417. // 7.3.7 Video Region-of-Interest (ROI) Signaling
  418. /*
  419. Arbitrary ROI
  420. 0 1 2 3
  421. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  422. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  423. | Position_X (h)| Position_X (l)| Position_Y (h)| Position_Y(l)|
  424. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  425. | Size_X (h) | Size_X (l) | Size_Y (h) | Size_Y(l) |
  426. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  427. Pre-defined ROI
  428. 0 1 2 3
  429. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  430. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  431. | all ones | ROI_ID |
  432. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  433. 0 1 2 3
  434. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  435. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  436. | ID | len=7 | Position_X (h)| Position_X (l)| Position_Y (h)|
  437. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  438. | Position_Y (l)| Size_X (h) | Size_X (l) | Size_Y (h) |
  439. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  440. | Size_Y (l) | zero padding |
  441. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  442. 0 1 2 3
  443. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  444. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  445. | ID | len=0 | ROI_ID | zero padding |
  446. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  447. */
  448. static int rtcp_psfb_roi_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  449. {
  450. (void)ctx, (void)header, (void)msg, (void)ptr, (void)bytes;
  451. return 0;
  452. }
  453. // https://datatracker.ietf.org/doc/html/rfc4585#section-6.4
  454. // https://datatracker.ietf.org/doc/html/draft-alvestrand-rmcat-remb-03#section-2.2
  455. /*
  456. 0 1 2 3
  457. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  458. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  459. |V=2|P| FMT=15 | PT=206 | length |
  460. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  461. | SSRC of packet sender |
  462. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  463. | SSRC of media source |
  464. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  465. | Unique identifier 'R' 'E' 'M' 'B' |
  466. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  467. | Num SSRC | BR Exp | BR Mantissa |
  468. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  469. | SSRC feedback |
  470. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  471. | ... |
  472. */
  473. static int rtcp_psfb_afb_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  474. {
  475. uint32_t i, n, exp, mantissa;
  476. rtcp_remb_t* remb, remb0[4];
  477. const uint8_t id[] = { 'R', 'E', 'M', 'B' };
  478. if (bytes >= 8 && 0 == memcmp(ptr, id, 4))
  479. {
  480. n = ptr[4];
  481. exp = (ptr[5] >> 2) & 0x3F;
  482. mantissa = ((ptr[5] & 0x3) << 16) | nbo_r16(ptr+6);
  483. ptr += 8;
  484. bytes -= 8;
  485. if (n * 4 > bytes)
  486. return -1;
  487. if (n > sizeof(remb0) / sizeof(remb0[0]))
  488. {
  489. remb = calloc(n, sizeof(*remb));
  490. if (!remb) return -ENOMEM;
  491. }
  492. else
  493. {
  494. remb = remb0;
  495. memset(remb, 0, sizeof(remb[0]) * n);
  496. }
  497. for (i = 0; i < n; i++)
  498. {
  499. remb[i].exp = exp;
  500. remb[i].mantissa = mantissa;
  501. remb[i].ssrc = nbo_r32(ptr);
  502. ptr += 4;
  503. }
  504. msg->u.psfb.u.afb.remb = remb;
  505. msg->u.psfb.u.afb.count = i;
  506. ctx->handler.on_rtcp(ctx->cbparam, msg);
  507. if (remb && remb != remb0)
  508. free(remb);
  509. return 0;
  510. }
  511. (void)ctx, (void)header;
  512. return 0;
  513. }
  514. static int rtcp_psfb_remb_pack(const rtcp_remb_t* remb, int count, uint8_t* ptr, uint32_t bytes)
  515. {
  516. int i;
  517. const uint8_t id[] = { 'R', 'E', 'M', 'B' };
  518. if (count < 1 || count > 255 || (int)bytes < 4 + 4 + count * 4)
  519. return -E2BIG;
  520. memcpy(ptr, id, sizeof(id));
  521. nbo_w32(ptr + 4, (count << 24) | (remb[0].exp << 18) | remb[0].mantissa);
  522. ptr += 8;
  523. for (i = 0; i < count; i++)
  524. {
  525. nbo_w32(ptr, remb[i].ssrc);
  526. ptr += 4;
  527. }
  528. return 4 + 4 + count * 4;
  529. }
  530. // https://datatracker.ietf.org/doc/html/rfc4585#section-6.3
  531. /*
  532. * Common Packet Format for Feedback Messages
  533. 0 1 2 3
  534. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  535. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  536. |V=2|P| FMT | PT | length |
  537. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  538. | SSRC of packet sender |
  539. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  540. | SSRC of media source |
  541. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  542. : Feedback Control Information (FCI) :
  543. : :
  544. */
  545. void rtcp_psfb_unpack(struct rtp_context* ctx, const rtcp_header_t* header, const uint8_t* ptr, size_t bytes)
  546. {
  547. int r;
  548. struct rtcp_msg_t msg;
  549. struct rtp_member* sender;
  550. if (bytes < 8 /*sizeof(rtcp_fci_t)*/)
  551. {
  552. assert(0);
  553. return;
  554. }
  555. msg.type = RTCP_PSFB | (header->rc << 8);
  556. msg.ssrc = nbo_r32(ptr);
  557. msg.u.psfb.media = nbo_r32(ptr + 4);
  558. sender = rtp_sender_fetch(ctx, msg.ssrc);
  559. if (!sender) return; // error
  560. assert(sender != ctx->self);
  561. r = 0;
  562. switch (header->rc)
  563. {
  564. case RTCP_PSFB_PLI:
  565. r = rtcp_psfb_pli_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  566. break;
  567. case RTCP_PSFB_SLI:
  568. r = rtcp_psfb_sli_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  569. break;
  570. case RTCP_PSFB_RPSI:
  571. r = rtcp_psfb_rpsi_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  572. break;
  573. case RTCP_PSFB_FIR:
  574. r = rtcp_psfb_fir_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  575. break;
  576. case RTCP_PSFB_TSTR:
  577. r = rtcp_psfb_tstr_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  578. break;
  579. case RTCP_PSFB_TSTN:
  580. r = rtcp_psfb_tstn_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  581. break;
  582. case RTCP_PSFB_VBCM:
  583. r = rtcp_psfb_vbcm_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  584. break;
  585. case RTCP_PSFB_PSLEI:
  586. r = rtcp_psfb_pslei_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  587. break;
  588. case RTCP_PSFB_ROI:
  589. r = rtcp_psfb_roi_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  590. break;
  591. case RTCP_PSFB_LRR:
  592. r = rtcp_psfb_lrr_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  593. break;
  594. case RTCP_PSFB_AFB:
  595. r = rtcp_psfb_afb_unpack(ctx, header, &msg, ptr + 8, bytes - 8);
  596. break;
  597. default:
  598. assert(0);
  599. r = 0; // ignore
  600. break;
  601. }
  602. return;
  603. }
  604. int rtcp_psfb_pack(struct rtp_context* ctx, uint8_t* data, int bytes, enum rtcp_psfb_type_t id, const rtcp_psfb_t* psfb)
  605. {
  606. int r;
  607. rtcp_header_t header;
  608. (void)ctx;
  609. if (bytes < 4 + 4 + 4)
  610. return 4 + 4 + 4;
  611. switch (id)
  612. {
  613. case RTCP_PSFB_PLI:
  614. r = rtcp_psfb_pli_pack(data + 12, bytes - 12);
  615. break;
  616. case RTCP_PSFB_SLI:
  617. r = rtcp_psfb_sli_pack(psfb->u.sli.sli, psfb->u.sli.count, data + 12, bytes - 12);
  618. break;
  619. case RTCP_PSFB_RPSI:
  620. r = rtcp_psfb_rpsi_pack(psfb->u.rpsi.pt, psfb->u.rpsi.payload, psfb->u.rpsi.len, data + 12, bytes - 12);
  621. break;
  622. case RTCP_PSFB_FIR:
  623. r = rtcp_psfb_fir_pack(psfb->u.fir.fir, psfb->u.fir.count, data + 12, bytes - 12);
  624. break;
  625. case RTCP_PSFB_TSTR:
  626. r = rtcp_psfb_tstr_pack(psfb->u.fir.fir, psfb->u.fir.count, data + 12, bytes - 12);
  627. break;
  628. case RTCP_PSFB_TSTN:
  629. r = rtcp_psfb_tstn_pack(psfb->u.fir.fir, psfb->u.fir.count, data + 12, bytes - 12);
  630. break;
  631. case RTCP_PSFB_VBCM:
  632. r = rtcp_psfb_vbcm_pack(&psfb->u.vbcm, data + 12, bytes - 12);
  633. break;
  634. case RTCP_PSFB_PSLEI:
  635. r = rtcp_psfb_pslei_pack(psfb->u.pslei.ssrc, psfb->u.pslei.count, data + 12, bytes - 12);
  636. break;
  637. case RTCP_PSFB_LRR:
  638. r = rtcp_psfb_lrr_pack(psfb->u.lrr.lrr, psfb->u.lrr.count, data + 12, bytes - 12);
  639. break;
  640. case RTCP_PSFB_REMB:
  641. r = rtcp_psfb_remb_pack(psfb->u.afb.remb, psfb->u.afb.count, data + 12, bytes - 12);
  642. break;
  643. case RTCP_PSFB_ROI:
  644. default:
  645. assert(0);
  646. return -1;
  647. }
  648. header.v = 2;
  649. header.p = 0;
  650. header.pt = RTCP_PSFB;
  651. header.rc = id;
  652. header.length = (r + 8 + 3) / 4;
  653. nbo_write_rtcp_header(data, &header);
  654. nbo_w32(data + 4, ctx->self->ssrc);
  655. //nbo_w32(data + 4, psfb->sender);
  656. nbo_w32(data + 8, psfb->media);
  657. //assert(8 == (header.length + 1) * 4);
  658. return header.length * 4 + 4;
  659. }
  660. #if defined(_DEBUG) || defined(DEBUG)
  661. static void rtcp_on_psfb_test(void* param, const struct rtcp_msg_t* msg)
  662. {
  663. int r;
  664. static uint8_t buffer[1400];
  665. switch (msg->type & 0xFF)
  666. {
  667. case RTCP_PSFB:
  668. switch ((msg->type >> 8) & 0xFF)
  669. {
  670. case RTCP_PSFB_PLI:
  671. r = rtcp_psfb_pli_pack(buffer, sizeof(buffer));
  672. assert(0 == r);
  673. break;
  674. case RTCP_PSFB_FIR:
  675. assert(1 == msg->u.psfb.u.fir.count);
  676. assert(0x23456789 == msg->u.psfb.u.fir.fir[0].ssrc && 13 == msg->u.psfb.u.fir.fir[0].sn);
  677. r = rtcp_psfb_fir_pack(msg->u.psfb.u.fir.fir, msg->u.psfb.u.fir.count, buffer, sizeof(buffer));
  678. assert(r == 8 && 0 == memcmp(buffer, param, r));
  679. break;
  680. case RTCP_PSFB_REMB:
  681. assert(3 == msg->u.psfb.u.afb.count);
  682. assert(0x23456789 == msg->u.psfb.u.afb.remb[0].ssrc && 1 == msg->u.psfb.u.afb.remb[0].exp && 0x3fb93 == msg->u.psfb.u.afb.remb[0].mantissa);
  683. assert(0x2345678a == msg->u.psfb.u.afb.remb[1].ssrc && 1 == msg->u.psfb.u.afb.remb[1].exp && 0x3fb93 == msg->u.psfb.u.afb.remb[1].mantissa);
  684. assert(0x2345678b == msg->u.psfb.u.afb.remb[2].ssrc && 1 == msg->u.psfb.u.afb.remb[2].exp && 0x3fb93 == msg->u.psfb.u.afb.remb[2].mantissa);
  685. r = rtcp_psfb_remb_pack(msg->u.psfb.u.afb.remb, msg->u.psfb.u.afb.count, buffer, sizeof(buffer));
  686. assert(r == 20 && 0 == memcmp(buffer, param, r));
  687. break;
  688. default:
  689. break;
  690. }
  691. break;
  692. default:
  693. assert(0);
  694. }
  695. }
  696. static void rtcp_rtpfb_pli_test(void)
  697. {
  698. struct rtcp_msg_t msg;
  699. struct rtp_context rtp;
  700. rtp.handler.on_rtcp = rtcp_on_psfb_test;
  701. rtp.cbparam = NULL;
  702. msg.type = (RTCP_PSFB_PLI << 8) | RTCP_PSFB;
  703. assert(0 == rtcp_psfb_pli_unpack(&rtp, NULL, &msg, NULL, 0));
  704. }
  705. static void rtcp_rtpfb_fir_test(void)
  706. {
  707. const uint8_t data[] = { 0x23, 0x45, 0x67, 0x89, 0x0d, 0x00, 0x00, 0x00 };
  708. struct rtcp_msg_t msg;
  709. struct rtp_context rtp;
  710. rtp.handler.on_rtcp = rtcp_on_psfb_test;
  711. rtp.cbparam = (void*)data;
  712. msg.type = (RTCP_PSFB_FIR << 8) | RTCP_PSFB;
  713. assert(0 == rtcp_psfb_fir_unpack(&rtp, NULL, &msg, data, sizeof(data)));
  714. }
  715. static void rtcp_rtpfb_remb_test(void)
  716. {
  717. const uint8_t data[] = { 'R', 'E', 'M', 'B', 0x03, 0x07, 0xfb, 0x93, 0x23, 0x45, 0x67, 0x89, 0x23, 0x45, 0x67, 0x8a, 0x23, 0x45, 0x67, 0x8b };
  718. struct rtcp_msg_t msg;
  719. struct rtp_context rtp;
  720. rtp.handler.on_rtcp = rtcp_on_psfb_test;
  721. rtp.cbparam = (void*)data;
  722. msg.type = (RTCP_PSFB_REMB << 8) | RTCP_PSFB;
  723. assert(0 == rtcp_psfb_afb_unpack(&rtp, NULL, &msg, data, sizeof(data)));
  724. }
  725. void rtcp_psfb_test(void)
  726. {
  727. rtcp_rtpfb_pli_test();
  728. rtcp_rtpfb_fir_test();
  729. rtcp_rtpfb_remb_test();
  730. }
  731. #endif