#include "rtsp_server.h" #include #include #include #include "assert.h" #include "signal.h" #include "stdint.h" #include "stdio.h" #include "unistd.h" static std::shared_ptr video_cap_flow = nullptr; std::shared_ptr g_video_enc_flow = nullptr; std::shared_ptr g_video_rtsp_flow = nullptr; std::shared_ptr video_dump_flow = nullptr; std::shared_ptr create_flow(const std::string& flow_name, const std::string& flow_param, const std::string& elem_param) { auto&& param = easymedia::JoinFlowParam(flow_param, 1, elem_param); // printf("create_flow :\n"); // printf("flow_name : %s\n", flow_name.c_str()); // printf("param : \n%s\n", param.c_str()); auto ret = easymedia::REFLECTOR(Flow)::Create(flow_name.c_str(), param.c_str()); printf(" ####### create_flow flow use_count %d\n", ret.use_count()); if (!ret) { fprintf(stderr, "Create flow %s failed\n", flow_name.c_str()); } return ret; } std::string get_video_cap_flow_param(std::string input_path, std::string pixel_format, int video_width, int video_height) { std::string flow_param; // Reading yuv from camera flow_param = ""; PARAM_STRING_APPEND(flow_param, KEY_NAME, "v4l2_capture_stream"); // PARAM_STRING_APPEND_TO(flow_param, KEY_FPS, video_fps); PARAM_STRING_APPEND(flow_param, KEK_THREAD_SYNC_MODEL, KEY_SYNC); PARAM_STRING_APPEND(flow_param, KEK_INPUT_MODEL, KEY_DROPFRONT); PARAM_STRING_APPEND_TO(flow_param, KEY_INPUT_CACHE_NUM, 5); return flow_param; } std::string get_video_cap_stream_param(std::string input_path, std::string pixel_format, int video_width, int video_height) { std::string stream_param; stream_param = ""; PARAM_STRING_APPEND_TO(stream_param, KEY_USE_LIBV4L2, 1); PARAM_STRING_APPEND(stream_param, KEY_DEVICE, input_path); // PARAM_STRING_APPEND(param, KEY_SUB_DEVICE, sub_input_path); PARAM_STRING_APPEND(stream_param, KEY_V4L2_CAP_TYPE, KEY_V4L2_C_TYPE(VIDEO_CAPTURE)); PARAM_STRING_APPEND(stream_param, KEY_V4L2_MEM_TYPE, KEY_V4L2_M_TYPE(MEMORY_MMAP)); PARAM_STRING_APPEND_TO(stream_param, KEY_FRAMES, 4); PARAM_STRING_APPEND(stream_param, KEY_OUTPUTDATATYPE, pixel_format); PARAM_STRING_APPEND_TO(stream_param, KEY_BUFFER_WIDTH, video_width); PARAM_STRING_APPEND_TO(stream_param, KEY_BUFFER_HEIGHT, video_height); return stream_param; } std::shared_ptr create_video_capture_flow(std::string input_path, std::string pixel_format, int video_width, int video_height) { std::string flow_name; std::string flow_param; std::string stream_param; std::shared_ptr video_read_flow; flow_name = "source_flow"; flow_param = get_video_cap_flow_param(input_path, pixel_format, video_width, video_height); stream_param = get_video_cap_stream_param(input_path, pixel_format, video_width, video_height); video_read_flow = create_flow(flow_name, flow_param, stream_param); if (!video_read_flow) { fprintf(stderr, "Create flow %s failed\n", flow_name.c_str()); exit(EXIT_FAILURE); } return video_read_flow; } std::string get_video_enc_flow_param(std::string pixel_format, std::string video_enc_type, int video_width, int video_height, int video_fps) { std::string flow_param; flow_param = ""; PARAM_STRING_APPEND(flow_param, KEY_NAME, "rkmpp"); PARAM_STRING_APPEND(flow_param, KEY_INPUTDATATYPE, pixel_format); PARAM_STRING_APPEND(flow_param, KEY_OUTPUTDATATYPE, video_enc_type); return flow_param; } std::string get_video_enc_stream_param(std::string pixel_format, std::string video_enc_type, int video_width, int video_height, int video_fps) { std::string stream_param; int bps = video_width * video_height * video_fps / 14; stream_param = ""; PARAM_STRING_APPEND_TO(stream_param, KEY_BUFFER_WIDTH, video_width); PARAM_STRING_APPEND_TO(stream_param, KEY_BUFFER_HEIGHT, video_height); PARAM_STRING_APPEND_TO(stream_param, KEY_BUFFER_VIR_WIDTH, video_width); PARAM_STRING_APPEND_TO(stream_param, KEY_BUFFER_VIR_HEIGHT, video_height); PARAM_STRING_APPEND_TO(stream_param, KEY_COMPRESS_BITRATE, bps); PARAM_STRING_APPEND_TO(stream_param, KEY_COMPRESS_BITRATE_MAX, bps * 17 / 16); PARAM_STRING_APPEND_TO(stream_param, KEY_COMPRESS_BITRATE_MIN, bps / 16); PARAM_STRING_APPEND(stream_param, KEY_FPS, "30/0"); PARAM_STRING_APPEND(stream_param, KEY_FPS_IN, "30/0"); PARAM_STRING_APPEND_TO(stream_param, KEY_FULL_RANGE, 1); return stream_param; } std::shared_ptr create_video_enc_flow(std::string pixel_format, std::string video_enc_type, int video_width, int video_height, int video_fps) { std::shared_ptr video_encoder_flow; std::string flow_name; std::string flow_param; std::string stream_param; flow_name = "video_enc"; flow_param = get_video_enc_flow_param(pixel_format, video_enc_type, video_width, video_height, video_fps); stream_param = get_video_enc_stream_param(pixel_format, video_enc_type, video_width, video_height, video_fps); video_encoder_flow = create_flow(flow_name, flow_param, stream_param); if (!video_encoder_flow) { fprintf(stderr, "Create flow %s failed\n", flow_name.c_str()); exit(EXIT_FAILURE); } return video_encoder_flow; } std::string get_rtsp_server_flow_param(std::string channel_name, std::string media_type) { std::string flow_param; flow_param = ""; PARAM_STRING_APPEND(flow_param, KEY_INPUTDATATYPE, media_type); PARAM_STRING_APPEND(flow_param, KEY_CHANNEL_NAME, channel_name); PARAM_STRING_APPEND_TO(flow_param, KEY_PORT_NUM, 554); return flow_param; } std::string get_rtsp_server_stream_param(std::string channel_name, std::string media_type) { std::string stream_param; stream_param = ""; return stream_param; } std::shared_ptr create_rtsp_server_flow(std::string channel_name, std::string media_type) { std::shared_ptr rtsp_flow; std::string flow_name; std::string flow_param; std::string stream_param; flow_name = "live555_rtsp_server"; flow_param = get_rtsp_server_flow_param(channel_name, media_type); stream_param = get_rtsp_server_stream_param(channel_name, media_type); rtsp_flow = create_flow(flow_name, flow_param, stream_param); if (!rtsp_flow) { fprintf(stderr, "Create flow %s failed\n", flow_name.c_str()); exit(EXIT_FAILURE); } return rtsp_flow; } std::string get_rtmp_server_flow_param(std::string stream_addr, std::string output_type) { std::string flow_param; flow_param = ""; PARAM_STRING_APPEND(flow_param, KEY_NAME, "muxer_flow"); PARAM_STRING_APPEND(flow_param, KEY_PATH, stream_addr); PARAM_STRING_APPEND(flow_param, KEY_OUTPUTDATATYPE, output_type); return flow_param; } std::string get_rtmp_server_stream_param(std::string channel_name, std::string media_type) { std::string stream_param; stream_param = ""; return stream_param; } std::shared_ptr create_rtmp_server_flow(std::string stream_addr, std::string output_type, std::string video_param, std::string audio_param) { std::shared_ptr rtmp_flow; std::string flow_name; std::string flow_param; std::string muxer_param; flow_name = "muxer_flow"; flow_param = get_rtmp_server_flow_param(stream_addr, output_type); muxer_param = easymedia::JoinFlowParam(flow_param, 2, video_param, audio_param); rtmp_flow = create_flow(flow_name, flow_param, muxer_param); if (!rtmp_flow) { fprintf(stderr, "Create flow %s failed\n", flow_name.c_str()); exit(EXIT_FAILURE); } return rtmp_flow; } std::string get_dump_flow_param(std::string input_type) { std::string flow_param; flow_param = ""; PARAM_STRING_APPEND(flow_param, KEY_INPUTDATATYPE, input_type); return flow_param; } std::shared_ptr create_dump_server_flow(std::string input_type) { std::shared_ptr dump_flow; std::string flow_name; std::string flow_param; flow_name = "link_flow"; flow_param = get_dump_flow_param(input_type); dump_flow = create_flow(flow_name, flow_param, ""); if (!dump_flow) { fprintf(stderr, "Create flow %s failed\n", flow_name.c_str()); exit(EXIT_FAILURE); } return dump_flow; } void deinit_rtsp() { if (video_cap_flow && video_dump_flow) { video_cap_flow->RemoveDownFlow(video_dump_flow); } if (video_cap_flow && g_video_enc_flow) { video_cap_flow->RemoveDownFlow(g_video_enc_flow); } if (g_video_rtsp_flow && g_video_enc_flow) { g_video_enc_flow->RemoveDownFlow(g_video_rtsp_flow); } if (g_video_rtsp_flow) { g_video_rtsp_flow.reset(); } if (g_video_enc_flow) { g_video_enc_flow.reset(); } if (video_cap_flow) { video_cap_flow.reset(); } g_video_rtsp_flow = nullptr; g_video_enc_flow = nullptr; video_cap_flow = nullptr; } int init_rtsp(const char* video_dev, int width, int height, std::string enc_type) { deinit_rtsp(); int fps = 30; std::string yuv_format = IMAGE_NV12; printf("init_rtsp video_dev %s\n", video_dev); easymedia::REFLECTOR(Flow)::DumpFactories(); easymedia::REFLECTOR(Stream)::DumpFactories(); video_cap_flow = create_video_capture_flow(video_dev, yuv_format, width, height); g_video_enc_flow = create_video_enc_flow(yuv_format, enc_type, width, height, fps); g_video_rtsp_flow = create_rtsp_server_flow("main_stream", enc_type); video_dump_flow = create_dump_server_flow(yuv_format); g_video_enc_flow->AddDownFlow(g_video_rtsp_flow, 0, 0); video_cap_flow->AddDownFlow(g_video_enc_flow, 0, 0); video_cap_flow->AddDownFlow(video_dump_flow, 0, 0); if (!video_cap_flow || !video_dump_flow) { return -1; } return 0; }