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

#include <assert.h>
#include <iostream>
#include <sstream>
#include <time.h>

#include "webrtc/common_types.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/test/test_callbacks.h"
#include "webrtc/modules/video_coding/main/test/test_macros.h"
#include "webrtc/modules/video_coding/main/test/test_util.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/metrics/video_metrics.h"

using namespace webrtc;

int NormalTest::RunTest(const CmdArgs& args)
{
    SimulatedClock sim_clock(0);
    SimulatedClock* clock = &sim_clock;
    NullEventFactory event_factory;
    Trace::CreateTrace();
    Trace::SetTraceFile(
        (test::OutputPath() + "VCMNormalTestTrace.txt").c_str());
    Trace::set_level_filter(webrtc::kTraceAll);
    VideoCodingModule* vcm = VideoCodingModule::Create(clock, &event_factory);
    NormalTest VCMNTest(vcm, clock);
    VCMNTest.Perform(args);
    VideoCodingModule::Destroy(vcm);
    Trace::ReturnTrace();
    return 0;
}

////////////////
// Callback Implementation
//////////////

VCMNTEncodeCompleteCallback::VCMNTEncodeCompleteCallback(FILE* encodedFile,
                                                         NormalTest& test):
    _encodedFile(encodedFile),
    _encodedBytes(0),
    _skipCnt(0),
    _VCMReceiver(NULL),
    _seqNo(0),
    _test(test)
{
    //
}
VCMNTEncodeCompleteCallback::~VCMNTEncodeCompleteCallback()
{
}

void VCMNTEncodeCompleteCallback::RegisterTransportCallback(
    VCMPacketizationCallback* transport)
{
}

int32_t VCMNTEncodeCompleteCallback::SendData(
    uint8_t payloadType,
    const webrtc::EncodedImage& encoded_image,
    const RTPFragmentationHeader& /*fragmentationHeader*/,
    const webrtc::RTPVideoHeader* videoHdr)
{
  // will call the VCMReceiver input packet
  _frameType = VCMEncodedFrame::ConvertFrameType(encoded_image._frameType);
  // writing encodedData into file
  if (fwrite(encoded_image._buffer, 1, encoded_image._length, _encodedFile) !=
      encoded_image._length) {
    return -1;
  }
  WebRtcRTPHeader rtpInfo;
  rtpInfo.header.markerBit = true;
  rtpInfo.type.Video.width = 0;
  rtpInfo.type.Video.height = 0;
  switch (_test.VideoType())
  {
  case kVideoCodecVP8:
    rtpInfo.type.Video.codec = kRtpVideoVp8;
    rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
    rtpInfo.type.Video.codecHeader.VP8.nonReference =
        videoHdr->codecHeader.VP8.nonReference;
    rtpInfo.type.Video.codecHeader.VP8.pictureId =
        videoHdr->codecHeader.VP8.pictureId;
    break;
  case kVideoCodecVP9:
    // Leave for now, until we add kRtpVideoVp9 to RTP.
    break;
  default:
    assert(false);
    return -1;
  }
  rtpInfo.header.payloadType = payloadType;
  rtpInfo.header.sequenceNumber = _seqNo++;
  rtpInfo.header.ssrc = 0;
  rtpInfo.header.timestamp = encoded_image._timeStamp;
  rtpInfo.frameType = _frameType;
  rtpInfo.type.Video.isFirstPacket = true;
  // Size should also be received from that table, since the payload type
  // defines the size.

  _encodedBytes += encoded_image._length;
  if (encoded_image._length < 20)
  {
      _skipCnt++;
  }
  _VCMReceiver->IncomingPacket(
      encoded_image._buffer, encoded_image._length, rtpInfo);
  return 0;
}
void
VCMNTEncodeCompleteCallback::RegisterReceiverVCM(VideoCodingModule *vcm)
{
  _VCMReceiver = vcm;
  return;
}
 size_t
VCMNTEncodeCompleteCallback::EncodedBytes()
{
  return _encodedBytes;
}

uint32_t
VCMNTEncodeCompleteCallback::SkipCnt()
{
  return _skipCnt;
}

// Decoded Frame Callback Implementation
VCMNTDecodeCompleteCallback::~VCMNTDecodeCompleteCallback()
{
  if (_decodedFile)
  fclose(_decodedFile);
}
 int32_t
VCMNTDecodeCompleteCallback::FrameToRender(webrtc::I420VideoFrame& videoFrame)
{
    if (videoFrame.width() != _currentWidth ||
        videoFrame.height() != _currentHeight)
    {
        _currentWidth = videoFrame.width();
        _currentHeight = videoFrame.height();
        if (_decodedFile != NULL)
        {
            fclose(_decodedFile);
            _decodedFile = NULL;
        }
        _decodedFile = fopen(_outname.c_str(), "wb");
    }
    if (PrintI420VideoFrame(videoFrame, _decodedFile) < 0) {
      return -1;
    }
    _decodedBytes += webrtc::CalcBufferSize(webrtc::kI420, videoFrame.width(),
                                            videoFrame.height());
    return VCM_OK;
}

 size_t
