Commit 68926b4a by ziyue

支持bitrate

parent 42679cdf
......@@ -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 {
......
......@@ -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;
......
......@@ -185,7 +185,7 @@ Sdp::Ptr AACTrack::getSdp() {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<AACSdp>(getAacCfg(),getAudioSampleRate(), getAudioChannel());
return std::make_shared<AACSdp>(getAacCfg(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}
}//namespace mediakit
\ No newline at end of file
......@@ -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";
if (bitrate) {
_printer << "b=AS:" << bitrate << "\r\n";
}
_printer << "a=rtpmap:" << payload_type << " MPEG4-GENERIC/" << sample_rate << "/" << channels << "\r\n";
string configStr;
......
......@@ -17,7 +17,7 @@ Sdp::Ptr G711Track::getSdp() {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getAudioChannel());
return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}
}//namespace mediakit
......
......@@ -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";
}
......
......@@ -123,7 +123,7 @@ Sdp::Ptr H264Track::getSdp() {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<H264Sdp>(getSps(),getPps());
return std::make_shared<H264Sdp>(getSps(), getPps(), getBitRate() / 1024);
}
}//namespace mediakit
......
......@@ -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";
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=";
......
......@@ -55,7 +55,7 @@ Sdp::Ptr H265Track::getSdp() {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<H265Sdp>(getVps(),getSps(),getPps());
return std::make_shared<H265Sdp>(getVps(), getSps(), getPps(), getBitRate() / 1024);
}
}//namespace mediakit
......@@ -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";
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=";
......
......@@ -17,7 +17,7 @@ Sdp::Ptr OpusTrack::getSdp() {
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<OpusSdp>(getAudioSampleRate(), getAudioChannel());
return std::make_shared<OpusSdp>(getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}
}//namespace mediakit
\ No newline at end of file
......@@ -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";
}
......
......@@ -32,7 +32,6 @@ public:
/**
* 是否准备好,准备好才能获取譬如sps pps等信息
* @return
*/
virtual bool ready() = 0;
......@@ -40,7 +39,6 @@ public:
* 克隆接口,用于复制本对象用
* 在调用该接口时只会复制派生类的信息
* 环形缓存和代理关系不能拷贝,否则会关系紊乱
* @return
*/
virtual Track::Ptr clone() = 0;
......@@ -51,11 +49,27 @@ 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;};
};
......
......@@ -88,7 +88,7 @@ public:
if (key) {
_have_video = true;
}
_speed += packet->size();
_speed[TrackVideo] += packet->size();
auto stamp = packet->time_stamp;
PacketCache<FMP4Packet>::inputPacket(stamp, true, std::move(packet), key);
}
......
......@@ -80,7 +80,7 @@ public:
}
void onSegmentSize(uint64_t bytes) {
_speed += bytes;
_speed[TrackVideo] += bytes;
}
private:
......
......@@ -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());
}
......
......@@ -261,7 +261,7 @@ class VideoMeta : public Metadata{
public:
typedef std::shared_ptr<VideoMeta> 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<AudioMeta> Ptr;
AudioMeta(const AudioTrack::Ptr &audio,int datarate = 160);
AudioMeta(const AudioTrack::Ptr &audio);
virtual ~AudioMeta(){}
......
......@@ -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<VideoTrack>(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<AudioTrack>(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) {
......
......@@ -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;
......
......@@ -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<RtmpPacket>::inputPacket(stamp, is_video, std::move(pkt), key);
}
......
......@@ -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<AudioTrack>(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<VideoTrack>(Factory::getTrackBySdp(video));
if(_videoTrack){
setBitRate(video, _videoTrack);
//生成RtpCodec对象以便解码rtp
_videoRtpDecoder = Factory::getRtpDecoderByTrack(_videoTrack);
if(_videoRtpDecoder){
......
......@@ -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) {
......
......@@ -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();
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论