/*
 * libjingle
 * Copyright 2004--2014 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/media/devices/yuvframescapturer.h"

#include "webrtc/base/bytebuffer.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/thread.h"

#include "webrtc/system_wrappers/interface/clock.h"

namespace cricket {
///////////////////////////////////////////////////////////////////////
// Definition of private class YuvFramesThread that periodically generates
// frames.
///////////////////////////////////////////////////////////////////////
class YuvFramesCapturer::YuvFramesThread
    : public rtc::Thread, public rtc::MessageHandler {
 public:
  explicit YuvFramesThread(YuvFramesCapturer* capturer)
      : capturer_(capturer),
        finished_(false) {
  }

  virtual ~YuvFramesThread() {
    Stop();
  }

  // Override virtual method of parent Thread. Context: Worker Thread.
  virtual void Run() {
    // Read the first frame and start the message pump. The pump runs until
    // Stop() is called externally or Quit() is called by OnMessage().
    int waiting_time_ms = 0;
    if (capturer_) {
      capturer_->ReadFrame(true);
      PostDelayed(waiting_time_ms, this);
      Thread::Run();
    }

    rtc::CritScope cs(&crit_);
    finished_ = true;
  }

  // Override virtual method of parent MessageHandler. Context: Worker Thread.
  virtual void OnMessage(rtc::Message* /*pmsg*/) {
    int waiting_time_ms = 0;
    if (capturer_) {
      capturer_->ReadFrame(false);
      PostDelayed(waiting_time_ms, this);
    } else {
      Quit();
    }
  }

  // Check if Run() is finished.
  bool Finished() const {
    rtc::CritScope cs(&crit_);
    return finished_;
  }

 private:
  YuvFramesCapturer* capturer_;
  mutable rtc::CriticalSection crit_;
  bool finished_;

  DISALLOW_COPY_AND_ASSIGN(YuvFramesThread);
};

/////////////////////////////////////////////////////////////////////
// Implementation of class YuvFramesCapturer.
/////////////////////////////////////////////////////////////////////

const char* YuvFramesCapturer::kYuvFrameDeviceName = "YuvFramesGenerator";

// TODO(shaowei): allow width_ and height_ to be configurable.
YuvFramesCapturer::YuvFramesCapturer()
    : frames_generator_thread(NULL),
      width_(640),
      height_(480),
      frame_index_(0),
      barcode_interval_(1) {
}

YuvFramesCapturer::~YuvFramesCapturer() {
  Stop();
  delete[] static_cast<char*>(captured_frame_.data);
}

void YuvFramesCapturer::Init() {
  int size = width_ * height_;
  int qsize = size / 4;
  frame_generator_ = new YuvFrameGenerator(width_, height_, true);
  frame_data_size_ = size + 2 * qsize;
  captured_frame_.data = new char[frame_data_size_];
  captured_frame_.fourcc = FOURCC_IYUV;
  captured_frame_.pixel_height = 1;
  captured_frame_.pixel_width = 1;
  captured_frame_.width = width_;
  captured_frame_.height = height_;
  captured_frame_.data_size = frame_data_size_;

  // Enumerate the supported formats. We have only one supported format.
  VideoFormat format(width_, height_, VideoFormat::kMinimumInterval,
                     FOURCC_IYUV);
  std::vector<VideoFormat> supported;
  supported.push_back(format);
  SetSupportedFormats(supported);
}

CaptureState YuvFramesCapturer::Start(const VideoFormat& capture_format) {
  if (IsRunning()) {
    LOG(LS_ERROR) << "Yuv Frame Generator is already running";
    return CS_FAILED;
  }
  SetCaptureFormat(&capture_format);

  barcode_reference_timestamp_millis_ =
      static_cast<int64>(rtc::Time()) * 1000;
  // Create a thread to generate frames.
  frames_generator_thread = new YuvFramesThread(this);
  bool ret = frames_generator_thread->Start();
  if (ret) {
    LOG(LS_INFO) << "Yuv Frame Generator started";
    return CS_RUNNING;
  } else {
    LOG(LS_ERROR) << "Yuv Frame Generator failed to start";
    return CS_FAILED;
  }
}

bool YuvFramesCapturer::IsRunning() {
  return frames_generator_thread && !frames_generator_thread->Finished();
}

void YuvFramesCapturer::Stop() {
  if (frames_generator_thread) {
    frames_generator_thread->Stop();
    frames_generator_thread = NULL;
    LOG(LS_INFO) << "Yuv Frame Generator stopped";
  }
  SetCaptureFormat(NULL);
}

bool YuvFramesCapturer::GetPreferredFourccs(std::vector<uint32>* fourccs) {
  if (!fourccs) {
    return false;
  }
  fourccs->push_back(GetSupportedFormats()->at(0).fourcc);
  return true;
}

// Executed in the context of YuvFramesThread.
void YuvFramesCapturer::ReadFrame(bool first_frame) {
  // 1. Signal the previously read frame to downstream.
  if (!first_frame) {
    SignalFrameCaptured(this, &captured_frame_);
  }
  uint8* buffer = new uint8[frame_data_size_];
  frame_generator_->GenerateNextFrame(buffer, GetBarcodeValue());
  frame_index_++;
  memmove(captured_frame_.data, buffer, frame_data_size_);
  delete[] buffer;
}


int32 YuvFramesCapturer::GetBarcodeValue() {
  if (barcode_reference_timestamp_millis_ == -1 ||
       frame_index_ % barcode_interval_ != 0) {
     return -1;
  }
  int64 now_millis = static_cast<int64>(rtc::Time()) * 1000;
  return static_cast<int32>(now_millis - barcode_reference_timestamp_millis_);
}

}  // namespace cricket
