2020-03-06 13:00:06 +08:00
|
|
|
|
/*
|
2023-12-09 16:23:51 +08:00
|
|
|
|
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
2020-03-06 13:00:06 +08:00
|
|
|
|
*
|
2023-12-09 16:23:51 +08:00
|
|
|
|
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
2020-03-06 13:00:06 +08:00
|
|
|
|
*
|
2023-12-09 16:23:51 +08:00
|
|
|
|
* Use of this source code is governed by MIT-like license that can be found in the
|
2020-04-04 20:30:09 +08:00
|
|
|
|
* 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.
|
2020-03-06 13:00:06 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "Decoder.h"
|
|
|
|
|
|
#include "PSDecoder.h"
|
|
|
|
|
|
#include "TSDecoder.h"
|
2023-12-09 16:23:51 +08:00
|
|
|
|
#include "Extension/Factory.h"
|
2020-05-17 18:00:23 +08:00
|
|
|
|
|
2020-06-12 18:17:49 +08:00
|
|
|
|
#if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
|
2022-11-09 17:44:38 +08:00
|
|
|
|
#include "mpeg-ts.h"
|
2020-06-12 18:17:49 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2022-02-02 20:34:50 +08:00
|
|
|
|
using namespace toolkit;
|
|
|
|
|
|
|
2020-03-06 13:00:06 +08:00
|
|
|
|
namespace mediakit {
|
2022-06-29 11:01:16 +08:00
|
|
|
|
|
|
|
|
|
|
void Decoder::setOnDecode(Decoder::onDecode cb) {
|
|
|
|
|
|
_on_decode = std::move(cb);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Decoder::setOnStream(Decoder::onStream cb) {
|
|
|
|
|
|
_on_stream = std::move(cb);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-17 18:00:23 +08:00
|
|
|
|
static Decoder::Ptr createDecoder_l(DecoderImp::Type type) {
|
2020-03-06 13:00:06 +08:00
|
|
|
|
switch (type){
|
2020-05-17 18:00:23 +08:00
|
|
|
|
case DecoderImp::decoder_ps:
|
|
|
|
|
|
#ifdef ENABLE_RTPPROXY
|
|
|
|
|
|
return std::make_shared<PSDecoder>();
|
|
|
|
|
|
#else
|
|
|
|
|
|
WarnL << "创建ps解复用器失败,请打开ENABLE_RTPPROXY然后重新编译";
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
#endif//ENABLE_RTPPROXY
|
|
|
|
|
|
|
|
|
|
|
|
case DecoderImp::decoder_ts:
|
|
|
|
|
|
#ifdef ENABLE_HLS
|
|
|
|
|
|
return std::make_shared<TSDecoder>();
|
|
|
|
|
|
#else
|
|
|
|
|
|
WarnL << "创建mpegts解复用器失败,请打开ENABLE_HLS然后重新编译";
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
#endif//ENABLE_HLS
|
|
|
|
|
|
|
|
|
|
|
|
default: return nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
2020-05-21 11:44:57 +08:00
|
|
|
|
DecoderImp::Ptr DecoderImp::createDecoder(Type type, MediaSinkInterface *sink){
|
2020-05-17 18:00:23 +08:00
|
|
|
|
auto decoder = createDecoder_l(type);
|
|
|
|
|
|
if(!decoder){
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecoderImp::Ptr(new DecoderImp(decoder, sink));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-16 19:49:56 +08:00
|
|
|
|
void DecoderImp::flush() {
|
2023-12-09 22:34:22 +08:00
|
|
|
|
for (auto &pr : _tracks) {
|
|
|
|
|
|
pr.second.second.flush();
|
|
|
|
|
|
}
|
2022-10-16 19:49:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-02-09 14:01:10 +08:00
|
|
|
|
ssize_t DecoderImp::input(const uint8_t *data, size_t bytes){
|
2020-05-17 18:00:23 +08:00
|
|
|
|
return _decoder->input(data, bytes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-21 11:44:57 +08:00
|
|
|
|
DecoderImp::DecoderImp(const Decoder::Ptr &decoder, MediaSinkInterface *sink){
|
2020-05-17 18:00:23 +08:00
|
|
|
|
_decoder = decoder;
|
|
|
|
|
|
_sink = sink;
|
2021-01-17 18:31:50 +08:00
|
|
|
|
_decoder->setOnDecode([this](int stream, int codecid, int flags, int64_t pts, int64_t dts, const void *data, size_t bytes) {
|
2020-11-29 09:38:04 +08:00
|
|
|
|
onDecode(stream, codecid, flags, pts, dts, data, bytes);
|
|
|
|
|
|
});
|
2021-01-17 18:31:50 +08:00
|
|
|
|
_decoder->setOnStream([this](int stream, int codecid, const void *extra, size_t bytes, int finish) {
|
2020-11-29 09:38:04 +08:00
|
|
|
|
onStream(stream, codecid, extra, bytes, finish);
|
2020-05-17 18:00:23 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-12 18:17:49 +08:00
|
|
|
|
#if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
|
2020-05-17 18:00:23 +08:00
|
|
|
|
|
2023-12-09 16:23:51 +08:00
|
|
|
|
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;
|
2020-11-29 09:38:04 +08:00
|
|
|
|
}
|
2023-12-09 22:34:22 +08:00
|
|
|
|
onTrack(stream, std::move(track));
|
2023-12-09 16:23:51 +08:00
|
|
|
|
// 防止未获取视频track提前complete导致忽略后续视频的问题,用于兼容一些不太规范的ps流
|
2023-12-09 22:34:22 +08:00
|
|
|
|
if (finish && _have_video) {
|
2020-11-29 09:38:04 +08:00
|
|
|
|
_sink->addTrackCompleted();
|
2023-12-09 16:23:51 +08:00
|
|
|
|
InfoL << "Add track finished";
|
2020-11-29 09:38:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-09 16:23:51 +08:00
|
|
|
|
void DecoderImp::onDecode(int stream, int codecid, int flags, int64_t pts, int64_t dts, const void *data, size_t bytes) {
|
2020-05-17 18:00:23 +08:00
|
|
|
|
pts /= 90;
|
|
|
|
|
|
dts /= 90;
|
|
|
|
|
|
|
2023-12-09 16:23:51 +08:00
|
|
|
|
auto codec = getCodecByMpegId(codecid);
|
|
|
|
|
|
if (codec == CodecInvalid) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-12-09 22:34:22 +08:00
|
|
|
|
auto &ref = _tracks[stream];
|
|
|
|
|
|
if (!ref.first) {
|
|
|
|
|
|
onTrack(stream, Factory::getTrackByCodecId(codec, 8000, 1, 16));
|
2023-12-09 16:23:51 +08:00
|
|
|
|
}
|
2023-12-09 22:34:22 +08:00
|
|
|
|
auto frame = Factory::getFrameFromPtr(codec, (char *)data, bytes, dts, pts);
|
|
|
|
|
|
if (getTrackType(codec) != TrackVideo) {
|
|
|
|
|
|
onFrame(stream, frame);
|
|
|
|
|
|
return;
|
2020-03-06 13:00:06 +08:00
|
|
|
|
}
|
2023-12-09 22:34:22 +08:00
|
|
|
|
ref.second.inputFrame(frame, [&](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) {
|
|
|
|
|
|
onFrame(stream, Factory::getFrameFromBuffer(codec, buffer, dts, pts));
|
|
|
|
|
|
});
|
2020-03-06 13:00:06 +08:00
|
|
|
|
}
|
2020-06-12 18:17:49 +08:00
|
|
|
|
#else
|
2021-01-17 18:31:50 +08:00
|
|
|
|
void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,size_t bytes) {}
|
|
|
|
|
|
void DecoderImp::onStream(int stream,int codecid,const void *extra,size_t bytes,int finish) {}
|
2020-06-12 18:17:49 +08:00
|
|
|
|
#endif
|
2020-03-06 13:00:06 +08:00
|
|
|
|
|
2023-12-09 22:34:22 +08:00
|
|
|
|
void DecoderImp::onTrack(int index, const Track::Ptr &track) {
|
2023-12-09 16:23:51 +08:00
|
|
|
|
if (!track) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-12-09 22:34:22 +08:00
|
|
|
|
track->setIndex(index);
|
|
|
|
|
|
auto &ref = _tracks[index];
|
|
|
|
|
|
if (ref.first) {
|
|
|
|
|
|
WarnL << "Already existed a same track: " << index << ", codec: " << track->getCodecName();
|
|
|
|
|
|
return;
|
2021-06-16 11:39:46 +08:00
|
|
|
|
}
|
2023-12-09 22:34:22 +08:00
|
|
|
|
ref.first = track;
|
|
|
|
|
|
_sink->addTrack(track);
|
|
|
|
|
|
InfoL << "Got track: " << track->getCodecName();
|
|
|
|
|
|
_have_video = track->getTrackType() == TrackVideo ? true : _have_video;
|
2020-05-17 18:00:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-09 22:34:22 +08:00
|
|
|
|
void DecoderImp::onFrame(int index, const Frame::Ptr &frame) {
|
2023-12-09 16:23:51 +08:00
|
|
|
|
if (frame) {
|
2023-12-09 22:34:22 +08:00
|
|
|
|
frame->setIndex(index);
|
2023-12-09 16:23:51 +08:00
|
|
|
|
_sink->inputFrame(frame);
|
|
|
|
|
|
}
|
2020-05-17 18:00:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-03-06 13:00:06 +08:00
|
|
|
|
}//namespace mediakit
|
2020-06-12 18:17:49 +08:00
|
|
|
|
|