/*
 *  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 "video_processing_impl.h"
#include "critical_section_wrapper.h"
#include "trace.h"

#include <cassert>

namespace webrtc {

namespace
{
    void
    SetSubSampling(VideoProcessingModule::FrameStats& stats,
                   const WebRtc_Word32 width,
                   const WebRtc_Word32 height)
    {
        if (width * height >= 640 * 480)
        {
            stats.subSamplWidth = 3; 
            stats.subSamplHeight = 3;
        }
        else if (width * height >= 352 * 288)
        {
            stats.subSamplWidth = 2; 
            stats.subSamplHeight = 2;
        }
        else if (width * height >= 176 * 144)
        {
            stats.subSamplWidth = 1; 
            stats.subSamplHeight = 1;
        }
        else
        {
            stats.subSamplWidth = 0; 
            stats.subSamplHeight = 0;
        }
    }
}

VideoProcessingModule*
VideoProcessingModule::Create(const WebRtc_Word32 id)
{
    WEBRTC_TRACE(webrtc::kTraceModuleCall, webrtc::kTraceVideoPreocessing, id, 
               "VideoProcessingModule::Create()");

    return new VideoProcessingModuleImpl(id);
}

void
VideoProcessingModule::Destroy(VideoProcessingModule* module)
{
    if (module)
    {
        WEBRTC_TRACE(webrtc::kTraceModuleCall, webrtc::kTraceVideoPreocessing,
            static_cast<VideoProcessingModuleImpl*>(module)->Id(),
                "VideoProcessingModule::destroy()");
        delete static_cast<VideoProcessingModuleImpl*>(module);
    }
}

WebRtc_Word32
VideoProcessingModuleImpl::ChangeUniqueId(const WebRtc_Word32 id)
{
    CriticalSectionScoped mutex(_mutex);
    WEBRTC_TRACE(webrtc::kTraceModuleCall, webrtc::kTraceVideoPreocessing, _id, "ChangeUniqueId(new id:%d)", id);   
    _id = id;
    _brightnessDetection.ChangeUniqueId(id);
    _deflickering.ChangeUniqueId(id);
    _denoising.ChangeUniqueId(id);
    _framePreProcessor.ChangeUniqueId(id);
    return VPM_OK;
}

WebRtc_Word32
VideoProcessingModuleImpl::Id() const
{
    CriticalSectionScoped mutex(_mutex);
    return _id;
}

VideoProcessingModuleImpl::VideoProcessingModuleImpl(const WebRtc_Word32 id) :
    _id(id),
    _mutex(*CriticalSectionWrapper::CreateCriticalSection())
{
    _brightnessDetection.ChangeUniqueId(id);
    _deflickering.ChangeUniqueId(id);
    _denoising.ChangeUniqueId(id);
    _framePreProcessor.ChangeUniqueId(id);
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideoPreocessing, _id, "Created");
}


VideoProcessingModuleImpl::~VideoProcessingModuleImpl()
{
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideoPreocessing, _id, "Destroyed");
    
    delete &_mutex;
}

void
VideoProcessingModuleImpl::Reset()
{
    CriticalSectionScoped mutex(_mutex);
    _deflickering.Reset();
    _denoising.Reset();
    _brightnessDetection.Reset();
    _framePreProcessor.Reset();

}

WebRtc_Word32
VideoProcessingModule::GetFrameStats(FrameStats& stats,
                                         const VideoFrame& frame)
{
    return GetFrameStats(stats, frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModule::GetFrameStats(FrameStats& stats,
                                         const WebRtc_UWord8* frame,
                                         const WebRtc_UWord32 width,
                                         const WebRtc_UWord32 height)
{
    if (frame == NULL)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, -1, "Null frame pointer");
        return VPM_PARAMETER_ERROR;
    }
    
    if (width == 0 || height == 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, -1, "Invalid frame size");
        return VPM_PARAMETER_ERROR;
    }

    ClearFrameStats(stats); // The histogram needs to be zeroed out.
    SetSubSampling(stats, width, height);

    // Compute histogram and sum of frame
    for (WebRtc_UWord32 i = 0; i < height; i += (1 << stats.subSamplHeight))
    {
        WebRtc_Word32 k = i * width;
        for (WebRtc_UWord32 j = 0; j < width; j += (1 << stats.subSamplWidth))
        { 
            stats.hist[frame[k + j]]++;
            stats.sum += frame[k + j];
        }
    }

    stats.numPixels = (width * height) / ((1 << stats.subSamplWidth) * (1 << stats.subSamplHeight));
    assert(stats.numPixels > 0);

    // Compute mean value of frame
    stats.mean = stats.sum / stats.numPixels;
    
    return VPM_OK;
}

bool
VideoProcessingModule::ValidFrameStats(const FrameStats& stats)
{
    if (stats.numPixels == 0)
    {
        return false;
    }

    return true;
}

void
VideoProcessingModule::ClearFrameStats(FrameStats& stats)
{
    stats.mean = 0;
    stats.sum = 0;
    stats.numPixels = 0;
    stats.subSamplWidth = 0;
    stats.subSamplHeight = 0;
    memset(stats.hist, 0, sizeof(stats.hist));
}

WebRtc_Word32
VideoProcessingModule::ColorEnhancement(VideoFrame& frame)
{
    return ColorEnhancement(frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModule::ColorEnhancement(WebRtc_UWord8* frame,
                                            const WebRtc_UWord32 width,
                                            const WebRtc_UWord32 height)
{
    return VideoProcessing::ColorEnhancement(frame, width, height);
}

WebRtc_Word32
VideoProcessingModule::Brighten(VideoFrame& frame, int delta)
{
    return Brighten(frame.Buffer(), frame.Width(), frame.Height(), delta);
}

WebRtc_Word32
VideoProcessingModule::Brighten(WebRtc_UWord8* frame,
                                    int width,
                                    int height,
                                    int delta)
{
    return VideoProcessing::Brighten(frame, width, height, delta);
}

WebRtc_Word32
VideoProcessingModuleImpl::Deflickering(VideoFrame& frame,
                                            FrameStats& stats)
{
    return Deflickering(frame.Buffer(), frame.Width(), frame.Height(), 
        frame.TimeStamp(), stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::Deflickering(WebRtc_UWord8* frame,
                                            const WebRtc_UWord32 width,
                                            const WebRtc_UWord32 height,
                                            const WebRtc_UWord32 timestamp,
                                            FrameStats& stats)
{
    CriticalSectionScoped mutex(_mutex);
    return _deflickering.ProcessFrame(frame, width, height, timestamp, stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::Denoising(VideoFrame& frame)
{
    return Denoising(frame.Buffer(), frame.Width(), frame.Height());
}

WebRtc_Word32
VideoProcessingModuleImpl::Denoising(WebRtc_UWord8* frame,
                                         const WebRtc_UWord32 width,
                                         const WebRtc_UWord32 height)
{
    CriticalSectionScoped mutex(_mutex);
    return _denoising.ProcessFrame(frame, width, height);
}

WebRtc_Word32
VideoProcessingModuleImpl::BrightnessDetection(const VideoFrame& frame,
                                                   const FrameStats& stats)
{
    return BrightnessDetection(frame.Buffer(), frame.Width(), frame.Height(), stats);
}

WebRtc_Word32
VideoProcessingModuleImpl::BrightnessDetection(const WebRtc_UWord8* frame,
                                                   const WebRtc_UWord32 width,
                                                   const WebRtc_UWord32 height,
                                                   const FrameStats& stats)
{
    CriticalSectionScoped mutex(_mutex);
    return _brightnessDetection.ProcessFrame(frame, width, height, stats);
}


void 
VideoProcessingModuleImpl::EnableTemporalDecimation(bool enable)
{
    CriticalSectionScoped mutex(_mutex);
    _framePreProcessor.EnableTemporalDecimation(enable);
}


void 
VideoProcessingModuleImpl::SetInputFrameResampleMode(VideoFrameResampling resamplingMode)
{
    CriticalSectionScoped cs(_mutex);
    _framePreProcessor.SetInputFrameResampleMode(resamplingMode);
}

WebRtc_Word32
VideoProcessingModuleImpl::SetMaxFrameRate(WebRtc_UWord32 maxFrameRate)
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.SetMaxFrameRate(maxFrameRate);

}

WebRtc_Word32
VideoProcessingModuleImpl::SetTargetResolution(WebRtc_UWord32 width, WebRtc_UWord32 height, WebRtc_UWord32 frameRate)
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.SetTargetResolution(width, height, frameRate);
}


WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedFrameRate()
{
    CriticalSectionScoped cs(_mutex);
    return  _framePreProcessor.DecimatedFrameRate();
}


WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedWidth() const
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.DecimatedWidth();
}

WebRtc_UWord32
VideoProcessingModuleImpl::DecimatedHeight() const
{
    CriticalSectionScoped cs(_mutex);
    return _framePreProcessor.DecimatedHeight();
}

WebRtc_Word32
VideoProcessingModuleImpl::PreprocessFrame(const VideoFrame *frame, VideoFrame **processedFrame)
{
    CriticalSectionScoped mutex(_mutex);
    return _framePreProcessor.PreprocessFrame(frame, processedFrame);
}

VideoContentMetrics*
VideoProcessingModuleImpl::ContentMetrics() const
{
    CriticalSectionScoped mutex(_mutex);
    return _framePreProcessor.ContentMetrics();
}


void
VideoProcessingModuleImpl::EnableContentAnalysis(bool enable)
{
    CriticalSectionScoped mutex(_mutex);
    _framePreProcessor.EnableContentAnalysis(enable);
}

} //namespace
