精简代码

This commit is contained in:
xia-chu 2023-12-09 03:18:57 +08:00
parent 7d4a930162
commit 630b5d75d9
13 changed files with 89 additions and 147 deletions

View File

@ -10,8 +10,7 @@
#include "mk_h264_splitter.h" #include "mk_h264_splitter.h"
#include "Http/HttpRequestSplitter.h" #include "Http/HttpRequestSplitter.h"
#include "Extension/H264.h" #include "Extension/Factory.h"
#include "Extension/H265.h"
using namespace mediakit; using namespace mediakit;
@ -71,9 +70,9 @@ const char *H264Splitter::onSearchPacketTail(const char *data, size_t len) {
auto last_frame_len = next_frame - last_frame; auto last_frame_len = next_frame - last_frame;
Frame::Ptr frame; Frame::Ptr frame;
if (_h265) { if (_h265) {
frame = std::make_shared<H265FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len)); frame = Factory::getFrameFromPtr(CodecH265, (char *)last_frame, last_frame_len, 0, 0);
} else { } else {
frame = std::make_shared<H264FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len)); frame = Factory::getFrameFromPtr(CodecH264, (char *)last_frame, last_frame_len, 0, 0);
} }
if (frame->decodeAble()) { if (frame->decodeAble()) {
_search_pos = 0; _search_pos = 0;

View File

@ -15,7 +15,6 @@
#include "Util/File.h" #include "Util/File.h"
#include "Util/uv_errno.h" #include "Util/uv_errno.h"
#include "Transcode.h" #include "Transcode.h"
#include "Extension/AAC.h"
#include "Common/config.h" #include "Common/config.h"
#define MAX_DELAY_SECOND 3 #define MAX_DELAY_SECOND 3

View File

@ -11,11 +11,7 @@
#include "Device.h" #include "Device.h"
#include "Util/logger.h" #include "Util/logger.h"
#include "Util/base64.h" #include "Util/base64.h"
#include "Extension/AAC.h" #include "Extension/Factory.h"
#include "Extension/Opus.h"
#include "Extension/G711.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#ifdef ENABLE_FAAC #ifdef ENABLE_FAAC
#include "Codec/AACEncoder.h" #include "Codec/AACEncoder.h"
#endif //ENABLE_FAAC #endif //ENABLE_FAAC
@ -85,15 +81,7 @@ bool DevChannel::inputH264(const char *data, int len, uint64_t dts, uint64_t pts
pts = dts; pts = dts;
} }
//由于rtmp/hls/mp4需要缓存时间戳相同的帧 return inputFrame(Factory::getFrameFromPtr(CodecH264,data, len, dts, pts));
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
auto frame = FrameImp::create<H264Frame>();
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign(data, len);
frame->_prefix_size = prefixSize(data,len);
return inputFrame(frame);
} }
bool DevChannel::inputH265(const char *data, int len, uint64_t dts, uint64_t pts) { bool DevChannel::inputH265(const char *data, int len, uint64_t dts, uint64_t pts) {
@ -104,17 +92,11 @@ bool DevChannel::inputH265(const char *data, int len, uint64_t dts, uint64_t pts
pts = dts; pts = dts;
} }
//由于rtmp/hls/mp4需要缓存时间戳相同的帧 return inputFrame(Factory::getFrameFromPtr(CodecH265, data, len, dts, pts));
//所以使用FrameNoCacheAble类型的帧反而会在转换成FrameCacheAble时多次内存拷贝
//在此处只拷贝一次,性能开销更低
auto frame = FrameImp::create<H265Frame>();
frame->_dts = dts;
frame->_pts = pts;
frame->_buffer.assign(data, len);
frame->_prefix_size = prefixSize(data,len);
return inputFrame(frame);
} }
#define ADTS_HEADER_LEN 7
bool DevChannel::inputAAC(const char *data_without_adts, int len, uint64_t dts, const char *adts_header){ bool DevChannel::inputAAC(const char *data_without_adts, int len, uint64_t dts, const char *adts_header){
if (dts == 0) { if (dts == 0) {
dts = _aTicker[1].elapsedTime(); dts = _aTicker[1].elapsedTime();
@ -122,47 +104,36 @@ bool DevChannel::inputAAC(const char *data_without_adts, int len, uint64_t dts,
if (!adts_header) { if (!adts_header) {
//没有adts头 //没有adts头
return inputFrame(std::make_shared<FrameFromPtr>(_audio->codecId, (char *) data_without_adts, len, dts, 0, 0)); return inputFrame(std::make_shared<FrameFromPtr>(CodecAAC, (char *) data_without_adts, len, dts, 0, 0));
} }
if (adts_header + ADTS_HEADER_LEN == data_without_adts) { if (adts_header + ADTS_HEADER_LEN == data_without_adts) {
//adts头和帧在一起 //adts头和帧在一起
return inputFrame(std::make_shared<FrameFromPtr>(_audio->codecId, (char *) data_without_adts - ADTS_HEADER_LEN, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN)); return inputFrame(std::make_shared<FrameFromPtr>(CodecAAC, (char *) data_without_adts - ADTS_HEADER_LEN, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN));
} }
//adts头和帧不在一起 //adts头和帧不在一起
char *data_with_adts = new char[len + ADTS_HEADER_LEN]; char *data_with_adts = new char[len + ADTS_HEADER_LEN];
memcpy(data_with_adts, adts_header, ADTS_HEADER_LEN); memcpy(data_with_adts, adts_header, ADTS_HEADER_LEN);
memcpy(data_with_adts + ADTS_HEADER_LEN, data_without_adts, len); memcpy(data_with_adts + ADTS_HEADER_LEN, data_without_adts, len);
return inputFrame(std::make_shared<FrameAutoDelete>(_audio->codecId, data_with_adts, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN)); return inputFrame(std::make_shared<FrameAutoDelete>(CodecAAC, data_with_adts, len + ADTS_HEADER_LEN, dts, 0, ADTS_HEADER_LEN));
} }
bool DevChannel::inputAudio(const char *data, int len, uint64_t dts){ bool DevChannel::inputAudio(const char *data, int len, uint64_t dts){
if (dts == 0) { if (dts == 0) {
dts = _aTicker[1].elapsedTime(); dts = _aTicker[1].elapsedTime();
} }
return inputFrame(std::make_shared<FrameFromPtr>(_audio->codecId, (char *) data, len, dts, 0)); return inputFrame(Factory::getFrameFromPtr(_audio->codecId, (char *) data, len, dts, dts));
} }
bool DevChannel::initVideo(const VideoInfo &info) { bool DevChannel::initVideo(const VideoInfo &info) {
_video = std::make_shared<VideoInfo>(info); _video = std::make_shared<VideoInfo>(info);
switch (info.codecId){ return addTrack(Factory::getTrackByCodecId(info.codecId));
case CodecH265 : return addTrack(std::make_shared<H265Track>());
case CodecH264 : return addTrack(std::make_shared<H264Track>());
default: WarnL << "不支持该类型的视频编码类型:" << info.codecId; return false;
}
} }
bool DevChannel::initAudio(const AudioInfo &info) { bool DevChannel::initAudio(const AudioInfo &info) {
_audio = std::make_shared<AudioInfo>(info); _audio = std::make_shared<AudioInfo>(info);
switch (info.codecId) { return addTrack(Factory::getTrackByCodecId(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit));
case CodecAAC : return addTrack(std::make_shared<AACTrack>());
case CodecG711A :
case CodecG711U : return addTrack(std::make_shared<G711Track>(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit));
case CodecOpus : return addTrack(std::make_shared<OpusTrack>());
default: WarnL << "不支持该类型的音频编码类型:" << info.codecId; return false;
}
} }
bool DevChannel::inputFrame(const Frame::Ptr &frame) { bool DevChannel::inputFrame(const Frame::Ptr &frame) {

View File

@ -9,8 +9,8 @@
*/ */
#include "MediaSink.h" #include "MediaSink.h"
#include "Extension/AAC.h"
#include "Common/config.h" #include "Common/config.h"
#include "Extension/Factory.h"
using namespace std; using namespace std;
@ -226,16 +226,16 @@ static uint8_t s_mute_adts[] = {0xff, 0xf1, 0x6c, 0x40, 0x2d, 0x3f, 0xfc, 0x00,
0xc5, 0x97, 0x39, 0x6a, 0xb8, 0xa2, 0x55, 0xa8, 0xf8}; 0xc5, 0x97, 0x39, 0x6a, 0xb8, 0xa2, 0x55, 0xa8, 0xf8};
#define MUTE_ADTS_DATA s_mute_adts #define MUTE_ADTS_DATA s_mute_adts
#define MUTE_ADTS_DATA_LEN sizeof(s_mute_adts)
#define MUTE_ADTS_DATA_MS 128 #define MUTE_ADTS_DATA_MS 128
static uint8_t ADTS_CONFIG[2] = { 0x15, 0x88 };
bool MuteAudioMaker::inputFrame(const Frame::Ptr &frame) { bool MuteAudioMaker::inputFrame(const Frame::Ptr &frame) {
if (frame->getTrackType() == TrackVideo) { if (frame->getTrackType() == TrackVideo) {
auto audio_idx = frame->dts() / MUTE_ADTS_DATA_MS; auto audio_idx = frame->dts() / MUTE_ADTS_DATA_MS;
if (_audio_idx != audio_idx) { if (_audio_idx != audio_idx) {
_audio_idx = audio_idx; _audio_idx = audio_idx;
auto aacFrame = std::make_shared<FrameToCache<FrameFromPtr>>(CodecAAC, (char *) MUTE_ADTS_DATA, MUTE_ADTS_DATA_LEN, auto aacFrame = std::make_shared<FrameToCache<FrameFromPtr>>(CodecAAC, (char *) MUTE_ADTS_DATA, sizeof(s_mute_adts),
_audio_idx * MUTE_ADTS_DATA_MS, 0, ADTS_HEADER_LEN); _audio_idx * MUTE_ADTS_DATA_MS, 0, 7);
return FrameDispatcher::inputFrame(aacFrame); return FrameDispatcher::inputFrame(aacFrame);
} }
} }
@ -249,7 +249,8 @@ bool MediaSink::addMuteAudioTrack() {
if (_track_map.find(TrackAudio) != _track_map.end()) { if (_track_map.find(TrackAudio) != _track_map.end()) {
return false; return false;
} }
auto audio = std::make_shared<AACTrack>(MUTE_ADTS_DATA, ADTS_HEADER_LEN); auto audio = Factory::getTrackByCodecId(CodecAAC);
audio->setExtraData(ADTS_CONFIG, 2);
_track_map[audio->getTrackType()] = std::make_pair(audio, true); _track_map[audio->getTrackType()] = std::make_pair(audio, true);
audio->addDelegate([this](const Frame::Ptr &frame) { audio->addDelegate([this](const Frame::Ptr &frame) {
return onTrackFrame(frame); return onTrackFrame(frame);

View File

@ -244,8 +244,6 @@ AACTrack::AACTrack(const string &aac_cfg) {
update(); update();
} }
AACTrack::AACTrack(const uint8_t *adts, size_t size) : AACTrack(makeAacConfig(adts, size)) {}
CodecId AACTrack::getCodecId() const { CodecId AACTrack::getCodecId() const {
return CodecAAC; return CodecAAC;
} }

View File

@ -17,8 +17,6 @@
namespace mediakit{ namespace mediakit{
int dumpAacConfig(const std::string &config, size_t length, uint8_t *out, size_t out_size);
/** /**
* aac音频通道 * aac音频通道
*/ */
@ -33,11 +31,6 @@ public:
*/ */
AACTrack(const std::string &aac_cfg); AACTrack(const std::string &aac_cfg);
/**
* aac adts头
*/
AACTrack(const uint8_t *adts, size_t size);
bool ready() const override; bool ready() const override;
CodecId getCodecId() const override; CodecId getCodecId() const override;
int getAudioChannel() const override; int getAudioChannel() const override;

View File

@ -29,6 +29,7 @@
#include "Common/config.h" #include "Common/config.h"
using namespace std; using namespace std;
using namespace toolkit;
namespace mediakit{ namespace mediakit{
@ -293,5 +294,39 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) {
} }
} }
static size_t aacPrefixSize(const char *data, size_t bytes) {
uint8_t *ptr = (uint8_t *)data;
size_t prefix = 0;
if (!(bytes > ADTS_HEADER_LEN && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0)) {
return 0;
}
return ADTS_HEADER_LEN;
}
Frame::Ptr Factory::getFrameFromPtr(CodecId codec, const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
switch (codec) {
case CodecH264: return std::make_shared<H264FrameNoCacheAble>((char *)data, bytes, dts, pts, prefixSize(data, bytes));
case CodecH265: return std::make_shared<H265FrameNoCacheAble>((char *)data, bytes, dts, pts, prefixSize(data, bytes));
case CodecAAC: return std::make_shared<FrameFromPtr>(codec, (char *)data, bytes, dts, pts, aacPrefixSize(data, bytes));
case CodecOpus:
case CodecG711A:
case CodecG711U: return std::make_shared<FrameFromPtr>(codec, (char *)data, bytes, dts, pts);
default: return nullptr;
}
}
Frame::Ptr Factory::getFrameFromBuffer(CodecId codec, const Buffer::Ptr &data, uint64_t dts, uint64_t pts) {
switch (codec) {
case CodecH264: return std::make_shared<FrameFromBuffer<H264FrameNoCacheAble>>(data, dts, pts, prefixSize(data->data(), data->size()), 0);
case CodecH265: return std::make_shared<FrameFromBuffer<H265FrameNoCacheAble>>(data, dts, pts, prefixSize(data->data(), data->size()), 0);
case CodecJPEG: return std::make_shared<JPEGFrame>(data, dts);
case CodecAAC: return std::make_shared<FrameFromBuffer<FrameFromPtr>>(data, dts, pts, aacPrefixSize(data->data(), data->size()), 0, codec);
case CodecOpus:
case CodecG711A:
case CodecG711U: return std::make_shared<FrameFromBuffer<FrameFromPtr>>(data, dts, pts, 0, 0, codec);
default: return nullptr;
}
}
}//namespace mediakit }//namespace mediakit

View File

@ -14,6 +14,7 @@
#include <string> #include <string>
#include "Rtmp/amf.h" #include "Rtmp/amf.h"
#include "Extension/Track.h" #include "Extension/Track.h"
#include "Extension/Frame.h"
#include "Rtsp/RtpCodec.h" #include "Rtsp/RtpCodec.h"
#include "Rtmp/RtmpCodec.h" #include "Rtmp/RtmpCodec.h"
@ -85,6 +86,9 @@ public:
* codecId获取rtmp的codec描述 * codecId获取rtmp的codec描述
*/ */
static AMFValue getAmfByCodecId(CodecId codecId); static AMFValue getAmfByCodecId(CodecId codecId);
static Frame::Ptr getFrameFromPtr(CodecId codec, const char *data, size_t size, uint64_t dts, uint64_t pts);
static Frame::Ptr getFrameFromBuffer(CodecId codec, const toolkit::Buffer::Ptr &data, uint64_t dts, uint64_t pts);
}; };
}//namespace mediakit }//namespace mediakit

View File

@ -97,6 +97,8 @@ CodecId getCodecByMpegId(int mpeg_id) {
#define XX(name, type, value, str, mpeg_id, mp4_id) case mpeg_id : return name; #define XX(name, type, value, str, mpeg_id, mp4_id) case mpeg_id : return name;
CODEC_MAP(XX) CODEC_MAP(XX)
#undef XX #undef XX
// 海康的 PS 流中会有0xBD 的包
case 0xBD: return CodecInvalid;
default : WarnL << "Unsupported mpeg: " << mpeg_id; return CodecInvalid; default : WarnL << "Unsupported mpeg: " << mpeg_id; return CodecInvalid;
} }
} }

View File

@ -251,9 +251,9 @@ template <typename Parent>
class FrameInternalBase : public Parent { class FrameInternalBase : public Parent {
public: public:
using Ptr = std::shared_ptr<FrameInternalBase>; 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) FrameInternalBase(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(ptr, size, dts, pts, prefix_size) {
_parent_frame = parent_frame; _parent_frame = std::move(parent_frame);
} }
bool cacheAble() const override { return _parent_frame->cacheAble(); } bool cacheAble() const override { return _parent_frame->cacheAble(); }

View File

@ -10,7 +10,6 @@
#include "PlayerProxy.h" #include "PlayerProxy.h"
#include "Common/config.h" #include "Common/config.h"
#include "Extension/AAC.h"
#include "Rtmp/RtmpMediaSource.h" #include "Rtmp/RtmpMediaSource.h"
#include "Rtmp/RtmpPlayer.h" #include "Rtmp/RtmpPlayer.h"
#include "Rtsp/RtspMediaSource.h" #include "Rtsp/RtspMediaSource.h"

View File

@ -11,9 +11,6 @@
#ifdef ENABLE_MP4 #ifdef ENABLE_MP4
#include "MP4Demuxer.h" #include "MP4Demuxer.h"
#include "Util/logger.h" #include "Util/logger.h"
#include "Extension/H265.h"
#include "Extension/H264.h"
#include "Extension/JPEG.h"
#include "Extension/Factory.h" #include "Extension/Factory.h"
using namespace std; using namespace std;
@ -143,8 +140,8 @@ Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int6
Frame::Ptr ret; Frame::Ptr ret;
auto codec = it->second->getCodecId(); auto codec = it->second->getCodecId();
switch (codec) { switch (codec) {
case CodecH264 : case CodecH264:
case CodecH265 : { case CodecH265: {
auto bytes = buf->size(); auto bytes = buf->size();
auto data = buf->data(); auto data = buf->data();
auto offset = 0u; auto offset = 0u;
@ -158,21 +155,12 @@ Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int6
memcpy(data + offset, "\x00\x00\x00\x01", 4); memcpy(data + offset, "\x00\x00\x00\x01", 4);
offset += (frame_len + 4); offset += (frame_len + 4);
} }
if (codec == CodecH264) { ret = Factory::getFrameFromBuffer(codec, buf, dts, pts);
ret = std::make_shared<FrameFromBuffer<H264FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
break;
}
ret = std::make_shared<FrameFromBuffer<H265FrameNoCacheAble> >(buf, (uint64_t)dts, (uint64_t)pts, 4, 0);
break;
}
case CodecJPEG: {
ret = std::make_shared<JPEGFrame>(buf, (uint64_t)dts, 0, 0);
break; break;
} }
default: { default: {
ret = std::make_shared<FrameFromBuffer<FrameFromPtr>>(buf, (uint64_t)dts, (uint64_t)pts, 0, 0, codec); ret = Factory::getFrameFromBuffer(codec, buf, dts, pts);
break; break;
} }
} }

View File

@ -11,11 +11,6 @@
#include "Decoder.h" #include "Decoder.h"
#include "PSDecoder.h" #include "PSDecoder.h"
#include "TSDecoder.h" #include "TSDecoder.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/AAC.h"
#include "Extension/G711.h"
#include "Extension/Opus.h"
#include "Extension/Factory.h" #include "Extension/Factory.h"
#if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS) #if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS)
@ -101,72 +96,25 @@ void DecoderImp::onStream(int stream, int codecid, const void *extra, size_t byt
} }
} }
void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t dts,const void *data,size_t bytes) { void DecoderImp::onDecode(int stream, int codecid, int flags, int64_t pts, int64_t dts, const void *data, size_t bytes) {
pts /= 90; pts /= 90;
dts /= 90; dts /= 90;
switch (codecid) { auto codec = getCodecByMpegId(codecid);
case PSI_STREAM_H264: { if (codec == CodecInvalid) {
if (!_tracks[TrackVideo]) { return;
onTrack(std::make_shared<H264Track>());
} }
auto frame = std::make_shared<H264FrameNoCacheAble>((char *) data, bytes, (uint64_t)dts, (uint64_t)pts, prefixSize((char *) data, bytes)); if (!_tracks[getTrackType(codec)]) {
_merger.inputFrame(frame,[this](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) { onTrack(Factory::getTrackByCodecId(codec, 8000, 1, 16));
onFrame(std::make_shared<FrameFromBuffer<H264FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0)); }
// TODO 支持多track
auto frame = Factory::getFrameFromPtr(codec, (char *) data, bytes, dts, pts);
if (getTrackType(codec) == TrackVideo) {
_merger.inputFrame(frame, [&](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) {
onFrame(Factory::getFrameFromBuffer(codec, buffer, dts, pts));
}); });
break; } else {
} onFrame(frame);
case PSI_STREAM_H265: {
if (!_tracks[TrackVideo]) {
onTrack(std::make_shared<H265Track>());
}
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<FrameFromBuffer<H265FrameNoCacheAble> >(buffer, dts, pts, prefixSize(buffer->data(), buffer->size()), 0));
});
break;
}
case PSI_STREAM_MPEG4_AAC :
case PSI_STREAM_AAC: {
uint8_t *ptr = (uint8_t *)data;
if(!(bytes > 7 && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0)){
//这不是aac
break;
}
if (!_tracks[TrackAudio]) {
onTrack(std::make_shared<AACTrack>());
}
onFrame(std::make_shared<FrameFromPtr>(CodecAAC, (char *) data, bytes, (uint64_t)dts, 0, ADTS_HEADER_LEN));
break;
}
case PSI_STREAM_AUDIO_G711A:
case PSI_STREAM_AUDIO_G711U: {
auto codec = codecid == PSI_STREAM_AUDIO_G711A ? CodecG711A : CodecG711U;
if (!_tracks[TrackAudio]) {
//G711传统只支持 8000/1/16的规格FFmpeg貌似做了扩展但是这里不管它了
onTrack(std::make_shared<G711Track>(codec, 8000, 1, 16));
}
onFrame(std::make_shared<FrameFromPtr>(codec, (char *) data, bytes, (uint64_t)dts));
break;
}
case PSI_STREAM_AUDIO_OPUS: {
if (!_tracks[TrackAudio]) {
onTrack(std::make_shared<OpusTrack>());
}
onFrame(std::make_shared<FrameFromPtr>(CodecOpus, (char *) data, bytes, (uint64_t)dts));
break;
}
default:
// 海康的 PS 流中会有 codecid 为 0xBD 的包
if (codecid != 0 && codecid != 0xBD) {
WarnL << "Unsupported codec type:" << codecid;
}
break;
} }
} }
#else #else
@ -175,6 +123,9 @@ void DecoderImp::onStream(int stream,int codecid,const void *extra,size_t bytes,
#endif #endif
void DecoderImp::onTrack(const Track::Ptr &track) { void DecoderImp::onTrack(const Track::Ptr &track) {
if (!track) {
return;
}
if (!_tracks[track->getTrackType()]) { if (!_tracks[track->getTrackType()]) {
_tracks[track->getTrackType()] = track; _tracks[track->getTrackType()] = track;
_sink->addTrack(track); _sink->addTrack(track);
@ -183,7 +134,9 @@ void DecoderImp::onTrack(const Track::Ptr &track) {
} }
void DecoderImp::onFrame(const Frame::Ptr &frame) { void DecoderImp::onFrame(const Frame::Ptr &frame) {
if (frame) {
_sink->inputFrame(frame); _sink->inputFrame(frame);
}
} }
}//namespace mediakit }//namespace mediakit