// Copyright (c) 2012 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/video/capture/win/sink_input_pin_win.h"

#include <cstring>

// Avoid including strsafe.h via dshow as it will cause build warnings.
#define NO_DSHOW_STRSAFE
#include <dshow.h>

#include "base/logging.h"

namespace media {

const REFERENCE_TIME kSecondsToReferenceTime = 10000000;

SinkInputPin::SinkInputPin(IBaseFilter* filter,
                           SinkFilterObserver* observer)
    : observer_(observer),
      PinBase(filter) {
  memset(&requested_capability_, 0, sizeof(requested_capability_));
  memset(&resulting_capability_, 0, sizeof(resulting_capability_));
}

SinkInputPin::~SinkInputPin() {}

bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) {
  if (media_type->cbFormat < sizeof(VIDEOINFOHEADER))
    return false;

  VIDEOINFOHEADER* pvi =
      reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);

  ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));
  pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  pvi->bmiHeader.biPlanes = 1;
  pvi->bmiHeader.biClrImportant = 0;
  pvi->bmiHeader.biClrUsed = 0;
  if (requested_capability_.frame_rate > 0) {
    pvi->AvgTimePerFrame = kSecondsToReferenceTime /
                           requested_capability_.frame_rate;
  }

  media_type->majortype = MEDIATYPE_Video;
  media_type->formattype = FORMAT_VideoInfo;
  media_type->bTemporalCompression = FALSE;

  switch (index) {
    case 0: {
      pvi->bmiHeader.biCompression = MAKEFOURCC('I', '4', '2', '0');
      pvi->bmiHeader.biBitCount = 12;  // bit per pixel
      pvi->bmiHeader.biWidth = requested_capability_.width;
      pvi->bmiHeader.biHeight = requested_capability_.height;
      pvi->bmiHeader.biSizeImage = 3 * requested_capability_.height *
                                   requested_capability_.width / 2;
      media_type->subtype = kMediaSubTypeI420;
      break;
    }
    case 1: {
      pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2');
      pvi->bmiHeader.biBitCount = 16;
      pvi->bmiHeader.biWidth = requested_capability_.width;
      pvi->bmiHeader.biHeight = requested_capability_.height;
      pvi->bmiHeader.biSizeImage = 2 * requested_capability_.width *
                                   requested_capability_.height;
      media_type->subtype = MEDIASUBTYPE_YUY2;
      break;
    }
    case 2: {
      pvi->bmiHeader.biCompression = BI_RGB;
      pvi->bmiHeader.biBitCount = 24;
      pvi->bmiHeader.biWidth = requested_capability_.width;
      pvi->bmiHeader.biHeight = requested_capability_.height;
      pvi->bmiHeader.biSizeImage = 3 * requested_capability_.height *
                                   requested_capability_.width;
      media_type->subtype = MEDIASUBTYPE_RGB24;
      break;
    }
    default:
      return false;
  }

  media_type->bFixedSizeSamples = TRUE;
  media_type->lSampleSize = pvi->bmiHeader.biSizeImage;
  return true;
}

bool SinkInputPin::IsMediaTypeValid(const AM_MEDIA_TYPE* media_type) {
  GUID type = media_type->majortype;
  if (type != MEDIATYPE_Video)
    return false;

  GUID format_type = media_type->formattype;
  if (format_type != FORMAT_VideoInfo)
    return false;

  // Check for the sub types we support.
  GUID sub_type = media_type->subtype;
  VIDEOINFOHEADER* pvi =
      reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
  if (pvi == NULL)
    return false;

  // Store the incoming width and height.
  resulting_capability_.width = pvi->bmiHeader.biWidth;
  resulting_capability_.height = abs(pvi->bmiHeader.biHeight);
  if (pvi->AvgTimePerFrame > 0) {
    resulting_capability_.frame_rate =
        static_cast<int>(kSecondsToReferenceTime / pvi->AvgTimePerFrame);
  } else {
    resulting_capability_.frame_rate = requested_capability_.frame_rate;
  }
  if (sub_type == kMediaSubTypeI420 &&
      pvi->bmiHeader.biCompression == MAKEFOURCC('I', '4', '2', '0')) {
    resulting_capability_.color = VideoCaptureCapability::kI420;
    return true;  // This format is acceptable.
  }
  if (sub_type == MEDIASUBTYPE_YUY2 &&
      pvi->bmiHeader.biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) {
    resulting_capability_.color = VideoCaptureCapability::kYUY2;
    return true;  // This format is acceptable.
  }
  if (sub_type == MEDIASUBTYPE_RGB24 &&
      pvi->bmiHeader.biCompression == BI_RGB) {
    resulting_capability_.color = VideoCaptureCapability::kRGB24;
    return true;  // This format is acceptable.
  }
  return false;
}

HRESULT SinkInputPin::Receive(IMediaSample* sample) {
  const int length = sample->GetActualDataLength();
  uint8* buffer = NULL;
  if (FAILED(sample->GetPointer(&buffer)))
    return S_FALSE;

  observer_->FrameReceived(buffer, length);
  return S_OK;
}

void SinkInputPin::SetRequestedMediaCapability(
    const VideoCaptureCapability& capability) {
  requested_capability_ = capability;
  resulting_capability_.width = 0;
  resulting_capability_.height = 0;
  resulting_capability_.frame_rate = 0;
  resulting_capability_.color = VideoCaptureCapability::kColorUnknown;
  resulting_capability_.expected_capture_delay = 0;
  resulting_capability_.interlaced = false;
}

const VideoCaptureCapability& SinkInputPin::ResultingCapability() {
  return resulting_capability_;
}

}  // namespace media
