// Copyright 2016 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/mojo/services/mojo_video_decoder_service.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/base/decoder_buffer.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "media/mojo/common/media_type_converters.h"
#include "media/mojo/services/mojo_media_client.h"
#include "mojo/public/c/system/types.h"
#include "mojo/public/cpp/system/buffer.h"
#include "mojo/public/cpp/system/handle.h"

namespace media {

MojoVideoDecoderService::MojoVideoDecoderService(
    mojo::InterfaceRequest<mojom::VideoDecoder> request,
    MojoMediaClient* mojo_media_client)
    : binding_(this, std::move(request)),
      mojo_media_client_(mojo_media_client),
      weak_factory_(this) {
  weak_this_ = weak_factory_.GetWeakPtr();
}

MojoVideoDecoderService::~MojoVideoDecoderService() {}

void MojoVideoDecoderService::Construct(
    mojom::VideoDecoderClientPtr client,
    mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe) {
  DVLOG(1) << __FUNCTION__;

  if (decoder_)
    return;

  // TODO(sandersd): Provide callback for requesting a stub.
  decoder_ = mojo_media_client_->CreateVideoDecoder(
      base::ThreadTaskRunnerHandle::Get());

  client_ = std::move(client);
  decoder_buffer_pipe_ = std::move(decoder_buffer_pipe);
}

void MojoVideoDecoderService::Initialize(mojom::VideoDecoderConfigPtr config,
                                         bool low_delay,
                                         const InitializeCallback& callback) {
  DVLOG(1) << __FUNCTION__;

  if (!decoder_) {
    callback.Run(false);
    return;
  }

  decoder_->Initialize(
      config.To<VideoDecoderConfig>(), low_delay, nullptr,
      base::Bind(&MojoVideoDecoderService::OnDecoderInitialized, weak_this_,
                 callback),
      base::Bind(&MojoVideoDecoderService::OnDecoderOutput, weak_this_));
}

void MojoVideoDecoderService::OnDecoderInitialized(
    const InitializeCallback& callback,
    bool success) {
  DVLOG(1) << __FUNCTION__;
  callback.Run(success);
}

void MojoVideoDecoderService::OnDecoderOutput(
    const scoped_refptr<VideoFrame>& frame) {
  DVLOG(1) << __FUNCTION__;
  DCHECK(client_);
  client_->OnVideoFrameDecoded(mojom::VideoFrame::From(frame));
}

void MojoVideoDecoderService::Decode(mojom::DecoderBufferPtr buffer,
                                     const DecodeCallback& callback) {
  DVLOG(1) << __FUNCTION__;

  if (!decoder_) {
    callback.Run(mojom::DecodeStatus::DECODE_ERROR);
    return;
  }

  // TODO(sandersd): After a decode error, we should enter an error state and
  // reject all future method calls.
  // TODO(sandersd): Extract and share with MojoAudioDecoderService.
  scoped_refptr<DecoderBuffer> media_buffer(
      buffer.To<scoped_refptr<DecoderBuffer>>());
  if (!media_buffer->end_of_stream()) {
    MojoResult result;
    MojoHandleSignalsState state;

    // TODO(sandersd): Do not wait indefinitely.
    result =
        MojoWait(decoder_buffer_pipe_.get().value(),
                 MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, &state);
    if (result != MOJO_RESULT_OK ||
        !(state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE)) {
      callback.Run(mojom::DecodeStatus::DECODE_ERROR);
      return;
    }

    uint32_t data_size = buffer->data_size;
    uint32_t bytes_read = data_size;
    DCHECK_EQ(data_size, media_buffer->data_size());
    result =
        ReadDataRaw(decoder_buffer_pipe_.get(), media_buffer->writable_data(),
                    &bytes_read, MOJO_READ_DATA_FLAG_ALL_OR_NONE);
    if (result != MOJO_RESULT_OK || bytes_read != data_size) {
      callback.Run(mojom::DecodeStatus::DECODE_ERROR);
      return;
    }
  }

  decoder_->Decode(media_buffer,
                   base::Bind(&MojoVideoDecoderService::OnDecoderDecoded,
                              weak_this_, callback));
}

void MojoVideoDecoderService::OnDecoderDecoded(const DecodeCallback& callback,
                                               DecodeStatus status) {
  DVLOG(1) << __FUNCTION__;
  callback.Run(static_cast<mojom::DecodeStatus>(status));
}

void MojoVideoDecoderService::Reset(const ResetCallback& callback) {
  DVLOG(1) << __FUNCTION__;

  if (!decoder_) {
    callback.Run();
    return;
  }

  decoder_->Reset(base::Bind(&MojoVideoDecoderService::OnDecoderReset,
                             weak_this_, callback));
}

void MojoVideoDecoderService::OnDecoderReset(const ResetCallback& callback) {
  DVLOG(1) << __FUNCTION__;
  callback.Run();
}

}  // namespace media
