From 40afa204d52564cace4064a38f2bcfe018c34ce2 Mon Sep 17 00:00:00 2001 From: baiyfcu Date: Fri, 17 Apr 2020 17:47:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0rtmp/rtsp=E5=AF=B9=E9=9F=B3?= =?UTF-8?q?=E9=A2=91G711A,G711U=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/include/mk_player.h | 12 +++++++++++ api/source/mk_player.cpp | 18 ++++++++++++++++ src/Common/MediaSink.cpp | 18 ++++++++++++++++ src/Extension/Factory.cpp | 45 ++++++++++++++++++++++++++++++++++++--- src/Extension/Factory.h | 20 ++++++++++++++--- src/Extension/Frame.cpp | 2 ++ src/Extension/G711.cpp | 2 +- src/Extension/G711.h | 3 ++- src/Extension/G711Rtmp.h | 2 +- src/Extension/G711Rtp.cpp | 8 +++---- src/Extension/G711Rtp.h | 2 +- src/Rtmp/Rtmp.h | 3 +++ src/Rtmp/RtmpDemuxer.cpp | 4 ++-- 13 files changed, 123 insertions(+), 16 deletions(-) diff --git a/api/include/mk_player.h b/api/include/mk_player.h index 16eae126..f228c845 100755 --- a/api/include/mk_player.h +++ b/api/include/mk_player.h @@ -105,6 +105,12 @@ API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_eve */ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb, void *user_data); +/** + * 获取视频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U + * @param ctx 播放器指针 + */ +API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx); + /** * 获取视频宽度 */ @@ -120,6 +126,12 @@ API_EXPORT int API_CALL mk_player_video_height(mk_player ctx); */ API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx); +/** + * 获取音频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U + * @param ctx 播放器指针 + */ +API_EXPORT int API_CALL mk_player_audio_codecId(mk_player ctx); + /** * 获取音频采样率 */ diff --git a/api/source/mk_player.cpp b/api/source/mk_player.cpp index d9ba3fab..5f7a681b 100755 --- a/api/source/mk_player.cpp +++ b/api/source/mk_player.cpp @@ -101,6 +101,15 @@ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb }); } + +API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx) +{ + assert(ctx); + MediaPlayer::Ptr& player = *((MediaPlayer::Ptr*)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackVideo)); + return track ? track->getCodecId() : CodecInvalid; +} + API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) { assert(ctx); MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); @@ -122,6 +131,15 @@ API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx) { return track ? track->getVideoFps() : 0; } + +API_EXPORT int API_CALL mk_player_audio_codecId(mk_player ctx) +{ + assert(ctx); + MediaPlayer::Ptr& player = *((MediaPlayer::Ptr*)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackAudio)); + return track ? track->getCodecId() : CodecInvalid; +} + API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) { assert(ctx); MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); diff --git a/src/Common/MediaSink.cpp b/src/Common/MediaSink.cpp index de315706..7bc30eac 100644 --- a/src/Common/MediaSink.cpp +++ b/src/Common/MediaSink.cpp @@ -35,6 +35,23 @@ void MediaSink::addTrack(const Track::Ptr &track_in) { if (_allTrackReady) { onTrackFrame(frame); } + else + { + if (frame->getTrackType() == TrackVideo) + { + checkTrackIfReady(nullptr); + + if (_allTrackReady) { + onTrackFrame(frame); + } + else + { + ErrorL << " 还有track未准备好,丢帧 codecName: " << frame->getCodecName(); + } + + }else + ErrorL << " 还有track未准备好,丢帧 codecName: " << frame->getCodecName(); + } })); } @@ -116,6 +133,7 @@ void MediaSink::emitAllTrackReady() { return; } + DebugL << "all track ready use " << _ticker.elapsedTime() << "ms"; if (!_trackReadyCallback.empty()) { //这是超时强制忽略未准备好的Track _trackReadyCallback.clear(); diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index 7ae50863..1fd6c754 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -169,7 +169,7 @@ RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) { /////////////////////////////rtmp相关/////////////////////////////////////////// -Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) { +Track::Ptr Factory::getVideoTrackByAmf(const AMFValue &amf) { CodecId codecId = getCodecIdByAmf(amf); if(codecId == CodecInvalid){ return nullptr; @@ -178,6 +178,15 @@ Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) { } +mediakit::Track::Ptr Factory::getAudioTrackByAmf(const AMFValue& amf) +{ + CodecId codecId = getAudioCodecIdByAmf(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(); @@ -212,6 +221,36 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){ } +CodecId Factory::getAudioCodecIdByAmf(const AMFValue& val) +{ + if (val.type() == AMF_STRING) { + auto str = val.as_string(); + 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 FLV_CODEC_AAC: return CodecAAC; + case FLV_CODEC_G711A: return CodecG711A; + case FLV_CODEC_G711U: return CodecG711U; + + default: + WarnL << "暂不支持该Amf:" << type_id; + return CodecInvalid; + } + } + else { + WarnL << "Metadata不存在相应的Track"; + } + + return CodecInvalid; +} + RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) { switch (track->getCodecId()){ case CodecH264: @@ -234,8 +273,8 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) { case CodecAAC: return AMFValue("mp4a"); case CodecH264: return AMFValue("avc1"); case CodecH265: return AMFValue(FLV_CODEC_H265); - case CodecG711A: return AMFValue(7); - case CodecG711U: return AMFValue(8); + case CodecG711A: return AMFValue(FLV_CODEC_G711A); + case CodecG711U: return AMFValue(FLV_CODEC_G711U); default: return AMFValue(AMF_NULL); } } diff --git a/src/Extension/Factory.h b/src/Extension/Factory.h index fd53a5b7..c8ad09a3 100644 --- a/src/Extension/Factory.h +++ b/src/Extension/Factory.h @@ -56,11 +56,18 @@ public: ////////////////////////////////rtmp相关////////////////////////////////// /** - * 根据amf对象获取响应的Track - * @param amf rtmp metadata中的videocodecid或audiocodecid的值 + * 根据amf对象获取视频相应的Track + * @param amf rtmp metadata中的videocodecid的值 * @return */ - static Track::Ptr getTrackByAmf(const AMFValue &amf); + static Track::Ptr getVideoTrackByAmf(const AMFValue &amf); + + /** + * 根据amf对象获取音频相应的Track + * @param amf rtmp metadata中的audiocodecid的值 + * @return + */ + static Track::Ptr getAudioTrackByAmf(const AMFValue& amf); /** * 根据amf对象获取相应的CodecId @@ -69,6 +76,13 @@ public: */ static CodecId getCodecIdByAmf(const AMFValue &val); + /** + * 根据amf对象获取音频相应的CodecId + * @param val rtmp metadata中的audiocodecid的值 + * @return + */ + static CodecId getAudioCodecIdByAmf(const AMFValue& val); + /** * 根据Track获取Rtmp的编解码器 * @param track 媒体描述对象 diff --git a/src/Extension/Frame.cpp b/src/Extension/Frame.cpp index 9244ca7c..9d543706 100644 --- a/src/Extension/Frame.cpp +++ b/src/Extension/Frame.cpp @@ -28,6 +28,8 @@ const char *CodecInfo::getCodecName() { SWITCH_CASE(CodecH264); SWITCH_CASE(CodecH265); SWITCH_CASE(CodecAAC); + SWITCH_CASE(CodecG711A); + SWITCH_CASE(CodecG711U); default: return "unknown codec"; } diff --git a/src/Extension/G711.cpp b/src/Extension/G711.cpp index f3492770..ee4211a8 100644 --- a/src/Extension/G711.cpp +++ b/src/Extension/G711.cpp @@ -15,7 +15,7 @@ namespace mediakit{ Sdp::Ptr G711Track::getSdp() { if(!ready()){ - WarnL << "AAC Track未准备好"; + WarnL << getCodecName() << " Track未准备好"; return nullptr; } return std::make_shared(getCodecId(), getAudioSampleRate(), getCodecId() == CodecG711A ? 8 : 0, getAudioSampleBit()); diff --git a/src/Extension/G711.h b/src/Extension/G711.h index 4dc99293..94c66975 100644 --- a/src/Extension/G711.h +++ b/src/Extension/G711.h @@ -57,7 +57,7 @@ public: } CodecId getCodecId() const override{ - return CodecAAC; + return _codecId; } bool keyFrame() const override { @@ -68,6 +68,7 @@ public: return false; } public: + CodecId _codecId = CodecG711A; unsigned int frameLength; // 一个帧的长度包括 raw data block unsigned char buffer[2 * 1024 + 7]; uint32_t timeStamp; diff --git a/src/Extension/G711Rtmp.h b/src/Extension/G711Rtmp.h index aa63ef08..3ab29765 100644 --- a/src/Extension/G711Rtmp.h +++ b/src/Extension/G711Rtmp.h @@ -51,7 +51,7 @@ protected: G711Frame::Ptr obtainFrame(); protected: G711Frame::Ptr _adts; - CodecId _codecid = CodecG711A; + CodecId _codecid = CodecInvalid; }; diff --git a/src/Extension/G711Rtp.cpp b/src/Extension/G711Rtp.cpp index 63eff6f3..c55cd956 100644 --- a/src/Extension/G711Rtp.cpp +++ b/src/Extension/G711Rtp.cpp @@ -51,12 +51,11 @@ void G711RtpEncoder::makeG711Rtp(const void *data, unsigned int len, bool mark, ///////////////////////////////////////////////////////////////////////////////////// G711RtpDecoder::G711RtpDecoder(const Track::Ptr &track){ - auto aacTrack = dynamic_pointer_cast(track); - _codecid = aacTrack->getCodecId(); - if(!aacTrack || !aacTrack->ready()){ + auto g711Track = dynamic_pointer_cast(track); + _codecid = g711Track->getCodecId(); + if(!g711Track || !g711Track->ready()){ WarnL << "该g711 track无效!"; }else{ - //_aac_cfg = aacTrack->getAacCfg(); } _adts = obtainFrame(); } @@ -81,6 +80,7 @@ bool G711RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { _adts->frameLength = length; memcpy(_adts->buffer, rtp_packet_buf, length); + _adts->_codecId = _codecid; if (rtppack->mark == true) { _adts->timeStamp = rtppack->timeStamp; onGetG711(_adts); diff --git a/src/Extension/G711Rtp.h b/src/Extension/G711Rtp.h index 0a429123..2d052720 100644 --- a/src/Extension/G711Rtp.h +++ b/src/Extension/G711Rtp.h @@ -44,7 +44,7 @@ private: G711Frame::Ptr obtainFrame(); private: G711Frame::Ptr _adts; - CodecId _codecid = CodecG711A; + CodecId _codecid = CodecInvalid; }; diff --git a/src/Rtmp/Rtmp.h b/src/Rtmp/Rtmp.h index a02fc0d8..53df18dd 100644 --- a/src/Rtmp/Rtmp.h +++ b/src/Rtmp/Rtmp.h @@ -75,6 +75,9 @@ using namespace toolkit; #define FLV_CODEC_AAC 10 #define FLV_CODEC_H264 7 #define FLV_CODEC_H265 12 +#define FLV_CODEC_G711A 7 +#define FLV_CODEC_G711U 8 + namespace mediakit { diff --git a/src/Rtmp/RtmpDemuxer.cpp b/src/Rtmp/RtmpDemuxer.cpp index bfdd6795..26a3106f 100644 --- a/src/Rtmp/RtmpDemuxer.cpp +++ b/src/Rtmp/RtmpDemuxer.cpp @@ -61,7 +61,7 @@ bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) { void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { //生成Track对象 - _videoTrack = dynamic_pointer_cast(Factory::getTrackByAmf(videoCodec)); + _videoTrack = dynamic_pointer_cast(Factory::getVideoTrackByAmf(videoCodec)); if (_videoTrack) { //生成rtmpCodec对象以便解码rtmp _videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack); @@ -78,7 +78,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) { //生成Track对象 - _audioTrack = dynamic_pointer_cast(Factory::getTrackByAmf(audioCodec)); + _audioTrack = dynamic_pointer_cast(Factory::getAudioTrackByAmf(audioCodec)); if (_audioTrack) { //生成rtmpCodec对象以便解码rtmp _audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);