// Copyright 2014 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/mac/video_capture_device_decklink_mac.h"

#include <utility>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/sys_string_conversions.h"
#include "base/synchronization/lock.h"
#include "media/capture/video/video_capture_device_info.h"
#include "third_party/decklink/mac/include/DeckLinkAPI.h"

namespace {

// DeckLink SDK uses ComPtr-style APIs. Microsoft::WRL::ComPtr<> is only
// available for Windows builds. This provides a subset of the methods required
// for ref counting.
template <class T>
class ScopedDeckLinkPtr : public scoped_refptr<T> {
 private:
  using scoped_refptr<T>::ptr_;

 public:
  T** Receive() {
    DCHECK(!ptr_) << "Object leak. Pointer must be NULL";
    return &ptr_;
  }

  void** ReceiveVoid() { return reinterpret_cast<void**>(Receive()); }

  void Release() {
    if (ptr_ != NULL) {
      ptr_->Release();
      ptr_ = NULL;
    }
  }
};

// This class is used to interact directly with DeckLink SDK for video capture.
// Implements the reference counted interface IUnknown. Has a weak reference to
// VideoCaptureDeviceDeckLinkMac for sending captured frames, error messages and
// logs.
class DeckLinkCaptureDelegate
    : public IDeckLinkInputCallback,
      public base::RefCountedThreadSafe<DeckLinkCaptureDelegate> {
 public:
  DeckLinkCaptureDelegate(
      const media::VideoCaptureDeviceDescriptor& device_descriptor,
      media::VideoCaptureDeviceDeckLinkMac* frame_receiver);

  void AllocateAndStart(const media::VideoCaptureParams& params);
  void StopAndDeAllocate();

  // Remove the VideoCaptureDeviceDeckLinkMac's weak reference.
  void ResetVideoCaptureDeviceReference();

 private:
  // IDeckLinkInputCallback interface implementation.
  HRESULT VideoInputFormatChanged(
      BMDVideoInputFormatChangedEvents notification_events,
      IDeckLinkDisplayMode* new_display_mode,
      BMDDetectedVideoInputFormatFlags detected_signal_flags) override;
  HRESULT VideoInputFrameArrived(
      IDeckLinkVideoInputFrame* video_frame,
      IDeckLinkAudioInputPacket* audio_packet) override;

  // IUnknown interface implementation.
  HRESULT QueryInterface(REFIID iid, void** ppv) override;
  ULONG AddRef() override;
  ULONG Release() override;

  // Forwarder to VideoCaptureDeviceDeckLinkMac::SendErrorString().
  void SendErrorString(media::VideoCaptureError error,
                       const base::Location& from_here,
                       const std::string& reason);

  // Forwarder to VideoCaptureDeviceDeckLinkMac::SendLogString().
  void SendLogString(const std::string& message);

  const media::VideoCaptureDeviceDescriptor device_descriptor_;

  // Protects concurrent setting and using of |frame_receiver_|.
  base::Lock lock_;
  // Weak reference to the captured frames client, used also for error messages
  // and logging. Initialized on construction and used until cleared by calling
  // ResetVideoCaptureDeviceReference().
  media::VideoCaptureDeviceDeckLinkMac* frame_receiver_;

  // This is used to control the video capturing device input interface.
  ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_;
  // |decklink_| represents a physical device attached to the host.
  ScopedDeckLinkPtr<IDeckLink> decklink_;

  base::TimeTicks first_ref_time_;

  // Checks for Device (a.k.a. Audio) thread.
  base::ThreadChecker thread_checker_;

  friend class scoped_refptr<DeckLinkCaptureDelegate>;
  friend class base::RefCountedThreadSafe<DeckLinkCaptureDelegate>;

  ~DeckLinkCaptureDelegate() override;

  DISALLOW_COPY_AND_ASSIGN(DeckLinkCaptureDelegate);
};

static float GetDisplayModeFrameRate(
    const ScopedDeckLinkPtr<IDeckLinkDisplayMode>& display_mode) {
  BMDTimeValue time_value, time_scale;
  float display_mode_frame_rate = 0.0f;
  if (display_mode->GetFrameRate(&time_value, &time_scale) == S_OK &&
      time_value > 0) {
    display_mode_frame_rate = static_cast<float>(time_scale) / time_value;
  }
  // Interlaced formats are going to be marked as double the frame rate,
  // which follows the general naming convention.
  if (display_mode->GetFieldDominance() == bmdLowerFieldFirst ||
      display_mode->GetFieldDominance() == bmdUpperFieldFirst) {
    display_mode_frame_rate *= 2.0f;
  }
  return display_mode_frame_rate;
}

DeckLinkCaptureDelegate::DeckLinkCaptureDelegate(
    const media::VideoCaptureDeviceDescriptor& device_descriptor,
    media::VideoCaptureDeviceDeckLinkMac* frame_receiver)
    : device_descriptor_(device_descriptor), frame_receiver_(frame_receiver) {}

DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate() {
}

void DeckLinkCaptureDelegate::AllocateAndStart(
    const media::VideoCaptureParams& params) {
  DCHECK(thread_checker_.CalledOnValidThread());
  scoped_refptr<IDeckLinkIterator> decklink_iter(
      CreateDeckLinkIteratorInstance());
  DLOG_IF(ERROR, !decklink_iter.get()) << "Error creating DeckLink iterator";
  if (!decklink_iter.get())
    return;

  ScopedDeckLinkPtr<IDeckLink> decklink_local;
  while (decklink_iter->Next(decklink_local.Receive()) == S_OK) {
    CFStringRef device_model_name = NULL;
    if ((decklink_local->GetModelName(&device_model_name) == S_OK) ||
        (device_descriptor_.device_id ==
         base::SysCFStringRefToUTF8(device_model_name))) {
      break;
    }
  }
  if (!decklink_local.get()) {
    SendErrorString(
        media::VideoCaptureError::kMacDeckLinkDeviceIdNotFoundInTheSystem,
        FROM_HERE, "Device id not found in the system");
    return;
  }

  ScopedDeckLinkPtr<IDeckLinkInput> decklink_input_local;
  if (decklink_local->QueryInterface(
          IID_IDeckLinkInput, decklink_input_local.ReceiveVoid()) != S_OK) {
    SendErrorString(
        media::VideoCaptureError::kMacDeckLinkErrorQueryingInputInterface,
        FROM_HERE, "Error querying input interface.");
    return;
  }

  ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
  if (decklink_input_local->GetDisplayModeIterator(
          display_mode_iter.Receive()) != S_OK) {
    SendErrorString(
        media::VideoCaptureError::kMacDeckLinkErrorCreatingDisplayModeIterator,
        FROM_HERE, "Error creating Display Mode Iterator");
    return;
  }

  ScopedDeckLinkPtr<IDeckLinkDisplayMode> chosen_display_mode;
  ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
  float min_diff = FLT_MAX;
  while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
    const float diff = labs(display_mode->GetWidth() -
                            params.requested_format.frame_size.width()) +
                       labs(params.requested_format.frame_size.height() -
                            display_mode->GetHeight()) +
                       fabs(params.requested_format.frame_rate -
                            GetDisplayModeFrameRate(display_mode));
    if (diff < min_diff) {
      chosen_display_mode = display_mode;
      min_diff = diff;
    }
    display_mode.Release();
  }
  if (!chosen_display_mode.get()) {
    SendErrorString(
        media::VideoCaptureError::kMacDeckLinkCouldNotFindADisplayMode,
        FROM_HERE, "Could not find a display mode");
    return;
  }
#if !defined(NDEBUG)
  DVLOG(1) << "Requested format: "
           << media::VideoCaptureFormat::ToString(params.requested_format);
  CFStringRef format_name = NULL;
  if (chosen_display_mode->GetName(&format_name) == S_OK)
    DVLOG(1) << "Chosen format: " << base::SysCFStringRefToUTF8(format_name);
#endif

