25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.9KB

  1. #include "rtmp-internal.h"
  2. #include "rtmp-msgtypeid.h"
  3. #include "rtmp-event.h"
  4. #include "rtmp-util.h"
  5. #include <assert.h>
  6. #define N_CHUNK_HEADER 12
  7. static void rtmp_user_control_message_header(uint8_t* out, size_t payload)
  8. {
  9. // 6.2. User Control Messages (p23)
  10. // RTMP uses message type ID 4 for User Control messages
  11. // User Control messages SHOULD use message stream ID 0 (known
  12. // as the control stream) and be sent in chunk stream ID 2.
  13. out[0] = (0x00 << 6) /*fmt*/ | 0x02 /*cs id*/;
  14. /* timestamp */
  15. out[1] = 0x00;
  16. out[2] = 0x00;
  17. out[3] = 0x00;
  18. /* message length */
  19. out[4] = (uint8_t)(payload >> 16);
  20. out[5] = (uint8_t)(payload >> 8);
  21. out[6] = (uint8_t)payload;
  22. /* message type id */
  23. out[7] = RTMP_TYPE_EVENT;
  24. /* message stream id */
  25. out[8] = 0x00;
  26. out[9] = 0x00;
  27. out[10] = 0x00;
  28. out[11] = 0x00;
  29. }
  30. // s -> c
  31. int rtmp_event_stream_begin(uint8_t* data, size_t bytes, uint32_t streamId)
  32. {
  33. if (bytes < N_CHUNK_HEADER + 6) return 0;
  34. rtmp_user_control_message_header(data, 6);
  35. be_write_uint16(N_CHUNK_HEADER + data, RTMP_EVENT_STREAM_BEGIN);
  36. be_write_uint32(N_CHUNK_HEADER + data + 2, streamId);
  37. return N_CHUNK_HEADER + 6;
  38. }
  39. // s -> c
  40. int rtmp_event_stream_eof(uint8_t* data, size_t bytes, uint32_t streamId)
  41. {
  42. if (bytes < N_CHUNK_HEADER + 6) return 0;
  43. rtmp_user_control_message_header(data, 6);
  44. be_write_uint16(N_CHUNK_HEADER + data, RTMP_EVENT_STREAM_EOF);
  45. be_write_uint32(N_CHUNK_HEADER + data + 2, streamId);
  46. return N_CHUNK_HEADER + 6;
  47. }
  48. // s -> c
  49. int rtmp_event_stream_dry(uint8_t* data, size_t bytes, uint32_t streamId)
  50. {
  51. if (bytes < N_CHUNK_HEADER + 6) return 0;
  52. rtmp_user_control_message_header(data, 6);
  53. be_write_uint16(N_CHUNK_HEADER + data, RTMP_EVENT_STREAM_DRY);
  54. be_write_uint32(N_CHUNK_HEADER + data + 2, streamId);
  55. return N_CHUNK_HEADER + 6;
  56. }
  57. // c -> s
  58. int rtmp_event_set_buffer_length(uint8_t* data, size_t bytes, uint32_t streamId, uint32_t ms)
  59. {
  60. if (bytes < N_CHUNK_HEADER + 10) return 0;
  61. rtmp_user_control_message_header(data, 10);
  62. be_write_uint16(N_CHUNK_HEADER + data, RTMP_EVENT_SET_BUFFER_LENGTH);
  63. be_write_uint32(N_CHUNK_HEADER + data + 2, streamId);
  64. be_write_uint32(N_CHUNK_HEADER + data + 6, ms);
  65. return N_CHUNK_HEADER + 10;
  66. }
  67. // s -> c
  68. int rtmp_event_stream_is_record(uint8_t* data, size_t bytes, uint32_t streamId)
  69. {
  70. if (bytes < N_CHUNK_HEADER + 6) return 0;
  71. rtmp_user_control_message_header(data, 6);
  72. be_write_uint16(N_CHUNK_HEADER + data, RTMP_EVENT_STREAM_IS_RECORD);
  73. be_write_uint32(N_CHUNK_HEADER + data + 2, streamId);
  74. return N_CHUNK_HEADER + 6;
  75. }
  76. // s -> c
  77. int rtmp_event_ping(uint8_t* data, size_t bytes, uint32_t timstamp)
  78. {
  79. if (bytes < N_CHUNK_HEADER + 6) return 0;
  80. rtmp_user_control_message_header(data, 6);
  81. be_write_uint16(N_CHUNK_HEADER + data, RTMP_EVENT_PING);
  82. be_write_uint32(N_CHUNK_HEADER + data + 2, timstamp);
  83. return N_CHUNK_HEADER + 6;
  84. }
  85. // c -> s
  86. int rtmp_event_pong(uint8_t* data, size_t bytes, uint32_t timstamp)
  87. {
  88. if (bytes < N_CHUNK_HEADER + 6) return 0;
  89. rtmp_user_control_message_header(data, 6);
  90. be_write_uint16(N_CHUNK_HEADER + data, RTMP_EVENT_PONG);
  91. be_write_uint32(N_CHUNK_HEADER + data + 2, timstamp);
  92. return N_CHUNK_HEADER + 6;
  93. }
  94. int rtmp_event_handler(struct rtmp_t* rtmp, const struct rtmp_chunk_header_t* header, const uint8_t* data)
  95. {
  96. uint16_t event = 0;
  97. uint32_t streamId = 0;
  98. if (header->length < 6) return 0;
  99. be_read_uint16(data, &event);
  100. be_read_uint32(data + 2, &streamId);
  101. switch (event)
  102. {
  103. case RTMP_EVENT_STREAM_BEGIN:
  104. case RTMP_EVENT_STREAM_DRY:
  105. case RTMP_EVENT_STREAM_IS_RECORD:
  106. return 6;
  107. case RTMP_EVENT_STREAM_EOF:
  108. rtmp->client.oneof ? rtmp->client.oneof(rtmp->param, streamId) : 0;
  109. return 6;
  110. case RTMP_EVENT_SET_BUFFER_LENGTH:
  111. if (header->length < 10) return 0;
  112. be_read_uint32(data + 6, &rtmp->buffer_length_ms);
  113. return 10;
  114. case RTMP_EVENT_PING:
  115. rtmp->client.onping ? rtmp->client.onping(rtmp->param, streamId) : 0;
  116. return 6;
  117. case RTMP_EVENT_PONG:
  118. return 6;
  119. default:
  120. return header->length;
  121. }
  122. }