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

#include "modules/utility/interface/file_player.h"
#include "modules/utility/interface/file_recorder.h"
#include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/tick_util.h"
#include "system_wrappers/interface/trace.h"
#include "video_engine/vie_defines.h"

namespace webrtc {

ViEFileRecorder::ViEFileRecorder(int instanceID)
    : recorder_cs_(CriticalSectionWrapper::CreateCriticalSection()),
      file_recorder_(NULL),
      is_first_frame_recorded_(false),
      is_out_stream_started_(false),
      instance_id_(instanceID),
      frame_delay_(0),
      audio_channel_(-1),
      audio_source_(NO_AUDIO),
      voe_file_interface_(NULL) {
}

ViEFileRecorder::~ViEFileRecorder() {
  StopRecording();
  delete recorder_cs_;
}

int ViEFileRecorder::StartRecording(const char* file_nameUTF8,
                                    const VideoCodec& codec_inst,
                                    AudioSource audio_source,
                                    int audio_channel,
                                    const CodecInst& audio_codec_inst,
                                    VoiceEngine* voe_ptr,
                                    const FileFormats file_format) {
  CriticalSectionScoped lock(recorder_cs_);

  if (file_recorder_) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "ViEFileRecorder::StartRecording() - already recording.");
    return -1;
  }
  file_recorder_ = FileRecorder::CreateFileRecorder(instance_id_, file_format);
  if (!file_recorder_) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "ViEFileRecorder::StartRecording() failed to create recoder.");
    return -1;
  }

  int error = file_recorder_->StartRecordingVideoFile(file_nameUTF8,
                                                      audio_codec_inst,
                                                      codec_inst,
                                                      AMRFileStorage,
                                                      audio_source == NO_AUDIO);
  if (error) {
    WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                 "ViEFileRecorder::StartRecording() failed to "
                 "StartRecordingVideoFile.");
    FileRecorder::DestroyFileRecorder(file_recorder_);
    file_recorder_ = NULL;
    return -1;
  }

  audio_source_ = audio_source;
  if (voe_ptr && audio_source != NO_AUDIO) {
    // VoE interface has been provided and we want to record audio.
    voe_file_interface_ = VoEFile::GetInterface(voe_ptr);
    if (!voe_file_interface_) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                   "ViEFileRecorder::StartRecording() failed to get VEFile "
                   "interface");
      return -1;
    }

    // Always L16.
    CodecInst engine_audio_codec_inst = {96, "L16", audio_codec_inst.plfreq,
                                         audio_codec_inst.plfreq / 100, 1,
                                         audio_codec_inst.plfreq * 16 };

    switch (audio_source) {
      // case NO_AUDIO is checked above.
      case MICROPHONE:
        error = voe_file_interface_->StartRecordingMicrophone(
            this, &engine_audio_codec_inst);
        break;
      case PLAYOUT:
        error = voe_file_interface_->StartRecordingPlayout(
            audio_channel, this, &engine_audio_codec_inst);
        break;
      default:
        assert(false && "Unknown audio_source");
    }
    if (error != 0) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                   "ViEFileRecorder::StartRecording() failed to start recording"
                   " audio");
      FileRecorder::DestroyFileRecorder(file_recorder_);
      file_recorder_ = NULL;
      return -1;
    }
    is_out_stream_started_ = true;
    audio_channel_ = audio_channel;
  }
  is_first_frame_recorded_ = false;
  return 0;
}

int ViEFileRecorder::StopRecording() {
  int error = 0;
  // We can not hold the ptr_cs_ while accessing VoE functions. It might cause
  // deadlock in Write.
  if (voe_file_interface_) {
    switch (audio_source_) {
      case MICROPHONE:
        error = voe_file_interface_->StopRecordingMicrophone();
        break;
      case PLAYOUT:
        error = voe_file_interface_->StopRecordingPlayout(audio_channel_);
        break;
      case NO_AUDIO:
        break;
      default:
        assert(false && "Unknown audio_source");
    }
    if (error != 0) {
      WEBRTC_TRACE(kTraceError, kTraceVideo, instance_id_,
                   "ViEFileRecorder::StopRecording() failed to stop recording "
                   "audio");
    }
  }
  CriticalSectionScoped lock(recorder_cs_);
  if (voe_file_interface_) {
    voe_file_interface_->Release();
    voe_file_interface_ = NULL;
  }

  if (file_recorder_) {
    if (file_recorder_->IsRecording()) {
      int error = file_recorder_->StopRecording();
      if (error) {
        return -1;
      }
    }
    FileRecorder::DestroyFileRecorder(file_recorder_);
    file_recorder_ = NULL;
  }
  is_first_frame_recorded_ = false;
  is_out_stream_started_ = false;
  return 0;
}

void ViEFileRecorder::SetFrameDelay(int frame_delay) {
  CriticalSectionScoped lock(recorder_cs_);
  frame_delay_ = frame_delay;
}

bool ViEFileRecorder::RecordingStarted() {
  CriticalSectionScoped lock(recorder_cs_);
  return file_recorder_ && file_recorder_->IsRecording();
}

bool ViEFileRecorder::FirstFrameRecorded() {
  CriticalSectionScoped lock(recorder_cs_);
  return is_first_frame_recorded_;
}

bool ViEFileRecorder::IsRecordingFileFormat(const FileFormats file_format) {
  CriticalSectionScoped lock(recorder_cs_);
  return (file_recorder_->RecordingFileFormat() == file_format) ? true : false;
}

void ViEFileRecorder::RecordVideoFrame(const I420VideoFrame& video_frame) {
  CriticalSectionScoped lock(recorder_cs_);

  if (file_recorder_ && file_recorder_->IsRecording()) {
    if (!IsRecordingFileFormat(kFileFormatAviFile))
      return;

    // Compensate for frame delay in order to get audio/video sync when
    // recording local video.
    const WebRtc_UWord32 time_stamp = video_frame.timestamp();
    const WebRtc_Word64 render_time_stamp = video_frame.render_time_ms();
    I420VideoFrame& unconst_video_frame =
        const_cast<I420VideoFrame&>(video_frame);
    unconst_video_frame.set_timestamp(time_stamp - 90 * frame_delay_);
    unconst_video_frame.set_render_time_ms(render_time_stamp - frame_delay_);

    file_recorder_->RecordVideoToFile(unconst_video_frame);

    unconst_video_frame.set_render_time_ms(render_time_stamp);
    unconst_video_frame.set_timestamp(time_stamp);
  }
}

bool ViEFileRecorder::Write(const void* buf, int len) {
  if (!is_out_stream_started_)
    return true;

  // Always 10 ms L16 from VoE.
  if (len % (2 * 80)) {
    // Not 2 bytes 80 samples.
    WEBRTC_TRACE(kTraceError, kTraceVideo, audio_channel_,
                 "Audio length not supported: %d.", len);
    return true;
  }

  AudioFrame audio_frame;
  WebRtc_UWord16 length_in_samples = len / 2;
  audio_frame.UpdateFrame(audio_channel_, 0,
                          static_cast<const WebRtc_Word16*>(buf),
                          length_in_samples, length_in_samples * 100,
                          AudioFrame::kUndefined,
                          AudioFrame::kVadUnknown);

  CriticalSectionScoped lock(recorder_cs_);
  if (file_recorder_ && file_recorder_->IsRecording()) {
    TickTime tick_time = TickTime::Now();
    file_recorder_->RecordAudioToFile(audio_frame, &tick_time);
  }

  // Always return true to continue recording.
  return true;
}

int ViEFileRecorder::Rewind() {
  // Not supported!
  return -1;
}

}  // namespace webrtc
