From 2fa5a0bee8c950f669ff3c6b22496eb40becc412 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 10 Oct 2021 11:50:07 +0800 Subject: [PATCH] Fix #2304, Remove Push RTSP feature. v4.0.171 --- trunk/conf/full.conf | 27 - trunk/conf/push.rtsp.conf | 19 +- trunk/configure | 2 +- trunk/doc/CHANGELOG.md | 1 + trunk/doc/Features.md | 2 +- trunk/src/app/srs_app_config.cpp | 5 - trunk/src/app/srs_app_config.hpp | 1 - trunk/src/app/srs_app_rtsp.cpp | 785 --------------------------- trunk/src/app/srs_app_rtsp.hpp | 192 ------- trunk/src/app/srs_app_server.cpp | 64 --- trunk/src/app/srs_app_server.hpp | 19 - trunk/src/core/srs_core_version4.hpp | 2 +- trunk/src/utest/srs_utest_config.cpp | 3 - 13 files changed, 5 insertions(+), 1117 deletions(-) delete mode 100644 trunk/src/app/srs_app_rtsp.cpp delete mode 100644 trunk/src/app/srs_app_rtsp.hpp diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 072af08d3..b8ba91835 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -323,33 +323,6 @@ stream_caster { listen 8935; } -# RTSP -# It's deprecated and will be removed in the future, see [#2304](https://github.com/ossrs/srs/issues/2304#issuecomment-826009290). -stream_caster { - # whether stream caster is enabled. - # default: off - enabled on; - # the caster type of stream, the casters: - # rtsp, Real Time Streaming Protocol (RTSP). - caster rtsp; - # the output rtmp url. - # for rtsp caster, the typically output url: - # rtmp://127.0.0.1/[app]/[stream] - # for example, the rtsp url: - # rtsp://192.168.1.173:8544/live/livestream.sdp - # where the [app] is "live" and [stream] is "livestream", output is: - # rtmp://127.0.0.1/live/livestream - output rtmp://127.0.0.1/[app]/[stream]; - # the listen port for stream caster. - # for rtsp caster, listen at tcp port. for example, 554. - listen 554; - # for the rtsp caster, the rtp server local port over udp, - # which reply the rtsp setup request message, the port will be used: - # [rtp_port_min, rtp_port_max) - rtp_port_min 57200; - rtp_port_max 57300; -} - # FLV stream_caster { # whether stream caster is enabled. diff --git a/trunk/conf/push.rtsp.conf b/trunk/conf/push.rtsp.conf index 016a06796..ea17332e4 100644 --- a/trunk/conf/push.rtsp.conf +++ b/trunk/conf/push.rtsp.conf @@ -1,19 +1,2 @@ # push MPEG-TS over UDP to SRS. -# @see https://github.com/ossrs/srs/wiki/v2_CN_Streamer#push-mpeg-ts-over-udp -# @see https://github.com/ossrs/srs/issues/250#issuecomment-72321769 -# @see full.conf for detail config. - -listen 1935; -max_connections 1000; -daemon off; -srs_log_tank console; -stream_caster { - enabled on; - caster rtsp; - output rtmp://127.0.0.1/[app]/[stream]; - listen 554; - rtp_port_min 57200; - rtp_port_max 57300; -} -vhost __defaultVhost__ { -} +# @note Removed for https://github.com/ossrs/srs/issues/2304#issuecomment-826009290 diff --git a/trunk/configure b/trunk/configure index c5dbfa871..ff3cf1d64 100755 --- a/trunk/configure +++ b/trunk/configure @@ -272,7 +272,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_sourc "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static" "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" - "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" + "srs_app_mpegts_udp" "srs_app_listener" "srs_app_async_call" "srs_app_caster_flv" "srs_app_latest_version" "srs_app_uuid" "srs_app_process" "srs_app_ng_exec" "srs_app_hourglass" "srs_app_dash" "srs_app_fragment" "srs_app_dvr" "srs_app_coworkers" "srs_app_hybrid" "srs_app_threads") diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 3e361380d..f9a40667c 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -8,6 +8,7 @@ The changelog for SRS. ## SRS 4.0 Changelog +* v4.0, 2021-10-10, Fix [#2304](https://github.com/ossrs/srs/issues/2304) Remove Push RTSP feature. v4.0.171 * v4.0, 2021-10-10, Fix [#2653](https://github.com/ossrs/srs/issues/2653) Remove HTTP RAW API. v4.0.170 * v4.0, 2021-10-08, Merge [#2654](https://github.com/ossrs/srs/pull/2654): Parse width and width from SPS/PPS. v4.0.169 * v4.0, 2021-10-08, Default to log to console for docker. v4.0.168 diff --git a/trunk/doc/Features.md b/trunk/doc/Features.md index bb99a231b..5aeb3f31b 100644 --- a/trunk/doc/Features.md +++ b/trunk/doc/Features.md @@ -54,10 +54,10 @@ The features of SRS. - [x] [Experimental] Support pushing FLV over HTTP POST, please read wiki([CN][v4_CN_Streamer2], [EN][v4_EN_Streamer2]). - [x] [Experimental] Support SRT server, read [#1147][bug #1147]. - [x] [Experimental] Support transmux RTC to RTMP, [#2093][bug #2093]. -- [x] [Deprecated] Support pushing RTSP, please read [bug #2304][bug #2304]. - [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v4_CN_DeliveryHDS], [EN][v4_EN_DeliveryHDS]) and [#1535][bug #1535]. - [x] [Deprecated] Support bandwidth testing, please read [#1535][bug #1535]. - [x] [Deprecated] Support Adobe FMS/AMS token traverse([CN][v4_CN_DRM2], [EN][v4_EN_DRM2]) authentication, please read [#1535][bug #1535]. +- [x] [Removed] Support pushing RTSP, please read [#2304](https://github.com/ossrs/srs/issues/2304#issuecomment-826009290). - [x] [Removed] Support HTTP RAW API, please read [#2653](https://github.com/ossrs/srs/issues/2653). - [x] [Removed] Support RTMP client library: [srs-librtmp][srs-librtmp]. - [ ] Support Windows/Cygwin 64bits, [#2532](https://github.com/ossrs/srs/issues/2532). diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 030831a9a..5bbb4f3e2 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -250,11 +250,6 @@ bool srs_stream_caster_is_udp(string caster) return caster == "mpegts_over_udp"; } -bool srs_stream_caster_is_rtsp(string caster) -{ - return caster == "rtsp"; -} - bool srs_stream_caster_is_flv(string caster) { return caster == "flv"; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 46b87e6ba..e6854c165 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -100,7 +100,6 @@ extern bool srs_config_ingest_is_stream(std::string type); extern bool srs_config_dvr_is_plan_segment(std::string plan); extern bool srs_config_dvr_is_plan_session(std::string plan); extern bool srs_stream_caster_is_udp(std::string caster); -extern bool srs_stream_caster_is_rtsp(std::string caster); extern bool srs_stream_caster_is_flv(std::string caster); // Whether the dvr_apply active the stream specified by req. extern bool srs_config_apply_filter(SrsConfDirective* dvr_apply, SrsRequest* req); diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp deleted file mode 100644 index 8433f26cb..000000000 --- a/trunk/src/app/srs_app_rtsp.cpp +++ /dev/null @@ -1,785 +0,0 @@ -// -// Copyright (c) 2013-2021 Winlin -// -// SPDX-License-Identifier: MIT -// - -#include - -#include -using namespace std; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -SrsRtpConn::SrsRtpConn(SrsRtspConn* r, int p, int sid) -{ - rtsp = r; - _port = p; - stream_id = sid; - // TODO: support listen at <[ip:]port> - listener = new SrsUdpListener(this, srs_any_address_for_listener(), p); - cache = new SrsRtspPacket(); - pprint = SrsPithyPrint::create_caster(); -} - -SrsRtpConn::~SrsRtpConn() -{ - srs_freep(listener); - srs_freep(cache); - srs_freep(pprint); -} - -int SrsRtpConn::port() -{ - return _port; -} - -srs_error_t SrsRtpConn::listen() -{ - return listener->listen(); -} - -srs_error_t SrsRtpConn::on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf) -{ - srs_error_t err = srs_success; - - pprint->elapse(); - - if (true) { - SrsBuffer stream(buf, nb_buf); - - SrsRtspPacket pkt; - if ((err = pkt.decode(&stream)) != srs_success) { - return srs_error_wrap(err, "decode"); - } - - if (pkt.chunked) { - if (!cache) { - cache = new SrsRtspPacket(); - } - cache->copy(&pkt); - cache->payload->append(pkt.payload->bytes(), pkt.payload->length()); - if (pprint->can_print()) { - srs_trace("<- " SRS_CONSTS_LOG_STREAM_CASTER " rtsp: rtp chunked %dB, age=%d, vt=%d/%u, sts=%u/%#x/%#x, paylod=%dB", - nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc, - cache->payload->length() - ); - } - - if (!cache->completed){ - return err; - } - } else { - srs_freep(cache); - cache = new SrsRtspPacket(); - cache->reap(&pkt); - } - } - - if (pprint->can_print()) { - srs_trace("<- " SRS_CONSTS_LOG_STREAM_CASTER " rtsp: rtp #%d %dB, age=%d, vt=%d/%u, sts=%u/%u/%#x, paylod=%dB, chunked=%d", - stream_id, nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc, - cache->payload->length(), cache->chunked - ); - } - - // always free it. - SrsAutoFree(SrsRtspPacket, cache); - - err = rtsp->on_rtp_packet(cache, stream_id); - if (err != srs_success) { - srs_warn("ignore RTP packet err %s", srs_error_desc(err).c_str()); - srs_freep(err); - } - - return err; -} - -SrsRtspAudioCache::SrsRtspAudioCache() -{ - dts = 0; - audio = NULL; - payload = NULL; -} - -SrsRtspAudioCache::~SrsRtspAudioCache() -{ - srs_freep(audio); - srs_freep(payload); -} - -SrsRtspJitter::SrsRtspJitter() -{ - delta = 0; - previous_timestamp = 0; - pts = 0; -} - -SrsRtspJitter::~SrsRtspJitter() -{ -} - -int64_t SrsRtspJitter::timestamp() -{ - return pts; -} - -srs_error_t SrsRtspJitter::correct(int64_t& ts) -{ - srs_error_t err = srs_success; - - if (previous_timestamp == 0) { - previous_timestamp = ts; - } - - delta = srs_max(0, (int)(ts - previous_timestamp)); - if (delta > 90000) { - delta = 0; - } - - previous_timestamp = ts; - - ts = pts + delta; - pts = ts; - - return err; -} - -SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, srs_netfd_t fd, std::string o) -{ - output_template = o; - - session = ""; - video_rtp = NULL; - audio_rtp = NULL; - - caster = c; - stfd = fd; - skt = new SrsStSocket(); - rtsp = new SrsRtspStack(skt); - trd = new SrsSTCoroutine("rtsp", this); - - audio_id = 0; - video_id = 0; - audio_sample_rate = 0; - audio_channel = 0; - - req = NULL; - sdk = NULL; - vjitter = new SrsRtspJitter(); - ajitter = new SrsRtspJitter(); - - avc = new SrsRawH264Stream(); - aac = new SrsRawAacStream(); - acodec = new SrsRawAacStreamCodec(); - acache = new SrsRtspAudioCache(); -} - -SrsRtspConn::~SrsRtspConn() -{ - close(); - - srs_close_stfd(stfd); - - srs_freep(video_rtp); - srs_freep(audio_rtp); - - srs_freep(trd); - srs_freep(skt); - srs_freep(rtsp); - - srs_freep(sdk); - srs_freep(req); - - srs_freep(vjitter); - srs_freep(ajitter); - - srs_freep(avc); - srs_freep(aac); - srs_freep(acodec); - srs_freep(acache); -} - -srs_error_t SrsRtspConn::serve() -{ - srs_error_t err = srs_success; - - if ((err = skt->initialize(stfd)) != srs_success) { - return srs_error_wrap(err, "socket initialize"); - } - - if ((err = trd->start()) != srs_success) { - return srs_error_wrap(err, "rtsp connection"); - } - - return err; -} - -std::string SrsRtspConn::remote_ip() -{ - // TODO: FIXME: Implement it. - return ""; -} - -std::string SrsRtspConn::desc() -{ - return "RtspConn"; -} - -const SrsContextId& SrsRtspConn::get_id() -{ - return _srs_context->get_id(); -} - -srs_error_t SrsRtspConn::do_cycle() -{ - srs_error_t err = srs_success; - - // retrieve ip of client. - int fd = srs_netfd_fileno(stfd); - std::string ip = srs_get_peer_ip(fd); - int port = srs_get_peer_port(fd); - - if (ip.empty() && !_srs_config->empty_ip_ok()) { - srs_warn("empty ip for fd=%d", srs_netfd_fileno(stfd)); - } - srs_trace("rtsp: serve %s:%d", ip.c_str(), port); - - // consume all rtsp messages. - while (true) { - if ((err = trd->pull()) != srs_success) { - return srs_error_wrap(err, "rtsp cycle"); - } - - SrsRtspRequest* req = NULL; - if ((err = rtsp->recv_message(&req)) != srs_success) { - return srs_error_wrap(err, "recv message"); - } - SrsAutoFree(SrsRtspRequest, req); - srs_info("rtsp: got rtsp request"); - - if (req->is_options()) { - SrsRtspOptionsResponse* res = new SrsRtspOptionsResponse((int)req->seq); - res->session = session; - if ((err = rtsp->send_message(res)) != srs_success) { - return srs_error_wrap(err, "response option"); - } - } else if (req->is_announce()) { - if (rtsp_tcUrl.empty()) { - rtsp_tcUrl = req->uri; - } - size_t pos = string::npos; - if ((pos = rtsp_tcUrl.rfind(".sdp")) != string::npos) { - rtsp_tcUrl = rtsp_tcUrl.substr(0, pos); - } - srs_parse_rtmp_url(rtsp_tcUrl, rtsp_tcUrl, rtsp_stream); - - srs_assert(req->sdp); - video_id = ::atoi(req->sdp->video_stream_id.c_str()); - audio_id = ::atoi(req->sdp->audio_stream_id.c_str()); - video_codec = req->sdp->video_codec; - audio_codec = req->sdp->audio_codec; - audio_sample_rate = ::atoi(req->sdp->audio_sample_rate.c_str()); - audio_channel = ::atoi(req->sdp->audio_channel.c_str()); - h264_sps = req->sdp->video_sps; - h264_pps = req->sdp->video_pps; - aac_specific_config = req->sdp->audio_sh; - srs_trace("rtsp: video(#%d, %s, %s/%s), audio(#%d, %s, %s/%s, %dHZ %dchannels), %s/%s", - video_id, video_codec.c_str(), req->sdp->video_protocol.c_str(), req->sdp->video_transport_format.c_str(), - audio_id, audio_codec.c_str(), req->sdp->audio_protocol.c_str(), req->sdp->audio_transport_format.c_str(), - audio_sample_rate, audio_channel, rtsp_tcUrl.c_str(), rtsp_stream.c_str() - ); - - SrsRtspResponse* res = new SrsRtspResponse((int)req->seq); - res->session = session; - if ((err = rtsp->send_message(res)) != srs_success) { - return srs_error_wrap(err, "response announce"); - } - } else if (req->is_setup()) { - srs_assert(req->transport); - int lpm = 0; - if ((err = caster->alloc_port(&lpm)) != srs_success) { - return srs_error_wrap(err, "alloc port"); - } - - SrsRtpConn* rtp = NULL; - if (req->stream_id == video_id) { - srs_freep(video_rtp); - rtp = video_rtp = new SrsRtpConn(this, lpm, video_id); - } else { - srs_freep(audio_rtp); - rtp = audio_rtp = new SrsRtpConn(this, lpm, audio_id); - } - if ((err = rtp->listen()) != srs_success) { - return srs_error_wrap(err, "rtp listen"); - } - srs_trace("rtsp: #%d %s over %s/%s/%s %s client-port=%d-%d, server-port=%d-%d", - req->stream_id, (req->stream_id == video_id)? "Video":"Audio", - req->transport->transport.c_str(), req->transport->profile.c_str(), req->transport->lower_transport.c_str(), - req->transport->cast_type.c_str(), req->transport->client_port_min, req->transport->client_port_max, - lpm, lpm + 1); - - // create session. - if (session.empty()) { - session = "O9EaZ4bf"; // TODO: FIXME: generate session id. - } - - SrsRtspSetupResponse* res = new SrsRtspSetupResponse((int)req->seq); - res->client_port_min = req->transport->client_port_min; - res->client_port_max = req->transport->client_port_max; - res->local_port_min = lpm; - res->local_port_max = lpm + 1; - res->session = session; - if ((err = rtsp->send_message(res)) != srs_success) { - return srs_error_wrap(err, "response setup"); - } - } else if (req->is_record()) { - SrsRtspResponse* res = new SrsRtspResponse((int)req->seq); - res->session = session; - if ((err = rtsp->send_message(res)) != srs_success) { - return srs_error_wrap(err, "response record"); - } - } - } - - return err; -} - -srs_error_t SrsRtspConn::on_rtp_packet(SrsRtspPacket* pkt, int stream_id) -{ - srs_error_t err = srs_success; - - // ensure rtmp connected. - if ((err = connect()) != srs_success) { - return srs_error_wrap(err, "connect"); - } - - if (stream_id == video_id) { - // rtsp tbn is ts tbn. - int64_t pts = pkt->timestamp; - if ((err = vjitter->correct(pts)) != srs_success) { - return srs_error_wrap(err, "jitter"); - } - - // TODO: FIXME: set dts to pts, please finger out the right dts. - int64_t dts = pts; - - return on_rtp_video(pkt, dts, pts); - } else { - // rtsp tbn is ts tbn. - int64_t pts = pkt->timestamp; - if ((err = ajitter->correct(pts)) != srs_success) { - return srs_error_wrap(err, "jitter"); - } - - return on_rtp_audio(pkt, pts); - } - - return err; -} - -srs_error_t SrsRtspConn::cycle() -{ - // serve the rtsp client. - srs_error_t err = do_cycle(); - - caster->remove(this); - - if (err == srs_success) { - srs_trace("client finished."); - } else if (srs_is_client_gracefully_close(err)) { - srs_warn("client disconnect peer. code=%d", srs_error_code(err)); - srs_freep(err); - } - - if (video_rtp) { - caster->free_port(video_rtp->port(), video_rtp->port() + 1); - } - - if (audio_rtp) { - caster->free_port(audio_rtp->port(), audio_rtp->port() + 1); - } - - return err; -} - -srs_error_t SrsRtspConn::on_rtp_video(SrsRtspPacket* pkt, int64_t dts, int64_t pts) -{ - srs_error_t err = srs_success; - - if ((err = kickoff_audio_cache(pkt, dts)) != srs_success) { - return srs_error_wrap(err, "kickoff audio cache"); - } - - char* bytes = pkt->payload->bytes(); - int length = pkt->payload->length(); - uint32_t fdts = (uint32_t)(dts / 90); - uint32_t fpts = (uint32_t)(pts / 90); - if ((err = write_h264_ipb_frame(bytes, length, fdts, fpts)) != srs_success) { - return srs_error_wrap(err, "write ibp frame"); - } - - return err; -} - -srs_error_t SrsRtspConn::on_rtp_audio(SrsRtspPacket* pkt, int64_t dts) -{ - srs_error_t err = srs_success; - - if ((err = kickoff_audio_cache(pkt, dts)) != srs_success) { - return srs_error_wrap(err, "kickoff audio cache"); - } - - // cache current audio to kickoff. - acache->dts = dts; - acache->audio = pkt->audio; - acache->payload = pkt->payload; - - pkt->audio = NULL; - pkt->payload = NULL; - - return err; -} - -srs_error_t SrsRtspConn::kickoff_audio_cache(SrsRtspPacket* pkt, int64_t dts) -{ - srs_error_t err = srs_success; - - // nothing to kick off. - if (!acache->payload) { - return err; - } - - if (dts - acache->dts > 0 && acache->audio->nb_samples > 0) { - int64_t delta = (dts - acache->dts) / acache->audio->nb_samples; - for (int i = 0; i < acache->audio->nb_samples; i++) { - char* frame = acache->audio->samples[i].bytes; - int nb_frame = acache->audio->samples[i].size; - int64_t timestamp = (acache->dts + delta * i) / 90; - acodec->aac_packet_type = 1; - if ((err = write_audio_raw_frame(frame, nb_frame, acodec, (uint32_t)timestamp)) != srs_success) { - return srs_error_wrap(err, "write audio raw frame"); - } - } - } - - acache->dts = 0; - srs_freep(acache->audio); - srs_freep(acache->payload); - - return err; -} - -srs_error_t SrsRtspConn::write_sequence_header() -{ - srs_error_t err = srs_success; - - // use the current dts. - int64_t dts = vjitter->timestamp() / 90; - - // send video sps/pps - if ((err = write_h264_sps_pps((uint32_t)dts, (uint32_t)dts)) != srs_success) { - return srs_error_wrap(err, "write sps/pps"); - } - - // generate audio sh by audio specific config. - if (aac_specific_config.empty()) { - srs_warn("no audio asc"); - return err; - } - - std::string sh = aac_specific_config; - - SrsFormat* format = new SrsFormat(); - SrsAutoFree(SrsFormat, format); - - if ((err = format->on_aac_sequence_header((char*)sh.c_str(), (int)sh.length())) != srs_success) { - return srs_error_wrap(err, "on aac sequence header"); - } - - SrsAudioCodecConfig* dec = format->acodec; - - acodec->sound_format = SrsAudioCodecIdAAC; - acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono; - acodec->sound_size = SrsAudioSampleBits16bit; - acodec->aac_packet_type = 0; - - static int srs_aac_srates[] = { - 96000, 88200, 64000, 48000, - 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, - 7350, 0, 0, 0 - }; - switch (srs_aac_srates[dec->aac_sample_rate]) { - case 11025: - acodec->sound_rate = SrsAudioSampleRate11025; - break; - case 22050: - acodec->sound_rate = SrsAudioSampleRate22050; - break; - case 44100: - acodec->sound_rate = SrsAudioSampleRate44100; - break; - default: - break; - }; - - if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != srs_success) { - return srs_error_wrap(err, "write audio raw frame"); - } - - return err; -} - -srs_error_t SrsRtspConn::write_h264_sps_pps(uint32_t dts, uint32_t pts) -{ - srs_error_t err = srs_success; - - if (h264_sps.empty() || h264_pps.empty()) { - srs_warn("no sps=%dB or pps=%dB", (int)h264_sps.size(), (int)h264_pps.size()); - return err; - } - - // h264 raw to h264 packet. - std::string sh; - if ((err = avc->mux_sequence_header(h264_sps, h264_pps, dts, pts, sh)) != srs_success) { - return srs_error_wrap(err, "mux sequence header"); - } - - // h264 packet to flv packet. - int8_t frame_type = SrsVideoAvcFrameTypeKeyFrame; - int8_t avc_packet_type = SrsVideoAvcFrameTraitSequenceHeader; - char* flv = NULL; - int nb_flv = 0; - if ((err = avc->mux_avc2flv(sh, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) { - return srs_error_wrap(err, "mux avc to flv"); - } - - // the timestamp in rtmp message header is dts. - uint32_t timestamp = dts; - if ((err = rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv)) != srs_success) { - return srs_error_wrap(err, "write packet"); - } - - return err; -} - -srs_error_t SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts) -{ - srs_error_t err = srs_success; - - // 5bits, 7.3.1 NAL unit syntax, - // ISO_IEC_14496-10-AVC-2003.pdf, page 44. - // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame - SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(frame[0] & 0x1f); - - // for IDR frame, the frame is keyframe. - SrsVideoAvcFrameType frame_type = SrsVideoAvcFrameTypeInterFrame; - if (nal_unit_type == SrsAvcNaluTypeIDR) { - frame_type = SrsVideoAvcFrameTypeKeyFrame; - } - - std::string ibp; - if ((err = avc->mux_ipb_frame(frame, frame_size, ibp)) != srs_success) { - return srs_error_wrap(err, "mux ibp frame"); - } - - int8_t avc_packet_type = SrsVideoAvcFrameTraitNALU; - char* flv = NULL; - int nb_flv = 0; - if ((err = avc->mux_avc2flv(ibp, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) { - return srs_error_wrap(err, "mux avc to flv"); - } - - // the timestamp in rtmp message header is dts. - uint32_t timestamp = dts; - return rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv); -} - -srs_error_t SrsRtspConn::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts) -{ - srs_error_t err = srs_success; - - char* data = NULL; - int size = 0; - if ((err = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != srs_success) { - return srs_error_wrap(err, "mux aac to flv"); - } - - return rtmp_write_packet(SrsFrameTypeAudio, dts, data, size); -} - -srs_error_t SrsRtspConn::rtmp_write_packet(char type, uint32_t timestamp, char* data, int size) -{ - srs_error_t err = srs_success; - - if ((err = connect()) != srs_success) { - return srs_error_wrap(err, "connect"); - } - - SrsSharedPtrMessage* msg = NULL; - - if ((err = srs_rtmp_create_msg(type, timestamp, data, size, sdk->sid(), &msg)) != srs_success) { - return srs_error_wrap(err, "create message"); - } - srs_assert(msg); - - // send out encoded msg. - if ((err = sdk->send_and_free_message(msg)) != srs_success) { - close(); - return srs_error_wrap(err, "write message"); - } - - return err; -} - -srs_error_t SrsRtspConn::connect() -{ - srs_error_t err = srs_success; - - // Ignore when connected. - if (sdk) { - return err; - } - - // generate rtmp url to connect to. - std::string url; - if (!req) { - std::string schema, host, vhost, app, param; - int port; - srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, rtsp_stream, port, param); - - // generate output by template. - std::string output = output_template; - output = srs_string_replace(output, "[app]", app); - output = srs_string_replace(output, "[stream]", rtsp_stream); - url = output; - } - - // connect host. - srs_utime_t cto = SRS_CONSTS_RTMP_TIMEOUT; - srs_utime_t sto = SRS_CONSTS_RTMP_PULSE; - sdk = new SrsSimpleRtmpClient(url, cto, sto); - - if ((err = sdk->connect()) != srs_success) { - close(); - return srs_error_wrap(err, "connect %s failed, cto=%dms, sto=%dms.", url.c_str(), srsu2msi(cto), srsu2msi(sto)); - } - - // publish. - if ((err = sdk->publish(SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE)) != srs_success) { - close(); - return srs_error_wrap(err, "publish %s failed", url.c_str()); - } - - return write_sequence_header(); -} - -void SrsRtspConn::close() -{ - srs_freep(sdk); -} - -SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c) -{ - // TODO: FIXME: support reload. - engine = _srs_config->get_stream_caster_engine(c); - output = _srs_config->get_stream_caster_output(c); - local_port_min = _srs_config->get_stream_caster_rtp_port_min(c); - local_port_max = _srs_config->get_stream_caster_rtp_port_max(c); - manager = new SrsResourceManager("CRTSP"); -} - -SrsRtspCaster::~SrsRtspCaster() -{ - std::vector::iterator it; - for (it = clients.begin(); it != clients.end(); ++it) { - SrsRtspConn* conn = *it; - manager->remove(conn); - } - clients.clear(); - used_ports.clear(); - - srs_freep(manager); -} - -srs_error_t SrsRtspCaster::initialize() -{ - srs_error_t err = srs_success; - if ((err = manager->start()) != srs_success) { - return srs_error_wrap(err, "start manager"); - } - return err; -} - -srs_error_t SrsRtspCaster::alloc_port(int* pport) -{ - srs_error_t err = srs_success; - - // use a pair of port. - for (int i = local_port_min; i < local_port_max - 1; i += 2) { - if (!used_ports[i]) { - used_ports[i] = true; - used_ports[i + 1] = true; - *pport = i; - break; - } - } - srs_trace("rtsp: %s alloc port=%d-%d", engine.c_str(), *pport, *pport + 1); - - return err; -} - -void SrsRtspCaster::free_port(int lpmin, int lpmax) -{ - for (int i = lpmin; i < lpmax; i++) { - used_ports[i] = false; - } - srs_trace("rtsp: %s free rtp port=%d-%d", engine.c_str(), lpmin, lpmax); -} - -srs_error_t SrsRtspCaster::on_tcp_client(srs_netfd_t stfd) -{ - srs_error_t err = srs_success; - - SrsRtspConn* conn = new SrsRtspConn(this, stfd, output); - - if ((err = conn->serve()) != srs_success) { - srs_freep(conn); - return srs_error_wrap(err, "serve conn"); - } - - clients.push_back(conn); - - return err; -} - -void SrsRtspCaster::remove(SrsRtspConn* conn) -{ - std::vector::iterator it = find(clients.begin(), clients.end(), conn); - if (it != clients.end()) { - clients.erase(it); - } - srs_info("rtsp: remove connection from caster."); - - manager->remove(conn); -} - diff --git a/trunk/src/app/srs_app_rtsp.hpp b/trunk/src/app/srs_app_rtsp.hpp deleted file mode 100644 index 3f1548071..000000000 --- a/trunk/src/app/srs_app_rtsp.hpp +++ /dev/null @@ -1,192 +0,0 @@ -// -// Copyright (c) 2013-2021 Winlin -// -// SPDX-License-Identifier: MIT -// - -#ifndef SRS_APP_RTSP_HPP -#define SRS_APP_RTSP_HPP - -#include - -#include -#include -#include - -#include -#include -#include - -class SrsStSocket; -class SrsRtspConn; -class SrsRtspStack; -class SrsRtspCaster; -class SrsConfDirective; -class SrsRtspPacket; -class SrsRequest; -class SrsStSocket; -class SrsRtmpClient; -class SrsRawH264Stream; -class SrsRawAacStream; -struct SrsRawAacStreamCodec; -class SrsSharedPtrMessage; -class SrsAudioFrame; -class SrsSimpleStream; -class SrsPithyPrint; -class SrsSimpleRtmpClient; -class SrsResourceManager; - -// A rtp connection which transport a stream. -class SrsRtpConn: public ISrsUdpHandler -{ -private: - SrsPithyPrint* pprint; - SrsUdpListener* listener; - SrsRtspConn* rtsp; - SrsRtspPacket* cache; - int stream_id; - int _port; -public: - SrsRtpConn(SrsRtspConn* r, int p, int sid); - virtual ~SrsRtpConn(); -public: - virtual int port(); - virtual srs_error_t listen(); -// Interface ISrsUdpHandler -public: - virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); -}; - -// The audio cache, audio is grouped by frames. -struct SrsRtspAudioCache -{ - int64_t dts; - SrsAudioFrame* audio; - SrsSimpleStream* payload; - - SrsRtspAudioCache(); - virtual ~SrsRtspAudioCache(); -}; - -// The time jitter correct for rtsp. -class SrsRtspJitter -{ -private: - int64_t previous_timestamp; - int64_t pts; - int delta; -public: - SrsRtspJitter(); - virtual ~SrsRtspJitter(); -public: - virtual int64_t timestamp(); - virtual srs_error_t correct(int64_t& ts); -}; - -// The rtsp connection serve the fd. -class SrsRtspConn : public ISrsCoroutineHandler, public ISrsConnection -{ -private: - std::string output_template; - std::string rtsp_tcUrl; - std::string rtsp_stream; -private: - std::string session; - // video stream. - int video_id; - std::string video_codec; - SrsRtpConn* video_rtp; - // audio stream. - int audio_id; - std::string audio_codec; - int audio_sample_rate; - int audio_channel; - SrsRtpConn* audio_rtp; -private: - srs_netfd_t stfd; - SrsStSocket* skt; - SrsRtspStack* rtsp; - SrsRtspCaster* caster; - SrsCoroutine* trd; -private: - SrsRequest* req; - SrsSimpleRtmpClient* sdk; - SrsRtspJitter* vjitter; - SrsRtspJitter* ajitter; -private: - SrsRawH264Stream* avc; - std::string h264_sps; - std::string h264_pps; -private: - SrsRawAacStream* aac; - SrsRawAacStreamCodec* acodec; - std::string aac_specific_config; - SrsRtspAudioCache* acache; -public: - SrsRtspConn(SrsRtspCaster* c, srs_netfd_t fd, std::string o); - virtual ~SrsRtspConn(); -public: - virtual srs_error_t serve(); -// Interface ISrsConnection. -public: - virtual std::string remote_ip(); - virtual const SrsContextId& get_id(); - virtual std::string desc(); -private: - virtual srs_error_t do_cycle(); -// internal methods -public: - virtual srs_error_t on_rtp_packet(SrsRtspPacket* pkt, int stream_id); -// Interface ISrsOneCycleThreadHandler -public: - virtual srs_error_t cycle(); -private: - virtual srs_error_t on_rtp_video(SrsRtspPacket* pkt, int64_t dts, int64_t pts); - virtual srs_error_t on_rtp_audio(SrsRtspPacket* pkt, int64_t dts); - virtual srs_error_t kickoff_audio_cache(SrsRtspPacket* pkt, int64_t dts); -private: - virtual srs_error_t write_sequence_header(); - virtual srs_error_t write_h264_sps_pps(uint32_t dts, uint32_t pts); - virtual srs_error_t write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts); - virtual srs_error_t write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts); - virtual srs_error_t rtmp_write_packet(char type, uint32_t timestamp, char* data, int size); -private: - // Connect to RTMP server. - virtual srs_error_t connect(); - // Close the connection to RTMP server. - virtual void close(); -}; - -// The caster for rtsp. -class SrsRtspCaster : public ISrsTcpHandler -{ -private: - std::string engine; - std::string output; - int local_port_min; - int local_port_max; - // The key: port, value: whether used. - std::map used_ports; -private: - std::vector clients; - SrsResourceManager* manager; -public: - SrsRtspCaster(SrsConfDirective* c); - virtual ~SrsRtspCaster(); -public: - // Alloc a rtp port from local ports pool. - // @param pport output the rtp port. - virtual srs_error_t alloc_port(int* pport); - // Free the alloced rtp port. - virtual void free_port(int lpmin, int lpmax); - virtual srs_error_t initialize(); -// Interface ISrsTcpHandler -public: - virtual srs_error_t on_tcp_client(srs_netfd_t stfd); -// internal methods. -public: - virtual void remove(SrsRtspConn* conn); -}; - -#endif - diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index f4e05197a..8c050b1c6 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -30,7 +30,6 @@ using namespace std; #include #include #include -#include #include #include #include @@ -53,8 +52,6 @@ std::string srs_listener_type2string(SrsListenerType type) return "HTTP-Server"; case SrsListenerMpegTsOverUdp: return "MPEG-TS over UDP"; - case SrsListenerRtsp: - return "RTSP"; case SrsListenerFlv: return "HTTP-FLV"; default: @@ -119,62 +116,6 @@ srs_error_t SrsBufferListener::on_tcp_client(srs_netfd_t stfd) return srs_success; } -SrsRtspListener::SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsListener(svr, t) -{ - listener = NULL; - - // the caller already ensure the type is ok, - // we just assert here for unknown stream caster. - srs_assert(type == SrsListenerRtsp); - if (type == SrsListenerRtsp) { - caster = new SrsRtspCaster(c); - - // TODO: FIXME: Must check error. - caster->initialize(); - } -} - -SrsRtspListener::~SrsRtspListener() -{ - srs_freep(caster); - srs_freep(listener); -} - -srs_error_t SrsRtspListener::listen(string i, int p) -{ - srs_error_t err = srs_success; - - // the caller already ensure the type is ok, - // we just assert here for unknown stream caster. - srs_assert(type == SrsListenerRtsp); - - ip = i; - port = p; - - srs_freep(listener); - listener = new SrsTcpListener(this, ip, port); - - if ((err = listener->listen()) != srs_success) { - return srs_error_wrap(err, "rtsp listen %s:%d", ip.c_str(), port); - } - - string v = srs_listener_type2string(type); - srs_trace("%s listen at tcp://%s:%d, fd=%d", v.c_str(), ip.c_str(), port, listener->fd()); - - return err; -} - -srs_error_t SrsRtspListener::on_tcp_client(srs_netfd_t stfd) -{ - srs_error_t err = caster->on_tcp_client(stfd); - if (err != srs_success) { - srs_warn("accept client failed, err is %s", srs_error_desc(err).c_str()); - srs_freep(err); - } - - return srs_success; -} - SrsHttpFlvListener::SrsHttpFlvListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsListener(svr, t) { listener = NULL; @@ -629,7 +570,6 @@ void SrsServer::dispose() close_listeners(SrsListenerHttpStream); close_listeners(SrsListenerHttpsStream); close_listeners(SrsListenerMpegTsOverUdp); - close_listeners(SrsListenerRtsp); close_listeners(SrsListenerFlv); // Fast stop to notify FFMPEG to quit, wait for a while then fast kill. @@ -656,7 +596,6 @@ void SrsServer::gracefully_dispose() close_listeners(SrsListenerHttpStream); close_listeners(SrsListenerHttpsStream); close_listeners(SrsListenerMpegTsOverUdp); - close_listeners(SrsListenerRtsp); close_listeners(SrsListenerFlv); srs_trace("listeners closed"); @@ -1349,9 +1288,6 @@ srs_error_t SrsServer::listen_stream_caster() std::string caster = _srs_config->get_stream_caster_engine(stream_caster); if (srs_stream_caster_is_udp(caster)) { listener = new SrsUdpCasterListener(this, SrsListenerMpegTsOverUdp, stream_caster); - } else if (srs_stream_caster_is_rtsp(caster)) { - srs_warn("It's deprecated and will be removed in the future, see https://github.com/ossrs/srs/issues/2304#issuecomment-826009290"); - listener = new SrsRtspListener(this, SrsListenerRtsp, stream_caster); } else if (srs_stream_caster_is_flv(caster)) { listener = new SrsHttpFlvListener(this, SrsListenerFlv, stream_caster); } else { diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 4cbcf26d7..b599f6bf9 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -33,7 +33,6 @@ class ISrsUdpHandler; class SrsUdpListener; class SrsTcpListener; class SrsAppCasterFlv; -class SrsRtspCaster; class SrsResourceManager; class SrsLatestVersion; @@ -49,8 +48,6 @@ enum SrsListenerType SrsListenerHttpStream = 2, // UDP stream, MPEG-TS over udp. SrsListenerMpegTsOverUdp = 3, - // TCP stream, RTSP stream. - SrsListenerRtsp = 4, // TCP stream, FLV stream over HTTP. SrsListenerFlv = 5, // HTTPS api, @@ -91,22 +88,6 @@ public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); }; -// A TCP listener, for rtsp server. -class SrsRtspListener : public SrsListener, public ISrsTcpHandler -{ -private: - SrsTcpListener* listener; - SrsRtspCaster* caster; -public: - SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c); - virtual ~SrsRtspListener(); -public: - virtual srs_error_t listen(std::string i, int p); -// Interface ISrsTcpHandler -public: - virtual srs_error_t on_tcp_client(srs_netfd_t stfd); -}; - // A TCP listener, for flv stream server. class SrsHttpFlvListener : public SrsListener, public ISrsTcpHandler { diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index c5ccbbc39..fbb1c6570 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 0 -#define VERSION_REVISION 170 +#define VERSION_REVISION 171 #endif diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp index f0a86fb9e..2b43355c5 100644 --- a/trunk/src/utest/srs_utest_config.cpp +++ b/trunk/src/utest/srs_utest_config.cpp @@ -2162,9 +2162,6 @@ VOID TEST(ConfigUnitTest, OperatorEquals) EXPECT_TRUE(srs_stream_caster_is_udp("mpegts_over_udp")); EXPECT_FALSE(srs_stream_caster_is_udp("xxx")); - EXPECT_TRUE(srs_stream_caster_is_rtsp("rtsp")); - EXPECT_FALSE(srs_stream_caster_is_rtsp("xxx")); - EXPECT_TRUE(srs_stream_caster_is_flv("flv")); EXPECT_FALSE(srs_stream_caster_is_flv("xxx"));