ZLMediaKit/src/Extension/Factory.cpp

213 lines
7.2 KiB
C++
Raw Normal View History

2018-10-25 10:00:17 +08:00
/*
2023-12-09 16:23:51 +08:00
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
2018-10-25 10:00:17 +08:00
*
2023-12-09 16:23:51 +08:00
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
2018-10-25 10:00:17 +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.
2018-10-25 10:00:17 +08:00
*/
2018-10-24 09:23:57 +08:00
#include "Factory.h"
2020-04-04 22:54:49 +08:00
#include "Rtmp/Rtmp.h"
#include "Common/config.h"
2018-10-24 09:23:57 +08:00
using namespace std;
2023-12-09 16:23:51 +08:00
using namespace toolkit;
2023-12-10 10:21:40 +08:00
namespace mediakit {
static std::unordered_map<int, const CodecPlugin *> s_plugins;
extern CodecPlugin h264_plugin;
extern CodecPlugin h265_plugin;
extern CodecPlugin jpeg_plugin;
extern CodecPlugin aac_plugin;
extern CodecPlugin opus_plugin;
extern CodecPlugin g711a_plugin;
extern CodecPlugin g711u_plugin;
extern CodecPlugin l16_plugin;
REGISTER_CODEC(h264_plugin);
REGISTER_CODEC(h265_plugin);
REGISTER_CODEC(jpeg_plugin);
REGISTER_CODEC(aac_plugin);
REGISTER_CODEC(opus_plugin);
REGISTER_CODEC(g711a_plugin)
REGISTER_CODEC(g711u_plugin);
REGISTER_CODEC(l16_plugin);
void Factory::registerPlugin(const CodecPlugin &plugin) {
InfoL << "Load codec: " << getCodecName(plugin.getCodec());
s_plugins[(int)(plugin.getCodec())] = &plugin;
}
2018-10-24 17:17:55 +08:00
2018-10-26 09:56:29 +08:00
Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) {
2021-08-23 21:15:19 +08:00
auto codec = getCodecId(track->_codec);
if (codec == CodecInvalid) {
2023-12-10 10:21:40 +08:00
// 根据传统的payload type 获取编码类型以及采样率等信息
2021-08-23 21:15:19 +08:00
codec = RtpPayload::getCodecId(track->_pt);
}
2023-12-10 10:21:40 +08:00
auto it = s_plugins.find(codec);
if (it == s_plugins.end()) {
WarnL << "Unsupported codec: " << track->getName();
return nullptr;
2020-04-18 23:00:48 +08:00
}
2023-12-10 10:21:40 +08:00
return it->second->getTrackBySdp(track);
2018-10-24 18:41:37 +08:00
}
2023-12-10 10:21:40 +08:00
Track::Ptr Factory::getTrackByAbstractTrack(const Track::Ptr &track) {
auto codec = track->getCodecId();
2023-12-10 10:21:40 +08:00
if (track->getTrackType() == TrackVideo) {
return getTrackByCodecId(codec);
}
2023-12-10 10:21:40 +08:00
auto audio_track = dynamic_pointer_cast<AudioTrack>(track);
return getTrackByCodecId(codec, audio_track->getAudioSampleRate(), audio_track->getAudioChannel(), audio_track->getAudioSampleBit());
}
2023-12-10 10:21:40 +08:00
RtpCodec::Ptr Factory::getRtpEncoderByCodecId(CodecId codec, uint8_t pt) {
auto it = s_plugins.find(codec);
if (it == s_plugins.end()) {
WarnL << "Unsupported codec: " << getCodecName(codec);
return nullptr;
}
2023-12-10 10:21:40 +08:00
return it->second->getRtpEncoderByCodecId(pt);
}
2023-12-10 10:21:40 +08:00
RtpCodec::Ptr Factory::getRtpDecoderByCodecId(CodecId codec) {
auto it = s_plugins.find(codec);
if (it == s_plugins.end()) {
WarnL << "Unsupported codec: " << getCodecName(codec);
return nullptr;
2018-10-24 09:23:57 +08:00
}
2023-12-10 10:21:40 +08:00
return it->second->getRtpDecoderByCodecId();
2018-10-24 09:23:57 +08:00
}
2018-10-30 17:11:36 +08:00
/////////////////////////////rtmp相关///////////////////////////////////////////
2020-04-18 18:46:20 +08:00
static CodecId getVideoCodecIdByAmf(const AMFValue &val){
2020-08-01 10:22:12 +08:00
if (val.type() == AMF_STRING) {
2018-10-30 17:11:36 +08:00
auto str = val.as_string();
2020-08-01 10:22:12 +08:00
if (str == "avc1") {
2018-10-30 17:11:36 +08:00
return CodecH264;
}
2020-08-01 10:22:12 +08:00
if (str == "hev1" || str == "hvc1") {
2019-12-12 22:25:55 +08:00
return CodecH265;
}
2023-12-10 10:21:40 +08:00
WarnL << "Unsupported codec: " << str;
2018-10-30 17:11:36 +08:00
return CodecInvalid;
}
2020-08-01 10:22:12 +08:00
if (val.type() != AMF_NULL) {
auto type_id = (RtmpVideoCodec)val.as_integer();
2020-08-01 10:22:12 +08:00
switch (type_id) {
case RtmpVideoCodec::h264: return CodecH264;
case RtmpVideoCodec::fourcc_hevc:
case RtmpVideoCodec::h265: return CodecH265;
case RtmpVideoCodec::fourcc_av1: return CodecAV1;
case RtmpVideoCodec::fourcc_vp9: return CodecVP9;
2023-12-10 10:21:40 +08:00
default: WarnL << "Unsupported codec: " << (int)type_id; return CodecInvalid;
2018-10-30 17:11:36 +08:00
}
}
return CodecInvalid;
}
2023-12-10 10:21:40 +08:00
Track::Ptr Factory::getTrackByCodecId(CodecId codec, int sample_rate, int channels, int sample_bit) {
auto it = s_plugins.find(codec);
if (it == s_plugins.end()) {
WarnL << "Unsupported codec: " << getCodecName(codec);
return nullptr;
2020-04-18 22:13:11 +08:00
}
2023-12-10 10:21:40 +08:00
return it->second->getTrackByCodecId(sample_rate, channels, sample_bit);
2020-04-18 22:13:11 +08:00
}
2020-04-18 18:46:20 +08:00
Track::Ptr Factory::getVideoTrackByAmf(const AMFValue &amf) {
CodecId codecId = getVideoCodecIdByAmf(amf);
if(codecId == CodecInvalid){
return nullptr;
}
return getTrackByCodecId(codecId);
}
2018-10-30 17:11:36 +08:00
2020-04-18 18:46:20 +08:00
static CodecId getAudioCodecIdByAmf(const AMFValue &val) {
if (val.type() == AMF_STRING) {
auto str = val.as_string();
if (str == "mp4a") {
return CodecAAC;
}
2023-12-10 10:21:40 +08:00
WarnL << "Unsupported codec: " << str;
return CodecInvalid;
}
if (val.type() != AMF_NULL) {
auto type_id = (RtmpAudioCodec)val.as_integer();
switch (type_id) {
case RtmpAudioCodec::aac : return CodecAAC;
case RtmpAudioCodec::g711a : return CodecG711A;
case RtmpAudioCodec::g711u : return CodecG711U;
case RtmpAudioCodec::opus : return CodecOpus;
2023-12-10 10:21:40 +08:00
default : WarnL << "Unsupported codec: " << (int)type_id; return CodecInvalid;
}
}
return CodecInvalid;
}
2020-04-18 22:13:11 +08:00
Track::Ptr Factory::getAudioTrackByAmf(const AMFValue& amf, int sample_rate, int channels, int sample_bit){
2020-04-18 18:46:20 +08:00
CodecId codecId = getAudioCodecIdByAmf(amf);
if (codecId == CodecInvalid) {
return nullptr;
}
2020-04-18 22:13:11 +08:00
return getTrackByCodecId(codecId, sample_rate, channels, sample_bit);
2020-04-18 18:46:20 +08:00
}
2023-12-09 16:23:51 +08:00
RtmpCodec::Ptr Factory::getRtmpDecoderByTrack(const Track::Ptr &track) {
2023-12-10 10:21:40 +08:00
auto it = s_plugins.find(track->getCodecId());
if (it == s_plugins.end()) {
WarnL << "Unsupported codec: " << track->getCodecName();
return nullptr;
2023-12-09 16:23:51 +08:00
}
2023-12-10 10:21:40 +08:00
return it->second->getRtmpDecoderByTrack(track);
2023-12-09 16:23:51 +08:00
}
RtmpCodec::Ptr Factory::getRtmpEncoderByTrack(const Track::Ptr &track) {
2023-12-10 10:21:40 +08:00
auto it = s_plugins.find(track->getCodecId());
if (it == s_plugins.end()) {
WarnL << "Unsupported codec: " << track->getCodecName();
return nullptr;
2018-10-24 22:03:17 +08:00
}
2023-12-10 10:21:40 +08:00
return it->second->getRtmpEncoderByTrack(track);
2018-10-24 22:03:17 +08:00
}
2018-10-25 14:49:47 +08:00
AMFValue Factory::getAmfByCodecId(CodecId codecId) {
2023-12-09 16:23:51 +08:00
GET_CONFIG(bool, enhanced, Rtmp::kEnhanced);
switch (codecId) {
case CodecAAC: return AMFValue((int)RtmpAudioCodec::aac);
case CodecH264: return AMFValue((int)RtmpVideoCodec::h264);
2023-12-09 16:23:51 +08:00
case CodecH265: return enhanced ? AMFValue((int)RtmpVideoCodec::fourcc_hevc) : AMFValue((int)RtmpVideoCodec::h265);
case CodecG711A: return AMFValue((int)RtmpAudioCodec::g711a);
case CodecG711U: return AMFValue((int)RtmpAudioCodec::g711u);
case CodecOpus: return AMFValue((int)RtmpAudioCodec::opus);
2023-12-09 16:23:51 +08:00
case CodecAV1: return AMFValue((int)RtmpVideoCodec::fourcc_av1);
case CodecVP9: return AMFValue((int)RtmpVideoCodec::fourcc_vp9);
2019-12-12 22:25:55 +08:00
default: return AMFValue(AMF_NULL);
2018-10-25 14:49:47 +08:00
}
}
2018-10-24 18:41:37 +08:00
2023-12-09 16:23:51 +08:00
Frame::Ptr Factory::getFrameFromPtr(CodecId codec, const char *data, size_t bytes, uint64_t dts, uint64_t pts) {
2023-12-10 10:21:40 +08:00
auto it = s_plugins.find(codec);
if (it == s_plugins.end()) {
WarnL << "Unsupported codec: " << getCodecName(codec);
return nullptr;
2023-12-09 16:23:51 +08:00
}
2023-12-10 10:21:40 +08:00
return it->second->getFrameFromPtr(data, bytes, dts, pts);
2023-12-09 16:23:51 +08:00
}
Frame::Ptr Factory::getFrameFromBuffer(CodecId codec, Buffer::Ptr data, uint64_t dts, uint64_t pts) {
auto frame = Factory::getFrameFromPtr(codec, data->data(), data->size(), dts, pts);
return std::make_shared<FrameCacheAble>(frame, false, std::move(data));
}
2018-10-24 17:17:55 +08:00
}//namespace mediakit