/*************************************************************************************** * * 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; }