Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

rtp-av1-unpack.c 11KB

5 månader sedan
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. // https://aomediacodec.github.io/av1-rtp-spec/#41-rtp-header-usage
  2. #include "rtp-packet.h"
  3. #include "rtp-profile.h"
  4. #include "rtp-payload-helper.h"
  5. #include "rtp-payload-internal.h"
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <assert.h>
  9. #include <errno.h>
  10. #include <errno.h>
  11. #define N_MAX_OBU 255
  12. #define N_RESERVED_OBU_SIZE_FIELD 2
  13. struct rtp_decode_av1_obu_t
  14. {
  15. int off;
  16. int len;
  17. };
  18. struct rtp_decode_av1_t
  19. {
  20. struct rtp_payload_t handler;
  21. void* cbparam;
  22. int lost;
  23. uint16_t seq; // rtp seq
  24. uint32_t timestamp;
  25. int flags;
  26. struct
  27. {
  28. struct rtp_decode_av1_obu_t* arr;
  29. int num, cap;
  30. } obu;
  31. struct
  32. {
  33. uint8_t* ptr;
  34. int len, cap;
  35. } ptr;
  36. };
  37. static inline const uint8_t* leb128(const uint8_t* data, size_t bytes, int64_t* size)
  38. {
  39. size_t i;
  40. for (*size = i = 0; i * 7 < 64 && i < bytes;)
  41. {
  42. *size |= ((int64_t)(data[i] & 0x7F)) << (i * 7);
  43. if (0 == (data[i++] & 0x80))
  44. break;
  45. }
  46. return data + i;
  47. }
  48. //static inline uint8_t* leb128_write(int64_t size, uint8_t* data, size_t bytes)
  49. //{
  50. // size_t i;
  51. // assert(3 == bytes && size <= 0x1FFFFF);
  52. // for (i = 0; i * 7 < 64 && i < bytes; i++)
  53. // {
  54. // data[i] = (uint8_t)(size & 0x7F);
  55. // size >>= 7;
  56. // data[i] |= (size > 0 || i + 1 < bytes)? 0x80 : 0;
  57. // }
  58. // return data + i;
  59. //}
  60. static inline int leb128_write(int64_t size, uint8_t* data, int bytes)
  61. {
  62. int i;
  63. for (i = 0; i * 7 < 64 && i < bytes;)
  64. {
  65. data[i] = (uint8_t)(size & 0x7F);
  66. size >>= 7;
  67. data[i++] |= size > 0 ? 0x80 : 0;
  68. if (0 == size)
  69. break;
  70. }
  71. return i;
  72. }
  73. static void* rtp_av1_unpack_create(struct rtp_payload_t* handler, void* param)
  74. {
  75. struct rtp_decode_av1_t* unpacker;
  76. unpacker = (struct rtp_decode_av1_t*)calloc(1, sizeof(*unpacker));
  77. if (!unpacker)
  78. return NULL;
  79. memcpy(&unpacker->handler, handler, sizeof(unpacker->handler));
  80. unpacker->cbparam = param;
  81. unpacker->flags = -1;
  82. return unpacker;
  83. }
  84. static void rtp_av1_unpack_destroy(void* p)
  85. {
  86. struct rtp_decode_av1_t* unpacker;
  87. unpacker = (struct rtp_decode_av1_t*)p;
  88. if (unpacker->obu.arr)
  89. free(unpacker->obu.arr);
  90. if (unpacker->ptr.ptr)
  91. free(unpacker->ptr.ptr);
  92. #if defined(_DEBUG) || defined(DEBUG)
  93. memset(unpacker, 0xCC, sizeof(*unpacker));
  94. #endif
  95. free(unpacker);
  96. }
  97. static int rtp_av1_unpack_obu_append(struct rtp_decode_av1_t* unpacker, const uint8_t* data, int bytes, int start)
  98. {
  99. void* p;
  100. int size;
  101. int64_t n;
  102. uint8_t head;
  103. const uint8_t* pend;
  104. pend = data + bytes;
  105. size = unpacker->ptr.len + bytes + 9 /*obu_size*/ + 2 /*obu temporal delimiter*/;
  106. if (size > RTP_PAYLOAD_MAX_SIZE || size < 0 || bytes < 2)
  107. return -EINVAL;
  108. if (size >= unpacker->ptr.cap)
  109. {
  110. size += size / 4 > 16000 ? size / 4 : 16000;
  111. p = realloc(unpacker->ptr.ptr, size);
  112. if (!p)
  113. {
  114. //unpacker->flags |= RTP_PAYLOAD_FLAG_PACKET_LOST;
  115. unpacker->lost = 1;
  116. //unpacker->size = 0;
  117. return -ENOMEM;
  118. }
  119. unpacker->ptr.ptr = (uint8_t*)p;
  120. unpacker->ptr.cap = size;
  121. }
  122. if (unpacker->obu.num + start >= unpacker->obu.cap)
  123. {
  124. if (unpacker->obu.cap >= N_MAX_OBU)
  125. return -E2BIG;
  126. p = realloc(unpacker->obu.arr, sizeof(struct rtp_decode_av1_obu_t) * (unpacker->obu.cap + 8));
  127. if (!p)
  128. return -ENOMEM;
  129. memset((struct rtp_decode_av1_obu_t*)p + unpacker->obu.cap, 0, sizeof(struct rtp_decode_av1_obu_t) * 8);
  130. unpacker->obu.arr = (struct rtp_decode_av1_obu_t*)p;
  131. unpacker->obu.cap += 8;
  132. }
  133. // add temporal delimiter obu
  134. //if (0 == unpacker->ptr.len)
  135. //{
  136. // static const uint8_t av1_temporal_delimiter[] = { 0x12, 0x00 };
  137. // assert(0 == unpacker->ptr.len);
  138. // memcpy(unpacker->ptr.ptr, av1_temporal_delimiter, sizeof(av1_temporal_delimiter));
  139. // unpacker->ptr.len += sizeof(av1_temporal_delimiter);
  140. //}
  141. if (start)
  142. {
  143. unpacker->obu.arr[unpacker->obu.num].off = unpacker->ptr.len;
  144. unpacker->obu.arr[unpacker->obu.num].len = 0;
  145. // obu_head
  146. head = *data++;
  147. unpacker->ptr.ptr[unpacker->ptr.len++] = head;
  148. if (head & 0x04) { // obu_extension_flag
  149. unpacker->ptr.ptr[unpacker->ptr.len++] = *data++;
  150. }
  151. if (head & 0x02) { // obu_has_size_field
  152. data = leb128(data, pend - data, &n);
  153. unpacker->ptr.len += leb128_write(n, unpacker->ptr.ptr + unpacker->ptr.len, unpacker->ptr.cap - unpacker->ptr.len);
  154. } else {
  155. unpacker->ptr.len += N_RESERVED_OBU_SIZE_FIELD; // obu_size
  156. }
  157. unpacker->obu.num++;
  158. }
  159. unpacker->obu.arr[unpacker->obu.num-1].len += (int)(intptr_t)(pend - data);
  160. // obu
  161. memcpy(unpacker->ptr.ptr + unpacker->ptr.len, data, pend - data);
  162. unpacker->ptr.len += (int)(intptr_t)(pend - data);
  163. return 0;
  164. }
  165. int rtp_av1_unpack_onframe(struct rtp_decode_av1_t* unpacker)
  166. {
  167. int i, j, r, n;
  168. uint8_t* obu, *data, obu_size_field[9];
  169. int64_t len;
  170. r = 0;
  171. if (unpacker->obu.num < unpacker->obu.cap && unpacker->obu.arr[0].len > 0
  172. #if !defined(RTP_ENABLE_COURRUPT_PACKET)
  173. && 0 == unpacker->lost
  174. #endif
  175. )
  176. {
  177. // write obu length
  178. for (i = 0; i < unpacker->obu.num; i++)
  179. {
  180. obu = unpacker->ptr.ptr + unpacker->obu.arr[i].off;
  181. data = obu + ((0x04 & obu[0]) ? 2 : 1);
  182. if (0x02 & obu[0]) { // obu_has_size_field
  183. assert(unpacker->lost || (leb128(data, 9, &len) && len == unpacker->obu.arr[i].len));
  184. continue;
  185. }
  186. obu[0] |= 0x02; // obu_has_size_field
  187. n = leb128_write(unpacker->obu.arr[i].len, obu_size_field, sizeof(obu_size_field));
  188. if (n != N_RESERVED_OBU_SIZE_FIELD) {
  189. memmove(data + n, data + N_RESERVED_OBU_SIZE_FIELD, unpacker->ptr.ptr + unpacker->ptr.len - (data + N_RESERVED_OBU_SIZE_FIELD));
  190. unpacker->ptr.len -= N_RESERVED_OBU_SIZE_FIELD - n;
  191. for (j = i + 1; j < unpacker->obu.num; j++)
  192. {
  193. assert(unpacker->obu.arr[j].off + n > N_RESERVED_OBU_SIZE_FIELD);
  194. unpacker->obu.arr[j].off = unpacker->obu.arr[j].off + n - N_RESERVED_OBU_SIZE_FIELD;
  195. }
  196. }
  197. memcpy(data, obu_size_field, n);
  198. }
  199. // previous packet done
  200. r = unpacker->handler.packet(unpacker->cbparam, unpacker->ptr.ptr, unpacker->ptr.len, unpacker->timestamp, unpacker->flags | (unpacker->lost ? RTP_PAYLOAD_FLAG_PACKET_CORRUPT : 0));
  201. // RTP_PAYLOAD_FLAG_PACKET_LOST: miss
  202. unpacker->flags &= ~RTP_PAYLOAD_FLAG_PACKET_LOST; // clear packet lost flag
  203. }
  204. // set packet lost flag on next frame
  205. if (unpacker->lost)
  206. unpacker->flags |= RTP_PAYLOAD_FLAG_PACKET_LOST;
  207. // new frame start
  208. unpacker->lost = 0;
  209. unpacker->ptr.len = 0;
  210. unpacker->obu.num = 0;
  211. memset(unpacker->obu.arr, 0, sizeof(struct rtp_decode_av1_obu_t) * unpacker->obu.cap);
  212. return r;
  213. }
  214. /*
  215. 0 1 2 3
  216. 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
  217. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  218. |V=2|P|X| CC |M| PT | sequence number |
  219. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  220. | timestamp |
  221. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  222. | synchronization source (SSRC) identifier |
  223. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  224. | contributing source (CSRC) identifiers |
  225. | .... |
  226. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  227. | 0x100 | 0x0 | extensions length |
  228. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  229. | 0x1(ID) | hdr_length | |
  230. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
  231. | |
  232. | dependency descriptor (hdr_length #octets) |
  233. | |
  234. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  235. | | Other rtp header extensions...|
  236. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  237. | AV1 aggr hdr | |
  238. +-+-+-+-+-+-+-+-+ |
  239. | |
  240. | Bytes 2..N of AV1 payload |
  241. | |
  242. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  243. | : OPTIONAL RTP padding |
  244. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  245. */
  246. static int rtp_av1_unpack_input(void* p, const void* packet, int bytes)
  247. {
  248. int lost;
  249. int64_t size;
  250. uint8_t z, y, w, n, i;
  251. const uint8_t *ptr, *pend;
  252. struct rtp_packet_t pkt;
  253. struct rtp_decode_av1_t* unpacker;
  254. unpacker = (struct rtp_decode_av1_t*)p;
  255. if (!unpacker || 0 != rtp_packet_deserialize(&pkt, packet, bytes) || pkt.payloadlen < 1)
  256. return -EINVAL;
  257. lost = 0;
  258. if (-1 == unpacker->flags)
  259. {
  260. unpacker->flags = 0;
  261. unpacker->seq = (uint16_t)(pkt.rtp.seq - 1); // disable packet lost
  262. }
  263. if ((uint16_t)pkt.rtp.seq != (uint16_t)(unpacker->seq + 1))
  264. {
  265. lost = 1;
  266. unpacker->flags = RTP_PAYLOAD_FLAG_PACKET_LOST;
  267. unpacker->ptr.len = 0; // discard previous packets
  268. }
  269. // check timestamp
  270. if (pkt.rtp.timestamp != unpacker->timestamp)
  271. {
  272. rtp_av1_unpack_onframe(unpacker);
  273. // lost:
  274. // 0 - packet lost before timestamp change
  275. // 1 - packet lost on timestamp changed, can't known losted packet is at old packet tail or new packet start, so two packets mark as packet lost
  276. if (0 != lost)
  277. unpacker->lost = lost;
  278. }
  279. unpacker->seq = (uint16_t)pkt.rtp.seq;
  280. unpacker->timestamp = pkt.rtp.timestamp;
  281. ptr = (const uint8_t *)pkt.payload;
  282. pend = ptr + pkt.payloadlen;
  283. // AV1 aggregation header
  284. /*
  285. 0 1 2 3 4 5 6 7
  286. +-+-+-+-+-+-+-+-+
  287. |Z|Y| W |N|-|-|-|
  288. +-+-+-+-+-+-+-+-+
  289. */
  290. z = ptr[0] & 0x80; // MUST be set to 1 if the first OBU element is an OBU fragment that is a continuation of an OBU fragment from the previous packet, and MUST be set to 0 otherwise.
  291. y = ptr[0] & 0x40; // MUST be set to 1 if the last OBU element is an OBU fragment that will continue in the next packet, and MUST be set to 0 otherwise.
  292. w = (ptr[0] & 0x30) >> 4; // two bit field that describes the number of OBU elements in the packet. This field MUST be set equal to 0 or equal to the number of OBU elements contained in the packet. If set to 0, each OBU element MUST be preceded by a length field.
  293. n = ptr[0] & 0x08; // MUST be set to 1 if the packet is the first packet of a coded video sequence, and MUST be set to 0 otherwise.
  294. (void)y;
  295. // if N equals 1 then Z must equal 0.
  296. assert(!n || 0 == z);
  297. if (0 == z && 1 == n) {
  298. // new video codec sequence
  299. rtp_av1_unpack_onframe(unpacker);
  300. }
  301. for (i = 1, ptr++; ptr < pend; ptr += size, i++)
  302. {
  303. if (i < w || 0 == w)
  304. {
  305. ptr = leb128(ptr, pend - ptr, &size);
  306. }
  307. else
  308. {
  309. size = pend - ptr;
  310. }
  311. // skip fragment frame OBU size
  312. if (ptr + size > pend)
  313. {
  314. //assert(0);
  315. //unpacker->size = 0;
  316. unpacker->lost = 1;
  317. //unpacker->flags |= RTP_PAYLOAD_FLAG_PACKET_LOST;
  318. return -1; // invalid packet
  319. }
  320. rtp_av1_unpack_obu_append(unpacker, ptr, (int)size, (1 != i || 0 == z) ? 1 : 0);
  321. }
  322. // The RTP header Marker bit MUST be set equal to 0
  323. // if the packet is not the last packet of the temporal unit,
  324. // it SHOULD be set equal to 1 otherwise.
  325. if (pkt.rtp.m)
  326. {
  327. rtp_av1_unpack_onframe(unpacker);
  328. }
  329. return 1; // packet handled
  330. }
  331. struct rtp_payload_decode_t *rtp_av1_decode()
  332. {
  333. static struct rtp_payload_decode_t unpacker = {
  334. rtp_av1_unpack_create,
  335. rtp_av1_unpack_destroy,
  336. rtp_av1_unpack_input,
  337. };
  338. return &unpacker;
  339. }