/*
 *  Copyright (c) 2012 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 "modules/video_capture/windows/sink_filter_ds.h"

#include "modules/video_capture/windows/help_functions_ds.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/string_utils.h"

#include <dvdmedia.h>  // VIDEOINFOHEADER2
#include <initguid.h>

#define DELETE_RESET(p) \
  {                     \
    delete (p);         \
    (p) = NULL;         \
  }

DEFINE_GUID(CLSID_SINKFILTER,
            0x88cdbbdc,
            0xa73b,
            0x4afa,
            0xac,
            0xbf,
            0x15,
            0xd5,
            0xe2,
            0xce,
            0x12,
            0xc3);

namespace webrtc {
namespace videocapturemodule {

typedef struct tagTHREADNAME_INFO {
  DWORD dwType;      // must be 0x1000
  LPCSTR szName;     // pointer to name (in user addr space)
  DWORD dwThreadID;  // thread ID (-1=caller thread)
  DWORD dwFlags;     // reserved for future use, must be zero
} THREADNAME_INFO;

CaptureInputPin::CaptureInputPin(IN TCHAR* szName,
                                 IN CaptureSinkFilter* pFilter,
                                 IN CCritSec* pLock,
                                 OUT HRESULT* pHr,
                                 IN LPCWSTR pszName)
    : CBaseInputPin(szName, pFilter, pLock, pHr, pszName),
      _requestedCapability(),
      _resultingCapability() {
  _threadHandle = NULL;
}

CaptureInputPin::~CaptureInputPin() {}

HRESULT
CaptureInputPin::GetMediaType(IN int iPosition, OUT CMediaType* pmt) {
  // reset the thread handle
  _threadHandle = NULL;

  if (iPosition < 0)
    return E_INVALIDARG;

  VIDEOINFOHEADER* pvi =
      (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  if (NULL == pvi) {
    RTC_LOG(LS_INFO) << "CheckMediaType VIDEOINFOHEADER is NULL. Returning.";
    return (E_OUTOFMEMORY);
  }

  ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));
  pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  pvi->bmiHeader.biPlanes = 1;
  pvi->bmiHeader.biClrImportant = 0;
  pvi->bmiHeader.biClrUsed = 0;
  if (_requestedCapability.maxFPS != 0) {
    pvi->AvgTimePerFrame = 10000000 / _requestedCapability.maxFPS;
  }

  SetRectEmpty(&(pvi->rcSource));  // we want the whole image area rendered.
  SetRectEmpty(&(pvi->rcTarget));  // no particular destination rectangle

  pmt->SetType(&MEDIATYPE_Video);
  pmt->SetFormatType(&FORMAT_VideoInfo);
  pmt->SetTemporalCompression(FALSE);

  int32_t positionOffset = 1;
  switch (iPosition + positionOffset) {
    case 0: {
      pvi->bmiHeader.biCompression = MAKEFOURCC('I', '4', '2', '0');
      pvi->bmiHeader.biBitCount = 12;  // bit per pixel
      pvi->bmiHeader.biWidth = _requestedCapability.width;
      pvi->bmiHeader.biHeight = _requestedCapability.height;
      pvi->bmiHeader.biSizeImage =
          3 * _requestedCapability.height * _requestedCapability.width / 2;
      pmt->SetSubtype(&MEDIASUBTYPE_I420);
    } break;
    case 1: {
      pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2');
      ;
      pvi->bmiHeader.biBitCount = 16;  // bit per pixel
      pvi->bmiHeader.biWidth = _requestedCapability.width;
      pvi->bmiHeader.biHeight = _requestedCapability.height;
      pvi->bmiHeader.biSizeImage =
          2 * _requestedCapability.width * _requestedCapability.height;
      pmt->SetSubtype(&MEDIASUBTYPE_YUY2);
    } break;
    case 2: {
      pvi->bmiHeader.biCompression = BI_RGB;
      pvi->bmiHeader.biBitCount = 24;  // bit per pixel
      pvi->bmiHeader.biWidth = _requestedCapability.width;
      pvi->bmiHeader.biHeight = _requestedCapability.height;
      pvi->bmiHeader.biSizeImage =
          3 * _requestedCapability.height * _requestedCapability.width;
      pmt->SetSubtype(&MEDIASUBTYPE_RGB24);
    } break;
    case 3: {
      pvi->bmiHeader.biCompression = MAKEFOURCC('U', 'Y', 'V', 'Y');
      pvi->bmiHeader.biBitCount = 16;  // bit per pixel
      pvi->bmiHeader.biWidth = _requestedCapability.width;
      pvi->bmiHeader.biHeight = _requestedCapability.height;
      pvi->bmiHeader.biSizeImage =
          2 * _requestedCapability.height * _requestedCapability.width;
      pmt->SetSubtype(&MEDIASUBTYPE_UYVY);
    } break;
    case 4: {
      pvi->bmiHeader.biCompression = MAKEFOURCC('M', 'J', 'P', 'G');
      pvi->bmiHeader.biBitCount = 12;  // bit per pixel
      pvi->bmiHeader.biWidth = _requestedCapability.width;
      pvi->bmiHeader.biHeight = _requestedCapability.height;
      pvi->bmiHeader.biSizeImage =
          3 * _requestedCapability.height * _requestedCapability.width / 2;
      pmt->SetSubtype(&MEDIASUBTYPE_MJPG);
    } break;
    default:
      return VFW_S_NO_MORE_ITEMS;
  }
  pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);
  RTC_LOG(LS_INFO) << "GetMediaType position " << iPosition << ", width "
                   << _requestedCapability.width << ", height "
                   << _requestedCapability.height << ", biCompression 0x"
                   << rtc::ToHex(pvi->bmiHeader.biCompression);
  return NOERROR;
}

HRESULT
CaptureInputPin::CheckMediaType(IN const CMediaType* pMediaType) {
  // reset the thread handle
  _threadHandle = NULL;

  const GUID* type = pMediaType->Type();
  if (*type != MEDIATYPE_Video)
    return E_INVALIDARG;

  const GUID* formatType = pMediaType->FormatType();

  // Check for the subtypes we support
  const GUID* SubType = pMediaType->Subtype();
  if (SubType == NULL) {
    return E_INVALIDARG;
  }

  if (*formatType == FORMAT_VideoInfo) {
    VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pMediaType->Format();
    if (pvi == NULL) {
      return E_INVALIDARG;
    }

    // Store the incoming width and height
    _resultingCapability.width = pvi->bmiHeader.biWidth;

    // Store the incoming height,
    // for RGB24 we assume the frame to be upside down
    if (*SubType == MEDIASUBTYPE_RGB24 && pvi->bmiHeader.biHeight > 0) {
      _resultingCapability.height = -(pvi->bmiHeader.biHeight);
    } else {
      _resultingCapability.height = abs(pvi->bmiHeader.biHeight);
    }

    RTC_LOG(LS_INFO) << "CheckMediaType width:" << pvi->bmiHeader.biWidth
                     << " height:" << pvi->bmiHeader.biHeight
                     << " Compression:0x"
                     << rtc::ToHex(pvi->bmiHeader.biCompression);

    if (*SubType == MEDIASUBTYPE_MJPG &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('M', 'J', 'P', 'G')) {
      _resultingCapability.videoType = VideoType::kMJPEG;
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_I420 &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('I', '4', '2', '0')) {
      _resultingCapability.videoType = VideoType::kI420;
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_YUY2 &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) {
      _resultingCapability.videoType = VideoType::kYUY2;
      ::Sleep(60);  // workaround for bad driver
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_UYVY &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('U', 'Y', 'V', 'Y')) {
      _resultingCapability.videoType = VideoType::kUYVY;
      return S_OK;  // This format is acceptable.
    }

    if (*SubType == MEDIASUBTYPE_HDYC) {
      _resultingCapability.videoType = VideoType::kUYVY;
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_RGB24 &&
        pvi->bmiHeader.biCompression == BI_RGB) {
      _resultingCapability.videoType = VideoType::kRGB24;
      return S_OK;  // This format is acceptable.
    }
  }
  if (*formatType == FORMAT_VideoInfo2) {
    // VIDEOINFOHEADER2 that has dwInterlaceFlags
    VIDEOINFOHEADER2* pvi = (VIDEOINFOHEADER2*)pMediaType->Format();

    if (pvi == NULL) {
      return E_INVALIDARG;
    }

    RTC_LOG(LS_INFO) << "CheckMediaType width:" << pvi->bmiHeader.biWidth
                     << " height:" << pvi->bmiHeader.biHeight
                     << " Compression:0x"
                     << rtc::ToHex(pvi->bmiHeader.biCompression);

    _resultingCapability.width = pvi->bmiHeader.biWidth;

    // Store the incoming height,
    // for RGB24 we assume the frame to be upside down
    if (*SubType == MEDIASUBTYPE_RGB24 && pvi->bmiHeader.biHeight > 0) {
      _resultingCapability.height = -(pvi->bmiHeader.biHeight);
    } else {
      _resultingCapability.height = abs(pvi->bmiHeader.biHeight);
    }

    if (*SubType == MEDIASUBTYPE_MJPG &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('M', 'J', 'P', 'G')) {
      _resultingCapability.videoType = VideoType::kMJPEG;
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_I420 &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('I', '4', '2', '0')) {
      _resultingCapability.videoType = VideoType::kI420;
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_YUY2 &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) {
      _resultingCapability.videoType = VideoType::kYUY2;
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_UYVY &&
        pvi->bmiHeader.biCompression == MAKEFOURCC('U', 'Y', 'V', 'Y')) {
      _resultingCapability.videoType = VideoType::kUYVY;
      return S_OK;  // This format is acceptable.
    }

    if (*SubType == MEDIASUBTYPE_HDYC) {
      _resultingCapability.videoType = VideoType::kUYVY;
      return S_OK;  // This format is acceptable.
    }
    if (*SubType == MEDIASUBTYPE_RGB24 &&
        pvi->bmiHeader.biCompression == BI_RGB) {
      _resultingCapability.videoType = VideoType::kRGB24;
      return S_OK;  // This format is acceptable.
    }
  }
  return E_INVALIDARG;
}

HRESULT
CaptureInputPin::Receive(IN IMediaSample* pIMediaSample) {
  HRESULT hr = S_OK;

  RTC_DCHECK(m_pFilter);
  RTC_DCHECK(pIMediaSample);

  // get the thread handle of the delivering thread inc its priority
  if (_threadHandle == NULL) {
    HANDLE handle = GetCurrentThread();
    SetThreadPriority(handle, THREAD_PRIORITY_HIGHEST);
    _threadHandle = handle;

    rtc::SetCurrentThreadName("webrtc_video_capture");
  }

  reinterpret_cast<CaptureSinkFilter*>(m_pFilter)->LockReceive();
  hr = CBaseInputPin::Receive(pIMediaSample);

  if (SUCCEEDED(hr)) {
    const LONG length = pIMediaSample->GetActualDataLength();
    RTC_DCHECK(length >= 0);

    unsigned char* pBuffer = NULL;
    if (S_OK != pIMediaSample->GetPointer(&pBuffer)) {
      reinterpret_cast<CaptureSinkFilter*>(m_pFilter)->UnlockReceive();
      return S_FALSE;
    }

    // NOTE: filter unlocked within Send call
    reinterpret_cast<CaptureSinkFilter*>(m_pFilter)->ProcessCapturedFrame(
        pBuffer, static_cast<size_t>(length), _resultingCapability);
  } else {
    reinterpret_cast<CaptureSinkFilter*>(m_pFilter)->UnlockReceive();
  }

  return hr;
}

// called under LockReceive
HRESULT CaptureInputPin::SetMatchingMediaType(
    const VideoCaptureCapability& capability) {
  _requestedCapability = capability;
  _resultingCapability = VideoCaptureCapability();
  return S_OK;
}
//  ----------------------------------------------------------------------------
CaptureSinkFilter::CaptureSinkFilter(const IN TCHAR* tszName,
                                     IN LPUNKNOWN punk,
                                     OUT HRESULT* phr,
                                     VideoCaptureExternal& captureObserver)
    : CBaseFilter(tszName, punk, &m_crtFilter, CLSID_SINKFILTER),
      m_pInput(NULL),
      _captureObserver(captureObserver) {
  (*phr) = S_OK;
  TCHAR inputPinName[] = L"VideoCaptureInputPin";
  m_pInput = new CaptureInputPin(inputPinName, this, &m_crtFilter, phr,
                                 L"VideoCapture");
  if (m_pInput == NULL || FAILED(*phr)) {
    (*phr) = FAILED(*phr) ? (*phr) : E_OUTOFMEMORY;
    goto cleanup;
  }
cleanup:
  return;
}

CaptureSinkFilter::~CaptureSinkFilter() {
  delete m_pInput;
}

int CaptureSinkFilter::GetPinCount() {
  return 1;
}

CBasePin* CaptureSinkFilter::GetPin(IN int Index) {
  CBasePin* pPin;
  LockFilter();
  if (Index == 0) {
    pPin = m_pInput;
  } else {
    pPin = NULL;
  }
  UnlockFilter();
  return pPin;
}

STDMETHODIMP CaptureSinkFilter::Pause() {
  LockReceive();
  LockFilter();
  if (m_State == State_Stopped) {
    //  change the state, THEN activate the input pin
    m_State = State_Paused;
    if (m_pInput && m_pInput->IsConnected()) {
      m_pInput->Active();
    }
    if (m_pInput && !m_pInput->IsConnected()) {
      m_State = State_Running;
    }
  } else if (m_State == State_Running) {
    m_State = State_Paused;
  }
  UnlockFilter();
  UnlockReceive();
  return S_OK;
}

STDMETHODIMP CaptureSinkFilter::Stop() {
  LockReceive();
  LockFilter();

  //  set the state
  m_State = State_Stopped;

  //  inactivate the pins
  if (m_pInput)
    m_pInput->Inactive();

  UnlockFilter();
  UnlockReceive();
  return S_OK;
}

void CaptureSinkFilter::SetFilterGraph(IGraphBuilder* graph) {
  LockFilter();
  m_pGraph = graph;
  UnlockFilter();
}

void CaptureSinkFilter::ProcessCapturedFrame(
    unsigned char* pBuffer,
    size_t length,
    const VideoCaptureCapability& frameInfo) {
  //  we have the receiver lock
  if (m_State == State_Running) {
    _captureObserver.IncomingFrame(pBuffer, length, frameInfo);

    // trying to hold it since it's only a memcpy
    // IMPROVEMENT if this work move critsect
    UnlockReceive();
    return;
  }
  UnlockReceive();
  return;
}

STDMETHODIMP CaptureSinkFilter::SetMatchingMediaType(
    const VideoCaptureCapability& capability) {
  LockReceive();
  LockFilter();
  HRESULT hr;
  if (m_pInput) {
    hr = m_pInput->SetMatchingMediaType(capability);
  } else {
    hr = E_UNEXPECTED;
  }
  UnlockFilter();
  UnlockReceive();
  return hr;
}

STDMETHODIMP CaptureSinkFilter::GetClassID(OUT CLSID* pCLSID) {
  (*pCLSID) = CLSID_SINKFILTER;
  return S_OK;
}

}  // namespace videocapturemodule
}  // namespace webrtc