VCMNTDecodeCompleteCallback::DecodedBytes()
{
  return _decodedBytes;
}

 //VCM Normal Test Class implementation

NormalTest::NormalTest(VideoCodingModule* vcm, Clock* clock)
:
_clock(clock),
_vcm(vcm),
_sumEncBytes(0),
_timeStamp(0),
_totalEncodeTime(0),
_totalDecodeTime(0),
_decodeCompleteTime(0),
_encodeCompleteTime(0),
_totalEncodePipeTime(0),
_totalDecodePipeTime(0),
_frameCnt(0),
_encFrameCnt(0),
_decFrameCnt(0)
{
    //
}

NormalTest::~NormalTest()
{
    //
}
void
NormalTest::Setup(const CmdArgs& args)
{
  _inname = args.inputFile;
  _encodedName = test::OutputPath() + "encoded_normaltest.yuv";
  _width = args.width;
  _height = args.height;
  _frameRate = args.frameRate;
  _bitRate = args.bitRate;
  if (args.outputFile == "")
  {
      std::ostringstream filename;
      filename << test::OutputPath() << "NormalTest_" <<
          _width << "x" << _height << "_" << _frameRate << "Hz_P420.yuv";
      _outname = filename.str();
  }
  else
  {
      _outname = args.outputFile;
  }
  _lengthSourceFrame  = 3*_width*_height/2;
  _videoType = args.codecType;

  if ((_sourceFile = fopen(_inname.c_str(), "rb")) == NULL)
  {
      printf("Cannot read file %s.\n", _inname.c_str());
      exit(1);
  }
  if ((_encodedFile = fopen(_encodedName.c_str(), "wb")) == NULL)
  {
      printf("Cannot write encoded file.\n");
      exit(1);
  }

  _log.open((test::OutputPath() + "TestLog.txt").c_str(),
            std::fstream::out | std::fstream::app);
}

int32_t
NormalTest::Perform(const CmdArgs& args)
{
  Setup(args);
  EventWrapper* waitEvent = EventWrapper::Create();
  VideoCodec _sendCodec;
  _vcm->InitializeReceiver();
  _vcm->InitializeSender();
  TEST(VideoCodingModule::Codec(_videoType, &_sendCodec) == VCM_OK);
  // should be later on changed via the API
  _sendCodec.startBitrate = (int)_bitRate;
  _sendCodec.width = static_cast<uint16_t>(_width);
  _sendCodec.height = static_cast<uint16_t>(_height);
  _sendCodec.maxFramerate = _frameRate;
  // will also set and init the desired codec
  TEST(_vcm->RegisterSendCodec(&_sendCodec, 4, 1400) == VCM_OK);
  // register a decoder (same codec for decoder and encoder )
  TEST(_vcm->RegisterReceiveCodec(&_sendCodec, 1) == VCM_OK);
  /* Callback Settings */
  VCMNTDecodeCompleteCallback _decodeCallback(_outname);
  _vcm->RegisterReceiveCallback(&_decodeCallback);
  VCMNTEncodeCompleteCallback _encodeCompleteCallback(_encodedFile, *this);
  _vcm->RegisterTransportCallback(&_encodeCompleteCallback);
  // encode and decode with the same vcm
  _encodeCompleteCallback.RegisterReceiverVCM(_vcm);
  ///////////////////////
  /// Start Test
  ///////////////////////
  I420VideoFrame sourceFrame;
  int size_y = _width * _height;
  int half_width = (_width + 1) / 2;
  int half_height = (_height + 1) / 2;
  int size_uv = half_width * half_height;
  sourceFrame.CreateEmptyFrame(_width, _height,
                               _width, half_width, half_width);
  uint8_t* tmpBuffer = new uint8_t[_lengthSourceFrame];
  double startTime = clock()/(double)CLOCKS_PER_SEC;
  _vcm->SetChannelParameters(static_cast<uint32_t>(1000 * _bitRate), 0, 0);

  SendStatsTest sendStats;
  sendStats.set_framerate(static_cast<uint32_t>(_frameRate));
  sendStats.set_bitrate(1000 * _bitRate);
  _vcm->RegisterSendStatisticsCallback(&sendStats);

  while (feof(_sourceFile) == 0) {
    TEST(fread(tmpBuffer, 1, _lengthSourceFrame, _sourceFile) > 0 ||
         feof(_sourceFile));
    _frameCnt++;
    sourceFrame.CreateFrame(size_y, tmpBuffer,
                            size_uv, tmpBuffer + size_y,
                            size_uv, tmpBuffer + size_y + size_uv,
                            _width, _height,
                            _width, half_width, half_width);
    _timeStamp +=
        (uint32_t)(9e4 / static_cast<float>(_sendCodec.maxFramerate));
    sourceFrame.set_timestamp(_timeStamp);
    _encodeTimes[int(sourceFrame.timestamp())] =
        clock()/(double)CLOCKS_PER_SEC;
    int32_t ret = _vcm->AddVideoFrame(sourceFrame);
    double encodeTime = clock()/(double)CLOCKS_PER_SEC -
                        _encodeTimes[int(sourceFrame.timestamp())];
    _totalEncodeTime += encodeTime;
    if (ret < 0)
    {
        printf("Error in AddFrame: %d\n", ret);
        //exit(1);
    }
    _decodeTimes[int(sourceFrame.timestamp())] =
        clock()/(double)CLOCKS_PER_SEC;
    ret = _vcm->Decode();
    _totalDecodeTime += clock()/(double)CLOCKS_PER_SEC -
                        _decodeTimes[int(sourceFrame.timestamp())];
    if (ret < 0)
    {
        printf("Error in Decode: %d\n", ret);
        //exit(1);
    }
    if (_vcm->TimeUntilNextProcess() <= 0)
    {
        _vcm->Process();
    }
    uint32_t framePeriod =
        static_cast<uint32_t>(
            1000.0f / static_cast<float>(_sendCodec.maxFramerate) + 0.5f);
    static_cast<SimulatedClock*>(_clock)->AdvanceTimeMilliseconds(framePeriod);
  }
  double endTime = clock()/(double)CLOCKS_PER_SEC;
  _testTotalTime = endTime - startTime;
  _sumEncBytes = _encodeCompleteCallback.EncodedBytes();

  delete [] tmpBuffer;
  delete waitEvent;
  Teardown();
  Print();
  return 0;
}

