📄 player_media.cpp
字号:
*/ int ret = process_rtsp_rtpinfo(decode->rtp_info, m_parent, this); if (ret < 0) { media_message(LOG_ERR, "rtsp rtpinfo failed"); free_decode_response(decode); if (errmsg != NULL) { snprintf(errmsg, errlen, "RTSP aggregate RtpInfo response failure"); } return (-1); } free_decode_response(decode); } if (m_source_addr == NULL) { // get the ip address of the server from the rtsp stack m_source_addr = strdup(inet_ntoa(get_server_ip_address(m_rtsp_session))); media_message(LOG_INFO, "Setting source address from rtsp - %s", m_source_addr); } // ASDF - probably need to do some stuff here for no rtpinfo... /* * set the various play times, and send a message to the recv task * that it needs to start */ m_play_start_time = start_time_offset; } if (m_byte_stream != NULL) { m_byte_stream->play((uint64_t)(start_time_offset * 1000.0)); } m_paused = 0; if (m_rtp_use_rtsp) { rtsp_thread_perform_callback(m_parent->get_rtsp_client(), c_rtp_start, this); } } else { /* * File (or other) playback. */ if (m_paused == 0 || start_time_offset == 0.0) { m_byte_stream->reset(); } m_byte_stream->play((uint64_t)(start_time_offset * 1000.0)); m_play_start_time = start_time_offset; m_paused = 0; start_decoding(); } return (0);}/* * CPlayerMedia::do_pause - stop what we're doing */int CPlayerMedia::do_pause (void){ if (m_streaming != 0) { if (m_stream_ondemand != 0) { /* * streaming - send RTSP pause */ if (m_parent->session_control_is_aggregate() == 0) { rtsp_command_t cmd; rtsp_decode_t *decode; memset(&cmd, 0, sizeof(rtsp_command_t)); if (rtsp_send_pause(m_rtsp_session, &cmd, &decode) != 0) { media_message(LOG_ERR, "RTSP play command failed"); free_decode_response(decode); return (-1); } free_decode_response(decode); } } if (m_recv_thread != NULL) { m_rtp_msg_queue.send_message(MSG_PAUSE_SESSION); } } if (m_byte_stream != NULL) m_byte_stream->pause(); /* * Pause the various threads */ m_decode_msg_queue.send_message(MSG_PAUSE_SESSION, NULL, 0, m_decode_thread_sem); m_paused = 1; return (0);}double CPlayerMedia::get_max_playtime (void) { if (m_byte_stream) { return (m_byte_stream->get_max_playtime()); } return (0.0);}/*************************************************************************** * Transport and RTP-Info RTSP header line parsing. ***************************************************************************/#define ADV_SPACE(a) {while (isspace(*(a)) && (*(a) != '\0'))(a)++;}#define TTYPE(a,b) {a, sizeof(a), b}static char *transport_parse_unicast (char *transport, CPlayerMedia *m){ ADV_SPACE(transport); if (*transport == '\0') return (transport); if (*transport != ';') return (NULL); transport++; ADV_SPACE(transport); return (transport);}static char *transport_parse_multicast (char *transport, CPlayerMedia *m){ media_message(LOG_ERR,"Received multicast indication during SETUP"); return (NULL);}static char *convert_number (char *transport, uint32_t &value){ value = 0; while (isdigit(*transport)) { value *= 10; value += *transport - '0'; transport++; } return (transport);}static char *convert_hex (char *transport, uint32_t &value){ value = 0; while (isxdigit(*transport)) { value *= 16; if (isdigit(*transport)) value += *transport - '0'; else value += tolower(*transport) - 'a' + 10; transport++; } return (transport);}static char *transport_parse_client_port (char *transport, CPlayerMedia *m){ uint32_t port; uint16_t our_port, our_port_max; if (*transport++ != '=') { return (NULL); } ADV_SPACE(transport); transport = convert_number(transport, port); ADV_SPACE(transport); our_port = m->get_our_port(); our_port_max = our_port + 1; if (port != our_port) { media_message(LOG_ERR, "Returned client port %u doesn't match sent %u", port, our_port); return (NULL); } if (*transport == ';') { transport++; return (transport); } if (*transport == '\0') { return (transport); } if (*transport != '-') { return (NULL); } transport++; ADV_SPACE(transport); transport = convert_number(transport, port); if ((port < our_port) || (port > our_port_max)) { media_message(LOG_ERR, "Illegal client to port %u, range %u to %u", port, our_port, our_port_max); return (NULL); } ADV_SPACE(transport); if (*transport == ';') { transport++; } return(transport);}static char *transport_parse_server_port (char *transport, CPlayerMedia *m){ uint32_t fromport, toport; if (*transport++ != '=') { return (NULL); } ADV_SPACE(transport); transport = convert_number(transport, fromport); ADV_SPACE(transport); m->set_server_port((uint16_t)fromport); if (*transport == ';') { transport++; return (transport); } if (*transport == '\0') { return (transport); } if (*transport != '-') { return (NULL); } transport++; ADV_SPACE(transport); transport = convert_number(transport, toport); if (toport < fromport || toport > fromport + 1) { media_message(LOG_ERR, "Illegal server to port %u, from is %u", toport, fromport); return (NULL); } ADV_SPACE(transport); if (*transport == ';') { transport++; } return(transport);}static char *transport_parse_source (char *transport, CPlayerMedia *m){ char *ptr, *newone; uint32_t addrlen; if (*transport != '=') { return (NULL); } transport++; ADV_SPACE(transport); ptr = transport; while (*transport != ';' && *transport != '\0') transport++; addrlen = transport - ptr; if (addrlen == 0) { return (NULL); } newone = (char *)malloc(addrlen + 1); if (newone == NULL) { media_message(LOG_ERR, "Can't alloc memory for transport source"); return (NULL); } strncpy(newone, ptr, addrlen); newone[addrlen] = '\0'; m->set_source_addr(newone); if (*transport == ';') transport++; return (transport);}static char *transport_parse_ssrc (char *transport, CPlayerMedia *m){ uint32_t ssrc; if (*transport != '=') { return (NULL); } transport++; ADV_SPACE(transport); transport = convert_hex(transport, ssrc); ADV_SPACE(transport); if (*transport != '\0') { if (*transport != ';') { return (NULL); } transport++; } m->set_rtp_ssrc(ssrc); return (transport);}static char *transport_parse_interleave (char *transport, CPlayerMedia *m){ uint32_t chan, chan2; if (*transport != '=') { return (NULL); } transport++; ADV_SPACE(transport); transport = convert_number(transport, chan); chan2 = m->get_rtp_media_number() * 2; if (chan != chan2) { media_message(LOG_ERR, "Transport interleave not what was requested %d %d", chan, chan2); return NULL; } ADV_SPACE(transport); if (*transport != '\0') { if (*transport != '-') { return (NULL); } transport++; transport = convert_number(transport, chan2); if (chan + 1 != chan2) { media_message(LOG_ERR, "Error in transport interleaved field"); return (NULL); } if (*transport == '\0') return (transport); } if (*transport != ';') return (NULL); transport++; return (transport);}static char *rtpinfo_parse_ssrc (char *transport, CPlayerMedia *m, int &end){ uint32_t ssrc; if (*transport != '=') { return (NULL); } transport++; ADV_SPACE(transport); transport = convert_hex(transport, ssrc); ADV_SPACE(transport); if (*transport != '\0') { if (*transport == ',') { end = 1; } else if (*transport != ';') { return (NULL); } transport++; } m->set_rtp_ssrc(ssrc); return (transport);}static char *rtpinfo_parse_seq (char *rtpinfo, CPlayerMedia *m, int &endofurl){ uint32_t seq; if (*rtpinfo != '=') { return (NULL); } rtpinfo++; ADV_SPACE(rtpinfo); rtpinfo = convert_number(rtpinfo, seq); ADV_SPACE(rtpinfo); if (*rtpinfo != '\0') { if (*rtpinfo == ',') { endofurl = 1; } else if (*rtpinfo != ';') { return (NULL); } rtpinfo++; } m->set_rtp_base_seq(seq); return (rtpinfo);}static char *rtpinfo_parse_rtptime (char *rtpinfo, CPlayerMedia *m, int &endofurl){ uint32_t rtptime; int neg = 0; if (*rtpinfo != '=') { return (NULL); } rtpinfo++; ADV_SPACE(rtpinfo); if (*rtpinfo == '-') { neg = 1; rtpinfo++; ADV_SPACE(rtpinfo); } rtpinfo = convert_number(rtpinfo, rtptime); ADV_SPACE(rtpinfo); if (*rtpinfo != '\0') { if (*rtpinfo == ',') { endofurl = 1; } else if (*rtpinfo != ';') { return (NULL); } rtpinfo++; } if (neg != 0) { player_error_message("Warning - negative time returned in rtpinfo"); rtptime = 0 - rtptime; } m->set_rtp_base_ts(rtptime); return (rtpinfo);}struct { const char *name; uint32_t namelen; char *(*routine)(char *transport, CPlayerMedia *);} transport_types[] = { TTYPE("unicast", transport_parse_unicast), TTYPE("multicast", transport_parse_multicast), TTYPE("client_port", transport_parse_client_port), TTYPE("server_port", transport_parse_server_port), TTYPE("source", transport_parse_source), TTYPE("ssrc", transport_parse_ssrc), TTYPE("interleaved", transport_parse_interleave), {NULL, 0, NULL},}; int CPlayerMedia::process_rtsp_transport (char *transport){ uint32_t protolen; int ix; if (transport == NULL) return (-1); protolen = strlen(m_media_info->proto); if (strncasecmp(transport, m_media_info->proto, protolen) != 0) { media_message(LOG_ERR, "transport %s doesn't match %s", transport, m_media_info->proto); return (-1); } transport += protolen; if (*transport == '/') { transport++; if (m_rtp_use_rtsp) { if (strncasecmp(transport, "TCP", strlen("TCP")) != 0) { media_message(LOG_ERR, "Transport is not TCP"); return (-1); } transport += strlen("TCP"); } else { if (strncasecmp(transport, "UDP", strlen("UDP")) != 0) { media_message(LOG_ERR, "Transport is not UDP"); return (-1); } transport += strlen("UDP"); } } if (*transport != ';') { return (-1); } transport++; do { ADV_SPACE(transport); for (ix = 0; transport_types[ix].name != NULL; ix++) { if (strncasecmp(transport, transport_types[ix].name, transport_types[ix].namelen - 1) == 0) { transport += transport_types[ix].namelen - 1; ADV_SPACE(transport); transport = (transport_types[ix].routine)(transport, this); break; } } if (transport_types[ix].name == NULL) { media_message(LOG_INFO, "Illegal mime type in transport - skipping %s", transport); while (*transport != ';' && *transport != '\0') transport++; if (*transport != '\0') transport++; } } while (transport != NULL && *transport != '\0'); if (transport == NULL) { return (-1); } return (0);}struct { const char *name; uint32_t namelen; char *(*routine)(char *transport, CPlayerMedia *, int &end_for_url);} rtpinfo_types[] = { TTYPE("seq", rtpinfo_parse_seq), TTYPE("rtptime", rtpinfo_parse_rtptime), TTYPE("ssrc", rtpinfo_parse_ssrc), {NULL, 0, NULL},};int process_rtsp_rtpinfo (char *rtpinfo, CPlayerSession *session, CPlayerMedia *media){ int ix; CPlayerMedia *newmedia; if (rtpinfo == NULL) return (0); do { int no_mimes = 0; ADV_SPACE(rtpinfo); if (strncasecmp(rtpinfo, "url", strlen("url")) != 0) { media_message(LOG_ERR, "Url not found"); return (-1); } rtpinfo += strlen("url"); ADV_SPACE(rtpinfo); if (*rtpinfo != '=') { media_message(LOG_ERR, "Can't find = after url"); return (-1); } rtpinfo++; ADV_SPACE(rtpinfo); char *url = rtpinfo; while (*rtpinfo != '\0' && *rtpinfo != ';' && *rtpinfo != ',') { rtpinfo++; } if (*rtpinfo == '\0') { no_mimes = 1; } else { if (*rtpinfo == ',') { no_mimes = 1; } *rtpinfo++ = '\0'; } char *temp = url; newmedia = session->rtsp_url_to_media(url); if (newmedia == NULL) { media_message(LOG_ERR, "Can't find media from %s", url); return -1; } else if (media != NULL && media != newmedia) { media_message(LOG_ERR, "Url in rtpinfo does not match media %s", url); return -1; } if (temp != url) free(url); if (no_mimes == 0) { int endofurl = 0; do { ADV_SPACE(rtpinfo); for (ix = 0; rtpinfo_types[ix].name != NULL; ix++) { if (strncasecmp(rtpinfo, rtpinfo_types[ix].name, rtpinfo_types[ix].namelen - 1) == 0) { rtpinfo += rtpinfo_types[ix].namelen - 1; ADV_SPACE(rtpinfo); rtpinfo = (rtpinfo_types[ix].routine)(rtpinfo, newmedia, endofurl); break; } } if (rtpinfo_types[ix].name == NULL) {#if 1 media_message(LOG_INFO, "Unknown mime-type in RtpInfo - skipping %s", rtpinfo);#endif while (*rtpinfo != ';' && *rtpinfo != '\0') rtpinfo++; if (*rtpinfo != '\0') rtpinfo++; } } while (endofurl == 0 && rtpinfo != NULL && *rtpinfo != '\0'); } newmedia = NULL; } while (rtpinfo != NULL && *rtpinfo != '\0'); if (rtpinfo == NULL) { return (-1); } return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -