/*
 *  Copyright (c) 2011 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 "engine_configurations.h"

#include "video_engine/vie_file_impl.h"

#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
#include "common_video/jpeg/main/interface/jpeg.h"
#include "system_wrappers/interface/condition_variable_wrapper.h"
#include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/trace.h"
#include "video_engine/include/vie_errors.h"
#include "video_engine/vie_capturer.h"
#include "video_engine/vie_channel.h"
#include "video_engine/vie_channel_manager.h"
#include "video_engine/vie_defines.h"
#include "video_engine/vie_encoder.h"
#include "video_engine/vie_file_image.h"
#include "video_engine/vie_file_player.h"
#include "video_engine/vie_file_recorder.h"
#include "video_engine/vie_impl.h"
#include "video_engine/vie_input_manager.h"
#include "video_engine/vie_render_manager.h"
#include "video_engine/vie_renderer.h"
#endif

namespace webrtc {

ViEFile* ViEFile::GetInterface(VideoEngine* video_engine) {
#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
  if (!video_engine) {
    return NULL;
  }
  VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
  ViEFileImpl* vie_file_impl = vie_impl;
  // Increase ref count.
  (*vie_file_impl)++;
  return vie_file_impl;
#else
  return NULL;
#endif
}

#ifdef WEBRTC_VIDEO_ENGINE_FILE_API

int ViEFileImpl::Release() {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, instance_id_,
               "ViEFile::Release()");
  // Decrease ref count.
  (*this)--;
  WebRtc_Word32 ref_count = GetCount();
  if (ref_count < 0) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo, instance_id_,
                 "ViEFile release too many times");
    SetLastError(kViEAPIDoesNotExist);
    return -1;
  }
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, instance_id_,
               "ViEFile reference count: %d", ref_count);
  return ref_count;
}

ViEFileImpl::ViEFileImpl() {
  WEBRTC_TRACE(kTraceMemory, kTraceVideo, instance_id_,
               "ViEFileImpl::ViEFileImpl() Ctor");
}

ViEFileImpl::~ViEFileImpl() {
  WEBRTC_TRACE(kTraceMemory, kTraceVideo, instance_id_,
               "ViEFileImpl::~ViEFileImpl() Dtor");
}

int ViEFileImpl::StartPlayFile(const char* file_nameUTF8,
                               int& file_id,
                               const bool loop,
                               const FileFormats file_format) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_), "%s",
               __FUNCTION__);

  if (!Initialized()) {
    SetLastError(kViENotInitialized);
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s - ViE instance %d not initialized", __FUNCTION__,
                 instance_id_);
    return -1;
  }

  VoiceEngine* voice = channel_manager_.GetVoiceEngine();
  const WebRtc_Word32 result = input_manager_.CreateFilePlayer(file_nameUTF8,
                                                               loop,
                                                               file_format,
                                                               voice, file_id);
  if (result != 0) {
    SetLastError(result);
    return -1;
  }
  return 0;
}

int ViEFileImpl::StopPlayFile(const int file_id) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_),
               "%s(file_id: %d)", __FUNCTION__, file_id);
  {
    ViEInputManagerScoped is(input_manager_);
    ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
    if (!vie_file_player) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                   "%s: File with id %d is not playing.", __FUNCTION__,
                   file_id);
      SetLastError(kViEFileNotPlaying);
      return -1;
    }
  }
  // Destroy the capture device.
  return input_manager_.DestroyFilePlayer(file_id);
}

int ViEFileImpl::RegisterObserver(int file_id, ViEFileObserver& observer) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_),
               "%s(file_id: %d)", __FUNCTION__, file_id);

  ViEInputManagerScoped is(input_manager_);
  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileNotPlaying);
    return -1;
  }
  if (vie_file_player->IsObserverRegistered()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, file_id),
                 "%s: Observer already registered", __FUNCTION__);
    SetLastError(kViEFileObserverAlreadyRegistered);
    return -1;
  }
  if (vie_file_player->RegisterObserver(observer) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, file_id),
                 "%s: Failed to register observer", __FUNCTION__, file_id);
    SetLastError(kViEFileUnknownError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::DeregisterObserver(int file_id, ViEFileObserver& observer) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_),
               "%s(file_id: %d)", __FUNCTION__, file_id);

  ViEInputManagerScoped is(input_manager_);
  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileNotPlaying);
    return -1;
  }
  if (!vie_file_player->IsObserverRegistered()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(instance_id_, file_id), "%s: No Observer registered",
                 __FUNCTION__);
    SetLastError(kViEFileObserverNotRegistered);
    return -1;
  }
  if (vie_file_player->DeRegisterObserver() != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, file_id),
                 "%s: Failed to deregister observer", __FUNCTION__, file_id);
    SetLastError(kViEFileUnknownError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::SendFileOnChannel(const int file_id, const int video_channel) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_),
               "%s(file_id: %d)", __FUNCTION__, file_id);

  ViEChannelManagerScoped cs(channel_manager_);
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  if (!vie_encoder) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidChannelId);
    return -1;
  }

  ViEInputManagerScoped is(input_manager_);
  if (is.FrameProvider(vie_encoder) != NULL) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d already connected to a capture device or "
                 "file.", __FUNCTION__, video_channel);
    SetLastError(kViEFileInputAlreadyConnected);
    return -1;
  }

  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileNotPlaying);
    return -1;
  }

  if (vie_file_player->RegisterFrameCallback(video_channel, vie_encoder)
      != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: Failed to register frame callback.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileUnknownError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::StopSendFileOnChannel(const int video_channel) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_),
               "%s(video_channel: %d)", __FUNCTION__, video_channel);

  ViEChannelManagerScoped cs(channel_manager_);
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  if (!vie_encoder) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidChannelId);
    return -1;
  }

  ViEInputManagerScoped is(input_manager_);
  ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
  if (!frame_provider ||
      frame_provider->Id() < kViEFileIdBase ||
      frame_provider->Id() > kViEFileIdMax) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: No file connected to Channel %d", __FUNCTION__,
                 video_channel);
    SetLastError(kViEFileNotConnected);
    return -1;
  }
  if (frame_provider->DeregisterFrameCallback(vie_encoder) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Failed to deregister file from channel %d",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileUnknownError);
  }
  return 0;
}

int ViEFileImpl::StartPlayFileAsMicrophone(const int file_id,
                                           const int audio_channel,
                                           bool mix_microphone,
                                           float volume_scaling) {
  ViEInputManagerScoped is(input_manager_);

  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileNotPlaying);
    return -1;
  }
  if (vie_file_player->SendAudioOnChannel(audio_channel, mix_microphone,
  volume_scaling) != 0) {
    SetLastError(kViEFileVoEFailure);
    return -1;
  }
  return 0;
}

int ViEFileImpl::StopPlayFileAsMicrophone(const int file_id,
const int audio_channel) {
  ViEInputManagerScoped is(input_manager_);

  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileNotPlaying);
    return -1;
  }

  if (vie_file_player->StopSendAudioOnChannel(audio_channel) != 0) {
    SetLastError(kViEFileVoEFailure);
    return -1;
  }
  return 0;
}

int ViEFileImpl::StartPlayAudioLocally(const int file_id,
                                       const int audio_channel,
                                       float volume_scaling) {
  ViEInputManagerScoped is(input_manager_);

  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileNotPlaying);
    return -1;
  }
  if (vie_file_player->PlayAudioLocally(audio_channel, volume_scaling) != 0) {
    SetLastError(kViEFileVoEFailure);
    return -1;
  }
  return 0;
}

int ViEFileImpl::StopPlayAudioLocally(const int file_id,
                                      const int audio_channel) {
  ViEInputManagerScoped is(input_manager_);

  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    SetLastError(kViEFileNotPlaying);
    return -1;
  }
  if (vie_file_player->StopPlayAudioLocally(audio_channel) != 0) {
    SetLastError(kViEFileVoEFailure);
    return -1;
  }
  return 0;
}

int ViEFileImpl::StartRecordOutgoingVideo(const int video_channel,
                                          const char* file_nameUTF8,
                                          AudioSource audio_source,
                                          const CodecInst& audio_codec,
                                          const VideoCodec& video_codec,
                                          const FileFormats file_format) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
               "%s video_channel: %d)", __FUNCTION__, video_channel);

  ViEChannelManagerScoped cs(channel_manager_);
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  if (!vie_encoder) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidChannelId);
    return -1;
  }
  ViEFileRecorder& file_recorder = vie_encoder->GetOutgoingFileRecorder();
  if (file_recorder.RecordingStarted()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Already recording outgoing video on channel %d",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileAlreadyRecording);
    return -1;
  }

  WebRtc_Word32 ve_channel_id = -1;
  VoiceEngine* ve_ptr = NULL;
  if (audio_source != NO_AUDIO) {
    ViEChannel* vie_channel = cs.Channel(video_channel);
    // Channel should exists since we have a ViEEncoder.
    assert(vie_channel);
    ve_channel_id = vie_channel->VoiceChannel();
    ve_ptr = channel_manager_.GetVoiceEngine();
    if (!ve_ptr) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                   "%s: Can't access voice engine. Have SetVoiceEngine "
                   "been called?", __FUNCTION__);
      SetLastError(kViEFileVoENotSet);
      return -1;
    }
  }
  if (file_recorder.StartRecording(file_nameUTF8, video_codec, audio_source,
                                   ve_channel_id, audio_codec, ve_ptr,
                                   file_format) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Failed to start recording. Check arguments.",
                 __FUNCTION__);
    SetLastError(kViEFileUnknownError);
    return -1;
  }

  return 0;
}

int ViEFileImpl::StopRecordOutgoingVideo(const int video_channel) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
               ViEId(instance_id_, video_channel), "%s video_channel: %d)",
               __FUNCTION__, video_channel);

  ViEChannelManagerScoped cs(channel_manager_);
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  if (!vie_encoder) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidChannelId);
    return -1;
  }
  ViEFileRecorder& file_recorder = vie_encoder->GetOutgoingFileRecorder();
  if (!file_recorder.RecordingStarted()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d is not recording.", __FUNCTION__,
                 video_channel);
    SetLastError(kViEFileNotRecording);
    return -1;
  }
  if (file_recorder.StopRecording() != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Failed to stop recording of channel %d.", __FUNCTION__,
                 video_channel);
    SetLastError(kViEFileUnknownError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::StopRecordIncomingVideo(const int video_channel) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
               "%s video_channel: %d)", __FUNCTION__, video_channel);

  ViEChannelManagerScoped cs(channel_manager_);
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidChannelId);
    return -1;
  }
  ViEFileRecorder& file_recorder = vie_channel->GetIncomingFileRecorder();
  if (!file_recorder.RecordingStarted()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d is not recording.", __FUNCTION__,
                 video_channel);
    SetLastError(kViEFileNotRecording);
    vie_channel->ReleaseIncomingFileRecorder();
    return -1;
  }
  if (file_recorder.StopRecording() != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Failed to stop recording of channel %d.",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileUnknownError);
    vie_channel->ReleaseIncomingFileRecorder();
    return -1;
  }
  // Let the channel know we are no longer recording.
  vie_channel->ReleaseIncomingFileRecorder();
  return 0;
}

int ViEFileImpl::StartRecordIncomingVideo(const int video_channel,
                                          const char* file_nameUTF8,
                                          AudioSource audio_source,
                                          const CodecInst& audio_codec,
                                          const VideoCodec& video_codec,
                                          const FileFormats file_format) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
               "%s video_channel: %d)", __FUNCTION__, video_channel);

  ViEChannelManagerScoped cs(channel_manager_);
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__,
                 video_channel);
    SetLastError(kViEFileInvalidChannelId);
    return -1;
  }
  ViEFileRecorder& file_recorder = vie_channel->GetIncomingFileRecorder();
  if (file_recorder.RecordingStarted()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Already recording outgoing video on channel %d",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileAlreadyRecording);
    return -1;
  }

  WebRtc_Word32 ve_channel_id = -1;
  VoiceEngine* ve_ptr = NULL;
  if (audio_source != NO_AUDIO) {
    ve_channel_id = vie_channel->VoiceChannel();
    ve_ptr = channel_manager_.GetVoiceEngine();

    if (!ve_ptr) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                   "%s: Can't access voice engine. Have SetVoiceEngine "
                   "been called?", __FUNCTION__);
      SetLastError(kViEFileVoENotSet);
      return -1;
    }
  }
  if (file_recorder.StartRecording(file_nameUTF8, video_codec, audio_source,
                                   ve_channel_id, audio_codec, ve_ptr,
                                   file_format) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s: Failed to start recording. Check arguments.",
                 __FUNCTION__);
    SetLastError(kViEFileUnknownError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::GetFileInformation(const char* file_name,
                                    VideoCodec& video_codec,
                                    CodecInst& audio_codec,
                                    const FileFormats file_format) {
  return ViEFilePlayer::GetFileInformation(
           instance_id_, static_cast<const WebRtc_Word8*>(file_name),
           video_codec, audio_codec, file_format);
}

int ViEFileImpl::GetRenderSnapshot(const int video_channel,
                                   const char* file_nameUTF8) {
  // Gain access to the renderer for the specified channel and get it's
  // current frame.
  ViERenderManagerScoped rs(render_manager_);
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    return -1;
  }

  VideoFrame video_frame;
  if (renderer->GetLastRenderedFrame(video_channel, video_frame) == -1) {
    return -1;
  }

  // JPEGEncoder writes the jpeg file for you (no control over it) and does
  // not return you the buffer. Thus, we are not going to be writing to the
  // disk here.
  JpegEncoder jpeg_encoder;
  RawImage input_image;
  if (jpeg_encoder.SetFileName(file_nameUTF8) == -1) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "\tCould not open output file '%s' for writing!",
                 file_nameUTF8);
    return -1;
  }

  input_image._width = video_frame.Width();
  input_image._height = video_frame.Height();
  video_frame.Swap(input_image._buffer, input_image._length,
                   input_image._size);

  if (jpeg_encoder.Encode(input_image) == -1) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "\tCould not encode i420 -> jpeg file '%s' for writing!",
                 file_nameUTF8);
    if (input_image._buffer) {
      delete [] input_image._buffer;
      input_image._buffer = NULL;
    }
    return -1;
  }
  delete [] input_image._buffer;
  input_image._buffer = NULL;
  return 0;
}

int ViEFileImpl::GetRenderSnapshot(const int video_channel,
                                   ViEPicture& picture) {
  // Gain access to the renderer for the specified channel and get it's
  // current frame.
  ViERenderManagerScoped rs(render_manager_);
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    return -1;
  }

  VideoFrame video_frame;
  if (renderer->GetLastRenderedFrame(video_channel, video_frame) == -1) {
    return -1;
  }

  // Copy from VideoFrame class to ViEPicture struct.
  int buffer_length =
      static_cast<int>(video_frame.Width() * video_frame.Height() * 1.5);
  picture.data =  static_cast<WebRtc_UWord8*>(malloc(
      buffer_length * sizeof(WebRtc_UWord8)));
  memcpy(picture.data, video_frame.Buffer(), buffer_length);
  picture.size = buffer_length;
  picture.width = video_frame.Width();
  picture.height = video_frame.Height();
  picture.type = kVideoI420;
  return 0;
}

int ViEFileImpl::GetCaptureDeviceSnapshot(const int capture_id,
                                          const char* file_nameUTF8) {
  ViEInputManagerScoped is(input_manager_);
  ViECapturer* capturer = is.Capture(capture_id);
  if (!capturer) {
    return -1;
  }

  VideoFrame video_frame;
  if (GetNextCapturedFrame(capture_id, video_frame) == -1) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "Could not gain acces to capture device %d video frame "
                 "%s:%d", capture_id, __FUNCTION__);
    return -1;
  }

  // JPEGEncoder writes the jpeg file for you (no control over it) and does
  // not return you the buffer Thusly, we are not going to be writing to the
  // disk here.
  JpegEncoder jpeg_encoder;
  RawImage input_image;
  input_image._width = video_frame.Width();
  input_image._height = video_frame.Height();
  video_frame.Swap(input_image._buffer, input_image._length,
                   input_image._size);

  if (jpeg_encoder.SetFileName(file_nameUTF8) == -1) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "\tCould not open output file '%s' for writing!",
                 file_nameUTF8);

    if (input_image._buffer) {
      delete [] input_image._buffer;
    }
    return -1;
  }
  if (jpeg_encoder.Encode(input_image) == -1) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "\tCould not encode i420 -> jpeg file '%s' for "
                 "writing!", file_nameUTF8);
    if (input_image._buffer) {
      delete [] input_image._buffer;
    }
    return -1;
  }
  delete [] input_image._buffer;
  input_image._buffer = NULL;
  return 0;
}

int ViEFileImpl::GetCaptureDeviceSnapshot(const int capture_id,
                                          ViEPicture& picture) {
  VideoFrame video_frame;
  ViEInputManagerScoped is(input_manager_);
  ViECapturer* capturer = is.Capture(capture_id);
  if (!capturer) {
    return -1;
  }
  if (GetNextCapturedFrame(capture_id, video_frame) == -1) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "Could not gain acces to capture device %d video frame "
                 "%s:%d", capture_id, __FUNCTION__);
    return -1;
  }

  // Copy from VideoFrame class to ViEPicture struct.
  int buffer_length =
      static_cast<int>(video_frame.Width() * video_frame.Height() * 1.5);
  picture.data = static_cast<WebRtc_UWord8*>(malloc(
      buffer_length * sizeof(WebRtc_UWord8)));
  memcpy(picture.data, video_frame.Buffer(), buffer_length);
  picture.size = buffer_length;
  picture.width = video_frame.Width();
  picture.height = video_frame.Height();
  picture.type = kVideoI420;
  return 0;
}

int ViEFileImpl::FreePicture(ViEPicture& picture) {
  if (picture.data) {
    free(picture.data);
  }

  picture.data = NULL;
  picture.size = 0;
  picture.width = 0;
  picture.height = 0;
  picture.type = kVideoUnknown;
  return 0;
}
int ViEFileImpl::SetCaptureDeviceImage(const int capture_id,
                                       const char* file_nameUTF8) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, instance_id_,
               "%s(capture_id: %d)", __FUNCTION__, capture_id);

  ViEInputManagerScoped is(input_manager_);
  ViECapturer* capturer = is.Capture(capture_id);
  if (!capturer) {
    SetLastError(kViEFileInvalidCaptureId);
    return -1;
  }

  VideoFrame capture_image;
  if (ViEFileImage::ConvertJPEGToVideoFrame(
  ViEId(instance_id_, capture_id), file_nameUTF8, capture_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(instance_id_, capture_id),
                 "%s(capture_id: %d) Failed to open file.", __FUNCTION__,
                 capture_id);
    SetLastError(kViEFileInvalidFile);
    return -1;
  }
  if (capturer->SetCaptureDeviceImage(capture_image)) {
    SetLastError(kViEFileSetCaptureImageError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::SetCaptureDeviceImage(const int capture_id,
const ViEPicture& picture) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, instance_id_,
               "%s(capture_id: %d)", __FUNCTION__, capture_id);

  if (picture.type != kVideoI420) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, capture_id),
                 "%s(capture_id: %d) Not a valid picture type.",
                 __FUNCTION__, capture_id);
    SetLastError(kViEFileInvalidArgument);
    return -1;
  }
  ViEInputManagerScoped is(input_manager_);
  ViECapturer* capturer = is.Capture(capture_id);
  if (!capturer) {
    SetLastError(kViEFileSetCaptureImageError);
    return -1;
  }

  VideoFrame capture_image;
  if (ViEFileImage::ConvertPictureToVideoFrame(
  ViEId(instance_id_, capture_id), picture, capture_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, capture_id),
                 "%s(capture_id: %d) Failed to use picture.", __FUNCTION__,
                 capture_id);
    SetLastError(kViEFileInvalidFile);
    return -1;
  }
  if (capturer->SetCaptureDeviceImage(capture_image)) {
    SetLastError(kViEFileInvalidCapture);
    return -1;
  }
  return 0;
}

int ViEFileImpl::SetRenderStartImage(const int video_channel,
const char* file_nameUTF8) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
               "%s(video_channel: %d)", __FUNCTION__, video_channel);

  ViERenderManagerScoped rs(render_manager_);
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    SetLastError(kViEFileInvalidRenderId);
    return -1;
  }

  VideoFrame start_image;
  if (ViEFileImage::ConvertJPEGToVideoFrame(
  ViEId(instance_id_, video_channel), file_nameUTF8, start_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Failed to open file.", __FUNCTION__,
                 video_channel);
    SetLastError(kViEFileInvalidFile);
    return -1;
  }
  if (renderer->SetRenderStartImage(start_image) != 0) {
    SetLastError(kViEFileSetStartImageError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::SetRenderStartImage(const int video_channel,
                                     const ViEPicture& picture) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
               ViEId(instance_id_, video_channel), "%s(video_channel: %d)",
               __FUNCTION__, video_channel);
  if (picture.type != kVideoI420) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Not a valid picture type.",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidArgument);
    return -1;
  }

  ViERenderManagerScoped rs(render_manager_);
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    SetLastError(kViEFileInvalidRenderId);
    return -1;
  }

  VideoFrame start_image;
  if (ViEFileImage::ConvertPictureToVideoFrame(
  ViEId(instance_id_, video_channel), picture, start_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Failed to use picture.",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidCapture);
    return -1;
  }
  if (renderer->SetRenderStartImage(start_image) != 0) {
    SetLastError(kViEFileSetStartImageError);
    return -1;
  }
  return 0;
}
int ViEFileImpl::SetRenderTimeoutImage(const int video_channel,
                                       const char* file_nameUTF8,
                                       const unsigned int timeout_ms) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
               "%s(video_channel: %d)", __FUNCTION__, video_channel);

  ViERenderManagerScoped rs(render_manager_);
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    SetLastError(kViEFileInvalidRenderId);
    return -1;
  }
  VideoFrame timeout_image;
  if (ViEFileImage::ConvertJPEGToVideoFrame(
  ViEId(instance_id_, video_channel), file_nameUTF8, timeout_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Failed to open file.", __FUNCTION__,
                 video_channel);
    SetLastError(kViEFileInvalidFile);
    return -1;
  }
  WebRtc_Word32 timeout_time = timeout_ms;
  if (timeout_ms < kViEMinRenderTimeoutTimeMs) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
                 __FUNCTION__, video_channel, kViEMinRenderTimeoutTimeMs);
    timeout_time = kViEMinRenderTimeoutTimeMs;
  }
  if (timeout_ms > kViEMaxRenderTimeoutTimeMs) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
                 __FUNCTION__, video_channel, kViEMaxRenderTimeoutTimeMs);
    timeout_time = kViEMaxRenderTimeoutTimeMs;
  }
  if (renderer->SetTimeoutImage(timeout_image, timeout_time) != 0) {
    SetLastError(kViEFileSetRenderTimeoutError);
    return -1;
  }
  return 0;
}

int ViEFileImpl::SetRenderTimeoutImage(const int video_channel,
                                       const ViEPicture& picture,
const unsigned int timeout_ms) {
  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
               "%s(video_channel: %d)", __FUNCTION__, video_channel);

  if (picture.type != kVideoI420) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Not a valid picture type.",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidArgument);
    return -1;
  }

  ViERenderManagerScoped rs(render_manager_);
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    SetLastError(kViEFileSetRenderTimeoutError);
    return -1;
  }
  VideoFrame timeout_image;
  if (ViEFileImage::ConvertPictureToVideoFrame(
  ViEId(instance_id_, video_channel), picture, timeout_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Failed to use picture.",
                 __FUNCTION__, video_channel);
    SetLastError(kViEFileInvalidCapture);
    return -1;
  }
  WebRtc_Word32 timeout_time = timeout_ms;
  if (timeout_ms < kViEMinRenderTimeoutTimeMs) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
                 __FUNCTION__, video_channel, kViEMinRenderTimeoutTimeMs);
    timeout_time = kViEMinRenderTimeoutTimeMs;
  }
  if (timeout_ms > kViEMaxRenderTimeoutTimeMs) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(instance_id_, video_channel),
                 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
                 __FUNCTION__, video_channel, kViEMaxRenderTimeoutTimeMs);
    timeout_time = kViEMaxRenderTimeoutTimeMs;
  }
  if (renderer->SetTimeoutImage(timeout_image, timeout_time) != 0) {
    SetLastError(kViEFileSetRenderTimeoutError);
    return -1;
  }
  return 0;
}

WebRtc_Word32 ViEFileImpl::GetNextCapturedFrame(WebRtc_Word32 capture_id,
VideoFrame& video_frame) {
  ViEInputManagerScoped is(input_manager_);
  ViECapturer* capturer = is.Capture(capture_id);
  if (!capturer) {
    return -1;
  }

  ViECaptureSnapshot* snap_shot = new ViECaptureSnapshot();
  capturer->RegisterFrameCallback(-1, snap_shot);
  bool snapshot_taken = snap_shot->GetSnapshot(
      video_frame, kViECaptureMaxSnapshotWaitTimeMs);

  // Check once again if it has been destroyed.
  capturer->DeregisterFrameCallback(snap_shot);
  delete snap_shot;
  snap_shot = NULL;

  if (snapshot_taken) {
    return 0;
  }
  return -1;
}

ViECaptureSnapshot::ViECaptureSnapshot()
    : crit_(CriticalSectionWrapper::CreateCriticalSection()),
      condition_varaible_(ConditionVariableWrapper::CreateConditionVariable()),
      video_frame_(NULL) {
}

ViECaptureSnapshot::~ViECaptureSnapshot() {
  if (video_frame_) {
    delete video_frame_;
    video_frame_ = NULL;
  }
}

bool ViECaptureSnapshot::GetSnapshot(VideoFrame& video_frame,
                                     unsigned int max_wait_time) {
  crit_->Enter();
  video_frame_ = new VideoFrame();
  if (condition_varaible_->SleepCS(*(crit_.get()), max_wait_time)) {
    // Snapshot taken.
    video_frame.SwapFrame(*video_frame_);
    delete video_frame_;
    video_frame_ = NULL;
    crit_->Leave();
    return true;
  }
  crit_->Leave();
  return false;
}

void ViECaptureSnapshot::DeliverFrame(int id, VideoFrame& video_frame,
                                      int num_csrcs,
const WebRtc_UWord32 CSRC[kRtpCsrcSize]) {
  CriticalSectionScoped cs(crit_.get());
  if (!video_frame_) {
    return;
  }
  video_frame_->SwapFrame(video_frame);
  condition_varaible_->WakeAll();
  return;
}

#endif

}  // namespace webrtc
