精简代码

This commit is contained in:
xia-chu 2023-12-09 03:18:57 +08:00
parent 7d4a930162
commit 630b5d75d9
13 changed files with 89 additions and 147 deletions

View File

@ -10,8 +10,7 @@
#include "mk_h264_splitter.h"
#include "Http/HttpRequestSplitter.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/Factory.h"
using namespace mediakit;
@ -71,9 +70,9 @@ const char *H264Splitter::onSearchPacketTail(const char *data, size_t len) {
auto last_frame_len = next_frame - last_frame;
Frame::Ptr frame;
if (_h265) {
frame = std::make_shared<H265FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len));
frame = Factory::getFrameFromPtr(CodecH265, (char *)last_frame, last_frame_len, 0, 0);
} else {
frame = std::make_shared<H264FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len));
frame = Factory::getFrameFromPtr(CodecH264, (char *)last_frame, last_frame_len, 0, 0);
}
if (frame->decodeAble()) {
_search_pos = 0;

View File

@ -15,7 +15,6 @@
#include "Util/File.h"
#include "Util/uv_errno.h"
#include "Transcode.h"
#include "Extension/AAC.h"
#include "Common/config.h"
#define MAX_DELAY_SECOND 3

View File

@ -11,11 +11,7 @@
#include "Device.h"
#include "Util/logger.h"
#include "Util/base64.h"
#include "Extension/AAC.h"
#include "Extension/Opus.h"
#include "Extension/G711.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/Factory.h"
#ifdef ENABLE_FAAC
#include "Codec/AACEncoder.h"
#endif //ENABLE_FAAC
@ -85,15 +81,7 @@ bool DevChannel::inputH264(const char *data, int len, uint64_t dts, uint64_t pts
pts = dts;
}
//由于rtmp/hls/mp4需要缓存时间戳相同的帧
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
auto frame = FrameImp::create<H264Frame>();
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign(data, len);
frame->_prefix_size = prefixSize(data,len);
return inputFrame(frame);
return inputFrame(Factory::getFrameFromPtr(CodecH264,data, len, dts, pts));
}
bool DevChannel::inputH265(const char *data, int len, uint64_t dts, uint64_t pts) {
@ -104,17 +92,11 @@ bool DevChannel::inputH265(const char *data, int len, uint64_t dts, uint64_t pts
pts = dts;
}
//由于rtmp/hls/mp4需要缓存时间戳相同的帧
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
auto frame = FrameImp::create<H265Frame>();
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign(data, len);
frame->_prefix_size = prefixSize(data,len);
return inputFrame(frame);
return inputFrame(Factory::getFrameFromPtr(CodecH265, data, len, dts, pts));
}
#define ADTS_HEADER_LEN 7
bool DevChannel::inputAAC(const char *data_without_adts, int len, uint64_t dts, const char *adts_header){
if (dts == 0) {
dts = _aTicker[1].elapsedTime();
@ -122,47 +104,36 @@ bool DevChannel::inputAAC(const char *data_without_adts, int len, uint64_t dts,
if (!adts_header) {
//没有adts头
return inputFrame(std::make_shared<FrameFromPtr>(_audio->codecId, (char *) data_without_adts, len, dts, 0, 0));
return inputFrame(std::make_shared<FrameFromPtr>(CodecAAC, (char *) data_without_adts, len, dts, 0, 0));
}
if (adts_header + ADTS_HEADER_LEN == data_without_adts) {
//adts头和帧在一起
return inputFrame(std::make_shared<FrameFromPtr>(_audio->codecId, (char *) data_without_adts - ADTS_HEADER_LEN, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN));
return inputFrame(std::make_shared<FrameFromPtr>(CodecAAC, (char *) data_without_adts - ADTS_HEADER_LEN, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN));
}
//adts头和帧不在一起
char *data_with_adts = new char[len + ADTS_HEADER_LEN];
memcpy(data_with_adts, adts_header, ADTS_HEADER_LEN);
memcpy(data_with_adts + ADTS_HEADER_LEN, data_without_adts, len);
return inputFrame(std::make_shared<FrameAutoDelete>(_audio->codecId, data_with_adts, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN));
return inputFrame(std::make_shared<FrameAutoDelete>(CodecAAC, data_with_adts, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN));
}
bool DevChannel::inputAudio(const char *data, int len, uint64_t dts){
if (dts == 0) {
dts = _aTicker[1].elapsedTime();
}
return inputFrame(std::make_shared<FrameFromPtr>(_audio->codecId, (char *) data, len, dts, 0));
return inputFrame(Factory::getFrameFromPtr(_audio->codecId, (char *) data, len, dts, dts));
}
bool DevChannel::initVideo(const VideoInfo &info) {
_video = std::make_shared<VideoInfo>(info);
switch (info.codecId){
case CodecH265 : return addTrack(std::make_shared<H265Track>());
case CodecH264 : return addTrack(std::make_shared<H264Track>());
default: WarnL << "不支持该类型的视频编码类型:" << info.codecId; return false;
}
return addTrack(Factory::getTrackByCodecId(info.codecId));
}
bool DevChannel::initAudio(const AudioInfo &info) {
_audio = std::make_shared<AudioInfo>(info);
switch (info.codecId) {
case CodecAAC : return addTrack(std::make_shared<AACTrack>());
case CodecG711A :
case CodecG711U : return addTrack(std::make_shared<G711Track>(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit));
case CodecOpus : return addTrack(std::make_shared<OpusTrack>());
default: WarnL << "不支持该类型的音频编码类型:" << info.codecId; return false;
}
return addTrack(Factory::getTrackByCodecId(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit));
}
bool DevChannel::inputFrame(const Frame::Ptr &frame) {

View File

@ -9,8 +9,8 @@
*/
#include "MediaSink.h"
#include "Extension/AAC.h"
#include "Common/config.h"
#include "Extension/Factory.h"
using namespace std;
@ -226,16 +226,16 @@ static uint8_t s_mute_adts[] = {0xff, 0xf1, 0x6c, 0x40, 0x2d, 0x3f, 0xfc, 0x00,
0xc5, 0x97, 0x39, 0x6a, 0xb8, 0xa2, 0x55, 0xa8, 0xf8};
#define MUTE_ADTS_DATA s_mute_adts
#define MUTE_ADTS_DATA_LEN sizeof(s_mute_adts)
#define MUTE_ADTS_DATA_MS 128
static uint8_t ADTS_CONFIG[2] = { 0x15, 0x88 };
bool MuteAudioMaker::inputFrame(const Frame::Ptr &frame) {
if (frame->getTrackType() == TrackVideo) {
auto audio_idx = frame->dts() / MUTE_ADTS_DATA_MS;
if (_audio_idx != audio_idx) {
_audio_idx = audio_idx;
auto aacFrame = std::make_shared<FrameToCache<FrameFromPtr>>(CodecAAC, (char *) MUTE_ADTS_DATA, MUTE_ADTS_DATA_LEN,
_audio_idx * MUTE_ADTS_DATA_MS, 0, ADTS_HEADER_LEN);
auto aacFrame = std::make_shared<FrameToCache<FrameFromPtr>>(CodecAAC, (char *) MUTE_ADTS_DATA, sizeof(s_mute_adts),
_audio_idx * MUTE_ADTS_DATA_MS, 0, 7);
return FrameDispatcher::inputFrame(aacFrame);
}
}
@ -249,7 +249,8 @@ bool MediaSink::addMuteAudioTrack() {
if (_track_map.find(TrackAudio) != _track_map.end()) {
return false;
}
auto audio = std::make_shared<AACTrack>(MUTE_ADTS_DATA, ADTS_HEADER_LEN);
auto audio = Factory::getTrackByCodecId(CodecAAC);
audio->setExtraData(ADTS_CONFIG, 2);
_track_map[audio->getTrackType()] = std::make_pair(audio, true);
audio->addDelegate([this](const Frame::Ptr &frame) {
return onTrackFrame(frame);

View File

@ -244,8 +244,6 @@ AACTrack::AACTrack(const string &aac_cfg) {
update();
}
AACTrack::AACTrack(const uint8_t *adts, size_t size) : AACTrack(makeAacConfig(adts, size)) {}
CodecId AACTrack::getCodecId() const {
return CodecAAC;
}

View File

@ -17,8 +17,6 @@
namespace mediakit{
int dumpAacConfig(const std::string &config, size_t length, uint8_t *out, size_t out_size);
/**
* aac音频通道
*/
@ -33,11 +31,6 @@ public:
*/
AACTrack(const std::string &aac_cfg);
/**
* aac adts头
*/
AACTrack(const uint8_t *adts, size_t size);
bool ready() const override;
CodecId getCodecId() const override;
int getAudioChannel() const override;

View File

@ -29,6 +29,7 @@
#include "Common/config.h"
using namespace std;
using namespace toolkit;
namespace mediakit{
@ -293,5 +294,39 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) {
}
}
static size_t aacPrefixSize(const char *data, size_t bytes) {
uint8_t *ptr = (uint8_t *)data;
size_t prefix = 0;
if (!(bytes > ADTS_HEADER_LEN && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0)) {
return 0;
}
return ADTS_HEADER_LEN;
}
Frame::Ptr Factory::getFrameFromPtr(CodecId codec, const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
switch (codec) {
case CodecH264: return std::make_shared<H264FrameNoCacheAble>((char *)data, bytes, dts, pts, prefixSize(data, bytes));
case CodecH265: return std::make_shared<H265FrameNoCacheAble>((char *)data, bytes, dts, pts, prefixSize(data, bytes));
case CodecAAC: return std::make_shared<FrameFromPtr>(codec, (char *)data, bytes, dts, pts, aacPrefixSize(data, bytes));
case CodecOpus:
case CodecG711A:
case CodecG711U: return std::make_shared<FrameFromPtr>(codec, (char *)data, bytes, dts, pts);
default: return nullptr;
}
}
Frame::Ptr Factory::getFrameFromBuffer(CodecId codec, const Buffer::Ptr &data, uint64_t dts, uint64_t pts) {
switch (codec) {
case CodecH264: return std::make_shared<FrameFromBuffer<H264FrameNoCacheAble>>(data, dts, pts, prefixSize(data->data(), data->size()), 0);
case CodecH265: return std::make_shared<FrameFromBuffer<H265FrameNoCacheAble>>(data, dts, pts, prefixSize(data->data(), data->size()), 0);
case CodecJPEG: return std::make_shared<JPEGFrame>(data, dts);
case CodecAAC: return std::make_shared<FrameFromBuffer<FrameFromPtr>>(data, dts, pts, aacPrefixSize(data->data(), data->size()), 0, codec);
case CodecOpus:
case CodecG711A:
case CodecG711U: return std::make_shared<FrameFromBuffer<FrameFromPtr>>(data, dts, pts, 0, 0, codec);
default: return nullptr;
}
}
}//namespace mediakit

View File

@ -14,6 +14,7 @@
#include <string>
#include "Rtmp/amf.h"
#include "Extension/Track.h"
#include "Extension/Frame.h"
#include "Rtsp/RtpCodec.h"
#include "Rtmp/RtmpCodec.h"
@ -85,6 +86,9 @@ public:
* codecId获取rtmp的codec描述
*/
static AMFValue getAmfByCodecId(CodecId codecId);
static Frame::Ptr getFrameFromPtr(CodecId codec, const char *data, size_t size, uint64_t dts, uint64_t pts);
static Frame::Ptr getFrameFromBuffer(CodecId codec, const toolkit::Buffer::Ptr &data, uint64_t dts, uint64_t pts);
};
}//namespace mediakit

View File

@ -97,6 +97,8 @@ CodecId getCodecByMpegId(int mpeg_id) {
#define XX(name, type, value, str, mpeg_id, mp4_id) case mpeg_id : return name;
CODEC_MAP(XX)
#undef XX
// 海康的 PS 流中会有0xBD 的包
case 0xBD: return CodecInvalid;
default : WarnL << "Unsupported mpeg: " << mpeg_id; return CodecInvalid;
}
}

View File

@ -251,9 +251,9 @@ template <typename Parent>
class FrameInternalBase : public Parent {
public:
using Ptr = std::shared_ptr<FrameInternalBase>;
FrameInternalBase(const Frame::Ptr &parent_frame, char *ptr, size_t size, size_t prefix_size, uint64_t dts, uint64_t pts)
FrameInternalBase(Frame::Ptr parent_frame, char *ptr, size_t size, size_t prefix_size, uint64_t dts, uint64_t pts)
: Parent(ptr, size, dts, pts, prefix_size) {
_parent_frame = parent_frame;
_parent_frame = std::move(parent_frame);
}
bool cacheAble() const override { return _parent_frame->cacheAble(); }

View File

@ -10,7 +10,6 @@
#include "PlayerProxy.h"
#include "Common/config.h"
#include "Extension/AAC.h"
#include "Rtmp/RtmpMediaSource.h"
#include "Rtmp/RtmpPlayer.h"
#include "Rtsp/RtspMediaSource.h"

View File

@ -11,9 +11,6 @@
#ifdef ENABLE_MP4
#include "MP4Demuxer.h"
#include "Util/logger.h"
#include "Extension/H265.h"
#include "Extension/H264.h"
#include "Extension/JPEG.h"
#include "Extension/Factory.h"
using namespace std;
@ -143,8 +140,8 @@ Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int6
Frame::Ptr ret;
auto codec = it->second->getCodecId();
switch (codec) {
case CodecH264 :
case CodecH265 : {
case CodecH264:
case CodecH265: {
auto bytes = buf->size();
auto data = buf->data();
auto offset = 0u;
@ -158,21 +155,12 @@ Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int6
memcpy(data + offset, "\x00\x00\x00\x01", 4);
offset += (frame_len + 4);
}
if (codec == CodecH264) {
ret = std::make_shared<FrameFromBuffer<H264FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
break;
}
ret = std::make_shared<FrameFromBuffer<H265FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
break;
}
case CodecJPEG: {
ret = std::make_shared<JPEGFrame>(buf, (uint64_t)dts, 0, 0);
ret = Factory::getFrameFromBuffer(codec, buf, dts, pts);
break;
}
default: {
ret = std::make_shared<FrameFromBuffer<FrameFromPtr>>(buf, (uint64_t)dts, (uint64_t)pts, 0, 0, codec);
ret = Factory::getFrameFromBuffer(codec, buf, dts, pts);
break;
}
}

View File

@ -11,11 +11,6 @@
#include "Decoder.h"
#include "PSDecoder.h"
#include "TSDecoder.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/AAC.h"
#include "Extension/G711.h"
#include "Extension/Opus.h"
#include "Extension/Factory.h"
#if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
@ -101,72 +96,25 @@ void DecoderImp::onStream(int stream, int codecid, const void *extra, size_t byt
}
}
void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,size_t bytes) {
void DecoderImp::onDecode(int stream, int codecid, int flags, int64_t pts, int64_t dts, const void *data, size_t bytes) {
pts /= 90;
dts /= 90;
switch (codecid) {
case PSI_STREAM_H264: {
if (!_tracks[TrackVideo]) {
onTrack(std::make_shared<H264Track>());
}
auto frame = std::make_shared<H264FrameNoCacheAble>((char *) data, bytes, (uint64_t)dts, (uint64_t)pts, prefixSize((char *) data, bytes));
_merger.inputFrame(frame,[this](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) {
onFrame(std::make_shared<FrameFromBuffer<H264FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0));
});
break;
}
case PSI_STREAM_H265: {
if (!_tracks[TrackVideo]) {
onTrack(std::make_shared<H265Track>());
}
auto frame = std::make_shared<H265FrameNoCacheAble>((char *) data, bytes, (uint64_t)dts, (uint64_t)pts, prefixSize((char *) data, bytes));
_merger.inputFrame(frame,[this](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) {
onFrame(std::make_shared<FrameFromBuffer<H265FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0));
});
break;
}
case PSI_STREAM_MPEG4_AAC :
case PSI_STREAM_AAC: {
uint8_t *ptr = (uint8_t *)data;
if(!(bytes > 7 && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0)){
//这不是aac
break;
}
if (!_tracks[TrackAudio]) {
onTrack(std::make_shared<AACTrack>());
}
onFrame(std::make_shared<FrameFromPtr>(CodecAAC, (char *) data, bytes, (uint64_t)dts, 0, ADTS_HEADER_LEN));
break;
}
case PSI_STREAM_AUDIO_G711A:
case PSI_STREAM_AUDIO_G711U: {
auto codec = codecid == PSI_STREAM_AUDIO_G711A ? CodecG711A : CodecG711U;
if (!_tracks[TrackAudio]) {
//G711传统只支持 8000/1/16的规格FFmpeg貌似做了扩展但是这里不管它了
onTrack(std::make_shared<G711Track>(codec, 8000, 1, 16));
}
onFrame(std::make_shared<FrameFromPtr>(codec, (char *) data, bytes, (uint64_t)dts));
break;
}
case PSI_STREAM_AUDIO_OPUS: {
if (!_tracks[TrackAudio]) {
onTrack(std::make_shared<OpusTrack>());
}
onFrame(std::make_shared<FrameFromPtr>(CodecOpus, (char *) data, bytes, (uint64_t)dts));
break;
}
default:
// 海康的 PS 流中会有 codecid 为 0xBD 的包
if (codecid != 0 && codecid != 0xBD) {
WarnL << "Unsupported codec type:" << codecid;
}
break;
auto codec = getCodecByMpegId(codecid);
if (codec == CodecInvalid) {
return;
}
if (!_tracks[getTrackType(codec)]) {
onTrack(Factory::getTrackByCodecId(codec, 8000, 1, 16));
}
// TODO 支持多track
auto frame = Factory::getFrameFromPtr(codec, (char *) data, bytes, dts, pts);
if (getTrackType(codec) == TrackVideo) {
_merger.inputFrame(frame, [&](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) {
onFrame(Factory::getFrameFromBuffer(codec, buffer, dts, pts));
});
} else {
onFrame(frame);
}
}
#else
@ -175,6 +123,9 @@ void DecoderImp::onStream(int stream,int codecid,const void *extra,size_t bytes,
#endif
void DecoderImp::onTrack(const Track::Ptr &track) {
if (!track) {
return;
}
if (!_tracks[track->getTrackType()]) {
_tracks[track->getTrackType()] = track;
_sink->addTrack(track);
@ -183,7 +134,9 @@ void DecoderImp::onTrack(const Track::Ptr &track) {
}
void DecoderImp::onFrame(const Frame::Ptr &frame) {
_sink->inputFrame(frame);
if (frame) {
_sink->inputFrame(frame);
}
}
}//namespace mediakit