Commit 946b00f4 by xiongziliang

初步实现265 rtp解包

parent 9511a9fe
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "RtmpMuxer/AACRtmpCodec.h" #include "RtmpMuxer/AACRtmpCodec.h"
#include "RtspMuxer/H264RtpCodec.h" #include "RtspMuxer/H264RtpCodec.h"
#include "RtspMuxer/AACRtpCodec.h" #include "RtspMuxer/AACRtpCodec.h"
#include "RtspMuxer/H265RtpCodec.h"
namespace mediakit{ namespace mediakit{
...@@ -107,47 +108,30 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { ...@@ -107,47 +108,30 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
return std::make_shared<H264Track>(sps,pps,0,0); return std::make_shared<H264Track>(sps,pps,0,0);
} }
WarnL << "暂不支持该sdp:" << track->_codec << " " << track->_fmtp; if (strcasestr(track->_codec.data(), "h265") != nullptr) {
return nullptr; //a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwBdoAKAgC0WNrkky/AIAAADAAgAAAMBlQg=; sprop-pps=RAHA8vA8kAA=
} int pt;
char sprop_sps[128] = {0},sprop_pps[128] = {0};
if (3 != sscanf(track->_fmtp.c_str(), "%d sprop-sps=%127[^;]; sprop-pps=%127[^;]", &pt, sprop_sps, sprop_pps)) {
CodecId Factory::getCodecIdByAmf(const AMFValue &val){ return std::make_shared<H265Track>();
if (val.type() == AMF_STRING){
auto str = val.as_string();
if(str == "avc1"){
return CodecH264;
}
if(str == "mp4a"){
return CodecAAC;
} }
WarnL << "暂不支持该Amf:" << str; return std::make_shared<H265Track>("",sprop_sps,sprop_pps,0,0,0);
return CodecInvalid;
} }
if (val.type() != AMF_NULL){
auto type_id = val.as_integer(); WarnL << "暂不支持该sdp:" << track->_codec << " " << track->_fmtp;
switch (type_id){ return nullptr;
case 7:{
return CodecH264;
}
case 10:{
return CodecAAC;
}
default:
WarnL << "暂不支持该Amf:" << type_id;
return CodecInvalid;
}
}
WarnL << "暂不支持该Amf:" << val.type();
return CodecInvalid;
} }
Track::Ptr Factory::getTrackByCodecId(CodecId codecId) { Track::Ptr Factory::getTrackByCodecId(CodecId codecId) {
switch (codecId){ switch (codecId){
case CodecH264:{ case CodecH264:{
return std::make_shared<H264Track>(); return std::make_shared<H264Track>();
} }
case CodecH265:{
return std::make_shared<H265Track>();
}
case CodecAAC:{ case CodecAAC:{
return std::make_shared<AACTrack>(); return std::make_shared<AACTrack>();
} }
...@@ -157,16 +141,6 @@ Track::Ptr Factory::getTrackByCodecId(CodecId codecId) { ...@@ -157,16 +141,6 @@ Track::Ptr Factory::getTrackByCodecId(CodecId codecId) {
} }
} }
Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) {
CodecId codecId = getCodecIdByAmf(amf);
if(codecId == CodecInvalid){
return nullptr;
}
return getTrackByCodecId(codecId);
}
RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId, RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId,
uint32_t ui32Ssrc, uint32_t ui32Ssrc,
uint32_t ui32MtuSize, uint32_t ui32MtuSize,
...@@ -176,6 +150,8 @@ RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId, ...@@ -176,6 +150,8 @@ RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId,
switch (codecId){ switch (codecId){
case CodecH264: case CodecH264:
return std::make_shared<H264RtpEncoder>(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); return std::make_shared<H264RtpEncoder>(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved);
case CodecH265:
return std::make_shared<H265RtpEncoder>(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved);
case CodecAAC: case CodecAAC:
return std::make_shared<AACRtpEncoder>(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved); return std::make_shared<AACRtpEncoder>(ui32Ssrc,ui32MtuSize,ui32SampleRate,ui8PlayloadType,ui8Interleaved);
default: default:
...@@ -188,6 +164,8 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) { ...@@ -188,6 +164,8 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) {
switch (codecId){ switch (codecId){
case CodecH264: case CodecH264:
return std::make_shared<H264RtpDecoder>(); return std::make_shared<H264RtpDecoder>();
case CodecH265:
return std::make_shared<H265RtpDecoder>();
case CodecAAC: case CodecAAC:
return std::make_shared<AACRtpDecoder>(); return std::make_shared<AACRtpDecoder>();
default: default:
...@@ -196,6 +174,49 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) { ...@@ -196,6 +174,49 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId) {
} }
} }
/////////////////////////////rtmp相关///////////////////////////////////////////
Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) {
CodecId codecId = getCodecIdByAmf(amf);
if(codecId == CodecInvalid){
return nullptr;
}
return getTrackByCodecId(codecId);
}
CodecId Factory::getCodecIdByAmf(const AMFValue &val){
if (val.type() == AMF_STRING){
auto str = val.as_string();
if(str == "avc1"){
return CodecH264;
}
if(str == "mp4a"){
return CodecAAC;
}
WarnL << "暂不支持该Amf:" << str;
return CodecInvalid;
}
if (val.type() != AMF_NULL){
auto type_id = val.as_integer();
switch (type_id){
case 7:{
return CodecH264;
}
case 10:{
return CodecAAC;
}
default:
WarnL << "暂不支持该Amf:" << type_id;
return CodecInvalid;
}
}
WarnL << "暂不支持该Amf:" << val.type();
return CodecInvalid;
}
RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) { RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) {
switch (track->getCodecId()){ switch (track->getCodecId()){
case CodecH264: case CodecH264:
......
...@@ -435,11 +435,13 @@ void RtspPlayer::handleResPAUSE(const Parser& parser, bool bPause) { ...@@ -435,11 +435,13 @@ void RtspPlayer::handleResPAUSE(const Parser& parser, bool bPause) {
auto strControlSuffix = strTrack.substr(1 + strTrack.rfind('/'),strTrack.find(';') - strTrack.rfind('/') - 1); auto strControlSuffix = strTrack.substr(1 + strTrack.rfind('/'),strTrack.find(';') - strTrack.rfind('/') - 1);
auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";"); auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";");
auto idx = getTrackIndexByControlSuffix(strControlSuffix); auto idx = getTrackIndexByControlSuffix(strControlSuffix);
if(idx != -1){
_aiFistStamp[idx] = atoll(strRtpTime.data()) * 1000 / _aTrackInfo[idx]->_samplerate; _aiFistStamp[idx] = atoll(strRtpTime.data()) * 1000 / _aTrackInfo[idx]->_samplerate;
_aiNowStamp[idx] = _aiFistStamp[idx]; _aiNowStamp[idx] = _aiFistStamp[idx];
DebugL << "rtptime(ms):" << strControlSuffix <<" " << strRtpTime; DebugL << "rtptime(ms):" << strControlSuffix <<" " << strRtpTime;
} }
} }
}
onPlayResult_l(SockException(Err_success, "rtsp play success")); onPlayResult_l(SockException(Err_success, "rtsp play success"));
} else { } else {
_pRtpTimer.reset(); _pRtpTimer.reset();
......
...@@ -42,7 +42,7 @@ typedef struct { ...@@ -42,7 +42,7 @@ typedef struct {
unsigned type :5; unsigned type :5;
} FU; } FU;
bool MakeNalu(uint8_t in, NALU &nal) { static bool MakeNalu(uint8_t in, NALU &nal) {
nal.forbidden_zero_bit = in >> 7; nal.forbidden_zero_bit = in >> 7;
if (nal.forbidden_zero_bit) { if (nal.forbidden_zero_bit) {
return false; return false;
...@@ -51,7 +51,7 @@ bool MakeNalu(uint8_t in, NALU &nal) { ...@@ -51,7 +51,7 @@ bool MakeNalu(uint8_t in, NALU &nal) {
nal.type = in & 0x1f; nal.type = in & 0x1f;
return true; return true;
} }
bool MakeFU(uint8_t in, FU &fu) { static bool MakeFU(uint8_t in, FU &fu) {
fu.S = in >> 7; fu.S = in >> 7;
fu.E = (in >> 6) & 0x01; fu.E = (in >> 6) & 0x01;
fu.R = (in >> 5) & 0x01; fu.R = (in >> 5) & 0x01;
...@@ -62,7 +62,6 @@ bool MakeFU(uint8_t in, FU &fu) { ...@@ -62,7 +62,6 @@ bool MakeFU(uint8_t in, FU &fu) {
return true; return true;
} }
H264RtpDecoder::H264RtpDecoder() { H264RtpDecoder::H264RtpDecoder() {
_h264frame = obtainFrame(); _h264frame = obtainFrame();
} }
...@@ -157,8 +156,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { ...@@ -157,8 +156,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) { void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) {
//写入环形缓存 //写入环形缓存
auto lastSeq = _h264frame->sequence;
RtpCodec::inputFrame(frame); RtpCodec::inputFrame(frame);
_h264frame = obtainFrame(); _h264frame = obtainFrame();
_h264frame->sequence = lastSeq;
} }
......
...@@ -28,41 +28,41 @@ ...@@ -28,41 +28,41 @@
namespace mediakit{ namespace mediakit{
//41
typedef struct { //42 0 1
unsigned forbidden_zero_bit :1; //43 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
unsigned nal_ref_idc :2; //44 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
unsigned type :5; //45 |F| Type | LayerId | TID |
} NALU; //46 +-------------+-----------------+
//48 F = 0
//49 Type = 49 (fragmentation unit (FU))
//50 LayerId = 0
//51 TID = 1
//56 /*
//57 create the FU header
//58
//59 0 1 2 3 4 5 6 7
//60 +-+-+-+-+-+-+-+-+
//61 |S|E| FuType |
//62 +---------------+
//63
//64 S = variable
//65 E = variable
//66 FuType = NAL unit type
//67
typedef struct { typedef struct {
unsigned S :1; unsigned S :1;
unsigned E :1; unsigned E :1;
unsigned R :1; unsigned type :6;
unsigned type :5;
} FU; } FU;
bool MakeNalu(uint8_t in, NALU &nal) { static void MakeFU(uint8_t in, FU &fu) {
nal.forbidden_zero_bit = in >> 7;
if (nal.forbidden_zero_bit) {
return false;
}
nal.nal_ref_idc = (in & 0x60) >> 5;
nal.type = in & 0x1f;
return true;
}
bool MakeFU(uint8_t in, FU &fu) {
fu.S = in >> 7; fu.S = in >> 7;
fu.E = (in >> 6) & 0x01; fu.E = (in >> 6) & 0x01;
fu.R = (in >> 5) & 0x01; fu.type = in & 0x3f;
fu.type = in & 0x1f;
if (fu.R != 0) {
return false;
}
return true;
} }
H265RtpDecoder::H265RtpDecoder() { H265RtpDecoder::H265RtpDecoder() {
_h265frame = obtainFrame(); _h265frame = obtainFrame();
} }
...@@ -93,38 +93,35 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { ...@@ -93,38 +93,35 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
const uint8_t *frame = (uint8_t *) rtppack->payload + rtppack->offset; const uint8_t *frame = (uint8_t *) rtppack->payload + rtppack->offset;
int length = rtppack->length - rtppack->offset; int length = rtppack->length - rtppack->offset;
NALU nal;
MakeNalu(*frame, nal);
if (nal.type >= 0 && nal.type < 24) { int nal = H265_TYPE(frame[0]);
//a full frame
_h265frame->buffer.assign("\x0\x0\x0\x1", 4);
_h265frame->buffer.append((char *)frame, length);
_h265frame->type = nal.type;
_h265frame->timeStamp = rtppack->timeStamp;
_h265frame->sequence = rtppack->sequence;
auto isIDR = _h265frame->type == 5;
onGetH265(_h265frame);
return (isIDR); //i frame
}
if (nal.type == 28) { if (nal > 50){
//FU-A WarnL << "不支持该类型的265 RTP包" << nal;
return false; // packet discard, Unsupported (HEVC) NAL type
}
switch (nal) {
case 50:
case 48: // aggregated packet (AP) - with two or more NAL units
WarnL << "不支持该类型的265 RTP包" << nal;
return false;
case 49: {
// fragmentation unit (FU)
FU fu; FU fu;
MakeFU(frame[1], fu); MakeFU(frame[1], fu);
if (fu.S == 1) { if (fu.S == 1) {
//FU-A start //FU-A start
char tmp = (nal.forbidden_zero_bit << 7 | nal.nal_ref_idc << 5 | fu.type);
_h265frame->buffer.assign("\x0\x0\x0\x1", 4); _h265frame->buffer.assign("\x0\x0\x0\x1", 4);
_h265frame->buffer.push_back(tmp); _h265frame->buffer.push_back(fu.type << 1);
_h265frame->buffer.append((char *)frame + 2, length - 2); _h265frame->buffer.push_back(0x01);
_h265frame->buffer.append((char *) frame + 2, length - 2);
_h265frame->type = fu.type; _h265frame->type = fu.type;
_h265frame->timeStamp = rtppack->timeStamp; _h265frame->timeStamp = rtppack->timeStamp;
_h265frame->sequence = rtppack->sequence; _h265frame->sequence = rtppack->sequence;
return (_h265frame->type == 5); //i frame return (_h265frame->keyFrame()); //i frame
} }
if (rtppack->sequence != (uint16_t)(_h265frame->sequence + 1)) { if (rtppack->sequence != (uint16_t) (_h265frame->sequence + 1)) {
_h265frame->buffer.clear(); _h265frame->buffer.clear();
WarnL << "丢包,帧废弃:" << rtppack->sequence << "," << _h265frame->sequence; WarnL << "丢包,帧废弃:" << rtppack->sequence << "," << _h265frame->sequence;
return false; return false;
...@@ -132,33 +129,36 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { ...@@ -132,33 +129,36 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
_h265frame->sequence = rtppack->sequence; _h265frame->sequence = rtppack->sequence;
if (fu.E == 1) { if (fu.E == 1) {
//FU-A end //FU-A end
_h265frame->buffer.append((char *)frame + 2, length - 2); _h265frame->buffer.append((char *) frame + 2, length - 2);
_h265frame->timeStamp = rtppack->timeStamp; _h265frame->timeStamp = rtppack->timeStamp;
auto isIDR = _h265frame->type == 5; auto isIDR = _h265frame->keyFrame();
onGetH265(_h265frame); onGetH265(_h265frame);
return isIDR; return isIDR;
} }
//FU-A mid //FU-A mid
_h265frame->buffer.append((char *)frame + 2, length - 2); _h265frame->buffer.append((char *) frame + 2, length - 2);
return false; return false;
} }
WarnL << "不支持的rtp类型:" << nal.type << " " << rtppack->sequence; default: // 4.4.1. Single NAL Unit Packets (p24)
return false; //a full frame
// 29 FU-B 单NAL单元B模式 _h265frame->buffer.assign("\x0\x0\x0\x1", 4);
// 24 STAP-A 单一时间的组合包 _h265frame->buffer.append((char *)frame, length);
// 25 STAP-B 单一时间的组合包 _h265frame->type = nal;
// 26 MTAP16 多个时间的组合包 _h265frame->timeStamp = rtppack->timeStamp;
// 27 MTAP24 多个时间的组合包 _h265frame->sequence = rtppack->sequence;
// 0 udef auto isIDR = _h265frame->keyFrame();
// 30 udef onGetH265(_h265frame);
// 31 udef return (isIDR); //i frame
}
} }
void H265RtpDecoder::onGetH265(const H265Frame::Ptr &frame) { void H265RtpDecoder::onGetH265(const H265Frame::Ptr &frame) {
//写入环形缓存 //写入环形缓存
auto lastSeq = _h265frame->sequence;
RtpCodec::inputFrame(frame); RtpCodec::inputFrame(frame);
_h265frame = obtainFrame(); _h265frame = obtainFrame();
_h265frame->sequence = lastSeq;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论