Merge pull request #656 from rmokerone/master

RTSP推流增加L16动态payload type支持(RFC 3551 Section 4.5.11, RFC 2586)
This commit is contained in:
夏楚 2020-12-27 21:00:34 +08:00 committed by GitHub
commit 4244cbf29e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 1 deletions

View File

@ -369,6 +369,10 @@ bool MultiMediaSourceMuxer::stopSendRtp(MediaSource &sender, const string& ssrc)
} }
void MultiMediaSourceMuxer::addTrack(const Track::Ptr &track) { void MultiMediaSourceMuxer::addTrack(const Track::Ptr &track) {
if (CodecL16 == track->getCodecId()) {
WarnL << "L16音频格式目前只支持RTSP协议推流拉流!!!";
return;
}
_muxer->addTrack(track); _muxer->addTrack(track);
} }

View File

@ -20,6 +20,7 @@
#include "CommonRtp.h" #include "CommonRtp.h"
#include "Opus.h" #include "Opus.h"
#include "G711.h" #include "G711.h"
#include "L16.h"
#include "Common/Parser.h" #include "Common/Parser.h"
namespace mediakit{ namespace mediakit{
@ -56,6 +57,10 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
return std::make_shared<G711Track>(CodecG711U, track->_samplerate, track->_channel, 16); return std::make_shared<G711Track>(CodecG711U, track->_samplerate, track->_channel, 16);
} }
if (strcasecmp(track->_codec.data(), "L16") == 0) {
return std::make_shared<L16Track>(track->_samplerate, track->_channel);
}
if (strcasecmp(track->_codec.data(), "h264") == 0) { if (strcasecmp(track->_codec.data(), "h264") == 0) {
//a=fmtp:96 packetization-mode=1;profile-level-id=42C01F;sprop-parameter-sets=Z0LAH9oBQBboQAAAAwBAAAAPI8YMqA==,aM48gA== //a=fmtp:96 packetization-mode=1;profile-level-id=42C01F;sprop-parameter-sets=Z0LAH9oBQBboQAAAAwBAAAAPI8YMqA==,aM48gA==
auto map = Parser::parseArgs(FindField(track->_fmtp.data()," ", nullptr),";","="); auto map = Parser::parseArgs(FindField(track->_fmtp.data()," ", nullptr),";","=");
@ -123,6 +128,7 @@ RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) {
case CodecH264 : return std::make_shared<H264RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved); case CodecH264 : return std::make_shared<H264RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
case CodecH265 : return std::make_shared<H265RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved); case CodecH265 : return std::make_shared<H265RtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
case CodecAAC : return std::make_shared<AACRtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved); case CodecAAC : return std::make_shared<AACRtpEncoder>(ssrc, mtu, sample_rate, pt, interleaved);
case CodecL16 :
case CodecOpus : case CodecOpus :
case CodecG711A : case CodecG711A :
case CodecG711U : return std::make_shared<CommonRtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved); case CodecG711U : return std::make_shared<CommonRtpEncoder>(codec_id, ssrc, mtu, sample_rate, pt, interleaved);
@ -135,6 +141,7 @@ RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) {
case CodecH264 : return std::make_shared<H264RtpDecoder>(); case CodecH264 : return std::make_shared<H264RtpDecoder>();
case CodecH265 : return std::make_shared<H265RtpDecoder>(); case CodecH265 : return std::make_shared<H265RtpDecoder>();
case CodecAAC : return std::make_shared<AACRtpDecoder>(track->clone()); case CodecAAC : return std::make_shared<AACRtpDecoder>(track->clone());
case CodecL16 :
case CodecOpus : case CodecOpus :
case CodecG711A : case CodecG711A :
case CodecG711U : return std::make_shared<CommonRtpDecoder>(track->getCodecId()); case CodecG711U : return std::make_shared<CommonRtpDecoder>(track->getCodecId());

View File

@ -80,6 +80,7 @@ const char *getCodecName(CodecId codecId) {
SWITCH_CASE(CodecG711A); SWITCH_CASE(CodecG711A);
SWITCH_CASE(CodecG711U); SWITCH_CASE(CodecG711U);
SWITCH_CASE(CodecOpus); SWITCH_CASE(CodecOpus);
SWITCH_CASE(CodecL16);
default : return "unknown codec"; default : return "unknown codec";
} }
} }
@ -91,7 +92,8 @@ TrackType getTrackType(CodecId codecId){
case CodecAAC: case CodecAAC:
case CodecG711A: case CodecG711A:
case CodecG711U: case CodecG711U:
case CodecOpus: return TrackAudio; case CodecOpus:
case CodecL16: return TrackAudio;
default: return TrackInvalid; default: return TrackInvalid;
} }
} }

View File

@ -29,6 +29,7 @@ typedef enum {
CodecG711A, CodecG711A,
CodecG711U, CodecG711U,
CodecOpus, CodecOpus,
CodecL16,
CodecMax = 0x7FFF CodecMax = 0x7FFF
} CodecId; } CodecId;

26
src/Extension/L16.cpp Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT 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.
*/
#include "L16.h"
namespace mediakit{
Sdp::Ptr L16Track::getSdp() {
WarnL << "Enter L16Track::getSdp function";
if(!ready()){
WarnL << getCodecName() << " Track未准备好";
return nullptr;
}
return std::make_shared<L16Sdp>(getCodecId(), getAudioSampleRate(), getAudioChannel(), getBitRate() / 1024);
}
}//namespace mediakit

74
src/Extension/L16.h Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT 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 ZLMEDIAKIT_L16_H
#define ZLMEDIAKIT_L16_H
#include "Frame.h"
#include "Track.h"
namespace mediakit{
/**
* L16音频通道
*/
class L16Track : public AudioTrackImp{
public:
typedef std::shared_ptr<L16Track> Ptr;
L16Track(int sample_rate, int channels) : AudioTrackImp(CodecL16,sample_rate,channels,16){}
private:
//克隆该Track
Track::Ptr clone() override {
return std::make_shared<std::remove_reference<decltype(*this)>::type >(*this);
}
//生成sdp
Sdp::Ptr getSdp() override ;
};
/**
* L16类型SDP
*/
class L16Sdp : public Sdp {
public:
/**
* L16采样位数固定为16位
* @param codecId CodecL16
* @param sample_rate
* @param payload_type rtp payload
* @param bitrate
*/
L16Sdp(CodecId codecId,
int sample_rate,
int channels,
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 << " L16/" << sample_rate << "/" << channels << "\r\n";
_printer << "a=control:trackID=" << (int)TrackAudio << "\r\n";
}
string getSdp() const override {
return _printer;
}
CodecId getCodecId() const override {
return _codecId;
}
private:
_StrPrinter _printer;
CodecId _codecId;
};
}//namespace mediakit
#endif //ZLMEDIAKIT_L16_H