259 lines
4.8 KiB
C++
259 lines
4.8 KiB
C++
|
|
/***************************************************************************************
|
||
|
|
*
|
||
|
|
* 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;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|