mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-31 00:37:39 +08:00
支持ts rtp流
This commit is contained in:
parent
d35f1d0bfe
commit
069bde09c1
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
|
||||
|
41
src/Rtp/Decoder.cpp
Normal file
41
src/Rtp/Decoder.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 xiongziliang <771730766@qq.com>
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
#include "Decoder.h"
|
||||
#include "PSDecoder.h"
|
||||
#include "TSDecoder.h"
|
||||
namespace mediakit {
|
||||
Decoder::Ptr Decoder::createDecoder(Decoder::Type type) {
|
||||
switch (type){
|
||||
case decoder_ps : return std::make_shared<PSDecoder>();
|
||||
case decoder_ts : return std::make_shared<TSDecoder>();
|
||||
default : return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
#endif//defined(ENABLE_RTPPROXY)
|
57
src/Rtp/Decoder.h
Normal file
57
src/Rtp/Decoder.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 xiongziliang <771730766@qq.com>
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ZLMEDIAKIT_DECODER_H
|
||||
#define ZLMEDIAKIT_DECODER_H
|
||||
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include "Decoder.h"
|
||||
using namespace std;
|
||||
namespace mediakit {
|
||||
|
||||
class Decoder {
|
||||
public:
|
||||
typedef std::shared_ptr<Decoder> Ptr;
|
||||
typedef enum {
|
||||
decoder_ts = 0,
|
||||
decoder_ps
|
||||
}Type;
|
||||
|
||||
typedef std::function<void(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,int bytes)> 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;
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
#endif//defined(ENABLE_RTPPROXY)
|
||||
#endif //ZLMEDIAKIT_DECODER_H
|
@ -27,7 +27,6 @@
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
#include "PSDecoder.h"
|
||||
#include "mpeg-ps.h"
|
||||
|
||||
namespace mediakit{
|
||||
|
||||
PSDecoder::PSDecoder() {
|
||||
@ -40,7 +39,9 @@ PSDecoder::PSDecoder() {
|
||||
const void* data,
|
||||
size_t bytes){
|
||||
PSDecoder *thiz = (PSDecoder *)param;
|
||||
thiz->onPSDecode(stream, codecid, flags, pts, dts, data, bytes);
|
||||
if(thiz->_on_decode){
|
||||
thiz->_on_decode(stream, codecid, flags, pts, dts, data, bytes);
|
||||
}
|
||||
},this);
|
||||
}
|
||||
|
||||
@ -48,10 +49,13 @@ PSDecoder::~PSDecoder() {
|
||||
ps_demuxer_destroy((struct ps_demuxer_t*)_ps_demuxer);
|
||||
}
|
||||
|
||||
int PSDecoder::decodePS(const uint8_t *data, int bytes) {
|
||||
int PSDecoder::input(const uint8_t *data, int bytes) {
|
||||
return ps_demuxer_input((struct ps_demuxer_t*)_ps_demuxer,data,bytes);
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
void PSDecoder::setOnDecode(const Decoder::onDecode &decode) {
|
||||
_on_decode = decode;
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
#endif//#if defined(ENABLE_RTPPROXY)
|
@ -29,27 +29,21 @@
|
||||
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Decoder.h"
|
||||
namespace mediakit{
|
||||
|
||||
class PSDecoder {
|
||||
//ps解析器
|
||||
class PSDecoder : public Decoder {
|
||||
public:
|
||||
PSDecoder();
|
||||
virtual ~PSDecoder();
|
||||
int decodePS(const uint8_t *data, int bytes);
|
||||
protected:
|
||||
virtual void onPSDecode(int stream,
|
||||
int codecid,
|
||||
int flags,
|
||||
int64_t pts,
|
||||
int64_t dts,
|
||||
const void *data,
|
||||
int bytes) = 0;
|
||||
~PSDecoder();
|
||||
int input(const uint8_t* data, int bytes) override;
|
||||
void setOnDecode(const onDecode &decode) override;
|
||||
private:
|
||||
void *_ps_demuxer = nullptr;
|
||||
onDecode _on_decode;
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
|
||||
#endif//defined(ENABLE_RTPPROXY)
|
||||
#endif //ZLMEDIAKIT_PSDECODER_H
|
||||
|
@ -63,7 +63,7 @@ void RtpDecoder::decodeRtp(const void *data, int bytes,const string &type_name)
|
||||
},
|
||||
[](void* param, const void *packet, int bytes, uint32_t timestamp, int flags){
|
||||
RtpDecoder *obj = (RtpDecoder *)param;
|
||||
obj->onRtpDecode(packet, bytes, timestamp, flags);
|
||||
obj->onRtpDecode((uint8_t *)packet, bytes, timestamp, flags);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
virtual ~RtpDecoder();
|
||||
protected:
|
||||
void decodeRtp(const void *data, int bytes,const string &type_name);
|
||||
virtual void onRtpDecode(const void *packet, int bytes, uint32_t timestamp, int flags) = 0;
|
||||
virtual void onRtpDecode(const uint8_t *packet, int bytes, uint32_t timestamp, int flags) = 0;
|
||||
private:
|
||||
void *_rtp_decoder = nullptr;
|
||||
BufferRaw::Ptr _buffer;
|
||||
|
@ -179,12 +179,26 @@ void RtpProcess::onRtpSorted(const RtpPacket::Ptr &rtp, int) {
|
||||
decodeRtp(rtp->data() + 4 ,rtp->size() - 4,_rtp_type);
|
||||
}
|
||||
|
||||
void RtpProcess::onRtpDecode(const void *packet, int bytes, uint32_t, int flags) {
|
||||
void RtpProcess::onRtpDecode(const uint8_t *packet, int bytes, uint32_t, int flags) {
|
||||
if(_save_file_ps){
|
||||
fwrite((uint8_t *)packet,bytes, 1, _save_file_ps.get());
|
||||
}
|
||||
|
||||
auto ret = decodePS((uint8_t *)packet,bytes);
|
||||
if(!_decoder){
|
||||
//创建解码器
|
||||
if(bytes % 188 == 0 || packet[0] == 0x47){
|
||||
//猜测是ts负载
|
||||
_decoder = Decoder::createDecoder(Decoder::decoder_ts);
|
||||
}else{
|
||||
//猜测是ps负载
|
||||
_decoder = Decoder::createDecoder(Decoder::decoder_ps);
|
||||
}
|
||||
_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){
|
||||
WarnL << ret << " != " << bytes << " " << flags;
|
||||
if(++_rtp_dec_failed_cnt == 10){
|
||||
@ -215,13 +229,7 @@ static const char *getCodecName(int codec_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void RtpProcess::onPSDecode(int stream,
|
||||
int codecid,
|
||||
int flags,
|
||||
int64_t pts,
|
||||
int64_t dts,
|
||||
const void *data,
|
||||
int bytes) {
|
||||
void RtpProcess::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,int bytes) {
|
||||
pts /= 90;
|
||||
dts /= 90;
|
||||
_stamps[codecid].revise(dts,pts,dts,pts,false);
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#include "Rtsp/RtpReceiver.h"
|
||||
#include "RtpDecoder.h"
|
||||
#include "PSDecoder.h"
|
||||
#include "Decoder.h"
|
||||
#include "Common/Device.h"
|
||||
#include "Common/Stamp.h"
|
||||
using namespace mediakit;
|
||||
@ -40,7 +40,7 @@ namespace mediakit{
|
||||
|
||||
string printSSRC(uint32_t ui32Ssrc);
|
||||
class FrameMerger;
|
||||
class RtpProcess : public RtpReceiver , public RtpDecoder , public PSDecoder {
|
||||
class RtpProcess : public RtpReceiver , public RtpDecoder{
|
||||
public:
|
||||
typedef std::shared_ptr<RtpProcess> Ptr;
|
||||
RtpProcess(uint32_t ssrc);
|
||||
@ -54,14 +54,8 @@ public:
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener);
|
||||
protected:
|
||||
void onRtpSorted(const RtpPacket::Ptr &rtp, int track_index) override ;
|
||||
void onRtpDecode(const void *packet, int bytes, uint32_t timestamp, int flags) override;
|
||||
void onPSDecode(int stream,
|
||||
int codecid,
|
||||
int flags,
|
||||
int64_t pts,
|
||||
int64_t dts,
|
||||
const void *data,
|
||||
int bytes) 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);
|
||||
private:
|
||||
void getNextRtpType();
|
||||
private:
|
||||
@ -82,6 +76,7 @@ private:
|
||||
int _rtp_type_idx = 0;
|
||||
string _rtp_type;
|
||||
int _rtp_dec_failed_cnt = 0;
|
||||
Decoder::Ptr _decoder;
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
|
96
src/Rtp/TSDecoder.cpp
Normal file
96
src/Rtp/TSDecoder.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 xiongziliang <771730766@qq.com>
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
#include "mpeg-ts.h"
|
||||
#include "TSDecoder.h"
|
||||
#define TS_PACKET_SIZE 188
|
||||
namespace mediakit {
|
||||
|
||||
void TSSegment::setOnSegment(const TSSegment::onSegment &cb) {
|
||||
_onSegment = cb;
|
||||
}
|
||||
|
||||
int64_t TSSegment::onRecvHeader(const char *data, uint64_t len) {
|
||||
_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) {
|
||||
return data + _size;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
//下一个包头
|
||||
if (((uint8_t *) data)[_size] == 0x47) {
|
||||
return data + _size;
|
||||
}
|
||||
|
||||
auto pos = memchr(data + _size, 0x47, len - _size);
|
||||
if (pos) {
|
||||
return (char *) pos;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
TSDecoder::TSDecoder() : _ts_segment(TS_PACKET_SIZE) {
|
||||
_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){
|
||||
TSDecoder *thiz = (TSDecoder*)param;
|
||||
if(thiz->_on_decode){
|
||||
thiz->_on_decode(stream,codecid,flags,pts,dts,data,bytes);
|
||||
}
|
||||
return 0;
|
||||
},this);
|
||||
}
|
||||
|
||||
TSDecoder::~TSDecoder() {
|
||||
ts_demuxer_destroy(_demuxer_ctx);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
_ts_segment.input((char*)data,bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void TSDecoder::setOnDecode(const Decoder::onDecode &decode) {
|
||||
_on_decode = decode;
|
||||
}
|
||||
|
||||
}//namespace mediakit
|
||||
#endif//defined(ENABLE_RTPPROXY)
|
68
src/Rtp/TSDecoder.h
Normal file
68
src/Rtp/TSDecoder.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 xiongziliang <771730766@qq.com>
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ZLMEDIAKIT_TSDECODER_H
|
||||
#define ZLMEDIAKIT_TSDECODER_H
|
||||
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
#include "Util/logger.h"
|
||||
#include "Http/HttpRequestSplitter.h"
|
||||
#include "Decoder.h"
|
||||
|
||||
using namespace toolkit;
|
||||
namespace mediakit {
|
||||
|
||||
//ts包拆分器
|
||||
class TSSegment : public HttpRequestSplitter {
|
||||
public:
|
||||
typedef std::function<void(const char *data,uint64_t len)> onSegment;
|
||||
TSSegment(int size = 188) : _size(size){}
|
||||
~TSSegment(){}
|
||||
void setOnSegment(const onSegment &cb);
|
||||
protected:
|
||||
int64_t onRecvHeader(const char *data, uint64_t len) override ;
|
||||
const char *onSearchPacketTail(const char *data, int len) override ;
|
||||
private:
|
||||
int _size;
|
||||
onSegment _onSegment;
|
||||
};
|
||||
|
||||
//ts解析器
|
||||
class TSDecoder : public Decoder {
|
||||
public:
|
||||
TSDecoder();
|
||||
~TSDecoder();
|
||||
int input(const uint8_t* data, int bytes) override ;
|
||||
void setOnDecode(const onDecode &decode) override;
|
||||
private:
|
||||
TSSegment _ts_segment;
|
||||
struct ts_demuxer_t* _demuxer_ctx = nullptr;
|
||||
onDecode _on_decode;
|
||||
};
|
||||
|
||||
}//namespace mediakit
|
||||
#endif//defined(ENABLE_RTPPROXY)
|
||||
#endif //ZLMEDIAKIT_TSDECODER_H
|
Loading…
Reference in New Issue
Block a user