490 lines
18 KiB
C
Executable File
490 lines
18 KiB
C
Executable File
/*
|
|
* Copyright (c) XCAM. All rights reserved.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include "xcam_type.h"
|
|
#include "xcam_track_source.h"
|
|
#include "xcam_livestream_rtsp_server.h"
|
|
#include "xcam_liveserver.h"
|
|
|
|
#define LIVESVR_RTSP_PACKET_LEN 1500 /* packet length, value[500,5000], recommend 1500, unit:byte */
|
|
#define LIVESVR_RTSP_DEF_LISTEN_PORT 554 /* value[1,65535], normal 554 */
|
|
#define LIVESVR_RTSP_MAX_PAYLOAD_CNT 8 /* max payload num in mbuffer, value[1,254] */
|
|
#define LIVESVR_RTSP_TIMEOUT_SEC -1 /* <0: not use timeout, unit:s */
|
|
#define LIVESVR_RTSP_MAX_STREAM_CNT 4
|
|
#define LIVESVR_VIDEO_MBUFFER_FRAME 5
|
|
#define LIVESVR_PATH_MAX 64
|
|
#define LIVESVR_AUDIO_MBUFFER_SIZE (16 << 10) /* 16K */
|
|
#define RTSP_MIN_MBUFFER_SIZE (216 << 10) /* 216K */
|
|
#define RTSP_MAX_MBUFFER_SIZE (3 << 20) /* 3M */
|
|
#define LIVESVR_DEF_PATTERN_NAME "livestream"
|
|
|
|
#define INVALID_TRACK (-1)
|
|
|
|
#ifndef MAX
|
|
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
|
#endif
|
|
#ifndef MIN
|
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
#endif
|
|
|
|
|
|
typedef struct {
|
|
xcam_bool is_used;
|
|
xcam_char stream_name[LIVESVR_PATH_MAX];
|
|
xcam_track_source track_video_src;
|
|
xcam_track_source track_audio_src;
|
|
} xcam_liveserver_rtsp_stream_ctx;
|
|
|
|
typedef struct {
|
|
xcam_bool is_initialized;
|
|
xcam_void* rtspserv_obj;
|
|
xcam_liveserver_rtsp_stream_ctx rtsp_stream_ctx[LIVESVR_RTSP_MAX_STREAM_CNT];
|
|
xcam_char pattern_path[PATTERN_NAME_LEN];
|
|
} xcam_liveserver_context;
|
|
|
|
static xcam_liveserver_context g_xcam_liveserver_ctx;
|
|
|
|
static xcam_void client_connect_callback(xcam_server_state_listener* listener, xcam_char* ipaddr)
|
|
{
|
|
if (listener == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("Null pointer [listener]!\n");
|
|
}
|
|
if (ipaddr == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("Null pointer [ipaddr]!\n");
|
|
return;
|
|
}
|
|
|
|
LOG_LIVESERVER_INFO("client connect, ipaddr(%s).\n", ipaddr);
|
|
return;
|
|
}
|
|
|
|
static xcam_void client_disconnect_callback(const xcam_server_state_listener* listener, const xcam_char* ipaddr)
|
|
{
|
|
if (listener == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("Null pointer [listener]!\n");
|
|
}
|
|
if (ipaddr == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("Null pointer [ipaddr]!\n");
|
|
return;
|
|
}
|
|
|
|
LOG_LIVESERVER_INFO("client disconnect, ipaddr(%s)!\n", ipaddr);
|
|
return;
|
|
}
|
|
|
|
static xcam_void server_error_callback(xcam_server_state_listener* listener, xcam_s32 err_id, xcam_char* err_msg)
|
|
{
|
|
if (listener == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("Null pointer [listener]!\n");
|
|
}
|
|
if (err_msg == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("Null pointer [err_msg]!\n");
|
|
return;
|
|
}
|
|
|
|
LOG_LIVESERVER_INFO("server error, err_id(%d) err_msg(%s)!\n", err_id, err_msg);
|
|
return;
|
|
}
|
|
|
|
static xcam_s32 init_rtsp_server(const xcam_s32 max_conn_num, const xcam_u16 lsn_port)
|
|
{
|
|
xcam_server_state_listener listener;
|
|
xcam_livestream_rtsp_config rtsp_cfg;
|
|
xcam_s32 ret;
|
|
|
|
rtsp_cfg.listen_port = (xcam_s32)lsn_port;
|
|
rtsp_cfg.max_conn_num = max_conn_num;
|
|
rtsp_cfg.max_payload = LIVESVR_RTSP_MAX_PAYLOAD_CNT;
|
|
rtsp_cfg.packet_len = LIVESVR_RTSP_PACKET_LEN;
|
|
rtsp_cfg.timeout = LIVESVR_RTSP_TIMEOUT_SEC;
|
|
ret = xcam_livestream_rtsp_server_create(&g_xcam_liveserver_ctx.rtspserv_obj, &rtsp_cfg);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Create rtsp server failed, ret:0x%x!\n", ret);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
listener.func_client_connect = client_connect_callback;
|
|
listener.func_client_disconnect = client_disconnect_callback;
|
|
listener.func_server_error = server_error_callback;
|
|
ret = xcam_livestream_rtsp_server_set_listener(g_xcam_liveserver_ctx.rtspserv_obj, &listener);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Set rtsp server listener failed, ret:0x%x!\n", ret);
|
|
(xcam_void)xcam_livestream_rtsp_server_destroy(g_xcam_liveserver_ctx.rtspserv_obj);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
LOG_LIVESERVER_INFO("Start rtsp server, listen port[%u] max conn count[%d]!\n",
|
|
lsn_port, max_conn_num);
|
|
|
|
ret = xcam_livestream_rtsp_server_start(g_xcam_liveserver_ctx.rtspserv_obj);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Start rtsp server failed, ret:0x%x!\n", ret);
|
|
(xcam_void)xcam_livestream_rtsp_server_destroy(g_xcam_liveserver_ctx.rtspserv_obj);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
return XCAM_SUCCESS;
|
|
}
|
|
|
|
static xcam_void deinit_rtsp_server(xcam_void)
|
|
{
|
|
xcam_s32 ret;
|
|
|
|
ret = xcam_livestream_rtsp_server_stop(g_xcam_liveserver_ctx.rtspserv_obj);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("rtsp server stop failed, ret:0x%X!\n", ret);
|
|
}
|
|
ret = xcam_livestream_rtsp_server_destroy(g_xcam_liveserver_ctx.rtspserv_obj);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("rtsp server destroy failed, ret:0x%X!\n", ret);
|
|
}
|
|
}
|
|
|
|
static xcam_s32 get_available_stream_context(const xcam_char* stream_name, xcam_liveserver_rtsp_stream_ctx** stream_ctx)
|
|
{
|
|
xcam_u32 idx;
|
|
for (idx = 0; idx < LIVESVR_RTSP_MAX_STREAM_CNT; ++idx) {
|
|
if (g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].is_used) {
|
|
if (strncmp(g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].stream_name, stream_name, LIVESVR_PATH_MAX) == 0) {
|
|
LOG_LIVESERVER_ERROR("stream_name[%s] already exists!\n", stream_name);
|
|
return XCAM_LIVESERVER_ERR_EXISTED;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (idx = 0; idx < LIVESVR_RTSP_MAX_STREAM_CNT; ++idx) {
|
|
if (!g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].is_used) {
|
|
*stream_ctx = &g_xcam_liveserver_ctx.rtsp_stream_ctx[idx];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (*stream_ctx == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("Beyond max stream count!\n");
|
|
return XCAM_LIVESERVER_ERR_NO_FREE_RESOURCE;
|
|
}
|
|
|
|
return XCAM_SUCCESS;
|
|
}
|
|
|
|
static xcam_s32 get_rtsp_stream_context(xcam_handle venc_handle, xcam_track_video_source_info *video_src_info,
|
|
xcam_handle aenc_handle, xcam_track_audio_source_info *audio_src_info,
|
|
const xcam_char* stream_name, xcam_liveserver_rtsp_stream_ctx* stream_ctx)
|
|
{
|
|
xcam_s32 ret;
|
|
|
|
if (venc_handle != (xcam_handle)INVALID_TRACK) {
|
|
memcpy(&stream_ctx->track_video_src.track_source_attr.video_info, video_src_info,
|
|
sizeof(xcam_track_video_source_info));
|
|
stream_ctx->track_video_src.private_handle = venc_handle;
|
|
stream_ctx->track_video_src.track_type = XCAM_TRACK_SOURCE_TYPE_VIDEO;
|
|
} else {
|
|
stream_ctx->track_video_src.private_handle = INVALID_TRACK;
|
|
}
|
|
|
|
if (aenc_handle != (xcam_handle)INVALID_TRACK) {
|
|
memcpy(&stream_ctx->track_audio_src.track_source_attr.audio_info, audio_src_info,
|
|
sizeof(xcam_track_audio_source_info));
|
|
stream_ctx->track_audio_src.private_handle = aenc_handle;
|
|
stream_ctx->track_audio_src.track_type = XCAM_TRACK_SOURCE_TYPE_AUDIO;
|
|
} else {
|
|
stream_ctx->track_audio_src.private_handle = INVALID_TRACK;
|
|
}
|
|
|
|
ret = snprintf(stream_ctx->stream_name, LIVESVR_PATH_MAX - 1, "%s", stream_name);
|
|
if (ret < 0) {
|
|
LOG_LIVESERVER_ERROR("snprintf failed, ret:0x%x!\n", ret);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
return XCAM_SUCCESS;
|
|
}
|
|
|
|
static xcam_void get_rtsp_source(xcam_liveserver_rtsp_stream_ctx* stream_ctx,
|
|
xcam_livestream_rtsp_source* rtsp_src)
|
|
{
|
|
if (stream_ctx->track_video_src.private_handle != INVALID_TRACK) {
|
|
rtsp_src->video_src_handle = &stream_ctx->track_video_src;
|
|
} else {
|
|
rtsp_src->video_src_handle = XCAM_NULL;
|
|
}
|
|
|
|
if (stream_ctx->track_audio_src.private_handle != INVALID_TRACK) {
|
|
rtsp_src->audio_src_handle = &stream_ctx->track_audio_src;
|
|
} else {
|
|
rtsp_src->audio_src_handle = XCAM_NULL;
|
|
}
|
|
}
|
|
|
|
static xcam_void get_mbuffer_size(const xcam_liveserver_rtsp_stream_ctx* stream_ctx, xcam_u32* mbuf_size)
|
|
{
|
|
*mbuf_size = RTSP_MIN_MBUFFER_SIZE;
|
|
if (stream_ctx->track_video_src.private_handle != INVALID_TRACK) {
|
|
*mbuf_size += (stream_ctx->track_video_src.track_source_attr.video_info.bit_rate /
|
|
stream_ctx->track_video_src.track_source_attr.video_info.frame_rate * LIVESVR_VIDEO_MBUFFER_FRAME);
|
|
}
|
|
|
|
if (stream_ctx->track_audio_src.private_handle != INVALID_TRACK) {
|
|
*mbuf_size += LIVESVR_AUDIO_MBUFFER_SIZE;
|
|
}
|
|
|
|
*mbuf_size = MAX(*mbuf_size, RTSP_MIN_MBUFFER_SIZE);
|
|
*mbuf_size = MIN(*mbuf_size, RTSP_MAX_MBUFFER_SIZE);
|
|
}
|
|
|
|
xcam_s32 xcam_liveserver_send_video_data(xcam_handle venc_handle, xcam_livestream_rtsp_data *rtsp_data)
|
|
{
|
|
if (rtsp_data == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("NuLL pointer [aenc_data]\n");
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
|
|
xcam_track_source_handle track_video = &(g_xcam_liveserver_ctx.rtsp_stream_ctx[venc_handle].track_video_src);
|
|
xcam_s32 ret;
|
|
|
|
ret = xcam_livestream_rtsp_server_write_frame(g_xcam_liveserver_ctx.rtspserv_obj,
|
|
(xcam_track_source_handle)track_video, rtsp_data);
|
|
return ret;
|
|
}
|
|
|
|
xcam_s32 xcam_liveserver_send_audio_data(xcam_handle aenc_handle, xcam_livestream_rtsp_data *rtsp_data)
|
|
{
|
|
if (rtsp_data == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("NuLL pointer [aenc_data]\n");
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
|
|
xcam_track_source_handle track_audio = &(g_xcam_liveserver_ctx.rtsp_stream_ctx[aenc_handle].track_audio_src);
|
|
xcam_s32 ret;
|
|
|
|
ret = xcam_livestream_rtsp_server_write_frame(g_xcam_liveserver_ctx.rtspserv_obj,
|
|
(xcam_track_source_handle)track_audio, rtsp_data);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// xcam_livestream_rtsp_data rtsp_data;
|
|
// xcam_u32 offset = 0;
|
|
// rtsp_data.data_ptr[0] = aenc_data->pStream + offset;
|
|
// rtsp_data.data_len[0] = aenc_data->u32Len - offset;
|
|
// rtsp_data.pts_us = aenc_data->u64TimeStamp;
|
|
// rtsp_data.seq_num = aenc_data->u32Seq;
|
|
// rtsp_data.block_cnt = 1;
|
|
// rtsp_data.is_key_frame = XCAM_FALSE;
|
|
|
|
|
|
xcam_s32 xcam_liveserver_add_stream(xcam_handle venc_handle, xcam_track_video_source_info *video_src_info,
|
|
xcam_handle aenc_handle, xcam_track_audio_source_info *audio_src_info,
|
|
const xcam_char* stream_name,
|
|
func_xcam_track_source_request_key_frame func_request_key_frame)
|
|
{
|
|
xcam_liveserver_rtsp_stream_ctx* stream_ctx = XCAM_NULL;
|
|
xcam_char stream_path[LIVESVR_PATH_MAX];
|
|
xcam_livestream_rtsp_source rtsp_src;
|
|
xcam_u32 mbuf_size;
|
|
xcam_s32 ret;
|
|
|
|
if (!g_xcam_liveserver_ctx.is_initialized) {
|
|
LOG_LIVESERVER_ERROR("liveserver is not inited yet!\n");
|
|
return XCAM_LIVESERVER_ERR_NOT_INIT;
|
|
}
|
|
if (stream_name == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("NuLL pointer [stream_name]!\n");
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
if ((venc_handle == (xcam_handle)INVALID_TRACK)
|
|
&& (aenc_handle == (xcam_handle)INVALID_TRACK)) {
|
|
LOG_LIVESERVER_ERROR("venc_handle[%d] aenc_handle[%d] is invalid!\n", venc_handle, aenc_handle);
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
|
|
if (strlen(stream_name) == 0) {
|
|
LOG_LIVESERVER_ERROR("stream_name is null!\n");
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
|
|
ret = get_available_stream_context(stream_name, &stream_ctx);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Get one available stream context failed, ret:0x%x!\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
memset(&stream_ctx->track_video_src, 0x0, sizeof(xcam_track_source));
|
|
memset(&stream_ctx->track_audio_src, 0x0, sizeof(xcam_track_source));
|
|
ret = get_rtsp_stream_context(venc_handle, video_src_info, aenc_handle, audio_src_info, stream_name, stream_ctx);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Get specific stream context failed, ret:0x%x!\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
if (venc_handle != (xcam_handle)INVALID_TRACK && func_request_key_frame) {
|
|
stream_ctx->track_video_src.func_request_key_frame = func_request_key_frame;
|
|
}
|
|
|
|
get_rtsp_source(stream_ctx, &rtsp_src);
|
|
get_mbuffer_size(stream_ctx, &mbuf_size);
|
|
ret = snprintf(stream_path, LIVESVR_PATH_MAX - 1, "%s/%s", g_xcam_liveserver_ctx.pattern_path, stream_name);
|
|
if (ret < 0) {
|
|
LOG_LIVESERVER_ERROR("snprintf failed, ret:0x%x!\n", ret);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
LOG_LIVESERVER_INFO("Add stream_path[%s] venc_hdl[%d] aenc_hdl[%d] mbuf_size[%u byte]!\n",
|
|
stream_path, venc_handle, aenc_handle, mbuf_size);
|
|
|
|
ret = xcam_livestream_rtsp_server_add_media_stream(g_xcam_liveserver_ctx.rtspserv_obj, &rtsp_src, stream_path, mbuf_size);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Add media stream failed, ret:0x%x!\n", ret);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
stream_ctx->is_used = XCAM_TRUE;
|
|
|
|
return XCAM_SUCCESS;
|
|
}
|
|
|
|
xcam_s32 xcam_liveserver_remove_stream(const xcam_char* stream_name)
|
|
{
|
|
xcam_s32 ret;
|
|
xcam_s32 idx;
|
|
|
|
if (g_xcam_liveserver_ctx.is_initialized == XCAM_FALSE) {
|
|
LOG_LIVESERVER_ERROR("liveserver is not init yet!\n");
|
|
return XCAM_LIVESERVER_ERR_NOT_INIT;
|
|
}
|
|
if (stream_name == XCAM_NULL) {
|
|
LOG_LIVESERVER_ERROR("NuLL pointer [stream_name]!\n");
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
if (strlen(stream_name) == 0) {
|
|
LOG_LIVESERVER_ERROR("valid length of stream_name is 0!\n");
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
|
|
for (idx = 0; idx < LIVESVR_RTSP_MAX_STREAM_CNT; ++idx) {
|
|
if ( (g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].is_used == XCAM_TRUE)
|
|
&& (strncmp(g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].stream_name,
|
|
stream_name, LIVESVR_PATH_MAX) == 0) ) {
|
|
xcam_char stream_path[LIVESVR_PATH_MAX];
|
|
memset(stream_path, '\0', sizeof(stream_path));
|
|
ret = snprintf(stream_path, LIVESVR_PATH_MAX - 1, "%s/%s", g_xcam_liveserver_ctx.pattern_path, stream_name);
|
|
if (ret < 0) {
|
|
LOG_LIVESERVER_ERROR("snprintf failed, ret:0x%x.\n", ret);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
ret = xcam_livestream_rtsp_server_remove_media_stream(g_xcam_liveserver_ctx.rtspserv_obj, (const xcam_char*)stream_path);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Remove media stream failed, ret:0x%x.\n", ret);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].is_used = XCAM_FALSE;
|
|
|
|
return XCAM_SUCCESS;
|
|
}
|
|
}
|
|
|
|
LOG_LIVESERVER_ERROR("could not find stream[%s].\n", stream_name);
|
|
return XCAM_LIVESERVER_ERR_NOT_FIND;
|
|
}
|
|
|
|
xcam_s32 xcam_liveserver_remove_all_stream(xcam_void)
|
|
{
|
|
xcam_s32 ret;
|
|
xcam_s32 idx;
|
|
|
|
if (!g_xcam_liveserver_ctx.is_initialized) {
|
|
LOG_LIVESERVER_ERROR("liveserver is not init yet!\n");
|
|
return XCAM_LIVESERVER_ERR_NOT_INIT;
|
|
}
|
|
|
|
for (idx = 0; idx < LIVESVR_RTSP_MAX_STREAM_CNT; ++idx) {
|
|
if (g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].is_used == XCAM_TRUE) {
|
|
xcam_char stream_path[LIVESVR_PATH_MAX];
|
|
memset(stream_path, '\0', sizeof(stream_path));
|
|
ret = snprintf(stream_path, LIVESVR_PATH_MAX - 1, "%s/%s",
|
|
g_xcam_liveserver_ctx.pattern_path,
|
|
g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].stream_name);
|
|
if (ret < 0) {
|
|
LOG_LIVESERVER_ERROR("snprintf failed, ret:0x%x!\n", ret);
|
|
continue;
|
|
}
|
|
|
|
ret = xcam_livestream_rtsp_server_remove_media_stream(g_xcam_liveserver_ctx.rtspserv_obj, stream_path);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("remove media stream failed, ret:0x%x!\n", ret);
|
|
}
|
|
|
|
g_xcam_liveserver_ctx.rtsp_stream_ctx[idx].is_used = XCAM_FALSE;
|
|
}
|
|
}
|
|
|
|
return XCAM_SUCCESS;
|
|
}
|
|
|
|
xcam_bool xcam_liveserver_is_init(xcam_void)
|
|
{
|
|
return g_xcam_liveserver_ctx.is_initialized;
|
|
}
|
|
|
|
xcam_s32 xcam_liveserver_init(const xcam_liveserver_init_param param)
|
|
{
|
|
if (g_xcam_liveserver_ctx.is_initialized) {
|
|
LOG_LIVESERVER_ERROR("Liveserver had been initialized!\n");
|
|
return XCAM_LIVESERVER_ERR_WAS_INITED;
|
|
}
|
|
if ((param.max_conn_num < XCAM_LIVESERVER_CONN_CNT_MIN)
|
|
|| (param.max_conn_num > XCAM_LIVESERVER_CONN_CNT_MAX)) {
|
|
LOG_LIVESERVER_ERROR("max conn num[%d] is beyond range[%d, %d]!\n", param.max_conn_num,
|
|
XCAM_LIVESERVER_CONN_CNT_MIN, XCAM_LIVESERVER_CONN_CNT_MAX);
|
|
return XCAM_LIVESERVER_ERR_ILLEGAL_PARAM;
|
|
}
|
|
|
|
xcam_u16 serv_port = param.listen_port;
|
|
if (serv_port == 0) {
|
|
serv_port = LIVESVR_RTSP_DEF_LISTEN_PORT;
|
|
LOG_LIVESERVER_INFO("Use default listen port(%u)!\n", serv_port);
|
|
}
|
|
|
|
memset(&g_xcam_liveserver_ctx, 0x0, sizeof(xcam_liveserver_context));
|
|
xcam_s32 ret = init_rtsp_server(param.max_conn_num, serv_port);
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Init rtsp server failed, ret:0x%x!\n", ret);
|
|
return XCAM_FAILURE;
|
|
}
|
|
|
|
if (strlen(param.pattern_name) > 0) {
|
|
strncpy(g_xcam_liveserver_ctx.pattern_path, param.pattern_name, PATTERN_NAME_LEN);
|
|
} else {
|
|
LOG_LIVESERVER_INFO("Use default pattern name(%s)!\n", LIVESVR_DEF_PATTERN_NAME);
|
|
strncpy(g_xcam_liveserver_ctx.pattern_path, LIVESVR_DEF_PATTERN_NAME, PATTERN_NAME_LEN);
|
|
}
|
|
|
|
g_xcam_liveserver_ctx.is_initialized = XCAM_TRUE;
|
|
return XCAM_SUCCESS;
|
|
}
|
|
|
|
xcam_s32 xcam_liveserver_deinit(xcam_void)
|
|
{
|
|
xcam_s32 ret;
|
|
|
|
if (!g_xcam_liveserver_ctx.is_initialized) {
|
|
LOG_LIVESERVER_ERROR("liveserver is not init yet!\n");
|
|
return XCAM_LIVESERVER_ERR_NOT_INIT;
|
|
}
|
|
ret = xcam_liveserver_remove_all_stream();
|
|
if (ret != XCAM_SUCCESS) {
|
|
LOG_LIVESERVER_ERROR("Remove all stream failed, ret:0x%x!\n", ret);
|
|
}
|
|
|
|
deinit_rtsp_server();
|
|
g_xcam_liveserver_ctx.is_initialized = XCAM_FALSE;
|
|
|
|
return XCAM_SUCCESS;
|
|
}
|