Initial setup for CLion
This commit is contained in:
337
MediaClient/rtsp/rtsp_backchannel.cpp
Normal file
337
MediaClient/rtsp/rtsp_backchannel.cpp
Normal file
@@ -0,0 +1,337 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include "rtsp_backchannel.h"
|
||||
#include "rtsp_rcua.h"
|
||||
#include "rtp.h"
|
||||
#include "rtsp_util.h"
|
||||
#include "base64.h"
|
||||
#include "http_cln.h"
|
||||
#include "media_format.h"
|
||||
#ifdef OVER_WEBSOCKET
|
||||
#include "rtsp_ws.h"
|
||||
#endif
|
||||
|
||||
#ifdef BACKCHANNEL
|
||||
|
||||
/***************************************************************************************/
|
||||
|
||||
/**
|
||||
* Send rtp data by TCP socket
|
||||
*
|
||||
* @param p_rua rtsp user agent
|
||||
* @param p_data rtp data
|
||||
* @param len rtp data len
|
||||
* @return -1 on error, or the data length has been sent
|
||||
*/
|
||||
int rtp_tcp_tx(RCUA * p_rua, uint8 * p_data, int len)
|
||||
{
|
||||
int offset = 0;
|
||||
SOCKET fd;
|
||||
int buflen;
|
||||
char * p_buff;
|
||||
|
||||
#ifdef OVER_HTTP
|
||||
if (p_rua->over_http)
|
||||
{
|
||||
fd = p_rua->rtsp_send.cfd;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef OVER_WEBSOCKET
|
||||
if (p_rua->over_ws)
|
||||
{
|
||||
fd = p_rua->ws_http.cfd;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
fd = p_rua->fd;
|
||||
|
||||
if (fd <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef OVER_HTTP
|
||||
if (p_rua->over_http)
|
||||
{
|
||||
char * tx_buf_base64 = (char *)malloc(2 * len);
|
||||
if (NULL == tx_buf_base64)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == base64_encode(p_data, len, tx_buf_base64, 2 * len))
|
||||
{
|
||||
free(tx_buf_base64);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_buff = tx_buf_base64;
|
||||
buflen = strlen(tx_buf_base64);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef OVER_WEBSOCKET
|
||||
if (p_rua->over_ws)
|
||||
{
|
||||
int extra = rtsp_ws_encode_data(p_data, len, 0x82, 1);
|
||||
|
||||
p_buff = (char *)(p_data - extra);
|
||||
buflen = len + extra;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
p_buff = (char *)p_data;
|
||||
buflen = len;
|
||||
}
|
||||
|
||||
while (offset < buflen)
|
||||
{
|
||||
int tlen;
|
||||
|
||||
#ifdef OVER_HTTP
|
||||
if (p_rua->over_http)
|
||||
{
|
||||
tlen = http_cln_tx(&p_rua->rtsp_send, p_buff+offset, buflen-offset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef OVER_WEBSOCKET
|
||||
if (p_rua->over_ws)
|
||||
{
|
||||
tlen = http_cln_tx(&p_rua->ws_http, p_buff+offset, buflen-offset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
tlen = send(fd, (const char *)p_buff+offset, buflen-offset, 0);
|
||||
if (tlen > 0)
|
||||
{
|
||||
offset += tlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
int sockerr = sys_os_get_socket_error_num();
|
||||
if (sockerr == EINTR || sockerr == EAGAIN)
|
||||
{
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
log_print(HT_LOG_ERR, "%s, send failed, fd[%d], tlen[%d,%d], err[%d][%s]!!!\r\n",
|
||||
__FUNCTION__, fd, tlen, buflen-offset, sockerr, sys_os_get_socket_error());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OVER_HTTP
|
||||
if (p_rua->over_http)
|
||||
{
|
||||
free(p_buff);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (offset == buflen) ? len : -1;
|
||||
}
|
||||
|
||||
|
||||
int rtp_udp_tx(RCUA * p_rua, int av_t, uint8 * p_data, int len)
|
||||
{
|
||||
int slen;
|
||||
SOCKET fd = 0;
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr(p_rua->ripstr);
|
||||
|
||||
if (AV_TYPE_BACKCHANNEL == av_t)
|
||||
{
|
||||
addr.sin_port = htons(p_rua->channels[av_t].r_port);
|
||||
fd = p_rua->channels[av_t].udp_fd;
|
||||
|
||||
if (p_rua->rtp_mcast)
|
||||
{
|
||||
addr.sin_addr.s_addr = inet_addr(p_rua->channels[av_t].destination);
|
||||
}
|
||||
}
|
||||
|
||||
if (fd <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
slen = sendto(fd, (char *)p_data, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||
if (slen != len)
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, slen = %d, len = %d, ip=0x%08x\r\n", __FUNCTION__, slen, len, p_rua->ripstr);
|
||||
}
|
||||
|
||||
return slen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build audio rtp packet and send
|
||||
*
|
||||
* @param p_rua rtsp user agent
|
||||
* @param p_data payload data
|
||||
* @param len payload data length
|
||||
* @ts the packet timestamp
|
||||
* @return the rtp packet length, -1 on error
|
||||
*/
|
||||
int rtp_audio_build(RCUA * p_rua, uint8 * p_data, int len, uint32 ts, int mbit)
|
||||
{
|
||||
int offset = 0;
|
||||
int slen = 0;
|
||||
uint8 * p_rtp_ptr = p_data - 12; // shift forward RTP head
|
||||
|
||||
if (p_rua->rtp_tcp)
|
||||
{
|
||||
p_rtp_ptr -= 4;
|
||||
|
||||
*(p_rtp_ptr+offset) = 0x24; // magic
|
||||
offset++;
|
||||
|
||||
*(p_rtp_ptr+offset) = p_rua->channels[AV_BACK_CH].interleaved; // channel
|
||||
offset++;
|
||||
|
||||
offset += rtp_write_uint16(p_rtp_ptr+offset, 12 + len); // rtp payload length
|
||||
}
|
||||
|
||||
*(p_rtp_ptr+offset) = (RTP_VERSION << 6);
|
||||
offset++;
|
||||
|
||||
*(p_rtp_ptr+offset) = (p_rua->bc_rtp_info.rtp_pt) | ((mbit & 0x01) << 7);
|
||||
offset++;
|
||||
|
||||
offset += rtp_write_uint16(p_rtp_ptr+offset, p_rua->bc_rtp_info.rtp_cnt);
|
||||
|
||||
offset += rtp_write_uint32(p_rtp_ptr+offset, p_rua->bc_rtp_info.rtp_ts);
|
||||
|
||||
offset += rtp_write_uint32(p_rtp_ptr+offset, p_rua->bc_rtp_info.rtp_ssrc);
|
||||
|
||||
if (p_rua->rtp_tcp)
|
||||
{
|
||||
slen = rtp_tcp_tx(p_rua, p_rtp_ptr, offset+len);
|
||||
}
|
||||
else
|
||||
{
|
||||
slen = rtp_udp_tx(p_rua, AV_TYPE_BACKCHANNEL, p_rtp_ptr, offset+len);
|
||||
}
|
||||
|
||||
p_rua->bc_rtp_info.rtp_cnt = (p_rua->bc_rtp_info.rtp_cnt + 1) & 0xFFFF;
|
||||
|
||||
return (slen == offset+len) ? slen : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build audio rtp packet and send (not fragment)
|
||||
*
|
||||
* @param p_rua rtsp user agent
|
||||
* @param p_data payload data
|
||||
* @param len payload data length
|
||||
* @ts the packet timestamp
|
||||
* @return the rtp packet length, -1 on error
|
||||
*/
|
||||
int rtp_audio_tx(RCUA * p_rua, uint8 * p_data, int size, uint32 ts)
|
||||
{
|
||||
return rtp_audio_build(p_rua, p_data, size, ts, 1);
|
||||
}
|
||||
|
||||
int rtp_aac_audio_tx(RCUA * p_rua, uint8 * p_data, int size, uint32 ts)
|
||||
{
|
||||
int ret = 0;
|
||||
int len, max_packet_size, au_size;
|
||||
uint8 *p;
|
||||
|
||||
max_packet_size = RTP_MAX_LEN;
|
||||
|
||||
if (p_data[0] == 0xFF && (p_data[1] & 0xF0) == 0xF0)
|
||||
{
|
||||
// skip ADTS header
|
||||
p_data += 7;
|
||||
size -= 7;
|
||||
}
|
||||
|
||||
p = p_data - 4;
|
||||
au_size = size;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
len = MIN(size, max_packet_size);
|
||||
|
||||
rtp_write_uint16(p, 2 * 8);
|
||||
rtp_write_uint16(&p[2], au_size * 8);
|
||||
|
||||
ret = rtp_audio_build(p_rua, p, len + 4, ts, len == size);
|
||||
if (ret < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
size -= len;
|
||||
p += len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rtsp_bc_cb(uint8 *data, int size, int nbsamples, void *pUserdata)
|
||||
{
|
||||
RCUA * p_rua = (RCUA *)pUserdata;
|
||||
|
||||
if (p_rua->send_bc_data)
|
||||
{
|
||||
uint8 * p_buf = NULL;
|
||||
|
||||
p_buf = (uint8 *)malloc(size + 40);
|
||||
if (p_buf == NULL)
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, malloc failed!!!\r\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 * p_tbuf = p_buf + 40; // shift forword header
|
||||
|
||||
memcpy(p_tbuf, data, size);
|
||||
|
||||
if (AUDIO_CODEC_AAC == p_rua->bc_audio_codec)
|
||||
{
|
||||
rtp_aac_audio_tx(p_rua, p_tbuf, size, rtsp_get_timestamp(nbsamples));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtp_audio_tx(p_rua, p_tbuf, size, rtsp_get_timestamp(nbsamples));
|
||||
}
|
||||
|
||||
free(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void rtsp_bc_cb(uint8 *data, int size, int nbsamples, void *pUserdata)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // BACKCHANNEL
|
||||
|
||||
|
||||
|
||||
37
MediaClient/rtsp/rtsp_backchannel.h
Normal file
37
MediaClient/rtsp/rtsp_backchannel.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef RTSP_BACKCHANNEL_H
|
||||
#define RTSP_BACKCHANNEL_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void rtsp_bc_cb(uint8 * data, int size, int nbsamples, void * pUserdata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
3598
MediaClient/rtsp/rtsp_cln.cpp
Normal file
3598
MediaClient/rtsp/rtsp_cln.cpp
Normal file
File diff suppressed because it is too large
Load Diff
443
MediaClient/rtsp/rtsp_cln.h
Normal file
443
MediaClient/rtsp/rtsp_cln.h
Normal file
@@ -0,0 +1,443 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef RTSP_CLN_H
|
||||
#define RTSP_CLN_H
|
||||
|
||||
#include "sys_buf.h"
|
||||
#include "rtsp_rcua.h"
|
||||
#include "media_format.h"
|
||||
#include "h264_rtp_rx.h"
|
||||
#include "mjpeg_rtp_rx.h"
|
||||
#include "h265_rtp_rx.h"
|
||||
#include "mpeg4_rtp_rx.h"
|
||||
#include "aac_rtp_rx.h"
|
||||
#include "pcm_rtp_rx.h"
|
||||
|
||||
|
||||
typedef int (*notify_cb)(int, void *);
|
||||
typedef int (*video_cb)(uint8 *, int, uint32, uint16, void *);
|
||||
typedef int (*audio_cb)(uint8 *, int, uint32, uint16, void *);
|
||||
typedef int (*rtcp_cb)(uint8 *, int, int, void *);
|
||||
typedef int (*metadata_cb)(uint8 *, int, uint32, uint16, void *);
|
||||
|
||||
|
||||
#define RTSP_EVE_STOPPED 0 // stopped
|
||||
#define RTSP_EVE_CONNECTING 1 // connecting
|
||||
#define RTSP_EVE_CONNFAIL 2 // connect failed
|
||||
#define RTSP_EVE_CONNSUCC 3 // connect success
|
||||
#define RTSP_EVE_NOSIGNAL 4 // no signal
|
||||
#define RTSP_EVE_RESUME 5 // resume
|
||||
#define RTSP_EVE_AUTHFAILED 6 // authentication failed
|
||||
#define RTSP_EVE_NODATA 7 // No data received within the timeout period
|
||||
|
||||
#define RTSP_RX_FAIL -1 // rtsp data receive failed
|
||||
#define RTSP_RX_TIMEOUT 1 // rtsp data receive timeout
|
||||
#define RTSP_RX_SUCC 2 // rtsp data receive success
|
||||
|
||||
#define RTSP_PARSE_FAIL -1 // rtsp message parse failed
|
||||
#define RTSP_PARSE_MOREDATA 0 // need more data to parse rtsp message
|
||||
#define RTSP_PARSE_SUCC 1 // rtsp message parse success
|
||||
|
||||
|
||||
|
||||
class CRtspClient
|
||||
{
|
||||
public:
|
||||
CRtspClient(void);
|
||||
~CRtspClient(void);
|
||||
|
||||
public:
|
||||
BOOL rtsp_start(const char * suffix, const char * ip, int port, const char * user, const char * pass);
|
||||
BOOL rtsp_start(const char * url, const char * user, const char * pass);
|
||||
BOOL rtsp_play(int npt_start = 0);
|
||||
BOOL rtsp_stop();
|
||||
BOOL rtsp_pause();
|
||||
BOOL rtsp_close();
|
||||
|
||||
RCUA * get_rua() {return &m_rua;}
|
||||
char * get_url() {return m_url;}
|
||||
char * get_ip() {return m_ip;}
|
||||
int get_port() {return m_nport;}
|
||||
char * get_user() {return m_rua.auth_info.auth_name;}
|
||||
char * get_pass() {return m_rua.auth_info.auth_pwd;}
|
||||
void set_notify_cb(notify_cb notify, void * userdata);
|
||||
void set_video_cb(video_cb cb);
|
||||
void set_audio_cb(audio_cb cb);
|
||||
void set_metadata_cb(metadata_cb cb);
|
||||
void set_rtcp_cb(rtcp_cb cb);
|
||||
|
||||
/**
|
||||
* @desc : set channel flags
|
||||
* @params :
|
||||
* channel:
|
||||
* AV_VIDEO_CH : video channel
|
||||
* AV_AUDIO_CH : audio channel
|
||||
* AV_METADATA_CH : metadata channel
|
||||
* AV_BACK_CH : audio back channel
|
||||
*
|
||||
* flag : 1 - If the SDP description has the channel information, then SETUP this channel,
|
||||
* 0 - DO NOT SETUP THIS CHANNEL
|
||||
*
|
||||
* note : All channels are setup by default
|
||||
*/
|
||||
void set_channel(int channel, int flag);
|
||||
|
||||
/**
|
||||
* @desc : Set rtp multicast
|
||||
* @params :
|
||||
* flag : 1 - enable rtp multcast, 0 - disable rtp multcast
|
||||
*/
|
||||
void set_rtp_multicast(int flag);
|
||||
|
||||
/**
|
||||
* @desc : Set rtp over udp
|
||||
* @params :
|
||||
* flag : 1 - enable rtp over udp, 0 - disable rtp over udp
|
||||
*/
|
||||
void set_rtp_over_udp(int flag);
|
||||
|
||||
/**
|
||||
* @desc : Set rtsp over http
|
||||
* @params :
|
||||
* flag : 1 - enable rtsp over http, 0 - disable rtsp over http
|
||||
* port : if flag = 1, specify the http port
|
||||
*/
|
||||
void set_rtsp_over_http(int flag, int port);
|
||||
|
||||
/**
|
||||
* @desc : Set rtsp over websocket
|
||||
* @params :
|
||||
* flag : 1 - enable rtsp over websocket, 0 - disable rtsp over websocket
|
||||
* ws_uri : if flag = 1, specify the websocket port
|
||||
*/
|
||||
void set_rtsp_over_ws(int flag, int port);
|
||||
|
||||
/**
|
||||
* @desc : Set the data rx timeout, if the data is not received within the specified time,
|
||||
* send RTSP_EVE_NODATA notification
|
||||
* @params :
|
||||
* timeout : Timeout value, unit is second
|
||||
*/
|
||||
void set_rx_timeout(int timeout);
|
||||
|
||||
/**
|
||||
* @desc : Set the connect timeout
|
||||
* @params :
|
||||
* timeout : Timeout value, unit is second
|
||||
*/
|
||||
void set_conn_timeout(int timeout);
|
||||
|
||||
/**
|
||||
* @desc : Get H264, SPS, PPS parameters, and return through the video callback function
|
||||
*/
|
||||
void get_h264_params();
|
||||
|
||||
/**
|
||||
* @desc : Get H264, SPS, PPS parameters
|
||||
* @params
|
||||
* p_sps : Receive H264 SPS data, the buffer size is not less than 256
|
||||
* sps_len : Receive H264 SPS buffer length
|
||||
* p_pps : Receive H264 PPS data, the buffer size is not less than 256
|
||||
* pps_len : Receive H264 PPS buffer length
|
||||
*/
|
||||
BOOL get_h264_params(uint8 * p_sps, int * sps_len, uint8 * p_pps, int * pps_len);
|
||||
|
||||
/**
|
||||
* @desc : Get H265, VPS, SPS, PPS parameters, and return through the video callback function
|
||||
*/
|
||||
void get_h265_params();
|
||||
|
||||
/**
|
||||
* @desc : Get H265, VPS, SPS, PPS parameters
|
||||
* @params
|
||||
* p_sps : Receive H264 SPS data, the buffer size is not less than 256
|
||||
* sps_len : Receive H264 SPS buffer length
|
||||
* p_pps : Receive H264 PPS data, the buffer size is not less than 256
|
||||
* pps_len : Receive H264 PPS buffer length
|
||||
* p_vps : Receive H264 VPS data, the buffer size is not less than 256
|
||||
* vps_len : Receive H264 VPS buffer length
|
||||
*/
|
||||
BOOL get_h265_params(uint8 * p_sps, int * sps_len, uint8 * p_pps, int * pps_len, uint8 * p_vps, int * vps_len);
|
||||
|
||||
/**
|
||||
* @desc : If the describe request response returned by the server has an H264 SDP description, get the H264 SDP description
|
||||
* @params
|
||||
* p_sdp : Receive H264 SDP description
|
||||
* max_len : Maximum length of buffer p_sdp
|
||||
*/
|
||||
BOOL get_h264_sdp_desc(char * p_sdp, int max_len);
|
||||
|
||||
/**
|
||||
* @desc : If the describe request response returned by the server has an H265 SDP description, get the H265 SDP description
|
||||
* @params
|
||||
* p_sdp : Receive H265 SDP description
|
||||
* max_len : Maximum length of buffer p_sdp
|
||||
*/
|
||||
BOOL get_h265_sdp_desc(char * p_sdp, int max_len);
|
||||
|
||||
/**
|
||||
* @desc : If the describe request response returned by the server has an H265 SDP description, get the MP4 SDP description
|
||||
* @params
|
||||
* p_sdp : Receive MP4 SDP description
|
||||
* max_len : Maximum length of buffer p_sdp
|
||||
*/
|
||||
BOOL get_mp4_sdp_desc(char * p_sdp, int max_len);
|
||||
|
||||
/**
|
||||
* @desc : If the describe request response returned by the server has an H265 SDP description, get the AAC SDP description
|
||||
* @params
|
||||
* p_sdp : Receive AAC SDP description
|
||||
* max_len : Maximum length of buffer p_sdp
|
||||
*/
|
||||
BOOL get_aac_sdp_desc(char * p_sdp, int max_len);
|
||||
|
||||
/**
|
||||
* @desc : Get video codec
|
||||
* @retrun : reference the media_format.h, VIDEO_CODEC_H264, ...
|
||||
*/
|
||||
int audio_codec() {return m_rua.audio_codec;}
|
||||
|
||||
/**
|
||||
* @desc : Get audio codec
|
||||
* @retrun : reference the media_format.h, AUDIO_CODEC_AAC, ...
|
||||
*/
|
||||
int video_codec() {return m_rua.video_codec;}
|
||||
|
||||
/**
|
||||
* @desc : Get audio sample rate
|
||||
*/
|
||||
int get_audio_samplerate() {return m_rua.sample_rate;}
|
||||
|
||||
/**
|
||||
* @desc : Get audio channel numbers
|
||||
*/
|
||||
int get_audio_channels() {return m_rua.audio_channels;}
|
||||
|
||||
/**
|
||||
* @desc : Get audio bits per sample, for G726 decoder
|
||||
*/
|
||||
int get_audio_bitpersample() {return m_rua.bit_per_sample;}
|
||||
|
||||
/**
|
||||
* @desc : Get audio config data, for AAC
|
||||
*/
|
||||
uint8 * get_audio_config() {return m_rua.audio_spec;}
|
||||
|
||||
/**
|
||||
* @desc : Get audio config data length, for AAC
|
||||
*/
|
||||
int get_audio_config_len() {return m_rua.audio_spec_len;}
|
||||
|
||||
/**
|
||||
* @desc : get the audio backchannel flag
|
||||
*/
|
||||
int get_bc_flag();
|
||||
|
||||
/**
|
||||
* @desc : set the audio backchannel flag
|
||||
* @params
|
||||
* flag : 1 - enable audio backchannel; 0 - disable audio backchannel
|
||||
*/
|
||||
void set_bc_flag(int flag);
|
||||
|
||||
/**
|
||||
* @desc : get the audio backchannel data sending flag
|
||||
*/
|
||||
int get_bc_data_flag();
|
||||
|
||||
/**
|
||||
* @desc : set the audio backchannel data sending flag
|
||||
* @params
|
||||
* flag : 1 - enable audio backchannel data sending; 0 - disable audio backchannel data sending
|
||||
*/
|
||||
void set_bc_data_flag(int flag);
|
||||
|
||||
/**
|
||||
* @desc : set the audio backchannel audio capture device index
|
||||
* @params
|
||||
* index : audio capture device index
|
||||
*/
|
||||
void set_audio_device(int index);
|
||||
|
||||
/**
|
||||
* @desc : get the replay flag
|
||||
*/
|
||||
int get_replay_flag();
|
||||
|
||||
/**
|
||||
* @desc : set the replay flag
|
||||
* @params
|
||||
* flag : 1 - enable replay; 0 - disable replay
|
||||
*/
|
||||
void set_replay_flag(int flag);
|
||||
|
||||
/**
|
||||
* @desc : set the scale info
|
||||
* @params
|
||||
* scale : when not set the rata control flag, the scale is valid.
|
||||
* It shall be either 1.0 or -1.0, to indicate forward or reverse playback respectively.
|
||||
* If it is not present, forward playback is assumed
|
||||
*/
|
||||
void set_scale(double scale);
|
||||
|
||||
/**
|
||||
* @desc : set the rate control flag
|
||||
* @params
|
||||
* flag :
|
||||
* 1-the stream is delivered in real time using standard RTP timing mechanisms
|
||||
* 0-the stream is delivered as fast as possible, using only the flow control provided by the transport to limit the delivery rate
|
||||
*/
|
||||
void set_rate_control_flag(int flag);
|
||||
|
||||
/**
|
||||
* @desc : set the immediate flag
|
||||
* @params
|
||||
* flag :
|
||||
* 1 - immediately start playing from the new location, cancelling any existing PLAY command.
|
||||
* The first packet sent from the new location shall have the D (discontinuity) bit set in its RTP extension header.
|
||||
*/
|
||||
void set_immediate_flag(int flag);
|
||||
|
||||
/**
|
||||
* @desc : set the frame flag
|
||||
* @params
|
||||
* flag :
|
||||
* 0 - all frames
|
||||
* 1 - I-frame and P-frame
|
||||
* 2 - I-frame
|
||||
* interval :
|
||||
* when flag = 2, set the I-frame interval
|
||||
*/
|
||||
void set_frames_flag(int flag, int interval);
|
||||
|
||||
/**
|
||||
* @desc : set replay range
|
||||
* @params
|
||||
* start : the replay start timestamp
|
||||
* end : the replay end timestamp
|
||||
*/
|
||||
void set_replay_range(time_t start, time_t end);
|
||||
|
||||
void tcp_rx_thread();
|
||||
void udp_rx_thread();
|
||||
void rtsp_video_data_cb(uint8 * p_data, int len, uint32 ts, uint32 seq);
|
||||
void rtsp_audio_data_cb(uint8 * p_data, int len, uint32 ts, uint32 seq);
|
||||
void rtsp_meta_data_cb(uint8 * p_data, int len, uint32 ts, uint32 seq);
|
||||
|
||||
private:
|
||||
void set_default();
|
||||
BOOL rtsp_client_start();
|
||||
void rtsp_client_stop(RCUA * p_rua);
|
||||
BOOL rtsp_client_state(RCUA * p_rua, HRTSP_MSG * rx_msg);
|
||||
int rtsp_epoll_rx();
|
||||
int rtsp_tcp_data_rx(RCUA * p_rua);
|
||||
int rtsp_over_tcp_rx(RCUA * p_rua);
|
||||
int rtsp_tcp_rx();
|
||||
int rtsp_udp_rx();
|
||||
int rtsp_msg_parser(RCUA * p_rua);
|
||||
void rtsp_keep_alive();
|
||||
BOOL rtsp_setup_channel(RCUA * p_rua, int av_t);
|
||||
|
||||
BOOL make_prepare_play();
|
||||
BOOL rtsp_unauth_res(RCUA * p_rua, HRTSP_MSG * rx_msg);
|
||||
BOOL rtsp_options_res(RCUA * p_rua, HRTSP_MSG * rx_msg);
|
||||
BOOL rtsp_describe_res(RCUA * p_rua, HRTSP_MSG * rx_msg);
|
||||
BOOL rtsp_setup_res(RCUA * p_rua, HRTSP_MSG * rx_msg, int av_t);
|
||||
BOOL rtsp_play_res(RCUA * p_rua, HRTSP_MSG * rx_msg);
|
||||
|
||||
BOOL rtsp_init_backchannel(RCUA * p_rua);
|
||||
BOOL rtsp_get_bc_media_info();
|
||||
|
||||
void send_notify(int event);
|
||||
|
||||
BOOL rtsp_get_transport_info(RCUA * p_rua, HRTSP_MSG * rx_msg, int av_type);
|
||||
void rtsp_get_video_size(int * w, int * h);
|
||||
BOOL rtsp_get_video_media_info();
|
||||
BOOL rtsp_get_audio_media_info();
|
||||
|
||||
void tcp_data_rx(uint8 * lpData, int rlen);
|
||||
void udp_data_rx(uint8 * lpData, int rlen, int type);
|
||||
void rtcp_data_rx(uint8 * lpData, int rlen, int type);
|
||||
|
||||
void rtsp_send_h264_params(RCUA * p_rua);
|
||||
void rtsp_send_h265_params(RCUA * p_rua);
|
||||
void rtsp_get_mpeg4_config(RCUA * p_rua);
|
||||
void rtsp_get_aac_config(RCUA * p_rua);
|
||||
|
||||
int rtsp_build_http_get_req(void * p_user, char * bufs, int buflen, char * cookie);
|
||||
int rtsp_build_http_post_req(void * p_user, char * bufs, int buflen, char * cookie);
|
||||
BOOL rtsp_over_http_start();
|
||||
int rtsp_over_http_rx(RCUA * p_rua);
|
||||
|
||||
int rtsp_build_ws_req(void * p_user, char * bufs, int buflen);
|
||||
BOOL rtsp_over_ws_start();
|
||||
BOOL rtsp_ws_ping_process(RCUA * p_rua, char * p_buff, int len);
|
||||
BOOL rtsp_ws_rtsp_process(RCUA * p_rua, char * p_buff, int len);
|
||||
BOOL rtsp_ws_data_process(RCUA * p_rua);
|
||||
int rtsp_over_ws_rx(RCUA * p_rua);
|
||||
|
||||
private:
|
||||
RCUA m_rua;
|
||||
char m_url[256];
|
||||
char m_ip[128];
|
||||
char m_suffix[128];
|
||||
int m_nport;
|
||||
|
||||
int m_ep_fd;
|
||||
struct epoll_event * m_ep_events;
|
||||
int m_ep_event_num;
|
||||
|
||||
notify_cb m_pNotify;
|
||||
void * m_pUserdata;
|
||||
video_cb m_pVideoCB;
|
||||
audio_cb m_pAudioCB;
|
||||
rtcp_cb m_pRtcpCB;
|
||||
metadata_cb m_pMetadataCB;
|
||||
void * m_pMutex;
|
||||
int m_nRxTimeout;
|
||||
int m_nConnTimeout;
|
||||
int m_nWidth;
|
||||
int m_nHeight;
|
||||
|
||||
union {
|
||||
H264RXI h264rxi;
|
||||
H265RXI h265rxi;
|
||||
MJPEGRXI mjpegrxi;
|
||||
MPEG4RXI mpeg4rxi;
|
||||
};
|
||||
|
||||
union {
|
||||
AACRXI aacrxi;
|
||||
PCMRXI pcmrxi;
|
||||
};
|
||||
|
||||
PCMRXI metadatarxi;
|
||||
|
||||
BOOL m_bRunning;
|
||||
pthread_t m_tcpRxTid;
|
||||
pthread_t m_udpRxTid;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // RTSP_CLN_H
|
||||
|
||||
|
||||
|
||||
1839
MediaClient/rtsp/rtsp_parse.cpp
Normal file
1839
MediaClient/rtsp/rtsp_parse.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
MediaClient/rtsp/rtsp_parse.h
Normal file
152
MediaClient/rtsp/rtsp_parse.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef _RTSP_PARSE_H
|
||||
#define _RTSP_PARSE_H
|
||||
|
||||
#include "sys_inc.h"
|
||||
|
||||
/*************************************************************************/
|
||||
typedef enum rtsp_req_mt
|
||||
{
|
||||
RTSP_MT_NULL = 0,
|
||||
RTSP_MT_DESCRIBE,
|
||||
RTSP_MT_ANNOUNCE,
|
||||
RTSP_MT_OPTIONS,
|
||||
RTSP_MT_PAUSE,
|
||||
RTSP_MT_PLAY,
|
||||
RTSP_MT_RECORD,
|
||||
RTSP_MT_REDIRECT,
|
||||
RTSP_MT_SETUP,
|
||||
RTSP_MT_SET_PARAMETER,
|
||||
RTSP_MT_GET_PARAMETER,
|
||||
RTSP_MT_TEARDOWN
|
||||
} RTSP_RMT;
|
||||
|
||||
typedef struct rtsp_req_message_type_value
|
||||
{
|
||||
RTSP_RMT msg_type;
|
||||
char msg_str[32];
|
||||
int msg_len;
|
||||
} RREQMTV;
|
||||
|
||||
typedef enum rtsp_context_type
|
||||
{
|
||||
RTSP_CTX_NULL = 0,
|
||||
RTSP_CTX_RTSP,
|
||||
RTSP_CTX_SDP,
|
||||
RTSP_CTX_TXT,
|
||||
RTSP_CTX_HTM,
|
||||
} RTSPCTXT;
|
||||
|
||||
typedef struct hrtsp_msg_content
|
||||
{
|
||||
uint32 msg_type; // message type : 0 represents a request, 1 represents a response
|
||||
uint32 msg_sub_type; // message sub type
|
||||
HDRV first_line;
|
||||
|
||||
PPSN_CTX rtsp_ctx;
|
||||
PPSN_CTX sdp_ctx;
|
||||
|
||||
int rtsp_len;
|
||||
int sdp_len;
|
||||
|
||||
RTSPCTXT ctx_type;
|
||||
int ctx_len;
|
||||
|
||||
char * msg_buf;
|
||||
int buf_offset;
|
||||
|
||||
uint32 remote_ip;
|
||||
uint16 remote_port;
|
||||
uint16 local_port;
|
||||
}HRTSP_MSG;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
BOOL rtsp_is_rtsp_msg(char * msg_buf);
|
||||
void rtsp_headl_parse(char * pline, int llen, HRTSP_MSG * p_msg);
|
||||
int rtsp_line_parse(char * p_buf, int max_len, char sep_char, PPSN_CTX * p_ctx);
|
||||
int rtsp_ctx_parse(HRTSP_MSG * p_msg);
|
||||
int rtsp_msg_parse(char * msg_buf, int msg_buf_len, HRTSP_MSG * msg);
|
||||
int rtsp_msg_parse_part1(char * p_buf, int buf_len, HRTSP_MSG * msg);
|
||||
int rtsp_msg_parse_part2(char * p_buf, int buf_len, HRTSP_MSG * msg);
|
||||
|
||||
/*************************************************************************/
|
||||
HDRV * rtsp_find_headline(HRTSP_MSG * msg, const char * head);
|
||||
HDRV * rtsp_find_headline_next(HRTSP_MSG * msg, const char * head, HDRV * hrv);
|
||||
HDRV * rtsp_find_sdp_headline(HRTSP_MSG * msg, const char * head);
|
||||
BOOL rtsp_msg_with_sdp(HRTSP_MSG * msg);
|
||||
BOOL rtsp_match_msg_session(HRTSP_MSG * rx_msg, HRTSP_MSG * tx_msg);
|
||||
BOOL rtsp_match_msg_cseq(HRTSP_MSG * rx_msg, HRTSP_MSG * tx_msg);
|
||||
BOOL rtsp_get_headline_uri(HRTSP_MSG * rx_msg, char * p_uri, int size);
|
||||
BOOL rtsp_get_headline_string(HRTSP_MSG * rx_msg, const char * head, char * p_value, int size);
|
||||
BOOL rtsp_get_msg_session(HRTSP_MSG * rx_msg, char *session_buf, int len);
|
||||
BOOL rtsp_get_msg_cseq(HRTSP_MSG * rx_msg, char *cseq_buf, int len);
|
||||
BOOL rtsp_get_user_agent_info(HRTSP_MSG * rx_msg, char * agent_buf, int max_len);
|
||||
BOOL rtsp_get_session_info(HRTSP_MSG * rx_msg, char * session_buf, int max_len, int * timeout);
|
||||
BOOL rtsp_get_rtp_info(HRTSP_MSG * rx_msg, char * v_ctl, uint32 * p_v_ts, char * a_ctl, uint32 * p_a_ts);
|
||||
BOOL rtsp_get_tcp_transport_info(HRTSP_MSG * rx_msg, uint16 *interleaved);
|
||||
BOOL rtsp_get_udp_transport_info(HRTSP_MSG * rx_msg, uint16 *client_port, uint16 *server_port);
|
||||
BOOL rtsp_get_mc_transport_info(HRTSP_MSG * rx_msg, char *destination, uint16 *port);
|
||||
BOOL rtsp_get_cbase_info(HRTSP_MSG * rx_msg, char * cbase_buf, int max_len);
|
||||
BOOL rtsp_get_digest_info(HRTSP_MSG * rx_msg, HD_AUTH_INFO * auth_info);
|
||||
BOOL rtsp_get_auth_digest_info(HRTSP_MSG * rx_msg, HD_AUTH_INFO * p_auth);
|
||||
BOOL rtsp_is_line_exist(HRTSP_MSG * rx_msg, const char * head, const char * value);
|
||||
void rtsp_add_tx_msg_line(HRTSP_MSG * tx_msg, const char * msg_hdr, const char * msg_fmt, ...);
|
||||
void rtsp_add_tx_msg_sdp_line(HRTSP_MSG * tx_msg, const char * msg_hdr, const char * msg_fmt, ...);
|
||||
void rtsp_add_tx_msg_fline(HRTSP_MSG * tx_msg, const char * msg_hdr, const char * msg_fmt, ...);
|
||||
void rtsp_copy_msg_line(HRTSP_MSG * src_msg, HRTSP_MSG * dst_msg, const char * msg_hdr);
|
||||
void rtsp_free_msg(HRTSP_MSG * msg);
|
||||
void rtsp_free_msg_content(HRTSP_MSG * msg);
|
||||
|
||||
/*************************************************************************/
|
||||
BOOL rtsp_get_remote_media_ip(HRTSP_MSG * rx_msg, uint32 * media_ip);
|
||||
HDRV * rtsp_find_mdesc_point(HRTSP_MSG * rx_msg, HDRV * pStartHdr, const char * cap_name, int * next_offset, const char * attr=NULL);
|
||||
BOOL rtsp_get_remote_cap(HRTSP_MSG * rx_msg, const char * cap_name, int * cap_count, uint8 * cap_array, uint16 * rtp_port, const char * attr=NULL);
|
||||
BOOL rtsp_get_remote_cap_desc(HRTSP_MSG * rx_msg, const char * cap_name, char cap_desc[][MAX_AVDESCLEN], const char * attr=NULL);
|
||||
BOOL rtsp_find_sdp_control(HRTSP_MSG * rx_msg, char * ctl_buf, const char * tname, int max_len, const char *attr = NULL);
|
||||
BOOL rtsp_get_sdp_range(HRTSP_MSG * rx_msg, int * p_start, int * p_end);
|
||||
BOOL rtsp_is_support_mcast(HRTSP_MSG * rx_msg);
|
||||
BOOL rtsp_get_scale_info(HRTSP_MSG * rx_msg, int * p_scale);
|
||||
BOOL rtsp_get_rate_control(HRTSP_MSG * rx_msg, int * p_ratectrl);
|
||||
BOOL rtsp_get_immediate(HRTSP_MSG * rx_msg, int * p_imme);
|
||||
BOOL rtsp_get_frame_info(HRTSP_MSG * rx_msg, int * p_frame, int * p_interval);
|
||||
|
||||
/*************************************************************************/
|
||||
BOOL rtsp_msg_buf_init(int num);
|
||||
void rtsp_msg_buf_deinit();
|
||||
HRTSP_MSG * rtsp_get_msg_buf();
|
||||
void rtsp_msg_ctx_init(HRTSP_MSG * msg);
|
||||
void rtsp_free_msg_buf(HRTSP_MSG * msg);
|
||||
uint32 rtsp_idle_msg_buf_num();
|
||||
BOOL rtsp_parse_buf_init(int nums);
|
||||
void rtsp_parse_buf_deinit();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _RTSP_PARSE_H
|
||||
|
||||
|
||||
1074
MediaClient/rtsp/rtsp_rcua.cpp
Normal file
1074
MediaClient/rtsp/rtsp_rcua.cpp
Normal file
File diff suppressed because it is too large
Load Diff
243
MediaClient/rtsp/rtsp_rcua.h
Normal file
243
MediaClient/rtsp/rtsp_rcua.h
Normal file
@@ -0,0 +1,243 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef RTSP_RCUA_H
|
||||
#define RTSP_RCUA_H
|
||||
|
||||
#include "rtsp_parse.h"
|
||||
#include "http.h"
|
||||
|
||||
#ifdef BACKCHANNEL
|
||||
#include "audio_capture.h"
|
||||
#endif
|
||||
|
||||
#ifdef OVER_WEBSOCKET
|
||||
#include "rtsp_ws.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define AV_TYPE_VIDEO 0
|
||||
#define AV_TYPE_AUDIO 1
|
||||
#define AV_TYPE_METADATA 2
|
||||
#define AV_TYPE_BACKCHANNEL 3
|
||||
|
||||
#define AV_MAX_CHS 4
|
||||
|
||||
#define AV_VIDEO_CH AV_TYPE_VIDEO
|
||||
#define AV_AUDIO_CH AV_TYPE_AUDIO
|
||||
#define AV_METADATA_CH AV_TYPE_METADATA
|
||||
#define AV_BACK_CH AV_TYPE_BACKCHANNEL
|
||||
|
||||
/**
|
||||
* RTSP over websocket needs to reserve some space
|
||||
* in the header of the send buffer
|
||||
*/
|
||||
#define RTSP_SND_RESV_SIZE 32
|
||||
|
||||
typedef enum rtsp_client_states
|
||||
{
|
||||
RCS_NULL = 0,
|
||||
RCS_OPTIONS,
|
||||
RCS_DESCRIBE,
|
||||
RCS_INIT_V,
|
||||
RCS_INIT_A,
|
||||
RCS_INIT_M,
|
||||
RCS_INIT_BC,
|
||||
RCS_READY,
|
||||
RCS_PLAYING,
|
||||
RCS_RECORDING,
|
||||
} RCSTATE;
|
||||
|
||||
typedef struct rtsp_client_media_channel
|
||||
{
|
||||
int disabled; // not setup this channel
|
||||
SOCKET udp_fd; // udp socket
|
||||
SOCKET rtcp_fd; // rtcp udp socket
|
||||
char ctl[128]; // control string
|
||||
uint16 setup; // whether the media channel already be setuped
|
||||
uint16 r_port; // remote udp port
|
||||
uint16 l_port; // local udp port
|
||||
uint16 interleaved; // rtp channel values
|
||||
char destination[32]; // multicast address
|
||||
int cap_count; // Local number of capabilities
|
||||
uint8 cap[MAX_AVN]; // Local capability
|
||||
char cap_desc[MAX_AVN][MAX_AVDESCLEN];
|
||||
} RCMCH;
|
||||
|
||||
typedef struct rtsp_client_user_agent
|
||||
{
|
||||
uint32 used_flag : 1; // used flag
|
||||
uint32 rtp_tcp : 1; // rtp over tcp
|
||||
uint32 mcast_flag : 1; // use rtp multicast, set by user
|
||||
uint32 rtp_mcast : 1; // use rtp multicast, set by stack
|
||||
uint32 rtp_tx : 1; // rtp sending flag
|
||||
uint32 need_auth : 1; // need auth flag
|
||||
uint32 auth_mode : 2; // 0 - baisc; 1 - digest
|
||||
uint32 gp_cmd : 1; // is support get_parameter command
|
||||
uint32 backchannel : 1; // audio backchannle flag
|
||||
uint32 send_bc_data: 1; // audio backchannel data sending flag
|
||||
uint32 replay : 1; // replay flag
|
||||
uint32 over_http : 1; // rtsp over http flag
|
||||
uint32 over_ws : 1; // rtsp over websocket flag
|
||||
uint32 auth_retry : 3; // auth retry numbers
|
||||
uint32 reserved : 15;
|
||||
|
||||
int state; // state, RCSTATE
|
||||
SOCKET fd; // socket handler
|
||||
uint32 keepalive_time; // keepalive time
|
||||
|
||||
char ripstr[128]; // remote ip
|
||||
uint16 rport; // rtsp server port
|
||||
|
||||
uint32 cseq; // seq no
|
||||
char sid[64]; // Session ID
|
||||
char uri[256]; // rtsp://221.10.50.195:554/cctv.sdp
|
||||
char cbase[256]; // Content-Base: rtsp://221.10.50.195:554/broadcast.sdp/
|
||||
char user_agent[64]; // user agent string
|
||||
int session_timeout; // session timeout value
|
||||
int play_start; // a=range:npt=0-20.735, unit is millisecond
|
||||
int play_end; // a=range:npt=0-20.735, unit is millisecond
|
||||
uint32 video_init_ts; // video init timestampe
|
||||
uint32 audio_init_ts; // audio init timestampe
|
||||
int seek_pos; // seek pos
|
||||
int media_start; // media start time, unit is millisecond
|
||||
|
||||
char rcv_buf[2052]; // receive buffer
|
||||
int rcv_dlen; // receive data length
|
||||
int rtp_t_len; // rtp payload total length
|
||||
int rtp_rcv_len; // rtp payload receive length
|
||||
char * rtp_rcv_buf; // rtp payload receive buffer
|
||||
|
||||
RCMCH channels[AV_MAX_CHS]; // media channels
|
||||
|
||||
HD_AUTH_INFO auth_info; // auth information
|
||||
|
||||
int video_codec; // video codec
|
||||
|
||||
int audio_codec; // audio codec
|
||||
int sample_rate; // audio sample rate
|
||||
int audio_channels; // audio channels
|
||||
int bit_per_sample; // audio bit per sample
|
||||
|
||||
uint8 * audio_spec; // audio special data, for AAC etc.
|
||||
uint32 audio_spec_len; // audio special data length
|
||||
|
||||
#ifdef BACKCHANNEL
|
||||
int bc_audio_device; // back channel audio device index, start from 0
|
||||
int bc_audio_codec; // back channel audio codec
|
||||
int bc_sample_rate; // back channel sample rate
|
||||
int bc_channels; // back channel channel numbers
|
||||
int bc_bit_per_sample; // back channel bit per sample
|
||||
UA_RTP_INFO bc_rtp_info; // back channel audio rtp info
|
||||
CAudioCapture * audio_captrue; // audio capture
|
||||
#endif
|
||||
|
||||
#ifdef REPLAY
|
||||
uint32 scale_flag : 1;
|
||||
uint32 rate_control_flag : 1;
|
||||
uint32 immediate_flag : 1;
|
||||
uint32 frame_flag : 1;
|
||||
uint32 frame_interval_flag : 1;
|
||||
uint32 range_flag : 1;
|
||||
uint32 replay_reserved : 26;
|
||||
|
||||
int scale; // scale info, when not set the rata control flag, the scale is valid.
|
||||
// It shall be either 100.0 or -100.0, to indicate forward or reverse playback respectively.
|
||||
// If it is not present, forward playback is assumed
|
||||
// 100 means 1.0, Divide by 100 when using
|
||||
int rate_control; // rate control flag,
|
||||
// 1-the stream is delivered in real time using standard RTP timing mechanisms
|
||||
// 0-the stream is delivered as fast as possible, using only the flow control provided by the transport to limit the delivery rate
|
||||
int immediate; // 1 - immediately start playing from the new location, cancelling any existing PLAY command.
|
||||
// The first packet sent from the new location shall have the D (discontinuity) bit set in its RTP extension header.
|
||||
int frame; // 0 - all frames
|
||||
// 1 - I-frame and P-frame
|
||||
// 2 - I-frame
|
||||
int frame_interval; // I-frame interval, unit is milliseconds
|
||||
time_t replay_start; // replay start time
|
||||
time_t replay_end; // replay end time
|
||||
#endif
|
||||
|
||||
#ifdef OVER_HTTP
|
||||
uint16 http_port; // rtsp over http port
|
||||
HTTPREQ rtsp_send; // rtsp over http get connection
|
||||
HTTPREQ rtsp_recv; // rtsp over http post connection
|
||||
#endif
|
||||
|
||||
#ifdef OVER_WEBSOCKET
|
||||
uint16 ws_port; // rtsp over websocket port
|
||||
HTTPREQ ws_http; // rtsp over websocket connection
|
||||
WSMSG ws_msg; // rtsp over websocket message handler
|
||||
#endif
|
||||
} RCUA;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
HRTSP_MSG * rcua_build_describe(RCUA * p_rua);
|
||||
HRTSP_MSG * rcua_build_setup(RCUA * p_rua,int type);
|
||||
HRTSP_MSG * rcua_build_play(RCUA * p_rua);
|
||||
HRTSP_MSG * rcua_build_pause(RCUA * p_rua);
|
||||
HRTSP_MSG * rcua_build_teardown(RCUA * p_rua);
|
||||
HRTSP_MSG * rcua_build_get_parameter(RCUA * p_rua);
|
||||
HRTSP_MSG * rcua_build_options(RCUA * p_rua);
|
||||
|
||||
/*************************************************************************/
|
||||
BOOL rcua_get_media_info(RCUA * p_rua, HRTSP_MSG * rx_msg);
|
||||
|
||||
BOOL rcua_get_sdp_video_desc(RCUA * p_rua, const char * key, int * pt, char * p_sdp, int max_len);
|
||||
BOOL rcua_get_sdp_audio_desc(RCUA * p_rua, const char * key, int * pt, char * p_sdp, int max_len);
|
||||
|
||||
BOOL rcua_get_sdp_h264_desc(RCUA * p_rua, int * pt, char * p_sdp, int max_len);
|
||||
BOOL rcua_get_sdp_h264_params(RCUA * p_rua, int * pt, char * p_sps_pps, int max_len);
|
||||
|
||||
BOOL rcua_get_sdp_h265_desc(RCUA * p_rua, int * pt, char * p_sdp, int max_len);
|
||||
BOOL rcua_get_sdp_h265_params(RCUA * p_rua, int * pt, BOOL * donfield, char * p_vps, int vps_len, char * p_sps, int sps_len, char * p_pps, int pps_len);
|
||||
|
||||
BOOL rcua_get_sdp_mp4_desc(RCUA * p_rua, int * pt, char * p_sdp, int max_len);
|
||||
BOOL rcua_get_sdp_mp4_params(RCUA * p_rua, int * pt, char * p_cfg, int max_len);
|
||||
|
||||
BOOL rcua_get_sdp_aac_desc(RCUA * p_rua, int * pt, char * p_sdp, int max_len);
|
||||
BOOL rcua_get_sdp_aac_params(RCUA * p_rua, int *pt, int *sizelength, int *indexlength, int *indexdeltalength, char * p_cfg, int max_len);
|
||||
|
||||
SOCKET rcua_init_udp_connection(uint16 port);
|
||||
SOCKET rcua_init_mc_connection(uint16 port, char * destination);
|
||||
|
||||
/*************************************************************************/
|
||||
void rcua_send_rtsp_msg(RCUA * p_rua,HRTSP_MSG * tx_msg);
|
||||
|
||||
#define rcua_send_free_rtsp_msg(p_rua,tx_msg) \
|
||||
do { \
|
||||
rcua_send_rtsp_msg(p_rua,tx_msg); \
|
||||
rtsp_free_msg(tx_msg); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RTSP_RCUA_H
|
||||
|
||||
|
||||
|
||||
|
||||
258
MediaClient/rtsp/rtsp_util.cpp
Normal file
258
MediaClient/rtsp/rtsp_util.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include "rtsp_util.h"
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
#define UDP_BASE_PORT 40000
|
||||
|
||||
static uint16 g_udp_bport = UDP_BASE_PORT;
|
||||
static void * g_udp_port_mutex = sys_os_create_mutex();
|
||||
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
uint16 rtsp_get_udp_port()
|
||||
{
|
||||
uint16 port;
|
||||
|
||||
sys_os_mutex_enter(g_udp_port_mutex);
|
||||
|
||||
port = g_udp_bport;
|
||||
g_udp_bport += 2;
|
||||
if (g_udp_bport > 65534)
|
||||
{
|
||||
g_udp_bport = UDP_BASE_PORT;
|
||||
}
|
||||
|
||||
sys_os_mutex_leave(g_udp_port_mutex);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
uint32 rtsp_get_timestamp(int frequency)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
|
||||
// Begin by converting from "struct timeval" units to RTP timestamp units:
|
||||
uint32 increment = (frequency*tv.tv_sec);
|
||||
increment += (uint32)(frequency*(tv.tv_usec/1000000.0) + 0.5); // note: rounding
|
||||
|
||||
return increment;
|
||||
}
|
||||
|
||||
char * rtsp_get_utc_time()
|
||||
{
|
||||
static char buff[100];
|
||||
|
||||
time_t t = time(NULL);
|
||||
struct tm *ptr = gmtime(&t);
|
||||
|
||||
strftime(buff, sizeof(buff)-1, "%a, %b %d %Y %H:%M:%S GMT", ptr);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
int rtsp_pkt_find_end(char * p_buf)
|
||||
{
|
||||
int end_off = 0;
|
||||
int rtsp_pkt_finish = 0;
|
||||
|
||||
while (p_buf[end_off] != '\0')
|
||||
{
|
||||
if ((p_buf[end_off+0] == '\r' && p_buf[end_off+1] == '\n') &&
|
||||
(p_buf[end_off+2] == '\r' && p_buf[end_off+3] == '\n'))
|
||||
{
|
||||
rtsp_pkt_finish = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
end_off++;
|
||||
}
|
||||
|
||||
if (rtsp_pkt_finish)
|
||||
{
|
||||
return(end_off + 4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t rtsp_timegm(struct tm *T)
|
||||
{
|
||||
time_t t, g, z;
|
||||
struct tm tm;
|
||||
|
||||
t = mktime(T);
|
||||
if (t == (time_t)-1)
|
||||
{
|
||||
return (time_t)-1;
|
||||
}
|
||||
|
||||
tm = *gmtime(&t);
|
||||
|
||||
tm.tm_isdst = 0;
|
||||
g = mktime(&tm);
|
||||
if (g == (time_t)-1)
|
||||
{
|
||||
return (time_t)-1;
|
||||
}
|
||||
|
||||
z = g - t;
|
||||
return t - z;
|
||||
}
|
||||
|
||||
BOOL rtsp_parse_xsd_datetime(const char * s, time_t * p)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
char zone[32];
|
||||
struct tm T;
|
||||
const char *t;
|
||||
|
||||
*zone = '\0';
|
||||
memset(&T, 0, sizeof(T));
|
||||
|
||||
if (strchr(s, '-'))
|
||||
{
|
||||
t = "%d-%d-%dT%d:%d:%d%31s";
|
||||
}
|
||||
else if (strchr(s, ':'))
|
||||
{
|
||||
t = "%4d%2d%2dT%d:%d:%d%31s";
|
||||
}
|
||||
else /* parse non-XSD-standard alternative ISO 8601 format */
|
||||
{
|
||||
t = "%4d%2d%2dT%2d%2d%2d%31s";
|
||||
}
|
||||
|
||||
if (sscanf(s, t, &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone) < 6)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (T.tm_year == 1)
|
||||
{
|
||||
T.tm_year = 70;
|
||||
}
|
||||
else
|
||||
{
|
||||
T.tm_year -= 1900;
|
||||
}
|
||||
|
||||
T.tm_mon--;
|
||||
|
||||
if (*zone == '.')
|
||||
{
|
||||
for (s = zone + 1; *s; s++)
|
||||
{
|
||||
if (*s < '0' || *s > '9')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s = zone;
|
||||
}
|
||||
|
||||
if (*s)
|
||||
{
|
||||
if (*s == '+' || *s == '-')
|
||||
{
|
||||
int h = 0, m = 0;
|
||||
if (s[3] == ':')
|
||||
{
|
||||
/* +hh:mm */
|
||||
sscanf(s, "%d:%d", &h, &m);
|
||||
if (h < 0)
|
||||
m = -m;
|
||||
}
|
||||
else /* +hhmm */
|
||||
{
|
||||
m = (int)strtol(s, NULL, 10);
|
||||
h = m / 100;
|
||||
m = m % 100;
|
||||
}
|
||||
|
||||
T.tm_min -= m;
|
||||
T.tm_hour -= h;
|
||||
/* put hour and min in range */
|
||||
T.tm_hour += T.tm_min / 60;
|
||||
T.tm_min %= 60;
|
||||
|
||||
if (T.tm_min < 0)
|
||||
{
|
||||
T.tm_min += 60;
|
||||
T.tm_hour--;
|
||||
}
|
||||
|
||||
T.tm_mday += T.tm_hour / 24;
|
||||
T.tm_hour %= 24;
|
||||
|
||||
if (T.tm_hour < 0)
|
||||
{
|
||||
T.tm_hour += 24;
|
||||
T.tm_mday--;
|
||||
}
|
||||
/* note: day of the month may be out of range, timegm() handles it */
|
||||
}
|
||||
|
||||
*p = rtsp_timegm(&T);
|
||||
}
|
||||
else /* no UTC or timezone, so assume we got a localtime */
|
||||
{
|
||||
T.tm_isdst = -1;
|
||||
*p = mktime(&T);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int64 rtsp_gettime()
|
||||
{
|
||||
#if __LINUX_OS__
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (int64)tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
#elif __WINDOWS_OS__
|
||||
FILETIME ft;
|
||||
int64 t;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
t = (int64)ft.dwHighDateTime << 32 | ft.dwLowDateTime;
|
||||
return t / 10 - 11644473600000000; /* Jan 1, 1601 */
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64 rtsp_ntp_time()
|
||||
{
|
||||
return (rtsp_gettime() / 1000) * 1000 + NTP_OFFSET_US;
|
||||
}
|
||||
|
||||
|
||||
|
||||
47
MediaClient/rtsp/rtsp_util.h
Normal file
47
MediaClient/rtsp/rtsp_util.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef RTSP_UTIL_H
|
||||
#define RTSP_UTIL_H
|
||||
|
||||
#define NTP_OFFSET 2208988800ULL
|
||||
#define NTP_OFFSET_US (NTP_OFFSET * 1000000ULL)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint16 rtsp_get_udp_port();
|
||||
uint32 rtsp_get_timestamp(int frequency);
|
||||
char * rtsp_get_utc_time();
|
||||
int rtsp_pkt_find_end(char * p_buf);
|
||||
BOOL rtsp_parse_xsd_datetime(const char * s, time_t * p);
|
||||
int64 rtsp_gettime();
|
||||
uint64 rtsp_ntp_time();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
211
MediaClient/rtsp/rtsp_ws.cpp
Normal file
211
MediaClient/rtsp/rtsp_ws.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sys_inc.h"
|
||||
#include "rtsp_ws.h"
|
||||
#include "rtp.h"
|
||||
|
||||
|
||||
int rtsp_ws_decode_data(WSMSG * p_msg)
|
||||
{
|
||||
int length, has_mask;
|
||||
char * p_buff = p_msg->buff;
|
||||
|
||||
/**
|
||||
* Extracting information from frame
|
||||
*/
|
||||
has_mask = p_buff[1] & 0x80 ? 1 : 0;
|
||||
length = p_buff[1] & 0x7f;
|
||||
|
||||
p_msg->opcode = (p_buff[0] & 0xF);
|
||||
p_msg->finbit = ((p_buff[0] & 0x80) ? 1 : 0);
|
||||
|
||||
/**
|
||||
* We need to handle the received frame differently according to which
|
||||
* length that the frame has set.
|
||||
*
|
||||
* length <= 125: We know that length is the actual length of the message,
|
||||
* and that the maskin data must be placed 2 bytes further
|
||||
* ahead.
|
||||
* length == 126: We know that the length is an unsigned 16 bit integer,
|
||||
* which is placed at the 2 next bytes, and that the masking
|
||||
* data must be further 2 bytes away.
|
||||
* length == 127: We know that the length is an unsigned 64 bit integer,
|
||||
* which is placed at the 8 next bytes, and that the masking
|
||||
* data must be further 2 bytes away.
|
||||
*/
|
||||
if (length <= 125)
|
||||
{
|
||||
if (p_msg->rcv_len < 6)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_msg->msg_len = length;
|
||||
p_msg->skip = 2;
|
||||
|
||||
if (has_mask)
|
||||
{
|
||||
p_msg->skip += 4;
|
||||
memcpy(&p_msg->mask, p_buff + 2, sizeof(p_msg->mask));
|
||||
}
|
||||
}
|
||||
else if (length == 126)
|
||||
{
|
||||
if (p_msg->rcv_len < 8)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_msg->msg_len = rtp_read_uint16((uint8 *)p_buff + 2);
|
||||
p_msg->skip = 4;
|
||||
|
||||
if (has_mask)
|
||||
{
|
||||
p_msg->skip += 4;
|
||||
memcpy(&p_msg->mask, p_buff + 4, sizeof(p_msg->mask));
|
||||
}
|
||||
}
|
||||
else if (length == 127)
|
||||
{
|
||||
if (p_msg->rcv_len < 14)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_msg->msg_len = (uint32)rtp_read_uint64((uint8 *)p_buff + 2);
|
||||
p_msg->skip = 10;
|
||||
|
||||
if (has_mask)
|
||||
{
|
||||
p_msg->skip += 4;
|
||||
memcpy(&p_msg->mask, p_buff + 10, sizeof(p_msg->mask));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, Obscure length received from client: %d\r\n", __FUNCTION__, length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the message length is greater that our WS_MAXMESSAGE constant, we
|
||||
* skip the message and close the connection.
|
||||
*/
|
||||
if (p_msg->msg_len > WS_MAXMESSAGE)
|
||||
{
|
||||
log_print(HT_LOG_ERR, "%s, Message received was bigger than WS_MAXMESSAGE\r\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32 buf_len = (p_msg->rcv_len - p_msg->skip);
|
||||
|
||||
/**
|
||||
* The message read from recv is larger than the message we are supposed
|
||||
* to receive. This means that we have received the first part of the next
|
||||
* message as well.
|
||||
*/
|
||||
if (buf_len >= p_msg->msg_len)
|
||||
{
|
||||
if (has_mask)
|
||||
{
|
||||
char * buff = p_msg->buff + p_msg->skip;
|
||||
|
||||
/**
|
||||
* If everything went well, we have to remove the masking from the data.
|
||||
*/
|
||||
for (uint32 i = 0; i < p_msg->msg_len; i++)
|
||||
{
|
||||
buff[i] = buff[i] ^ p_msg->mask[i % 4];
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
* websocket encod data, add websocket header before p_data
|
||||
* The p_data pointer must reserve a certain amount of space
|
||||
*/
|
||||
int rtsp_ws_encode_data(uint8 * p_data, int len, uint8 opcode, uint8 have_mask)
|
||||
{
|
||||
int offset = 0;
|
||||
uint8 mask[4];
|
||||
|
||||
if (have_mask)
|
||||
{
|
||||
mask[0] = rand();
|
||||
mask[1] = rand();
|
||||
mask[2] = rand();
|
||||
mask[3] = rand();
|
||||
|
||||
for (int32 i = 0; i < len; i++)
|
||||
{
|
||||
p_data[i] = p_data[i] ^ mask[i % 4];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC6455 message encoding
|
||||
*/
|
||||
if (len <= 125)
|
||||
{
|
||||
p_data -= have_mask ? 6 : 2;
|
||||
p_data[0] = opcode;
|
||||
p_data[1] = have_mask ? (len | 0x80) : len;
|
||||
if (have_mask)
|
||||
{
|
||||
memcpy(p_data+2, mask, 4);
|
||||
}
|
||||
offset = have_mask ? 6 : 2;
|
||||
}
|
||||
else if (len <= 65535)
|
||||
{
|
||||
p_data -= have_mask ? 8 : 4;
|
||||
p_data[0] = opcode;
|
||||
p_data[1] = have_mask ? (126 | 0x80) : 126;
|
||||
rtp_write_uint16(p_data + 2, len);
|
||||
if (have_mask)
|
||||
{
|
||||
memcpy(p_data+4, mask, 4);
|
||||
}
|
||||
offset = have_mask ? 8 : 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 len64 = len;
|
||||
p_data -= have_mask ? 14 : 10;
|
||||
p_data[0] = opcode;
|
||||
p_data[1] = have_mask ? (127 | 0x80) : 127;
|
||||
rtp_write_uint32(p_data + 2, len64 & 0xFFFF);
|
||||
rtp_write_uint32(p_data + 6, (len64 >> 32) & 0xFFFF);
|
||||
if (have_mask)
|
||||
{
|
||||
memcpy(p_data+10, mask, 4);
|
||||
}
|
||||
offset = have_mask ? 14 : 10;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
62
MediaClient/rtsp/rtsp_ws.h
Normal file
62
MediaClient/rtsp/rtsp_ws.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef RTSP_WS_H
|
||||
#define RTSP_WS_H
|
||||
|
||||
#include "sys_inc.h"
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
#define WS_VERSION 13 // websocket version
|
||||
#define WS_PROTOCOL "rtsp.onvif.org" // websocket protocol
|
||||
#define WS_MAXMESSAGE 1048576 // Max size message = 1MB
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 finbit : 1;
|
||||
uint32 opcode : 4;
|
||||
uint32 reserved : 27;
|
||||
|
||||
char mask[4];
|
||||
int skip;
|
||||
uint32 buff_len;
|
||||
uint32 rcv_len;
|
||||
uint32 msg_len;
|
||||
char * buff;
|
||||
} WSMSG;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int rtsp_ws_decode_data(WSMSG * p_msg);
|
||||
int rtsp_ws_encode_data(uint8 * p_data, int len, uint8 opcode, uint8 have_mask);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user