/*
 *  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 "webrtc/modules/video_coding/main/test/receiver_tests.h"
#include "webrtc/modules/video_coding/main/test/vcm_payload_sink_factory.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/test/testsupport/fileutils.h"

namespace {

const bool kConfigProtectionEnabled = true;
const webrtc::VCMVideoProtection kConfigProtectionMethod =
    webrtc::kProtectionNack;
const float kConfigLossRate = 0.0f;
const bool kConfigReordering = false;
const int64_t kConfigRttMs = 0;
const uint32_t kConfigRenderDelayMs = 0;
const uint32_t kConfigMinPlayoutDelayMs = 0;
const int64_t kConfigMaxRuntimeMs = -1;
const uint8_t kDefaultUlpFecPayloadType = 97;
const uint8_t kDefaultRedPayloadType = 96;
const uint8_t kDefaultVp8PayloadType = 100;
}  // namespace

int RtpPlay(const CmdArgs& args) {
  std::string trace_file = webrtc::test::OutputPath() + "receiverTestTrace.txt";
  webrtc::Trace::CreateTrace();
  webrtc::Trace::SetTraceFile(trace_file.c_str());
  webrtc::Trace::set_level_filter(webrtc::kTraceAll);

  webrtc::rtpplayer::PayloadTypes payload_types;
  payload_types.push_back(webrtc::rtpplayer::PayloadCodecTuple(
      kDefaultUlpFecPayloadType, "ULPFEC", webrtc::kVideoCodecULPFEC));
  payload_types.push_back(webrtc::rtpplayer::PayloadCodecTuple(
      kDefaultRedPayloadType, "RED", webrtc::kVideoCodecRED));
  payload_types.push_back(webrtc::rtpplayer::PayloadCodecTuple(
      kDefaultVp8PayloadType, "VP8", webrtc::kVideoCodecVP8));

  std::string output_file = args.outputFile;
  if (output_file == "") {
    output_file = webrtc::test::OutputPath() + "RtpPlay_decoded.yuv";
  }

  webrtc::SimulatedClock clock(0);
  webrtc::rtpplayer::VcmPayloadSinkFactory factory(output_file, &clock,
      kConfigProtectionEnabled, kConfigProtectionMethod, kConfigRttMs,
      kConfigRenderDelayMs, kConfigMinPlayoutDelayMs);
  rtc::scoped_ptr<webrtc::rtpplayer::RtpPlayerInterface> rtp_player(
      webrtc::rtpplayer::Create(args.inputFile, &factory, &clock, payload_types,
                                kConfigLossRate, kConfigRttMs,
                                kConfigReordering));
  if (rtp_player.get() == NULL) {
    return -1;
  }

  int ret = 0;
  while ((ret = rtp_player->NextPacket(clock.TimeInMilliseconds())) == 0) {
    ret = factory.DecodeAndProcessAll(true);
    if (ret < 0 || (kConfigMaxRuntimeMs > -1 &&
        clock.TimeInMilliseconds() >= kConfigMaxRuntimeMs)) {
      break;
    }
    clock.AdvanceTimeMilliseconds(1);
  }

  rtp_player->Print();

  switch (ret) {
    case 1:
      printf("Success\n");
      return 0;
    case -1:
      printf("Failed\n");
      return -1;
    case 0:
      printf("Timeout\n");
      return -1;
  }

  webrtc::Trace::ReturnTrace();
  return 0;
}
