2020-10-24 23:37:43 +08:00
|
|
|
|
/*
|
2020-10-24 23:33:13 +08:00
|
|
|
|
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
|
|
|
|
|
|
*
|
|
|
|
|
|
* Use of this source code is governed by MIT license that can be found in the
|
|
|
|
|
|
* LICENSE file in the root of the source tree. All contributing project authors
|
|
|
|
|
|
* may be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(ENABLE_RTPPROXY)
|
|
|
|
|
|
#include "GB28181Process.h"
|
|
|
|
|
|
#include "Util/File.h"
|
|
|
|
|
|
#include "Http/HttpTSPlayer.h"
|
|
|
|
|
|
#include "Extension/CommonRtp.h"
|
2020-11-01 22:27:44 +08:00
|
|
|
|
#include "Extension/H264Rtp.h"
|
2020-10-24 23:33:13 +08:00
|
|
|
|
|
|
|
|
|
|
namespace mediakit{
|
|
|
|
|
|
|
|
|
|
|
|
//判断是否为ts负载
|
|
|
|
|
|
static inline bool checkTS(const uint8_t *packet, int bytes){
|
|
|
|
|
|
return bytes % TS_PACKET_SIZE == 0 && packet[0] == TS_SYNC_BYTE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GB28181Process::GB28181Process(const MediaInfo &media_info, MediaSinkInterface *interface) {
|
|
|
|
|
|
assert(interface);
|
|
|
|
|
|
_media_info = media_info;
|
|
|
|
|
|
_interface = interface;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GB28181Process::~GB28181Process() {}
|
|
|
|
|
|
|
|
|
|
|
|
bool GB28181Process::inputRtp(bool, const char *data, int data_len) {
|
|
|
|
|
|
return handleOneRtp(0, TrackVideo, 90000, (unsigned char *) data, data_len);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GB28181Process::onRtpSorted(const RtpPacket::Ptr &rtp, int) {
|
|
|
|
|
|
if (!_rtp_decoder) {
|
|
|
|
|
|
switch (rtp->PT) {
|
2021-01-02 20:02:38 +08:00
|
|
|
|
case 98: {
|
|
|
|
|
|
//H264负载
|
|
|
|
|
|
_rtp_decoder = std::make_shared<H264RtpDecoder>();
|
|
|
|
|
|
_interface->addTrack(std::make_shared<H264Track>());
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
default: {
|
|
|
|
|
|
if (rtp->PT != 33 && rtp->PT != 96) {
|
|
|
|
|
|
WarnL << "rtp payload type未识别(" << (int) rtp->PT << "),已按ts或ps负载处理";
|
|
|
|
|
|
}
|
2020-10-24 23:33:13 +08:00
|
|
|
|
//ts或ps负载
|
2021-01-09 17:53:21 +08:00
|
|
|
|
_rtp_decoder = std::make_shared<CommonRtpDecoder>(CodecInvalid, 32 * 1024);
|
2020-10-24 23:33:13 +08:00
|
|
|
|
//设置dump目录
|
|
|
|
|
|
GET_CONFIG(string, dump_dir, RtpProxy::kDumpDir);
|
|
|
|
|
|
if (!dump_dir.empty()) {
|
|
|
|
|
|
auto save_path = File::absolutePath(_media_info._streamid + ".mp2", dump_dir);
|
|
|
|
|
|
_save_file_ps.reset(File::create_file(save_path.data(), "wb"), [](FILE *fp) {
|
|
|
|
|
|
if (fp) {
|
|
|
|
|
|
fclose(fp);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//设置frame回调
|
|
|
|
|
|
_rtp_decoder->addDelegate(std::make_shared<FrameWriterInterfaceHelper>([this](const Frame::Ptr &frame) {
|
|
|
|
|
|
onRtpDecode(frame);
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//解码rtp
|
|
|
|
|
|
_rtp_decoder->inputRtp(rtp, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-01 03:41:35 +08:00
|
|
|
|
const char *GB28181Process::onSearchPacketTail(const char *packet,uint64_t bytes){
|
2020-10-24 23:33:13 +08:00
|
|
|
|
try {
|
|
|
|
|
|
auto ret = _decoder->input((uint8_t *) packet, bytes);
|
|
|
|
|
|
if (ret > 0) {
|
|
|
|
|
|
return packet + ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
} catch (std::exception &ex) {
|
|
|
|
|
|
InfoL << "解析ps或ts异常: bytes=" << bytes
|
|
|
|
|
|
<< " ,exception=" << ex.what()
|
|
|
|
|
|
<< " ,hex=" << hexdump((uint8_t *) packet, bytes);
|
|
|
|
|
|
if (remainDataSize() > 256 * 1024) {
|
|
|
|
|
|
//缓存太多数据无法处理则上抛异常
|
|
|
|
|
|
throw;
|
|
|
|
|
|
}
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GB28181Process::onRtpDecode(const Frame::Ptr &frame) {
|
2020-11-01 22:27:44 +08:00
|
|
|
|
if (frame->getCodecId() == CodecH264) {
|
|
|
|
|
|
//这是H264
|
|
|
|
|
|
_interface->inputFrame(frame);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-10-24 23:33:13 +08:00
|
|
|
|
//这是TS或PS
|
|
|
|
|
|
if (_save_file_ps) {
|
|
|
|
|
|
fwrite(frame->data(), frame->size(), 1, _save_file_ps.get());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!_decoder) {
|
|
|
|
|
|
//创建解码器
|
|
|
|
|
|
if (checkTS((uint8_t *) frame->data(), frame->size())) {
|
|
|
|
|
|
//猜测是ts负载
|
|
|
|
|
|
InfoL << _media_info._streamid << " judged to be TS";
|
|
|
|
|
|
_decoder = DecoderImp::createDecoder(DecoderImp::decoder_ts, _interface);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
//猜测是ps负载
|
|
|
|
|
|
InfoL << _media_info._streamid << " judged to be PS";
|
|
|
|
|
|
_decoder = DecoderImp::createDecoder(DecoderImp::decoder_ps, _interface);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_decoder) {
|
|
|
|
|
|
HttpRequestSplitter::input(frame->data(), frame->size());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}//namespace mediakit
|
2021-01-09 17:53:21 +08:00
|
|
|
|
#endif//defined(ENABLE_RTPPROXY)
|