  // Enable video input. Configure for no input video format change detection,
  // this in turn will disable calls to VideoInputFormatChanged().
  if (decklink_input_local->EnableVideoInput(
          chosen_display_mode->GetDisplayMode(), bmdFormat8BitYUV,
          bmdVideoInputFlagDefault) != S_OK) {
    SendErrorString(media::VideoCaptureError::
                        kMacDeckLinkCouldNotSelectTheVideoFormatWeLike,
                    FROM_HERE, "Could not select the video format we like.");
    return;
  }

  decklink_input_local->SetCallback(this);
  if (decklink_input_local->StartStreams() != S_OK)
    SendErrorString(
        media::VideoCaptureError::kMacDeckLinkCouldNotStartCapturing, FROM_HERE,
        "Could not start capturing");

  if (frame_receiver_)
    frame_receiver_->ReportStarted();

  decklink_.swap(decklink_local);
  decklink_input_.swap(decklink_input_local);
}

void DeckLinkCaptureDelegate::StopAndDeAllocate() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!decklink_input_.get())
    return;
  if (decklink_input_->StopStreams() != S_OK)
    SendLogString("Problem stopping capture.");
  decklink_input_->SetCallback(NULL);
  decklink_input_->DisableVideoInput();
  decklink_input_.Release();
  decklink_.Release();
  ResetVideoCaptureDeviceReference();
}

HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(
    BMDVideoInputFormatChangedEvents notification_events,
    IDeckLinkDisplayMode* new_display_mode,
    BMDDetectedVideoInputFormatFlags detected_signal_flags) {
  DCHECK(thread_checker_.CalledOnValidThread());
  return S_OK;
}

HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(
    IDeckLinkVideoInputFrame* video_frame,
    IDeckLinkAudioInputPacket* /* audio_packet */) {
  // Capture frames are manipulated as an IDeckLinkVideoFrame.
  uint8_t* video_data = NULL;
  video_frame->GetBytes(reinterpret_cast<void**>(&video_data));

  media::VideoPixelFormat pixel_format =
      media::PIXEL_FORMAT_UNKNOWN;
  switch (video_frame->GetPixelFormat()) {
    case bmdFormat8BitYUV:  // A.k.a. '2vuy';
      pixel_format = media::PIXEL_FORMAT_UYVY;
      break;
    case bmdFormat8BitARGB:
      pixel_format = media::PIXEL_FORMAT_ARGB;
      break;
    default:
      SendErrorString(
          media::VideoCaptureError::kMacDeckLinkUnsupportedPixelFormat,
          FROM_HERE, "Unsupported pixel format");
      break;
  }

  const media::VideoCaptureFormat capture_format(
      gfx::Size(video_frame->GetWidth(), video_frame->GetHeight()),
      0.0f,  // Frame rate is not needed for captured data callback.
      pixel_format);
  base::TimeTicks now = base::TimeTicks::Now();
  if (first_ref_time_.is_null())
    first_ref_time_ = now;
  base::AutoLock lock(lock_);
  if (frame_receiver_) {
    const BMDTimeScale micros_time_scale = base::Time::kMicrosecondsPerSecond;
    BMDTimeValue frame_time;
    BMDTimeValue frame_duration;
    base::TimeDelta timestamp;
    if (SUCCEEDED(video_frame->GetStreamTime(&frame_time, &frame_duration,
                                             micros_time_scale))) {
      timestamp = base::Microseconds(frame_time);
    } else {
      timestamp = now - first_ref_time_;
    }
    // TODO(julien.isorce): Build a gfx::ColorSpace from DeckLink API, .i.e
    // using BMDDisplayModeFlags or BMDDeckLinkFrameMetadataID. See
    // http://crbug.com/959953.
    frame_receiver_->OnIncomingCapturedData(
        video_data, video_frame->GetRowBytes() * video_frame->GetHeight(),
        capture_format, gfx::ColorSpace(),
        0,      // Rotation.
        false,  // Vertical flip.
        now, timestamp);
  }
  return S_OK;
}

