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

#include "video_engine/vie_file_impl.h"

#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
#include "common_video/jpeg/include/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, shared_data_->instance_id(),
               "ViEFile::Release()");
  // Decrease ref count.
  (*this)--;
  WebRtc_Word32 ref_count = GetCount();
  if (ref_count < 0) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
                 "ViEFile release too many times");
    shared_data_->SetLastError(kViEAPIDoesNotExist);
    return -1;
  }
  WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
               "ViEFile reference count: %d", ref_count);
  return ref_count;
}

ViEFileImpl::ViEFileImpl(ViESharedData* shared_data)
    : shared_data_(shared_data) {
  WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
               "ViEFileImpl::ViEFileImpl() Ctor");
}

ViEFileImpl::~ViEFileImpl() {
  WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->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(shared_data_->instance_id()),
               "%s", __FUNCTION__);

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

  VoiceEngine* voice = shared_data_->channel_manager()->GetVoiceEngine();
  const WebRtc_Word32 result = shared_data_->input_manager()->CreateFilePlayer(
      file_nameUTF8, loop, file_format, voice, file_id);
  if (result != 0) {
    shared_data_->SetLastError(result);
    return -1;
  }
  return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

  ViEInputManagerScoped is(*(shared_data_->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(shared_data_->instance_id(), video_channel),
                 "%s: No file connected to Channel %d", __FUNCTION__,
                 video_channel);
    shared_data_->SetLastError(kViEFileNotConnected);
    return -1;
  }
  if (frame_provider->DeregisterFrameCallback(vie_encoder) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Failed to deregister file from channel %d",
                 __FUNCTION__, video_channel);
    shared_data_->SetLastError(kViEFileUnknownError);
  }
  return 0;
}

