Merge remote-tracking branch 'upstream/master'

This commit is contained in:
monktan 2020-12-07 11:40:22 +08:00
commit 394c540bba
27 changed files with 131 additions and 65 deletions

View File

@ -68,8 +68,11 @@ const string& MediaSource::getId() const {
return _stream_id; return _stream_id;
} }
int MediaSource::getBytesSpeed(){ int MediaSource::getBytesSpeed(TrackType type){
return _speed.getSpeed(); if(type == TrackInvalid){
return _speed[TrackVideo].getSpeed() + _speed[TrackAudio].getSpeed();
}
return _speed[type].getSpeed();
} }
uint64_t MediaSource::getCreateStamp() const { uint64_t MediaSource::getCreateStamp() const {

View File

@ -220,7 +220,7 @@ public:
virtual void setTimeStamp(uint32_t stamp) {}; virtual void setTimeStamp(uint32_t stamp) {};
// 获取数据速率单位bytes/s // 获取数据速率单位bytes/s
int getBytesSpeed(); int getBytesSpeed(TrackType type = TrackInvalid);
// 获取流创建GMT unix时间戳单位秒 // 获取流创建GMT unix时间戳单位秒
uint64_t getCreateStamp() const; uint64_t getCreateStamp() const;
// 获取流上线时间,单位秒 // 获取流上线时间,单位秒
@ -286,7 +286,7 @@ private:
void emitEvent(bool regist); void emitEvent(bool regist);
protected: protected:
BytesSpeed _speed; BytesSpeed _speed[TrackMax];
private: private:
time_t _create_stamp; time_t _create_stamp;

View File

@ -185,7 +185,7 @@ Sdp::Ptr AACTrack::getSdp() {
WarnL << getCodecName() << " Track未准备好"; WarnL << getCodecName() << " Track未准备好";
return nullptr; return nullptr;
} }
return std::make_shared<AACSdp>(getAacCfg(),getAudioSampleRate(), getAudioChannel()); return std::make_shared<AACSdp>(getAacCfg(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
} }
}//namespace mediakit }//namespace mediakit

View File

@ -177,10 +177,12 @@ public:
AACSdp(const string &aac_cfg, AACSdp(const string &aac_cfg,
int sample_rate, int sample_rate,
int channels, int channels,
int payload_type = 98, int bitrate = 128,
int bitrate = 128) : Sdp(sample_rate,payload_type){ int payload_type = 98) : Sdp(sample_rate,payload_type){
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n"; _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"; _printer << "a=rtpmap:" << payload_type << " MPEG4-GENERIC/" << sample_rate << "/" << channels << "\r\n";
string configStr; string configStr;

View File

@ -17,7 +17,7 @@ Sdp::Ptr G711Track::getSdp() {
WarnL << getCodecName() << " Track未准备好"; WarnL << getCodecName() << " Track未准备好";
return nullptr; return nullptr;
} }
return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getAudioChannel()); return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
} }
}//namespace mediakit }//namespace mediakit

View File

@ -48,9 +48,12 @@ public:
G711Sdp(CodecId codecId, G711Sdp(CodecId codecId,
int sample_rate, int sample_rate,
int channels, int channels,
int payload_type = 98, int bitrate = 128,
int bitrate = 128) : Sdp(sample_rate,payload_type), _codecId(codecId){ int payload_type = 98) : Sdp(sample_rate,payload_type), _codecId(codecId){
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n"; _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=rtpmap:" << payload_type << (codecId == CodecG711A ? " PCMA/" : " PCMU/") << sample_rate << "/" << channels << "\r\n";
_printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n";
} }

View File

@ -123,7 +123,7 @@ Sdp::Ptr H264Track::getSdp() {
WarnL << getCodecName() << " Track未准备好"; WarnL << getCodecName() << " Track未准备好";
return nullptr; return nullptr;
} }
return std::make_shared<H264Sdp>(getSps(),getPps()); return std::make_shared<H264Sdp>(getSps(), getPps(), getBitRate() / 1024);
} }
}//namespace mediakit }//namespace mediakit

View File