HRESULT DeckLinkCaptureDelegate::QueryInterface(REFIID iid, void** ppv) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CFUUIDBytes iunknown = CFUUIDGetUUIDBytes(IUnknownUUID);
  if (memcmp(&iid, &iunknown, sizeof(REFIID)) == 0 ||
      memcmp(&iid, &IID_IDeckLinkInputCallback, sizeof(REFIID)) == 0) {
    *ppv = static_cast<IDeckLinkInputCallback*>(this);
    AddRef();
    return S_OK;
  }
  return E_NOINTERFACE;
}

ULONG DeckLinkCaptureDelegate::AddRef() {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::RefCountedThreadSafe<DeckLinkCaptureDelegate>::AddRef();
  return 1;
}

ULONG DeckLinkCaptureDelegate::Release() {
  DCHECK(thread_checker_.CalledOnValidThread());
  bool ret_value = !HasOneRef();
  base::RefCountedThreadSafe<DeckLinkCaptureDelegate>::Release();
  return ret_value;
}

void DeckLinkCaptureDelegate::SendErrorString(media::VideoCaptureError error,
                                              const base::Location& from_here,
                                              const std::string& reason) {
  base::AutoLock lock(lock_);
  if (frame_receiver_)
    frame_receiver_->SendErrorString(error, from_here, reason);
}

void DeckLinkCaptureDelegate::SendLogString(const std::string& message) {
  base::AutoLock lock(lock_);
  if (frame_receiver_)
    frame_receiver_->SendLogString(message);
}

void DeckLinkCaptureDelegate::ResetVideoCaptureDeviceReference() {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::AutoLock lock(lock_);
  frame_receiver_ = NULL;
}

}  // namespace

