简化接口

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);
/**
* h264视频轨
*
* @param ctx
* @param track_id 0:CodecH264/1:CodecH265
* @param width
* @param height
* @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 width
* @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 track_id 2:CodecAAC/3:CodecG711A/4:CodecG711U
* @param channel
* @param sample_bit 16
* @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完毕后调用此函数
@ -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);
/**
* 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头)
* @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 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音频

View File

@ -109,50 +109,25 @@ API_EXPORT void API_CALL mk_media_release(mk_media ctx) {
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);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
VideoInfo info;
info.codecId = CodecH264;
info.iFrameRate = frameRate;
info.codecId = (CodecId)track_id;
info.iFrameRate = fps;
info.iWidth = width;
info.iHeight = height;
(*obj)->getChannel()->initVideo(info);
}
API_EXPORT void API_CALL mk_media_init_h265(mk_media ctx, int width, int height, int frameRate) {
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) {
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;
AudioInfo info;
info.codecId = CodecAAC;
info.codecId = (CodecId)track_id;
info.iSampleRate = sample_rate;
info.iChannel = channel;
info.iChannel = channels;
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);
}
@ -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);
}
API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, uint32_t dts, int with_adts_header) {
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) {
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 && adts);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->getChannel()->inputAAC((char *) data, len, dts, (char *) adts);

View File

@ -20,15 +20,15 @@ using namespace toolkit;
namespace mediakit {
DevChannel::DevChannel(const string &strVhost,
const string &strApp,
const string &strId,
float fDuration,
bool bEanbleRtsp,
bool bEanbleRtmp,
bool bEanbleHls,
bool bEnableMp4) :
MultiMediaSourceMuxer(strVhost, strApp, strId, fDuration, bEanbleRtsp, bEanbleRtmp, bEanbleHls, bEnableMp4) {}
DevChannel::DevChannel(const string &vhost,
const string &app,
const string &stream_id,
float duration,
bool enable_rtsp,
bool enable_rtmp,
bool enable_hls,
bool enable_mp4) :
MultiMediaSourceMuxer(vhost, app, stream_id, duration, enable_rtsp, enable_rtmp, enable_hls, enable_mp4) {}
DevChannel::~DevChannel() {}
@ -65,13 +65,13 @@ void DevChannel::inputPCM(char* pcData, int iDataLen, uint32_t uiStamp) {
unsigned char *pucOut;
int iRet = _pAacEnc->inputData(pcData, iDataLen, &pucOut);
if (iRet > 0) {
inputAAC((char *) pucOut, iRet, uiStamp);
inputAAC((char *) pucOut + 7, iRet, uiStamp, pucOut);
}
}
}
#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){
dts = (uint32_t)_aTicker[0].elapsedTime();
}
@ -79,24 +79,27 @@ void DevChannel::inputH264(const char* pcData, int iDataLen, uint32_t dts,uint32
pts = dts;
}
int prefixeSize;
if (memcmp("\x00\x00\x00\x01", pcData, 4) == 0) {
if (memcmp("\x00\x00\x00\x01", data, 4) == 0) {
prefixeSize = 4;
} else if (memcmp("\x00\x00\x01", pcData, 3) == 0) {
} else if (memcmp("\x00\x00\x01", data, 3) == 0) {
prefixeSize = 3;
} else {
prefixeSize = 0;
}
//由于rtmp/hls/mp4需要缓存时间戳相同的帧
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
H264Frame::Ptr frame = std::make_shared<H264Frame>();
frame->_dts = dts;
frame->_pts = pts;
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;
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){
dts = (uint32_t)_aTicker[0].elapsedTime();
}
@ -104,54 +107,66 @@ void DevChannel::inputH265(const char* pcData, int iDataLen, uint32_t dts,uint32
pts = dts;
}
int prefixeSize;
if (memcmp("\x00\x00\x00\x01", pcData, 4) == 0) {
if (memcmp("\x00\x00\x00\x01", data, 4) == 0) {
prefixeSize = 4;
} else if (memcmp("\x00\x00\x01", pcData, 3) == 0) {
} else if (memcmp("\x00\x00\x01", data, 3) == 0) {
prefixeSize = 3;
} else {
prefixeSize = 0;
}
//由于rtmp/hls/mp4需要缓存时间戳相同的帧
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
H265Frame::Ptr frame = std::make_shared<H265Frame>();
frame->_dts = dts;
frame->_pts = pts;
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;
inputFrame(frame);
}
void DevChannel::inputAAC(const char* pcData, int iDataLen, uint32_t uiStamp,bool withAdtsHeader) {
if(withAdtsHeader){
inputAAC(pcData+7,iDataLen-7,uiStamp,pcData);
} else if(_audio) {
inputAAC(pcData,iDataLen,uiStamp,(char *)_adtsHeader);
class AACFrameCacheAble : public AACFrameNoCacheAble{
public:
template <typename ... ARGS>
AACFrameCacheAble(ARGS && ...args) : AACFrameNoCacheAble(std::forward<ARGS>(args)...){};
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();
}
if(adts_header){
if(adts_header + 7 == data_without_adts){
//adts头和帧再一起
inputFrame(std::make_shared<AACFrameNoCacheAble>((char *)data_without_adts - 7, len + 7, dts, 0, 7));
}else{
//adts头和帧不再一起
char *dataWithAdts = new char[len + 7];
memcpy(dataWithAdts, adts_header, 7);
memcpy(dataWithAdts + 7 , data_without_adts , len);
inputFrame(std::make_shared<AACFrameCacheAble>(dataWithAdts, len + 7, dts, 0, 7));
}
}
}
void DevChannel::inputAAC(const char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,const char *pcAdtsHeader){
if(uiStamp == 0){
uiStamp = (uint32_t)_aTicker[1].elapsedTime();
}
if(pcAdtsHeader + 7 == pcDataWithoutAdts){
inputFrame(std::make_shared<AACFrameNoCacheAble>((char *)pcDataWithoutAdts - 7,iDataLen + 7,uiStamp,0,7));
} else {
char *dataWithAdts = new char[iDataLen + 7];
memcpy(dataWithAdts,pcAdtsHeader,7);
memcpy(dataWithAdts + 7 , pcDataWithoutAdts , iDataLen);
inputFrame(std::make_shared<AACFrameNoCacheAble>(dataWithAdts,iDataLen + 7,uiStamp,0,7));
delete [] dataWithAdts;
void DevChannel::inputG711(const char *data, int len, uint32_t dts){
if (dts == 0) {
dts = (uint32_t)_aTicker[1].elapsedTime();
}
inputFrame(std::make_shared<G711FrameNoCacheAble>(_audio->codecId, (char*)data, len, dts, 0));
}
void DevChannel::inputG711(const char* pcData, int iDataLen, uint32_t uiStamp){
if (uiStamp == 0) {
uiStamp = (uint32_t)_aTicker[1].elapsedTime();
}
inputFrame(std::make_shared<G711FrameNoCacheAble>(_audio->codecId, (char*)pcData, iDataLen, uiStamp, 0));
}
void DevChannel::initVideo(const VideoInfo& info) {
void DevChannel::initVideo(const VideoInfo &info) {
_video = std::make_shared<VideoInfo>(info);
switch (info.codecId){
case CodecH265 : addTrack(std::make_shared<H265Track>()); break;
@ -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);
switch (info.codecId) {
case CodecAAC : {
addTrack(std::make_shared<AACTrack>());
makeAdtsHeader(info.iProfile, info.iSampleBit, info.iChannel, _adtsHeader);
break;
}
case CodecAAC : addTrack(std::make_shared<AACTrack>()); break;
case CodecG711A :
case CodecG711U : addTrack(std::make_shared<G711Track>(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit)); break;
default: WarnL << "不支持该类型的音频编码类型:" << info.codecId; break;

View File

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