Commit 40afa204 by baiyfcu

增加rtmp/rtsp对音频G711A,G711U的支持

parent 5fcc22ba
...@@ -106,6 +106,12 @@ API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_eve ...@@ -106,6 +106,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); 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);
/**
* 获取视频宽度 * 获取视频宽度
*/ */
API_EXPORT int API_CALL mk_player_video_width(mk_player ctx); API_EXPORT int API_CALL mk_player_video_width(mk_player ctx);
...@@ -121,6 +127,12 @@ API_EXPORT int API_CALL mk_player_video_height(mk_player ctx); ...@@ -121,6 +127,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); 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);
/**
* 获取音频采样率 * 获取音频采样率
*/ */
API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx); API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx);
......
...@@ -101,6 +101,15 @@ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb ...@@ -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<VideoTrack>(player->getTrack(TrackVideo));
return track ? track->getCodecId() : CodecInvalid;
}
API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) { API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) {
assert(ctx); assert(ctx);
MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx);
...@@ -122,6 +131,15 @@ API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx) { ...@@ -122,6 +131,15 @@ API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx) {
return track ? track->getVideoFps() : 0; 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<AudioTrack>(player->getTrack(TrackAudio));
return track ? track->getCodecId() : CodecInvalid;
}
API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) { API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) {
assert(ctx); assert(ctx);
MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx);
......
...@@ -35,6 +35,23 @@ void MediaSink::addTrack(const Track::Ptr &track_in) { ...@@ -35,6 +35,23 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
if (_allTrackReady) { if (_allTrackReady) {
onTrackFrame(frame); 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() { ...@@ -116,6 +133,7 @@ void MediaSink::emitAllTrackReady() {
return; return;
} }
DebugL << "all track ready use " << _ticker.elapsedTime() << "ms";
if (!_trackReadyCallback.empty()) { if (!_trackReadyCallback.empty()) {
//这是超时强制忽略未准备好的Track //这是超时强制忽略未准备好的Track
_trackReadyCallback.clear(); _trackReadyCallback.clear();
......
...@@ -169,7 +169,7 @@ RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) { ...@@ -169,7 +169,7 @@ RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) {
/////////////////////////////rtmp相关/////////////////////////////////////////// /////////////////////////////rtmp相关///////////////////////////////////////////
Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) { Track::Ptr Factory::getVideoTrackByAmf(const AMFValue &amf) {
CodecId codecId = getCodecIdByAmf(amf); CodecId codecId = getCodecIdByAmf(amf);
if(codecId == CodecInvalid){ if(codecId == CodecInvalid){
return nullptr; return nullptr;
...@@ -178,6 +178,15 @@ Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) { ...@@ -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){ CodecId Factory::getCodecIdByAmf(const AMFValue &val){
if (val.type() == AMF_STRING){ if (val.type() == AMF_STRING){
auto str = val.as_string(); auto str = val.as_string();
...@@ -212,6 +221,36 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){ ...@@ -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) { RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) {
switch (track->getCodecId()){ switch (track->getCodecId()){
case CodecH264: case CodecH264:
...@@ -234,8 +273,8 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) { ...@@ -234,8 +273,8 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) {
case CodecAAC: return AMFValue("mp4a"); case CodecAAC: return AMFValue("mp4a");
case CodecH264: return AMFValue("avc1"); case CodecH264: return AMFValue("avc1");
case CodecH265: return AMFValue(FLV_CODEC_H265); case CodecH265: return AMFValue(FLV_CODEC_H265);
case CodecG711A: return AMFValue(7); case CodecG711A: return AMFValue(FLV_CODEC_G711A);
case CodecG711U: return AMFValue(8); case CodecG711U: return AMFValue(FLV_CODEC_G711U);
default: return AMFValue(AMF_NULL); default: return AMFValue(AMF_NULL);
} }
} }
......
...@@ -56,11 +56,18 @@ public: ...@@ -56,11 +56,18 @@ public:
////////////////////////////////rtmp相关////////////////////////////////// ////////////////////////////////rtmp相关//////////////////////////////////
/** /**
* 根据amf对象获取应的Track * 根据amf对象获取视频相应的Track
* @param amf rtmp metadata中的videocodecid或audiocodecid的值 * @param amf rtmp metadata中的videocodecid的值
* @return * @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 * 根据amf对象获取相应的CodecId
...@@ -70,6 +77,13 @@ public: ...@@ -70,6 +77,13 @@ public:
static CodecId getCodecIdByAmf(const AMFValue &val); static CodecId getCodecIdByAmf(const AMFValue &val);
/** /**
* 根据amf对象获取音频相应的CodecId
* @param val rtmp metadata中的audiocodecid的值
* @return
*/
static CodecId getAudioCodecIdByAmf(const AMFValue& val);
/**
* 根据Track获取Rtmp的编解码器 * 根据Track获取Rtmp的编解码器
* @param track 媒体描述对象 * @param track 媒体描述对象
* @return * @return
......
...@@ -28,6 +28,8 @@ const char *CodecInfo::getCodecName() { ...@@ -28,6 +28,8 @@ const char *CodecInfo::getCodecName() {
SWITCH_CASE(CodecH264); SWITCH_CASE(CodecH264);
SWITCH_CASE(CodecH265); SWITCH_CASE(CodecH265);
SWITCH_CASE(CodecAAC); SWITCH_CASE(CodecAAC);
SWITCH_CASE(CodecG711A);
SWITCH_CASE(CodecG711U);
default: default:
return "unknown codec"; return "unknown codec";
} }
......
...@@ -15,7 +15,7 @@ namespace mediakit{ ...@@ -15,7 +15,7 @@ namespace mediakit{
Sdp::Ptr G711Track::getSdp() { Sdp::Ptr G711Track::getSdp() {
if(!ready()){ if(!ready()){
WarnL << "AAC Track未准备好"; WarnL << getCodecName() << " Track未准备好";
return nullptr; return nullptr;
} }
return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getCodecId() == CodecG711A ? 8 : 0, getAudioSampleBit()); return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getCodecId() == CodecG711A ? 8 : 0, getAudioSampleBit());
......
...@@ -57,7 +57,7 @@ public: ...@@ -57,7 +57,7 @@ public:
} }
CodecId getCodecId() const override{ CodecId getCodecId() const override{
return CodecAAC; return _codecId;
} }
bool keyFrame() const override { bool keyFrame() const override {
...@@ -68,6 +68,7 @@ public: ...@@ -68,6 +68,7 @@ public:
return false; return false;
} }
public: public:
CodecId _codecId = CodecG711A;
unsigned int frameLength; // 一个帧的长度包括 raw data block unsigned int frameLength; // 一个帧的长度包括 raw data block
unsigned char buffer[2 * 1024 + 7]; unsigned char buffer[2 * 1024 + 7];
uint32_t timeStamp; uint32_t timeStamp;
......
...@@ -51,7 +51,7 @@ protected: ...@@ -51,7 +51,7 @@ protected:
G711Frame::Ptr obtainFrame(); G711Frame::Ptr obtainFrame();
protected: protected:
G711Frame::Ptr _adts; G711Frame::Ptr _adts;
CodecId _codecid = CodecG711A; CodecId _codecid = CodecInvalid;
}; };
......
...@@ -51,12 +51,11 @@ void G711RtpEncoder::makeG711Rtp(const void *data, unsigned int len, bool mark, ...@@ -51,12 +51,11 @@ void G711RtpEncoder::makeG711Rtp(const void *data, unsigned int len, bool mark,
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
G711RtpDecoder::G711RtpDecoder(const Track::Ptr &track){ G711RtpDecoder::G711RtpDecoder(const Track::Ptr &track){
auto aacTrack = dynamic_pointer_cast<G711Track>(track); auto g711Track = dynamic_pointer_cast<G711Track>(track);
_codecid = aacTrack->getCodecId(); _codecid = g711Track->getCodecId();
if(!aacTrack || !aacTrack->ready()){ if(!g711Track || !g711Track->ready()){
WarnL << "该g711 track无效!"; WarnL << "该g711 track无效!";
}else{ }else{
//_aac_cfg = aacTrack->getAacCfg();
} }
_adts = obtainFrame(); _adts = obtainFrame();
} }
...@@ -81,6 +80,7 @@ bool G711RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) { ...@@ -81,6 +80,7 @@ bool G711RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
_adts->frameLength = length; _adts->frameLength = length;
memcpy(_adts->buffer, rtp_packet_buf, length); memcpy(_adts->buffer, rtp_packet_buf, length);
_adts->_codecId = _codecid;
if (rtppack->mark == true) { if (rtppack->mark == true) {
_adts->timeStamp = rtppack->timeStamp; _adts->timeStamp = rtppack->timeStamp;
onGetG711(_adts); onGetG711(_adts);
......
...@@ -44,7 +44,7 @@ private: ...@@ -44,7 +44,7 @@ private:
G711Frame::Ptr obtainFrame(); G711Frame::Ptr obtainFrame();
private: private:
G711Frame::Ptr _adts; G711Frame::Ptr _adts;
CodecId _codecid = CodecG711A; CodecId _codecid = CodecInvalid;
}; };
......
...@@ -75,6 +75,9 @@ using namespace toolkit; ...@@ -75,6 +75,9 @@ using namespace toolkit;
#define FLV_CODEC_AAC 10 #define FLV_CODEC_AAC 10
#define FLV_CODEC_H264 7 #define FLV_CODEC_H264 7
#define FLV_CODEC_H265 12 #define FLV_CODEC_H265 12
#define FLV_CODEC_G711A 7
#define FLV_CODEC_G711U 8
namespace mediakit { namespace mediakit {
......
...@@ -61,7 +61,7 @@ bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) { ...@@ -61,7 +61,7 @@ bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
//生成Track对象 //生成Track对象
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackByAmf(videoCodec)); _videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getVideoTrackByAmf(videoCodec));
if (_videoTrack) { if (_videoTrack) {
//生成rtmpCodec对象以便解码rtmp //生成rtmpCodec对象以便解码rtmp
_videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack); _videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
...@@ -78,7 +78,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { ...@@ -78,7 +78,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) { void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
//生成Track对象 //生成Track对象
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackByAmf(audioCodec)); _audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getAudioTrackByAmf(audioCodec));
if (_audioTrack) { if (_audioTrack) {
//生成rtmpCodec对象以便解码rtmp //生成rtmpCodec对象以便解码rtmp
_audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack); _audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论