@ -292,11 +292,13 @@ public:
*/ */
H264Sdp(const string &strSPS, H264Sdp(const string &strSPS,
const string &strPPS, const string &strPPS,
int payload_type = 96, int bitrate = 4000,
int bitrate = 4000) : Sdp(90000,payload_type) { int payload_type = 96) : Sdp(90000,payload_type) {
//视频通道 //视频通道
_printer << "m=video 0 RTP/AVP " << payload_type << "\r\n"; _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=rtpmap:" << payload_type << " H264/" << 90000 << "\r\n";
_printer << "a=fmtp:" << payload_type << " packetization-mode=1; profile-level-id="; _printer << "a=fmtp:" << payload_type << " packetization-mode=1; profile-level-id=";

View File

@ -55,7 +55,7 @@ Sdp::Ptr H265Track::getSdp() {
WarnL << getCodecName() << " Track未准备好"; WarnL << getCodecName() << " Track未准备好";
return nullptr; return nullptr;
} }
return std::make_shared<H265Sdp>(getVps(),getSps(),getPps()); return std::make_shared<H265Sdp>(getVps(), getSps(), getPps(), getBitRate() / 1024);
} }
}//namespace mediakit }//namespace mediakit

View File

@ -321,11 +321,13 @@ public:
H265Sdp(const string &strVPS, H265Sdp(const string &strVPS,
const string &strSPS, const string &strSPS,
const string &strPPS, const string &strPPS,
int payload_type = 96, int bitrate = 4000,
int bitrate = 4000) : Sdp(90000,payload_type) { int payload_type = 96) : Sdp(90000,payload_type) {
//视频通道 //视频通道
_printer << "m=video 0 RTP/AVP " << payload_type << "\r\n"; _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=rtpmap:" << payload_type << " H265/" << 90000 << "\r\n";
_printer << "a=fmtp:" << payload_type << " "; _printer << "a=fmtp:" << payload_type << " ";
_printer << "sprop-vps="; _printer << "sprop-vps=";

View File

@ -17,7 +17,7 @@ Sdp::Ptr OpusTrack::getSdp() {
WarnL << getCodecName() << " Track未准备好"; WarnL << getCodecName() << " Track未准备好";
return nullptr; return nullptr;
} }
return std::make_shared<OpusSdp>(getAudioSampleRate(), getAudioChannel()); return std::make_shared<OpusSdp>(getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
} }
}//namespace mediakit }//namespace mediakit

View File

@ -46,9 +46,12 @@ public:
*/ */
OpusSdp(int sample_rate, OpusSdp(int sample_rate,
int channels, int channels,
int payload_type = 98, int bitrate = 128,
int bitrate = 128) : Sdp(sample_rate,payload_type){ int payload_type = 98) : Sdp(sample_rate,payload_type){
_printer << "m=audio 0 RTP/AVP " << payload_type << "\r\n"; _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=rtpmap:" << payload_type << " opus/" << sample_rate << "/" << channels << "\r\n";
_printer << "a=control:trackID=" << (int)TrackAudio << "\r\n"; _printer << "a=control:trackID=" << (int)TrackAudio << "\r\n";
} }

View File

@ -32,7 +32,6 @@ public:
/** /**
* sps pps等信息 * sps pps等信息
* @return
*/ */
virtual bool ready() = 0; virtual bool ready() = 0;
@ -40,7 +39,6 @@ public:
* *
* *
* *
* @return
*/ */
virtual Track::Ptr clone() = 0; virtual Track::Ptr clone() = 0;
@ -50,12 +48,28 @@ public:
*/ */
virtual Sdp::Ptr getSdp() = 0; 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;}; virtual int getVideoHeight() const {return 0;};
/** /**
* *
* @return
*/ */
virtual int getVideoWidth() const {return 0;}; virtual int getVideoWidth() const {return 0;};
/** /**
* fps * fps
* @return
*/ */
virtual float getVideoFps() const {return 0;}; virtual float getVideoFps() const {return 0;};
}; };
@ -93,19 +104,16 @@ public:
/** /**
* *
* @return
*/ */
virtual int getAudioSampleRate() const {return 0;}; virtual int getAudioSampleRate() const {return 0;};
/** /**
* 168 * 168
* @return
*/ */
virtual int getAudioSampleBit() const {return 0;}; virtual int getAudioSampleBit() const {return 0;};
/** /**
* *
* @return
*/ */
virtual int getAudioChannel() const {return 0;}; virtual int getAudioChannel() const {return 0;};
}; };

