#include "RtspServer.h" #include "Core/Logger.h" #include #include #include #include #include #include #include #include constexpr auto iniConfig = R"( [rtsp] lowLatency=1 )"; class RtspServerPrivate { public: RtspServerPrivate(boost::asio::io_context &ioContext) : strand{ioContext.get_executor()} { } boost::asio::strand strand; mk_media media; mk_h264_splitter splitter; }; static void on_h264_frame(void *user_data, mk_h264_splitter splitter, const char *data, int size) { using namespace std::chrono; using namespace std::chrono_literals; int pts = duration_cast(system_clock::now().time_since_epoch()).count(); mk_frame frame = mk_frame_create(MKCodecH264, pts, pts, data, size, NULL, NULL); mk_media_input_frame((mk_media)user_data, frame); mk_frame_unref(frame); } RtspServer::RtspServer(boost::asio::io_context &ioContext) : m_d(new RtspServerPrivate(ioContext)) { mk_config config; std::memset(&config, 0, sizeof(mk_config)); config.ini = iniConfig; config.ini_is_path = 0; config.log_mask = LOG_CONSOLE; config.ssl_is_path = 1; mk_env_init(&config); uint16_t status = mk_rtsp_server_start(554, 0); status = mk_rtc_server_start(7764); if (status == 0) { LOG(error) << "mk_rtc_server_start() failed."; } m_d->media = mk_media_create("__defaultVhost__", "live", "video", 0, 0, 0); codec_args v_args = {0}; mk_track v_track = mk_track_create(MKCodecH264, &v_args); mk_media_init_track(m_d->media, v_track); mk_media_init_complete(m_d->media); mk_track_unref(v_track); m_d->splitter = mk_h264_splitter_create(on_h264_frame, m_d->media, 0); } RtspServer::~RtspServer() { mk_h264_splitter_release(m_d->splitter); mk_media_release(m_d->media); mk_stop_all_server(); if (m_d != nullptr) { delete m_d; } } void RtspServer::push(const uint8_t *data, uint32_t size) { boost::asio::post(m_d->strand, [this, frame = std::vector(data, data + size)]() { mk_h264_splitter_input_data(m_d->splitter, reinterpret_cast(frame.data()), frame.size()); }); }