/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef CODEC_CONFIG_H_ #define CODEC_CONFIG_H_ #include #include #include "common/EncodingConstraints.h" namespace mozilla { /** * Minimalistic Audio Codec Config Params */ struct AudioCodecConfig { /* * The data-types for these properties mimic the * corresponding webrtc::CodecInst data-types. */ int mType; std::string mName; int mFreq; int mChannels; bool mFECEnabled; bool mDtmfEnabled; uint32_t mFrameSizeMs; uint32_t mMaxFrameSizeMs; uint32_t mMinFrameSizeMs; // OPUS-specific bool mDTXEnabled; uint32_t mMaxAverageBitrate; int mMaxPlaybackRate; bool mCbrEnabled; AudioCodecConfig(int type, std::string name, int freq, int channels, bool FECEnabled) : mType(type), mName(name), mFreq(freq), mChannels(channels), mFECEnabled(FECEnabled), mDtmfEnabled(false), mFrameSizeMs(0), mMaxFrameSizeMs(0), mMinFrameSizeMs(0), mDTXEnabled(false), mMaxAverageBitrate(0), mMaxPlaybackRate(0), mCbrEnabled(false) {} bool operator==(const AudioCodecConfig& aOther) const { return mType == aOther.mType && mName == aOther.mName && mFreq == aOther.mFreq && mChannels == aOther.mChannels && mFECEnabled == aOther.mFECEnabled && mDtmfEnabled == aOther.mDtmfEnabled && mFrameSizeMs == aOther.mFrameSizeMs && mMaxFrameSizeMs == aOther.mMaxFrameSizeMs && mMinFrameSizeMs == aOther.mMinFrameSizeMs && mDTXEnabled == aOther.mDTXEnabled && mMaxAverageBitrate == aOther.mMaxAverageBitrate && mMaxPlaybackRate == aOther.mMaxPlaybackRate && mCbrEnabled == aOther.mCbrEnabled; } }; /* * Minimalistic video codec configuration * More to be added later depending on the use-case */ #define MAX_SPROP_LEN 128 // used for holding SDP negotiation results struct VideoCodecConfigH264 { char sprop_parameter_sets[MAX_SPROP_LEN]; int packetization_mode; int profile_level_id; int tias_bw; bool operator==(const VideoCodecConfigH264& aOther) const { return strncmp(sprop_parameter_sets, aOther.sprop_parameter_sets, MAX_SPROP_LEN) == 0 && packetization_mode == aOther.packetization_mode && profile_level_id == aOther.profile_level_id && tias_bw == aOther.tias_bw; } }; // class so the std::strings can get freed more easily/reliably class VideoCodecConfig { public: /* * The data-types for these properties mimic the * corresponding webrtc::VideoCodec data-types. */ int mType; // payload type std::string mName; std::vector mAckFbTypes; std::vector mNackFbTypes; std::vector mCcmFbTypes; // Don't pass mOtherFbTypes from JsepVideoCodecDescription because we'd have // to drag SdpRtcpFbAttributeList::Feedback along too. bool mRembFbSet; bool mFECFbSet; bool mTransportCCFbSet; int mULPFECPayloadType; int mREDPayloadType; int mREDRTXPayloadType; int mRTXPayloadType; uint32_t mTias; EncodingConstraints mEncodingConstraints; struct Encoding { std::string rid; EncodingConstraints constraints; bool active = true; // TODO(bug 1744116): Use = default here bool operator==(const Encoding& aOther) const { return rid == aOther.rid && constraints == aOther.constraints && active == aOther.active; } }; std::vector mEncodings; std::string mSpropParameterSets; uint8_t mProfile; uint8_t mConstraints; uint8_t mLevel; uint8_t mPacketizationMode; // TODO: add external negotiated SPS/PPS // TODO(bug 1744116): Use = default here bool operator==(const VideoCodecConfig& aRhs) const { return mType == aRhs.mType && mName == aRhs.mName && mAckFbTypes == aRhs.mAckFbTypes && mNackFbTypes == aRhs.mNackFbTypes && mCcmFbTypes == aRhs.mCcmFbTypes && mRembFbSet == aRhs.mRembFbSet && mFECFbSet == aRhs.mFECFbSet && mTransportCCFbSet == aRhs.mTransportCCFbSet && mULPFECPayloadType == aRhs.mULPFECPayloadType && mREDPayloadType == aRhs.mREDPayloadType && mREDRTXPayloadType == aRhs.mREDRTXPayloadType && mRTXPayloadType == aRhs.mRTXPayloadType && mTias == aRhs.mTias && mEncodingConstraints == aRhs.mEncodingConstraints && mEncodings == aRhs.mEncodings && mSpropParameterSets == aRhs.mSpropParameterSets && mProfile == aRhs.mProfile && mConstraints == aRhs.mConstraints && mLevel == aRhs.mLevel && mPacketizationMode == aRhs.mPacketizationMode; } VideoCodecConfig(int type, std::string name, const EncodingConstraints& constraints, const struct VideoCodecConfigH264* h264 = nullptr) : mType(type), mName(name), mRembFbSet(false), mFECFbSet(false), mTransportCCFbSet(false), mULPFECPayloadType(-1), mREDPayloadType(-1), mREDRTXPayloadType(-1), mRTXPayloadType(-1), mTias(0), mEncodingConstraints(constraints), mProfile(0x42), mConstraints(0xE0), mLevel(0x0C), mPacketizationMode(1) { if (h264) { mProfile = (h264->profile_level_id & 0x00FF0000) >> 16; mConstraints = (h264->profile_level_id & 0x0000FF00) >> 8; mLevel = (h264->profile_level_id & 0x000000FF); mPacketizationMode = h264->packetization_mode; mSpropParameterSets = h264->sprop_parameter_sets; } } bool ResolutionEquals(const VideoCodecConfig& aConfig) const { if (mEncodings.size() != aConfig.mEncodings.size()) { return false; } for (size_t i = 0; i < mEncodings.size(); ++i) { if (!mEncodings[i].constraints.ResolutionEquals( aConfig.mEncodings[i].constraints)) { return false; } } return true; } // Nothing seems to use this right now. Do we intend to support this // someday? bool RtcpFbAckIsSet(const std::string& type) const { for (auto i = mAckFbTypes.begin(); i != mAckFbTypes.end(); ++i) { if (*i == type) { return true; } } return false; } bool RtcpFbNackIsSet(const std::string& type) const { for (auto i = mNackFbTypes.begin(); i != mNackFbTypes.end(); ++i) { if (*i == type) { return true; } } return false; } bool RtcpFbCcmIsSet(const std::string& type) const { for (auto i = mCcmFbTypes.begin(); i != mCcmFbTypes.end(); ++i) { if (*i == type) { return true; } } return false; } bool RtcpFbRembIsSet() const { return mRembFbSet; } bool RtcpFbFECIsSet() const { return mFECFbSet; } bool RtcpFbTransportCCIsSet() const { return mTransportCCFbSet; } bool RtxPayloadTypeIsSet() const { return mRTXPayloadType != -1; } }; } // namespace mozilla #endif