解耦代码

This commit is contained in:
xia-chu 2023-12-09 02:07:43 +08:00
parent fbe159db0e
commit 7d4a930162
13 changed files with 369 additions and 452 deletions

View File

@ -19,7 +19,7 @@
using namespace mediakit;
extern "C" {
#define XX(name, type, value, str, mpeg_id) API_EXPORT const int MK##name = value;
#define XX(name, type, value, str, mpeg_id, mp4_id) API_EXPORT const int MK##name = value;
CODEC_MAP(XX)
#undef XX
}

View File

@ -11,7 +11,6 @@
#include "mk_player.h"
#include "Util/logger.h"
#include "Player/MediaPlayer.h"
#include "Extension/H264.h"
using namespace std;
using namespace toolkit;

View File

@ -115,20 +115,6 @@ bool DevChannel::inputH265(const char *data, int len, uint64_t dts, uint64_t pts
return inputFrame(frame);
}
class FrameAutoDelete : public FrameFromPtr{
public:
template <typename ... ARGS>
FrameAutoDelete(ARGS && ...args) : FrameFromPtr(std::forward<ARGS>(args)...){}
~FrameAutoDelete() override {
delete [] _ptr;
};
bool cacheAble() const override {
return true;
}
};
bool DevChannel::inputAAC(const char *data_without_adts, int len, uint64_t dts, const char *adts_header){
if (dts == 0) {
dts = _aTicker[1].elapsedTime();

View File

@ -201,16 +201,6 @@ vector<Track::Ptr> MediaSink::getTracks(bool ready) const{
return ret;
}
class FrameFromStaticPtr : public FrameFromPtr {
public:
template<typename ... ARGS>
FrameFromStaticPtr(ARGS &&...args) : FrameFromPtr(std::forward<ARGS>(args)...) {};
bool cacheAble() const override {
return true;
}
};
static uint8_t s_mute_adts[] = {0xff, 0xf1, 0x6c, 0x40, 0x2d, 0x3f, 0xfc, 0x00, 0xe0, 0x34, 0x20, 0xad, 0xf2, 0x3f, 0xb5, 0xdd,
0x73, 0xac, 0xbd, 0xca, 0xd7, 0x7d, 0x4a, 0x13, 0x2d, 0x2e, 0xa2, 0x62, 0x02, 0x70, 0x3c, 0x1c,
0xc5, 0x63, 0x55, 0x69, 0x94, 0xb5, 0x8d, 0x70, 0xd7, 0x24, 0x6a, 0x9e, 0x2e, 0x86, 0x24, 0xea,
@ -244,7 +234,7 @@ bool MuteAudioMaker::inputFrame(const Frame::Ptr &frame) {
auto audio_idx = frame->dts() / MUTE_ADTS_DATA_MS;
if (_audio_idx != audio_idx) {
_audio_idx = audio_idx;
auto aacFrame = std::make_shared<FrameFromStaticPtr>(CodecAAC, (char *) MUTE_ADTS_DATA, MUTE_ADTS_DATA_LEN,
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);
return FrameDispatcher::inputFrame(aacFrame);
}

View File

@ -300,7 +300,7 @@ bool AACTrack::inputFrame(const Frame::Ptr &frame) {
if (frame_len == (int)frame->size()) {
return inputFrame_l(frame);
}
auto sub_frame = std::make_shared<FrameTSInternal<FrameFromPtr>>(frame, (char *)ptr, frame_len, ADTS_HEADER_LEN, dts, pts);
auto sub_frame = std::make_shared<FrameInternalBase<FrameFromPtr>>(frame, (char *)ptr, frame_len, ADTS_HEADER_LEN, dts, pts);
ptr += frame_len;
if (ptr > end) {
WarnL << "invalid aac length in adts header: " << frame_len

View File

@ -15,6 +15,14 @@
#include "Common/Stamp.h"
#include "Common/MediaSource.h"
#if defined(ENABLE_MP4)
#include "mov-format.h"
#endif
#if defined(ENABLE_HLS) || defined(ENABLE_RTPPROXY)
#include "mpeg-proto.h"
#endif
using namespace std;
using namespace toolkit;
@ -41,24 +49,71 @@ FrameStamp::FrameStamp(Frame::Ptr frame, Stamp &stamp, int modify_stamp)
TrackType getTrackType(CodecId codecId) {
switch (codecId) {
#define XX(name, type, value, str, mpeg_id) case name : return type;
#define XX(name, type, value, str, mpeg_id, mp4_id) case name : return type;
CODEC_MAP(XX)
#undef XX
default : return TrackInvalid;
}
}
#if defined(ENABLE_MP4)
int getMovIdByCodec(CodecId codecId) {
switch (codecId) {
#define XX(name, type, value, str, mpeg_id, mp4_id) case name : return mp4_id;
CODEC_MAP(XX)
#undef XX
default : return MOV_OBJECT_NONE;
}
}
CodecId getCodecByMovId(int object_id) {
if (object_id == MOV_OBJECT_NONE) {
return CodecInvalid;
}
switch (object_id) {
#define XX(name, type, value, str, mpeg_id, mp4_id) case mp4_id : return name;
CODEC_MAP(XX)
#undef XX
default : WarnL << "Unsupported mov: " << object_id; return CodecInvalid;
}
}
#endif
#if defined(ENABLE_HLS) || defined(ENABLE_RTPPROXY)
int getMpegIdByCodec(CodecId codec) {
switch (codec) {
#define XX(name, type, value, str, mpeg_id, mp4_id) case name : return mpeg_id;
CODEC_MAP(XX)
#undef XX
default : return PSI_STREAM_RESERVED;
}
}
CodecId getCodecByMpegId(int mpeg_id) {
if (mpeg_id == PSI_STREAM_RESERVED) {
return CodecInvalid;
}
switch (mpeg_id) {
#define XX(name, type, value, str, mpeg_id, mp4_id) case mpeg_id : return name;
CODEC_MAP(XX)
#undef XX
default : WarnL << "Unsupported mpeg: " << mpeg_id; return CodecInvalid;
}
}
#endif
const char *getCodecName(CodecId codec) {
switch (codec) {
#define XX(name, type, value, str, mpeg_id) case name : return str;
#define XX(name, type, value, str, mpeg_id, mp4_id) case name : return str;
CODEC_MAP(XX)
#undef XX
default : return "invalid";
}
}
#define XX(name, type, value, str, mpeg_id) {str, name},
static map<string, CodecId, StrCaseCompare> codec_map = {CODEC_MAP(XX)};
#define XX(name, type, value, str, mpeg_id, mp4_id) {str, name},
static map<string, CodecId, StrCaseCompare> codec_map = { CODEC_MAP(XX) };
#undef XX
CodecId getCodecId(const string &str){

View File

@ -20,7 +20,9 @@
#include "Network/Buffer.h"
namespace mediakit {
class Stamp;
typedef enum {
TrackInvalid = -1,
TrackVideo = 0,
@ -31,21 +33,21 @@ typedef enum {
} TrackType;
#define CODEC_MAP(XX) \
XX(CodecH264, TrackVideo, 0, "H264", PSI_STREAM_H264) \
XX(CodecH265, TrackVideo, 1, "H265", PSI_STREAM_H265) \
XX(CodecAAC, TrackAudio, 2, "mpeg4-generic", PSI_STREAM_AAC) \
XX(CodecG711A, TrackAudio, 3, "PCMA", PSI_STREAM_AUDIO_G711A) \
XX(CodecG711U, TrackAudio, 4, "PCMU", PSI_STREAM_AUDIO_G711U) \
XX(CodecOpus, TrackAudio, 5, "opus", PSI_STREAM_AUDIO_OPUS) \
XX(CodecL16, TrackAudio, 6, "L16", PSI_STREAM_RESERVED) \
XX(CodecVP8, TrackVideo, 7, "VP8", PSI_STREAM_VP8) \
XX(CodecVP9, TrackVideo, 8, "VP9", PSI_STREAM_VP9) \
XX(CodecAV1, TrackVideo, 9, "AV1", PSI_STREAM_AV1) \
XX(CodecJPEG, TrackVideo, 10, "JPEG", PSI_STREAM_RESERVED)
XX(CodecH264, TrackVideo, 0, "H264", PSI_STREAM_H264, MOV_OBJECT_H264) \
XX(CodecH265, TrackVideo, 1, "H265", PSI_STREAM_H265, MOV_OBJECT_HEVC) \
XX(CodecAAC, TrackAudio, 2, "mpeg4-generic", PSI_STREAM_AAC, MOV_OBJECT_AAC) \
XX(CodecG711A, TrackAudio, 3, "PCMA", PSI_STREAM_AUDIO_G711A, MOV_OBJECT_G711a) \
XX(CodecG711U, TrackAudio, 4, "PCMU", PSI_STREAM_AUDIO_G711U, MOV_OBJECT_G711u) \
XX(CodecOpus, TrackAudio, 5, "opus", PSI_STREAM_AUDIO_OPUS, MOV_OBJECT_OPUS) \
XX(CodecL16, TrackAudio, 6, "L16", PSI_STREAM_RESERVED, MOV_OBJECT_NONE) \
XX(CodecVP8, TrackVideo, 7, "VP8", PSI_STREAM_VP8, MOV_OBJECT_VP8) \
XX(CodecVP9, TrackVideo, 8, "VP9", PSI_STREAM_VP9, MOV_OBJECT_VP9) \
XX(CodecAV1, TrackVideo, 9, "AV1", PSI_STREAM_AV1, MOV_OBJECT_AV1) \
XX(CodecJPEG, TrackVideo, 10, "JPEG", PSI_STREAM_JPEG_2000, MOV_OBJECT_JPEG)
typedef enum {
CodecInvalid = -1,
#define XX(name, type, value, str, mpeg_id) name = value,
#define XX(name, type, value, str, mpeg_id, mp4_id) name = value,
CODEC_MAP(XX)
#undef XX
CodecMax
@ -78,6 +80,26 @@ const char *getCodecName(CodecId codecId);
*/
TrackType getTrackType(CodecId codecId);
/**
* codecid获取mov object id
*/
int getMovIdByCodec(CodecId codecId);
/**
* mov object id获取CodecId
*/
CodecId getCodecByMovId(int object_id);
/**
* codecid获取mpeg id
*/
int getMpegIdByCodec(CodecId codec);
/**
* mpeg id获取CodecId
*/
CodecId getCodecByMpegId(int mpeg_id);
/**
*
*/
@ -220,17 +242,17 @@ protected:
};
/**
* Frame类中可以有多个帧 0x 00 00 01
* Frame类中可以有多个帧(AAC)
* ZLMediaKit会先把这种复合帧split成单个帧然后再处理
* Frame
*
*/
template <typename Parent>
class FrameInternal : public Parent {
class FrameInternalBase : public Parent {
public:
using Ptr = std::shared_ptr<FrameInternal>;
FrameInternal(const Frame::Ptr &parent_frame, char *ptr, size_t size, size_t prefix_size)
: Parent(ptr, size, parent_frame->dts(), parent_frame->pts(), prefix_size) {
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)
: Parent(ptr, size, dts, pts, prefix_size) {
_parent_frame = parent_frame;
}
bool cacheAble() const override { return _parent_frame->cacheAble(); }
@ -240,24 +262,233 @@ private:
};
/**
* Frame类中可以有多个帧(AAC)
* Frame类中可以有多个帧 0x 00 00 01
* ZLMediaKit会先把这种复合帧split成单个帧然后再处理
* Frame
*
*/
template <typename Parent>
class FrameTSInternal : public Parent {
class FrameInternal : public FrameInternalBase<Parent> {
public:
using Ptr = std::shared_ptr<FrameTSInternal>;
FrameTSInternal(
const 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;
using Ptr = std::shared_ptr<FrameInternal>;
FrameInternal(const Frame::Ptr &parent_frame, char *ptr, size_t size, size_t prefix_size)
: FrameInternalBase<Parent>(parent_frame, ptr, size, prefix_size, parent_frame->dts(), parent_frame->pts()) {}
};
// 包装一个指针成不可缓存的frame
class FrameFromPtr : public Frame {
public:
using Ptr = std::shared_ptr<FrameFromPtr>;
FrameFromPtr(CodecId codec_id, char *ptr, size_t size, uint64_t dts, uint64_t pts = 0, size_t prefix_size = 0, bool is_key = false)
: FrameFromPtr(ptr, size, dts, pts, prefix_size, is_key) {
_codec_id = codec_id;
}
bool cacheAble() const override { return _parent_frame->cacheAble(); }
FrameFromPtr(char *ptr, size_t size, uint64_t dts, uint64_t pts = 0, size_t prefix_size = 0, bool is_key = false) {
_ptr = ptr;
_size = size;
_dts = dts;
_pts = pts;
_prefix_size = prefix_size;
_is_key = is_key;
}
char *data() const override { return _ptr; }
size_t size() const override { return _size; }
uint64_t dts() const override { return _dts; }
uint64_t pts() const override { return _pts ? _pts : dts(); }
size_t prefixSize() const override { return _prefix_size; }
bool cacheAble() const override { return false; }
bool keyFrame() const override { return _is_key; }
bool configFrame() const override { return false; }
void setCodecId(CodecId codec_id) { _codec_id = codec_id; }
CodecId getCodecId() const override {
if (_codec_id == CodecInvalid) {
throw std::invalid_argument("Invalid codec type of FrameFromPtr");
}
return _codec_id;
}
protected:
FrameFromPtr() = default;
protected:
bool _is_key;
char *_ptr;
uint64_t _dts;
uint64_t _pts = 0;
size_t _size;
size_t _prefix_size;
CodecId _codec_id = CodecInvalid;
};
// 管理一个指针生命周期并生产一个frame
class FrameAutoDelete : public FrameFromPtr {
public:
template <typename... ARGS>
FrameAutoDelete(ARGS &&...args) : FrameFromPtr(std::forward<ARGS>(args)...) {}
~FrameAutoDelete() override { delete[] _ptr; };
bool cacheAble() const override { return true; }
};
// 把一个不可缓存的frame声明为可缓存的
template <typename Parent>
class FrameToCache : public Parent {
public:
template<typename ... ARGS>
FrameToCache(ARGS &&...args) : Parent(std::forward<ARGS>(args)...) {};
bool cacheAble() const override {
return true;
}
};
// 该对象的功能是把一个不可缓存的帧转换成可缓存的帧
class FrameCacheAble : public FrameFromPtr {
public:
using Ptr = std::shared_ptr<FrameCacheAble>;
FrameCacheAble(const Frame::Ptr &frame, bool force_key_frame = false) {
if (frame->cacheAble()) {
_frame = frame;
_ptr = frame->data();
} else {
_buffer = FrameImp::create();
_buffer->_buffer.assign(frame->data(), frame->size());
_ptr = _buffer->data();
}
_size = frame->size();
_dts = frame->dts();
_pts = frame->pts();
_prefix_size = frame->prefixSize();
_codec_id = frame->getCodecId();
_key = force_key_frame ? true : frame->keyFrame();
_config = frame->configFrame();
_drop_able = frame->dropAble();
_decode_able = frame->decodeAble();
}
/**
*
*/
bool cacheAble() const override { return true; }
bool keyFrame() const override { return _key; }
bool configFrame() const override { return _config; }
bool dropAble() const override { return _drop_able; }
bool decodeAble() const override { return _decode_able; }
private:
Frame::Ptr _parent_frame;
bool _key;
bool _config;
bool _drop_able;
bool _decode_able;
Frame::Ptr _frame;
FrameImp::Ptr _buffer;
};
//该类实现frame级别的时间戳覆盖
class FrameStamp : public Frame {
public:
using Ptr = std::shared_ptr<FrameStamp>;
FrameStamp(Frame::Ptr frame, Stamp &stamp, int modify_stamp);
~FrameStamp() override {}
uint64_t dts() const override { return (uint64_t)_dts; }
uint64_t pts() const override { return (uint64_t)_pts; }
size_t prefixSize() const override { return _frame->prefixSize(); }
bool keyFrame() const override { return _frame->keyFrame(); }
bool configFrame() const override { return _frame->configFrame(); }
bool cacheAble() const override { return _frame->cacheAble(); }
bool dropAble() const override { return _frame->dropAble(); }
bool decodeAble() const override { return _frame->decodeAble(); }
char *data() const override { return _frame->data(); }
size_t size() const override { return _frame->size(); }
CodecId getCodecId() const override { return _frame->getCodecId(); }
private:
int64_t _dts;
int64_t _pts;
Frame::Ptr _frame;
};
/**
* Buffer对象转换成可缓存的Frame对象
*/
template <typename Parent>
class FrameFromBuffer : public Parent {
public:
/**
* frame
* @param buf
* @param dts
* @param pts
* @param prefix
* @param offset buffer有效数据偏移量
*/
FrameFromBuffer(toolkit::Buffer::Ptr buf, uint64_t dts, uint64_t pts, size_t prefix, size_t offset)
: Parent(buf->data() + offset, buf->size() - offset, dts, pts, prefix) {
_buf = std::move(buf);
}
/**
* frame
* @param buf
* @param dts
* @param pts
* @param prefix
* @param offset buffer有效数据偏移量
* @param codec
*/
FrameFromBuffer(toolkit::Buffer::Ptr buf, uint64_t dts, uint64_t pts, size_t prefix, size_t offset, CodecId codec)
: Parent(codec, buf->data() + offset, buf->size() - offset, dts, pts, prefix) {
_buf = std::move(buf);
}
/**
*
*/
bool cacheAble() const override { return true; }
private:
toolkit::Buffer::Ptr _buf;
};
/**
* frame
*/
class FrameMerger {
public:
using onOutput = std::function<void(uint64_t dts, uint64_t pts, const toolkit::Buffer::Ptr &buffer, bool have_key_frame)>;
using Ptr = std::shared_ptr<FrameMerger>;
enum {
none = 0,
h264_prefix,
mp4_nal_size,
};
FrameMerger(int type);
/**
* FrameMerger::inputFrame传入的onOutput回调
*
*/
void flush();
void clear();
bool inputFrame(const Frame::Ptr &frame, onOutput cb, toolkit::BufferLikeString *buffer = nullptr);
private:
bool willFlush(const Frame::Ptr &frame) const;
void doMerge(toolkit::BufferLikeString &buffer, const Frame::Ptr &frame) const;
private:
int _type;
bool _have_decode_able_frame = false;
onOutput _cb;
toolkit::List<Frame::Ptr> _frame_cache;
};
/**
@ -393,202 +624,5 @@ private:
std::map<void *, FrameWriterInterface::Ptr> _delegates;
};
/**
* Frame接口包装指针便使ZLMediaKit
*/
class FrameFromPtr : public Frame {
public:
using Ptr = std::shared_ptr<FrameFromPtr>;
FrameFromPtr(CodecId codec_id, char *ptr, size_t size, uint64_t dts, uint64_t pts = 0, size_t prefix_size = 0, bool is_key = false)
: FrameFromPtr(ptr, size, dts, pts, prefix_size,is_key) {
_codec_id = codec_id;
}
FrameFromPtr(char *ptr, size_t size, uint64_t dts, uint64_t pts = 0, size_t prefix_size = 0, bool is_key = false) {
_ptr = ptr;
_size = size;
_dts = dts;
_pts = pts;
_prefix_size = prefix_size;
_is_key = is_key;
}
char *data() const override { return _ptr; }
size_t size() const override { return _size; }
uint64_t dts() const override { return _dts; }
uint64_t pts() const override { return _pts ? _pts : dts(); }
size_t prefixSize() const override { return _prefix_size; }
bool cacheAble() const override { return false; }
bool keyFrame() const override { return _is_key; }
bool configFrame() const override { return false; }
void setCodecId(CodecId codec_id) { _codec_id = codec_id; }
CodecId getCodecId() const override {
if (_codec_id == CodecInvalid) {
throw std::invalid_argument("FrameFromPtr对象未设置codec类型");
}
return _codec_id;
}
protected:
FrameFromPtr() = default;
protected:
bool _is_key;
char *_ptr;
uint64_t _dts;
uint64_t _pts = 0;
size_t _size;
size_t _prefix_size;
CodecId _codec_id = CodecInvalid;
};
/**
*
*/
class FrameCacheAble : public FrameFromPtr {
public:
using Ptr = std::shared_ptr<FrameCacheAble>;
FrameCacheAble(const Frame::Ptr &frame, bool force_key_frame = false) {
if (frame->cacheAble()) {
_frame = frame;
_ptr = frame->data();
} else {
_buffer = FrameImp::create();
_buffer->_buffer.assign(frame->data(), frame->size());
_ptr = _buffer->data();
}
_size = frame->size();
_dts = frame->dts();
_pts = frame->pts();
_prefix_size = frame->prefixSize();
_codec_id = frame->getCodecId();
_key = force_key_frame ? true : frame->keyFrame();
_config = frame->configFrame();
_drop_able = frame->dropAble();
_decode_able = frame->decodeAble();
}
/**
*
*/
bool cacheAble() const override { return true; }
bool keyFrame() const override { return _key; }
bool configFrame() const override { return _config; }
bool dropAble() const override { return _drop_able; }
bool decodeAble() const override { return _decode_able; }
private:
bool _key;
bool _config;
bool _drop_able;
bool _decode_able;
Frame::Ptr _frame;
FrameImp::Ptr _buffer;
};
//该类实现frame级别的时间戳覆盖
class FrameStamp : public Frame {
public:
using Ptr = std::shared_ptr<FrameStamp>;
FrameStamp(Frame::Ptr frame, Stamp &stamp, int modify_stamp);
~FrameStamp() override {}
uint64_t dts() const override { return (uint64_t)_dts; }
uint64_t pts() const override { return (uint64_t)_pts; }
size_t prefixSize() const override { return _frame->prefixSize(); }
bool keyFrame() const override { return _frame->keyFrame(); }
bool configFrame() const override { return _frame->configFrame(); }
bool cacheAble() const override { return _frame->cacheAble(); }
bool dropAble() const override { return _frame->dropAble(); }
bool decodeAble() const override { return _frame->decodeAble(); }
char *data() const override { return _frame->data(); }
size_t size() const override { return _frame->size(); }
CodecId getCodecId() const override { return _frame->getCodecId(); }
private:
int64_t _dts;
int64_t _pts;
Frame::Ptr _frame;
};
/**
* Buffer对象转换成可缓存的Frame对象
*/
template <typename Parent>
class FrameWrapper : public Parent {
public:
/**
* frame
* @param buf
* @param dts
* @param pts
* @param prefix
* @param offset buffer有效数据偏移量
*/
FrameWrapper(toolkit::Buffer::Ptr buf, uint64_t dts, uint64_t pts, size_t prefix, size_t offset)
: Parent(buf->data() + offset, buf->size() - offset, dts, pts, prefix) {
_buf = std::move(buf);
}
/**
* frame
* @param buf
* @param dts
* @param pts
* @param prefix
* @param offset buffer有效数据偏移量
* @param codec
*/
FrameWrapper(toolkit::Buffer::Ptr buf, uint64_t dts, uint64_t pts, size_t prefix, size_t offset, CodecId codec)
: Parent(codec, buf->data() + offset, buf->size() - offset, dts, pts, prefix) {
_buf = std::move(buf);
}
/**
*
*/
bool cacheAble() const override { return true; }
private:
toolkit::Buffer::Ptr _buf;
};
/**
* frame
*/
class FrameMerger {
public:
using onOutput = std::function<void(uint64_t dts, uint64_t pts, const toolkit::Buffer::Ptr &buffer, bool have_key_frame)>;
using Ptr = std::shared_ptr<FrameMerger>;
enum {
none = 0,
h264_prefix,
mp4_nal_size,
};
FrameMerger(int type);
/**
* FrameMerger::inputFrame传入的onOutput回调
*
*/
void flush();
void clear();
bool inputFrame(const Frame::Ptr &frame, onOutput cb, toolkit::BufferLikeString *buffer = nullptr);
private:
bool willFlush(const Frame::Ptr &frame) const;
void doMerge(toolkit::BufferLikeString &buffer, const Frame::Ptr &frame) const;
private:
int _type;
bool _have_decode_able_frame = false;
onOutput _cb;
toolkit::List<Frame::Ptr> _frame_cache;
};
} // namespace mediakit
#endif // ZLMEDIAKIT_FRAME_H

View File

@ -13,10 +13,8 @@
#include "Util/logger.h"
#include "Extension/H265.h"
#include "Extension/H264.h"
#include "Extension/AAC.h"
#include "Extension/G711.h"
#include "Extension/Opus.h"
#include "Extension/JPEG.h"
#include "Extension/Factory.h"
using namespace std;
using namespace toolkit;
@ -61,85 +59,21 @@ int MP4Demuxer::getAllTracks() {
return mov_reader_getinfo(_mov_reader.get(),&s_on_track,this);
}
#define SWITCH_CASE(obj_id) case obj_id : return #obj_id
static const char *getObjectName(int obj_id) {
switch (obj_id) {
SWITCH_CASE(MOV_OBJECT_TEXT);
SWITCH_CASE(MOV_OBJECT_MP4V);
SWITCH_CASE(MOV_OBJECT_H264);
SWITCH_CASE(MOV_OBJECT_HEVC);
SWITCH_CASE(MOV_OBJECT_AAC);
SWITCH_CASE(MOV_OBJECT_MP2V);
SWITCH_CASE(MOV_OBJECT_AAC_MAIN);
SWITCH_CASE(MOV_OBJECT_AAC_LOW);
SWITCH_CASE(MOV_OBJECT_AAC_SSR);
SWITCH_CASE(MOV_OBJECT_MP3);
SWITCH_CASE(MOV_OBJECT_MP1V);
SWITCH_CASE(MOV_OBJECT_MP1A);
SWITCH_CASE(MOV_OBJECT_JPEG);
SWITCH_CASE(MOV_OBJECT_PNG);
SWITCH_CASE(MOV_OBJECT_JPEG2000);
SWITCH_CASE(MOV_OBJECT_G719);
SWITCH_CASE(MOV_OBJECT_OPUS);
SWITCH_CASE(MOV_OBJECT_G711a);
SWITCH_CASE(MOV_OBJECT_G711u);
SWITCH_CASE(MOV_OBJECT_AV1);
default: return "unknown mp4 object";
}
}
void MP4Demuxer::onVideoTrack(uint32_t track, uint8_t object, int width, int height, const void *extra, size_t bytes) {
Track::Ptr video;
switch (object) {
case MOV_OBJECT_H264: {
video = std::make_shared<H264Track>();
_track_to_codec.emplace(track, video);
break;
}
case MOV_OBJECT_HEVC: {
video = std::make_shared<H265Track>();
_track_to_codec.emplace(track, video);
break;
}
case MOV_OBJECT_JPEG: {
video = std::make_shared<JPEGTrack>();
_track_to_codec.emplace(track, video);
break;
}
default: WarnL << "不支持该编码类型的MP4,已忽略:" << getObjectName(object); break;
auto video = Factory::getTrackByCodecId(getCodecByMovId(object));
if (!video) {
return;
}
_track_to_codec.emplace(track, video);
if (extra && bytes) {
video->setExtraData((uint8_t *)extra, bytes);
}
}
void MP4Demuxer::onAudioTrack(uint32_t track_id, uint8_t object, int channel_count, int bit_per_sample, int sample_rate, const void *extra, size_t bytes) {
Track::Ptr audio;
switch(object){
case MOV_OBJECT_AAC:{
audio = std::make_shared<AACTrack>();
_track_to_codec.emplace(track_id, audio);
break;
}
case MOV_OBJECT_G711a:
case MOV_OBJECT_G711u:{
audio = std::make_shared<G711Track>(object == MOV_OBJECT_G711a ? CodecG711A : CodecG711U, sample_rate, channel_count, bit_per_sample / channel_count );
_track_to_codec.emplace(track_id, audio);
break;
}
case MOV_OBJECT_OPUS: {
audio = std::make_shared<OpusTrack>();
_track_to_codec.emplace(track_id, audio);
break;
}
default: WarnL << "不支持该编码类型的MP4,已忽略:" << getObjectName(object); break;
auto audio = Factory::getTrackByCodecId(getCodecByMovId(object), sample_rate, channel_count, bit_per_sample / channel_count);
if (!audio) {
return;
}
if (extra && bytes) {
audio->setExtraData((uint8_t *)extra, bytes);
@ -225,10 +159,10 @@ Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int6
offset += (frame_len + 4);
}
if (codec == CodecH264) {
ret = std::make_shared<FrameWrapper<H264FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
ret = std::make_shared<FrameFromBuffer<H264FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
break;
}
ret = std::make_shared<FrameWrapper<H265FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
ret = std::make_shared<FrameFromBuffer<H265FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
break;
}
@ -238,7 +172,7 @@ Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int6
}
default: {
ret = std::make_shared<FrameWrapper<FrameFromPtr>>(buf, (uint64_t)dts, (uint64_t)pts, 0, 0, codec);
ret = std::make_shared<FrameFromBuffer<FrameFromPtr>>(buf, (uint64_t)dts, (uint64_t)pts, 0, 0, codec);
break;
}
}

View File

@ -133,21 +133,6 @@ bool MP4MuxerInterface::inputFrame(const Frame::Ptr &frame) {
return true;
}
static uint8_t getObject(CodecId codecId) {
switch (codecId){
case CodecG711A : return MOV_OBJECT_G711a;
case CodecG711U : return MOV_OBJECT_G711u;
case CodecOpus : return MOV_OBJECT_OPUS;
case CodecAAC : return MOV_OBJECT_AAC;
case CodecH264 : return MOV_OBJECT_H264;
case CodecH265 : return MOV_OBJECT_HEVC;
case CodecJPEG : return MOV_OBJECT_JPEG;
case CodecVP9: return MOV_OBJECT_VP9;
case CodecAV1: return MOV_OBJECT_AV1;
default : return 0;
}
}
void MP4MuxerInterface::stampSync() {
if (_codec_to_trackid.size() < 2) {
return;
@ -172,14 +157,14 @@ bool MP4MuxerInterface::addTrack(const Track::Ptr &track) {
if (!_mov_writter) {
_mov_writter = createWriter();
}
auto mp4_object = getObject(track->getCodecId());
if (!mp4_object) {
WarnL << "MP4录制不支持该编码格式:" << track->getCodecName();
auto mp4_object = getMovIdByCodec(track->getCodecId());
if (mp4_object == MOV_OBJECT_NONE) {
WarnL << "Unsupported codec: " << track->getCodecName();
return false;
}
if (!track->ready()) {
WarnL << "Track[" << track->getCodecName() << "]未就绪";
WarnL << "Track[" << track->getCodecName() << "] unready";
return false;
}

View File

@ -30,26 +30,22 @@ MpegMuxer::~MpegMuxer() {
releaseContext();
}
#define XX(name, type, value, str, mpeg_id) \
case name: { \
if (mpeg_id == PSI_STREAM_RESERVED) { \
break; \
} \
if (track->getTrackType() == TrackVideo) { \
_have_video = true; \
} \
_codec_to_trackid[track->getCodecId()] = mpeg_muxer_add_stream((::mpeg_muxer_t *)_context, mpeg_id, nullptr, 0); \
return true; \
}
bool MpegMuxer::addTrack(const Track::Ptr &track) {
switch (track->getCodecId()) {
CODEC_MAP(XX)
default: break;
auto mpeg_id = getMpegIdByCodec(track->getCodecId());
if (mpeg_id == PSI_STREAM_RESERVED) {
WarnL << "Unsupported codec: " << track->getCodecName();
return false;
}
WarnL << "不支持该编码格式,已忽略:" << track->getCodecName();
return false;
if (track->getTrackType() == TrackVideo) {
_have_video = true;
}
auto extra_data = track->getExtraData();
_codec_to_trackid[track->getCodecId()] = mpeg_muxer_add_stream((::mpeg_muxer_t *)_context, mpeg_id,
extra_data ? extra_data->data() : nullptr,
extra_data ? extra_data->size(): 0);
return true;
}
#undef XX
bool MpegMuxer::inputFrame(const Frame::Ptr &frame) {
auto it = _codec_to_trackid.find(frame->getCodecId());

View File

@ -16,6 +16,7 @@
#include "Extension/AAC.h"
#include "Extension/G711.h"
#include "Extension/Opus.h"
#include "Extension/Factory.h"
#if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
#include "mpeg-ts.h"
@ -85,78 +86,18 @@ DecoderImp::DecoderImp(const Decoder::Ptr &decoder, MediaSinkInterface *sink){
}
#if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
#define SWITCH_CASE(codec_id) case codec_id : return #codec_id
static const char *getCodecName(int codec_id) {
switch (codec_id) {
SWITCH_CASE(PSI_STREAM_MPEG1);
SWITCH_CASE(PSI_STREAM_MPEG2);
SWITCH_CASE(PSI_STREAM_AUDIO_MPEG1);
SWITCH_CASE(PSI_STREAM_MP3);
SWITCH_CASE(PSI_STREAM_AAC);
SWITCH_CASE(PSI_STREAM_MPEG4);
SWITCH_CASE(PSI_STREAM_MPEG4_AAC_LATM);
SWITCH_CASE(PSI_STREAM_H264);
SWITCH_CASE(PSI_STREAM_MPEG4_AAC);
SWITCH_CASE(PSI_STREAM_H265);
SWITCH_CASE(PSI_STREAM_AUDIO_AC3);
SWITCH_CASE(PSI_STREAM_AUDIO_EAC3);
SWITCH_CASE(PSI_STREAM_AUDIO_DTS);
SWITCH_CASE(PSI_STREAM_VIDEO_DIRAC);
SWITCH_CASE(PSI_STREAM_VIDEO_VC1);
SWITCH_CASE(PSI_STREAM_VIDEO_SVAC);
SWITCH_CASE(PSI_STREAM_AUDIO_SVAC);
SWITCH_CASE(PSI_STREAM_AUDIO_G711A);
SWITCH_CASE(PSI_STREAM_AUDIO_G711U);
SWITCH_CASE(PSI_STREAM_AUDIO_G722);
SWITCH_CASE(PSI_STREAM_AUDIO_G723);
SWITCH_CASE(PSI_STREAM_AUDIO_G729);
SWITCH_CASE(PSI_STREAM_AUDIO_OPUS);
default : return "unknown codec";
void DecoderImp::onStream(int stream, int codecid, const void *extra, size_t bytes, int finish) {
// G711传统只支持 8000/1/16的规格FFmpeg貌似做了扩展但是这里不管它了
auto track = Factory::getTrackByCodecId(getCodecByMpegId(codecid), 8000, 1, 16);
if (!track) {
return;
}
}
void DecoderImp::onStream(int stream, int codecid, const void *extra, size_t bytes, int finish){
switch (codecid) {
case PSI_STREAM_H264: {
onTrack(std::make_shared<H264Track>());
break;
}
case PSI_STREAM_H265: {
onTrack(std::make_shared<H265Track>());
break;
}
case PSI_STREAM_MPEG4_AAC :
case PSI_STREAM_AAC: {
onTrack(std::make_shared<AACTrack>());
break;
}
case PSI_STREAM_AUDIO_G711A:
case PSI_STREAM_AUDIO_G711U: {
auto codec = codecid == PSI_STREAM_AUDIO_G711A ? CodecG711A : CodecG711U;
//G711传统只支持 8000/1/16的规格FFmpeg貌似做了扩展但是这里不管它了
onTrack(std::make_shared<G711Track>(codec, 8000, 1, 16));
break;
}
case PSI_STREAM_AUDIO_OPUS: {
onTrack(std::make_shared<OpusTrack>());
break;
}
default:
if(codecid != 0){
WarnL<< "unsupported codec type:" << getCodecName(codecid) << " " << (int)codecid;
}
break;
}
//防止未获取视频track提前complete导致忽略后续视频的问题用于兼容一些不太规范的ps流
if (finish && _tracks[TrackVideo] ) {
onTrack(std::move(track));
// 防止未获取视频track提前complete导致忽略后续视频的问题用于兼容一些不太规范的ps流
if (finish && _tracks[TrackVideo]) {
_sink->addTrackCompleted();
InfoL << "add track finished";
InfoL << "Add track finished";
}
}
@ -171,7 +112,7 @@ void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t d
}
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<FrameWrapper<H264FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0));
onFrame(std::make_shared<FrameFromBuffer<H264FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0));
});
break;
}
@ -182,7 +123,7 @@ void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t d
}
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<FrameWrapper<H265FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0));
onFrame(std::make_shared<FrameFromBuffer<H265FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0));
});
break;
}
@ -223,7 +164,7 @@ void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t d
default:
// 海康的 PS 流中会有 codecid 为 0xBD 的包
if (codecid != 0 && codecid != 0xBD) {
WarnL << "unsupported codec type:" << getCodecName(codecid) << " " << (int) codecid;
WarnL << "Unsupported codec type:" << codecid;
}
break;
}

View File

@ -12,11 +12,6 @@
#include "GB28181Process.h"
#include "Extension/CommonRtp.h"
#include "Extension/Factory.h"
#include "Extension/G711.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/Opus.h"
#include "Extension/JPEG.h"
#include "Http/HttpTSPlayer.h"
#include "Util/File.h"
#include "Common/config.h"
@ -90,7 +85,8 @@ bool GB28181Process::inputRtp(bool, const char *data, size_t data_len) {
case Rtsp::PT_PCMU: {
// CodecG711U or CodecG711A
ref = std::make_shared<RtpReceiverImp>(8000, [this](RtpPacket::Ptr rtp) { onRtpSorted(std::move(rtp)); });
auto track = std::make_shared<G711Track>(pt == Rtsp::PT_PCMU ? CodecG711U : CodecG711A, 8000, 1, 16);
auto track = Factory::getTrackByCodecId(pt == Rtsp::PT_PCMU ? CodecG711U : CodecG711A, 8000, 1, 16);
CHECK(track);
_interface->addTrack(track);
_rtp_decoder[pt] = Factory::getRtpDecoderByTrack(track);
break;
@ -98,7 +94,8 @@ bool GB28181Process::inputRtp(bool, const char *data, size_t data_len) {
case Rtsp::PT_JPEG: {
// mjpeg
ref = std::make_shared<RtpReceiverImp>(90000, [this](RtpPacket::Ptr rtp) { onRtpSorted(std::move(rtp)); });
auto track = std::make_shared<JPEGTrack>();
auto track = Factory::getTrackByCodecId(CodecJPEG);
CHECK(track);
_interface->addTrack(track);
_rtp_decoder[pt] = Factory::getRtpDecoderByTrack(track);
break;
@ -107,19 +104,20 @@ bool GB28181Process::inputRtp(bool, const char *data, size_t data_len) {
if (pt == opus_pt) {
// opus负载
ref = std::make_shared<RtpReceiverImp>(48000, [this](RtpPacket::Ptr rtp) { onRtpSorted(std::move(rtp)); });
auto track = std::make_shared<OpusTrack>();
auto track = Factory::getTrackByCodecId(CodecOpus);
CHECK(track);
_interface->addTrack(track);
_rtp_decoder[pt] = Factory::getRtpDecoderByTrack(track);
} else if (pt == h265_pt) {
// H265负载
ref = std::make_shared<RtpReceiverImp>(90000, [this](RtpPacket::Ptr rtp) { onRtpSorted(std::move(rtp)); });
auto track = std::make_shared<H265Track>();
auto track = Factory::getTrackByCodecId(CodecH265);
_interface->addTrack(track);
_rtp_decoder[pt] = Factory::getRtpDecoderByTrack(track);
} else if (pt == h264_pt) {
// H264负载
ref = std::make_shared<RtpReceiverImp>(90000, [this](RtpPacket::Ptr rtp) { onRtpSorted(std::move(rtp)); });
auto track = std::make_shared<H264Track>();
auto track = Factory::getTrackByCodecId(CodecH264);
_interface->addTrack(track);
_rtp_decoder[pt] = Factory::getRtpDecoderByTrack(track);
} else {

View File

@ -12,7 +12,6 @@
#include "PSEncoder.h"
#include "Common/config.h"
#include "Extension/H264.h"
#include "Extension/CommonRtp.h"
#include "Rtsp/RtspMuxer.h"