Files
gb28181/GB28181Device/rtsp/mansrtsp.cpp
2024-12-15 20:42:32 +08:00

315 lines
6.2 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-2022, 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 "sip_inc.h"
#include "hqueue.h"
#include "sua.h"
#include "mansrtsp.h"
#include "rtsp_parse.h"
BOOL mansrtsp_get_range_info(HRTSP_MSG * rx_msg, int * p_sec, int * offset_mode)
{
// SEEK_SET: 开始位置, SEEK_CUR: 当前位置
// Range: npt=55814-
// Range: npt=now-
if (rx_msg == NULL || p_sec == NULL || offset_mode == NULL)
{
return FALSE;
}
HDRV * rx_line = rtsp_find_headline(rx_msg, "Range");
if (rx_line == NULL)
{
return FALSE;
}
char * ptr = strstr(rx_line->value_string, "npt=");
if (ptr == NULL)
{
log_print(HT_LOG_WARN, "%s, npt err: Range:[%s]\r\n", __FUNCTION__, rx_line->value_string);
return FALSE;
}
ptr += strlen("npt=");
while (*ptr == ' ' || *ptr == '\t')
{
ptr++;
}
if (memcmp(ptr, "now-", strlen("now-")) == 0)
{
*p_sec = 0;
*offset_mode = SEEK_CUR;
return TRUE;
}
log_print(HT_LOG_INFO, "%s, range[%s]\r\n", __FUNCTION__, ptr);
char * ptr_e = ptr;
while (is_num(*ptr_e))
{
ptr_e++;
}
if (*ptr_e == '-')
{
char bufs[32];
uint32 len = ptr_e - ptr;
if (len >= sizeof(bufs))
{
log_print(HT_LOG_WARN, "%s, len[%d]!!!\r\n", __FUNCTION__, len);
return FALSE;
}
memcpy(bufs, ptr, len);
bufs[len] = '\0';
*p_sec = atoi(bufs);
*offset_mode = SEEK_SET;
return TRUE;
}
else
{
log_print(HT_LOG_ERR, "%s, ptr_e[%c]\r\n", __FUNCTION__, *ptr_e);
return FALSE;
}
}
BOOL mansrtsp_get_scale_info(HRTSP_MSG * rx_msg, float * p_scale)
{
// Scale: 2.00
// Scale: 0.5
// Scale: -2.0
if (rx_msg == NULL || p_scale == NULL)
{
return FALSE;
}
HDRV * rx_line = rtsp_find_headline(rx_msg, "Scale");
if (rx_line == NULL)
{
return FALSE;
}
char * ptr = rx_line->value_string;
while (*ptr == ' ' || *ptr == '\t')
{
ptr++;
}
float scale = strtod(ptr, NULL);
if (scale == 0)
{
return FALSE;
}
*p_scale = scale;
return TRUE;
}
BOOL mansrtsp_get_step_info(HRTSP_MSG * rx_msg, int * p_step)
{
// Step: 120
// Step: -120
if (rx_msg == NULL || p_step == NULL)
{
return FALSE;
}
HDRV * rx_line = rtsp_find_headline(rx_msg, "Step");
if(rx_line == NULL)
{
return FALSE;
}
char * ptr = rx_line->value_string;
while (*ptr == ' ' || *ptr == '\t')
{
ptr++;
}
int step = atoi(ptr);
if (step == 0)
{
return FALSE;
}
*p_step = step;
return TRUE;
}
void mansrtsp_play_pause(PLAYCTX * p_ctx)
{
if (p_ctx->b_pausing == 0)
{
p_ctx->b_pausing = 1;
p_ctx->b_backing = 0;
// 恢复到正常播放速度 ???
p_ctx->b_scale_finish = 0;
p_ctx->scale = 1.0;
p_ctx->b_scale_req = 1;
}
}
void mansrtsp_play_seek(PLAYCTX * p_ctx, int mode, int sec)
{
if (mode == SEEK_CUR)
{
}
else if (mode == SEEK_SET && sec >= 0)
{
// 调整位置
if (p_ctx->b_seek_req == 0 || (p_ctx->b_seek_req == 1 && p_ctx->b_seek_finish == 1))
{
p_ctx->b_seek_finish = 0;
p_ctx->seek_pos = sec;
p_ctx->b_seek_req = 1;
log_print(HT_LOG_INFO, "%s, set seek pos[%d].\r\n", __FUNCTION__, sec);
}
}
}
void mansrtsp_play_scale(PLAYCTX * p_ctx, float scale)
{
if (p_ctx->b_scale_req == 0 || (p_ctx->b_scale_req == 1 && p_ctx->b_scale_finish == 1))
{
p_ctx->b_scale_finish = 0;
p_ctx->scale = scale;
p_ctx->b_scale_req = 1;
log_print(HT_LOG_INFO, "%s, set scale[%.2f]\r\n", __FUNCTION__, scale);
}
}
void mansrtsp_play_step(PLAYCTX * p_ctx, int step)
{
p_ctx->b_pausing = 1;
// 没有执行动作或者前一个动作执行完成
if (p_ctx->b_step_req == 0 || (p_ctx->b_step_req == 1 && p_ctx->b_step_finish == 1))
{
p_ctx->b_step_finish = 0;
p_ctx->step = step;
p_ctx->b_step_req = 1;
log_print(HT_LOG_INFO, "%s, set step[%d]\r\n", __FUNCTION__, step);
}
}
void mansrtsp_play_play(PLAYCTX * p_ctx)
{
p_ctx->b_pausing = 0;
}
int mansrtsp_play_handle(SUA * p_sua, HRTSP_MSG * rx_msg)
{
int sec;
int mode;
int step;
float scale;
log_print(HT_LOG_DBG, "%s, enter...\r\n", __FUNCTION__);
if (mansrtsp_get_range_info(rx_msg, &sec, &mode))
{
log_print(HT_LOG_INFO, "%s, mansrtsp_get_range_info[%d,%d]\r\n", __FUNCTION__, sec, mode);
mansrtsp_play_seek(&p_sua->play_ctx, mode, sec);
return 0;
}
if (mansrtsp_get_scale_info(rx_msg, &scale))
{
mansrtsp_play_scale(&p_sua->play_ctx, scale);
return 0;
}
if (mansrtsp_get_step_info(rx_msg, &step))
{
mansrtsp_play_step(&p_sua->play_ctx, step);
return 0;
}
return -1;
}
int mansrtsp_msg_handler(SUA * p_sua, char * mansrtsp, int len)
{
int ret = 0;
HRTSP_MSG msg;
memset(&msg, 0, sizeof(msg));
rtsp_msg_ctx_init(&msg);
log_print(HT_LOG_DBG, "%s, len=%d,[%s]\r\n", __FUNCTION__, len, mansrtsp);
int parse_len = rtsp_msg_parse(mansrtsp, len, &msg);
if (parse_len < 0)
{
log_print(HT_LOG_ERR, "%s, rtsp_msg_parse failed!!!\r\n", __FUNCTION__);
ret = -1;
goto exit;
}
switch (msg.msg_sub_type)
{
case RTSP_MT_PAUSE:
log_print(HT_LOG_INFO, "%s, RTSP_MT_PAUSE\r\n", __FUNCTION__);
mansrtsp_play_pause(&p_sua->play_ctx);
break;
case RTSP_MT_PLAY:
log_print(HT_LOG_INFO, "%s, RTSP_MT_PLAY\r\n", __FUNCTION__);
mansrtsp_play_play(&p_sua->play_ctx);
mansrtsp_play_handle(p_sua, &msg);
break;
case RTSP_MT_TEARDOWN:
log_print(HT_LOG_INFO, "%s, RTSP_MT_TEARDOWN\r\n", __FUNCTION__);
break;
default:
log_print(HT_LOG_INFO, "%s, [%d]!!!\r\n", __FUNCTION__, msg.msg_sub_type);
ret = -1;
goto exit;
}
exit:
hdrv_ctx_free(&(msg.rtsp_ctx));
hdrv_ctx_free(&(msg.sdp_ctx));
return ret;
}