Commit 4244cbf2 by 夏楚 Committed by GitHub

Merge pull request #656 from rmokerone/master

RTSP推流增加L16动态payload type支持(RFC 3551 Section 4.5.11, RFC 2586)
parents 45e86a39 92376862
...@@ -369,6 +369,10 @@ bool MultiMediaSourceMuxer::stopSendRtp(MediaSource &sender, const string& ssrc) ...@@ -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);
} }
......
...@@ -20,6 +20,7 @@ ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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());
......
...@@ -80,6 +80,7 @@ const char *getCodecName(CodecId codecId) { ...@@ -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){ ...@@ -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;
} }
} }
......
...@@ -29,6 +29,7 @@ typedef enum { ...@@ -29,6 +29,7 @@ typedef enum {
CodecG711A, CodecG711A,
CodecG711U, CodecG711U,
CodecOpus, CodecOpus,
CodecL16,
CodecMax = 0x7FFF CodecMax = 0x7FFF
} CodecId; } CodecId;
......
/*
* 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
/*
* 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
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论