/*
 *  Copyright (c) 2015 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 "modules/video_coding/codecs/h264/include/h264.h"

#include <memory>
#include <string>

#include "absl/container/inlined_vector.h"
#include "absl/types/optional.h"
#include "api/video_codecs/sdp_video_format.h"
#include "media/base/media_constants.h"
#include "rtc_base/trace_event.h"

#if defined(WEBRTC_USE_H264)
#include "modules/video_coding/codecs/h264/h264_decoder_impl.h"
#include "modules/video_coding/codecs/h264/h264_encoder_impl.h"
#endif

#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

namespace {

#if defined(WEBRTC_USE_H264)
bool g_rtc_use_h264 = true;
#endif

// If H.264 OpenH264/FFmpeg codec is supported.
bool IsH264CodecSupported() {
#if defined(WEBRTC_USE_H264)
  return g_rtc_use_h264;
#else
  return false;
#endif
}

constexpr ScalabilityMode kSupportedScalabilityModes[] = {
    ScalabilityMode::kL1T1, ScalabilityMode::kL1T2, ScalabilityMode::kL1T3};

}  // namespace

SdpVideoFormat CreateH264Format(H264Profile profile,
                                H264Level level,
                                const std::string& packetization_mode,
                                bool add_scalability_modes) {
  const absl::optional<std::string> profile_string =
      H264ProfileLevelIdToString(H264ProfileLevelId(profile, level));
  RTC_CHECK(profile_string);
  absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
  if (add_scalability_modes) {
    for (const auto scalability_mode : kSupportedScalabilityModes) {
      scalability_modes.push_back(scalability_mode);
    }
  }
  return SdpVideoFormat(
      cricket::kH264CodecName,
      {{cricket::kH264FmtpProfileLevelId, *profile_string},
       {cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
       {cricket::kH264FmtpPacketizationMode, packetization_mode}},
      scalability_modes);
}

void DisableRtcUseH264() {
#if defined(WEBRTC_USE_H264)
  g_rtc_use_h264 = false;
#endif
}

std::vector<SdpVideoFormat> SupportedH264Codecs(bool add_scalability_modes) {
  TRACE_EVENT0("webrtc", __func__);
  if (!IsH264CodecSupported())
    return std::vector<SdpVideoFormat>();
  // We only support encoding Constrained Baseline Profile (CBP), but the
  // decoder supports more profiles. We can list all profiles here that are
  // supported by the decoder and that are also supersets of CBP, i.e. the
  // decoder for that profile is required to be able to decode CBP. This means
  // we can encode and send CBP even though we negotiated a potentially
  // higher profile. See the H264 spec for more information.
  //
  // We support both packetization modes 0 (mandatory) and 1 (optional,
  // preferred).
  return {CreateH264Format(H264Profile::kProfileBaseline, H264Level::kLevel3_1,
                           "1", add_scalability_modes),
          CreateH264Format(H264Profile::kProfileBaseline, H264Level::kLevel3_1,
                           "0", add_scalability_modes),
          CreateH264Format(H264Profile::kProfileConstrainedBaseline,
                           H264Level::kLevel3_1, "1", add_scalability_modes),
          CreateH264Format(H264Profile::kProfileConstrainedBaseline,
                           H264Level::kLevel3_1, "0", add_scalability_modes),
          CreateH264Format(H264Profile::kProfileMain, H264Level::kLevel3_1, "1",
                           add_scalability_modes),
          CreateH264Format(H264Profile::kProfileMain, H264Level::kLevel3_1, "0",
                           add_scalability_modes)};
}

std::vector<SdpVideoFormat> SupportedH264DecoderCodecs() {
  TRACE_EVENT0("webrtc", __func__);
  if (!IsH264CodecSupported())
    return std::vector<SdpVideoFormat>();

  std::vector<SdpVideoFormat> supportedCodecs = SupportedH264Codecs();

  // OpenH264 doesn't yet support High Predictive 4:4:4 encoding but it does
  // support decoding.
  supportedCodecs.push_back(CreateH264Format(
      H264Profile::kProfilePredictiveHigh444, H264Level::kLevel3_1, "1"));
  supportedCodecs.push_back(CreateH264Format(
      H264Profile::kProfilePredictiveHigh444, H264Level::kLevel3_1, "0"));

  return supportedCodecs;
}

std::unique_ptr<H264Encoder> H264Encoder::Create(
    const cricket::VideoCodec& codec) {
  RTC_DCHECK(H264Encoder::IsSupported());
#if defined(WEBRTC_USE_H264)
  RTC_CHECK(g_rtc_use_h264);
  RTC_LOG(LS_INFO) << "Creating H264EncoderImpl.";
  return std::make_unique<H264EncoderImpl>(codec);
#else
  RTC_DCHECK_NOTREACHED();
  return nullptr;
#endif
}

bool H264Encoder::IsSupported() {
  return IsH264CodecSupported();
}

bool H264Encoder::SupportsScalabilityMode(ScalabilityMode scalability_mode) {
  for (const auto& entry : kSupportedScalabilityModes) {
    if (entry == scalability_mode) {
      return true;
    }
  }
  return false;
}

std::unique_ptr<H264Decoder> H264Decoder::Create() {
  RTC_DCHECK(H264Decoder::IsSupported());
#if defined(WEBRTC_USE_H264)
  RTC_CHECK(g_rtc_use_h264);
  RTC_LOG(LS_INFO) << "Creating H264DecoderImpl.";
  return std::make_unique<H264DecoderImpl>();
#else
  RTC_DCHECK_NOTREACHED();
  return nullptr;
#endif
}

bool H264Decoder::IsSupported() {
  return IsH264CodecSupported();
}

}  // namespace webrtc
