// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/win32/media_transform.h"

#include "starboard/log.h"
#include "starboard/shared/win32/error_utils.h"

namespace starboard {
namespace shared {
namespace win32 {

using Microsoft::WRL::ComPtr;
using ::starboard::shared::starboard::ThreadChecker;

namespace {

template <typename T>
void ReleaseIfNotNull(T** ptr) {
  if (*ptr) {
    (*ptr)->Release();
    *ptr = NULL;
  }
}

const int kStreamId = 0;

}  // namespace

MediaTransform::MediaTransform(CLSID clsid)
    : thread_checker_(ThreadChecker::kSetThreadIdOnFirstCheck),
      state_(kCanAcceptInput),
      stream_begun_(false),
      discontinuity_(true) {
  LPVOID* ptr_address = reinterpret_cast<LPVOID*>(transform_.GetAddressOf());
  HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
                                IID_IMFTransform, ptr_address);
  CheckResult(hr);
}

MediaTransform::MediaTransform(
    const Microsoft::WRL::ComPtr<IMFTransform>& transform)
    : transform_(transform),
      thread_checker_(ThreadChecker::kSetThreadIdOnFirstCheck),
      state_(kCanAcceptInput),
      stream_begun_(false),
      discontinuity_(true) {
  SB_DCHECK(transform_);
}

bool MediaTransform::TryWrite(const ComPtr<IMFSample>& input) {
  SB_DCHECK(thread_checker_.CalledOnValidThread());

  if (state_ != kCanAcceptInput) {
    return false;
  }

  if (!stream_begun_) {
    SendMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING);
    SendMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM);
    stream_begun_ = true;
  }

  HRESULT hr = transform_->ProcessInput(kStreamId, input.Get(), 0);

  if (SUCCEEDED(hr)) {
    return true;
  }
  if (hr == MF_E_NOTACCEPTING) {
    state_ = kCanProvideOutput;
    return false;
  }
  SB_NOTREACHED() << "Unexpected return value " << hr;
  return false;
}

ComPtr<IMFSample> MediaTransform::TryRead(ComPtr<IMFMediaType>* new_type) {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  SB_DCHECK(new_type);

  if (state_ != kCanProvideOutput && state_ != kDraining) {
    return NULL;
  }

  ComPtr<IMFSample> sample;
  HRESULT hr = ProcessOutput(&sample);

  if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
    hr = transform_->GetOutputAvailableType(kStreamId,
                                            0,  // TypeIndex
                                            new_type->GetAddressOf());
    CheckResult(hr);
    SetOutputType(*new_type);

    hr = ProcessOutput(&sample);
  }

  if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
    if (state_ == kCanProvideOutput) {
      state_ = kCanAcceptInput;
    }
    if (state_ == kDraining) {
      state_ = kDrained;
    }
    return NULL;
  }

  if (FAILED(hr)) {
    // Sometimes the decryptor refuse to emit output after shutting down.
    SB_DCHECK(hr == MF_E_INVALIDREQUEST);
    if (state_ == kDraining) {
      state_ = kDrained;
    }
    return NULL;
  }

  SB_DCHECK(sample);

  if (discontinuity_) {
    sample->SetUINT32(MFSampleExtension_Discontinuity, TRUE);
    discontinuity_ = false;
  }

  return sample;
}

void MediaTransform::Drain() {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  SB_DCHECK(state_ != kDraining && state_ != kDrained);

  if (state_ == kDraining || state_ == kDrained) {
    return;
  }

  if (!stream_begun_) {
    state_ = kDrained;
    return;
  }

  SendMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM);
  SendMessage(MFT_MESSAGE_COMMAND_DRAIN);
  state_ = kDraining;
}

bool MediaTransform::draining() const {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  return state_ == kDraining;
}

bool MediaTransform::drained() const {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  return state_ == kDrained;
}

void MediaTransform::ResetFromDrained() {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  SB_DCHECK(drained());

  state_ = kCanAcceptInput;
  stream_begun_ = false;
  discontinuity_ = true;
}

ComPtr<IMFMediaType> MediaTransform::GetCurrentInputType() {
  ComPtr<IMFMediaType> type;
  HRESULT hr = transform_->GetInputCurrentType(kStreamId, type.GetAddressOf());
  CheckResult(hr);
  return type;
}

void MediaTransform::SetInputType(const ComPtr<IMFMediaType>& input_type) {
  HRESULT hr = transform_->SetInputType(0, input_type.Get(), 0);
  CheckResult(hr);
}

std::vector<ComPtr<IMFMediaType>> MediaTransform::GetAvailableInputTypes() {
  std::vector<ComPtr<IMFMediaType>> input_types;

  for (DWORD i = 0;; ++i) {
    ComPtr<IMFMediaType> curr_type;
    HRESULT hr = transform_->GetInputAvailableType(kStreamId, i,
                                                   curr_type.GetAddressOf());
    if (FAILED(hr)) {
      break;
    }
    input_types.push_back(curr_type);
  }

  return input_types;
}

ComPtr<IMFMediaType> MediaTransform::GetCurrentOutputType() {
  ComPtr<IMFMediaType> type;
  HRESULT hr = transform_->GetOutputCurrentType(kStreamId, type.GetAddressOf());
  CheckResult(hr);
  return type;
}