namespace media {

static std::string JoinDeviceNameAndFormat(CFStringRef name,
                                           CFStringRef format) {
  return base::SysCFStringRefToUTF8(name) + " - " +
         base::SysCFStringRefToUTF8(format);
}

// static
void VideoCaptureDeviceDeckLinkMac::EnumerateDevices(
    std::vector<VideoCaptureDeviceInfo>* devices_info) {
  scoped_refptr<IDeckLinkIterator> decklink_iter(
      CreateDeckLinkIteratorInstance());
  // At this point, not being able to create a DeckLink iterator means that
  // there are no Blackmagic DeckLink devices in the system, don't print error.
  DVLOG_IF(1, !decklink_iter.get()) << "Could not create DeckLink iterator";
  if (!decklink_iter.get())
    return;

  ScopedDeckLinkPtr<IDeckLink> decklink;
  while (decklink_iter->Next(decklink.Receive()) == S_OK) {
    ScopedDeckLinkPtr<IDeckLink> decklink_local;
    decklink_local.swap(decklink);

    CFStringRef device_model_name = NULL;
    HRESULT hr = decklink_local->GetModelName(&device_model_name);
    DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device model name";
    CFStringRef device_display_name = NULL;
    hr = decklink_local->GetDisplayName(&device_display_name);
    DVLOG_IF(1, hr != S_OK) << "Error reading Blackmagic device display name";
    DVLOG_IF(1, hr == S_OK) << "Blackmagic device found with name: "
                            << base::SysCFStringRefToUTF8(device_display_name);

    if (!device_model_name && !device_display_name)
      continue;

    ScopedDeckLinkPtr<IDeckLinkInput> decklink_input;
    if (decklink_local->QueryInterface(IID_IDeckLinkInput,
                                       decklink_input.ReceiveVoid()) != S_OK) {
      DLOG(ERROR) << "Error Blackmagic querying input interface.";
      return;
    }

    ScopedDeckLinkPtr<IDeckLinkDisplayModeIterator> display_mode_iter;
    if (decklink_input->GetDisplayModeIterator(display_mode_iter.Receive()) !=
        S_OK) {
      continue;
    }

    ScopedDeckLinkPtr<IDeckLinkDisplayMode> display_mode;
    while (display_mode_iter->Next(display_mode.Receive()) == S_OK) {
      CFStringRef format_name = NULL;
      if (display_mode->GetName(&format_name) == S_OK) {
        VideoCaptureDeviceDescriptor descriptor;
        descriptor.set_display_name(
            JoinDeviceNameAndFormat(device_display_name, format_name));
        descriptor.device_id =
            JoinDeviceNameAndFormat(device_model_name, format_name);
        descriptor.capture_api = VideoCaptureApi::MACOSX_DECKLINK;
        descriptor.transport_type = VideoCaptureTransportType::OTHER_TRANSPORT;
        descriptor.set_control_support(VideoCaptureControlSupport());
        DVLOG(1) << "Blackmagic camera enumerated: "
                 << descriptor.display_name();
        devices_info->emplace_back(std::move(descriptor));

        // IDeckLinkDisplayMode does not have information on pixel format, this
        // is only available on capture.
        const media::VideoCaptureFormat format(
            gfx::Size(display_mode->GetWidth(), display_mode->GetHeight()),
            GetDisplayModeFrameRate(display_mode), PIXEL_FORMAT_UNKNOWN);
        devices_info->back().supported_formats.push_back(format);
        DVLOG(2) << devices_info->back().descriptor.display_name() << " "
                 << VideoCaptureFormat::ToString(format);
      }
      display_mode.Release();
    }
  }
}

VideoCaptureDeviceDeckLinkMac::VideoCaptureDeviceDeckLinkMac(
    const VideoCaptureDeviceDescriptor& device_descriptor)
    : decklink_capture_delegate_(
          new DeckLinkCaptureDelegate(device_descriptor, this)) {}

VideoCaptureDeviceDeckLinkMac::~VideoCaptureDeviceDeckLinkMac() {
  decklink_capture_delegate_->ResetVideoCaptureDeviceReference();
}

void VideoCaptureDeviceDeckLinkMac::OnIncomingCapturedData(
    const uint8_t* data,
    size_t length,
    const VideoCaptureFormat& frame_format,
    const gfx::ColorSpace& color_space,
    int rotation,  // Clockwise.
    bool flip_y,
    base::TimeTicks reference_time,
    base::TimeDelta timestamp) {
  base::AutoLock lock(lock_);
  if (!client_)
    return;
  client_->OnIncomingCapturedData(data, length, frame_format, color_space,
                                  rotation, flip_y, reference_time, timestamp);
}

void VideoCaptureDeviceDeckLinkMac::SendErrorString(
    VideoCaptureError error,
    const base::Location& from_here,
    const std::string& reason) {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::AutoLock lock(lock_);
  if (client_)
    client_->OnError(error, from_here, reason);
}

void VideoCaptureDeviceDeckLinkMac::SendLogString(const std::string& message) {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::AutoLock lock(lock_);
  if (client_)
    client_->OnLog(message);
}

void VideoCaptureDeviceDeckLinkMac::ReportStarted() {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::AutoLock lock(lock_);
  if (client_)
    client_->OnStarted();
}

void VideoCaptureDeviceDeckLinkMac::AllocateAndStart(
    const VideoCaptureParams& params,
    std::unique_ptr<VideoCaptureDevice::Client> client) {
  DCHECK(thread_checker_.CalledOnValidThread());
  client_ = std::move(client);
  if (decklink_capture_delegate_.get())
    decklink_capture_delegate_->AllocateAndStart(params);
}

void VideoCaptureDeviceDeckLinkMac::StopAndDeAllocate() {
  if (decklink_capture_delegate_.get())
    decklink_capture_delegate_->StopAndDeAllocate();
}

}  // namespace media
