Older/MediaServer/Rtsp/RtspMediaSource.h

213 lines
6.2 KiB
C
Raw Permalink Normal View History

2024-09-28 23:55:00 +08:00
/*
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
*
* Use of this source code is governed by MIT-like license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef SRC_RTSP_RTSPMEDIASOURCE_H_
#define SRC_RTSP_RTSPMEDIASOURCE_H_
#include <mutex>
#include <string>
#include <memory>
#include <functional>
#include "Common/MediaSource.h"
#include "Common/PacketCache.h"
#include "Util/RingBuffer.h"
#define RTP_GOP_SIZE 512
namespace mediakit {
/**
* rtsp媒体源的数据抽象
* rtsp有关键的两要素sdprtp包
* rtsp推流rtsp服务器就很简单了
* rtsp推拉流协议中sdp(tcp/udp/)rtp
* Data abstraction of rtsp media source
* Rtsp has two key elements, sdp and rtp packets
* As long as these two elements are generated, it is very simple to implement rtsp push stream and rtsp server
* In the rtsp push and pull stream protocol, sdp is transmitted first, then the transmission method (tcp/udp/multicast) is negotiated, and finally rtp is continuously transmitted
* [AUTO-TRANSLATED:e04eee56]
*/
class RtspMediaSource : public MediaSource, public toolkit::RingDelegate<RtpPacket::Ptr>, private PacketCache<RtpPacket> {
public:
using Ptr = std::shared_ptr<RtspMediaSource>;
using RingDataType = std::shared_ptr<toolkit::List<RtpPacket::Ptr> >;
using RingType = toolkit::RingBuffer<RingDataType>;
/**
*
* @param vhost
* @param app
* @param stream_id id
* @param ring_size 0
* Constructor
* @param vhost Virtual host name
* @param app Application name
* @param stream_id Stream id
* @param ring_size You can set a fixed ring buffer size, 0 is adaptive
* [AUTO-TRANSLATED:5dd23423]
*/
RtspMediaSource(const MediaTuple& tuple, int ring_size = RTP_GOP_SIZE): MediaSource(RTSP_SCHEMA, tuple), _ring_size(ring_size) {}
~RtspMediaSource() override {
try {
flush();
} catch (std::exception &ex) {
WarnL << ex.what();
}
}
/**
*
* Get the ring buffer of the media source
* [AUTO-TRANSLATED:91a762bc]
*/
const RingType::Ptr &getRing() const {
return _ring;
}
void getPlayerList(const std::function<void(const std::list<toolkit::Any> &info_list)> &cb,
const std::function<toolkit::Any(toolkit::Any &&info)> &on_change) override {
assert(_ring);
_ring->getInfoList(cb, on_change);
}
bool broadcastMessage(const toolkit::Any &data) override {
assert(_ring);
_ring->sendMessage(data);
return true;
}
/**
*
* Get the number of players
* [AUTO-TRANSLATED:a451c846]
*/
int readerCount() override {
return _ring ? _ring->readerCount() : 0;
}
/**
* sdp
* Get the sdp of this source
* [AUTO-TRANSLATED:ebc43430]
*/
const std::string &getSdp() const {
return _sdp;
}
virtual RtspMediaSource::Ptr clone(const std::string& stream) {
return nullptr;
}
/**
* ssrc
* Get the ssrc of the corresponding track
* [AUTO-TRANSLATED:d26d7f76]
*/
virtual uint32_t getSsrc(TrackType trackType) {
assert(trackType >= 0 && trackType < TrackMax);
auto &track = _tracks[trackType];
if (!track) {
return 0;
}
return track->_ssrc;
}
/**
* seqence
* Get the sequence of the corresponding track
* [AUTO-TRANSLATED:24b0ee74]
*/
virtual uint16_t getSeqence(TrackType trackType) {
assert(trackType >= 0 && trackType < TrackMax);
auto &track = _tracks[trackType];
if (!track) {
return 0;
}
return track->_seq;
}
/**
*
* Get the timestamp of the corresponding track, in milliseconds
* [AUTO-TRANSLATED:564a0794]
*/
uint32_t getTimeStamp(TrackType trackType) override;
/**
*
* Update timestamp
* [AUTO-TRANSLATED:8defe253]
*/
void setTimeStamp(uint32_t stamp) override;
/**
* sdp
* Set sdp
* [AUTO-TRANSLATED:76a533c4]
*/
virtual void setSdp(const std::string &sdp);
/**
* rtp
* @param rtp rtp包
* @param keyPos
* Input rtp
* @param rtp rtp packet
* @param keyPos Whether this packet is the first packet of a key frame
* [AUTO-TRANSLATED:fe55afe8]
*/
void onWrite(RtpPacket::Ptr rtp, bool keyPos) override;
void clearCache() override{
PacketCache<RtpPacket>::clearCache();
_ring->clearCache();
}
private:
/**
* flush rtp包时触发该函数
* @param rtp_list rtp包列表
* @param key_pos
* Trigger this function when flushing rtp packets in batches
* @param rtp_list rtp packet list
* @param key_pos Whether it contains a key frame
* [AUTO-TRANSLATED:612c574b]
*/
void onFlush(std::shared_ptr<toolkit::List<RtpPacket::Ptr> > rtp_list, bool key_pos) override {
// 如果不存在视频那么就没有存在GOP缓存的意义所以is_key一直为true确保一直清空GOP缓存 [AUTO-TRANSLATED:5818a8d8]
// If there is no video, then there is no point in having a GOP cache, so is_key is always true to ensure that the GOP cache is always cleared
_ring->write(std::move(rtp_list), _have_video ? key_pos : true);
}
private:
bool _have_video = false;
int _ring_size;
std::string _sdp;
RingType::Ptr _ring;
SdpTrack::Ptr _tracks[TrackMax];
};
} /* namespace mediakit */
#endif /* SRC_RTSP_RTSPMEDIASOURCE_H_ */