From 370d31121cecbd931fd041f2bd14f81db82b4ee9 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Wed, 29 Aug 2018 11:19:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E7=94=9F?= =?UTF-8?q?=E6=88=90adts=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- c_wrapper/src/media.cpp | 11 ++++++----- c_wrapper/src/media.h | 12 ++++++------ src/Device/Device.cpp | 41 ++++++++++++++++++++++++++++++++++++---- src/Device/Device.h | 9 ++++++--- src/Http/HttpSession.cpp | 8 +------- src/Player/Player.cpp | 3 --- src/Player/Player.h | 8 ++++++++ 7 files changed, 64 insertions(+), 28 deletions(-) diff --git a/c_wrapper/src/media.cpp b/c_wrapper/src/media.cpp index fe3537ac..1403672b 100755 --- a/c_wrapper/src/media.cpp +++ b/c_wrapper/src/media.cpp @@ -49,8 +49,8 @@ static onceToken s_token([](){ //////////////////////////Rtsp media/////////////////////////// -API_EXPORT MediaContext API_CALL createMedia(const char *appName,const char *mediaName) { - DevChannel::Ptr ret(new DevChannel(DEFAULT_VHOST,appName,mediaName)); +API_EXPORT MediaContext API_CALL createMedia(const char *appName,const char *mediaName , int bEanbleHls, int bEnableMp4) { + DevChannel::Ptr ret(new DevChannel(DEFAULT_VHOST,appName,mediaName,0,bEanbleHls,bEnableMp4)); lock_guard lck(s_mtxMapMedia); s_mapMedia.emplace((void *) (ret.get()), ret); return ret.get(); @@ -68,12 +68,13 @@ API_EXPORT void API_CALL media_initVideo(MediaContext ctx, int width, int height info.iHeight = height; ptr->initVideo(info); } -API_EXPORT void API_CALL media_initAudio(MediaContext ctx, int channel, int sampleBit, int sampleRate) { +API_EXPORT void API_CALL media_initAudio(MediaContext ctx, int channel, int sampleBit, int sampleRate,int profile) { DevChannel *ptr = (DevChannel *) ctx; AudioInfo info; info.iSampleRate = sampleRate; info.iChannel = channel; info.iSampleBit = sampleBit; + info.iProfile = profile; ptr->initAudio(info); } API_EXPORT void API_CALL media_inputH264(MediaContext ctx, void *data, int len, unsigned long stamp) { @@ -81,10 +82,10 @@ API_EXPORT void API_CALL media_inputH264(MediaContext ctx, void *data, int len, DevChannel *ptr = (DevChannel *) ctx; ptr->inputH264((char *) data, len, stamp); } -API_EXPORT void API_CALL media_inputAAC(MediaContext ctx, void *data, int len,unsigned long stamp) { +API_EXPORT void API_CALL media_inputAAC(MediaContext ctx, void *data, int len,unsigned long stamp,int withAdtsHeader) { //TimeTicker(); DevChannel *ptr = (DevChannel *) ctx; - ptr->inputAAC((char *) data, len, stamp); + ptr->inputAAC((char *) data, len, stamp,withAdtsHeader); } API_EXPORT void API_CALL media_inputAAC1(MediaContext ctx, void *data, int len, unsigned long stamp,void *adts){ diff --git a/c_wrapper/src/media.h b/c_wrapper/src/media.h index 258459fc..11d2f20b 100755 --- a/c_wrapper/src/media.h +++ b/c_wrapper/src/media.h @@ -39,10 +39,10 @@ extern "C" { typedef void* MediaContext; /* * 描述:创建一个媒体源 - * 参数:mediaName:媒体名称,url地址的一部分 + * 参数:mediaName:媒体名称,url地址的一部分,bEanbleHls:是否启用hls,bEnableMp4:是否录制mp4 * 返回值:媒体源句柄 */ -API_EXPORT MediaContext API_CALL createMedia(const char *appName,const char *mediaName); +API_EXPORT MediaContext API_CALL createMedia(const char *appName,const char *mediaName,int bEanbleHls, int bEnableMp4); /* * 描述:销毁媒体源 @@ -60,10 +60,10 @@ API_EXPORT void API_CALL media_initVideo(MediaContext ctx, int width, int height /* * 描述:初始化媒体源的音频信息 - * 参数:ctx:媒体源句柄;channel:声道数;sampleBit:音频采样位数,支持16bit;sampleRate:音频采样率 + * 参数:ctx:媒体源句柄;channel:声道数;sampleBit:音频采样位数,支持16bit;sampleRate:音频采样率;profile:aac编码profile,在不输入adts头时用于生产adts头 * 返回值:无 */ -API_EXPORT void API_CALL media_initAudio(MediaContext ctx, int channel, int sampleBit, int sampleRate); +API_EXPORT void API_CALL media_initAudio(MediaContext ctx, int channel, int sampleBit, int sampleRate , int profile); /* * 描述:输入单帧H264视频,需要输入SPS和PPS帧,帧起始字节00 00 01,00 00 00 01均可 @@ -74,10 +74,10 @@ API_EXPORT void API_CALL media_inputH264(MediaContext ctx, void *data, int len, /* * 描述:输入单帧AAC音频(有adts头) - * 参数:ctx:媒体源句柄;data:单帧AAC数据;len:单帧AAC数据字节数;stamp:时间戳,毫秒 + * 参数:ctx:媒体源句柄;data:单帧AAC数据;len:单帧AAC数据字节数;stamp:时间戳,毫秒 ,withAdtsHeader:是否有adts头 * 返回值:无 */ -API_EXPORT void API_CALL media_inputAAC(MediaContext ctx, void *data, int len, unsigned long stamp); +API_EXPORT void API_CALL media_inputAAC(MediaContext ctx, void *data, int len, unsigned long stamp,int withAdtsHeader); /* diff --git a/src/Device/Device.cpp b/src/Device/Device.cpp index 1308551d..e1d3c508 100644 --- a/src/Device/Device.cpp +++ b/src/Device/Device.cpp @@ -100,7 +100,7 @@ void DevChannel::inputPCM(char* pcData, int iDataLen, uint32_t uiStamp) { } #endif //ENABLE_FAAC -void DevChannel::inputH264(char* pcData, int iDataLen, uint32_t uiStamp) { +void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t uiStamp) { if (!m_pRtpMaker_h264) { uint32_t ui32Ssrc; memcpy(&ui32Ssrc, makeRandStr(4, false).data(), 4); @@ -123,10 +123,16 @@ void DevChannel::inputH264(char* pcData, int iDataLen, uint32_t uiStamp) { m_pRtpMaker_h264->makeRtp(pcData + iOffset, iDataLen - iOffset, uiStamp); } -void DevChannel::inputAAC(char* pcData, int iDataLen, uint32_t uiStamp) { - inputAAC(pcData+7,iDataLen-7,uiStamp,pcData); +void DevChannel::inputAAC(const char* pcData, int iDataLen, uint32_t uiStamp,bool withAdtsHeader) { + if(withAdtsHeader){ + inputAAC(pcData+7,iDataLen-7,uiStamp,pcData); + } else if(m_pAdtsHeader){ + m_pAdtsHeader->aac_frame_length = iDataLen; + writeAdtsHeader(*m_pAdtsHeader,m_pAdtsHeader->data); + inputAAC(pcData,iDataLen,uiStamp,(const char *)m_pAdtsHeader->data); + } } -void DevChannel::inputAAC(char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,char *pcAdtsHeader){ +void DevChannel::inputAAC(const char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,const char *pcAdtsHeader){ if (!m_pRtpMaker_aac) { uint32_t ssrc; memcpy(&ssrc, makeRandStr(8, false).data() + 4, 4); @@ -273,6 +279,33 @@ void DevChannel::initVideo(const VideoInfo& info) { void DevChannel::initAudio(const AudioInfo& info) { m_audio.reset(new AudioInfo(info)); + m_pAdtsHeader.reset((AdtsFrame *)malloc(sizeof(AdtsFrame) - sizeof(AdtsFrame::data) + 7),[](AdtsFrame *ptr){ + free(ptr); + }); + + m_pAdtsHeader->syncword = 0x0FFF; + m_pAdtsHeader->id = 0; + m_pAdtsHeader->layer = 0; + m_pAdtsHeader->protection_absent = 1; + m_pAdtsHeader->profile = info.iProfile;//audioObjectType - 1; + int i = 0; + for(auto rate : samplingFrequencyTable){ + if(rate == info.iSampleRate){ + m_pAdtsHeader->sf_index = i; + }; + ++i; + } + + m_pAdtsHeader->private_bit = 0; + m_pAdtsHeader->channel_configuration = info.iChannel; + m_pAdtsHeader->original = 0; + m_pAdtsHeader->home = 0; + m_pAdtsHeader->copyright_identification_bit = 0; + m_pAdtsHeader->copyright_identification_start = 0; + m_pAdtsHeader->aac_frame_length = 7; + m_pAdtsHeader->adts_buffer_fullness = 2047; + m_pAdtsHeader->no_raw_data_blocks_in_frame = 0; + } } /* namespace DEV */ } /* namespace ZL */ diff --git a/src/Device/Device.h b/src/Device/Device.h index a164e99c..d53523f8 100644 --- a/src/Device/Device.h +++ b/src/Device/Device.h @@ -31,6 +31,7 @@ #include #include #include "Util/util.h" +#include "Player/Player.h" #include "RTP/RtpMakerAAC.h" #include "RTP/RtpMakerH264.h" #include "Rtsp/RtspToRtmpMediaSource.h" @@ -65,6 +66,7 @@ public: int iChannel; int iSampleBit; int iSampleRate; + int iProfile; }; class DevChannel : public RtspToRtmpMediaSource{ @@ -82,9 +84,9 @@ public: void initVideo(const VideoInfo &info); void initAudio(const AudioInfo &info); - void inputH264(char *pcData, int iDataLen, uint32_t uiStamp); - void inputAAC(char *pcDataWithAdts, int iDataLen, uint32_t uiStamp); - void inputAAC(char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,char *pcAdtsHeader); + void inputH264(const char *pcData, int iDataLen, uint32_t uiStamp); + void inputAAC(const char *pcDataWithAdts, int iDataLen, uint32_t uiStamp, bool withAdtsHeader = true); + void inputAAC(const char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,const char *pcAdtsHeader); #ifdef ENABLE_X264 void inputYUV(char *apcYuv[3], int aiYuvLen[3], uint32_t uiStamp); @@ -117,6 +119,7 @@ private: std::shared_ptr m_video; std::shared_ptr m_audio; SmoothTicker m_aTicker[2]; + std::shared_ptr m_pAdtsHeader; }; diff --git a/src/Http/HttpSession.cpp b/src/Http/HttpSession.cpp index 4c42036e..e031166f 100644 --- a/src/Http/HttpSession.cpp +++ b/src/Http/HttpSession.cpp @@ -208,18 +208,12 @@ inline bool HttpSession::checkLiveFlvStream(){ m_mediaInfo.m_streamid.erase(m_mediaInfo.m_streamid.size() - 4);//去除.flv后缀 auto mediaSrc = dynamic_pointer_cast(MediaSource::find(RTMP_SCHEMA,m_mediaInfo.m_vhost,m_mediaInfo.m_app,m_mediaInfo.m_streamid)); - if(!mediaSrc){ + if(!mediaSrc || !mediaSrc->ready()){ //该rtmp源不存在 sendNotFound(true); shutdown(); return true; } - if(!mediaSrc->ready()){ - //未准备好 - sendNotFound(true); - shutdown(); - return true; - } auto onRes = [this,mediaSrc](const string &err){ bool authSuccess = err.empty(); diff --git a/src/Player/Player.cpp b/src/Player/Player.cpp index e73160cf..4f2a1112 100644 --- a/src/Player/Player.cpp +++ b/src/Player/Player.cpp @@ -31,9 +31,6 @@ using namespace ZL::Util; -static unsigned const samplingFrequencyTable[16] = { 96000, 88200, - 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, - 8000, 7350, 0, 0, 0 }; void writeAdtsHeader(const AdtsFrame &hed, uint8_t *pcAdts) { pcAdts[0] = (hed.syncword >> 4 & 0xFF); //8bit diff --git a/src/Player/Player.h b/src/Player/Player.h index e826ee20..97d0b83f 100644 --- a/src/Player/Player.h +++ b/src/Player/Player.h @@ -63,6 +63,14 @@ typedef struct { uint32_t timeStamp; } AdtsFrame; +unsigned const samplingFrequencyTable[16] = { 96000, 88200, + 64000, 48000, + 44100, 32000, + 24000, 22050, + 16000, 12000, + 11025, 8000, + 7350, 0, 0, 0 }; + void makeAdtsHeader(const string &strAudioCfg,AdtsFrame &adts); void writeAdtsHeader(const AdtsFrame &adts, uint8_t *pcAdts) ; string makeAdtsConfig(const uint8_t *pcAdts);