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

#include "webrtc/modules/media_file/media_file_impl.h"
#include "webrtc/rtc_base/format_macros.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/system_wrappers/include/file_wrapper.h"

namespace webrtc {
MediaFile* MediaFile::CreateMediaFile(const int32_t id)
{
    return new MediaFileImpl(id);
}

void MediaFile::DestroyMediaFile(MediaFile* module)
{
    delete static_cast<MediaFileImpl*>(module);
}

MediaFileImpl::MediaFileImpl(const int32_t id)
    : _id(id),
      _ptrFileUtilityObj(NULL),
      codec_info_(),
      _ptrInStream(NULL),
      _ptrOutStream(NULL),
      _fileFormat((FileFormats)-1),
      _recordDurationMs(0),
      _playoutPositionMs(0),
      _notificationMs(0),
      _playingActive(false),
      _recordingActive(false),
      _isStereo(false),
      _openFile(false),
      _fileName(),
      _ptrCallback(NULL)
{
    LOG(LS_INFO) << "MediaFileImpl()";

    codec_info_.plname[0] = '\0';
    _fileName[0] = '\0';
}


MediaFileImpl::~MediaFileImpl()
{
    LOG(LS_INFO) << "~MediaFileImpl()";
    {
        rtc::CritScope lock(&_crit);

        if(_playingActive)
        {
            StopPlaying();
        }

        if(_recordingActive)
        {
            StopRecording();
        }

        delete _ptrFileUtilityObj;

        if(_openFile)
        {
            delete _ptrInStream;
            _ptrInStream = NULL;
            delete _ptrOutStream;
            _ptrOutStream = NULL;
        }
    }
}

int64_t MediaFileImpl::TimeUntilNextProcess()
{
    LOG(LS_WARNING)
        << "TimeUntilNextProcess: This method is not used by MediaFile class.";
    return -1;
}

void MediaFileImpl::Process()
{
    LOG(LS_WARNING) << "Process: This method is not used by MediaFile class.";
}

int32_t MediaFileImpl::PlayoutAudioData(int8_t* buffer,
                                        size_t& dataLengthInBytes)
{
    LOG(LS_INFO) << "MediaFileImpl::PlayoutData(buffer= "
                 << static_cast<void*>(buffer)
                 << ", bufLen= " << dataLengthInBytes << ")";

    const size_t bufferLengthInBytes = dataLengthInBytes;
    dataLengthInBytes = 0;

    if(buffer == NULL || bufferLengthInBytes == 0)
    {
        LOG(LS_ERROR) << "Buffer pointer or length is NULL!";
        return -1;
    }

    int32_t bytesRead = 0;
    {
        rtc::CritScope lock(&_crit);

        if(!_playingActive)
        {
            LOG(LS_WARNING) << "Not currently playing!";
            return -1;
        }

        if(!_ptrFileUtilityObj)
        {
            LOG(LS_ERROR) << "Playing, but no FileUtility object!";
            StopPlaying();
            return -1;
        }

        switch(_fileFormat)
        {
            case kFileFormatPcm48kHzFile:
            case kFileFormatPcm32kHzFile:
            case kFileFormatPcm16kHzFile:
            case kFileFormatPcm8kHzFile:
                bytesRead = _ptrFileUtilityObj->ReadPCMData(
                    *_ptrInStream,
                    buffer,
                    bufferLengthInBytes);
                break;
            case kFileFormatCompressedFile:
                bytesRead = _ptrFileUtilityObj->ReadCompressedData(
                    *_ptrInStream,
                    buffer,
                    bufferLengthInBytes);
                break;
            case kFileFormatWavFile:
                bytesRead = _ptrFileUtilityObj->ReadWavDataAsMono(
                    *_ptrInStream,
                    buffer,
                    bufferLengthInBytes);
                break;
            case kFileFormatPreencodedFile:
                bytesRead = _ptrFileUtilityObj->ReadPreEncodedData(
                    *_ptrInStream,
                    buffer,
                    bufferLengthInBytes);
                if(bytesRead > 0)
                {
                    dataLengthInBytes = static_cast<size_t>(bytesRead);
                    return 0;
                }
                break;
            default:
            {
                LOG(LS_ERROR) << "Invalid file format: " << _fileFormat;
                assert(false);
                break;
            }
        }

        if( bytesRead > 0)
        {
            dataLengthInBytes = static_cast<size_t>(bytesRead);
        }
    }
    HandlePlayCallbacks(bytesRead);
    return 0;
}

void MediaFileImpl::HandlePlayCallbacks(int32_t bytesRead)
{
    bool playEnded = false;
    uint32_t callbackNotifyMs = 0;

    if(bytesRead > 0)
    {
        // Check if it's time for PlayNotification(..).
        _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
        if(_notificationMs)
        {
            if(_playoutPositionMs >= _notificationMs)
            {
                _notificationMs = 0;
                callbackNotifyMs = _playoutPositionMs;
            }
        }
    }
    else
    {
        // If no bytes were read assume end of file.
        StopPlaying();
        playEnded = true;
    }

    // Only _callbackCrit may and should be taken when making callbacks.
    rtc::CritScope lock(&_callbackCrit);
    if(_ptrCallback)
    {
        if(callbackNotifyMs)
        {
            _ptrCallback->PlayNotification(_id, callbackNotifyMs);
        }
        if(playEnded)
        {
            _ptrCallback->PlayFileEnded(_id);
        }
    }
}

int32_t MediaFileImpl::PlayoutStereoData(
    int8_t* bufferLeft,
    int8_t* bufferRight,
    size_t& dataLengthInBytes)
{
    LOG(LS_INFO)
        << "MediaFileImpl::PlayoutStereoData(Left = "
        << static_cast<void*>(bufferLeft) << ", Right = "
        << static_cast<void*>(bufferRight) << ", Len= " << dataLengthInBytes
        << ")";

    const size_t bufferLengthInBytes = dataLengthInBytes;
    dataLengthInBytes = 0;

    if(bufferLeft == NULL || bufferRight == NULL || bufferLengthInBytes == 0)
    {
        LOG(LS_ERROR) << "A buffer pointer or the length is NULL!";
        return -1;
    }

    bool playEnded = false;
    uint32_t callbackNotifyMs = 0;
    {
        rtc::CritScope lock(&_crit);

        if(!_playingActive || !_isStereo)
        {
            LOG(LS_WARNING) << "Not currently playing stereo!";
            return -1;
        }

        if(!_ptrFileUtilityObj)
        {
            LOG(LS_ERROR)
                << "Playing stereo, but the FileUtility objects is NULL!";
            StopPlaying();
            return -1;
        }

        // Stereo playout only supported for WAV files.
        int32_t bytesRead = 0;
        switch(_fileFormat)
        {
            case kFileFormatWavFile:
                    bytesRead = _ptrFileUtilityObj->ReadWavDataAsStereo(
                        *_ptrInStream,
                        bufferLeft,
                        bufferRight,
                        bufferLengthInBytes);
                    break;
            default:
                LOG(LS_ERROR)
                    << "Trying to read non-WAV as stereo audio (not supported)";
                break;
        }

        if(bytesRead > 0)
        {
            dataLengthInBytes = static_cast<size_t>(bytesRead);

            // Check if it's time for PlayNotification(..).
            _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
            if(_notificationMs)
            {
                if(_playoutPositionMs >= _notificationMs)
                {
                    _notificationMs = 0;
                    callbackNotifyMs = _playoutPositionMs;
                }
            }
        }
        else
        {
            // If no bytes were read assume end of file.
            StopPlaying();
            playEnded = true;
        }
    }

    rtc::CritScope lock(&_callbackCrit);
    if(_ptrCallback)
    {
        if(callbackNotifyMs)
        {
            _ptrCallback->PlayNotification(_id, callbackNotifyMs);
        }
        if(playEnded)
        {
            _ptrCallback->PlayFileEnded(_id);
        }
    }
    return 0;
}

int32_t MediaFileImpl::StartPlayingAudioFile(
    const char* fileName,
    const uint32_t notificationTimeMs,
    const bool loop,
    const FileFormats format,
    const CodecInst* codecInst,
    const uint32_t startPointMs,
    const uint32_t stopPointMs)
{
    if(!ValidFileName(fileName))
    {
        return -1;
    }
    if(!ValidFileFormat(format,codecInst))
    {
        return -1;
    }
    if(!ValidFilePositions(startPointMs,stopPointMs))
    {
        return -1;
    }

    // Check that the file will play longer than notificationTimeMs ms.
    if((startPointMs && stopPointMs && !loop) &&
       (notificationTimeMs > (stopPointMs - startPointMs)))
    {
        LOG(LS_ERROR) << "specified notification time is longer than amount of"
                      << " ms that will be played";
        return -1;
    }

    FileWrapper* inputStream = FileWrapper::Create();
    if(inputStream == NULL)
    {
       LOG(LS_INFO) << "Failed to allocate input stream for file " << fileName;
        return -1;
    }

    if (!inputStream->OpenFile(fileName, true)) {
      delete inputStream;
      LOG(LS_ERROR) << "Could not open input file " << fileName;
      return -1;
    }

    if(StartPlayingStream(*inputStream, loop, notificationTimeMs,
                          format, codecInst, startPointMs, stopPointMs) == -1)
    {
        inputStream->CloseFile();
        delete inputStream;
        return -1;
    }

    rtc::CritScope lock(&_crit);
    _openFile = true;
    strncpy(_fileName, fileName, sizeof(_fileName));
    _fileName[sizeof(_fileName) - 1] = '\0';
    return 0;
}

int32_t MediaFileImpl::StartPlayingAudioStream(
    InStream& stream,
    const uint32_t notificationTimeMs,
    const FileFormats format,
    const CodecInst* codecInst,
    const uint32_t startPointMs,
    const uint32_t stopPointMs)
{
    return StartPlayingStream(stream, false, notificationTimeMs, format,
                              codecInst, startPointMs, stopPointMs);
}

int32_t MediaFileImpl::StartPlayingStream(
    InStream& stream,
    bool loop,
    const uint32_t notificationTimeMs,
    const FileFormats format,
    const CodecInst*  codecInst,
    const uint32_t startPointMs,
    const uint32_t stopPointMs)
{
    if(!ValidFileFormat(format,codecInst))
    {
        return -1;
    }

    if(!ValidFilePositions(startPointMs,stopPointMs))
    {
        return -1;
    }

    rtc::CritScope lock(&_crit);
    if(_playingActive || _recordingActive)
    {
        LOG(LS_ERROR)
            << "StartPlaying called, but already playing or recording file "
            << ((_fileName[0] == '\0') ? "(name not set)" : _fileName);
        return -1;
    }

    if(_ptrFileUtilityObj != NULL)
    {
        LOG(LS_ERROR)
            << "StartPlaying called, but FileUtilityObj already exists!";
        StopPlaying();
        return -1;
    }

    _ptrFileUtilityObj = new ModuleFileUtility();
    if(_ptrFileUtilityObj == NULL)
    {
        LOG(LS_INFO) << "Failed to create FileUtilityObj!";
        return -1;
    }

    switch(format)
    {
        case kFileFormatWavFile:
        {
            if(_ptrFileUtilityObj->InitWavReading(stream, startPointMs,
                                                  stopPointMs) == -1)
            {
                LOG(LS_ERROR) << "Not a valid WAV file!";
                StopPlaying();
                return -1;
            }
            _fileFormat = kFileFormatWavFile;
            break;
        }
        case kFileFormatCompressedFile:
        {
            if(_ptrFileUtilityObj->InitCompressedReading(stream, startPointMs,
                                                         stopPointMs) == -1)
            {
                LOG(LS_ERROR) << "Not a valid Compressed file!";
                StopPlaying();
                return -1;
            }
            _fileFormat = kFileFormatCompressedFile;
            break;
        }
        case kFileFormatPcm8kHzFile:
        case kFileFormatPcm16kHzFile:
        case kFileFormatPcm32kHzFile:
        case kFileFormatPcm48kHzFile:
        {
            // ValidFileFormat() called in the beginneing of this function
            // prevents codecInst from being NULL here.
            assert(codecInst != NULL);
            if(!ValidFrequency(codecInst->plfreq) ||
               _ptrFileUtilityObj->InitPCMReading(stream, startPointMs,
                                                  stopPointMs,
                                                  codecInst->plfreq) == -1)
            {
                LOG(LS_ERROR) << "Not a valid raw 8 or 16 KHz PCM file!";
                StopPlaying();
                return -1;
            }

            _fileFormat = format;
            break;
        }
        case kFileFormatPreencodedFile:
        {
            // ValidFileFormat() called in the beginneing of this function
            // prevents codecInst from being NULL here.
            assert(codecInst != NULL);
            if(_ptrFileUtilityObj->InitPreEncodedReading(stream, *codecInst) ==
               -1)
            {
                LOG(LS_ERROR) << "Not a valid PreEncoded file!";
                StopPlaying();
                return -1;
            }

            _fileFormat = kFileFormatPreencodedFile;
            break;
        }
        default:
        {
            LOG(LS_ERROR) << "Invalid file format: " << format;
            assert(false);
            break;
        }
    }
    if(_ptrFileUtilityObj->codec_info(codec_info_) == -1)
    {
        LOG(LS_ERROR) << "Failed to retrieve codec info!";
        StopPlaying();
        return -1;
    }

    _isStereo = (codec_info_.channels == 2);
    if(_isStereo && (_fileFormat != kFileFormatWavFile))
    {
        LOG(LS_WARNING) << "Stereo is only allowed for WAV files";
        StopPlaying();
        return -1;
    }
    _playingActive = true;
    _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs();
    _ptrInStream = &stream;
    _notificationMs = notificationTimeMs;

    return 0;
}

int32_t MediaFileImpl::StopPlaying()
{

    rtc::CritScope lock(&_crit);
    _isStereo = false;
    if(_ptrFileUtilityObj)
    {
        delete _ptrFileUtilityObj;
        _ptrFileUtilityObj = NULL;
    }
    if(_ptrInStream)
    {
        // If MediaFileImpl opened the InStream it must be reclaimed here.
        if(_openFile)
        {
            delete _ptrInStream;
            _openFile = false;
        }
        _ptrInStream = NULL;
    }

    codec_info_.pltype = 0;
    codec_info_.plname[0] = '\0';

    if(!_playingActive)
    {
        LOG(LS_WARNING) << "playing is not active!";
        return -1;
    }

    _playingActive = false;
    return 0;
}

bool MediaFileImpl::IsPlaying()
{
    LOG(LS_VERBOSE) << "MediaFileImpl::IsPlaying()";
    rtc::CritScope lock(&_crit);
    return _playingActive;
}

int32_t MediaFileImpl::IncomingAudioData(
    const int8_t*  buffer,
    const size_t bufferLengthInBytes)
{
    LOG(LS_INFO) << "MediaFile::IncomingData(buffer= "
                 << static_cast<const void*>(buffer) << ", bufLen= "
                 << bufferLengthInBytes << ")";

    if(buffer == NULL || bufferLengthInBytes == 0)
    {
        LOG(LS_ERROR) << "Buffer pointer or length is NULL!";
        return -1;
    }

    bool recordingEnded = false;
    uint32_t callbackNotifyMs = 0;
    {
        rtc::CritScope lock(&_crit);

        if(!_recordingActive)
        {
            LOG(LS_WARNING) << "Not currently recording!";
            return -1;
        }
        if(_ptrOutStream == NULL)
        {
            LOG(LS_ERROR) << "Recording is active, but output stream is NULL!";
            assert(false);
            return -1;
        }

        int32_t bytesWritten = 0;
        uint32_t samplesWritten = codec_info_.pacsize;
        if(_ptrFileUtilityObj)
        {
            switch(_fileFormat)
            {
                case kFileFormatPcm8kHzFile:
                case kFileFormatPcm16kHzFile:
                case kFileFormatPcm32kHzFile:
                case kFileFormatPcm48kHzFile:
                    bytesWritten = _ptrFileUtilityObj->WritePCMData(
                        *_ptrOutStream,
                        buffer,
                        bufferLengthInBytes);

                    // Sample size is 2 bytes.
                    if(bytesWritten > 0)
                    {
                        samplesWritten = bytesWritten/sizeof(int16_t);
                    }
                    break;
                case kFileFormatCompressedFile:
                    bytesWritten = _ptrFileUtilityObj->WriteCompressedData(
                        *_ptrOutStream, buffer, bufferLengthInBytes);
                    break;
                case kFileFormatWavFile:
                    bytesWritten = _ptrFileUtilityObj->WriteWavData(
                        *_ptrOutStream,
                        buffer,
                        bufferLengthInBytes);
                    if(bytesWritten > 0 && STR_NCASE_CMP(codec_info_.plname,
                                                         "L16", 4) == 0)
                    {
                        // Sample size is 2 bytes.
                        samplesWritten = bytesWritten/sizeof(int16_t);
                    }
                    break;
                case kFileFormatPreencodedFile:
                    bytesWritten = _ptrFileUtilityObj->WritePreEncodedData(
                        *_ptrOutStream, buffer, bufferLengthInBytes);
                    break;
                default:
                    LOG(LS_ERROR) << "Invalid file format: " << _fileFormat;
                    assert(false);
                    break;
            }
        } else {
            // TODO (hellner): quick look at the code makes me think that this
            //                 code is never executed. Remove?
            if(_ptrOutStream)
            {
                if(_ptrOutStream->Write(buffer, bufferLengthInBytes))
                {
                    bytesWritten = static_cast<int32_t>(bufferLengthInBytes);
                }
            }
        }

        _recordDurationMs += samplesWritten / (codec_info_.plfreq / 1000);

        // Check if it's time for RecordNotification(..).
        if(_notificationMs)
        {
            if(_recordDurationMs  >= _notificationMs)
            {
                _notificationMs = 0;
                callbackNotifyMs = _recordDurationMs;
            }
        }
        if(bytesWritten < (int32_t)bufferLengthInBytes)
        {
            LOG(LS_WARNING) << "Failed to write all requested bytes!";
            StopRecording();
            recordingEnded = true;
        }
    }

    // Only _callbackCrit may and should be taken when making callbacks.
    rtc::CritScope lock(&_callbackCrit);
    if(_ptrCallback)
    {
        if(callbackNotifyMs)
        {
            _ptrCallback->RecordNotification(_id, callbackNotifyMs);
        }
        if(recordingEnded)
        {
            _ptrCallback->RecordFileEnded(_id);
            return -1;
        }
    }
    return 0;
}

int32_t MediaFileImpl::StartRecordingAudioFile(
    const char* fileName,
    const FileFormats format,
    const CodecInst& codecInst,
    const uint32_t notificationTimeMs,
    const uint32_t maxSizeBytes)
{
    if(!ValidFileName(fileName))
    {
        return -1;
    }
    if(!ValidFileFormat(format,&codecInst))
    {
        return -1;
    }

    FileWrapper* outputStream = FileWrapper::Create();
    if(outputStream == NULL)
    {
        LOG(LS_INFO) << "Failed to allocate memory for output stream";
        return -1;
    }

    if (!outputStream->OpenFile(fileName, false)) {
      delete outputStream;
      LOG(LS_ERROR) << "Could not open output file '" << fileName
                    << "' for writing!";
      return -1;
    }

    if(maxSizeBytes)
    {
        outputStream->SetMaxFileSize(maxSizeBytes);
    }

    if(StartRecordingAudioStream(*outputStream, format, codecInst,
                                 notificationTimeMs) == -1)
    {
        outputStream->CloseFile();
        delete outputStream;
        return -1;
    }

    rtc::CritScope lock(&_crit);
    _openFile = true;
    strncpy(_fileName, fileName, sizeof(_fileName));
    _fileName[sizeof(_fileName) - 1] = '\0';
    return 0;
}

int32_t MediaFileImpl::StartRecordingAudioStream(
    OutStream& stream,
    const FileFormats format,
    const CodecInst& codecInst,
    const uint32_t notificationTimeMs)
{
    // Check codec info
    if(!ValidFileFormat(format,&codecInst))
    {
        return -1;
    }

    rtc::CritScope lock(&_crit);
    if(_recordingActive || _playingActive)
    {
        LOG(LS_ERROR)
            << "StartRecording called, but already recording or playing file "
            << _fileName << "!";
        return -1;
    }

    if(_ptrFileUtilityObj != NULL)
    {
        LOG(LS_ERROR)
            << "StartRecording called, but fileUtilityObj already exists!";
        StopRecording();
        return -1;
    }

    _ptrFileUtilityObj = new ModuleFileUtility();
    if(_ptrFileUtilityObj == NULL)
    {
        LOG(LS_INFO) << "Cannot allocate fileUtilityObj!";
        return -1;
    }

    CodecInst tmpAudioCodec;
    memcpy(&tmpAudioCodec, &codecInst, sizeof(CodecInst));
    switch(format)
    {
        case kFileFormatWavFile:
        {
            if(_ptrFileUtilityObj->InitWavWriting(stream, codecInst) == -1)
            {
                LOG(LS_ERROR) << "Failed to initialize WAV file!";
                delete _ptrFileUtilityObj;
                _ptrFileUtilityObj = NULL;
                return -1;
            }
            _fileFormat = kFileFormatWavFile;
            break;
        }
        case kFileFormatCompressedFile:
        {
            // Write compression codec name at beginning of file
            if(_ptrFileUtilityObj->InitCompressedWriting(stream, codecInst) ==
               -1)
            {
                LOG(LS_ERROR) << "Failed to initialize Compressed file!";
                delete _ptrFileUtilityObj;
                _ptrFileUtilityObj = NULL;
                return -1;
            }
            _fileFormat = kFileFormatCompressedFile;
            break;
        }
        case kFileFormatPcm8kHzFile:
        case kFileFormatPcm16kHzFile:
        case kFileFormatPcm32kHzFile:
        case kFileFormatPcm48kHzFile:
        {
            if(!ValidFrequency(codecInst.plfreq) ||
               _ptrFileUtilityObj->InitPCMWriting(stream, codecInst.plfreq) ==
               -1)
            {
                LOG(LS_ERROR) << "Failed to initialize PCM file!";
                delete _ptrFileUtilityObj;
                _ptrFileUtilityObj = NULL;
                return -1;
            }
            _fileFormat = format;
            break;
        }
        case kFileFormatPreencodedFile:
        {
            if(_ptrFileUtilityObj->InitPreEncodedWriting(stream, codecInst) ==
               -1)
            {
                LOG(LS_ERROR) << "Failed to initialize Pre-Encoded file!";
                delete _ptrFileUtilityObj;
                _ptrFileUtilityObj = NULL;
                return -1;
            }

            _fileFormat = kFileFormatPreencodedFile;
            break;
        }
        default:
        {
            LOG(LS_ERROR) << "Invalid file format " << format << " specified!";
            delete _ptrFileUtilityObj;
            _ptrFileUtilityObj = NULL;
            return -1;
        }
    }
    _isStereo = (tmpAudioCodec.channels == 2);
    if(_isStereo)
    {
        if(_fileFormat != kFileFormatWavFile)
        {
            LOG(LS_WARNING) << "Stereo is only allowed for WAV files";
            StopRecording();
            return -1;
        }
        if((STR_NCASE_CMP(tmpAudioCodec.plname, "L16", 4) != 0) &&
           (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMU", 5) != 0) &&
           (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMA", 5) != 0))
        {
            LOG(LS_WARNING)
                << "Stereo is only allowed for codec PCMU, PCMA and L16 ";
            StopRecording();
            return -1;
        }
    }
    memcpy(&codec_info_, &tmpAudioCodec, sizeof(CodecInst));
    _recordingActive = true;
    _ptrOutStream = &stream;
    _notificationMs = notificationTimeMs;
    _recordDurationMs = 0;
    return 0;
}

int32_t MediaFileImpl::StopRecording()
{

    rtc::CritScope lock(&_crit);
    if(!_recordingActive)
    {
        LOG(LS_WARNING) << "recording is not active!";
        return -1;
    }

    _isStereo = false;

    if(_ptrFileUtilityObj != NULL)
    {
        // Both AVI and WAV header has to be updated before closing the stream
        // because they contain size information.
        if((_fileFormat == kFileFormatWavFile) &&
            (_ptrOutStream != NULL))
        {
            _ptrFileUtilityObj->UpdateWavHeader(*_ptrOutStream);
        }
        delete _ptrFileUtilityObj;
        _ptrFileUtilityObj = NULL;
    }

    if(_ptrOutStream != NULL)
    {
        // If MediaFileImpl opened the OutStream it must be reclaimed here.
        if(_openFile)
        {
            delete _ptrOutStream;
            _openFile = false;
        }
        _ptrOutStream = NULL;
    }

    _recordingActive = false;
    codec_info_.pltype = 0;
    codec_info_.plname[0] = '\0';

    return 0;
}

bool MediaFileImpl::IsRecording()
{
    LOG(LS_VERBOSE) << "MediaFileImpl::IsRecording()";
    rtc::CritScope lock(&_crit);
    return _recordingActive;
}

int32_t MediaFileImpl::RecordDurationMs(uint32_t& durationMs)
{

    rtc::CritScope lock(&_crit);
    if(!_recordingActive)
    {
        durationMs = 0;
        return -1;
    }
    durationMs = _recordDurationMs;
    return 0;
}

bool MediaFileImpl::IsStereo()
{
    LOG(LS_VERBOSE) << "MediaFileImpl::IsStereo()";
    rtc::CritScope lock(&_crit);
    return _isStereo;
}

int32_t MediaFileImpl::SetModuleFileCallback(FileCallback* callback)
{

    rtc::CritScope lock(&_callbackCrit);

    _ptrCallback = callback;
    return 0;
}

int32_t MediaFileImpl::FileDurationMs(const char* fileName,
                                      uint32_t& durationMs,
                                      const FileFormats format,
                                      const uint32_t freqInHz)
{

    if(!ValidFileName(fileName))
    {
        return -1;
    }
    if(!ValidFrequency(freqInHz))
    {
        return -1;
    }

    ModuleFileUtility* utilityObj = new ModuleFileUtility();
    if(utilityObj == NULL)
    {
        LOG(LS_ERROR) << "failed to allocate utility object!";
        return -1;
    }

    const int32_t duration = utilityObj->FileDurationMs(fileName, format,
                                                        freqInHz);
    delete utilityObj;
    if(duration == -1)
    {
        durationMs = 0;
        return -1;
    }

    durationMs = duration;
    return 0;
}

int32_t MediaFileImpl::PlayoutPositionMs(uint32_t& positionMs) const
{
    rtc::CritScope lock(&_crit);
    if(!_playingActive)
    {
        positionMs = 0;
        return -1;
    }
    positionMs = _playoutPositionMs;
    return 0;
}

int32_t MediaFileImpl::codec_info(CodecInst& codecInst) const
{
    rtc::CritScope lock(&_crit);
    if(!_playingActive && !_recordingActive)
    {
        LOG(LS_ERROR) << "Neither playout nor recording has been initialized!";
        return -1;
    }
    if (codec_info_.pltype == 0 && codec_info_.plname[0] == '\0')
    {
        LOG(LS_ERROR) << "The CodecInst for "
                      << (_playingActive ? "Playback" : "Recording")
                      << " is unknown!";
        return -1;
    }
    memcpy(&codecInst,&codec_info_,sizeof(CodecInst));
    return 0;
}

bool MediaFileImpl::ValidFileFormat(const FileFormats format,
                                    const CodecInst*  codecInst)
{
    if(codecInst == NULL)
    {
        if(format == kFileFormatPreencodedFile ||
           format == kFileFormatPcm8kHzFile    ||
           format == kFileFormatPcm16kHzFile   ||
           format == kFileFormatPcm32kHzFile   ||
           format == kFileFormatPcm48kHzFile)
        {
            LOG(LS_ERROR) << "Codec info required for file format specified!";
            return false;
        }
    }
    return true;
}

bool MediaFileImpl::ValidFileName(const char* fileName)
{
    if((fileName == NULL) ||(fileName[0] == '\0'))
    {
        LOG(LS_ERROR) << "FileName not specified!";
        return false;
    }
    return true;
}


bool MediaFileImpl::ValidFilePositions(const uint32_t startPointMs,
                                       const uint32_t stopPointMs)
{
    if(startPointMs == 0 && stopPointMs == 0) // Default values
    {
        return true;
    }
    if(stopPointMs &&(startPointMs >= stopPointMs))
    {
        LOG(LS_ERROR) << "startPointMs must be less than stopPointMs!";
        return false;
    }
    if(stopPointMs &&((stopPointMs - startPointMs) < 20))
    {
        LOG(LS_ERROR) << "minimum play duration for files is 20 ms!";
        return false;
    }
    return true;
}

bool MediaFileImpl::ValidFrequency(const uint32_t frequency)
{
    if((frequency == 8000) || (frequency == 16000)|| (frequency == 32000) ||
       (frequency == 48000))
    {
        return true;
    }
    LOG(LS_ERROR) << "Frequency should be 8000, 16000, 32000, or 48000 (Hz)";
    return false;
}
}  // namespace webrtc
