/* * Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved. * * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit). * * Use of this source code is governed by MIT-like 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. */ #ifndef ZLMEDIAKIT_RTPMAP_H #define ZLMEDIAKIT_RTPMAP_H #include #include #include #include #include #include #include #include #include "Extension/Frame.h" namespace mediakit { class RtpMap { public: using Ptr = std::shared_ptr; RtpMap(std::string code_name, uint8_t payload, uint32_t clock_rate) : _code_name(std::move(code_name)) , _payload(payload) , _clock_rate(clock_rate) {} virtual ~RtpMap() = default; virtual TrackType getType() = 0; const std::map &getFmtp() const { return _fmtp; } const std::string &getCodeName() const { return _code_name; } uint8_t getPayload() const { return _payload; } uint32_t getClockRate() const { return _clock_rate; } protected: std::map _fmtp; std::string _code_name; uint8_t _payload; uint32_t _clock_rate; }; class VideoRtpMap : public RtpMap { public: VideoRtpMap(std::string code_name, uint8_t payload, uint32_t clock_rate) : RtpMap(std::move(code_name), payload, clock_rate) {}; TrackType getType() override { return TrackVideo; } }; class AudioRtpMap : public RtpMap { public: AudioRtpMap( std::string code_name, uint8_t payload, uint32_t clock_rate) : RtpMap(std::move(code_name), payload, clock_rate) {}; TrackType getType() override { return TrackAudio; }; }; #define H264_PROFILE_IDC_MAP(XX) \ XX(PROFILE_H264_BASELINE, 66, "baseline") \ XX(PROFILE_H264_MAIN, 77, "main") \ XX(PROFILE_H264_HIGH, 100, "high") \ XX(PROFILE_H264_HIGH10, 110, "high10") \ XX(PROFILE_H264_HIGH422, 122, "high422") \ XX(PROFILE_H264_HIGH444, 244, "high444") \ typedef enum { H264ProfileIdcInvalid = -1, #define XX(name, value, str) name = value, H264_PROFILE_IDC_MAP(XX) #undef XX H264ProfileIdcMax } H264ProfileIdc; #define H264_PROFILE_LEVEL_MAP(XX) \ XX(10) \ XX(20) \ XX(30) \ XX(31) \ XX(40) \ XX(41) \ XX(50) \ XX(51) typedef enum { H264ProfileLevelInvalid = -1, #define XX(value) H264_PROFILE_LEVEL_##value = value, H264_PROFILE_LEVEL_MAP(XX) #undef XX H264ProfileLevelMax } H264ProfileLevel; class H264RtpMap : public VideoRtpMap { public: H264RtpMap(uint8_t payload, uint32_t clock_rate, H264ProfileIdc profile_idc) : VideoRtpMap("H264", payload, clock_rate) , _profile_idc(profile_idc) { _fmtp.emplace("level-asymmetry-allowed", "1"); _fmtp.emplace("packetization-mode", "1"); toolkit::_StrPrinter printer; printer << std::setw(2) << std::setfill('0') << std::hex << _profile_idc; printer << std::setw(2) << std::setfill('0') << std::hex << _profile_iop; printer << std::setw(2) << std::setfill('0') << std::hex << _profile_level; _fmtp.emplace("profile-level-id", printer); }; private: H264ProfileIdc _profile_idc; int _profile_iop = 0; H264ProfileLevel _profile_level = H264_PROFILE_LEVEL_31; }; #define H265_PROFILE_IDC_MAP(XX) \ XX(PROFILE_H265_MAIN, 1, "main") \ XX(PROFILE_H265_MAIN10, 2, "main10") \ XX(PROFILE_H265_MAINSTILL, 3, "mainstill") \ XX(PROFILE_H265_RANGE_EXTS, 4, "RangeExtensions") \ XX(PROFILE_H265_HIGH_THROUGHPUT, 5, "HighThroughput") \ XX(PROFILE_H265_MULTIVIEW, 6, "MultiviewMain") \ XX(PROFILE_H265_SCALABLE_MAIN, 7, "ScalableMain") \ XX(PROFILE_H265_3DMAIN, 8, "3dMain") \ XX(PROFILE_H265_SCREEN, 9, "ScreenContentCoding") \ XX(PROFILE_H265_SCALABLE_RANGE_EXTENSIONS, 10, "ScalableRangeExtensions") \ XX(PROFILE_H265_HIGH_SCREEN, 11, "HighThroughputScreenContentCoding") typedef enum { H265ProfileIdcInvalid = -1, #define XX(name, value, str) name = value, H265_PROFILE_IDC_MAP(XX) #undef XX H265ProfileIdcMax } H265ProfileIdc; #define H265_PROFILE_LEVEL_MAP(XX) \ XX(30) \ XX(60) \ XX(63) \ XX(90) \ XX(93) \ XX(120) \ XX(123) \ XX(150) \ XX(153) \ XX(156) \ XX(180) \ XX(183) \ XX(186) typedef enum { H265ProfileLevelInvalid = -1, #define XX(value) H265_PROFILE_LEVEL_##value = value, H265_PROFILE_LEVEL_MAP(XX) #undef XX H265ProfileLevelMax } H265ProfileLevel; class H265RtpMap : public VideoRtpMap { public: H265RtpMap(uint8_t payload, uint32_t clock_rate, H265ProfileIdc profile_idc) : VideoRtpMap("H265", payload, clock_rate) , _profile_idc(profile_idc) { _fmtp.emplace("level-asymmetry-allowed", "1"); _fmtp.emplace("packetization-mode", "1"); _fmtp.emplace("profile-id", std::to_string(_profile_idc)); _fmtp.emplace("tier-flag", std::to_string(_tier_flag)); _fmtp.emplace("level-id", std::to_string(_profile_level)); } private: H265ProfileIdc _profile_idc; int _tier_flag = 0; // 0: main tier; 1: high tier H265ProfileLevel _profile_level = H265_PROFILE_LEVEL_30; }; class VP9RtpMap : public VideoRtpMap { public: VP9RtpMap(uint8_t payload, uint32_t clock_rate, int profile_id) : VideoRtpMap("VP9", payload, clock_rate) , _profile_id(profile_id) { _fmtp.emplace("profile-id", std::to_string(_profile_id)); }; private: int _profile_id = 1; // 0-3 }; class AV1RtpMap : public VideoRtpMap { public: AV1RtpMap(uint8_t payload, uint32_t clock_rate, int profile_id) : VideoRtpMap("AV1", payload, clock_rate) , _profile_id(profile_id) { // a=fmtp:45 level-idx=5;profile=0;tier=0 _fmtp.emplace("profile-id", std::to_string(_profile_id)); }; private: int _profile_id = 0; // 0-2 }; } // namespace mediakit #endif // ZLMEDIAKIT_RTPMAP_H