mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-04 09:47:33 +08:00
优化与完善rtmp协议相关代码
rtmp相关常量由宏改为枚举 明确rtmp包一些字段赋值含义
This commit is contained in:
@@ -18,7 +18,7 @@ namespace mediakit {
|
||||
|
||||
static string getAacCfg(const RtmpPacket &thiz) {
|
||||
string ret;
|
||||
if (thiz.getMediaType() != FLV_CODEC_AAC) {
|
||||
if ((RtmpAudioCodec)thiz.getRtmpCodecId() != RtmpAudioCodec::aac) {
|
||||
return ret;
|
||||
}
|
||||
if (!thiz.isCfgFrame()) {
|
||||
@@ -93,51 +93,45 @@ void AACRtmpEncoder::makeConfigPacket() {
|
||||
bool AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
if (_aac_cfg.empty()) {
|
||||
if (frame->prefixSize()) {
|
||||
//包含adts头,从adts头获取aac配置信息
|
||||
_aac_cfg = makeAacConfig((uint8_t *) (frame->data()), frame->prefixSize());
|
||||
// 包含adts头,从adts头获取aac配置信息
|
||||
_aac_cfg = makeAacConfig((uint8_t *)(frame->data()), frame->prefixSize());
|
||||
}
|
||||
makeConfigPacket();
|
||||
}
|
||||
|
||||
if(_aac_cfg.empty()){
|
||||
if (_aac_cfg.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto rtmpPkt = RtmpPacket::create();
|
||||
//header
|
||||
uint8_t is_config = false;
|
||||
rtmpPkt->buffer.push_back(_audio_flv_flags);
|
||||
rtmpPkt->buffer.push_back(!is_config);
|
||||
|
||||
//aac data
|
||||
rtmpPkt->buffer.append(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize());
|
||||
|
||||
rtmpPkt->body_size = rtmpPkt->buffer.size();
|
||||
rtmpPkt->chunk_id = CHUNK_AUDIO;
|
||||
rtmpPkt->stream_index = STREAM_MEDIA;
|
||||
rtmpPkt->time_stamp = frame->dts();
|
||||
rtmpPkt->type_id = MSG_AUDIO;
|
||||
RtmpCodec::inputRtmp(rtmpPkt);
|
||||
auto pkt = RtmpPacket::create();
|
||||
// header
|
||||
pkt->buffer.push_back(_audio_flv_flags);
|
||||
pkt->buffer.push_back((uint8_t)RtmpAACPacketType::aac_raw);
|
||||
// aac data
|
||||
pkt->buffer.append(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize());
|
||||
pkt->body_size = pkt->buffer.size();
|
||||
pkt->chunk_id = CHUNK_AUDIO;
|
||||
pkt->stream_index = STREAM_MEDIA;
|
||||
pkt->time_stamp = frame->dts();
|
||||
pkt->type_id = MSG_AUDIO;
|
||||
RtmpCodec::inputRtmp(pkt);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AACRtmpEncoder::makeAudioConfigPkt() {
|
||||
_audio_flv_flags = getAudioRtmpFlags(std::make_shared<AACTrack>(_aac_cfg));
|
||||
auto rtmpPkt = RtmpPacket::create();
|
||||
|
||||
//header
|
||||
uint8_t is_config = true;
|
||||
rtmpPkt->buffer.push_back(_audio_flv_flags);
|
||||
rtmpPkt->buffer.push_back(!is_config);
|
||||
//aac config
|
||||
rtmpPkt->buffer.append(_aac_cfg);
|
||||
|
||||
rtmpPkt->body_size = rtmpPkt->buffer.size();
|
||||
rtmpPkt->chunk_id = CHUNK_AUDIO;
|
||||
rtmpPkt->stream_index = STREAM_MEDIA;
|
||||
rtmpPkt->time_stamp = 0;
|
||||
rtmpPkt->type_id = MSG_AUDIO;
|
||||
RtmpCodec::inputRtmp(rtmpPkt);
|
||||
auto pkt = RtmpPacket::create();
|
||||
// header
|
||||
pkt->buffer.push_back(_audio_flv_flags);
|
||||
pkt->buffer.push_back((uint8_t)RtmpAACPacketType::aac_config_header);
|
||||
// aac config
|
||||
pkt->buffer.append(_aac_cfg);
|
||||
pkt->body_size = pkt->buffer.size();
|
||||
pkt->chunk_id = CHUNK_AUDIO;
|
||||
pkt->stream_index = STREAM_MEDIA;
|
||||
pkt->time_stamp = 0;
|
||||
pkt->type_id = MSG_AUDIO;
|
||||
RtmpCodec::inputRtmp(pkt);
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
@@ -201,11 +201,11 @@ static CodecId getVideoCodecIdByAmf(const AMFValue &val){
|
||||
}
|
||||
|
||||
if (val.type() != AMF_NULL) {
|
||||
auto type_id = val.as_integer();
|
||||
auto type_id = (RtmpVideoCodec)val.as_integer();
|
||||
switch (type_id) {
|
||||
case FLV_CODEC_H264 : return CodecH264;
|
||||
case FLV_CODEC_H265 : return CodecH265;
|
||||
default : WarnL << "暂不支持该视频Amf:" << type_id; return CodecInvalid;
|
||||
case RtmpVideoCodec::h264: return CodecH264;
|
||||
case RtmpVideoCodec::h265: return CodecH265;
|
||||
default: WarnL << "暂不支持该视频Amf:" << (int)type_id; return CodecInvalid;
|
||||
}
|
||||
}
|
||||
return CodecInvalid;
|
||||
@@ -243,13 +243,13 @@ static CodecId getAudioCodecIdByAmf(const AMFValue &val) {
|
||||
}
|
||||
|
||||
if (val.type() != AMF_NULL) {
|
||||
auto type_id = val.as_integer();
|
||||
auto type_id = (RtmpAudioCodec)val.as_integer();
|
||||
switch (type_id) {
|
||||
case FLV_CODEC_AAC : return CodecAAC;
|
||||
case FLV_CODEC_G711A : return CodecG711A;
|
||||
case FLV_CODEC_G711U : return CodecG711U;
|
||||
case FLV_CODEC_OPUS : return CodecOpus;
|
||||
default : WarnL << "暂不支持该音频Amf:" << type_id; return CodecInvalid;
|
||||
case RtmpAudioCodec::aac : return CodecAAC;
|
||||
case RtmpAudioCodec::g711a : return CodecG711A;
|
||||
case RtmpAudioCodec::g711u : return CodecG711U;
|
||||
case RtmpAudioCodec::opus : return CodecOpus;
|
||||
default : WarnL << "暂不支持该音频Amf:" << (int)type_id; return CodecInvalid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,13 +291,13 @@ RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track, bool is_enc
|
||||
}
|
||||
|
||||
AMFValue Factory::getAmfByCodecId(CodecId codecId) {
|
||||
switch (codecId){
|
||||
case CodecAAC: return AMFValue(FLV_CODEC_AAC);
|
||||
case CodecH264: return AMFValue(FLV_CODEC_H264);
|
||||
case CodecH265: return AMFValue(FLV_CODEC_H265);
|
||||
case CodecG711A: return AMFValue(FLV_CODEC_G711A);
|
||||
case CodecG711U: return AMFValue(FLV_CODEC_G711U);
|
||||
case CodecOpus: return AMFValue(FLV_CODEC_OPUS);
|
||||
switch (codecId) {
|
||||
case CodecAAC: return AMFValue((int)RtmpAudioCodec::aac);
|
||||
case CodecH264: return AMFValue((int)RtmpVideoCodec::h264);
|
||||
case CodecH265: return AMFValue((int)RtmpVideoCodec::h265);
|
||||
case CodecG711A: return AMFValue((int)RtmpAudioCodec::g711a);
|
||||
case CodecG711U: return AMFValue((int)RtmpAudioCodec::g711u);
|
||||
case CodecOpus: return AMFValue((int)RtmpAudioCodec::opus);
|
||||
default: return AMFValue(AMF_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ H264Frame::Ptr H264RtmpDecoder::obtainFrame() {
|
||||
* 返回不带0x00 00 00 01头的sps pps
|
||||
*/
|
||||
static bool getH264Config(const RtmpPacket &thiz, string &sps, string &pps) {
|
||||
if (thiz.getMediaType() != FLV_CODEC_H264) {
|
||||
if ((RtmpVideoCodec)thiz.getRtmpCodecId() != RtmpVideoCodec::h264) {
|
||||
return false;
|
||||
}
|
||||
if (!thiz.isCfgFrame()) {
|
||||
@@ -159,22 +159,21 @@ bool H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
}
|
||||
|
||||
return _merger.inputFrame(frame, [this](uint64_t dts, uint64_t pts, const Buffer::Ptr &, bool have_key_frame) {
|
||||
//flags
|
||||
_rtmp_packet->buffer[0] = FLV_CODEC_H264 | ((have_key_frame ? FLV_KEY_FRAME : FLV_INTER_FRAME) << 4);
|
||||
//not config
|
||||
_rtmp_packet->buffer[1] = true;
|
||||
int32_t cts = pts - dts;
|
||||
//cts
|
||||
set_be24(&_rtmp_packet->buffer[2], cts);
|
||||
_rtmp_packet->time_stamp = dts;
|
||||
_rtmp_packet->body_size = _rtmp_packet->buffer.size();
|
||||
_rtmp_packet->chunk_id = CHUNK_VIDEO;
|
||||
_rtmp_packet->stream_index = STREAM_MEDIA;
|
||||
_rtmp_packet->type_id = MSG_VIDEO;
|
||||
//输出rtmp packet
|
||||
RtmpCodec::inputRtmp(_rtmp_packet);
|
||||
_rtmp_packet = nullptr;
|
||||
}, &_rtmp_packet->buffer);
|
||||
// flags
|
||||
_rtmp_packet->buffer[0] = (uint8_t)RtmpVideoCodec::h264 | ((uint8_t)(have_key_frame ? RtmpFrameType::key_frame : RtmpFrameType::inter_frame) << 4);
|
||||
_rtmp_packet->buffer[1] = (uint8_t)RtmpH264PacketType::h264_nalu;
|
||||
int32_t cts = pts - dts;
|
||||
// cts
|
||||
set_be24(&_rtmp_packet->buffer[2], cts);
|
||||
_rtmp_packet->time_stamp = dts;
|
||||
_rtmp_packet->body_size = _rtmp_packet->buffer.size();
|
||||
_rtmp_packet->chunk_id = CHUNK_VIDEO;
|
||||
_rtmp_packet->stream_index = STREAM_MEDIA;
|
||||
_rtmp_packet->type_id = MSG_VIDEO;
|
||||
// 输出rtmp packet
|
||||
RtmpCodec::inputRtmp(_rtmp_packet);
|
||||
_rtmp_packet = nullptr;
|
||||
}, &_rtmp_packet->buffer);
|
||||
}
|
||||
|
||||
void H264RtmpEncoder::makeVideoConfigPkt() {
|
||||
@@ -182,42 +181,39 @@ void H264RtmpEncoder::makeVideoConfigPkt() {
|
||||
WarnL << "sps长度不足4字节";
|
||||
return;
|
||||
}
|
||||
int8_t flags = FLV_CODEC_H264;
|
||||
flags |= (FLV_KEY_FRAME << 4);
|
||||
bool is_config = true;
|
||||
|
||||
auto rtmpPkt = RtmpPacket::create();
|
||||
//header
|
||||
rtmpPkt->buffer.push_back(flags);
|
||||
rtmpPkt->buffer.push_back(!is_config);
|
||||
//cts
|
||||
rtmpPkt->buffer.append("\x0\x0\x0", 3);
|
||||
|
||||
//AVCDecoderConfigurationRecord start
|
||||
rtmpPkt->buffer.push_back(1); // version
|
||||
rtmpPkt->buffer.push_back(_sps[1]); // profile
|
||||
rtmpPkt->buffer.push_back(_sps[2]); // compat
|
||||
rtmpPkt->buffer.push_back(_sps[3]); // level
|
||||
rtmpPkt->buffer.push_back((char)0xff); // 6 bits reserved + 2 bits nal size length - 1 (11)
|
||||
rtmpPkt->buffer.push_back((char)0xe1); // 3 bits reserved + 5 bits number of sps (00001)
|
||||
//sps
|
||||
auto flags = (uint8_t)RtmpVideoCodec::h264;
|
||||
flags |= ((uint8_t)RtmpFrameType::key_frame << 4);
|
||||
auto pkt = RtmpPacket::create();
|
||||
// header
|
||||
pkt->buffer.push_back(flags);
|
||||
pkt->buffer.push_back((uint8_t)RtmpH264PacketType::h264_config_header);
|
||||
// cts
|
||||
pkt->buffer.append("\x0\x0\x0", 3);
|
||||
// AVCDecoderConfigurationRecord start
|
||||
pkt->buffer.push_back(1); // version
|
||||
pkt->buffer.push_back(_sps[1]); // profile
|
||||
pkt->buffer.push_back(_sps[2]); // compat
|
||||
pkt->buffer.push_back(_sps[3]); // level
|
||||
pkt->buffer.push_back((char)0xff); // 6 bits reserved + 2 bits nal size length - 1 (11)
|
||||
pkt->buffer.push_back((char)0xe1); // 3 bits reserved + 5 bits number of sps (00001)
|
||||
// sps
|
||||
uint16_t size = (uint16_t)_sps.size();
|
||||
size = htons(size);
|
||||
rtmpPkt->buffer.append((char *) &size, 2);
|
||||
rtmpPkt->buffer.append(_sps);
|
||||
//pps
|
||||
rtmpPkt->buffer.push_back(1); // version
|
||||
pkt->buffer.append((char *)&size, 2);
|
||||
pkt->buffer.append(_sps);
|
||||
// pps
|
||||
pkt->buffer.push_back(1); // version
|
||||
size = (uint16_t)_pps.size();
|
||||
size = htons(size);
|
||||
rtmpPkt->buffer.append((char *) &size, 2);
|
||||
rtmpPkt->buffer.append(_pps);
|
||||
pkt->buffer.append((char *)&size, 2);
|
||||
pkt->buffer.append(_pps);
|
||||
|
||||
rtmpPkt->body_size = rtmpPkt->buffer.size();
|
||||
rtmpPkt->chunk_id = CHUNK_VIDEO;
|
||||
rtmpPkt->stream_index = STREAM_MEDIA;
|
||||
rtmpPkt->time_stamp = 0;
|
||||
rtmpPkt->type_id = MSG_VIDEO;
|
||||
RtmpCodec::inputRtmp(rtmpPkt);
|
||||
pkt->body_size = pkt->buffer.size();
|
||||
pkt->chunk_id = CHUNK_VIDEO;
|
||||
pkt->stream_index = STREAM_MEDIA;
|
||||
pkt->time_stamp = 0;
|
||||
pkt->type_id = MSG_VIDEO;
|
||||
RtmpCodec::inputRtmp(pkt);
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
@@ -50,7 +50,7 @@ static bool decode_HEVCDecoderConfigurationRecord(uint8_t *extra, size_t bytes,
|
||||
* 返回不带0x00 00 00 01头的sps
|
||||
*/
|
||||
static bool getH265ConfigFrame(const RtmpPacket &thiz, string &frame) {
|
||||
if (thiz.getMediaType() != FLV_CODEC_H265) {
|
||||
if ((RtmpVideoCodec)thiz.getRtmpCodecId() != RtmpVideoCodec::h265) {
|
||||
return false;
|
||||
}
|
||||
if (!thiz.isCfgFrame()) {
|
||||
@@ -243,34 +243,31 @@ bool H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) {
|
||||
}
|
||||
|
||||
return _merger.inputFrame(frame, [this](uint64_t dts, uint64_t pts, const Buffer::Ptr &, bool have_key_frame) {
|
||||
// flags
|
||||
_rtmp_packet->buffer[0] = FLV_CODEC_H265 | ((have_key_frame ? FLV_KEY_FRAME : FLV_INTER_FRAME) << 4);
|
||||
// not config
|
||||
_rtmp_packet->buffer[1] = true;
|
||||
int32_t cts = pts - dts;
|
||||
// cts
|
||||
set_be24(&_rtmp_packet->buffer[2], cts);
|
||||
|
||||
_rtmp_packet->time_stamp = dts;
|
||||
_rtmp_packet->body_size = _rtmp_packet->buffer.size();
|
||||
_rtmp_packet->chunk_id = CHUNK_VIDEO;
|
||||
_rtmp_packet->stream_index = STREAM_MEDIA;
|
||||
_rtmp_packet->type_id = MSG_VIDEO;
|
||||
// 输出rtmp packet
|
||||
RtmpCodec::inputRtmp(_rtmp_packet);
|
||||
_rtmp_packet = nullptr;
|
||||
}, &_rtmp_packet->buffer);
|
||||
// flags
|
||||
_rtmp_packet->buffer[0] = (uint8_t)RtmpVideoCodec::h265 | ((uint8_t)(have_key_frame ? RtmpFrameType::key_frame : RtmpFrameType::inter_frame) << 4);
|
||||
_rtmp_packet->buffer[1] = (uint8_t)RtmpH264PacketType::h264_nalu;
|
||||
int32_t cts = pts - dts;
|
||||
// cts
|
||||
set_be24(&_rtmp_packet->buffer[2], cts);
|
||||
_rtmp_packet->time_stamp = dts;
|
||||
_rtmp_packet->body_size = _rtmp_packet->buffer.size();
|
||||
_rtmp_packet->chunk_id = CHUNK_VIDEO;
|
||||
_rtmp_packet->stream_index = STREAM_MEDIA;
|
||||
_rtmp_packet->type_id = MSG_VIDEO;
|
||||
// 输出rtmp packet
|
||||
RtmpCodec::inputRtmp(_rtmp_packet);
|
||||
_rtmp_packet = nullptr;
|
||||
}, &_rtmp_packet->buffer);
|
||||
}
|
||||
|
||||
void H265RtmpEncoder::makeVideoConfigPkt() {
|
||||
#ifdef ENABLE_MP4
|
||||
int8_t flags = FLV_CODEC_H265;
|
||||
flags |= (FLV_KEY_FRAME << 4);
|
||||
bool is_config = true;
|
||||
auto flags = (uint8_t)RtmpVideoCodec::h265;
|
||||
flags |= ((uint8_t)RtmpFrameType::key_frame << 4);
|
||||
auto pkt = RtmpPacket::create();
|
||||
// header
|
||||
pkt->buffer.push_back(flags);
|
||||
pkt->buffer.push_back(!is_config);
|
||||
pkt->buffer.push_back((uint8_t)RtmpH264PacketType::h264_config_header);
|
||||
// cts
|
||||
pkt->buffer.append("\x0\x0\x0", 3);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user