211 lines
6.4 KiB
C++
211 lines
6.4 KiB
C++
|
|
/*
|
|||
|
|
* 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 <set>
|
|||
|
|
#include <map>
|
|||
|
|
#include <string>
|
|||
|
|
#include <vector>
|
|||
|
|
#include <memory>
|
|||
|
|
#include <iostream>
|
|||
|
|
#include <iomanip>
|
|||
|
|
#include <cassert>
|
|||
|
|
#include "Extension/Frame.h"
|
|||
|
|
|
|||
|
|
namespace mediakit {
|
|||
|
|
|
|||
|
|
class RtpMap {
|
|||
|
|
public:
|
|||
|
|
using Ptr = std::shared_ptr<RtpMap>;
|
|||
|
|
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<std::string /*key*/, std::string /*value*/> &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<std::string /*key*/, std::string /*value*/> _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
|