/*
 *  Copyright (c) 2017 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 "webrtc/api/video/video_content_type.h"

// VideoContentType stored as a single byte, which is sent over the network.
// Structure:
//
//  0 1 2 3 4 5 6 7
// +---------------+
// |r r e e e s s c|
//
// where:
// r - reserved bits.
// e - 3-bit number of an experiment group counted from 1. 0 means there's no
// experiment ongoing.
// s - 2-bit simulcast stream id or spatial layer, counted from 1. 0 means that
// no simulcast information is set.
// c - content type. 0 means real-time video, 1 means screenshare.
//

namespace webrtc {
namespace videocontenttypehelpers {

namespace {
static constexpr uint8_t kScreenshareBitsSize = 1;
static constexpr uint8_t kScreenshareBitsMask =
    (1u << kScreenshareBitsSize) - 1;

static constexpr uint8_t kSimulcastShift = 1;
static constexpr uint8_t kSimulcastBitsSize = 2;
static constexpr uint8_t kSimulcastBitsMask = ((1u << kSimulcastBitsSize) - 1)
                                              << kSimulcastShift;  // 0b00000110

static constexpr uint8_t kExperimentShift = 3;
static constexpr uint8_t kExperimentBitsSize = 3;
static constexpr uint8_t kExperimentBitsMask =
    ((1u << kExperimentBitsSize) - 1) << kExperimentShift;  // 0b00111000

static constexpr uint8_t kTotalBitsSize =
    kScreenshareBitsSize + kSimulcastBitsSize + kExperimentBitsSize;
}  // namespace

bool SetExperimentId(VideoContentType* content_type,
                                              uint8_t experiment_id) {
  // Store in bits 2-4.
  if (experiment_id >= (1 << kExperimentBitsSize))
    return false;
  *content_type = static_cast<VideoContentType>(
      (static_cast<uint8_t>(*content_type) & ~kExperimentBitsMask) |
      ((experiment_id << kExperimentShift) & kExperimentBitsMask));
  return true;
}

bool SetSimulcastId(VideoContentType* content_type,
                                             uint8_t simulcast_id) {
  // Store in bits 5-6.
  if (simulcast_id >= (1 << kSimulcastBitsSize))
    return false;
  *content_type = static_cast<VideoContentType>(
      (static_cast<uint8_t>(*content_type) & ~kSimulcastBitsMask) |
      ((simulcast_id << kSimulcastShift) & kSimulcastBitsMask));
  return true;
}

uint8_t GetExperimentId(
    const VideoContentType& content_type) {
  return (static_cast<uint8_t>(content_type) & kExperimentBitsMask) >>
         kExperimentShift;
}
uint8_t GetSimulcastId(
    const VideoContentType& content_type) {
  return (static_cast<uint8_t>(content_type) & kSimulcastBitsMask) >>
         kSimulcastShift;
}

bool IsScreenshare(
    const VideoContentType& content_type) {
  return (static_cast<uint8_t>(content_type) & kScreenshareBitsMask) > 0;
}

bool IsValidContentType(uint8_t value) {
  // Any 6-bit value is allowed.
  return value < (1 << kTotalBitsSize);
}
}  // namespace videocontenttypehelpers
}  // namespace webrtc
