From 198f223d630edf372d81e7affbd23be025c756be Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sun, 17 May 2020 18:00:23 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9B=E4=B8=80=E6=AD=A5=E6=8A=BD=E8=B1=A1ts?= =?UTF-8?q?/ps=E8=A7=A3=E6=9E=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtp/Decoder.cpp | 197 +++++++++++++++++++++++++++++++++++++++-- src/Rtp/Decoder.h | 51 +++++++++-- src/Rtp/RtpProcess.cpp | 187 ++++---------------------------------- src/Rtp/RtpProcess.h | 12 ++- src/Rtp/TSDecoder.cpp | 32 +++---- src/Rtp/TSDecoder.h | 12 ++- 6 files changed, 283 insertions(+), 208 deletions(-) diff --git a/src/Rtp/Decoder.cpp b/src/Rtp/Decoder.cpp index e37fec10..2e3349dd 100644 --- a/src/Rtp/Decoder.cpp +++ b/src/Rtp/Decoder.cpp @@ -8,18 +8,203 @@ * may be found in the AUTHORS file in the root of the source tree. */ -#if defined(ENABLE_RTPPROXY) #include "Decoder.h" #include "PSDecoder.h" #include "TSDecoder.h" +#include "mpeg-ts-proto.h" +#include "Extension/H264.h" +#include "Extension/H265.h" +#include "Extension/AAC.h" +#include "Extension/G711.h" + namespace mediakit { -Decoder::Ptr Decoder::createDecoder(Decoder::Type type) { +static Decoder::Ptr createDecoder_l(DecoderImp::Type type) { switch (type){ - case decoder_ps : return std::make_shared(); - case decoder_ts : return std::make_shared(); - default : return nullptr; + case DecoderImp::decoder_ps: +#ifdef ENABLE_RTPPROXY + return std::make_shared(); +#else + WarnL << "创建ps解复用器失败,请打开ENABLE_RTPPROXY然后重新编译"; + return nullptr; +#endif//ENABLE_RTPPROXY + + case DecoderImp::decoder_ts: +#ifdef ENABLE_HLS + return std::make_shared(); +#else + WarnL << "创建mpegts解复用器失败,请打开ENABLE_HLS然后重新编译"; + return nullptr; +#endif//ENABLE_HLS + + default: return nullptr; } } +///////////////////////////////////////////////////////////// + +DecoderImp::Ptr DecoderImp::createDecoder(Type type, const MediaSinkInterface::Ptr &sink){ + auto decoder = createDecoder_l(type); + if(!decoder){ + return nullptr; + } + return DecoderImp::Ptr(new DecoderImp(decoder, sink)); +} + +int DecoderImp::input(const uint8_t *data, int bytes){ + return _decoder->input(data, bytes); +} + +DecoderImp::DecoderImp(const Decoder::Ptr &decoder,const MediaSinkInterface::Ptr &sink){ + _decoder = decoder; + _sink = sink; + _decoder->setOnDecode([this](int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,int bytes){ + onDecode(stream,codecid,flags,pts,dts,data,bytes); + }); +} + +#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); + default : return "unknown codec"; + } +} + +void FrameMerger::inputFrame(const Frame::Ptr &frame,const function &cb){ + if (!_frameCached.empty() && _frameCached.back()->dts() != frame->dts()) { + Frame::Ptr back = _frameCached.back(); + Buffer::Ptr merged_frame = back; + if(_frameCached.size() != 1){ + string merged; + _frameCached.for_each([&](const Frame::Ptr &frame){ + merged.append(frame->data(),frame->size()); + }); + merged_frame = std::make_shared(std::move(merged)); + } + cb(back->dts(),back->pts(),merged_frame); + _frameCached.clear(); + } + _frameCached.emplace_back(Frame::getCacheAbleFrame(frame)); +} + +void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,int bytes) { + pts /= 90; + dts /= 90; + + switch (codecid) { + case PSI_STREAM_H264: { + if (!_codecid_video) { + //获取到视频 + _codecid_video = codecid; + InfoL<< "got video track: H264"; + auto track = std::make_shared(); + onTrack(track); + } + + if (codecid != _codecid_video) { + WarnL<< "video track change to H264 from codecid:" << getCodecName(_codecid_video); + return; + } + + auto frame = std::make_shared((char *) data, bytes, dts, pts,0); + _merger.inputFrame(frame,[this](uint32_t dts, uint32_t pts, const Buffer::Ptr &buffer) { + onFrame(std::make_shared(buffer->data(), buffer->size(), dts, pts,4)); + }); + break; + } + + case PSI_STREAM_H265: { + if (!_codecid_video) { + //获取到视频 + _codecid_video = codecid; + InfoL<< "got video track: H265"; + auto track = std::make_shared(); + onTrack(track); + } + if (codecid != _codecid_video) { + WarnL<< "video track change to H265 from codecid:" << getCodecName(_codecid_video); + return; + } + auto frame = std::make_shared((char *) data, bytes, dts, pts, 0); + _merger.inputFrame(frame,[this](uint32_t dts, uint32_t pts, const Buffer::Ptr &buffer) { + onFrame(std::make_shared(buffer->data(), buffer->size(), dts, pts, 4)); + }); + break; + } + + case PSI_STREAM_AAC: { + if (!_codecid_audio) { + //获取到音频 + _codecid_audio = codecid; + InfoL<< "got audio track: AAC"; + auto track = std::make_shared(); + onTrack(track); + } + + if (codecid != _codecid_audio) { + WarnL<< "audio track change to AAC from codecid:" << getCodecName(_codecid_audio); + return; + } + onFrame(std::make_shared((char *) data, bytes, dts, 0, 7)); + break; + } + + case PSI_STREAM_AUDIO_G711A: + case PSI_STREAM_AUDIO_G711U: { + auto codec = codecid == PSI_STREAM_AUDIO_G711A ? CodecG711A : CodecG711U; + if (!_codecid_audio) { + //获取到音频 + _codecid_audio = codecid; + InfoL<< "got audio track: G711"; + //G711传统只支持 8000/1/16的规格,FFmpeg貌似做了扩展,但是这里不管它了 + auto track = std::make_shared(codec, 8000, 1, 16); + onTrack(track); + } + + if (codecid != _codecid_audio) { + WarnL<< "audio track change to G711 from codecid:" << getCodecName(_codecid_audio); + return; + } + auto frame = std::make_shared((char *) data, bytes, dts); + frame->setCodec(codec); + onFrame(frame); + break; + } + default: + if(codecid != 0){ + WarnL<< "unsupported codec type:" << getCodecName(codecid) << " " << (int)codecid; + } + break; + } +} + +void DecoderImp::onTrack(const Track::Ptr &track) { + _sink->addTrack(track); +} + +void DecoderImp::onFrame(const Frame::Ptr &frame) { + _sink->inputFrame(frame); +} + }//namespace mediakit -#endif//defined(ENABLE_RTPPROXY) diff --git a/src/Rtp/Decoder.h b/src/Rtp/Decoder.h index 203d51d9..c20bc65d 100644 --- a/src/Rtp/Decoder.h +++ b/src/Rtp/Decoder.h @@ -11,31 +11,66 @@ #ifndef ZLMEDIAKIT_DECODER_H #define ZLMEDIAKIT_DECODER_H -#if defined(ENABLE_RTPPROXY) #include #include #include #include "Decoder.h" +#include "Common/MediaSink.h" + using namespace std; namespace mediakit { class Decoder { public: typedef std::shared_ptr Ptr; - typedef enum { - decoder_ts = 0, - decoder_ps - }Type; - typedef std::function onDecode; virtual int input(const uint8_t *data, int bytes) = 0; virtual void setOnDecode(const onDecode &decode) = 0; - static Ptr createDecoder(Type type); protected: Decoder() = default; virtual ~Decoder() = default; }; +/** + * 合并一些时间戳相同的frame + */ +class FrameMerger { +public: + FrameMerger() = default; + ~FrameMerger() = default; + void inputFrame(const Frame::Ptr &frame,const function &cb); +private: + List _frameCached; +}; + +class DecoderImp{ +public: + typedef enum { + decoder_ts = 0, + decoder_ps + }Type; + + typedef std::shared_ptr Ptr; + ~DecoderImp() = default; + + static Ptr createDecoder(Type type, const MediaSinkInterface::Ptr &sink); + int input(const uint8_t *data, int bytes); + +protected: + void onTrack(const Track::Ptr &track); + void onFrame(const Frame::Ptr &frame); + +private: + DecoderImp(const Decoder::Ptr &decoder, const MediaSinkInterface::Ptr &sink); + void onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,int bytes); + +private: + Decoder::Ptr _decoder; + MediaSinkInterface::Ptr _sink; + FrameMerger _merger; + int _codecid_video = 0; + int _codecid_audio = 0; +}; + }//namespace mediakit -#endif//defined(ENABLE_RTPPROXY) #endif //ZLMEDIAKIT_DECODER_H diff --git a/src/Rtp/RtpProcess.cpp b/src/Rtp/RtpProcess.cpp index bcfa69e0..008c7406 100644 --- a/src/Rtp/RtpProcess.cpp +++ b/src/Rtp/RtpProcess.cpp @@ -9,44 +9,13 @@ */ #if defined(ENABLE_RTPPROXY) -#include "mpeg-ts-proto.h" #include "RtpProcess.h" #include "Util/File.h" -#include "Extension/H265.h" -#include "Extension/AAC.h" -#include "Extension/G711.h" +#include "Http/HttpTSPlayer.h" #define RTP_APP_NAME "rtp" namespace mediakit{ -/** - * 合并一些时间戳相同的frame - */ -class FrameMerger { -public: - FrameMerger() = default; - virtual ~FrameMerger() = default; - - void inputFrame(const Frame::Ptr &frame,const function &cb){ - if (!_frameCached.empty() && _frameCached.back()->dts() != frame->dts()) { - Frame::Ptr back = _frameCached.back(); - Buffer::Ptr merged_frame = back; - if(_frameCached.size() != 1){ - string merged; - _frameCached.for_each([&](const Frame::Ptr &frame){ - merged.append(frame->data(),frame->size()); - }); - merged_frame = std::make_shared(std::move(merged)); - } - cb(back->dts(),back->pts(),merged_frame); - _frameCached.clear(); - } - _frameCached.emplace_back(Frame::getCacheAbleFrame(frame)); - } -private: - List _frameCached; -}; - string printSSRC(uint32_t ui32Ssrc) { char tmp[9] = { 0 }; ui32Ssrc = htonl(ui32Ssrc); @@ -101,7 +70,6 @@ RtpProcess::RtpProcess(uint32_t ssrc) { }); } } - _merger = std::make_shared(); } RtpProcess::~RtpProcess() { @@ -157,7 +125,7 @@ bool RtpProcess::inputRtp(const Socket::Ptr &sock, const char *data, int data_le //判断是否为ts负载 static inline bool checkTS(const uint8_t *packet, int bytes){ - return bytes % 188 == 0 && packet[0] == 0x47; + return bytes % TS_PACKET_SIZE == 0 && packet[0] == TS_SYNC_BYTE; } void RtpProcess::onRtpSorted(const RtpPacket::Ptr &rtp, int) { @@ -179,153 +147,37 @@ void RtpProcess::onRtpDecode(const uint8_t *packet, int bytes, uint32_t timestam fwrite((uint8_t *)packet,bytes, 1, _save_file_ps.get()); } - if(!_decoder){ + if (!_decoder) { //创建解码器 - if(checkTS(packet, bytes)){ + if (checkTS(packet, bytes)) { //猜测是ts负载 InfoP(this) << "judged to be TS"; - _decoder = Decoder::createDecoder(Decoder::decoder_ts); - }else{ + _decoder = DecoderImp::createDecoder(DecoderImp::decoder_ts, shared_from_this()); + } else { //猜测是ps负载 InfoP(this) << "judged to be PS"; - _decoder = Decoder::createDecoder(Decoder::decoder_ps); + _decoder = DecoderImp::createDecoder(DecoderImp::decoder_ps, shared_from_this()); } - _decoder->setOnDecode([this](int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,int bytes){ - onDecode(stream,codecid,flags,pts,dts,data,bytes); - }); } - auto ret = _decoder->input((uint8_t *)packet,bytes); - if(ret != bytes){ - WarnP(this) << ret << " != " << bytes << " " << flags; + if (_decoder) { + auto ret = _decoder->input((uint8_t *) packet, bytes); + if (ret != bytes) { + WarnP(this) << ret << " != " << bytes << " " << flags; + } } } -#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); - default : return "unknown codec"; +void RtpProcess::inputFrame(const Frame::Ptr &frame){ + _dts = frame->dts(); + if (_save_file_video && frame->getTrackType() == TrackVideo) { + fwrite((uint8_t *) frame->data(), frame->size(), 1, _save_file_video.get()); } + _muxer->inputFrame(frame); } -void RtpProcess::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,int bytes) { - pts /= 90; - dts /= 90; - _dts = dts; - - switch (codecid) { - case PSI_STREAM_H264: { - if (!_codecid_video) { - //获取到视频 - _codecid_video = codecid; - InfoP(this) << "got video track: H264"; - auto track = std::make_shared(); - _muxer->addTrack(track); - } - - if (codecid != _codecid_video) { - WarnP(this) << "video track change to H264 from codecid:" << getCodecName(_codecid_video); - return; - } - - if(_save_file_video){ - fwrite((uint8_t *)data,bytes, 1, _save_file_video.get()); - } - auto frame = std::make_shared((char *) data, bytes, dts, pts,0); - _merger->inputFrame(frame,[this](uint32_t dts, uint32_t pts, const Buffer::Ptr &buffer) { - _muxer->inputFrame(std::make_shared(buffer->data(), buffer->size(), dts, pts,4)); - }); - break; - } - - case PSI_STREAM_H265: { - if (!_codecid_video) { - //获取到视频 - _codecid_video = codecid; - InfoP(this) << "got video track: H265"; - auto track = std::make_shared(); - _muxer->addTrack(track); - } - if (codecid != _codecid_video) { - WarnP(this) << "video track change to H265 from codecid:" << getCodecName(_codecid_video); - return; - } - if(_save_file_video){ - fwrite((uint8_t *)data,bytes, 1, _save_file_video.get()); - } - auto frame = std::make_shared((char *) data, bytes, dts, pts, 0); - _merger->inputFrame(frame,[this](uint32_t dts, uint32_t pts, const Buffer::Ptr &buffer) { - _muxer->inputFrame(std::make_shared(buffer->data(), buffer->size(), dts, pts, 4)); - }); - break; - } - - case PSI_STREAM_AAC: { - if (!_codecid_audio) { - //获取到音频 - _codecid_audio = codecid; - InfoP(this) << "got audio track: AAC"; - auto track = std::make_shared(); - _muxer->addTrack(track); - } - - if (codecid != _codecid_audio) { - WarnP(this) << "audio track change to AAC from codecid:" << getCodecName(_codecid_audio); - return; - } - _muxer->inputFrame(std::make_shared((char *) data, bytes, dts, 0, 7)); - break; - } - - case PSI_STREAM_AUDIO_G711A: - case PSI_STREAM_AUDIO_G711U: { - auto codec = codecid == PSI_STREAM_AUDIO_G711A ? CodecG711A : CodecG711U; - if (!_codecid_audio) { - //获取到音频 - _codecid_audio = codecid; - InfoP(this) << "got audio track: G711"; - //G711传统只支持 8000/1/16的规格,FFmpeg貌似做了扩展,但是这里不管它了 - auto track = std::make_shared(codec, 8000, 1, 16); - _muxer->addTrack(track); - } - - if (codecid != _codecid_audio) { - WarnP(this) << "audio track change to G711 from codecid:" << getCodecName(_codecid_audio); - return; - } - auto frame = std::make_shared((char *) data, bytes, dts); - frame->setCodec(codec); - _muxer->inputFrame(frame); - break; - } - default: - if(codecid != 0){ - WarnP(this) << "unsupported codec type:" << getCodecName(codecid) << " " << (int)codecid; - } - return; - } +void RtpProcess::addTrack(const Track::Ptr & track){ + _muxer->addTrack(track); } bool RtpProcess::alive() { @@ -410,6 +262,5 @@ void RtpProcess::emitOnPublish() { } } - }//namespace mediakit #endif//defined(ENABLE_RTPPROXY) \ No newline at end of file diff --git a/src/Rtp/RtpProcess.h b/src/Rtp/RtpProcess.h index 98140bc6..7b054292 100644 --- a/src/Rtp/RtpProcess.h +++ b/src/Rtp/RtpProcess.h @@ -23,8 +23,7 @@ using namespace mediakit; namespace mediakit{ string printSSRC(uint32_t ui32Ssrc); -class FrameMerger; -class RtpProcess : public RtpReceiver , public RtpDecoder, public SockInfo, public std::enable_shared_from_this{ +class RtpProcess : public RtpReceiver , public RtpDecoder, public SockInfo, public MediaSinkInterface, public std::enable_shared_from_this{ public: typedef std::shared_ptr Ptr; RtpProcess(uint32_t ssrc); @@ -44,7 +43,9 @@ public: protected: void onRtpSorted(const RtpPacket::Ptr &rtp, int track_index) override ; void onRtpDecode(const uint8_t *packet, int bytes, uint32_t timestamp, int flags) override; - void onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts, const void *data,int bytes); + void inputFrame(const Frame::Ptr &frame) override; + void addTrack(const Track::Ptr & track) override; + void resetTracks() override {}; private: void emitOnPublish(); @@ -57,13 +58,10 @@ private: SdpTrack::Ptr _track; struct sockaddr *_addr = nullptr; uint16_t _sequence = 0; - int _codecid_video = 0; - int _codecid_audio = 0; MultiMediaSourceMuxer::Ptr _muxer; - std::shared_ptr _merger; Ticker _last_rtp_time; uint32_t _dts = 0; - Decoder::Ptr _decoder; + DecoderImp::Ptr _decoder; std::weak_ptr _listener; MediaInfo _media_info; uint64_t _total_bytes = 0; diff --git a/src/Rtp/TSDecoder.cpp b/src/Rtp/TSDecoder.cpp index b8486fcf..0f25c20e 100644 --- a/src/Rtp/TSDecoder.cpp +++ b/src/Rtp/TSDecoder.cpp @@ -8,34 +8,38 @@ * may be found in the AUTHORS file in the root of the source tree. */ -#if defined(ENABLE_RTPPROXY) -#include "mpeg-ts.h" #include "TSDecoder.h" -#define TS_PACKET_SIZE 188 namespace mediakit { +bool TSSegment::isTSPacket(const char *data, int len){ + return len == TS_PACKET_SIZE && ((uint8_t*)data)[0] == TS_SYNC_BYTE; +} + void TSSegment::setOnSegment(const TSSegment::onSegment &cb) { _onSegment = cb; } int64_t TSSegment::onRecvHeader(const char *data, uint64_t len) { + if (!isTSPacket(data, len)) { + WarnL << "不是ts包:" << (int) (data[0]) << " " << len; + return 0; + } _onSegment(data, len); return 0; } const char *TSSegment::onSearchPacketTail(const char *data, int len) { if (len < _size + 1) { - if (len == _size && ((uint8_t *) data)[0] == 0x47) { + if (len == _size && ((uint8_t *) data)[0] == TS_SYNC_BYTE) { return data + _size; } return nullptr; } //下一个包头 - if (((uint8_t *) data)[_size] == 0x47) { + if (((uint8_t *) data)[_size] == TS_SYNC_BYTE) { return data + _size; } - - auto pos = memchr(data + _size, 0x47, len - _size); + auto pos = memchr(data + _size, TS_SYNC_BYTE, len - _size); if (pos) { return (char *) pos; } @@ -44,12 +48,10 @@ const char *TSSegment::onSearchPacketTail(const char *data, int len) { //////////////////////////////////////////////////////////////// -TSDecoder::TSDecoder() : _ts_segment(TS_PACKET_SIZE) { +#if defined(ENABLE_HLS) +#include "mpeg-ts.h" +TSDecoder::TSDecoder() : _ts_segment() { _ts_segment.setOnSegment([this](const char *data,uint64_t len){ - if(((uint8_t*)data)[0] != 0x47 || len != TS_PACKET_SIZE ){ - WarnL << "不是ts包:" << (int)(data[0]) << " " << len; - return; - } ts_demuxer_input(_demuxer_ctx,(uint8_t*)data,len); }); _demuxer_ctx = ts_demuxer_create([](void* param, int program, int stream, int codecid, int flags, int64_t pts, int64_t dts, const void* data, size_t bytes){ @@ -66,8 +68,8 @@ TSDecoder::~TSDecoder() { } int TSDecoder::input(const uint8_t *data, int bytes) { - if(bytes == TS_PACKET_SIZE && ((uint8_t*)data)[0] == 0x47){ - return ts_demuxer_input(_demuxer_ctx,(uint8_t*)data,bytes); + if (TSSegment::isTSPacket((char *)data, bytes)) { + return ts_demuxer_input(_demuxer_ctx, (uint8_t *) data, bytes); } _ts_segment.input((char*)data,bytes); return bytes; @@ -76,6 +78,6 @@ int TSDecoder::input(const uint8_t *data, int bytes) { void TSDecoder::setOnDecode(const Decoder::onDecode &decode) { _on_decode = decode; } +#endif//defined(ENABLE_HLS) }//namespace mediakit -#endif//defined(ENABLE_RTPPROXY) \ No newline at end of file diff --git a/src/Rtp/TSDecoder.h b/src/Rtp/TSDecoder.h index 6de2397c..42841404 100644 --- a/src/Rtp/TSDecoder.h +++ b/src/Rtp/TSDecoder.h @@ -11,7 +11,6 @@ #ifndef ZLMEDIAKIT_TSDECODER_H #define ZLMEDIAKIT_TSDECODER_H -#if defined(ENABLE_RTPPROXY) #include "Util/logger.h" #include "Http/HttpRequestSplitter.h" #include "Decoder.h" @@ -19,13 +18,17 @@ using namespace toolkit; namespace mediakit { -//ts包拆分器 +#define TS_PACKET_SIZE 188 +#define TS_SYNC_BYTE 0x47 + +//TS包分割器,用于split一个一个的ts包 class TSSegment : public HttpRequestSplitter { public: typedef std::function onSegment; - TSSegment(int size = 188) : _size(size){} + TSSegment(int size = TS_PACKET_SIZE) : _size(size){} ~TSSegment(){} void setOnSegment(const onSegment &cb); + static bool isTSPacket(const char *data, int len); protected: int64_t onRecvHeader(const char *data, uint64_t len) override ; const char *onSearchPacketTail(const char *data, int len) override ; @@ -34,6 +37,7 @@ private: onSegment _onSegment; }; +#if defined(ENABLE_HLS) //ts解析器 class TSDecoder : public Decoder { public: @@ -46,7 +50,7 @@ private: struct ts_demuxer_t* _demuxer_ctx = nullptr; onDecode _on_decode; }; +#endif//defined(ENABLE_HLS) }//namespace mediakit -#endif//defined(ENABLE_RTPPROXY) #endif //ZLMEDIAKIT_TSDECODER_H