/*
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
*	
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*	
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*	
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#include <tinydshow/DSFrameRateFilter.h>

#include <iostream>
#include <string>

using namespace std;

#define FPS_INPUT  30
#define FPS_OUTPUT 5

DSFrameRateFilter::DSFrameRateFilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr)
:CTransInPlaceFilter (tszName, punk, CLSID_DSFrameRateFilter, phr)
{
	this->m_rtFrameLength = (10000000)/FPS_OUTPUT;

	this->m_inputFps = FPS_INPUT;
	this->m_outputFps = FPS_OUTPUT;

	this->m_iFrameNumber = 0;
	this->m_progress = 0;
	this->m_bProcessFrame = true;
}

DSFrameRateFilter::~DSFrameRateFilter()
{
}

HRESULT DSFrameRateFilter::SetFps(int inputFps, int outputFps)
{
	if(inputFps <= 0 || outputFps <= 0)
	{
		return E_FAIL;
	}

	// Stop prcessing
	this->m_bProcessFrame = false;

	if(inputFps < outputFps) 
	{
		this->m_inputFps = this->m_outputFps = inputFps;
	}
	else
	{
		this->m_outputFps = outputFps;
		this->m_inputFps = inputFps;
	}

	// Restart processing
	this->m_iFrameNumber = 0;
	this->m_progress = 0;
	this->m_bProcessFrame = true;

	return S_OK;
}

HRESULT DSFrameRateFilter::Transform(IMediaSample *pSample)
{	
	if(!this->m_bProcessFrame) return S_FALSE;

	CheckPointer(pSample, E_POINTER);

	HRESULT hr = S_OK;
	HRESULT ret = S_FALSE;

	pSample->SetTime(NULL, NULL);

	// Drop frame?
	if(this->m_iFrameNumber == 0)
	{
		ret = S_OK;
	}
	else if(this->m_progress >= this->m_inputFps)
	{
		this->m_progress -= this->m_inputFps;
		ret = S_OK;
	}

	// Mark frame as accepted
	if (ret == S_OK)
	{
		// Set TRUE on every sample for uncompressed frames
		pSample->SetSyncPoint(TRUE);
	}

	this->m_progress += this->m_outputFps;
	this->m_iFrameNumber++;

	return ret;
}

HRESULT DSFrameRateFilter::CheckInputType(const CMediaType* mtIn)
{ 
	return S_OK;
}

//Implement CreateInstance for your filter object. Typically, CreateInstance calls the constructor of your filter clas
CUnknown * WINAPI DSFrameRateFilter::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
{
	DSFrameRateFilter *pNewObject = new DSFrameRateFilter(_T("Tdshow DirectShow Framerate Limiter Filter."), punk, phr );
	if (pNewObject == NULL) 
	{
		*phr = E_OUTOFMEMORY;
	}
	return pNewObject;
} 
