Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

256 рядки
6.9KB

  1. #include "rtmp-internal.h"
  2. #include "rtmp-msgtypeid.h"
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <errno.h>
  7. #define MIN(x, y) ((x) < (y) ? (x) : (y))
  8. static struct rtmp_packet_t* rtmp_packet_find(struct rtmp_t* rtmp, uint32_t cid)
  9. {
  10. uint32_t i;
  11. struct rtmp_packet_t* pkt;
  12. // The protocol supports up to 65597 streams with IDs 3-65599
  13. assert(cid <= 65535 + 64 && cid >= 2 /* Protocol Control Messages */);
  14. for (i = 0; i < N_CHUNK_STREAM; i++)
  15. {
  16. pkt = rtmp->in_packets + ((i + cid) % N_CHUNK_STREAM);
  17. if (pkt->header.cid == cid)
  18. return pkt;
  19. }
  20. return NULL;
  21. }
  22. static struct rtmp_packet_t* rtmp_packet_create(struct rtmp_t* rtmp, uint32_t cid)
  23. {
  24. uint32_t i;
  25. struct rtmp_packet_t* pkt;
  26. // The protocol supports up to 65597 streams with IDs 3-65599
  27. assert(cid <= 65535 + 64 && cid >= 2 /* Protocol Control Messages */);
  28. assert(NULL == rtmp_packet_find(rtmp, cid));
  29. for (i = 0; i < N_CHUNK_STREAM; i++)
  30. {
  31. pkt = rtmp->in_packets + ((i + cid) % N_CHUNK_STREAM);
  32. if (0 == pkt->header.cid)
  33. return pkt;
  34. }
  35. return NULL;
  36. }
  37. static struct rtmp_packet_t* rtmp_packet_parse(struct rtmp_t* rtmp, const uint8_t* buffer)
  38. {
  39. uint8_t fmt = 0;
  40. uint32_t cid = 0;
  41. struct rtmp_packet_t* packet;
  42. // chunk base header
  43. buffer += rtmp_chunk_basic_header_read(buffer, &fmt, &cid);
  44. // load previous header
  45. packet = rtmp_packet_find(rtmp, cid);
  46. if (NULL == packet)
  47. {
  48. if (RTMP_CHUNK_TYPE_0 != fmt && RTMP_CHUNK_TYPE_1 != fmt)
  49. return NULL; // don't know stream length
  50. packet = rtmp_packet_create(rtmp, cid);
  51. if (NULL == packet)
  52. return NULL;
  53. }
  54. // chunk message header
  55. packet->header.cid = cid;
  56. packet->header.fmt = fmt;
  57. rtmp_chunk_message_header_read(buffer, &packet->header);
  58. return packet;
  59. }
  60. static int rtmp_packet_alloc(struct rtmp_t* rtmp, struct rtmp_packet_t* packet)
  61. {
  62. void* p;
  63. (void)rtmp;
  64. // 24-bytes length
  65. assert(0 == packet->bytes);
  66. assert(packet->header.length < (1 << 24));
  67. // fixed SMS (Chinacache Smart Media Server) packet->header.length = 0
  68. if (0 == packet->capacity || packet->capacity < packet->header.length)
  69. {
  70. p = realloc(packet->payload, packet->header.length + 1024);
  71. if (NULL == p)
  72. return -ENOMEM;
  73. packet->payload = p;
  74. packet->capacity = packet->header.length + 1024;
  75. }
  76. return 0;
  77. }
  78. int rtmp_chunk_read(struct rtmp_t* rtmp, const uint8_t* data, size_t bytes)
  79. {
  80. const static uint32_t s_header_size[] = { 11, 7, 3, 0 };
  81. int r, invalid_extended_timestamp;
  82. size_t size, offset = 0;
  83. uint8_t extended_timestamp_buffer[4];
  84. uint32_t extended_timestamp = 0;
  85. struct rtmp_parser_t* parser = &rtmp->parser;
  86. struct rtmp_chunk_header_t header;
  87. while (offset < bytes)
  88. {
  89. switch (parser->state)
  90. {
  91. case RTMP_PARSE_INIT:
  92. parser->pkt = NULL;
  93. parser->bytes = 1;
  94. parser->buffer[0] = data[offset++];
  95. if (0 == (parser->buffer[0] & 0x3F))
  96. parser->basic_bytes = 2;
  97. else if (1 == (parser->buffer[0] & 0x3F))
  98. parser->basic_bytes = 3;
  99. else
  100. parser->basic_bytes = 1;
  101. parser->state = RTMP_PARSE_BASIC_HEADER;
  102. break;
  103. case RTMP_PARSE_BASIC_HEADER:
  104. assert(parser->bytes <= parser->basic_bytes);
  105. while (parser->bytes < parser->basic_bytes && offset < bytes)
  106. {
  107. parser->buffer[parser->bytes++] = data[offset++];
  108. }
  109. assert(parser->bytes <= parser->basic_bytes);
  110. if (parser->bytes >= parser->basic_bytes)
  111. {
  112. parser->state = RTMP_PARSE_MESSAGE_HEADER;
  113. }
  114. break;
  115. case RTMP_PARSE_MESSAGE_HEADER:
  116. size = s_header_size[parser->buffer[0] >> 6] + parser->basic_bytes;
  117. assert(parser->bytes <= size);
  118. while (parser->bytes < size && offset < bytes)
  119. {
  120. parser->buffer[parser->bytes++] = data[offset++];
  121. }
  122. assert(parser->bytes <= size);
  123. if (parser->bytes >= size)
  124. {
  125. parser->pkt = rtmp_packet_parse(rtmp, parser->buffer);
  126. parser->state = RTMP_PARSE_EXTENDED_TIMESTAMP;
  127. }
  128. break;
  129. case RTMP_PARSE_EXTENDED_TIMESTAMP:
  130. if (NULL == parser->pkt) return -ENOMEM;
  131. assert(parser->pkt->header.timestamp <= 0xFFFFFF);
  132. size = s_header_size[parser->pkt->header.fmt] + parser->basic_bytes;
  133. if (parser->pkt->header.timestamp == 0xFFFFFF) size += 4; // extended timestamp
  134. assert(parser->bytes <= size);
  135. while (parser->bytes < size && offset < bytes)
  136. {
  137. parser->buffer[parser->bytes++] = data[offset++];
  138. }
  139. assert(parser->bytes <= size);
  140. if (parser->bytes >= size)
  141. {
  142. invalid_extended_timestamp = 0;
  143. extended_timestamp = parser->pkt->header.timestamp;
  144. if (parser->pkt->header.timestamp == 0xFFFFFF)
  145. {
  146. // parse extended timestamp
  147. rtmp_chunk_extended_timestamp_read(parser->buffer + s_header_size[parser->buffer[0] >> 6] + parser->basic_bytes, &extended_timestamp);
  148. if (RTMP_CHUNK_TYPE_3 == parser->pkt->header.fmt && extended_timestamp != parser->pkt->delta)
  149. {
  150. // fix code offset -= 4 on offset < 4;
  151. invalid_extended_timestamp = 1;
  152. memcpy(extended_timestamp_buffer, parser->buffer + s_header_size[parser->buffer[0] >> 6] + parser->basic_bytes, 4);
  153. }
  154. }
  155. // first chunk
  156. if (0 == parser->pkt->bytes)
  157. {
  158. parser->pkt->delta = extended_timestamp;
  159. // handle timestamp/delta
  160. if (RTMP_CHUNK_TYPE_0 == parser->pkt->header.fmt)
  161. parser->pkt->clock = parser->pkt->delta;
  162. else
  163. parser->pkt->clock += parser->pkt->delta;
  164. if (0 != rtmp_packet_alloc(rtmp, parser->pkt))
  165. return -ENOMEM;
  166. }
  167. parser->state = RTMP_PARSE_PAYLOAD;
  168. // rewind extended_timestamp_buffer
  169. if (invalid_extended_timestamp)
  170. {
  171. r = rtmp_chunk_read(rtmp, extended_timestamp_buffer, 4);
  172. if (0 != r) return r;
  173. }
  174. }
  175. break;
  176. case RTMP_PARSE_PAYLOAD:
  177. if (NULL == parser->pkt || NULL == parser->pkt->payload
  178. || parser->pkt->bytes > parser->pkt->capacity
  179. || parser->pkt->bytes > parser->pkt->header.length
  180. || parser->pkt->header.length > parser->pkt->capacity)
  181. {
  182. assert(0);
  183. return -ENOMEM;
  184. }
  185. //assert(parser->pkt->bytes <= parser->pkt->header.length);
  186. //assert(parser->pkt->capacity >= parser->pkt->header.length);
  187. size = MIN(rtmp->in_chunk_size - (parser->pkt->bytes % rtmp->in_chunk_size), parser->pkt->header.length - parser->pkt->bytes);
  188. size = MIN(size, bytes - offset);
  189. if(size > 0) memcpy(parser->pkt->payload + parser->pkt->bytes, data + offset, size);
  190. parser->pkt->bytes += size;
  191. offset += size;
  192. if (parser->pkt->bytes >= parser->pkt->header.length)
  193. {
  194. assert(parser->pkt->bytes == parser->pkt->header.length);
  195. parser->state = RTMP_PARSE_INIT; // reset parser state
  196. parser->pkt->bytes = 0; // clear bytes
  197. memcpy(&header, &parser->pkt->header, sizeof(header));
  198. header.timestamp = parser->pkt->clock;
  199. r = rtmp_handler(rtmp, &header, parser->pkt->payload);
  200. if(0 != r) return r;
  201. }
  202. else if (0 == (parser->pkt->bytes % rtmp->in_chunk_size))
  203. {
  204. // next chunk
  205. parser->state = RTMP_PARSE_INIT;
  206. }
  207. else
  208. {
  209. // need more data
  210. assert(offset == bytes);
  211. }
  212. break;
  213. default:
  214. assert(0);
  215. break;
  216. }
  217. }
  218. return 0;
  219. }