/*
 *  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 "video_engine/vie_capturer.h"

#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/interface/module_common_types.h"
#include "modules/utility/interface/process_thread.h"
#include "webrtc/modules/video_capture/include/video_capture_factory.h"
#include "modules/video_processing/main/interface/video_processing.h"
#include "modules/video_render/main/interface/video_render_defines.h"
#include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/event_wrapper.h"
#include "system_wrappers/interface/thread_wrapper.h"
#include "system_wrappers/interface/trace.h"
#include "video_engine/include/vie_image_process.h"
#include "video_engine/vie_defines.h"
#include "video_engine/vie_encoder.h"

namespace webrtc {

const int kThreadWaitTimeMs = 100;
const int kMaxDeliverWaitTime = 500;

ViECapturer::ViECapturer(int capture_id,
                         int engine_id,
                         ProcessThread& module_process_thread)
    : ViEFrameProviderBase(capture_id, engine_id),
      capture_cs_(CriticalSectionWrapper::CreateCriticalSection()),
      deliver_cs_(CriticalSectionWrapper::CreateCriticalSection()),
      capture_module_(NULL),
      external_capture_module_(NULL),
      module_process_thread_(module_process_thread),
      capture_id_(capture_id),
      capture_thread_(*ThreadWrapper::CreateThread(ViECaptureThreadFunction,
                                                   this, kHighPriority,
                                                   "ViECaptureThread")),
      capture_event_(*EventWrapper::Create()),
      deliver_event_(*EventWrapper::Create()),
      effect_filter_(NULL),
      image_proc_module_(NULL),
      image_proc_module_ref_counter_(0),
      deflicker_frame_stats_(NULL),
      brightness_frame_stats_(NULL),
      current_brightness_level_(Normal),
      reported_brightness_level_(Normal),
      denoising_enabled_(false),
      observer_cs_(CriticalSectionWrapper::CreateCriticalSection()),
      observer_(NULL),
      encoding_cs_(CriticalSectionWrapper::CreateCriticalSection()),
      capture_encoder_(NULL),
      encode_complete_callback_(NULL),
      vie_encoder_(NULL),
      vcm_(NULL),
      decoder_initialized_(false) {
  WEBRTC_TRACE(kTraceMemory, kTraceVideo, ViEId(engine_id, capture_id),
               "ViECapturer::ViECapturer(capture_id: %d, engine_id: %d)",
               capture_id, engine_id);
  unsigned int t_id = 0;
  if (capture_thread_.Start(t_id)) {
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id, capture_id),
                 "%s: thread started: %u", __FUNCTION__, t_id);
  } else {
    assert(false);
  }
}

ViECapturer::~ViECapturer() {
  WEBRTC_TRACE(kTraceMemory, kTraceVideo, ViEId(engine_id_, capture_id_),
               "ViECapturer::~ViECapturer() - capture_id: %d, engine_id: %d",
               capture_id_, engine_id_);

  // Stop the thread.
  deliver_cs_->Enter();
  capture_cs_->Enter();
  capture_thread_.SetNotAlive();
  capture_event_.Set();
  capture_cs_->Leave();
  deliver_cs_->Leave();

  provider_cs_->Enter();
  if (vie_encoder_) {
    vie_encoder_->DeRegisterExternalEncoder(codec_.plType);
  }
  provider_cs_->Leave();

  // Stop the camera input.
  if (capture_module_) {
    module_process_thread_.DeRegisterModule(capture_module_);
    capture_module_->DeRegisterCaptureDataCallback();
    capture_module_->Release();
    capture_module_ = NULL;
  }
  if (capture_thread_.Stop()) {
    // Thread stopped.
    delete &capture_thread_;
    delete &capture_event_;
    delete &deliver_event_;
  } else {
    assert(false);
    WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer,
                 ViEId(engine_id_, capture_id_),
                 "%s: Not able to stop capture thread for device %d, leaking",
                 __FUNCTION__, capture_id_);
  }

  if (image_proc_module_) {
    VideoProcessingModule::Destroy(image_proc_module_);
  }
  if (deflicker_frame_stats_) {
    delete deflicker_frame_stats_;
    deflicker_frame_stats_ = NULL;
  }
  delete brightness_frame_stats_;
  if (vcm_) {
    delete vcm_;
  }
}

ViECapturer* ViECapturer::CreateViECapture(
    int capture_id,
    int engine_id,
    VideoCaptureModule* capture_module,
    ProcessThread& module_process_thread) {
  ViECapturer* capture = new ViECapturer(capture_id, engine_id,
                                         module_process_thread);
  if (!capture || capture->Init(capture_module) != 0) {
    delete capture;
    capture = NULL;
  }
  return capture;
}

WebRtc_Word32 ViECapturer::Init(VideoCaptureModule* capture_module) {
  assert(capture_module_ == NULL);
  capture_module_ = capture_module;
  capture_module_->RegisterCaptureDataCallback(*this);
  capture_module_->AddRef();
  if (module_process_thread_.RegisterModule(capture_module_) != 0) {
    return -1;
  }

  return 0;
}

ViECapturer* ViECapturer::CreateViECapture(
    int capture_id,
    int engine_id,
    const char* device_unique_idUTF8,
    const WebRtc_UWord32 device_unique_idUTF8Length,
    ProcessThread& module_process_thread) {
  ViECapturer* capture = new ViECapturer(capture_id, engine_id,
                                         module_process_thread);
  if (!capture ||
      capture->Init(device_unique_idUTF8, device_unique_idUTF8Length) != 0) {
    delete capture;
    capture = NULL;
  }
  return capture;
}

WebRtc_Word32 ViECapturer::Init(
    const char* device_unique_idUTF8,
    const WebRtc_UWord32 device_unique_idUTF8Length) {
  assert(capture_module_ == NULL);
  if (device_unique_idUTF8 == NULL) {
    capture_module_  = VideoCaptureFactory::Create(
        ViEModuleId(engine_id_, capture_id_), external_capture_module_);
  } else {
    capture_module_ = VideoCaptureFactory::Create(
        ViEModuleId(engine_id_, capture_id_), device_unique_idUTF8);
  }
  if (!capture_module_) {
    return -1;
  }
  capture_module_->AddRef();
  capture_module_->RegisterCaptureDataCallback(*this);
  if (module_process_thread_.RegisterModule(capture_module_) != 0) {
    return -1;
  }

  return 0;
}

int ViECapturer::FrameCallbackChanged() {
  if (Started() && !EncoderActive() && !CaptureCapabilityFixed()) {
    // Reconfigure the camera if a new size is required and the capture device
    // does not provide encoded frames.
    int best_width;
    int best_height;
    int best_frame_rate;
    VideoCaptureCapability capture_settings;
    capture_module_->CaptureSettings(capture_settings);
    GetBestFormat(&best_width, &best_height, &best_frame_rate);
    if (best_width != 0 && best_height != 0 && best_frame_rate != 0) {
      if (best_width != capture_settings.width ||
          best_height != capture_settings.height ||
          best_frame_rate != capture_settings.maxFPS ||
          capture_settings.codecType != kVideoCodecUnknown) {
        Stop();
        Start(requested_capability_);
      }
    }
  }
  return 0;
}

WebRtc_Word32 ViECapturer::Start(const CaptureCapability& capture_capability) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_), "%s",
               __FUNCTION__);
  int width;
  int height;
  int frame_rate;
  VideoCaptureCapability capability;
  requested_capability_ = capture_capability;
  if (EncoderActive()) {
    CriticalSectionScoped cs(encoding_cs_.get());
    capability.width = codec_.width;
    capability.height = codec_.height;
    capability.maxFPS = codec_.maxFramerate;
    capability.codecType = codec_.codecType;
    capability.rawType = kVideoI420;

  } else if (!CaptureCapabilityFixed()) {
    // Ask the observers for best size.
    GetBestFormat(&width, &height, &frame_rate);
    if (width == 0) {
      width = kViECaptureDefaultWidth;
    }
    if (height == 0) {
      height = kViECaptureDefaultHeight;
    }
    if (frame_rate == 0) {
      frame_rate = kViECaptureDefaultFramerate;
    }
    capability.height = height;
    capability.width = width;
    capability.maxFPS = frame_rate;
    capability.rawType = kVideoI420;
    capability.codecType = kVideoCodecUnknown;
  } else {
    // Width, height and type specified with call to Start, not set by
    // observers.
    capability.width = requested_capability_.width;
    capability.height = requested_capability_.height;
    capability.maxFPS = requested_capability_.maxFPS;
    capability.rawType = requested_capability_.rawType;
    capability.interlaced = requested_capability_.interlaced;
  }
  return capture_module_->StartCapture(capability);
}

WebRtc_Word32 ViECapturer::Stop() {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_), "%s",
               __FUNCTION__);
  requested_capability_ = CaptureCapability();
  return capture_module_->StopCapture();
}

bool ViECapturer::Started() {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_), "%s",
               __FUNCTION__);
  return capture_module_->CaptureStarted();
}

const char* ViECapturer::CurrentDeviceName() const {
  return capture_module_->CurrentDeviceName();
}

WebRtc_Word32 ViECapturer::SetCaptureDelay(WebRtc_Word32 delay_ms) {
  return capture_module_->SetCaptureDelay(delay_ms);
}

WebRtc_Word32 ViECapturer::SetRotateCapturedFrames(
  const RotateCapturedFrame rotation) {
  VideoCaptureRotation converted_rotation = kCameraRotate0;
  switch (rotation) {
    case RotateCapturedFrame_0:
      converted_rotation = kCameraRotate0;
      break;
    case RotateCapturedFrame_90:
      converted_rotation = kCameraRotate90;
      break;
    case RotateCapturedFrame_180:
      converted_rotation = kCameraRotate180;
      break;
    case RotateCapturedFrame_270:
      converted_rotation = kCameraRotate270;
      break;
  }
  return capture_module_->SetCaptureRotation(converted_rotation);
}

int ViECapturer::IncomingFrame(unsigned char* video_frame,
                               unsigned int video_frame_length,
                               uint16_t width,
                               uint16_t height,
                               RawVideoType video_type,
                               unsigned long long capture_time) {  // NOLINT
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "ExternalCapture::IncomingFrame width %d, height %d, "
               "capture_time %u", width, height, capture_time);

  if (!external_capture_module_) {
    return -1;
  }
  VideoCaptureCapability capability;
  capability.width = width;
  capability.height = height;
  capability.rawType = video_type;
  return external_capture_module_->IncomingFrame(video_frame,
                                                 video_frame_length,
                                                 capability, capture_time);
}

int ViECapturer::IncomingFrameI420(const ViEVideoFrameI420& video_frame,
                                   unsigned long long capture_time) {  // NOLINT
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "ExternalCapture::IncomingFrame width %d, height %d, "
               " capture_time %u", video_frame.width, video_frame.height,
               capture_time);

  if (!external_capture_module_) {
    return -1;
  }

  VideoFrameI420 frame;
  frame.width = video_frame.width;
  frame.height = video_frame.height;
  frame.y_plane = video_frame.y_plane;
  frame.u_plane = video_frame.u_plane;
  frame.v_plane = video_frame.v_plane;
  frame.y_pitch = video_frame.y_pitch;
  frame.u_pitch = video_frame.u_pitch;
  frame.v_pitch = video_frame.v_pitch;

  return external_capture_module_->IncomingFrameI420(frame, capture_time);
}

void ViECapturer::OnIncomingCapturedFrame(const WebRtc_Word32 capture_id,
                                          I420VideoFrame& video_frame) {
  WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_id: %d)", __FUNCTION__, capture_id);
  CriticalSectionScoped cs(capture_cs_.get());
  // Make sure we render this frame earlier since we know the render time set
  // is slightly off since it's being set when the frame has been received from
  // the camera, and not when the camera actually captured the frame.
  video_frame.set_render_time_ms(video_frame.render_time_ms() - FrameDelay());
  captured_frame_.SwapFrame(&video_frame);
  capture_event_.Set();
  return;
}

void ViECapturer::OnIncomingCapturedEncodedFrame(const WebRtc_Word32 capture_id,
                                                 VideoFrame& video_frame) {
  WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, capture_id_),
                "%s(capture_id: %d)", __FUNCTION__, capture_id);
  CriticalSectionScoped cs(capture_cs_.get());
  // Make sure we render this frame earlier since we know the render time set
  // is slightly off since it's being set when the frame has been received from
  // the camera, and not when the camera actually captured the frame.
  video_frame.SetRenderTime(video_frame.RenderTimeMs() - FrameDelay());
  if (encoded_frame_.Length() != 0) {
    // The last encoded frame has not been sent yet. Need to wait.
    deliver_event_.Reset();
    WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, capture_id_),
                 "%s(capture_id: %d) Last encoded frame not yet delivered.",
                 __FUNCTION__, capture_id);
    capture_cs_->Leave();
    // Wait for the coded frame to be sent before unblocking this.
    deliver_event_.Wait(kMaxDeliverWaitTime);
    assert(encoded_frame_.Length() == 0);
    capture_cs_->Enter();
  } else {
    assert(false);
  }
  encoded_frame_.SwapFrame(video_frame);
  capture_event_.Set();
  return;
}

void ViECapturer::OnCaptureDelayChanged(const WebRtc_Word32 id,
                                        const WebRtc_Word32 delay) {
  WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_id: %d) delay %d", __FUNCTION__, capture_id_,
               delay);

  // Deliver the network delay to all registered callbacks.
  ViEFrameProviderBase::SetFrameDelay(delay);
  CriticalSectionScoped cs(encoding_cs_.get());
  if (vie_encoder_) {
    vie_encoder_->DelayChanged(id, delay);
  }
}

WebRtc_Word32 ViECapturer::RegisterEffectFilter(
    ViEEffectFilter* effect_filter) {
  CriticalSectionScoped cs(deliver_cs_.get());

  if (!effect_filter) {
    if (!effect_filter_) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: no effect filter added for capture device %d",
                   __FUNCTION__, capture_id_);
      return -1;
    }
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
                 "%s: deregister effect filter for device %d", __FUNCTION__,
                 capture_id_);
  } else {
    if (effect_filter_) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: effect filter already added for capture device %d",
                   __FUNCTION__, capture_id_);
      return -1;
    }
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
                 "%s: register effect filter for device %d", __FUNCTION__,
                 capture_id_);
  }
  effect_filter_ = effect_filter;
  return 0;
}

WebRtc_Word32 ViECapturer::IncImageProcRefCount() {
  if (!image_proc_module_) {
    assert(image_proc_module_ref_counter_ == 0);
    image_proc_module_ = VideoProcessingModule::Create(
        ViEModuleId(engine_id_, capture_id_));
    if (!image_proc_module_) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: could not create video processing module",
                   __FUNCTION__);
      return -1;
    }
  }
  image_proc_module_ref_counter_++;
  return 0;
}

WebRtc_Word32 ViECapturer::DecImageProcRefCount() {
  image_proc_module_ref_counter_--;
  if (image_proc_module_ref_counter_ == 0) {
    // Destroy module.
    VideoProcessingModule::Destroy(image_proc_module_);
    image_proc_module_ = NULL;
  }
  return 0;
}

WebRtc_Word32 ViECapturer::EnableDenoising(bool enable) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d, enable: %d)", __FUNCTION__,
               capture_id_, enable);

  CriticalSectionScoped cs(deliver_cs_.get());
  if (enable) {
    if (denoising_enabled_) {
      // Already enabled, nothing need to be done.
      return 0;
    }
    denoising_enabled_ = true;
    if (IncImageProcRefCount() != 0) {
      return -1;
    }
  } else {
    if (denoising_enabled_ == false) {
      // Already disabled, nothing need to be done.
      return 0;
    }
    denoising_enabled_ = false;
    DecImageProcRefCount();
  }

  return 0;
}

WebRtc_Word32 ViECapturer::EnableDeflickering(bool enable) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d, enable: %d)", __FUNCTION__,
               capture_id_, enable);

  CriticalSectionScoped cs(deliver_cs_.get());
  if (enable) {
    if (deflicker_frame_stats_) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: deflickering already enabled", __FUNCTION__);
      return -1;
    }
    if (IncImageProcRefCount() != 0) {
      return -1;
    }
    deflicker_frame_stats_ = new VideoProcessingModule::FrameStats();
  } else {
    if (deflicker_frame_stats_ == NULL) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: deflickering not enabled", __FUNCTION__);
      return -1;
    }
    DecImageProcRefCount();
    delete deflicker_frame_stats_;
    deflicker_frame_stats_ = NULL;
  }
  return 0;
}

WebRtc_Word32 ViECapturer::EnableBrightnessAlarm(bool enable) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d, enable: %d)", __FUNCTION__,
               capture_id_, enable);

  CriticalSectionScoped cs(deliver_cs_.get());
  if (enable) {
    if (brightness_frame_stats_) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: BrightnessAlarm already enabled", __FUNCTION__);
      return -1;
    }
    if (IncImageProcRefCount() != 0) {
      return -1;
    }
    brightness_frame_stats_ = new VideoProcessingModule::FrameStats();
  } else {
    DecImageProcRefCount();
    if (brightness_frame_stats_ == NULL) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: deflickering not enabled", __FUNCTION__);
      return -1;
    }
    delete brightness_frame_stats_;
    brightness_frame_stats_ = NULL;
  }
  return 0;
}

bool ViECapturer::ViECaptureThreadFunction(void* obj) {
  return static_cast<ViECapturer*>(obj)->ViECaptureProcess();
}

bool ViECapturer::ViECaptureProcess() {
  if (capture_event_.Wait(kThreadWaitTimeMs) == kEventSignaled) {
    deliver_cs_->Enter();
    if (!captured_frame_.IsZeroSize()) {
      // New I420 frame.
      capture_cs_->Enter();
      deliver_frame_.SwapFrame(&captured_frame_);
      captured_frame_.ResetSize();
      capture_cs_->Leave();
      DeliverI420Frame(&deliver_frame_);
    }
    if (encoded_frame_.Length() > 0) {
      capture_cs_->Enter();
      deliver_encoded_frame_.SwapFrame(encoded_frame_);
      encoded_frame_.SetLength(0);
      deliver_event_.Set();
      capture_cs_->Leave();
      DeliverCodedFrame(&deliver_encoded_frame_);
    }
    deliver_cs_->Leave();
    if (current_brightness_level_ != reported_brightness_level_) {
      CriticalSectionScoped cs(observer_cs_.get());
      if (observer_) {
        observer_->BrightnessAlarm(id_, current_brightness_level_);
        reported_brightness_level_ = current_brightness_level_;
      }
    }
  }
  // We're done!
  return true;
}

void ViECapturer::DeliverI420Frame(I420VideoFrame* video_frame) {
  // Apply image enhancement and effect filter.
  if (deflicker_frame_stats_) {
    if (image_proc_module_->GetFrameStats(deflicker_frame_stats_,
                                          *video_frame) == 0) {
      image_proc_module_->Deflickering(video_frame, deflicker_frame_stats_);
    } else {
      WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, capture_id_),
                   "%s: could not get frame stats for captured frame",
                   __FUNCTION__);
    }
  }
  if (denoising_enabled_) {
    image_proc_module_->Denoising(video_frame);
  }
  if (brightness_frame_stats_) {
    if (image_proc_module_->GetFrameStats(brightness_frame_stats_,
                                          *video_frame) == 0) {
      WebRtc_Word32 brightness = image_proc_module_->BrightnessDetection(
          *video_frame, *brightness_frame_stats_);

      switch (brightness) {
      case VideoProcessingModule::kNoWarning:
        current_brightness_level_ = Normal;
        break;
      case VideoProcessingModule::kDarkWarning:
        current_brightness_level_ = Dark;
        break;
      case VideoProcessingModule::kBrightWarning:
        current_brightness_level_ = Bright;
        break;
      default:
        WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
                     "%s: Brightness detection failed", __FUNCTION__);
      }
    }
  }
  if (effect_filter_) {
    unsigned int length = CalcBufferSize(kI420,
                                         video_frame->width(),
                                         video_frame->height());
    scoped_array<uint8_t> video_buffer(new uint8_t[length]);
    ExtractBuffer(*video_frame, length, video_buffer.get());
    effect_filter_->Transform(length, video_buffer.get(),
                              video_frame->timestamp(), video_frame->width(),
                              video_frame->height());
  }
  // Deliver the captured frame to all observers (channels, renderer or file).
  ViEFrameProviderBase::DeliverFrame(video_frame);
}

void ViECapturer::DeliverCodedFrame(VideoFrame* video_frame) {
  if (encode_complete_callback_) {
    EncodedImage encoded_image(video_frame->Buffer(), video_frame->Length(),
                               video_frame->Size());
    encoded_image._timeStamp =
        90 * static_cast<WebRtc_UWord32>(video_frame->RenderTimeMs());
    encode_complete_callback_->Encoded(encoded_image);
  }

  if (NumberOfRegisteredFrameCallbacks() > 0 && decoder_initialized_) {
    video_frame->Swap(decode_buffer_.payloadData, decode_buffer_.bufferSize,
                     decode_buffer_.payloadSize);
    decode_buffer_.encodedHeight = video_frame->Height();
    decode_buffer_.encodedWidth = video_frame->Width();
    decode_buffer_.renderTimeMs = video_frame->RenderTimeMs();
    const int kMsToRtpTimestamp = 90;
    decode_buffer_.timeStamp = kMsToRtpTimestamp *
        static_cast<WebRtc_UWord32>(video_frame->RenderTimeMs());
    decode_buffer_.payloadType = codec_.plType;
    vcm_->DecodeFromStorage(decode_buffer_);
  }
}

int ViECapturer::DeregisterFrameCallback(
    const ViEFrameCallback* callbackObject) {
  provider_cs_->Enter();
  if (callbackObject == vie_encoder_) {
    // Don't use this camera as encoder anymore. Need to tell the ViEEncoder.
    ViEEncoder* vie_encoder = NULL;
    vie_encoder = vie_encoder_;
    vie_encoder_ = NULL;
    provider_cs_->Leave();

    // Need to take this here in order to avoid deadlock with VCM. The reason is
    // that VCM will call ::Release and a deadlock can occur.
    deliver_cs_->Enter();
    vie_encoder->DeRegisterExternalEncoder(codec_.plType);
    deliver_cs_->Leave();
    return 0;
  }
  provider_cs_->Leave();
  return ViEFrameProviderBase::DeregisterFrameCallback(callbackObject);
}

bool ViECapturer::IsFrameCallbackRegistered(
    const ViEFrameCallback* callbackObject) {
  CriticalSectionScoped cs(provider_cs_.get());
  if (callbackObject == vie_encoder_) {
    return true;
  }
  return ViEFrameProviderBase::IsFrameCallbackRegistered(callbackObject);
}

WebRtc_Word32 ViECapturer::PreEncodeToViEEncoder(const VideoCodec& codec,
                                                 ViEEncoder& vie_encoder,
                                                 WebRtc_Word32 vie_encoder_id) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d)", __FUNCTION__, capture_id_);
  if (vie_encoder_ && &vie_encoder != vie_encoder_) {
    WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
                 "%s(capture_device_id: %d Capture device already encoding)",
                 __FUNCTION__, capture_id_);
    return -1;
  }

  CriticalSectionScoped cs(encoding_cs_.get());
  VideoCaptureModule::VideoCaptureEncodeInterface* capture_encoder =
    capture_module_->GetEncodeInterface(codec);
  if (!capture_encoder) {
    // Encoding not supported?
    return -1;
  }
  capture_encoder_ = capture_encoder;

  // Create VCM module used for decoding frames if needed.
  if (!vcm_) {
    vcm_ = VideoCodingModule::Create(capture_id_);
  }

  if (vie_encoder.RegisterExternalEncoder(this, codec.plType) != 0) {
    return -1;
  }
  if (vie_encoder.SetEncoder(codec) != 0) {
    vie_encoder.DeRegisterExternalEncoder(codec.plType);
    return -1;
  }

  // Make sure the encoder is not an I420 observer.
  ViEFrameProviderBase::DeregisterFrameCallback(&vie_encoder);
  // Store the vie_encoder using this capture device.
  vie_encoder_ = &vie_encoder;
  vie_encoder_id_ = vie_encoder_id;
  memcpy(&codec_, &codec, sizeof(VideoCodec));
  return 0;
}

bool ViECapturer::EncoderActive() {
  return vie_encoder_ != NULL;
}

bool ViECapturer::CaptureCapabilityFixed() {
  return requested_capability_.width != 0 &&
      requested_capability_.height != 0 &&
      requested_capability_.maxFPS != 0;
}

WebRtc_Word32 ViECapturer::Version(char* version,
                                   WebRtc_Word32 length) const {
  return 0;
}

WebRtc_Word32 ViECapturer::InitEncode(const VideoCodec* codec_settings,
                                      WebRtc_Word32 number_of_cores,
                                      WebRtc_UWord32 max_payload_size) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d)", __FUNCTION__, capture_id_);

  CriticalSectionScoped cs(encoding_cs_.get());
  if (!capture_encoder_ || !codec_settings) {
    return WEBRTC_VIDEO_CODEC_ERROR;
  }

  if (vcm_) {
    // Initialize VCM to be able to decode frames if needed.
    if (vcm_->InitializeReceiver() == 0) {
      if (vcm_->RegisterReceiveCallback(this) == 0) {
        if (vcm_->RegisterReceiveCodec(codec_settings, number_of_cores,
                                       false) == 0) {
          decoder_initialized_ = true;
          WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
                       "%s(capture_device_id: %d) VCM Decoder initialized",
                       __FUNCTION__, capture_id_);
        }
      }
    }
  }
  return capture_encoder_->ConfigureEncoder(*codec_settings, max_payload_size);
}

WebRtc_Word32 ViECapturer::Encode(
    const I420VideoFrame& input_image,
    const CodecSpecificInfo* codec_specific_info,
    const std::vector<VideoFrameType>* frame_types) {
  CriticalSectionScoped cs(encoding_cs_.get());
  if (!capture_encoder_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (frame_types == NULL) {
    return capture_encoder_->EncodeFrameType(kVideoFrameDelta);
  } else if ((*frame_types)[0] == kKeyFrame) {
    return capture_encoder_->EncodeFrameType(kVideoFrameKey);
  } else if ((*frame_types)[0] == kSkipFrame) {
    return capture_encoder_->EncodeFrameType(kFrameEmpty);
  }
  return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}

WebRtc_Word32 ViECapturer::RegisterEncodeCompleteCallback(
    EncodedImageCallback* callback) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d)", __FUNCTION__, capture_id_);

  CriticalSectionScoped cs(deliver_cs_.get());
  if (!capture_encoder_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  encode_complete_callback_ = callback;
  return 0;
}

WebRtc_Word32 ViECapturer::Release() {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d)", __FUNCTION__, capture_id_);
  {
    CriticalSectionScoped cs(deliver_cs_.get());
    encode_complete_callback_ = NULL;
  }

  {
    CriticalSectionScoped cs(encoding_cs_.get());

    decoder_initialized_ = false;
    codec_.codecType = kVideoCodecUnknown;
    // Reset the camera to output I420.
    capture_encoder_->ConfigureEncoder(codec_, 0);

    if (vie_encoder_) {
      // Need to add the encoder as an observer of I420.
      ViEFrameProviderBase::RegisterFrameCallback(vie_encoder_id_,
                                                  vie_encoder_);
    }
    vie_encoder_ = NULL;
  }
  return 0;
}

// Should reset the capture device to the state it was in after the InitEncode
// function. Current implementation do nothing.
WebRtc_Word32 ViECapturer::Reset() {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d)", __FUNCTION__, capture_id_);
  return 0;
}

WebRtc_Word32 ViECapturer::SetChannelParameters(WebRtc_UWord32 packet_loss,
                                                int rtt) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d)", __FUNCTION__, capture_id_);

  CriticalSectionScoped cs(encoding_cs_.get());
  if (!capture_encoder_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  return capture_encoder_->SetChannelParameters(packet_loss, rtt);
}

WebRtc_Word32 ViECapturer::SetRates(WebRtc_UWord32 new_bit_rate,
                                    WebRtc_UWord32 frame_rate) {
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, capture_id_),
               "%s(capture_device_id: %d)", __FUNCTION__, capture_id_);

  CriticalSectionScoped cs(encoding_cs_.get());
  if (!capture_encoder_) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  return capture_encoder_->SetRates(new_bit_rate, frame_rate);
}

WebRtc_Word32 ViECapturer::FrameToRender(
    I420VideoFrame& video_frame) {  //NOLINT
  deliver_cs_->Enter();
  DeliverI420Frame(&video_frame);
  deliver_cs_->Leave();
  return 0;
}

WebRtc_Word32 ViECapturer::RegisterObserver(ViECaptureObserver* observer) {
  if (observer_) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                 "%s Observer already registered", __FUNCTION__, capture_id_);
    return -1;
  }
  if (capture_module_->RegisterCaptureCallback(*this) != 0) {
    return -1;
  }
  capture_module_->EnableFrameRateCallback(true);
  capture_module_->EnableNoPictureAlarm(true);
  observer_ = observer;
  return 0;
}

WebRtc_Word32 ViECapturer::DeRegisterObserver() {
  CriticalSectionScoped cs(observer_cs_.get());
  if (!observer_) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, capture_id_),
                 "%s No observer registered", __FUNCTION__, capture_id_);
    return -1;
  }
  capture_module_->EnableFrameRateCallback(false);
  capture_module_->EnableNoPictureAlarm(false);
  capture_module_->DeRegisterCaptureCallback();
  observer_ = NULL;
  return 0;
}

bool ViECapturer::IsObserverRegistered() {
  CriticalSectionScoped cs(observer_cs_.get());
  return observer_ != NULL;
}

void ViECapturer::OnCaptureFrameRate(const WebRtc_Word32 id,
                                     const WebRtc_UWord32 frame_rate) {
  WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, capture_id_),
               "OnCaptureFrameRate %d", frame_rate);

  CriticalSectionScoped cs(observer_cs_.get());
  observer_->CapturedFrameRate(id_, (WebRtc_UWord8) frame_rate);
}

void ViECapturer::OnNoPictureAlarm(const WebRtc_Word32 id,
                                   const VideoCaptureAlarm alarm) {
  WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, capture_id_),
               "OnNoPictureAlarm %d", alarm);

  CriticalSectionScoped cs(observer_cs_.get());
  CaptureAlarm vie_alarm = (alarm == Raised) ? AlarmRaised : AlarmCleared;
  observer_->NoPictureAlarm(id, vie_alarm);
}

}  // namespace webrtc
