/*
 *  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/logging.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
        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)
    {
        LOG(LS_WARNING) << "Get10msAudioFromFile() playing not started!"
                        << " codec freq = " << _codec.plfreq
                        << ", wanted freq = " << 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.
        size_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];
        size_t encodedLengthInBytes = 0;
        if(++_numberOf10MsInDecoder >= _numberOf10MsPerFrame)
        {
            _numberOf10MsInDecoder = 0;
            size_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))
    {
        LOG(LS_WARNING) << "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;
    }
    LOG(LS_WARNING) << "SetAudioScaling() non-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
        {
            LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
                          << "supported for PCM format.";
            return -1;
        }

        if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                              _fileFormat, &codecInstL16,
                                              startPosition,
                                              stopPosition) == -1)
        {
            LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
                            << "pcm file " << fileName;
            return -1;
        }
        SetAudioScaling(volumeScaling);
    }else if(_fileFormat == kFileFormatPreencodedFile)
    {
        if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                              _fileFormat, codecInst) == -1)
        {
            LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
                            << "pre-encoded file " << fileName;
            return -1;
        }
    } else
    {
        CodecInst* no_inst = NULL;
        if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
                                              _fileFormat, no_inst,
                                              startPosition,
                                              stopPosition) == -1)
        {
            LOG(LS_WARNING) << "StartPlayingFile() failed to initialize file "
                            << 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
        {
            LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
                          << "supported for PCM format.";
            return -1;
        }
        if (_fileModule.StartPlayingAudioStream(sourceStream, notification,
                                                _fileFormat, &codecInstL16,
                                                startPosition,
                                                stopPosition) == -1)
        {
            LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
                          << "playout.";
            return -1;
        }

    }else if(_fileFormat == kFileFormatPreencodedFile)
    {
        if (_fileModule.StartPlayingAudioStream(sourceStream, notification,
                                                _fileFormat, codecInst) == -1)
        {
            LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
                          << "playout.";
            return -1;
        }
    } else {
        CodecInst* no_inst = NULL;
        if (_fileModule.StartPlayingAudioStream(sourceStream, notification,
                                                _fileFormat, no_inst,
                                                startPosition,
                                                stopPosition) == -1)
        {
            LOG(LS_ERROR) << "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))
    {
        LOG(LS_WARNING) << "Failed to retrieve codec info of file data.";
        return -1;
    }
    if( STR_CASE_CMP(_codec.plname, "L16") != 0 &&
        _audioDecoder.SetDecodeCodec(_codec,AMRFileStorage) == -1)
    {
        LOG(LS_WARNING) << "SetUpAudioDecoder() codec " << _codec.plname
                        << " not supported.";
        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()),
      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());

    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
            size_t encodedBufferLengthInBytes = _encodedData.bufferSize;
            if(_fileModule.PlayoutAVIVideoData(
                   reinterpret_cast< int8_t*>(_encodedData.payloadData),
                   encodedBufferLengthInBytes) != 0)
            {
                LOG(LS_WARNING) << "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)
    {
        LOG(LS_WARNING) << "SetVideoDecoder() failed to retrieve codec info of "
                        << "file data.";
        return -1;
    }

    int32_t useNumberOfCores = 1;
    if (video_decoder_->SetDecodeCodec(video_codec_info_, useNumberOfCores) !=
        0) {
        LOG(LS_WARNING) << "SetUpVideoDecoder() codec "
                        << video_codec_info_.plName << " not supported.";
        return -1;
    }

    _frameLengthMS = 1000/video_codec_info_.maxFramerate;

    // Size of unencoded data (I420) should be the largest possible frame size
    // in a file.
    const size_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
