// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/capture/video/video_capture_system_impl.h"

#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "build/build_config.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capture/video/video_capture_metrics.h"

namespace {

// Compares two VideoCaptureFormat by checking smallest frame_size area, then
// by width, and then by _largest_ frame_rate. Used to order a
// VideoCaptureFormats vector so that the first entry for a given resolution has
// the largest frame rate.
bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1,
                            const media::VideoCaptureFormat& format2) {
  DCHECK(format1.frame_size.GetCheckedArea().IsValid());
  DCHECK(format2.frame_size.GetCheckedArea().IsValid());
  if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) ==
      format2.frame_size.GetCheckedArea().ValueOrDefault(0)) {
    if (format1.frame_size.width() == format2.frame_size.width()) {
      return format1.frame_rate > format2.frame_rate;
    }
    return format1.frame_size.width() > format2.frame_size.width();
  }
  return format1.frame_size.GetCheckedArea().ValueOrDefault(0) <
         format2.frame_size.GetCheckedArea().ValueOrDefault(0);
}

bool IsCaptureFormatEqual(const media::VideoCaptureFormat& format1,
                          const media::VideoCaptureFormat& format2) {
  return format1.frame_size == format2.frame_size &&
         format1.frame_rate == format2.frame_rate &&
         format1.pixel_format == format2.pixel_format;
}

// This function receives a list of capture formats, sets all of them to I420
// (while keeping Y16 as is), and then removes duplicates.
void ConsolidateCaptureFormats(media::VideoCaptureFormats* formats) {
  if (formats->empty())
    return;
  // Mark all formats as I420, since this is what the renderer side will get
  // anyhow: the actual pixel format is decided at the device level.
  // Don't do this for the Y16 or NV12 formats as they are handled separately.
  for (auto& format : *formats) {
    if (format.pixel_format != media::PIXEL_FORMAT_Y16 &&
        format.pixel_format != media::PIXEL_FORMAT_NV12)
      format.pixel_format = media::PIXEL_FORMAT_I420;
  }
  std::sort(formats->begin(), formats->end(), IsCaptureFormatSmaller);
  // Remove duplicates
  auto last =
      std::unique(formats->begin(), formats->end(), IsCaptureFormatEqual);
  formats->erase(last, formats->end());
}

}  // anonymous namespace

namespace media {

VideoCaptureSystemImpl::VideoCaptureSystemImpl(
    std::unique_ptr<VideoCaptureDeviceFactory> factory)
    : factory_(std::move(factory)) {
  thread_checker_.DetachFromThread();
}

VideoCaptureSystemImpl::~VideoCaptureSystemImpl() = default;

void VideoCaptureSystemImpl::GetDeviceInfosAsync(
    DeviceInfoCallback result_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  device_enum_request_queue_.push_back(std::move(result_callback));
  if (device_enum_request_queue_.size() == 1) {
    // base::Unretained() is safe because |factory_| is owned and it guarantees
    // not to call the callback after destruction.
    factory_->GetDevicesInfo(base::BindOnce(
        &VideoCaptureSystemImpl::DevicesInfoReady, base::Unretained(this)));
  }
}

std::unique_ptr<VideoCaptureDevice> VideoCaptureSystemImpl::CreateDevice(
    const std::string& device_id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  const VideoCaptureDeviceInfo* device_info = LookupDeviceInfoFromId(device_id);
  if (!device_info)
    return nullptr;
  return factory_->CreateDevice(device_info->descriptor);
}

const VideoCaptureDeviceInfo* VideoCaptureSystemImpl::LookupDeviceInfoFromId(
    const std::string& device_id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  auto iter =
      std::find_if(devices_info_cache_.begin(), devices_info_cache_.end(),
                   [&device_id](const VideoCaptureDeviceInfo& device_info) {
                     return device_info.descriptor.device_id == device_id;
                   });
  if (iter == devices_info_cache_.end())
    return nullptr;
  return &(*iter);
}

void VideoCaptureSystemImpl::DevicesInfoReady(
    std::vector<VideoCaptureDeviceInfo> devices_info) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!device_enum_request_queue_.empty());

  // Only save metrics the first time device infos are populated.
  if (devices_info_cache_.empty()) {
    LogCaptureDeviceMetrics(devices_info);
  }

  for (auto& device_info : devices_info) {
    ConsolidateCaptureFormats(&device_info.supported_formats);
  }

  devices_info_cache_ = std::move(devices_info);

  DeviceEnumQueue requests;
  std::swap(requests, device_enum_request_queue_);

  auto weak_this = weak_factory_.GetWeakPtr();
  for (auto& request : requests) {
    std::move(request).Run(devices_info_cache_);

    // Callbacks may destroy |this|.
    if (!weak_this)
      return;
  }
}

}  // namespace media
