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.

189 linhas
4.9KB

  1. #include "rtsp-client.h"
  2. #include "rtsp-client-internal.h"
  3. #include "rtp-profile.h"
  4. #include "sdp.h"
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <assert.h>
  8. #if defined(OS_WINDOWS)
  9. #define strncasecmp _strnicmp
  10. #endif
  11. struct rtsp_client_t* rtsp_client_create(const char* uri, const char* usr, const char* pwd, const struct rtsp_client_handler_t *handler, void* param)
  12. {
  13. struct rtsp_client_t *rtsp;
  14. rtsp = (struct rtsp_client_t*)calloc(1, sizeof(*rtsp));
  15. if(NULL == rtsp)
  16. return NULL;
  17. snprintf(rtsp->uri, sizeof(rtsp->uri) - 1, "%s", uri);
  18. snprintf(rtsp->usr, sizeof(rtsp->usr) - 1, "%s", usr ? usr : "");
  19. snprintf(rtsp->pwd, sizeof(rtsp->pwd) - 1, "%s", pwd ? pwd : "");
  20. rtsp->parser = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
  21. memcpy(&rtsp->handler, handler, sizeof(rtsp->handler));
  22. rtsp->rtp.onrtp = rtsp->handler.onrtp;
  23. rtsp->rtp.param = param;
  24. rtsp->state = RTSP_INIT;
  25. rtsp->param = param;
  26. rtsp->cseq = 1;
  27. rtsp->auth_failed = 0;
  28. return rtsp;
  29. }
  30. void rtsp_client_destroy(struct rtsp_client_t *rtsp)
  31. {
  32. if (rtsp->parser)
  33. {
  34. http_parser_destroy(rtsp->parser);
  35. rtsp->parser = NULL;
  36. }
  37. if (rtsp->rtp.data)
  38. {
  39. assert(rtsp->rtp.capacity > 0);
  40. free(rtsp->rtp.data);
  41. rtsp->rtp.data = NULL;
  42. rtsp->rtp.capacity = 0;
  43. }
  44. free(rtsp);
  45. }
  46. static int rtsp_client_handle(struct rtsp_client_t* rtsp, http_parser_t* parser)
  47. {
  48. switch (rtsp->state)
  49. {
  50. case RTSP_DESCRIBE: return rtsp_client_describe_onreply(rtsp, parser);
  51. case RTSP_SETUP: return rtsp_client_setup_onreply(rtsp, parser);
  52. case RTSP_PLAY: return rtsp_client_play_onreply(rtsp, parser);
  53. case RTSP_PAUSE: return rtsp_client_pause_onreply(rtsp, parser);
  54. case RTSP_TEARDWON: return rtsp_client_teardown_onreply(rtsp, parser);
  55. case RTSP_OPTIONS: return rtsp_client_options_onreply(rtsp, parser);
  56. case RTSP_GET_PARAMETER: return rtsp_client_get_parameter_onreply(rtsp, parser);
  57. case RTSP_SET_PARAMETER: return rtsp_client_set_parameter_onreply(rtsp, parser);
  58. case RTSP_ANNOUNCE: return rtsp_client_announce_onreply(rtsp, parser);
  59. case RTSP_RECORD: return rtsp_client_record_onreply(rtsp, parser);
  60. default: assert(0); return -1;
  61. }
  62. }
  63. static int rtsp_check_response_line(const char* data, size_t bytes)
  64. {
  65. const char* line = "RTSP/1.0 ";
  66. assert(bytes > 0);
  67. if (bytes >= 9)
  68. bytes = 9;
  69. return strncasecmp(line, data, 9);
  70. }
  71. int rtsp_client_input(struct rtsp_client_t *rtsp, const void* data, size_t bytes)
  72. {
  73. int r;
  74. size_t remain;
  75. const uint8_t* p, *end;
  76. r = 0;
  77. p = (const uint8_t*)data;
  78. end = p + bytes;
  79. do
  80. {
  81. if(rtsp->parser_need_more_data || 0 == rtsp_check_response_line((const char*)p, (size_t)(end - p)))
  82. {
  83. // TODO: server->client Announce (update sdp)
  84. remain = (size_t)(end - p);
  85. r = http_parser_input(rtsp->parser, p, &remain);
  86. rtsp->parser_need_more_data = r;
  87. assert(r <= 2); // 1-need more data
  88. if (0 == r)
  89. {
  90. r = rtsp_client_handle(rtsp, rtsp->parser);
  91. http_parser_clear(rtsp->parser); // reset parser
  92. assert((size_t)remain < bytes);
  93. }
  94. p = end - remain;
  95. }
  96. else
  97. {
  98. //if (0 == rtsp->parser_need_more_data && (*p == '$' || 0 != rtsp->rtp.state))
  99. p = rtp_over_rtsp(&rtsp->rtp, p, end);
  100. }
  101. } while (p < end && r >= 0);
  102. assert(r <= 2);
  103. return r >= 0 ? 0 : r;
  104. }
  105. const char* rtsp_client_get_header(struct rtsp_client_t* rtsp, const char* name)
  106. {
  107. return http_get_header_by_name(rtsp->parser, name);
  108. }
  109. int rtsp_client_media_count(struct rtsp_client_t *rtsp)
  110. {
  111. return rtsp->media_count;
  112. }
  113. const struct rtsp_header_transport_t* rtsp_client_get_media_transport(struct rtsp_client_t *rtsp, int media)
  114. {
  115. if(media < 0 || media >= rtsp->media_count)
  116. return NULL;
  117. return rtsp->transport + media;
  118. }
  119. const struct rtsp_media_t* rtsp_client_get_media(struct rtsp_client_t* rtsp, int media)
  120. {
  121. if (media < 0 || media >= rtsp->media_count)
  122. return NULL;
  123. return rtsp->media + media;
  124. }
  125. const char* rtsp_client_get_media_encoding(struct rtsp_client_t *rtsp, int media)
  126. {
  127. if (media < 0 || media >= rtsp->media_count)
  128. return NULL;
  129. return rtsp->media[media].avformats[0].encoding;
  130. }
  131. const char* rtsp_client_get_media_fmtp(struct rtsp_client_t *rtsp, int media)
  132. {
  133. if (media < 0 || media >= rtsp->media_count)
  134. return NULL;
  135. return rtsp->media[media].avformats[0].fmtp;
  136. }
  137. int rtsp_client_get_media_payload(struct rtsp_client_t *rtsp, int media)
  138. {
  139. if (media < 0 || media >= rtsp->media_count)
  140. return -1;
  141. return rtsp->media[media].avformats[0].fmt;
  142. }
  143. int rtsp_client_get_media_rate(struct rtsp_client_t *rtsp, int media)
  144. {
  145. int rate;
  146. if (media < 0 || media >= rtsp->media_count)
  147. return -1;
  148. rate = rtsp->media[media].avformats[0].rate;
  149. if (0 == rate)
  150. {
  151. const struct rtp_profile_t* profile;
  152. profile = rtp_profile_find(rtsp->media[media].avformats[0].fmt);
  153. rate = profile ? profile->frequency : 0;
  154. }
  155. return rate;
  156. }
  157. int rtsp_client_get_media_type(struct rtsp_client_t* rtsp, int media)
  158. {
  159. if (media < 0 || media >= rtsp->media_count)
  160. return -1;
  161. return sdp_option_media_from(rtsp->media[media].media);
  162. }