From 68926b4ae7b6ef05277c48db1825b06d0da789d7 Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Fri, 4 Dec 2020 16:44:53 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=94=AF=E6=8C=81bitrate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common/MediaSource.cpp | 7 +++++-- src/Common/MediaSource.h | 4 ++-- src/Extension/AAC.cpp | 2 +- src/Extension/AAC.h | 8 +++++--- src/Extension/G711.cpp | 2 +- src/Extension/G711.h | 7 +++++-- src/Extension/H264.cpp | 2 +- src/Extension/H264.h | 8 +++++--- src/Extension/H265.cpp | 2 +- src/Extension/H265.h | 8 +++++--- src/Extension/Opus.cpp | 2 +- src/Extension/Opus.h | 7 +++++-- src/Extension/Track.h | 28 ++++++++++++++++++---------- src/FMP4/FMP4MediaSource.h | 2 +- src/Record/HlsMediaSource.h | 2 +- src/Rtmp/Rtmp.cpp | 12 ++++++++---- src/Rtmp/Rtmp.h | 4 ++-- src/Rtmp/RtmpDemuxer.cpp | 24 ++++++++++++++++++------ src/Rtmp/RtmpDemuxer.h | 4 ++-- src/Rtmp/RtmpMediaSource.h | 4 ++-- src/Rtsp/RtspDemuxer.cpp | 11 +++++++++++ src/Rtsp/RtspMediaSource.h | 2 +- src/TS/TSMediaSource.h | 2 +- 23 files changed, 102 insertions(+), 52 deletions(-) diff --git a/src/Common/MediaSource.cpp b/src/Common/MediaSource.cpp index 51bd7efb..afe42ff7 100644 --- a/src/Common/MediaSource.cpp +++ b/src/Common/MediaSource.cpp @@ -68,8 +68,11 @@ const string& MediaSource::getId() const { return _stream_id; } -int MediaSource::getBytesSpeed(){ - return _speed.getSpeed(); +int MediaSource::getBytesSpeed(TrackType type){ + if(type == TrackInvalid){ + return _speed[TrackVideo].getSpeed() + _speed[TrackAudio].getSpeed(); + } + return _speed[type].getSpeed(); } uint64_t MediaSource::getCreateStamp() const { diff --git a/src/Common/MediaSource.h b/src/Common/MediaSource.h index 5df31f50..965e1e57 100644 --- a/src/Common/MediaSource.h +++ b/src/Common/MediaSource.h @@ -220,7 +220,7 @@ public: virtual void setTimeStamp(uint32_t stamp) {}; // 获取数据速率,单位bytes/s - int getBytesSpeed(); + int getBytesSpeed(TrackType type = TrackInvalid); // 获取流创建GMT unix时间戳,单位秒 uint64_t getCreateStamp() const; // 获取流上线时间,单位秒 @@ -286,7 +286,7 @@ private: void emitEvent(bool regist); protected: - BytesSpeed _speed; + BytesSpeed _speed[TrackMax]; private: time_t _create_stamp; diff --git a/src/Extension/AAC.cpp b/src/Extension/AAC.cpp index 1a820e42..30b4cf2f 100644 --- a/src/Extension/AAC.cpp +++ b/src/Extension/AAC.cpp @@ -185,7 +185,7 @@ Sdp::Ptr AACTrack::getSdp() { WarnL << getCodecName() << " Track未准备好"; return nullptr; } - return std::make_shared(getAacCfg(),getAudioSampleRate(), getAudioChannel()); + return std::make_shared(getAacCfg(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024); } }//namespace mediakit \ No newline at end of file diff --git a/src/Extension/AAC.h b/src/Extension/AAC.h index 243f919f..0dd5ecaf 100644 --- a/src/Extension/AAC.h +++ b/src/Extension/AAC.h @@ -177,10 +177,12 @@ public: AACSdp(const string &aac_cfg, int sample_rate, int channels, - int payload_type = 98, - int bitrate = 128) : Sdp(sample_rate,payload_type){ + int bitrate = 128, + int payload_type = 98) : Sdp(sample_rate,payload_type){ _printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n"; - _printer << "b=AS:" << bitrate << "\r\n"; + if (bitrate) { + _printer << "b=AS:" << bitrate << "\r\n"; + } _printer << "a=rtpmap:" << payload_type << " MPEG4-GENERIC/" << sample_rate << "/" << channels << "\r\n"; string configStr; diff --git a/src/Extension/G711.cpp b/src/Extension/G711.cpp index 15c3d74e..9943e97f 100644 --- a/src/Extension/G711.cpp +++ b/src/Extension/G711.cpp @@ -17,7 +17,7 @@ Sdp::Ptr G711Track::getSdp() { WarnL << getCodecName() << " Track未准备好"; return nullptr; } - return std::make_shared(getCodecId(), getAudioSampleRate(), getAudioChannel()); + return std::make_shared(getCodecId(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024); } }//namespace mediakit diff --git a/src/Extension/G711.h b/src/Extension/G711.h index 72273831..f7d82ee7 100644 --- a/src/Extension/G711.h +++ b/src/Extension/G711.h @@ -48,9 +48,12 @@ public: G711Sdp(CodecId codecId, int sample_rate, int channels, - int payload_type = 98, - int bitrate = 128) : Sdp(sample_rate,payload_type), _codecId(codecId){ + int bitrate = 128, + int payload_type = 98) : Sdp(sample_rate,payload_type), _codecId(codecId){ _printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n"; + if (bitrate) { + _printer << "b=AS:" << bitrate << "\r\n"; + } _printer << "a=rtpmap:" << payload_type << (codecId == CodecG711A ? " PCMA/" : " PCMU/") << sample_rate << "/" << channels << "\r\n"; _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; } diff --git a/src/Extension/H264.cpp b/src/Extension/H264.cpp index 910e79e2..84fc3e1c 100644 --- a/src/Extension/H264.cpp +++ b/src/Extension/H264.cpp @@ -123,7 +123,7 @@ Sdp::Ptr H264Track::getSdp() { WarnL << getCodecName() << " Track未准备好"; return nullptr; } - return std::make_shared(getSps(),getPps()); + return std::make_shared(getSps(), getPps(), getBitRate() / 1024); } }//namespace mediakit diff --git a/src/Extension/H264.h b/src/Extension/H264.h index 02eba813..589701cf 100644 --- a/src/Extension/H264.h +++ b/src/Extension/H264.h @@ -292,11 +292,13 @@ public: */ H264Sdp(const string &strSPS, const string &strPPS, - int payload_type = 96, - int bitrate = 4000) : Sdp(90000,payload_type) { + int bitrate = 4000, + int payload_type = 96) : Sdp(90000,payload_type) { //视频通道 _printer << "m=video 0 RTP/AVP " << payload_type << "\r\n"; - _printer << "b=AS:" << bitrate << "\r\n"; + if (bitrate) { + _printer << "b=AS:" << bitrate << "\r\n"; + } _printer << "a=rtpmap:" << payload_type << " H264/" << 90000 << "\r\n"; _printer << "a=fmtp:" << payload_type << " packetization-mode=1; profile-level-id="; diff --git a/src/Extension/H265.cpp b/src/Extension/H265.cpp index f46a756d..0283f33c 100644 --- a/src/Extension/H265.cpp +++ b/src/Extension/H265.cpp @@ -55,7 +55,7 @@ Sdp::Ptr H265Track::getSdp() { WarnL << getCodecName() << " Track未准备好"; return nullptr; } - return std::make_shared(getVps(),getSps(),getPps()); + return std::make_shared(getVps(), getSps(), getPps(), getBitRate() / 1024); } }//namespace mediakit diff --git a/src/Extension/H265.h b/src/Extension/H265.h index 4fc3d82e..a4014c2f 100644 --- a/src/Extension/H265.h +++ b/src/Extension/H265.h @@ -321,11 +321,13 @@ public: H265Sdp(const string &strVPS, const string &strSPS, const string &strPPS, - int payload_type = 96, - int bitrate = 4000) : Sdp(90000,payload_type) { + int bitrate = 4000, + int payload_type = 96) : Sdp(90000,payload_type) { //视频通道 _printer << "m=video 0 RTP/AVP " << payload_type << "\r\n"; - _printer << "b=AS:" << bitrate << "\r\n"; + if (bitrate) { + _printer << "b=AS:" << bitrate << "\r\n"; + } _printer << "a=rtpmap:" << payload_type << " H265/" << 90000 << "\r\n"; _printer << "a=fmtp:" << payload_type << " "; _printer << "sprop-vps="; diff --git a/src/Extension/Opus.cpp b/src/Extension/Opus.cpp index e9dea37d..ada06174 100644 --- a/src/Extension/Opus.cpp +++ b/src/Extension/Opus.cpp @@ -17,7 +17,7 @@ Sdp::Ptr OpusTrack::getSdp() { WarnL << getCodecName() << " Track未准备好"; return nullptr; } - return std::make_shared(getAudioSampleRate(), getAudioChannel()); + return std::make_shared(getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024); } }//namespace mediakit \ No newline at end of file diff --git a/src/Extension/Opus.h b/src/Extension/Opus.h index 144afb77..5402d4a9 100644 --- a/src/Extension/Opus.h +++ b/src/Extension/Opus.h @@ -46,9 +46,12 @@ public: */ OpusSdp(int sample_rate, int channels, - int payload_type = 98, - int bitrate = 128) : Sdp(sample_rate,payload_type){ + int bitrate = 128, + int payload_type = 98) : Sdp(sample_rate,payload_type){ _printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n"; + if (bitrate) { + _printer << "b=AS:" << bitrate << "\r\n"; + } _printer << "a=rtpmap:" << payload_type << " opus/" << sample_rate << "/" << channels << "\r\n"; _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; } diff --git a/src/Extension/Track.h b/src/Extension/Track.h index 788af78f..70f02ead 100644 --- a/src/Extension/Track.h +++ b/src/Extension/Track.h @@ -32,7 +32,6 @@ public: /** * 是否准备好,准备好才能获取譬如sps pps等信息 - * @return */ virtual bool ready() = 0; @@ -40,7 +39,6 @@ public: * 克隆接口,用于复制本对象用 * 在调用该接口时只会复制派生类的信息 * 环形缓存和代理关系不能拷贝,否则会关系紊乱 - * @return */ virtual Track::Ptr clone() = 0; @@ -50,12 +48,28 @@ public: */ virtual Sdp::Ptr getSdp() = 0; + /** + * 返回比特率 + * @return 比特率 + */ + virtual int getBitRate() const { return _bit_rate; } + + /** + * 设置比特率 + * @param bit_rate 比特率 + */ + virtual void setBitRate(int bit_rate) { _bit_rate = bit_rate; } + /** * 复制拷贝,只能拷贝派生类的信息, * 环形缓存和代理关系不能拷贝,否则会关系紊乱 - * @param that */ - Track(const Track &that){} + Track(const Track &that){ + _bit_rate = that._bit_rate; + } + +private: + int _bit_rate = 0; }; /** @@ -67,19 +81,16 @@ public: /** * 返回视频高度 - * @return */ virtual int getVideoHeight() const {return 0;}; /** * 返回视频宽度 - * @return */ virtual int getVideoWidth() const {return 0;}; /** * 返回视频fps - * @return */ virtual float getVideoFps() const {return 0;}; }; @@ -93,19 +104,16 @@ public: /** * 返回音频采样率 - * @return */ virtual int getAudioSampleRate() const {return 0;}; /** * 返回音频采样位数,一般为16或8 - * @return */ virtual int getAudioSampleBit() const {return 0;}; /** * 返回音频通道数 - * @return */ virtual int getAudioChannel() const {return 0;}; }; diff --git a/src/FMP4/FMP4MediaSource.h b/src/FMP4/FMP4MediaSource.h index ef4af868..16fb2ab2 100644 --- a/src/FMP4/FMP4MediaSource.h +++ b/src/FMP4/FMP4MediaSource.h @@ -88,7 +88,7 @@ public: if (key) { _have_video = true; } - _speed += packet->size(); + _speed[TrackVideo] += packet->size(); auto stamp = packet->time_stamp; PacketCache::inputPacket(stamp, true, std::move(packet), key); } diff --git a/src/Record/HlsMediaSource.h b/src/Record/HlsMediaSource.h index 32e46cc5..aa624b83 100644 --- a/src/Record/HlsMediaSource.h +++ b/src/Record/HlsMediaSource.h @@ -80,7 +80,7 @@ public: } void onSegmentSize(uint64_t bytes) { - _speed += bytes; + _speed[TrackVideo] += bytes; } private: diff --git a/src/Rtmp/Rtmp.cpp b/src/Rtmp/Rtmp.cpp index b7046163..0c80692c 100644 --- a/src/Rtmp/Rtmp.cpp +++ b/src/Rtmp/Rtmp.cpp @@ -12,7 +12,7 @@ #include "Extension/Factory.h" namespace mediakit{ -VideoMeta::VideoMeta(const VideoTrack::Ptr &video,int datarate ){ +VideoMeta::VideoMeta(const VideoTrack::Ptr &video){ if(video->getVideoWidth() > 0 ){ _metadata.set("width", video->getVideoWidth()); } @@ -22,13 +22,17 @@ VideoMeta::VideoMeta(const VideoTrack::Ptr &video,int datarate ){ if(video->getVideoFps() > 0 ){ _metadata.set("framerate", video->getVideoFps()); } - _metadata.set("videodatarate", datarate); + if (video->getBitRate()) { + _metadata.set("videodatarate", video->getBitRate() / 1024); + } _codecId = video->getCodecId(); _metadata.set("videocodecid", Factory::getAmfByCodecId(_codecId)); } -AudioMeta::AudioMeta(const AudioTrack::Ptr &audio,int datarate){ - _metadata.set("audiodatarate", datarate); +AudioMeta::AudioMeta(const AudioTrack::Ptr &audio){ + if (audio->getBitRate()) { + _metadata.set("audiodatarate", audio->getBitRate() / 1024); + } if(audio->getAudioSampleRate() > 0){ _metadata.set("audiosamplerate", audio->getAudioSampleRate()); } diff --git a/src/Rtmp/Rtmp.h b/src/Rtmp/Rtmp.h index 1f8d1e3e..f9f9790a 100644 --- a/src/Rtmp/Rtmp.h +++ b/src/Rtmp/Rtmp.h @@ -261,7 +261,7 @@ class VideoMeta : public Metadata{ public: typedef std::shared_ptr Ptr; - VideoMeta(const VideoTrack::Ptr &video,int datarate = 5000); + VideoMeta(const VideoTrack::Ptr &video); virtual ~VideoMeta(){} CodecId getCodecId() const override{ @@ -275,7 +275,7 @@ class AudioMeta : public Metadata{ public: typedef std::shared_ptr Ptr; - AudioMeta(const AudioTrack::Ptr &audio,int datarate = 160); + AudioMeta(const AudioTrack::Ptr &audio); virtual ~AudioMeta(){} diff --git a/src/Rtmp/RtmpDemuxer.cpp b/src/Rtmp/RtmpDemuxer.cpp index 53ce4c87..5225ce32 100644 --- a/src/Rtmp/RtmpDemuxer.cpp +++ b/src/Rtmp/RtmpDemuxer.cpp @@ -19,6 +19,8 @@ bool RtmpDemuxer::loadMetaData(const AMFValue &val){ int audiosamplerate = 0; int audiochannels = 0; int audiosamplesize = 0; + int videodatarate = 0; + int audiodatarate = 0; const AMFValue *audiocodecid = nullptr; const AMFValue *videocodecid = nullptr; val.object_for_each([&](const string &key, const AMFValue &val) { @@ -48,16 +50,24 @@ bool RtmpDemuxer::loadMetaData(const AMFValue &val){ audiocodecid = &val; return; } + if (key == "audiodatarate") { + audiodatarate = val.as_integer(); + return; + } + if (key == "videodatarate") { + videodatarate = val.as_integer(); + return; + } }); if (videocodecid) { //有视频 ret = true; - makeVideoTrack(*videocodecid); + makeVideoTrack(*videocodecid, videodatarate * 1024); } if (audiocodecid) { //有音频 ret = true; - makeAudioTrack(*audiocodecid, audiosamplerate, audiochannels, audiosamplesize); + makeAudioTrack(*audiocodecid, audiosamplerate, audiochannels, audiosamplesize, audiodatarate * 1024); } } catch (std::exception &ex) { WarnL << ex.what(); @@ -71,7 +81,7 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) { if (!_try_get_video_track) { _try_get_video_track = true; auto codec = AMFValue(pkt->getMediaType()); - makeVideoTrack(codec); + makeVideoTrack(codec, 0); } if (_video_rtmp_decoder) { _video_rtmp_decoder->inputRtmp(pkt); @@ -83,7 +93,7 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) { if (!_try_get_audio_track) { _try_get_audio_track = true; auto codec = AMFValue(pkt->getMediaType()); - makeAudioTrack(codec, pkt->getAudioSampleRate(), pkt->getAudioChannel(), pkt->getAudioSampleBit()); + makeAudioTrack(codec, pkt->getAudioSampleRate(), pkt->getAudioChannel(), pkt->getAudioSampleBit(), 0); } if (_audio_rtmp_decoder) { _audio_rtmp_decoder->inputRtmp(pkt); @@ -94,10 +104,11 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) { } } -void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { +void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec, int bit_rate) { //生成Track对象 _videoTrack = dynamic_pointer_cast(Factory::getVideoTrackByAmf(videoCodec)); if (_videoTrack) { + _videoTrack->setBitRate(bit_rate); //生成rtmpCodec对象以便解码rtmp _video_rtmp_decoder = Factory::getRtmpCodecByTrack(_videoTrack, false); if (_video_rtmp_decoder) { @@ -112,10 +123,11 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { } } -void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec,int sample_rate, int channels, int sample_bit) { +void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec,int sample_rate, int channels, int sample_bit, int bit_rate) { //生成Track对象 _audioTrack = dynamic_pointer_cast(Factory::getAudioTrackByAmf(audioCodec, sample_rate, channels, sample_bit)); if (_audioTrack) { + _audioTrack->setBitRate(bit_rate); //生成rtmpCodec对象以便解码rtmp _audio_rtmp_decoder = Factory::getRtmpCodecByTrack(_audioTrack, false); if (_audio_rtmp_decoder) { diff --git a/src/Rtmp/RtmpDemuxer.h b/src/Rtmp/RtmpDemuxer.h index 253cad69..f339ced3 100644 --- a/src/Rtmp/RtmpDemuxer.h +++ b/src/Rtmp/RtmpDemuxer.h @@ -39,8 +39,8 @@ public: void inputRtmp(const RtmpPacket::Ptr &pkt); private: - void makeVideoTrack(const AMFValue &val); - void makeAudioTrack(const AMFValue &val, int sample_rate, int channels, int sample_bit); + void makeVideoTrack(const AMFValue &val, int bit_rate); + void makeAudioTrack(const AMFValue &val, int sample_rate, int channels, int sample_bit, int bit_rate); private: bool _try_get_video_track = false; diff --git a/src/Rtmp/RtmpMediaSource.h b/src/Rtmp/RtmpMediaSource.h index 8d309654..483ff1ba 100644 --- a/src/Rtmp/RtmpMediaSource.h +++ b/src/Rtmp/RtmpMediaSource.h @@ -119,7 +119,8 @@ public: * @param pkt rtmp包 */ void onWrite(RtmpPacket::Ptr pkt, bool = true) override { - _speed += pkt->size(); + bool is_video = pkt->type_id == MSG_VIDEO; + _speed[is_video ? TrackVideo : TrackAudio] += pkt->size(); //保存当前时间戳 switch (pkt->type_id) { case MSG_VIDEO : _track_stamps[TrackVideo] = pkt->time_stamp, _have_video = true; break; @@ -153,7 +154,6 @@ public: } } bool key = pkt->isVideoKeyFrame(); - bool is_video = pkt->type_id == MSG_VIDEO; auto stamp = pkt->time_stamp; PacketCache::inputPacket(stamp, is_video, std::move(pkt), key); } diff --git a/src/Rtsp/RtspDemuxer.cpp b/src/Rtsp/RtspDemuxer.cpp index 2c406b2a..cee1aab4 100644 --- a/src/Rtsp/RtspDemuxer.cpp +++ b/src/Rtsp/RtspDemuxer.cpp @@ -63,11 +63,21 @@ bool RtspDemuxer::inputRtp(const RtpPacket::Ptr & rtp) { } } +static void setBitRate(const SdpTrack::Ptr &sdp, const Track::Ptr &track){ + if (!sdp->_b.empty()) { + int data_rate = 0; + sscanf(sdp->_b.data(), "AS:%d", &data_rate); + if (data_rate) { + track->setBitRate(data_rate * 1024); + } + } +} void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) { //生成Track对象 _audioTrack = dynamic_pointer_cast(Factory::getTrackBySdp(audio)); if(_audioTrack){ + setBitRate(audio, _audioTrack); //生成RtpCodec对象以便解码rtp _audioRtpDecoder = Factory::getRtpDecoderByTrack(_audioTrack); if(_audioRtpDecoder){ @@ -85,6 +95,7 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) { //生成Track对象 _videoTrack = dynamic_pointer_cast(Factory::getTrackBySdp(video)); if(_videoTrack){ + setBitRate(video, _videoTrack); //生成RtpCodec对象以便解码rtp _videoRtpDecoder = Factory::getRtpDecoderByTrack(_videoTrack); if(_videoRtpDecoder){ diff --git a/src/Rtsp/RtspMediaSource.h b/src/Rtsp/RtspMediaSource.h index 119a3e4c..77b5d97b 100644 --- a/src/Rtsp/RtspMediaSource.h +++ b/src/Rtsp/RtspMediaSource.h @@ -157,7 +157,7 @@ public: * @param keyPos 该包是否为关键帧的第一个包 */ void onWrite(RtpPacket::Ptr rtp, bool keyPos) override { - _speed += rtp->size(); + _speed[rtp->type] += rtp->size(); assert(rtp->type >= 0 && rtp->type < TrackMax); auto &track = _tracks[rtp->type]; if (track) { diff --git a/src/TS/TSMediaSource.h b/src/TS/TSMediaSource.h index f13ad1c1..10e6fe77 100644 --- a/src/TS/TSMediaSource.h +++ b/src/TS/TSMediaSource.h @@ -65,7 +65,7 @@ public: * @param key 是否为关键帧第一个包 */ void onWrite(TSPacket::Ptr packet, bool key) override { - _speed += packet->size(); + _speed[TrackVideo] += packet->size(); if (!_ring) { createRing(); } From dc3701e6ccbca7845cee40e7802c05a9c18b395c Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Sun, 6 Dec 2020 21:08:16 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8Drtp=E5=AD=98=E5=9C=A8ext?= =?UTF-8?q?=E6=97=B6=E6=97=A0=E6=B3=95=E8=A7=A3=E6=9E=90=E7=9A=84bug:#585?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtsp/RtpReceiver.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Rtsp/RtpReceiver.cpp b/src/Rtsp/RtpReceiver.cpp index 3ae03e01..75d5b45e 100644 --- a/src/Rtsp/RtpReceiver.cpp +++ b/src/Rtsp/RtpReceiver.cpp @@ -101,16 +101,18 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate, //ssrc匹配正确,不匹配计数清零 _ssrc_err_count[track_index] = 0; - //获取rtp中媒体数据偏移量 - rtp.offset = 12 + 4; + //rtp 12个固定字节头 + rtp.offset = 12; + //rtp有csrc rtp.offset += 4 * csrc; - if (ext && rtp_raw_len >= rtp.offset) { - /* calculate the header extension length (stored as number of 32-bit words) */ - ext = (AV_RB16(rtp_raw_ptr + rtp.offset - 2) + 1) << 2; - rtp.offset += ext; + if (ext) { + //rtp有ext + uint16_t reserved = AV_RB16(rtp_raw_ptr + rtp.offset); + uint16_t extlen = AV_RB16(rtp_raw_ptr + rtp.offset + 2) << 2; + rtp.offset += extlen + 4; } - if (rtp_raw_len + 4 <= rtp.offset) { + if (rtp_raw_len <= rtp.offset) { WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int) rtp.offset; return false; } @@ -128,9 +130,10 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate, payload_ptr[1] = rtp.interleaved; payload_ptr[2] = rtp_raw_len >> 8; payload_ptr[3] = (rtp_raw_len & 0x00FF); + //添加rtp over tcp前4个字节的偏移量 + rtp.offset += 4; //拷贝rtp负载 memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len); - //排序rtp auto seq = rtp_ptr->sequence; _rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr)); From c0a4170086872ef2a401b58c97cdc6645a9520eb Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Sun, 6 Dec 2020 21:50:41 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96http=20api=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BB=A3=E7=A0=81,=E6=96=B9=E4=BE=BF=E8=87=AA?= =?UTF-8?q?=E7=94=B1=E6=B7=BB=E5=8A=A0=E4=B8=8D=E5=90=8C=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E7=9A=84api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/WebApi.cpp | 102 +++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/server/WebApi.cpp b/server/WebApi.cpp index eee13997..b0fc78ec 100644 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -9,10 +9,8 @@ */ #include -#include #include #include -#include #include #include "jsoncpp/json.h" #include "Util/util.h" @@ -30,7 +28,6 @@ #include "Player/PlayerProxy.h" #include "Util/MD5.h" #include "WebApi.h" -#include "WebHook.h" #include "Thread/WorkThreadPool.h" #include "Rtp/RtpSelector.h" #include "FFmpegSource.h" @@ -98,25 +95,58 @@ public: #define API_ARGS1 SockInfo &sender,HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val #define API_ARGS2 API_ARGS1, const HttpSession::HttpResponseInvoker &invoker #define API_ARGS_VALUE1 sender,headerIn,headerOut,allArgs,val -#define API_ARGS_VALUE2 API_ARGS_VALUE1, invoker typedef map ApiArgsType; +typedef function HttpApi; //http api列表 -static map > s_map_api; +static map s_map_api; -template -static void api_regist1(const string &api_path, FUNC &&func) { - s_map_api.emplace(api_path, [func](API_ARGS2) { - func(API_ARGS_VALUE1); +static void responseApi(const Json::Value &res, const HttpSession::HttpResponseInvoker &invoker){ + GET_CONFIG(string, charSet, Http::kCharSet); + HttpSession::KeyValue headerOut; + headerOut["Content-Type"] = string("application/json; charset=") + charSet; + invoker("200 OK", headerOut, res.toStyledString()); +}; + +static void responseApi(int code, const string &msg, const HttpSession::HttpResponseInvoker &invoker){ + Json::Value res; + res["code"] = code; + res["msg"] = msg; + responseApi(res, invoker); +} + +static ApiArgsType getAllArgs(const Parser &parser); + +static HttpApi toApi(const function &cb) { + return [cb](const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender) { + GET_CONFIG(string, charSet, Http::kCharSet); + HttpSession::KeyValue headerOut; + headerOut["Content-Type"] = string("application/json; charset=") + charSet; + + Json::Value val; + val["code"] = API::Success; + + auto args = getAllArgs(parser); + cb(sender, parser.getHeader(), headerOut, args, val, invoker); + }; +} + +static HttpApi toApi(const function &cb) { + return toApi([cb](API_ARGS2) { + cb(API_ARGS_VALUE1); invoker("200 OK", headerOut, val.toStyledString()); }); } template -static void api_regist2(const string &api_path, FUNC &&func) { - s_map_api.emplace(api_path, std::forward(func)); +static void api_regist(const string &api_path, FUNC &&func) { + s_map_api.emplace(api_path, toApi(std::move(func))); } +#define api_regist1 api_regist +#define api_regist2 api_regist + + //获取HTTP请求中url参数、content参数 static ApiArgsType getAllArgs(const Parser &parser) { ApiArgsType allArgs; @@ -157,22 +187,11 @@ static inline void addHttpListener(){ } //该api已被消费 consumed = true; - //执行API - Json::Value val; - val["code"] = API::Success; - HttpSession::KeyValue headerOut; - auto allArgs = getAllArgs(parser); - HttpSession::KeyValue &headerIn = parser.getHeader(); - GET_CONFIG(string,charSet,Http::kCharSet); - headerOut["Content-Type"] = StrPrinter << "application/json; charset=" << charSet; + if(api_debug){ - auto newInvoker = [invoker,parser,allArgs](const string &codeOut, - const HttpSession::KeyValue &headerOut, - const HttpBody::Ptr &body){ - stringstream ss; - for(auto &pr : allArgs ){ - ss << pr.first << " : " << pr.second << "\r\n"; - } + auto newInvoker = [invoker, parser](const string &codeOut, + const HttpSession::KeyValue &headerOut, + const HttpBody::Ptr &body) { //body默认为空 int64_t size = 0; @@ -181,45 +200,36 @@ static inline void addHttpListener(){ size = body->remainSize(); } - if(size && size < 4 * 1024){ + if (size && size < 4 * 1024) { string contentOut = body->readData(size)->toString(); DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n" << "# content:\r\n" << parser.Content() << "\r\n" - << "# args:\r\n" << ss.str() << "# response:\r\n" << contentOut << "\r\n"; - invoker(codeOut,headerOut,contentOut); - } else{ + invoker(codeOut, headerOut, contentOut); + } else { DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n" << "# content:\r\n" << parser.Content() << "\r\n" - << "# args:\r\n" << ss.str() << "# response size:" - << size <<"\r\n"; - invoker(codeOut,headerOut,body); + << size << "\r\n"; + invoker(codeOut, headerOut, body); } }; - ((HttpSession::HttpResponseInvoker &)invoker) = newInvoker; + ((HttpSession::HttpResponseInvoker &) invoker) = newInvoker; } try { - it->second(sender,headerIn, headerOut, allArgs, val, invoker); - } catch(ApiRetException &ex){ - val["code"] = ex.code(); - val["msg"] = ex.what(); - invoker("200 OK", headerOut, val.toStyledString()); + it->second(parser, invoker, sender); + } catch (ApiRetException &ex) { + responseApi(ex.code(), ex.what(), invoker); } #ifdef ENABLE_MYSQL catch(SqlException &ex){ - val["code"] = API::SqlFailed; - val["msg"] = StrPrinter << "操作数据库失败:" << ex.what() << ":" << ex.getSql(); - WarnL << ex.what() << ":" << ex.getSql(); - invoker("200 OK", headerOut, val.toStyledString()); + responseApi(API::SqlFailed, StrPrinter << "操作数据库失败:" << ex.what() << ":" << ex.getSql(), invoker); } #endif// ENABLE_MYSQL catch (std::exception &ex) { - val["code"] = API::Exception; - val["msg"] = ex.what(); - invoker("200 OK", headerOut, val.toStyledString()); + responseApi(API::Exception, ex.what(), invoker); } }); } From 8b2fb0bc1f0ad433329ed326af5a7be7d34dc71b Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Sun, 6 Dec 2020 22:36:44 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8DLinux=E4=B8=8B=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/WebApi.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/WebApi.cpp b/server/WebApi.cpp index b0fc78ec..61ee2221 100644 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -28,6 +29,7 @@ #include "Player/PlayerProxy.h" #include "Util/MD5.h" #include "WebApi.h" +#include "WebHook.h" #include "Thread/WorkThreadPool.h" #include "Rtp/RtpSelector.h" #include "FFmpegSource.h"