/*
 * libjingle
 * Copyright 2014 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>

#include "talk/media/base/mediachannel.h"  // For VideoOptions
#include "talk/media/base/streamparams.h"
#include "talk/media/webrtc/simulcast.h"
#include "webrtc/base/common.h"
#include "webrtc/base/logging.h"
#include "webrtc/common_types.h"  // For webrtc::VideoCodec
#include "webrtc/system_wrappers/interface/field_trial.h"
namespace cricket {

struct SimulcastFormat {
  int width;
  int height;
  // The maximum number of simulcast layers can be used for
  // resolutions at |widthxheigh|.
  size_t max_layers;
  // The maximum bitrate for encoding stream at |widthxheight|, when we are
  // not sending the next higher spatial stream.
  int max_bitrate_kbps[SBM_COUNT];
  // The target bitrate for encoding stream at |widthxheight|, when this layer
  // is not the highest layer (i.e., when we are sending another higher spatial
  // stream).
  int target_bitrate_kbps[SBM_COUNT];
  // The minimum bitrate needed for encoding stream at |widthxheight|.
  int min_bitrate_kbps[SBM_COUNT];
};

// These tables describe from which resolution we can use how many
// simulcast layers at what bitrates (maximum, target, and minimum).
// Important!! Keep this table from high resolution to low resolution.
const SimulcastFormat kSimulcastFormats[] = {
  {1920, 1080, 3, {5000, 5000, 5000}, {4000, 4000, 4000}, {800, 800, 800}},
  {1280, 720, 3, {1200, 1200, 2500}, {1200, 1200, 2500}, {500, 600, 600}},
  {960, 540, 3, {900, 900, 900}, {900, 900, 900}, {350, 450, 450}},
  {640, 360, 2, {500, 700, 700}, {500, 500, 500}, {100, 150, 150}},
  {480, 270, 2, {350, 450, 450}, {350, 350, 350}, {100, 150, 150}},
  {320, 180, 1, {100, 200, 200}, {100, 150, 150}, {30, 30, 30}},
  {0, 0, 1, {100, 200, 200}, {100, 150, 150}, {30, 30, 30}}
};

// Multiway: Number of temporal layers for each simulcast stream, for maximum
// possible number of simulcast streams |kMaxSimulcastStreams|. The array
// goes from lowest resolution at position 0 to highest resolution.
// For example, first three elements correspond to say: QVGA, VGA, WHD.
static const int
    kDefaultConferenceNumberOfTemporalLayers[webrtc::kMaxSimulcastStreams] =
    {3, 3, 3, 3};

void GetSimulcastSsrcs(const StreamParams& sp, std::vector<uint32>* ssrcs) {
  const SsrcGroup* sim_group = sp.get_ssrc_group(kSimSsrcGroupSemantics);
  if (sim_group) {
    ssrcs->insert(
        ssrcs->end(), sim_group->ssrcs.begin(), sim_group->ssrcs.end());
  }
}

SimulcastBitrateMode GetSimulcastBitrateMode(
    const VideoOptions& options) {
  VideoOptions::HighestBitrate bitrate_mode;
  if (options.video_highest_bitrate.Get(&bitrate_mode)) {
    switch (bitrate_mode) {
      case VideoOptions::HIGH:
        return SBM_HIGH;
      case VideoOptions::VERY_HIGH:
        return SBM_VERY_HIGH;
      default:
        break;
    }
  }
  return SBM_NORMAL;
}

void MaybeExchangeWidthHeight(int* width, int* height) {
  // |kSimulcastFormats| assumes |width| >= |height|. If not, exchange them
  // before comparing.
  if (*width < *height) {
    int temp = *width;
    *width = *height;
    *height = temp;
  }
}

int FindSimulcastFormatIndex(int width, int height) {
  MaybeExchangeWidthHeight(&width, &height);

  for (int i = 0; i < ARRAY_SIZE(kSimulcastFormats); ++i) {
    if (width >= kSimulcastFormats[i].width &&
        height >= kSimulcastFormats[i].height) {
      return i;
    }
  }
  return -1;
}

int FindSimulcastFormatIndex(int width, int height, size_t max_layers) {
  MaybeExchangeWidthHeight(&width, &height);

  for (int i = 0; i < ARRAY_SIZE(kSimulcastFormats); ++i) {
    if (width >= kSimulcastFormats[i].width &&
        height >= kSimulcastFormats[i].height &&
        max_layers == kSimulcastFormats[i].max_layers) {
      return i;
    }
  }
  return -1;
}

SimulcastBitrateMode FindSimulcastBitrateMode(
    size_t max_layers,
    int stream_idx,
    SimulcastBitrateMode highest_enabled) {

  if (highest_enabled > SBM_NORMAL) {
    // We want high or very high for all layers if enabled.
    return highest_enabled;
  }
  if (kSimulcastFormats[stream_idx].max_layers == max_layers) {
    // We want high for the top layer.
    return SBM_HIGH;
  }
  // And normal for everything else.
  return SBM_NORMAL;
}

// Simulcast stream width and height must both be dividable by
// |2 ^ simulcast_layers - 1|.
int NormalizeSimulcastSize(int size, size_t simulcast_layers) {
  const int base2_exponent = static_cast<int>(simulcast_layers) - 1;
  return ((size >> base2_exponent) << base2_exponent);
}

size_t FindSimulcastMaxLayers(int width, int height) {
  int index = FindSimulcastFormatIndex(width, height);
  if (index == -1) {
    return -1;
  }
  return kSimulcastFormats[index].max_layers;
}

// TODO(marpan): Investigate if we should return 0 instead of -1 in
// FindSimulcast[Max/Target/Min]Bitrate functions below, since the
// codec struct max/min/targeBitrates are unsigned.
int FindSimulcastMaxBitrateBps(int width,
                               int height,
                               size_t max_layers,
                               SimulcastBitrateMode highest_enabled) {
  const int format_index = FindSimulcastFormatIndex(width, height);
  if (format_index == -1) {
    return -1;
  }
  const SimulcastBitrateMode bitrate_mode = FindSimulcastBitrateMode(
      max_layers, format_index, highest_enabled);
  return kSimulcastFormats[format_index].max_bitrate_kbps[bitrate_mode] * 1000;
}

int FindSimulcastTargetBitrateBps(int width,
                                  int height,
                                  size_t max_layers,
                                  SimulcastBitrateMode highest_enabled) {
  const int format_index = FindSimulcastFormatIndex(width, height);
  if (format_index == -1) {
    return -1;
  }
  const SimulcastBitrateMode bitrate_mode = FindSimulcastBitrateMode(
      max_layers, format_index, highest_enabled);
  return kSimulcastFormats[format_index].target_bitrate_kbps[bitrate_mode] *
         1000;
}

int FindSimulcastMinBitrateBps(int width,
                               int height,
                               size_t max_layers,
                               SimulcastBitrateMode highest_enabled) {
  const int format_index = FindSimulcastFormatIndex(width, height);
  if (format_index == -1) {
    return -1;
  }
  const SimulcastBitrateMode bitrate_mode = FindSimulcastBitrateMode(
      max_layers, format_index, highest_enabled);
  return kSimulcastFormats[format_index].min_bitrate_kbps[bitrate_mode] * 1000;
}

bool SlotSimulcastMaxResolution(size_t max_layers, int* width, int* height) {
  int index = FindSimulcastFormatIndex(*width, *height, max_layers);
  if (index == -1) {
    LOG(LS_ERROR) << "SlotSimulcastMaxResolution";
    return false;
  }

  *width = kSimulcastFormats[index].width;
  *height = kSimulcastFormats[index].height;
  LOG(LS_INFO) << "SlotSimulcastMaxResolution to width:" << *width
               << " height:" << *height;
  return true;
}

int GetTotalMaxBitrateBps(const std::vector<webrtc::VideoStream>& streams) {
  int total_max_bitrate_bps = 0;
  for (size_t s = 0; s < streams.size() - 1; ++s) {
    total_max_bitrate_bps += streams[s].target_bitrate_bps;
  }
  total_max_bitrate_bps += streams.back().max_bitrate_bps;
  return total_max_bitrate_bps;
}

std::vector<webrtc::VideoStream> GetSimulcastConfig(
    size_t max_streams,
    SimulcastBitrateMode bitrate_mode,
    int width,
    int height,
    int max_bitrate_bps,
    int max_qp,
    int max_framerate) {
  size_t simulcast_layers = FindSimulcastMaxLayers(width, height);
  if (simulcast_layers > max_streams) {
    // If the number of SSRCs in the group differs from our target
    // number of simulcast streams for current resolution, switch down
    // to a resolution that matches our number of SSRCs.
    if (!SlotSimulcastMaxResolution(max_streams, &width, &height)) {
      return std::vector<webrtc::VideoStream>();
    }
    simulcast_layers = max_streams;
  }
  std::vector<webrtc::VideoStream> streams;
  streams.resize(simulcast_layers);

  // Format width and height has to be divisible by |2 ^ number_streams - 1|.
  width = NormalizeSimulcastSize(width, simulcast_layers);
  height = NormalizeSimulcastSize(height, simulcast_layers);

  // Add simulcast sub-streams from lower resolution to higher resolutions.
  // Add simulcast streams, from highest resolution (|s| = number_streams -1)
  // to lowest resolution at |s| = 0.
  for (size_t s = simulcast_layers - 1;; --s) {
    streams[s].width = width;
    streams[s].height = height;
    // TODO(pbos): Fill actual temporal-layer bitrate thresholds.
    streams[s].temporal_layer_thresholds_bps.resize(
        kDefaultConferenceNumberOfTemporalLayers[s] - 1);
    streams[s].max_bitrate_bps = FindSimulcastMaxBitrateBps(
        width, height, simulcast_layers, bitrate_mode);
    streams[s].target_bitrate_bps = FindSimulcastTargetBitrateBps(
        width, height, simulcast_layers, bitrate_mode);
    streams[s].min_bitrate_bps = FindSimulcastMinBitrateBps(
        width, height, simulcast_layers, bitrate_mode);
    streams[s].max_qp = max_qp;
    streams[s].max_framerate = max_framerate;
    width /= 2;
    height /= 2;
    if (s == 0) {
      break;
    }
  }

  // Spend additional bits to boost the max stream.
  int bitrate_left_bps = max_bitrate_bps - GetTotalMaxBitrateBps(streams);
  if (bitrate_left_bps > 0) {
    streams.back().max_bitrate_bps += bitrate_left_bps;
  }

  return streams;
}

bool ConfigureSimulcastCodec(
    int number_ssrcs,
    SimulcastBitrateMode bitrate_mode,
    webrtc::VideoCodec* codec) {
  std::vector<webrtc::VideoStream> streams =
      GetSimulcastConfig(static_cast<size_t>(number_ssrcs),
                         bitrate_mode,
                         static_cast<int>(codec->width),
                         static_cast<int>(codec->height),
                         codec->maxBitrate * 1000,
                         codec->qpMax,
                         codec->maxFramerate);
  // Add simulcast sub-streams from lower resolution to higher resolutions.
  codec->numberOfSimulcastStreams = static_cast<unsigned int>(streams.size());
  codec->width = static_cast<unsigned short>(streams.back().width);
  codec->height = static_cast<unsigned short>(streams.back().height);
  // When using simulcast, |codec->maxBitrate| is set to the sum of the max
  // bitrates over all streams. For a given stream |s|, the max bitrate for that
  // stream is set by |simulcastStream[s].targetBitrate|, if it is not the
  // highest resolution stream, otherwise it is set by
  // |simulcastStream[s].maxBitrate|.

  for (size_t s = 0; s < streams.size(); ++s) {
    codec->simulcastStream[s].width =
        static_cast<unsigned short>(streams[s].width);
    codec->simulcastStream[s].height =
        static_cast<unsigned short>(streams[s].height);
    codec->simulcastStream[s].numberOfTemporalLayers =
        static_cast<unsigned int>(
            streams[s].temporal_layer_thresholds_bps.size() + 1);
    codec->simulcastStream[s].minBitrate = streams[s].min_bitrate_bps / 1000;
    codec->simulcastStream[s].targetBitrate =
        streams[s].target_bitrate_bps / 1000;
    codec->simulcastStream[s].maxBitrate = streams[s].max_bitrate_bps / 1000;
    codec->simulcastStream[s].qpMax = streams[s].max_qp;
  }

  codec->maxBitrate =
      static_cast<unsigned int>(GetTotalMaxBitrateBps(streams) / 1000);

  codec->codecSpecific.VP8.numberOfTemporalLayers =
      kDefaultConferenceNumberOfTemporalLayers[0];

  return true;
}

bool ConfigureSimulcastCodec(
    const StreamParams& sp,
    const VideoOptions& options,
    webrtc::VideoCodec* codec) {
  std::vector<uint32> ssrcs;
  GetSimulcastSsrcs(sp, &ssrcs);
  SimulcastBitrateMode bitrate_mode = GetSimulcastBitrateMode(options);
  return ConfigureSimulcastCodec(static_cast<int>(ssrcs.size()), bitrate_mode,
                                 codec);
}

void ConfigureSimulcastTemporalLayers(
    int num_temporal_layers, webrtc::VideoCodec* codec) {
  for (size_t i = 0; i < codec->numberOfSimulcastStreams; ++i) {
    codec->simulcastStream[i].numberOfTemporalLayers = num_temporal_layers;
  }
}

void DisableSimulcastCodec(webrtc::VideoCodec* codec) {
  // TODO(hellner): the proper solution is to uncomment the next code line
  // and remove the lines following it in this condition. This is pending
  // b/7012070 being fixed.
  // codec->numberOfSimulcastStreams = 0;
  // It is possible to set non simulcast without the above line. However,
  // the max bitrate for every simulcast layer must be set to 0. Further,
  // there is a sanity check making sure that the aspect ratio is the same
  // for all simulcast layers. The for-loop makes sure that the sanity check
  // does not fail.
  if (codec->numberOfSimulcastStreams > 0) {
    const int ratio = codec->width / codec->height;
    for (int i = 0; i < codec->numberOfSimulcastStreams - 1; ++i) {
      // Min/target bitrate has to be zero not to influence padding
      // calculations in VideoEngine.
      codec->simulcastStream[i].minBitrate = 0;
      codec->simulcastStream[i].targetBitrate = 0;
      codec->simulcastStream[i].maxBitrate = 0;
      codec->simulcastStream[i].width =
          codec->simulcastStream[i].height * ratio;
      codec->simulcastStream[i].numberOfTemporalLayers = 1;
    }
    // The for loop above did not set the bitrate of the highest layer.
    codec->simulcastStream[codec->numberOfSimulcastStreams - 1]
        .minBitrate = 0;
    codec->simulcastStream[codec->numberOfSimulcastStreams - 1]
        .targetBitrate = 0;
    codec->simulcastStream[codec->numberOfSimulcastStreams - 1].
        maxBitrate = 0;
    // The highest layer has to correspond to the non-simulcast resolution.
    codec->simulcastStream[codec->numberOfSimulcastStreams - 1].
        width = codec->width;
    codec->simulcastStream[codec->numberOfSimulcastStreams - 1].
        height = codec->height;
    codec->simulcastStream[codec->numberOfSimulcastStreams - 1].
        numberOfTemporalLayers = 1;
    // TODO(hellner): the maxFramerate should also be set here according to
    //                the screencasts framerate. Doing so will break some
    //                unittests.
  }
}

void LogSimulcastSubstreams(const webrtc::VideoCodec& codec) {
  for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) {
    LOG(LS_INFO) << "Simulcast substream " << i << ": "
                 << codec.simulcastStream[i].width << "x"
                 << codec.simulcastStream[i].height << "@"
                 << codec.simulcastStream[i].minBitrate << "-"
                 << codec.simulcastStream[i].maxBitrate << "kbps"
                 << " with "
                 << static_cast<int>(
                     codec.simulcastStream[i].numberOfTemporalLayers)
                 << " temporal layers";
  }
}

static const int kScreenshareMinBitrateKbps = 50;
static const int kScreenshareMaxBitrateKbps = 6000;
static const int kScreenshareDefaultTl0BitrateKbps = 100;
static const int kScreenshareDefaultTl1BitrateKbps = 1000;

static const char* kScreencastLayerFieldTrialName =
    "WebRTC-ScreenshareLayerRates";

ScreenshareLayerConfig::ScreenshareLayerConfig(int tl0_bitrate, int tl1_bitrate)
    : tl0_bitrate_kbps(tl0_bitrate), tl1_bitrate_kbps(tl1_bitrate) {
}

ScreenshareLayerConfig ScreenshareLayerConfig::GetDefault() {
  std::string group =
      webrtc::field_trial::FindFullName(kScreencastLayerFieldTrialName);

  ScreenshareLayerConfig config(kScreenshareDefaultTl0BitrateKbps,
                                kScreenshareDefaultTl1BitrateKbps);
  if (!group.empty() && !FromFieldTrialGroup(group, &config)) {
    LOG(LS_WARNING) << "Unable to parse WebRTC-ScreenshareLayerRates"
                       " field trial group: '" << group << "'.";
  }
  return config;
}

bool ScreenshareLayerConfig::FromFieldTrialGroup(
    const std::string& group,
    ScreenshareLayerConfig* config) {
  // Parse field trial group name, containing bitrates for tl0 and tl1.
  int tl0_bitrate;
  int tl1_bitrate;
  if (sscanf(group.c_str(), "%d-%d", &tl0_bitrate, &tl1_bitrate) != 2) {
    return false;
  }

  // Sanity check.
  if (tl0_bitrate < kScreenshareMinBitrateKbps ||
      tl0_bitrate > kScreenshareMaxBitrateKbps ||
      tl1_bitrate < kScreenshareMinBitrateKbps ||
      tl1_bitrate > kScreenshareMaxBitrateKbps || tl0_bitrate > tl1_bitrate) {
    return false;
  }

  config->tl0_bitrate_kbps = tl0_bitrate;
  config->tl1_bitrate_kbps = tl1_bitrate;

  return true;
}

void ConfigureConferenceModeScreencastCodec(webrtc::VideoCodec* codec) {
  codec->codecSpecific.VP8.numberOfTemporalLayers = 2;
  codec->codecSpecific.VP8.automaticResizeOn = false;
  ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault();

  // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked
  // on the VideoCodec struct as target and max bitrates, respectively.
  // See eg. webrtc::VP8EncoderImpl::SetRates().
  codec->targetBitrate = config.tl0_bitrate_kbps;
  codec->maxBitrate = config.tl1_bitrate_kbps;
}

}  // namespace cricket
