/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "media/engine/payload_type_mapper.h"

#include "api/audio_codecs/audio_format.h"
#include "common_types.h"  // NOLINT(build/include)
#include "media/base/mediaconstants.h"

namespace cricket {

webrtc::SdpAudioFormat AudioCodecToSdpAudioFormat(const AudioCodec& ac) {
  return webrtc::SdpAudioFormat(ac.name, ac.clockrate, ac.channels, ac.params);
}

PayloadTypeMapper::PayloadTypeMapper()
    // RFC 3551 reserves payload type numbers in the range 96-127 exclusively
    // for dynamic assignment. Once those are used up, it is recommended that
    // payload types unassigned by the RFC are used for dynamic payload type
    // mapping, before any static payload ids. At this point, we only support
    // mapping within the exclusive range.
    : next_unused_payload_type_(96),
      max_payload_type_(127),
      mappings_({
          // Static payload type assignments according to RFC 3551.
          {{"PCMU",   8000, 1}, 0},
          {{"GSM",    8000, 1}, 3},
          {{"G723",   8000, 1}, 4},
          {{"DVI4",   8000, 1}, 5},
          {{"DVI4",  16000, 1}, 6},
          {{"LPC",    8000, 1}, 7},
          {{"PCMA",   8000, 1}, 8},
          {{"G722",   8000, 1}, 9},
          {{"L16",   44100, 2}, 10},
          {{"L16",   44100, 1}, 11},
          {{"QCELP",  8000, 1}, 12},
          {{"CN",     8000, 1}, 13},
          // RFC 4566 is a bit ambiguous on the contents of the "encoding
          // parameters" field, which, for audio, encodes the number of
          // channels. It is "optional and may be omitted if the number of
          // channels is one". Does that necessarily imply that an omitted
          // encoding parameter means one channel?  Since RFC 3551 doesn't
          // specify a value for this parameter for MPA, I've included both 0
          // and 1 here, to increase the chances it will be correctly used if
          // someone implements an MPEG audio encoder/decoder.
          {{"MPA",   90000, 0}, 14},
          {{"MPA",   90000, 1}, 14},
          {{"G728",   8000, 1}, 15},
          {{"DVI4",  11025, 1}, 16},
          {{"DVI4",  22050, 1}, 17},
          {{"G729",   8000, 1}, 18},

          // Payload type assignments currently used by WebRTC.
          // Includes data to reduce collisions (and thus reassignments)
          {{kGoogleRtpDataCodecName, 0, 0}, kGoogleRtpDataCodecPlType},
          {{kIlbcCodecName,    8000, 1}, 102},
          {{kIsacCodecName,   16000, 1}, 103},
          {{kIsacCodecName,   32000, 1}, 104},
          {{kCnCodecName,     16000, 1}, 105},
          {{kCnCodecName,     32000, 1}, 106},
          {{kGoogleSctpDataCodecName, 0, 0}, kGoogleSctpDataCodecPlType},
          {{kOpusCodecName,   48000, 2,
              {{"minptime", "10"}, {"useinbandfec", "1"}}}, 111},
          // TODO(solenberg): Remove the hard coded 16k,32k,48k DTMF once we
          // assign payload types dynamically for send side as well.
          {{kDtmfCodecName,   48000, 1}, 110},
          {{kDtmfCodecName,   32000, 1}, 112},
          {{kDtmfCodecName,   16000, 1}, 113},
          {{kDtmfCodecName,    8000, 1}, 126}}) {
  // TODO(ossu): Try to keep this as change-proof as possible until we're able
  // to remove the payload type constants from everywhere in the code.
  for (const auto& mapping : mappings_) {
    used_payload_types_.insert(mapping.second);
  }
}

PayloadTypeMapper::~PayloadTypeMapper() = default;

rtc::Optional<int> PayloadTypeMapper::GetMappingFor(
    const webrtc::SdpAudioFormat& format) {
  auto iter = mappings_.find(format);
  if (iter != mappings_.end())
    return rtc::Optional<int>(iter->second);

  for (; next_unused_payload_type_ <= max_payload_type_;
       ++next_unused_payload_type_) {
    int payload_type = next_unused_payload_type_;
    if (used_payload_types_.find(payload_type) == used_payload_types_.end()) {
      used_payload_types_.insert(payload_type);
      mappings_[format] = payload_type;
      ++next_unused_payload_type_;
      return rtc::Optional<int>(payload_type);
    }
  }

  return rtc::Optional<int>();
}

rtc::Optional<int> PayloadTypeMapper::FindMappingFor(
    const webrtc::SdpAudioFormat& format) const {
  auto iter = mappings_.find(format);
  if (iter != mappings_.end())
    return rtc::Optional<int>(iter->second);

  return rtc::Optional<int>();
}

rtc::Optional<AudioCodec> PayloadTypeMapper::ToAudioCodec(
    const webrtc::SdpAudioFormat& format) {
  // TODO(ossu): We can safely set bitrate to zero here, since that field is
  // not presented in the SDP. It is used to ferry around some target bitrate
  // values for certain codecs (ISAC and Opus) and in ways it really
  // shouldn't. It should be removed once we no longer use CodecInsts in the
  // ACM or NetEq.
  auto opt_payload_type = GetMappingFor(format);
  if (opt_payload_type) {
    AudioCodec codec(*opt_payload_type, format.name, format.clockrate_hz, 0,
                     format.num_channels);
    codec.params = format.parameters;
    return rtc::Optional<AudioCodec>(std::move(codec));
  }

  return rtc::Optional<AudioCodec>();
}

bool PayloadTypeMapper::SdpAudioFormatOrdering::operator()(
    const webrtc::SdpAudioFormat& a,
    const webrtc::SdpAudioFormat& b) const {
  if (a.clockrate_hz == b.clockrate_hz) {
    if (a.num_channels == b.num_channels) {
      int name_cmp = STR_CASE_CMP(a.name.c_str(), b.name.c_str());
      if (name_cmp == 0)
        return a.parameters < b.parameters;
      return name_cmp < 0;
    }
    return a.num_channels < b.num_channels;
  }
  return a.clockrate_hz < b.clockrate_hz;
}

}  // namespace cricket
