text: //
  // Copyright (c) 2013-2021 The SRS Authors
  //
  // SPDX-License-Identifier: MIT
  //
  
  #ifndef SRS_APP_RTSP_HPP
  #define SRS_APP_RTSP_HPP
  
  #include <srs_core.hpp>
  
  #include <string>
  #include <vector>
  #include <map>
  
  #include <srs_app_st.hpp>
  #include <srs_app_listener.hpp>
  #include <srs_service_conn.hpp>
  
  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<int, bool> used_ports;
  private:
      std::vector<SrsRtspConn*> 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
  
  