void
NormalTest::FrameEncoded(uint32_t timeStamp)
{
  _encodeCompleteTime = clock()/(double)CLOCKS_PER_SEC;
  _encFrameCnt++;
  _totalEncodePipeTime += _encodeCompleteTime - _encodeTimes[int(timeStamp)];

}

void
NormalTest::FrameDecoded(uint32_t timeStamp)
{
  _decodeCompleteTime = clock()/(double)CLOCKS_PER_SEC;
  _decFrameCnt++;
  _totalDecodePipeTime += _decodeCompleteTime - _decodeTimes[timeStamp];
}

void
NormalTest::Print()
{
  std::cout << "Normal Test Completed!" << std::endl;
  (_log) << "Normal Test Completed!" << std::endl;
  (_log) << "Input file: " << _inname << std::endl;
  (_log) << "Output file: " << _outname << std::endl;
  (_log) << "Total run time: " << _testTotalTime << std::endl;
  printf("Total run time: %f s \n", _testTotalTime);
  double ActualBitRate =  8.0 *( _sumEncBytes / (_frameCnt / _frameRate));
  double actualBitRate = ActualBitRate / 1000.0;
  double avgEncTime = _totalEncodeTime / _frameCnt;
  double avgDecTime = _totalDecodeTime / _frameCnt;
  webrtc::test::QualityMetricsResult psnr, ssim;
  I420PSNRFromFiles(_inname.c_str(), _outname.c_str(), _width, _height,
                    &psnr);
  I420SSIMFromFiles(_inname.c_str(), _outname.c_str(), _width, _height,
                    &ssim);
  printf("Actual bitrate: %f kbps\n", actualBitRate);
  printf("Target bitrate: %f kbps\n", _bitRate);
  ( _log) << "Actual bitrate: " << actualBitRate <<
      " kbps\tTarget: " << _bitRate << " kbps" << std::endl;
  printf("Average encode time: %f s\n", avgEncTime);
  ( _log) << "Average encode time: " << avgEncTime << " s" << std::endl;
  printf("Average decode time: %f s\n", avgDecTime);
  ( _log) << "Average decode time: " << avgDecTime << " s" << std::endl;
  printf("PSNR: %f \n", psnr.average);
  ( _log) << "PSNR: " << psnr.average << std::endl;
  printf("SSIM: %f \n", ssim.average);
  ( _log) << "SSIM: " << ssim.average << std::endl;
  (_log) << std::endl;

  printf("\nVCM Normal Test: \n\n%i tests completed\n", vcmMacrosTests);
  if (vcmMacrosErrors > 0)
  {
      printf("%i FAILED\n\n", vcmMacrosErrors);
  }
  else
  {
      printf("ALL PASSED\n\n");
  }
}
void
NormalTest::Teardown()
{
  //_log.close();
  fclose(_sourceFile);
  fclose(_encodedFile);
  return;
}