int ViEFileImpl::StartPlayFileAsMicrophone(const int file_id,
                                           const int audio_channel,
                                           bool mix_microphone,
                                           float volume_scaling) {
  ViEInputManagerScoped is(*(shared_data_->input_manager()));

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

int ViEFileImpl::StopPlayFileAsMicrophone(const int file_id,
                                          const int audio_channel) {
  ViEInputManagerScoped is(*(shared_data_->input_manager()));

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

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

int ViEFileImpl::StartPlayAudioLocally(const int file_id,
                                       const int audio_channel,
                                       float volume_scaling) {
  ViEInputManagerScoped is(*(shared_data_->input_manager()));

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

int ViEFileImpl::StopPlayAudioLocally(const int file_id,
                                      const int audio_channel) {
  ViEInputManagerScoped is(*(shared_data_->input_manager()));

  ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
  if (!vie_file_player) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
                 "%s: File with id %d is not playing.", __FUNCTION__,
                 file_id);
    shared_data_->SetLastError(kViEFileNotPlaying);
    return -1;
  }
  if (vie_file_player->StopPlayAudioLocally(audio_channel) != 0) {
    shared_data_->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(shared_data_->instance_id(), video_channel),
               "%s video_channel: %d)", __FUNCTION__, video_channel);

  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  if (!vie_encoder) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
    shared_data_->SetLastError(kViEFileInvalidChannelId);
    return -1;
  }
  ViEFileRecorder& file_recorder = vie_encoder->GetOutgoingFileRecorder();
  if (file_recorder.RecordingStarted()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Already recording outgoing video on channel %d",
                 __FUNCTION__, video_channel);
    shared_data_->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);
    if (!vie_channel) {
      // Channel should exists since we have a ViEEncoder above.
      assert(false);
      return -1;
    }
    ve_channel_id = vie_channel->VoiceChannel();
    ve_ptr = shared_data_->channel_manager()->GetVoiceEngine();
    if (!ve_ptr) {
      WEBRTC_TRACE(kTraceError, kTraceVideo,
                   ViEId(shared_data_->instance_id(), video_channel),
                   "%s: Can't access voice engine. Have SetVoiceEngine "
                   "been called?", __FUNCTION__);
      shared_data_->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(shared_data_->instance_id(), video_channel),
                 "%s: Failed to start recording. Check arguments.",
                 __FUNCTION__);
    shared_data_->SetLastError(kViEFileUnknownError);
    return -1;
  }

  return 0;
}

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

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

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

  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
    shared_data_->SetLastError(kViEFileInvalidChannelId);
    return -1;
  }
  ViEFileRecorder& file_recorder = vie_channel->GetIncomingFileRecorder();
  if (!file_recorder.RecordingStarted()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Channel %d is not recording.", __FUNCTION__,
                 video_channel);
    shared_data_->SetLastError(kViEFileNotRecording);
    vie_channel->ReleaseIncomingFileRecorder();
    return -1;
  }
  if (file_recorder.StopRecording() != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Failed to stop recording of channel %d.",
                 __FUNCTION__, video_channel);
    shared_data_->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(shared_data_->instance_id(), video_channel),
               "%s video_channel: %d)", __FUNCTION__, video_channel);

  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Channel %d doesn't exist", __FUNCTION__,
                 video_channel);
    shared_data_->SetLastError(kViEFileInvalidChannelId);
    return -1;
  }
  ViEFileRecorder& file_recorder = vie_channel->GetIncomingFileRecorder();
  if (file_recorder.RecordingStarted()) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s: Already recording outgoing video on channel %d",
                 __FUNCTION__, video_channel);
    shared_data_->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 = shared_data_->channel_manager()->GetVoiceEngine();

    if (!ve_ptr) {
      WEBRTC_TRACE(kTraceError, kTraceVideo,
                   ViEId(shared_data_->instance_id(), video_channel),
                   "%s: Can't access voice engine. Have SetVoiceEngine "
                   "been called?", __FUNCTION__);
      shared_data_->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(shared_data_->instance_id(), video_channel),
                 "%s: Failed to start recording. Check arguments.",
                 __FUNCTION__);
    shared_data_->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(
           shared_data_->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(*(shared_data_->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, shared_data_->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, shared_data_->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(*(shared_data_->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(*(shared_data_->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, shared_data_->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, shared_data_->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, shared_data_->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(*(shared_data_->input_manager()));
  ViECapturer* capturer = is.Capture(capture_id);
  if (!capturer) {
    return -1;
  }
  if (GetNextCapturedFrame(capture_id, video_frame) == -1) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->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, shared_data_->instance_id(),
               "%s(capture_id: %d)", __FUNCTION__, capture_id);

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

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

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

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

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

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

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

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

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

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

  VideoFrame start_image;
  if (ViEFileImage::ConvertPictureToVideoFrame(
  ViEId(shared_data_->instance_id(), video_channel), picture, start_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s(video_channel: %d) Failed to use picture.",
                 __FUNCTION__, video_channel);
    shared_data_->SetLastError(kViEFileInvalidCapture);
    return -1;
  }
  if (renderer->SetRenderStartImage(start_image) != 0) {
    shared_data_->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(shared_data_->instance_id(), video_channel),
               "%s(video_channel: %d)", __FUNCTION__, video_channel);

  ViERenderManagerScoped rs(*(shared_data_->render_manager()));
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    shared_data_->SetLastError(kViEFileInvalidRenderId);
    return -1;
  }
  VideoFrame timeout_image;
  if (ViEFileImage::ConvertJPEGToVideoFrame(
          ViEId(shared_data_->instance_id(), video_channel), file_nameUTF8,
          timeout_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s(video_channel: %d) Failed to open file.", __FUNCTION__,
                 video_channel);
    shared_data_->SetLastError(kViEFileInvalidFile);
    return -1;
  }
  WebRtc_Word32 timeout_time = timeout_ms;
  if (timeout_ms < kViEMinRenderTimeoutTimeMs) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo,
                 ViEId(shared_data_->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(shared_data_->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) {
    shared_data_->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(shared_data_->instance_id(), video_channel),
               "%s(video_channel: %d)", __FUNCTION__, video_channel);

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

  ViERenderManagerScoped rs(*(shared_data_->render_manager()));
  ViERenderer* renderer = rs.Renderer(video_channel);
  if (!renderer) {
    shared_data_->SetLastError(kViEFileSetRenderTimeoutError);
    return -1;
  }
  VideoFrame timeout_image;
  if (ViEFileImage::ConvertPictureToVideoFrame(
          ViEId(shared_data_->instance_id(), video_channel), picture,
          timeout_image) != 0) {
    WEBRTC_TRACE(kTraceError, kTraceVideo,
                 ViEId(shared_data_->instance_id(), video_channel),
                 "%s(video_channel: %d) Failed to use picture.",
                 __FUNCTION__, video_channel);
    shared_data_->SetLastError(kViEFileInvalidCapture);
    return -1;
  }
  WebRtc_Word32 timeout_time = timeout_ms;
  if (timeout_ms < kViEMinRenderTimeoutTimeMs) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideo,
                 ViEId(shared_data_->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(shared_data_->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) {
    shared_data_->SetLastError(kViEFileSetRenderTimeoutError);
    return -1;
  }
  return 0;
}

WebRtc_Word32 ViEFileImpl::GetNextCapturedFrame(WebRtc_Word32 capture_id,
VideoFrame& video_frame) {
  ViEInputManagerScoped is(*(shared_data_->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
