|
- #include "rtsp-client.h"
- #include "rtsp-client-internal.h"
- #include "rtp-profile.h"
- #include "sdp.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
-
- #if defined(OS_WINDOWS)
- #define strncasecmp _strnicmp
- #endif
-
- 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)
- {
- struct rtsp_client_t *rtsp;
- rtsp = (struct rtsp_client_t*)calloc(1, sizeof(*rtsp));
- if(NULL == rtsp)
- return NULL;
-
- snprintf(rtsp->uri, sizeof(rtsp->uri) - 1, "%s", uri);
- snprintf(rtsp->usr, sizeof(rtsp->usr) - 1, "%s", usr ? usr : "");
- snprintf(rtsp->pwd, sizeof(rtsp->pwd) - 1, "%s", pwd ? pwd : "");
-
- rtsp->parser = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
- memcpy(&rtsp->handler, handler, sizeof(rtsp->handler));
- rtsp->rtp.onrtp = rtsp->handler.onrtp;
- rtsp->rtp.param = param;
- rtsp->state = RTSP_INIT;
- rtsp->param = param;
- rtsp->cseq = 1;
- rtsp->auth_failed = 0;
-
- return rtsp;
- }
-
- void rtsp_client_destroy(struct rtsp_client_t *rtsp)
- {
- if (rtsp->parser)
- {
- http_parser_destroy(rtsp->parser);
- rtsp->parser = NULL;
- }
-
- if (rtsp->rtp.data)
- {
- assert(rtsp->rtp.capacity > 0);
- free(rtsp->rtp.data);
- rtsp->rtp.data = NULL;
- rtsp->rtp.capacity = 0;
- }
-
- free(rtsp);
- }
-
- static int rtsp_client_handle(struct rtsp_client_t* rtsp, http_parser_t* parser)
- {
- switch (rtsp->state)
- {
- case RTSP_DESCRIBE: return rtsp_client_describe_onreply(rtsp, parser);
- case RTSP_SETUP: return rtsp_client_setup_onreply(rtsp, parser);
- case RTSP_PLAY: return rtsp_client_play_onreply(rtsp, parser);
- case RTSP_PAUSE: return rtsp_client_pause_onreply(rtsp, parser);
- case RTSP_TEARDWON: return rtsp_client_teardown_onreply(rtsp, parser);
- case RTSP_OPTIONS: return rtsp_client_options_onreply(rtsp, parser);
- case RTSP_GET_PARAMETER: return rtsp_client_get_parameter_onreply(rtsp, parser);
- case RTSP_SET_PARAMETER: return rtsp_client_set_parameter_onreply(rtsp, parser);
- case RTSP_ANNOUNCE: return rtsp_client_announce_onreply(rtsp, parser);
- case RTSP_RECORD: return rtsp_client_record_onreply(rtsp, parser);
- default: assert(0); return -1;
- }
- }
-
- static int rtsp_check_response_line(const char* data, size_t bytes)
- {
- const char* line = "RTSP/1.0 ";
- assert(bytes > 0);
- if (bytes >= 9)
- bytes = 9;
- return strncasecmp(line, data, 9);
- }
-
- int rtsp_client_input(struct rtsp_client_t *rtsp, const void* data, size_t bytes)
- {
- int r;
- size_t remain;
- const uint8_t* p, *end;
-
- r = 0;
- p = (const uint8_t*)data;
- end = p + bytes;
-
- do
- {
- if(rtsp->parser_need_more_data || 0 == rtsp_check_response_line((const char*)p, (size_t)(end - p)))
- {
- // TODO: server->client Announce (update sdp)
-
- remain = (size_t)(end - p);
- r = http_parser_input(rtsp->parser, p, &remain);
- rtsp->parser_need_more_data = r;
- assert(r <= 2); // 1-need more data
- if (0 == r)
- {
- r = rtsp_client_handle(rtsp, rtsp->parser);
- http_parser_clear(rtsp->parser); // reset parser
- assert((size_t)remain < bytes);
- }
- p = end - remain;
- }
- else
- {
- //if (0 == rtsp->parser_need_more_data && (*p == '$' || 0 != rtsp->rtp.state))
-
- p = rtp_over_rtsp(&rtsp->rtp, p, end);
- }
- } while (p < end && r >= 0);
-
- assert(r <= 2);
- return r >= 0 ? 0 : r;
- }
-
- const char* rtsp_client_get_header(struct rtsp_client_t* rtsp, const char* name)
- {
- return http_get_header_by_name(rtsp->parser, name);
- }
-
- int rtsp_client_media_count(struct rtsp_client_t *rtsp)
- {
- return rtsp->media_count;
- }
-
- const struct rtsp_header_transport_t* rtsp_client_get_media_transport(struct rtsp_client_t *rtsp, int media)
- {
- if(media < 0 || media >= rtsp->media_count)
- return NULL;
- return rtsp->transport + media;
- }
-
- const struct rtsp_media_t* rtsp_client_get_media(struct rtsp_client_t* rtsp, int media)
- {
- if (media < 0 || media >= rtsp->media_count)
- return NULL;
- return rtsp->media + media;
- }
-
- const char* rtsp_client_get_media_encoding(struct rtsp_client_t *rtsp, int media)
- {
- if (media < 0 || media >= rtsp->media_count)
- return NULL;
- return rtsp->media[media].avformats[0].encoding;
- }
-
- const char* rtsp_client_get_media_fmtp(struct rtsp_client_t *rtsp, int media)
- {
- if (media < 0 || media >= rtsp->media_count)
- return NULL;
- return rtsp->media[media].avformats[0].fmtp;
- }
-
- int rtsp_client_get_media_payload(struct rtsp_client_t *rtsp, int media)
- {
- if (media < 0 || media >= rtsp->media_count)
- return -1;
- return rtsp->media[media].avformats[0].fmt;
- }
-
- int rtsp_client_get_media_rate(struct rtsp_client_t *rtsp, int media)
- {
- int rate;
- if (media < 0 || media >= rtsp->media_count)
- return -1;
-
- rate = rtsp->media[media].avformats[0].rate;
- if (0 == rate)
- {
- const struct rtp_profile_t* profile;
- profile = rtp_profile_find(rtsp->media[media].avformats[0].fmt);
- rate = profile ? profile->frequency : 0;
- }
- return rate;
- }
-
- int rtsp_client_get_media_type(struct rtsp_client_t* rtsp, int media)
- {
- if (media < 0 || media >= rtsp->media_count)
- return -1;
- return sdp_option_media_from(rtsp->media[media].media);
- }
|