/*
 *  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/utility/source/file_player_impl.h"
#include "webrtc/system_wrappers/interface/trace.h"

#ifdef WEBRTC_MODULE_UTILITY_VIDEO
    #include "frame_scaler.h"
    #include "tick_util.h"
    #include "video_coder.h"
#endif

namespace webrtc {
FilePlayer* FilePlayer::CreateFilePlayer(uint32_t instanceID,
                                         FileFormats fileFormat)
{
    switch(fileFormat)
    {
    case kFileFormatWavFile:
    case kFileFormatCompressedFile:
    case kFileFormatPreencodedFile:
    case kFileFormatPcm16kHzFile:
    case kFileFormatPcm8kHzFile:
    case kFileFormatPcm32kHzFile:
        // audio formats
        return new FilePlayerImpl(instanceID, fileFormat);
    case kFileFormatAviFile:
#ifdef WEBRTC_MODULE_UTILITY_VIDEO
        return new VideoFilePlayerImpl(instanceID, fileFormat);
#else
        WEBRTC_TRACE(kTraceError, kTraceFile, -1,
                     "Invalid file format: %d", kFileFormatAviFile);
        assert(false);
        return NULL;
#endif
    }
    assert(false);
    return NULL;
}

void FilePlayer::DestroyFilePlayer(FilePlayer* player)
{
    delete player;
}

FilePlayerImpl::FilePlayerImpl(const uint32_t instanceID,
                               const FileFormats fileFormat)
    : _instanceID(instanceID),
      _fileFormat(fileFormat),
      _fileModule(*MediaFile::CreateMediaFile(instanceID)),
      _decodedLengthInMS(0),
      _audioDecoder(instanceID),
      _codec(),
      _numberOf10MsPerFrame(0),
      _numberOf10MsInDecoder(0),
      _resampler(),
      _scaling(1.0)
{
    _codec.plfreq = 0;
}

FilePlayerImpl::~FilePlayerImpl()
{
    MediaFile::DestroyMediaFile(&_fileModule);
}

int32_t FilePlayerImpl::Frequency() const
{
    if(_codec.plfreq == 0)
    {
        return -1;
    }
    // Make sure that sample rate is 8,16 or 32 kHz. E.g. WAVE files may have
    // other sampling rates.
    if(_codec.plfreq == 11000)
    {
        return 16000;
    }
    else if(_codec.plfreq == 22000)
    {
        return 32000;
    }
    else if(_codec.plfreq == 44000)
    {
        return 32000;
    }
    else if(_codec.plfreq == 48000)
    {
        return 32000;
    }
    else
    {
        return _codec.plfreq;
    }
}

int32_t FilePlayerImpl::AudioCodec(CodecInst& audioCodec) const
{
    audioCodec = _codec;
    return 0;
}

int32_t FilePlayerImpl::Get10msAudioFromFile(
    int16_t* outBuffer,
    int& lengthInSamples,
    int frequencyInHz)
{
    if(_codec.plfreq == 0)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceVoice, _instanceID,
           "FilePlayerImpl::Get10msAudioFromFile() playing not started!\
 codecFreq = %d, wantedFreq = %d",
           _codec.plfreq, frequencyInHz);
        return -1;
    }

    AudioFrame unresampledAudioFrame;
    if(STR_CASE_CMP(_codec.plname, "L16") == 0)
    {
        unresampledAudioFrame.sample_rate_hz_ = _codec.plfreq;

        // L16 is un-encoded data. Just pull 10 ms.
        uint32_t lengthInBytes =
            sizeof(unresampledAudioFrame.data_);
        if (_fileModule.PlayoutAudioData(
                (int8_t*)unresampledAudioFrame.data_,
                lengthInBytes) == -1)
        {
            // End of file reached.
            return -1;
        }
        if(lengthInBytes == 0)
        {
            lengthInSamples = 0;
            return 0;
        }
        // One sample is two bytes.
        unresampledAudioFrame.samples_per_channel_ =
            (uint16_t)lengthInBytes >> 1;

    }else {
        // Decode will generate 10 ms of audio data. PlayoutAudioData(..)
        // expects a full frame. If the frame size is larger than 10 ms,
        // PlayoutAudioData(..) data should be called proportionally less often.
        int16_t encodedBuffer[MAX_AUDIO_BUFFER_IN_SAMPLES];
        uint32_t encodedLengthInBytes = 0;
        if(++_numberOf10MsInDecoder >= _numberOf10MsPerFrame)
        {
            _numberOf10MsInDecoder = 0;
            uint32_t bytesFromFile = sizeof(encodedBuffer);
            if (_fileModule.PlayoutAudioData((int8_t*)encodedBuffer,
                                             bytesFromFile) == -1)
            {
                // End of file reached.
                return -1;
            }
            encodedLengthInBytes = bytesFromFile;
        }
        if(_audioDecoder.Decode(unresampledAudioFrame,frequencyInHz,
                                (int8_t*)encodedBuffer,
                                encodedLengthInBytes) == -1)
        {
            return -1;
        }
    }

    int outLen = 0;
    if(_resampler.ResetIfNeeded(unresampledAudioFrame.sample_rate_hz_,
                                frequencyInHz, kResamplerSynchronous))
    {
        WEBRTC_TRACE(kTraceWarning, kTraceVoice, _instanceID,
           "FilePlayerImpl::Get10msAudioFromFile() unexpected codec");

        // New sampling frequency. Update state.
        outLen = frequencyInHz / 100;
        memset(outBuffer, 0, outLen * sizeof(int16_t));
        return 0;
    }
    _resampler.Push(unresampledAudioFrame.data_,
                    unresampledAudioFrame.samples_per_channel_,
                    outBuffer,
                    MAX_AUDIO_BUFFER_IN_SAMPLES,
                    outLen);

    lengthInSamples = outLen;

    if(_scaling != 1.0)
    {
        for (int i = 0;i < outLen; i++)
        {
            outBuffer[i] = (int16_t)(outBuffer[i] * _scaling);
        }
    }
    _decodedLengthInMS += 10;
    return 0;
}

int32_t FilePlayerImpl::RegisterModuleFileCallback(FileCallback* callback)
{
    return _fileModule.SetModuleFileCallback(callback);
}

int32_t FilePlayerImpl::SetAudioScaling(float scaleFactor)
{
    if((scaleFactor >= 0)&&(scaleFactor <= 2.0))
    {
        _scaling = scaleFactor;
        return 0;
    }
    WEBRTC_TRACE(kTraceWarning, kTraceVoice, _instanceID,
              "FilePlayerImpl::SetAudioScaling() not allowed scale factor");
    return -1;
}

int32_t FilePlayerImpl::StartPlayingFile(const char* fileName,
                                         bool loop,
                                         uint32_t startPosition,
                                         float volumeScaling,
                                         uint32_t notification,
                                         uint32_t stopPosition,
                                         const CodecInst* codecInst)
{
    if (_fileFormat == kFileFormatPcm16kHzFile ||
        _fileFormat == kFileFormatPcm8kHzFile||
        _fileFormat == kFileFormatPcm32kHzFile )
    {
        CodecInst codecInstL16;
        strncpy(codecInstL16.plname,"L16",32);
        codecInstL16.pltype   = 93;
        codecInstL16.channels = 1;

        if (_fileFormat == kFileFormatPcm8kHzFile)
        {
            codecInstL16.rate     = 128000;
            codecInstL16.plfreq   = 8000;
            codecInstL16.pacsize  = 80;

        } else if(_fileFormat == kFileFormatPcm16kHzFile)
        {
            codecInstL16.rate     = 256000;
            codecInstL16.plfreq   = 16000;
            codecInstL16.pacsize  = 160;

        }else if(_fileFormat == kFileFormatPcm32kHzFile)
        {
            codecInstL16.rate     = 512000;
            codecInstL16.plfreq   = 32000;
            codecInstL16.pacsize  = 160;
        } else
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice, _instanceID,
                       "FilePlayerImpl::StartPlayingFile() sample frequency\
 specifed not supported for PCM format.");
            return -1;
        }

        if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                              _fileFormat, &codecInstL16,
                                              startPosition,
                                              stopPosition) == -1)
        {
            WEBRTC_TRACE(
                kTraceWarning,
                kTraceVoice,
                _instanceID,
                "FilePlayerImpl::StartPlayingFile() failed to initialize file\
 %s playout.", fileName);
            return -1;
        }
        SetAudioScaling(volumeScaling);
    }else if(_fileFormat == kFileFormatPreencodedFile)
    {
        if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                              _fileFormat, codecInst) == -1)
        {
            WEBRTC_TRACE(
                kTraceWarning,
                kTraceVoice,
                _instanceID,
                "FilePlayerImpl::StartPlayingPreEncodedFile() failed to\
 initialize pre-encoded file %s playout.",
                fileName);
            return -1;
        }
    } else
    {
        CodecInst* no_inst = NULL;
        if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                              _fileFormat, no_inst,
                                              startPosition,
                                              stopPosition) == -1)
        {
            WEBRTC_TRACE(
                kTraceWarning,
                kTraceVoice,
                _instanceID,
                "FilePlayerImpl::StartPlayingFile() failed to initialize file\
 %s playout.", fileName);
            return -1;
        }
        SetAudioScaling(volumeScaling);
    }
    if (SetUpAudioDecoder() == -1)
    {
        StopPlayingFile();
        return -1;
    }
    return 0;
}

int32_t FilePlayerImpl::StartPlayingFile(InStream& sourceStream,
                                         uint32_t startPosition,
                                         float volumeScaling,
                                         uint32_t notification,
                                         uint32_t stopPosition,
                                         const CodecInst* codecInst)
{
    if (_fileFormat == kFileFormatPcm16kHzFile ||
        _fileFormat == kFileFormatPcm32kHzFile ||
        _fileFormat == kFileFormatPcm8kHzFile)
    {
        CodecInst codecInstL16;
        strncpy(codecInstL16.plname,"L16",32);
        codecInstL16.pltype   = 93;
        codecInstL16.channels = 1;

        if (_fileFormat == kFileFormatPcm8kHzFile)
        {
            codecInstL16.rate     = 128000;
            codecInstL16.plfreq   = 8000;
            codecInstL16.pacsize  = 80;

        }else if (_fileFormat == kFileFormatPcm16kHzFile)
        {
            codecInstL16.rate     = 256000;
            codecInstL16.plfreq   = 16000;
            codecInstL16.pacsize  = 160;

        }else if (_fileFormat == kFileFormatPcm32kHzFile)
        {
            codecInstL16.rate     = 512000;
            codecInstL16.plfreq   = 32000;
            codecInstL16.pacsize  = 160;
        }else
        {
            WEBRTC_TRACE(
                kTraceError,
                kTraceVoice,
                _instanceID,
                "FilePlayerImpl::StartPlayingFile() sample frequency specifed\
 not supported for PCM format.");
            return -1;
        }
        if (_fileModule.StartPlayingAudioStream(sourceStream, notification,
                                                _fileFormat, &codecInstL16,
                                                startPosition,
                                                stopPosition) == -1)
        {
            WEBRTC_TRACE(
                kTraceError,
                kTraceVoice,
                _instanceID,
                "FilePlayerImpl::StartPlayingFile() failed to initialize stream\
 playout.");
            return -1;
        }

    }else if(_fileFormat == kFileFormatPreencodedFile)
    {
        if (_fileModule.StartPlayingAudioStream(sourceStream, notification,
                                                _fileFormat, codecInst) == -1)
        {
            WEBRTC_TRACE(
                kTraceWarning,
                kTraceVoice,
                _instanceID,
                "FilePlayerImpl::StartPlayingFile() failed to initialize stream\
 playout.");
            return -1;
        }
    } else {
        CodecInst* no_inst = NULL;
        if (_fileModule.StartPlayingAudioStream(sourceStream, notification,
                                                _fileFormat, no_inst,
                                                startPosition,
                                                stopPosition) == -1)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice, _instanceID,
                       "FilePlayerImpl::StartPlayingFile() failed to initialize\
 stream playout.");
            return -1;
        }
    }
    SetAudioScaling(volumeScaling);

    if (SetUpAudioDecoder() == -1)
    {
        StopPlayingFile();
        return -1;
    }
    return 0;
}

int32_t FilePlayerImpl::StopPlayingFile()
{
    memset(&_codec, 0, sizeof(CodecInst));
    _numberOf10MsPerFrame  = 0;
    _numberOf10MsInDecoder = 0;
    return _fileModule.StopPlaying();
}

bool FilePlayerImpl::IsPlayingFile() const
{
    return _fileModule.IsPlaying();
}

int32_t FilePlayerImpl::GetPlayoutPosition(uint32_t& durationMs)
{
    return _fileModule.PlayoutPositionMs(durationMs);
}

int32_t FilePlayerImpl::SetUpAudioDecoder()
{
    if ((_fileModule.codec_info(_codec) == -1))
    {
        WEBRTC_TRACE(
            kTraceWarning,
            kTraceVoice,
            _instanceID,
            "FilePlayerImpl::StartPlayingFile() failed to retrieve Codec info\
 of file data.");
        return -1;
    }
    if( STR_CASE_CMP(_codec.plname, "L16") != 0 &&
        _audioDecoder.SetDecodeCodec(_codec,AMRFileStorage) == -1)
    {
        WEBRTC_TRACE(
            kTraceWarning,
            kTraceVoice,
            _instanceID,
            "FilePlayerImpl::StartPlayingFile() codec %s not supported",
            _codec.plname);
        return -1;
    }
    _numberOf10MsPerFrame = _codec.pacsize / (_codec.plfreq / 100);
    _numberOf10MsInDecoder = 0;
    return 0;
}

#ifdef WEBRTC_MODULE_UTILITY_VIDEO
VideoFilePlayerImpl::VideoFilePlayerImpl(uint32_t instanceID,
                                         FileFormats fileFormat)
    : FilePlayerImpl(instanceID, fileFormat),
      video_decoder_(new VideoCoder(instanceID)),
      video_codec_info_(),
      _decodedVideoFrames(0),
      _encodedData(*new EncodedVideoData()),
      _frameScaler(*new FrameScaler()),
      _critSec(CriticalSectionWrapper::CreateCriticalSection()),
      _startTime(),
      _accumulatedRenderTimeMs(0),
      _frameLengthMS(0),
      _numberOfFramesRead(0),
      _videoOnly(false) {
  memset(&video_codec_info_, 0, sizeof(video_codec_info_));
}

VideoFilePlayerImpl::~VideoFilePlayerImpl()
{
    delete _critSec;
    delete &_frameScaler;
    video_decoder_.reset();
    delete &_encodedData;
}

int32_t VideoFilePlayerImpl::StartPlayingVideoFile(
    const char* fileName,
    bool loop,
    bool videoOnly)
{
    CriticalSectionScoped lock( _critSec);

    if(_fileModule.StartPlayingVideoFile(fileName, loop, videoOnly,
                                         _fileFormat) != 0)
    {
        return -1;
    }

    _decodedVideoFrames = 0;
    _accumulatedRenderTimeMs = 0;
    _frameLengthMS = 0;
    _numberOfFramesRead = 0;
    _videoOnly = videoOnly;

    // Set up video_codec_info_ according to file,
    if(SetUpVideoDecoder() != 0)
    {
        StopPlayingFile();
        return -1;
    }
    if(!videoOnly)
    {
        // Set up _codec according to file,
        if(SetUpAudioDecoder() != 0)
        {
            StopPlayingFile();
            return -1;
        }
    }
    return 0;
}

int32_t VideoFilePlayerImpl::StopPlayingFile()
{
    CriticalSectionScoped lock( _critSec);

    _decodedVideoFrames = 0;
    video_decoder_.reset(new VideoCoder(_instanceID));

    return FilePlayerImpl::StopPlayingFile();
}

int32_t VideoFilePlayerImpl::GetVideoFromFile(I420VideoFrame& videoFrame,
                                              uint32_t outWidth,
                                              uint32_t outHeight)
{
    CriticalSectionScoped lock( _critSec);

    int32_t retVal = GetVideoFromFile(videoFrame);
    if(retVal != 0)
    {
        return retVal;
    }
    if (!videoFrame.IsZeroSize())
    {
        retVal = _frameScaler.ResizeFrameIfNeeded(&videoFrame, outWidth,
                                                  outHeight);
    }
    return retVal;
}

int32_t VideoFilePlayerImpl::GetVideoFromFile(I420VideoFrame& videoFrame)
{
    CriticalSectionScoped lock( _critSec);
    // No new video data read from file.
    if(_encodedData.payloadSize == 0)
    {
        videoFrame.ResetSize();
        return -1;
    }
    int32_t retVal = 0;
    if(strncmp(video_codec_info_.plName, "I420", 5) == 0)
    {
      int size_y = video_codec_info_.width * video_codec_info_.height;
      int half_width = (video_codec_info_.width + 1) / 2;
      int half_height = (video_codec_info_.height + 1) / 2;
      int size_uv = half_width * half_height;

      // TODO(mikhal): Do we need to align the stride here?
      const uint8_t* buffer_y = _encodedData.payloadData;
      const uint8_t* buffer_u = buffer_y + size_y;
      const uint8_t* buffer_v = buffer_u + size_uv;
      videoFrame.CreateFrame(size_y, buffer_y,
                             size_uv, buffer_u,
                             size_uv, buffer_v,
                             video_codec_info_.width, video_codec_info_.height,
                             video_codec_info_.height, half_width, half_width);
    }else
    {
        // Set the timestamp manually since there is no timestamp in the file.
        // Update timestam according to 90 kHz stream.
        _encodedData.timeStamp += (90000 / video_codec_info_.maxFramerate);
        retVal = video_decoder_->Decode(videoFrame, _encodedData);
    }

    int64_t renderTimeMs = TickTime::MillisecondTimestamp();
    videoFrame.set_render_time_ms(renderTimeMs);

     // Indicate that the current frame in the encoded buffer is old/has
     // already been read.
    _encodedData.payloadSize = 0;
    if( retVal == 0)
    {
        _decodedVideoFrames++;
    }
    return retVal;
}

int32_t VideoFilePlayerImpl::video_codec_info(
    VideoCodec& videoCodec) const
{
    if(video_codec_info_.plName[0] == 0)
    {
        return -1;
    }
    memcpy(&videoCodec, &video_codec_info_, sizeof(VideoCodec));
    return 0;
}

int32_t VideoFilePlayerImpl::TimeUntilNextVideoFrame()
{
    if(_fileFormat != kFileFormatAviFile)
    {
        return -1;
    }
    if(!_fileModule.IsPlaying())
    {
        return -1;
    }
    if(_encodedData.payloadSize <= 0)
    {
        // Read next frame from file.
        CriticalSectionScoped lock( _critSec);

        if(_fileFormat == kFileFormatAviFile)
        {
            // Get next video frame
            uint32_t encodedBufferLengthInBytes = _encodedData.bufferSize;
            if(_fileModule.PlayoutAVIVideoData(
                   reinterpret_cast< int8_t*>(_encodedData.payloadData),
                   encodedBufferLengthInBytes) != 0)
            {
                 WEBRTC_TRACE(
                     kTraceWarning,
                     kTraceVideo,
                     _instanceID,
                     "FilePlayerImpl::TimeUntilNextVideoFrame() error reading\
 video data");
                return -1;
            }
            _encodedData.payloadSize = encodedBufferLengthInBytes;
            _encodedData.codec = video_codec_info_.codecType;
            _numberOfFramesRead++;

            if(_accumulatedRenderTimeMs == 0)
            {
                _startTime = TickTime::Now();
                // This if-statement should only trigger once.
                _accumulatedRenderTimeMs = 1;
            } else {
                // A full seconds worth of frames have been read.
                if(_numberOfFramesRead % video_codec_info_.maxFramerate == 0)
                {
                    // Frame rate is in frames per seconds. Frame length is
                    // calculated as an integer division which means it may
                    // be rounded down. Compensate for this every second.
                    uint32_t rest = 1000%_frameLengthMS;
                    _accumulatedRenderTimeMs += rest;
                }
                _accumulatedRenderTimeMs += _frameLengthMS;
            }
        }
    }

    int64_t timeToNextFrame;
    if(_videoOnly)
    {
        timeToNextFrame = _accumulatedRenderTimeMs -
            (TickTime::Now() - _startTime).Milliseconds();

    } else {
        // Synchronize with the audio stream instead of system clock.
        timeToNextFrame = _accumulatedRenderTimeMs - _decodedLengthInMS;
    }
    if(timeToNextFrame < 0)
    {
        return 0;

    } else if(timeToNextFrame > 0x0fffffff)
    {
        // Wraparound or audio stream has gone to far ahead of the video stream.
        return -1;
    }
    return static_cast<int32_t>(timeToNextFrame);
}

int32_t VideoFilePlayerImpl::SetUpVideoDecoder()
{
    if (_fileModule.VideoCodecInst(video_codec_info_) != 0)
    {
        WEBRTC_TRACE(
            kTraceWarning,
            kTraceVideo,
            _instanceID,
            "FilePlayerImpl::SetVideoDecoder() failed to retrieve Codec info of\
 file data.");
        return -1;
    }

    int32_t useNumberOfCores = 1;
    if (video_decoder_->SetDecodeCodec(video_codec_info_, useNumberOfCores) !=
        0) {
      WEBRTC_TRACE(kTraceWarning,
                   kTraceVideo,
                   _instanceID,
                   "FilePlayerImpl::SetUpVideoDecoder() codec %s not supported",
                   video_codec_info_.plName);
        return -1;
    }

    _frameLengthMS = 1000/video_codec_info_.maxFramerate;

    // Size of unencoded data (I420) should be the largest possible frame size
    // in a file.
    const uint32_t KReadBufferSize = 3 * video_codec_info_.width *
        video_codec_info_.height / 2;
    _encodedData.VerifyAndAllocate(KReadBufferSize);
    _encodedData.encodedHeight = video_codec_info_.height;
    _encodedData.encodedWidth = video_codec_info_.width;
    _encodedData.payloadType = video_codec_info_.plType;
    _encodedData.timeStamp = 0;
    return 0;
}
#endif // WEBRTC_MODULE_UTILITY_VIDEO
}  // namespace webrtc
