/**
   {file: 
	{name: LmiVideoStabilizer.h}
	{description: Defines the main structures and functions used for generic YUV 4:2:0 object.}
	{copyright:
		(c) 2011-2015 Vidyo, Inc.,
		433 Hackensack Avenue,
		Hackensack, NJ  07601.
	
		All rights reserved.
	
		The information contained herein is proprietary to Vidyo, Inc.
		and shall not be reproduced, copied (in whole or in part), adapted,
		modified, disseminated, transmitted, transcribed, stored in a retrieval
		system, or translated into any language in any form by any means
		without the express written consent of Vidyo, Inc.
		                  ***** CONFIDENTIAL *****
	}
   }
*/

#ifndef LMI_VIDEOSTABILIZER_H_
#define LMI_VIDEOSTABILIZER_H_

#include <Lmi/Video/Common/LmiVideoFrame.h>

LMI_BEGIN_EXTERN_C

/**
{type visibility="public":
	{name: LmiVideoStabilizer}
	{parent: VideoCommon}
	{include: Lmi/Video/Common/LmiVideoStabilizer.h}
	{description: Module used for video stabilization algorithm.}
}
*/
typedef struct 
{
    LmiBool firstFrame;
    LmiUint inputWidth;
    LmiUint inputHeight;

    LmiUint cropWidth;
    LmiUint cropHeight;
    LmiUint cropMarginX;
    LmiUint cropMarginY;
    LmiUint sad8width;
    LmiUint sad8height;
    LmiUint sad8offsetX;
    LmiUint sad8offsetY;
    LmiUint sad2width;
    LmiUint sad2height;
    LmiUint sad2offsetX;
    LmiUint sad2offsetY;

    LmiInt mvXhistory;
    LmiInt mvYhistory;
    LmiUint mvXcounter;
    LmiUint mvYcounter;
    LmiInt mvXstate;
    LmiInt mvYstate;

    LmiUint8 *previous;
    LmiUint8 *prevTemp1;
    LmiUint8 *prevTemp2;
    LmiUint8 *currTemp1;
    LmiUint8 *currTemp2;
    LmiAllocator *alloc;
    LmiMutex mutex;
} LmiVideoStabilizer;


/**
{function visibility="public":
	{name: LmiVideoStabilizerConstruct}
	{parent: LmiVideoStabilizer}
	{description: Constructs a video stabilizer module. }
	{prototype: LmiVideoStabilizer *LmiVideoStabilizerConstruct(LmiVideoStabilizer *sta, LmiAllocator *alloc)}
	{parameter: 
		{name: sta}
        {description: A pointer to an uninitialized LmiVideoStabilizer structure.}
	}
	{parameter: 
		{name: alloc}
		{description: A pointer to a LmiAllocator.}
	}
    {return: A pointer to the constructed object or NULL on error.}
}
*/
LmiVideoStabilizer *LmiVideoStabilizerConstruct(LmiVideoStabilizer *sta, LmiAllocator *alloc);

/**
{function visibility="public":
	{name: LmiVideoStabilizerGetCropDimension}
	{parent: LmiVideoStabilizer}
	{description: Calculates crop dimensions for given size. }
	{prototype: void LmiVideoStabilizerGetCropDimension(const LmiUint origSize, LmiUint *cropMargin, LmiUint *croppedSize)}
	{parameter: 
		{name: origSize}
        {description: Input value of original dimension size.}
	}
	{parameter: 
		{name: cropMargin}
		{description: Output value of crop margin size.}
	}
	{parameter: 
		{name: croppedSize}
		{description: Output value of cropped dimenstion size.}
	}
}
*/
void LmiVideoStabilizerGetCropDimension(const LmiUint origSize, LmiUint *cropMargin, LmiUint *croppedSize);

/**
{function visibility="public":
	{name: LmiVideoStabilizerDestruct}
	{parent: LmiVideoStabilizer}
	{description: Destructs a video stabilization module.}
	{prototype: void LmiVideoStabilizerDestruct(LmiVideoStabilizer *sta)}
	{parameter: 
		{name: sta}
        {description: A pointer to an initialized LmiVideoStabilizer structure.}
	}
}
*/
void LmiVideoStabilizerDestruct(LmiVideoStabilizer *sta);

/**
{function visibility="public":
	{name: LmiVideoStabilizerReset}
	{parent: LmiVideoStabilizer}
	{description: Resets the state of the video stabilization module.}
	{prototype: void LmiVideoStabilizerReset(LmiVideoStabilizer *sta)}
	{parameter: 
		{name: sta}
        {description: A pointer to an initialized LmiVideoStabilizer structure.}
	}
}
*/
void LmiVideoStabilizerReset(LmiVideoStabilizer *sta);

/**
{function visibility="public":
	{name: LmiVideoStabilizerProcessFrame}
	{parent: LmiVideoStabilizer}
	{description: Runs video stabilization algorithm on given LmiVideoFrame crops the image accordingly.}
	{prototype: void LmiVideoStabilizerProcessFrame(LmiVideoStabilizer *sta, LmiVideoFrame *yuv, LmiVideoFrame *yuvOut)}
	{parameter: 
		{name: sta}
        {description: A pointer to an initialized LmiVideoStabilizer structure.}
	}
	{parameter: 
		{name: yuv}
        {description: Full-sized input frame. Must be I420 format.}
	}
	{parameter: 
		{name: yuvOut}
        {description: Crop-sized output frame. Must be I420 format.
                      Algorithm will copy cropped frame into this object.
                      Use LmiVideoStabilizerGetCropDimension() to determine proper dimensions for yuvOut}
	}
}
*/
void LmiVideoStabilizerProcessFrame(LmiVideoStabilizer *sta, LmiVideoFrame *yuv, LmiVideoFrame *yuvOut);

LMI_END_EXTERN_C

#endif /* LMI_VIDEOSTABILIZER_H_ */