void MediaTransform::SetOutputType(const ComPtr<IMFMediaType>& output_type) {
  HRESULT hr = transform_->SetOutputType(0, output_type.Get(), 0);
  CheckResult(hr);
}

std::vector<ComPtr<IMFMediaType>> MediaTransform::GetAvailableOutputTypes() {
  std::vector<ComPtr<IMFMediaType>> output_types;

  for (DWORD i = 0;; ++i) {
    ComPtr<IMFMediaType> curr_type;
    HRESULT hr = transform_->GetOutputAvailableType(kStreamId, i,
                                                    curr_type.GetAddressOf());
    if (FAILED(hr)) {
      break;
    }
    output_types.push_back(curr_type);
  }

  return output_types;
}

void MediaTransform::SetOutputTypeBySubType(GUID subtype) {
  for (int index = 0;; ++index) {
    ComPtr<IMFMediaType> media_type;
    HRESULT hr =
        transform_->GetOutputAvailableType(kStreamId, index, &media_type);
    if (SUCCEEDED(hr)) {
      GUID media_sub_type = {};
      media_type->GetGUID(MF_MT_SUBTYPE, &media_sub_type);
      if (media_sub_type == subtype) {
        SetOutputType(media_type);
        return;
      }
    } else {
      SB_DCHECK(hr == MF_E_NO_MORE_TYPES);
      break;
    }
  }
  SB_NOTREACHED();
}

ComPtr<IMFAttributes> MediaTransform::GetAttributes() {
  ComPtr<IMFAttributes> attributes;
  HRESULT hr = transform_->GetAttributes(attributes.GetAddressOf());
  CheckResult(hr);
  return attributes;
}

ComPtr<IMFAttributes> MediaTransform::GetOutputStreamAttributes() {
  ComPtr<IMFAttributes> attributes;
  HRESULT hr =
      transform_->GetOutputStreamAttributes(0, attributes.GetAddressOf());
  CheckResult(hr);
  return attributes;
}

ComPtr<IMFSampleProtection> MediaTransform::GetSampleProtection() {
  ComPtr<IMFSampleProtection> sample_protection;
  HRESULT hr = transform_.As(&sample_protection);
  CheckResult(hr);
  return sample_protection;
}

void MediaTransform::GetStreamCount(DWORD* input_stream_count,
                                    DWORD* output_stream_count) {
  SB_DCHECK(input_stream_count);
  SB_DCHECK(output_stream_count);
  HRESULT hr =
      transform_->GetStreamCount(input_stream_count, output_stream_count);
  CheckResult(hr);
}

void MediaTransform::SendMessage(MFT_MESSAGE_TYPE msg, ULONG_PTR data /*= 0*/) {
  HRESULT hr = transform_->ProcessMessage(msg, data);
  CheckResult(hr);
}

void MediaTransform::Reset() {
  SendMessage(MFT_MESSAGE_COMMAND_FLUSH);
  thread_checker_.Detach();
  state_ = kCanAcceptInput;
  stream_begun_ = false;
  discontinuity_ = true;
}

void MediaTransform::PrepareOutputDataBuffer(
    MFT_OUTPUT_DATA_BUFFER* output_data_buffer) {
  output_data_buffer->dwStreamID = kStreamId;
  output_data_buffer->pSample = NULL;
  output_data_buffer->dwStatus = 0;
  output_data_buffer->pEvents = NULL;

  MFT_OUTPUT_STREAM_INFO output_stream_info;
  HRESULT hr = transform_->GetOutputStreamInfo(kStreamId, &output_stream_info);
  CheckResult(hr);

  static const DWORD kFlagAutoAllocateMemory =
      MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
      MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES;
  if ((output_stream_info.dwFlags & kFlagAutoAllocateMemory) != 0) {
    // Try to let the IMFTransform allocate the memory if possible.
    return;
  }

  ComPtr<IMFSample> sample;
  hr = MFCreateSample(&sample);
  CheckResult(hr);

  ComPtr<IMFMediaBuffer> buffer;
  hr = MFCreateAlignedMemoryBuffer(output_stream_info.cbSize,
                                   output_stream_info.cbAlignment, &buffer);
  CheckResult(hr);

  hr = sample->AddBuffer(buffer.Get());
  CheckResult(hr);

  output_data_buffer->pSample = sample.Detach();
}

HRESULT MediaTransform::ProcessOutput(ComPtr<IMFSample>* sample) {
  SB_DCHECK(sample);

  MFT_OUTPUT_DATA_BUFFER output_data_buffer;
  PrepareOutputDataBuffer(&output_data_buffer);

  const DWORD kFlags = 0;
  const DWORD kNumberOfBuffers = 1;
  DWORD status = 0;
  HRESULT hr = transform_->ProcessOutput(kFlags, kNumberOfBuffers,
                                         &output_data_buffer, &status);

  SB_DCHECK(!output_data_buffer.pEvents);

  *sample = output_data_buffer.pSample;
  ReleaseIfNotNull(&output_data_buffer.pEvents);
  ReleaseIfNotNull(&output_data_buffer.pSample);

  if (output_data_buffer.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE) {
    hr = MF_E_TRANSFORM_NEED_MORE_INPUT;
  }

  return hr;
}

}  // namespace win32
}  // namespace shared
}  // namespace starboard
