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.

218 linhas
5.5KB

  1. // RTP Payload Format for VP9 Video draft-ietf-payload-vp9-03
  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. /*
  12. 0 1 2 3
  13. 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
  14. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  15. |V=2|P|X| CC |M| PT | sequence number |
  16. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  17. | timestamp |
  18. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  19. | synchronization source (SSRC) identifier |
  20. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  21. | contributing source (CSRC) identifiers |
  22. | .... |
  23. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  24. | VP9 payload descriptor (integer #octets) |
  25. : :
  26. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  27. | : VP9 pyld hdr | |
  28. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
  29. | |
  30. + |
  31. : Bytes 2..N of VP9 payload :
  32. | |
  33. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  34. | : OPTIONAL RTP padding |
  35. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  36. */
  37. static int rtp_decode_vp9(void* p, const void* packet, int bytes)
  38. {
  39. uint8_t pictureid_present;
  40. uint8_t inter_picture_predicted_layer_frame;
  41. uint8_t layer_indices_preset;
  42. uint8_t flex_mode;
  43. uint8_t start_of_layer_frame;
  44. //uint8_t end_of_layer_frame;
  45. uint8_t scalability_struct_data_present;
  46. const uint8_t *ptr, *pend;
  47. struct rtp_packet_t pkt;
  48. struct rtp_payload_helper_t *helper;
  49. helper = (struct rtp_payload_helper_t *)p;
  50. if (!helper || 0 != rtp_packet_deserialize(&pkt, packet, bytes) || pkt.payloadlen < 1)
  51. return -EINVAL;
  52. rtp_payload_check(helper, &pkt);
  53. ptr = (const uint8_t *)pkt.payload;
  54. pend = ptr + pkt.payloadlen;
  55. // VP9 payload descriptor
  56. /*
  57. 0 1 2 3 4 5 6 7
  58. +-+-+-+-+-+-+-+-+
  59. |I|P|L|F|B|E|V|-| (REQUIRED)
  60. +-+-+-+-+-+-+-+-+
  61. */
  62. pictureid_present = ptr[0] & 0x80;
  63. inter_picture_predicted_layer_frame = ptr[0] & 0x40;
  64. layer_indices_preset = ptr[0] & 0x20;
  65. flex_mode = ptr[0] & 0x10;
  66. start_of_layer_frame = ptr[0] & 0x80;
  67. //end_of_layer_frame = ptr[0] & 0x04;
  68. scalability_struct_data_present = ptr[0] & 0x02;
  69. ptr++;
  70. if (pictureid_present && ptr < pend)
  71. {
  72. // +-+-+-+-+-+-+-+-+
  73. // I: |M| PICTURE ID | (RECOMMENDED)
  74. // +-+-+-+-+-+-+-+-+
  75. // M: | EXTENDED PID | (RECOMMENDED)
  76. // +-+-+-+-+-+-+-+-+
  77. //uint16_t picture_id;
  78. //picture_id = ptr[0] & 0x7F;
  79. if ((ptr[0] & 0x80) && ptr + 1 < pend)
  80. {
  81. //picture_id = (ptr[0] << 8) | ptr[1];
  82. ptr++;
  83. }
  84. ptr++;
  85. }
  86. if (layer_indices_preset && ptr < pend)
  87. {
  88. // +-+-+-+-+-+-+-+-+
  89. // L: | T | U | S | D | (CONDITIONALLY RECOMMENDED)
  90. // +-+-+-+-+-+-+-+-+
  91. // | TL0PICIDX | (CONDITIONALLY REQUIRED)
  92. // +-+-+-+-+-+-+-+-+
  93. // ignore Layer indices
  94. if (0 == flex_mode)
  95. ptr++; // TL0PICIDX
  96. ptr++;
  97. }
  98. if (inter_picture_predicted_layer_frame && flex_mode && ptr < pend)
  99. {
  100. // +-+-+-+-+-+-+-+-+ -\
  101. // P,F: | P_DIFF |N| (CONDITIONALLY REQUIRED) - up to 3 times
  102. // +-+-+-+-+-+-+-+-+ -/
  103. // ignore Reference indices
  104. if (ptr[0] & 0x01)
  105. {
  106. if ((ptr[1] & 0x01) && ptr + 1 < pend)
  107. ptr++;
  108. ptr++;
  109. }
  110. ptr++;
  111. }
  112. if (scalability_struct_data_present && ptr < pend)
  113. {
  114. /*
  115. +-+-+-+-+-+-+-+-+
  116. V: | N_S |Y|G|-|-|-|
  117. +-+-+-+-+-+-+-+-+ -\
  118. Y: | WIDTH | (OPTIONAL) .
  119. + + .
  120. | | (OPTIONAL) .
  121. +-+-+-+-+-+-+-+-+ . - N_S + 1 times
  122. | HEIGHT | (OPTIONAL) .
  123. + + .
  124. | | (OPTIONAL) .
  125. +-+-+-+-+-+-+-+-+ -/ -\
  126. G: | N_G | (OPTIONAL)
  127. +-+-+-+-+-+-+-+-+ -\
  128. N_G:| T |U| R |-|-| (OPTIONAL) .
  129. +-+-+-+-+-+-+-+-+ -\ . - N_G times
  130. | P_DIFF | (OPTIONAL) . - R times .
  131. +-+-+-+-+-+-+-+-+ -/ -/
  132. */
  133. uint8_t N_S, Y, G;
  134. N_S = ((ptr[0] >> 5) & 0x07) + 1;
  135. Y = ptr[0] & 0x10;
  136. G = ptr[0] & 0x80;
  137. ptr++;
  138. if (Y)
  139. {
  140. ptr += N_S * 4;
  141. }
  142. if (G && ptr < pend)
  143. {
  144. uint8_t i;
  145. uint8_t N_G = ptr[0];
  146. ptr++;
  147. for (i = 0; i < N_G && ptr < pend; i++)
  148. {
  149. uint8_t j;
  150. uint8_t R;
  151. R = (ptr[0] >> 2) & 0x03;
  152. ptr++;
  153. for (j = 0; j < R && ptr < pend; j++)
  154. {
  155. // ignore P_DIFF
  156. ptr++;
  157. }
  158. }
  159. }
  160. }
  161. if (ptr >= pend)
  162. {
  163. assert(0);
  164. //helper->size = 0;
  165. helper->lost = 1;
  166. //helper->flags |= RTP_PAYLOAD_FLAG_PACKET_LOST;
  167. return -1; // invalid packet
  168. }
  169. if (start_of_layer_frame)
  170. {
  171. // new frame begin
  172. rtp_payload_onframe(helper);
  173. }
  174. pkt.payload = ptr;
  175. pkt.payloadlen = (int)(pend - ptr);
  176. rtp_payload_write(helper, &pkt);
  177. if (pkt.rtp.m)
  178. {
  179. rtp_payload_onframe(helper);
  180. }
  181. return 1; // packet handled
  182. }
  183. struct rtp_payload_decode_t *rtp_vp9_decode()
  184. {
  185. static struct rtp_payload_decode_t unpacker = {
  186. rtp_payload_helper_create,
  187. rtp_payload_helper_destroy,
  188. rtp_decode_vp9,
  189. };
  190. return &unpacker;
  191. }