/*
 *  Copyright (c) 2011 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 "incoming_video_stream.h"

#include "critical_section_wrapper.h"
#include "event_wrapper.h"
#include "trace.h"
#include "thread_wrapper.h"
#include "video_render_frames.h"
#include "tick_util.h"
#include "map_wrapper.h"
#include "common_video/libyuv/include/libyuv.h"

#include <cassert>

// Platform specifics
#if defined(_WIN32)
#include <windows.h>
#elif defined(WEBRTC_LINUX)
#include <ctime>
#include <sys/time.h>
#else
#include <sys/time.h>
#endif

namespace webrtc {
IncomingVideoStream::IncomingVideoStream(const WebRtc_Word32 moduleId,
                                         const WebRtc_UWord32 streamId) :
    _moduleId(moduleId),
    _streamId(streamId),
    _streamCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
    _threadCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
    _bufferCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
    _ptrIncomingRenderThread(),
    _deliverBufferEvent(*EventWrapper::Create()),
    _running(false),
    _ptrExternalCallback(NULL),
    _ptrRenderCallback(NULL),
    _renderBuffers(*(new VideoRenderFrames)),
    _callbackVideoType(kVideoI420),
    _callbackWidth(0),
    _callbackHeight(0),
    _incomingRate(0),
    _lastRateCalculationTimeMs(0),
    _numFramesSinceLastCalculation(0),
    _lastRenderedFrame(),
    _tempFrame(),
    _startImage(),
    _timeoutImage(),
    _timeoutTime(),
    _mirrorFramesEnabled(false),
    _mirroring(),
    _transformedVideoFrame()
{
    WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer, _moduleId,
                 "%s created for stream %d", __FUNCTION__, streamId);
}

IncomingVideoStream::~IncomingVideoStream()
{
    WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer, _moduleId,
                 "%s deleted for stream %d", __FUNCTION__, _streamId);

    Stop();

    // _ptrIncomingRenderThread - Delete in stop
    delete &_renderBuffers;
    delete &_streamCritsect;
    delete &_bufferCritsect;
    delete &_threadCritsect;
    delete &_deliverBufferEvent;

}

WebRtc_Word32 IncomingVideoStream::ChangeModuleId(const WebRtc_Word32 id)
{
    CriticalSectionScoped cs(_streamCritsect);

    _moduleId = id;
    return 0;
}

VideoRenderCallback*
IncomingVideoStream::ModuleCallback()
{
    CriticalSectionScoped cs(_streamCritsect);
    return this;
}

WebRtc_Word32 IncomingVideoStream::RenderFrame(const WebRtc_UWord32 streamId,
                                               VideoFrame& videoFrame)
{

    CriticalSectionScoped csS(_streamCritsect);
    WEBRTC_TRACE(kTraceStream, kTraceVideoRenderer, _moduleId,
                 "%s for stream %d, render time: %u", __FUNCTION__, _streamId,
                 videoFrame.RenderTimeMs());

    if (!_running)
    {
        WEBRTC_TRACE(kTraceStream, kTraceVideoRenderer, _moduleId,
                     "%s: Not running", __FUNCTION__);
        return -1;
    }

    if (true == _mirrorFramesEnabled)
    {
        _transformedVideoFrame.VerifyAndAllocate(videoFrame.Length());
        if (_mirroring.mirrorXAxis)
        {
            MirrorI420UpDown(videoFrame.Buffer(),
                                     _transformedVideoFrame.Buffer(),
                                     videoFrame.Width(), videoFrame.Height());
            _transformedVideoFrame.SetLength(videoFrame.Length());
            _transformedVideoFrame.SetWidth(videoFrame.Width());
            _transformedVideoFrame.SetHeight(videoFrame.Height());
            videoFrame.SwapFrame(_transformedVideoFrame);
        }
        if (_mirroring.mirrorYAxis)
        {
            MirrorI420LeftRight(videoFrame.Buffer(),
                                        _transformedVideoFrame.Buffer(),
                                        videoFrame.Width(), videoFrame.Height());
            _transformedVideoFrame.SetLength(videoFrame.Length());
            _transformedVideoFrame.SetWidth(videoFrame.Width());
            _transformedVideoFrame.SetHeight(videoFrame.Height());
            videoFrame.SwapFrame(_transformedVideoFrame);
        }
    }

    // Rate statistics
    _numFramesSinceLastCalculation++;
    WebRtc_Word64 nowMs = TickTime::MillisecondTimestamp();
    if (nowMs >= _lastRateCalculationTimeMs + KFrameRatePeriodMs)
    {
        _incomingRate = (WebRtc_UWord32) (1000 * _numFramesSinceLastCalculation
                / (nowMs - _lastRateCalculationTimeMs));
        _numFramesSinceLastCalculation = 0;
        _lastRateCalculationTimeMs = nowMs;
    }

    // Insert frame
    CriticalSectionScoped csB(_bufferCritsect);
    if (_renderBuffers.AddFrame(&videoFrame) == 1)
        _deliverBufferEvent.Set();

    return 0;
}

WebRtc_Word32 IncomingVideoStream::SetStartImage(const VideoFrame& videoFrame)
{
    CriticalSectionScoped csS(_threadCritsect);
    return _startImage.CopyFrame(videoFrame);
}

WebRtc_Word32 IncomingVideoStream::SetTimeoutImage(const VideoFrame& videoFrame,
                                                   const WebRtc_UWord32 timeout)
{
    CriticalSectionScoped csS(_threadCritsect);
    _timeoutTime = timeout;
    return _timeoutImage.CopyFrame(videoFrame);
}

WebRtc_Word32 IncomingVideoStream::SetRenderCallback(VideoRenderCallback* renderCallback)
{
    CriticalSectionScoped cs(_streamCritsect);

    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _moduleId,
                 "%s(%x) for stream %d", __FUNCTION__, renderCallback,
                 _streamId);
    _ptrRenderCallback = renderCallback;
    return 0;
}

WebRtc_Word32 IncomingVideoStream::EnableMirroring(const bool enable,
                                                   const bool mirrorXAxis,
                                                   const bool mirrorYAxis)
{
    CriticalSectionScoped cs(_streamCritsect);
    _mirrorFramesEnabled = enable;
    _mirroring.mirrorXAxis = mirrorXAxis;
    _mirroring.mirrorYAxis = mirrorYAxis;

    return 0;
}

WebRtc_Word32 IncomingVideoStream::SetExternalCallback(VideoRenderCallback* externalCallback)
{
    CriticalSectionScoped cs(_streamCritsect);

    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _moduleId,
                 "%s(%x) for stream %d", __FUNCTION__, externalCallback,
                 _streamId);
    _ptrExternalCallback = externalCallback;
    _callbackVideoType = kVideoI420;
    _callbackWidth = 0;
    _callbackHeight = 0;
    return 0;
}

WebRtc_Word32 IncomingVideoStream::Start()
{
    CriticalSectionScoped csS(_streamCritsect);
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _moduleId,
                 "%s for stream %d", __FUNCTION__, _streamId);
    if (_running)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _moduleId,
                     "%s: Already running", __FUNCTION__);
        return 0;
    }

    CriticalSectionScoped csT(_threadCritsect);
    assert(_ptrIncomingRenderThread == NULL);

    _ptrIncomingRenderThread
            = ThreadWrapper::CreateThread(IncomingVideoStreamThreadFun, this,
                                          kRealtimePriority,
                                          "IncomingVideoStreamThread");
    if (!_ptrIncomingRenderThread)
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _moduleId,
                     "%s: No thread", __FUNCTION__);
        return -1;
    }

    unsigned int tId = 0;
    if (_ptrIncomingRenderThread->Start(tId))
    {
        WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _moduleId,
                     "%s: thread started: %u", __FUNCTION__, tId);
    }
    else
    {
        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _moduleId,
                     "%s: Could not start send thread", __FUNCTION__);
        return -1;
    }
    _deliverBufferEvent.StartTimer(false, KEventStartupTimeMS);

    _running = true;
    return 0;
}

WebRtc_Word32 IncomingVideoStream::Stop()
{
    CriticalSectionScoped csStream(_streamCritsect);
    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _moduleId,
                 "%s for stream %d", __FUNCTION__, _streamId);

    if (!_running)
    {
        WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _moduleId,
                     "%s: Not running", __FUNCTION__);
        return 0;
    }

    _threadCritsect.Enter();
    if (_ptrIncomingRenderThread)
    {
        ThreadWrapper* ptrThread = _ptrIncomingRenderThread;
        _ptrIncomingRenderThread = NULL;
        ptrThread->SetNotAlive();
#ifndef _WIN32
        _deliverBufferEvent.StopTimer();
#endif
        _threadCritsect.Leave();
        if (ptrThread->Stop())
        {
            delete ptrThread;
        }
        else
        {
            assert(false);
            WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _moduleId,
                         "%s: Not able to stop thread, leaking", __FUNCTION__);
        }
    }
    else
    {
        _threadCritsect.Leave();
    }
    _running = false;
    return 0;
}

WebRtc_Word32 IncomingVideoStream::Reset()
{
    CriticalSectionScoped csStream(_streamCritsect);
    CriticalSectionScoped csBuffer(_bufferCritsect);

    _renderBuffers.ReleaseAllFrames();
    return 0;
}

WebRtc_UWord32 IncomingVideoStream::StreamId() const
{
    CriticalSectionScoped csStream(_streamCritsect);
    return _streamId;
}

WebRtc_UWord32 IncomingVideoStream::IncomingRate() const
{
    CriticalSectionScoped cs(_streamCritsect);
    return _incomingRate;
}

bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj)
{
    return static_cast<IncomingVideoStream*> (obj)->IncomingVideoStreamProcess();
}

bool IncomingVideoStream::IncomingVideoStreamProcess()
{
    if (kEventError != _deliverBufferEvent.Wait(KEventMaxWaitTimeMs))
    {
        if (_ptrIncomingRenderThread == NULL)
        {
            // Terminating
            return false;
        }

        _threadCritsect.Enter();

        VideoFrame* ptrFrameToRender = NULL;

        // Get a new frame to render and the time for the frame after this one.
        _bufferCritsect.Enter();
        ptrFrameToRender = _renderBuffers.FrameToRender();
        WebRtc_UWord32 waitTime = _renderBuffers.TimeToNextFrameRelease();
        _bufferCritsect.Leave();

        // Set timer for next frame to render
        if (waitTime > KEventMaxWaitTimeMs)
        {
            waitTime = KEventMaxWaitTimeMs;
        }
        _deliverBufferEvent.StartTimer(false, waitTime);

        if (!ptrFrameToRender)
        {
            if (_ptrRenderCallback)
            {
                if (_lastRenderedFrame.RenderTimeMs() == 0
                        && _startImage.Size()) // And we have not rendered anything and have a start image
                {
                    _tempFrame.CopyFrame(_startImage);// Copy the startimage if the renderer modifies the render buffer.
                    _ptrRenderCallback->RenderFrame(_streamId, _tempFrame);
                }
                else if (_timeoutImage.Size()
                        && _lastRenderedFrame.RenderTimeMs() + _timeoutTime
                                < TickTime::MillisecondTimestamp()) // We have rendered something a long time ago and have a timeout image
                {
                    _tempFrame.CopyFrame(_timeoutImage); // Copy the timeoutImage if the renderer modifies the render buffer.
                    _ptrRenderCallback->RenderFrame(_streamId, _tempFrame);
                }
            }

            // No frame
            _threadCritsect.Leave();
            return true;
        }

        // Send frame for rendering
        if (_ptrExternalCallback)
        {
            WEBRTC_TRACE(kTraceStream,
                         kTraceVideoRenderer,
                         _moduleId,
                         "%s: executing external renderer callback to deliver frame",
                         __FUNCTION__, ptrFrameToRender->RenderTimeMs());
            _ptrExternalCallback->RenderFrame(_streamId, *ptrFrameToRender);
        }
        else
        {
            if (_ptrRenderCallback)
            {
                WEBRTC_TRACE(kTraceStream, kTraceVideoRenderer, _moduleId,
                             "%s: Render frame, time: ", __FUNCTION__,
                             ptrFrameToRender->RenderTimeMs());
                _ptrRenderCallback->RenderFrame(_streamId, *ptrFrameToRender);
            }
        }

        // Release critsect before calling the module user
        _threadCritsect.Leave();

        // We're done with this frame, delete it.
        if (ptrFrameToRender)
        {
            CriticalSectionScoped cs(_bufferCritsect);
            _lastRenderedFrame.SwapFrame(*ptrFrameToRender);
            _renderBuffers.ReturnFrame(ptrFrameToRender);
        }
    }
    return true;
}
WebRtc_Word32 IncomingVideoStream::GetLastRenderedFrame(VideoFrame& videoFrame) const
{
    CriticalSectionScoped cs(_bufferCritsect);
    return videoFrame.CopyFrame(_lastRenderedFrame);
}

} //namespace webrtc

