简化接口

This commit is contained in:
xiongziliang 2020-04-18 23:56:27 +08:00
parent e1459834df
commit 49596bd97f
4 changed files with 106 additions and 191 deletions

View File

@ -38,42 +38,24 @@ API_EXPORT mk_media API_CALL mk_media_create(const char *vhost, const char *app,
API_EXPORT void API_CALL mk_media_release(mk_media ctx); API_EXPORT void API_CALL mk_media_release(mk_media ctx);
/** /**
* h264视频轨 *
* @param ctx * @param ctx
* @param track_id 0:CodecH264/1:CodecH265
* @param width * @param width
* @param height * @param height
* @param fps fps * @param fps fps
*/ */
API_EXPORT void API_CALL mk_media_init_h264(mk_media ctx, int width, int height, int fps); API_EXPORT void API_CALL mk_media_init_video(mk_media ctx, int track_id, int width, int height, int fps);
/** /**
* h265视频轨 *
* @param ctx * @param ctx
* @param width * @param track_id 2:CodecAAC/3:CodecG711A/4:CodecG711U
* @param height
* @param fps fps
*/
API_EXPORT void API_CALL mk_media_init_h265(mk_media ctx, int width, int height, int fps);
/**
* aac音频轨道
* @param ctx
* @param channel
* @param sample_bit 16
* @param sample_rate
* @param profile aac编码profileadts头时用于生产adts头
*/
API_EXPORT void API_CALL mk_media_init_aac(mk_media ctx, int channel, int sample_bit, int sample_rate, int profile);
/**
* g711音频轨道
* @param ctx
* @param au 3 : G711A 4: G711U
* @param channel * @param channel
* @param sample_bit 16 * @param sample_bit 16
* @param sample_rate * @param sample_rate
*/ */
API_EXPORT void API_CALL mk_media_init_g711(mk_media ctx, int au, int sample_bit, int sample_rate); API_EXPORT void API_CALL mk_media_init_audio(mk_media ctx, int track_id, int sample_rate, int channels, int sample_bit);
/** /**
* h264/h265/aac完毕后调用此函数 * h264/h265/aac完毕后调用此函数
@ -103,16 +85,6 @@ API_EXPORT void API_CALL mk_media_input_h264(mk_media ctx, void *data, int len,
*/ */
API_EXPORT void API_CALL mk_media_input_h265(mk_media ctx, void *data, int len, uint32_t dts, uint32_t pts); API_EXPORT void API_CALL mk_media_input_h265(mk_media ctx, void *data, int len, uint32_t dts, uint32_t pts);
/**
* AAC音频
* @param ctx
* @param data AAC数据
* @param len AAC数据字节数
* @param dts
* @param with_adts_header data中是否包含7个字节的adts头
*/
API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, uint32_t dts, int with_adts_header);
/** /**
* AAC音频(adts头) * AAC音频(adts头)
* @param ctx * @param ctx
@ -121,7 +93,7 @@ API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, u
* @param dts * @param dts
* @param adts adts头 * @param adts adts头
*/ */
API_EXPORT void API_CALL mk_media_input_aac1(mk_media ctx, void *data, int len, uint32_t dts, void *adts); API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, uint32_t dts, void *adts);
/** /**
* G711音频 * G711音频

View File

@ -109,50 +109,25 @@ API_EXPORT void API_CALL mk_media_release(mk_media ctx) {
delete obj; delete obj;
} }
API_EXPORT void API_CALL mk_media_init_h264(mk_media ctx, int width, int height, int frameRate) { API_EXPORT void API_CALL mk_media_init_video(mk_media ctx, int track_id, int width, int height, int fps){
assert(ctx); assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx; MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
VideoInfo info; VideoInfo info;
info.codecId = CodecH264; info.codecId = (CodecId)track_id;
info.iFrameRate = frameRate; info.iFrameRate = fps;
info.iWidth = width; info.iWidth = width;
info.iHeight = height; info.iHeight = height;
(*obj)->getChannel()->initVideo(info); (*obj)->getChannel()->initVideo(info);
} }
API_EXPORT void API_CALL mk_media_init_h265(mk_media ctx, int width, int height, int frameRate) { API_EXPORT void API_CALL mk_media_init_audio(mk_media ctx, int track_id, int sample_rate, int channels, int sample_bit){
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
VideoInfo info;
info.codecId = CodecH265;
info.iFrameRate = frameRate;
info.iWidth = width;
info.iHeight = height;
(*obj)->getChannel()->initVideo(info);
}
API_EXPORT void API_CALL mk_media_init_aac(mk_media ctx, int channel, int sample_bit, int sample_rate, int profile) {
assert(ctx); assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx; MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
AudioInfo info; AudioInfo info;
info.codecId = CodecAAC; info.codecId = (CodecId)track_id;
info.iSampleRate = sample_rate; info.iSampleRate = sample_rate;
info.iChannel = channel; info.iChannel = channels;
info.iSampleBit = sample_bit; info.iSampleBit = sample_bit;
info.iProfile = profile;
(*obj)->getChannel()->initAudio(info);
}
API_EXPORT void API_CALL mk_media_init_g711(mk_media ctx, int au, int sample_bit, int sample_rate){
assert(ctx);
assert(au == CodecG711A || au == CodecG711U);
MediaHelper::Ptr* obj = (MediaHelper::Ptr*) ctx;
AudioInfo info;
info.codecId = (CodecId)au;
info.iSampleRate = sample_rate;
info.iChannel = 1;
info.iSampleBit = sample_bit;
info.iProfile = 0;
(*obj)->getChannel()->initAudio(info); (*obj)->getChannel()->initAudio(info);
} }
@ -174,13 +149,7 @@ API_EXPORT void API_CALL mk_media_input_h265(mk_media ctx, void *data, int len,
(*obj)->getChannel()->inputH265((char *) data, len, dts, pts); (*obj)->getChannel()->inputH265((char *) data, len, dts, pts);
} }
API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, uint32_t dts, int with_adts_header) { API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, uint32_t dts, void *adts) {
assert(ctx && data && len > 0);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->getChannel()->inputAAC((char *) data, len, dts, with_adts_header);
}
API_EXPORT void API_CALL mk_media_input_aac1(mk_media ctx, void *data, int len, uint32_t dts, void *adts) {
assert(ctx && data && len > 0 && adts); assert(ctx && data && len > 0 && adts);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx; MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->getChannel()->inputAAC((char *) data, len, dts, (char *) adts); (*obj)->getChannel()->inputAAC((char *) data, len, dts, (char *) adts);

View File

@ -20,15 +20,15 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
DevChannel::DevChannel(const string &strVhost, DevChannel::DevChannel(const string &vhost,
const string &strApp, const string &app,
const string &strId, const string &stream_id,
float fDuration, float duration,
bool bEanbleRtsp, bool enable_rtsp,
bool bEanbleRtmp, bool enable_rtmp,
bool bEanbleHls, bool enable_hls,
bool bEnableMp4) : bool enable_mp4) :
MultiMediaSourceMuxer(strVhost, strApp, strId, fDuration, bEanbleRtsp, bEanbleRtmp, bEanbleHls, bEnableMp4) {} MultiMediaSourceMuxer(vhost, app, stream_id, duration, enable_rtsp, enable_rtmp, enable_hls, enable_mp4) {}
DevChannel::~DevChannel() {} DevChannel::~DevChannel() {}
@ -65,13 +65,13 @@ void DevChannel::inputPCM(char* pcData, int iDataLen, uint32_t uiStamp) {
unsigned char *pucOut; unsigned char *pucOut;
int iRet = _pAacEnc->inputData(pcData, iDataLen, &pucOut); int iRet = _pAacEnc->inputData(pcData, iDataLen, &pucOut);
if (iRet > 0) { if (iRet > 0) {
inputAAC((char *) pucOut, iRet, uiStamp); inputAAC((char *) pucOut + 7, iRet, uiStamp, pucOut);
} }
} }
} }
#endif //ENABLE_FAAC #endif //ENABLE_FAAC
void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t dts,uint32_t pts) { void DevChannel::inputH264(const char *data, int len, uint32_t dts, uint32_t pts) {
if(dts == 0){ if(dts == 0){
dts = (uint32_t)_aTicker[0].elapsedTime(); dts = (uint32_t)_aTicker[0].elapsedTime();
} }
@ -79,24 +79,27 @@ void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t dts,uint32
pts = dts; pts = dts;
} }
int prefixeSize; int prefixeSize;
if (memcmp("\x00\x00\x00\x01", pcData, 4) == 0) { if (memcmp("\x00\x00\x00\x01", data, 4) == 0) {
prefixeSize = 4; prefixeSize = 4;
} else if (memcmp("\x00\x00\x01", pcData, 3) == 0) { } else if (memcmp("\x00\x00\x01", data, 3) == 0) {
prefixeSize = 3; prefixeSize = 3;
} else { } else {
prefixeSize = 0; prefixeSize = 0;
} }
//由于rtmp/hls/mp4需要缓存时间戳相同的帧
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
H264Frame::Ptr frame = std::make_shared<H264Frame>(); H264Frame::Ptr frame = std::make_shared<H264Frame>();
frame->_dts = dts; frame->_dts = dts;
frame->_pts = pts; frame->_pts = pts;
frame->_buffer.assign("\x00\x00\x00\x01",4); frame->_buffer.assign("\x00\x00\x00\x01",4);
frame->_buffer.append(pcData + prefixeSize, iDataLen - prefixeSize); frame->_buffer.append(data + prefixeSize, len - prefixeSize);
frame->_prefix_size = 4; frame->_prefix_size = 4;
inputFrame(frame); inputFrame(frame);
} }
void DevChannel::inputH265(const char* pcData, int iDataLen, uint32_t dts,uint32_t pts) { void DevChannel::inputH265(const char *data, int len, uint32_t dts, uint32_t pts) {
if(dts == 0){ if(dts == 0){
dts = (uint32_t)_aTicker[0].elapsedTime(); dts = (uint32_t)_aTicker[0].elapsedTime();
} }
@ -104,51 +107,63 @@ void DevChannel::inputH265(const char* pcData, int iDataLen, uint32_t dts,uint32
pts = dts; pts = dts;
} }
int prefixeSize; int prefixeSize;
if (memcmp("\x00\x00\x00\x01", pcData, 4) == 0) { if (memcmp("\x00\x00\x00\x01", data, 4) == 0) {
prefixeSize = 4; prefixeSize = 4;
} else if (memcmp("\x00\x00\x01", pcData, 3) == 0) { } else if (memcmp("\x00\x00\x01", data, 3) == 0) {
prefixeSize = 3; prefixeSize = 3;
} else { } else {
prefixeSize = 0; prefixeSize = 0;
} }
//由于rtmp/hls/mp4需要缓存时间戳相同的帧
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
H265Frame::Ptr frame = std::make_shared<H265Frame>(); H265Frame::Ptr frame = std::make_shared<H265Frame>();
frame->_dts = dts; frame->_dts = dts;
frame->_pts = pts; frame->_pts = pts;
frame->_buffer.assign("\x00\x00\x00\x01",4); frame->_buffer.assign("\x00\x00\x00\x01",4);
frame->_buffer.append(pcData + prefixeSize, iDataLen - prefixeSize); frame->_buffer.append(data + prefixeSize, len - prefixeSize);
frame->_prefix_size = 4; frame->_prefix_size = 4;
inputFrame(frame); inputFrame(frame);
} }
void DevChannel::inputAAC(const char* pcData, int iDataLen, uint32_t uiStamp,bool withAdtsHeader) { class AACFrameCacheAble : public AACFrameNoCacheAble{
if(withAdtsHeader){ public:
inputAAC(pcData+7,iDataLen-7,uiStamp,pcData); template <typename ... ARGS>
} else if(_audio) { AACFrameCacheAble(ARGS && ...args) : AACFrameNoCacheAble(std::forward<ARGS>(args)...){};
inputAAC(pcData,iDataLen,uiStamp,(char *)_adtsHeader); virtual ~AACFrameCacheAble() {
delete [] _ptr;
};
bool cacheAble() const override {
return true;
} }
};
void DevChannel::inputAAC(const char *data_without_adts, int len, uint32_t dts, const char *adts_header){
if(dts == 0){
dts = (uint32_t)_aTicker[1].elapsedTime();
} }
void DevChannel::inputAAC(const char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,const char *pcAdtsHeader){ if(adts_header){
if(uiStamp == 0){ if(adts_header + 7 == data_without_adts){
uiStamp = (uint32_t)_aTicker[1].elapsedTime(); //adts头和帧再一起
} inputFrame(std::make_shared<AACFrameNoCacheAble>((char *)data_without_adts - 7, len + 7, dts, 0, 7));
if(pcAdtsHeader + 7 == pcDataWithoutAdts){
inputFrame(std::make_shared<AACFrameNoCacheAble>((char *)pcDataWithoutAdts - 7,iDataLen + 7,uiStamp,0,7));
}else{ }else{
char *dataWithAdts = new char[iDataLen + 7]; //adts头和帧不再一起
memcpy(dataWithAdts,pcAdtsHeader,7); char *dataWithAdts = new char[len + 7];
memcpy(dataWithAdts + 7 , pcDataWithoutAdts , iDataLen); memcpy(dataWithAdts, adts_header, 7);
inputFrame(std::make_shared<AACFrameNoCacheAble>(dataWithAdts,iDataLen + 7,uiStamp,0,7)); memcpy(dataWithAdts + 7 , data_without_adts , len);
delete [] dataWithAdts; inputFrame(std::make_shared<AACFrameCacheAble>(dataWithAdts, len + 7, dts, 0, 7));
}
} }
} }
void DevChannel::inputG711(const char* pcData, int iDataLen, uint32_t uiStamp){ void DevChannel::inputG711(const char *data, int len, uint32_t dts){
if (uiStamp == 0) { if (dts == 0) {
uiStamp = (uint32_t)_aTicker[1].elapsedTime(); dts = (uint32_t)_aTicker[1].elapsedTime();
} }
inputFrame(std::make_shared<G711FrameNoCacheAble>(_audio->codecId, (char*)pcData, iDataLen, uiStamp, 0)); inputFrame(std::make_shared<G711FrameNoCacheAble>(_audio->codecId, (char*)data, len, dts, 0));
} }
void DevChannel::initVideo(const VideoInfo &info) { void DevChannel::initVideo(const VideoInfo &info) {
@ -160,41 +175,10 @@ void DevChannel::initVideo(const VideoInfo& info) {
} }
} }
static void makeAdtsHeader(int profile, int sampleRate, int channels,uint8_t *out){
AACFrame adtsHeader;
adtsHeader.syncword = 0x0FFF;
adtsHeader.id = 0;
adtsHeader.layer = 0;
adtsHeader.protection_absent = 1;
adtsHeader.profile = profile;//audioObjectType - 1;
int i = 0;
for (auto rate : samplingFrequencyTable) {
if (rate == sampleRate) {
adtsHeader.sf_index = i;
};
++i;
}
adtsHeader.private_bit = 0;
adtsHeader.channel_configuration = channels;
adtsHeader.original = 0;
adtsHeader.home = 0;
adtsHeader.copyright_identification_bit = 0;
adtsHeader.copyright_identification_start = 0;
adtsHeader.aac_frame_length = 7;
adtsHeader.adts_buffer_fullness = 2047;
adtsHeader.no_raw_data_blocks_in_frame = 0;
writeAdtsHeader(adtsHeader, out);
}
void DevChannel::initAudio(const AudioInfo &info) { void DevChannel::initAudio(const AudioInfo &info) {
_audio = std::make_shared<AudioInfo>(info); _audio = std::make_shared<AudioInfo>(info);
switch (info.codecId) { switch (info.codecId) {
case CodecAAC : { case CodecAAC : addTrack(std::make_shared<AACTrack>()); break;
addTrack(std::make_shared<AACTrack>());
makeAdtsHeader(info.iProfile, info.iSampleBit, info.iChannel, _adtsHeader);
break;
}
case CodecG711A : case CodecG711A :
case CodecG711U : addTrack(std::make_shared<G711Track>(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit)); break; case CodecG711U : addTrack(std::make_shared<G711Track>(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit)); break;
default: WarnL << "不支持该类型的音频编码类型:" << info.codecId; break; default: WarnL << "不支持该类型的音频编码类型:" << info.codecId; break;

View File

@ -30,7 +30,6 @@ using namespace toolkit;
#include "Codec/H264Encoder.h" #include "Codec/H264Encoder.h"
#endif //ENABLE_X264 #endif //ENABLE_X264
namespace mediakit { namespace mediakit {
class VideoInfo { class VideoInfo {
@ -40,90 +39,82 @@ public:
int iHeight; int iHeight;
float iFrameRate; float iFrameRate;
}; };
class AudioInfo { class AudioInfo {
public: public:
CodecId codecId = CodecAAC; CodecId codecId = CodecAAC;
int iChannel; int iChannel;
int iSampleBit; int iSampleBit;
int iSampleRate; int iSampleRate;
int iProfile;
}; };
/** /**
* 使MultiMediaSourceMuxer类 * MultiMediaSourceMuxer类的包装便使
*/ */
class DevChannel : public MultiMediaSourceMuxer{ class DevChannel : public MultiMediaSourceMuxer{
public: public:
typedef std::shared_ptr<DevChannel> Ptr; typedef std::shared_ptr<DevChannel> Ptr;
//fDuration<=0为直播否则为点播 //fDuration<=0为直播否则为点播
DevChannel(const string &strVhost, DevChannel(const string &vhost,
const string &strApp, const string &app,
const string &strId, const string &stream_id,
float fDuration = 0, float duration = 0,
bool bEanbleRtsp = true, bool enable_rtsp = true,
bool bEanbleRtmp = true, bool enable_rtmp = true,
bool bEanbleHls = true, bool enable_hls = true,
bool bEnableMp4 = false); bool enable_mp4 = false);
virtual ~DevChannel(); virtual ~DevChannel();
/** /**
* h264视频Track * Track
* MultiMediaSourceMuxer::addTrack(H264Track::Ptr ); * MultiMediaSourceMuxer::addTrack(VideoTrack::Ptr );
* @param info * @param info
*/ */
void initVideo(const VideoInfo &info); void initVideo(const VideoInfo &info);
/** /**
* aac音频Track * Track
* MultiMediaSourceMuxer::addTrack(AACTrack::Ptr ); * MultiMediaSourceMuxer::addTrack(AudioTrack::Ptr );
* @param info * @param info
*/ */
void initAudio(const AudioInfo &info); void initAudio(const AudioInfo &info);
/** /**
* 264 * 264
* @param pcData 264 * @param data 264
* @param iDataLen * @param len
* @param dts 0 * @param dts 0
* @param pts 0dts * @param pts 0dts
*/ */
void inputH264(const char *pcData, int iDataLen, uint32_t dts,uint32_t pts = 0); void inputH264(const char *data, int len, uint32_t dts, uint32_t pts = 0);
/** /**
* 265 * 265
* @param pcData 265 * @param data 265
* @param iDataLen * @param len
* @param dts 0 * @param dts 0
* @param pts 0dts * @param pts 0dts
*/ */
void inputH265(const char *pcData, int iDataLen, uint32_t dts,uint32_t pts = 0); void inputH265(const char *data, int len, uint32_t dts, uint32_t pts = 0);
/** /**
* adts头的aac帧 * aac帧
* @param pcDataWithAdts adts头的aac帧 * @param data_without_adts adts头的aac帧
* @param iDataLen * @param len
* @param uiStamp 0 * @param dts
* @param withAdtsHeader adts头 * @param adts_header adts头
*/ */
void inputAAC(const char *pcDataWithAdts, int iDataLen, uint32_t uiStamp, bool withAdtsHeader = true); void inputAAC(const char *data_without_adts, int len, uint32_t dts, const char *adts_header);
/**
* adts头的aac帧
* @param pcDataWithoutAdts adts头的aac帧
* @param iDataLen
* @param uiStamp
* @param pcAdtsHeader adts头
*/
void inputAAC(const char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,const char *pcAdtsHeader);
/** /**
* G711音频帧 * G711音频帧
* @param pcData * @param data
* @param iDataLen * @param len
* @param uiStamp * @param dts
*/ */
void inputG711(const char* pcData, int iDataLen, uint32_t uiStamp); void inputG711(const char* data, int len, uint32_t dts);
#ifdef ENABLE_X264 #ifdef ENABLE_X264
/** /**
* yuv420p视频帧inputH264方法 * yuv420p视频帧inputH264方法
@ -146,6 +137,7 @@ public:
#endif //ENABLE_FAAC #endif //ENABLE_FAAC
private: private:
#ifdef ENABLE_X264 #ifdef ENABLE_X264
std::shared_ptr<H264Encoder> _pH264Enc; std::shared_ptr<H264Encoder> _pH264Enc;
#endif //ENABLE_X264 #endif //ENABLE_X264
@ -155,9 +147,7 @@ private:
#endif //ENABLE_FAAC #endif //ENABLE_FAAC
std::shared_ptr<VideoInfo> _video; std::shared_ptr<VideoInfo> _video;
std::shared_ptr<AudioInfo> _audio; std::shared_ptr<AudioInfo> _audio;
SmoothTicker _aTicker[2]; SmoothTicker _aTicker[2];
uint8_t _adtsHeader[7];
}; };
} /* namespace mediakit */ } /* namespace mediakit */