View File

@ -88,7 +88,7 @@ public:
if (key) { if (key) {
_have_video = true; _have_video = true;
} }
_speed += packet->size(); _speed[TrackVideo] += packet->size();
auto stamp = packet->time_stamp; auto stamp = packet->time_stamp;
PacketCache<FMP4Packet>::inputPacket(stamp, true, std::move(packet), key); PacketCache<FMP4Packet>::inputPacket(stamp, true, std::move(packet), key);
} }

View File

@ -20,6 +20,7 @@ HttpTSPlayer::HttpTSPlayer(const EventPoller::Ptr &poller, bool split_ts){
HttpTSPlayer::~HttpTSPlayer() {} HttpTSPlayer::~HttpTSPlayer() {}
int64_t HttpTSPlayer::onResponseHeader(const string &status, const HttpClient::HttpHeader &headers) { int64_t HttpTSPlayer::onResponseHeader(const string &status, const HttpClient::HttpHeader &headers) {
_status = status;
if (status != "200" && status != "206") { if (status != "200" && status != "206") {
//http状态码不符合预期 //http状态码不符合预期
shutdown(SockException(Err_other, StrPrinter << "bad http status code:" + status)); shutdown(SockException(Err_other, StrPrinter << "bad http status code:" + status));
@ -35,6 +36,9 @@ int64_t HttpTSPlayer::onResponseHeader(const string &status, const HttpClient::H
} }
void HttpTSPlayer::onResponseBody(const char *buf, int64_t size, int64_t recvedSize, int64_t totalSize) { void HttpTSPlayer::onResponseBody(const char *buf, int64_t size, int64_t recvedSize, int64_t totalSize) {
if (_status != "200" && _status != "206") {
return;
}
if (recvedSize == size) { if (recvedSize == size) {
//开始接收数据 //开始接收数据
if (buf[0] == TS_SYNC_BYTE) { if (buf[0] == TS_SYNC_BYTE) {

View File

@ -48,6 +48,7 @@ private:
bool _is_first_packet_ts = false; bool _is_first_packet_ts = false;
//是否判断是否是ts并split //是否判断是否是ts并split
bool _split_ts; bool _split_ts;
string _status;
TSSegment _segment; TSSegment _segment;
onShutdown _on_disconnect; onShutdown _on_disconnect;
TSSegment::onSegment _on_segment; TSSegment::onSegment _on_segment;

View File

@ -80,7 +80,7 @@ public:
} }
void onSegmentSize(uint64_t bytes) { void onSegmentSize(uint64_t bytes) {
_speed += bytes; _speed[TrackVideo] += bytes;
} }
private: private:

View File

@ -11,6 +11,7 @@
#ifdef ENABLE_MP4 #ifdef ENABLE_MP4
#include <ctime> #include <ctime>
#include <sys/stat.h> #include <sys/stat.h>
#include "Util/File.h"
#include "Common/config.h" #include "Common/config.h"
#include "MP4Recorder.h" #include "MP4Recorder.h"
#include "Thread/WorkThreadPool.h" #include "Thread/WorkThreadPool.h"
@ -77,12 +78,19 @@ void MP4Recorder::asyncClose() {
const_cast<RecordInfo&>(info).time_len = ::time(NULL) - info.start_time; const_cast<RecordInfo&>(info).time_len = ::time(NULL) - info.start_time;
//关闭mp4非常耗时所以要放在后台线程执行 //关闭mp4非常耗时所以要放在后台线程执行
muxer->closeMP4(); muxer->closeMP4();
//临时文件名改成正式文件名防止mp4未完成时被访问
rename(strFileTmp.data(),strFile.data());
//获取文件大小 //获取文件大小
struct stat fileData; struct stat fileData;
stat(strFile.data(), &fileData); stat(strFileTmp.data(), &fileData);
const_cast<RecordInfo&>(info).file_size = fileData.st_size; const_cast<RecordInfo &>(info).file_size = fileData.st_size;
if (fileData.st_size < 1024) {
//录像文件太小,删除之
File::delete_file(strFileTmp.data());
return;
}
//临时文件名改成正式文件名防止mp4未完成时被访问
rename(strFileTmp.data(),strFile.data());
/////record 业务逻辑////// /////record 业务逻辑//////
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastRecordMP4,info); NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastRecordMP4,info);
}); });

View File

@ -12,7 +12,7 @@
#include "Extension/Factory.h" #include "Extension/Factory.h"
namespace mediakit{ namespace mediakit{
VideoMeta::VideoMeta(const VideoTrack::Ptr &video,int datarate ){ VideoMeta::VideoMeta(const VideoTrack::Ptr &video){
if(video->getVideoWidth() > 0 ){ if(video->getVideoWidth() > 0 ){
_metadata.set("width", video->getVideoWidth()); _metadata.set("width", video->getVideoWidth());
} }
@ -22,13 +22,17 @@ VideoMeta::VideoMeta(const VideoTrack::Ptr &video,int datarate ){
if(video->getVideoFps() > 0 ){ if(video->getVideoFps() > 0 ){
_metadata.set("framerate", video->getVideoFps()); _metadata.set("framerate", video->getVideoFps());
} }
_metadata.set("videodatarate", datarate); if (video->getBitRate()) {
_metadata.set("videodatarate", video->getBitRate() / 1024);
}
_codecId = video->getCodecId(); _codecId = video->getCodecId();
_metadata.set("videocodecid", Factory::getAmfByCodecId(_codecId)); _metadata.set("videocodecid", Factory::getAmfByCodecId(_codecId));
} }
AudioMeta::AudioMeta(const AudioTrack::Ptr &audio,int datarate){ AudioMeta::AudioMeta(const AudioTrack::Ptr &audio){
_metadata.set("audiodatarate", datarate); if (audio->getBitRate()) {
_metadata.set("audiodatarate", audio->getBitRate() / 1024);
}
if(audio->getAudioSampleRate() > 0){ if(audio->getAudioSampleRate() > 0){
_metadata.set("audiosamplerate", audio->getAudioSampleRate()); _metadata.set("audiosamplerate", audio->getAudioSampleRate());
} }

View File

@ -262,7 +262,7 @@ class VideoMeta : public Metadata{
public: public:
typedef std::shared_ptr<VideoMeta> Ptr; typedef std::shared_ptr<VideoMeta> Ptr;
VideoMeta(const VideoTrack::Ptr &video,int datarate = 5000); VideoMeta(const VideoTrack::Ptr &video);
virtual ~VideoMeta(){} virtual ~VideoMeta(){}
CodecId getCodecId() const override{ CodecId getCodecId() const override{
@ -276,7 +276,7 @@ class AudioMeta : public Metadata{
public: public:
typedef std::shared_ptr<AudioMeta> Ptr; typedef std::shared_ptr<AudioMeta> Ptr;
AudioMeta(const AudioTrack::Ptr &audio,int datarate = 160); AudioMeta(const AudioTrack::Ptr &audio);
virtual ~AudioMeta(){} virtual ~AudioMeta(){}

View File

@ -19,6 +19,8 @@ bool RtmpDemuxer::loadMetaData(const AMFValue &val){
int audiosamplerate = 0; int audiosamplerate = 0;
int audiochannels = 0; int audiochannels = 0;
int audiosamplesize = 0; int audiosamplesize = 0;
int videodatarate = 0;
int audiodatarate = 0;
const AMFValue *audiocodecid = nullptr; const AMFValue *audiocodecid = nullptr;
const AMFValue *videocodecid = nullptr; const AMFValue *videocodecid = nullptr;
val.object_for_each([&](const string &key, const AMFValue &val) { val.object_for_each([&](const string &key, const AMFValue &val) {
@ -48,16 +50,24 @@ bool RtmpDemuxer::loadMetaData(const AMFValue &val){
audiocodecid = &val; audiocodecid = &val;
return; return;
} }
if (key == "audiodatarate") {
audiodatarate = val.as_integer();
return;
}
if (key == "videodatarate") {
videodatarate = val.as_integer();
return;
}
}); });
if (videocodecid) { if (videocodecid) {
//有视频 //有视频
ret = true; ret = true;
makeVideoTrack(*videocodecid); makeVideoTrack(*videocodecid, videodatarate * 1024);
} }
if (audiocodecid) { if (audiocodecid) {
//有音频 //有音频
ret = true; ret = true;
makeAudioTrack(*audiocodecid, audiosamplerate, audiochannels, audiosamplesize); makeAudioTrack(*audiocodecid, audiosamplerate, audiochannels, audiosamplesize, audiodatarate * 1024);
} }
} catch (std::exception &ex) { } catch (std::exception &ex) {
WarnL << ex.what(); WarnL << ex.what();
@ -71,7 +81,7 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
if (!_try_get_video_track) { if (!_try_get_video_track) {
_try_get_video_track = true; _try_get_video_track = true;
auto codec = AMFValue(pkt->getMediaType()); auto codec = AMFValue(pkt->getMediaType());
makeVideoTrack(codec); makeVideoTrack(codec, 0);
} }
if (_video_rtmp_decoder) { if (_video_rtmp_decoder) {
_video_rtmp_decoder->inputRtmp(pkt); _video_rtmp_decoder->inputRtmp(pkt);
@ -83,7 +93,7 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
if (!_try_get_audio_track) { if (!_try_get_audio_track) {
_try_get_audio_track = true; _try_get_audio_track = true;
auto codec = AMFValue(pkt->getMediaType()); 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) { if (_audio_rtmp_decoder) {
_audio_rtmp_decoder->inputRtmp(pkt); _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对象 //生成Track对象
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getVideoTrackByAmf(videoCodec)); _videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getVideoTrackByAmf(videoCodec));
if (_videoTrack) { if (_videoTrack) {
_videoTrack->setBitRate(bit_rate);
//生成rtmpCodec对象以便解码rtmp //生成rtmpCodec对象以便解码rtmp
_video_rtmp_decoder = Factory::getRtmpCodecByTrack(_videoTrack, false); _video_rtmp_decoder = Factory::getRtmpCodecByTrack(_videoTrack, false);
if (_video_rtmp_decoder) { 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对象 //生成Track对象
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getAudioTrackByAmf(audioCodec, sample_rate, channels, sample_bit)); _audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getAudioTrackByAmf(audioCodec, sample_rate, channels, sample_bit));
if (_audioTrack) { if (_audioTrack) {
_audioTrack->setBitRate(bit_rate);
//生成rtmpCodec对象以便解码rtmp //生成rtmpCodec对象以便解码rtmp
_audio_rtmp_decoder = Factory::getRtmpCodecByTrack(_audioTrack, false); _audio_rtmp_decoder = Factory::getRtmpCodecByTrack(_audioTrack, false);
if (_audio_rtmp_decoder) { if (_audio_rtmp_decoder) {

View File

@ -39,8 +39,8 @@ public:
void inputRtmp(const RtmpPacket::Ptr &pkt); void inputRtmp(const RtmpPacket::Ptr &pkt);
private: private:
void makeVideoTrack(const AMFValue &val); void makeVideoTrack(const AMFValue &val, int bit_rate);
void makeAudioTrack(const AMFValue &val, int sample_rate, int channels, int sample_bit); void makeAudioTrack(const AMFValue &val, int sample_rate, int channels, int sample_bit, int bit_rate);
private: private:
bool _try_get_video_track = false; bool _try_get_video_track = false;

View File

@ -119,7 +119,8 @@ public:
* @param pkt rtmp包 * @param pkt rtmp包
*/ */
void onWrite(RtmpPacket::Ptr pkt, bool = true) override { 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) { switch (pkt->type_id) {
case MSG_VIDEO : _track_stamps[TrackVideo] = pkt->time_stamp, _have_video = true; break; case MSG_VIDEO : _track_stamps[TrackVideo] = pkt->time_stamp, _have_video = true; break;
@ -153,7 +154,6 @@ public:
} }
} }
bool key = pkt->isVideoKeyFrame(); bool key = pkt->isVideoKeyFrame();
bool is_video = pkt->type_id == MSG_VIDEO;
auto stamp = pkt->time_stamp; auto stamp = pkt->time_stamp;
PacketCache<RtmpPacket>::inputPacket(stamp, is_video, std::move(pkt), key); PacketCache<RtmpPacket>::inputPacket(stamp, is_video, std::move(pkt), key);
} }

View File

@ -101,16 +101,18 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate,
//ssrc匹配正确不匹配计数清零 //ssrc匹配正确不匹配计数清零
_ssrc_err_count[track_index] = 0; _ssrc_err_count[track_index] = 0;
//获取rtp中媒体数据偏移量 //rtp 12个固定字节头
rtp.offset = 12 + 4; rtp.offset = 12;
//rtp有csrc
rtp.offset += 4 * csrc; rtp.offset += 4 * csrc;
if (ext && rtp_raw_len >= rtp.offset) { if (ext) {
/* calculate the header extension length (stored as number of 32-bit words) */ //rtp有ext
ext = (AV_RB16(rtp_raw_ptr + rtp.offset - 2) + 1) << 2; uint16_t reserved = AV_RB16(rtp_raw_ptr + rtp.offset);
rtp.offset += ext; 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; WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int) rtp.offset;
return false; return false;
} }
@ -128,9 +130,10 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate,
payload_ptr[1] = rtp.interleaved; payload_ptr[1] = rtp.interleaved;
payload_ptr[2] = rtp_raw_len >> 8; payload_ptr[2] = rtp_raw_len >> 8;
payload_ptr[3] = (rtp_raw_len & 0x00FF); payload_ptr[3] = (rtp_raw_len & 0x00FF);
//添加rtp over tcp前4个字节的偏移量
rtp.offset += 4;
//拷贝rtp负载 //拷贝rtp负载
memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len); memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len);
//排序rtp //排序rtp
auto seq = rtp_ptr->sequence; auto seq = rtp_ptr->sequence;
_rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr)); _rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr));

View File

@ -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) { void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) {
//生成Track对象 //生成Track对象
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio)); _audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackBySdp(audio));
if(_audioTrack){ if(_audioTrack){
setBitRate(audio, _audioTrack);
//生成RtpCodec对象以便解码rtp //生成RtpCodec对象以便解码rtp
_audioRtpDecoder = Factory::getRtpDecoderByTrack(_audioTrack); _audioRtpDecoder = Factory::getRtpDecoderByTrack(_audioTrack);
if(_audioRtpDecoder){ if(_audioRtpDecoder){
@ -85,6 +95,7 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) {
//生成Track对象 //生成Track对象
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video)); _videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackBySdp(video));
if(_videoTrack){ if(_videoTrack){
setBitRate(video, _videoTrack);
//生成RtpCodec对象以便解码rtp //生成RtpCodec对象以便解码rtp
_videoRtpDecoder = Factory::getRtpDecoderByTrack(_videoTrack); _videoRtpDecoder = Factory::getRtpDecoderByTrack(_videoTrack);
if(_videoRtpDecoder){ if(_videoRtpDecoder){

View File

@ -157,7 +157,7 @@ public:
* @param keyPos * @param keyPos
*/ */
void onWrite(RtpPacket::Ptr rtp, bool keyPos) override { void onWrite(RtpPacket::Ptr rtp, bool keyPos) override {
_speed += rtp->size(); _speed[rtp->type] += rtp->size();
assert(rtp->type >= 0 && rtp->type < TrackMax); assert(rtp->type >= 0 && rtp->type < TrackMax);
auto &track = _tracks[rtp->type]; auto &track = _tracks[rtp->type];
if (track) { if (track) {

View File

@ -65,7 +65,7 @@ public:
* @param key * @param key
*/ */
void onWrite(TSPacket::Ptr packet, bool key) override { void onWrite(TSPacket::Ptr packet, bool key) override {
_speed += packet->size(); _speed[TrackVideo] += packet->size();
if (!_ring) { if (!_ring) {
createRing(); createRing();
} }