/** 
{file:
	{name: VidyoVideoFrame.h}
	{description: Monitor available for sharing. }
	{copyright:
		(c) 2013-2016 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.}
}
*/
#ifndef VIDYO_VIDEOFRAME_H_ 
#define VIDYO_VIDEOFRAME_H_ 

#include <Lmi/Utils/LmiTypes.h>
#include <Lmi/Utils/LmiVector.h>
#include <Lmi/Utils/LmiList.h>
#include <Lmi/Utils/LmiString.h>
#include <Lmi/Os/LmiSharedPtr.h>
#include <Lmi/Video/Common/LmiVideoFrame.h>
#include "VidyoMediaFormats.h"

#include <Lmi/Os/LmiTime.h>

LMI_BEGIN_EXTERN_C

struct VidyoVideoFrameImpl_;
typedef struct VidyoVideoFrameImpl_ VidyoVideoFrameImpl;
Declare_LmiSharedPtr(VidyoVideoFrameImpl)
Declare_LmiSharedPtrWrapper(VidyoVideoFrame, VidyoVideoFrameImpl)
Declare_LmiWeakPtrWrapper(VidyoVideoFrameHandle, VidyoVideoFrame, VidyoVideoFrameImpl)
Declare_LmiVector(VidyoVideoFrame)
Declare_LmiList(VidyoVideoFrame)

/**
{type apigroup="connector,simple" reference-counted="yes":
	{name: VidyoVideoFrame}
	{parent: Device}
	{include: Lmi/VidyoClient/VidyoVideoFrame.h}
	{description: This object represents a video frame.}
}
*/

/**
{callback:
	{name: VidyoVideoFrameReleaseCallback}
	{parent: VidyoVideoFrame}
	{description: Describes a callback used to release externally allocated buffer memory of an VidyoVideoFrame.}
	{prototype: void (*VidyoVideoFrameReleaseCallback)(void* buffer, LmiSizeT size, LmiAllocator* alloc)}
	{parameter:	{name: buffer} {description: The buffer to be released.}}
	{parameter:	{name: size} {description: The size of the buffer.}}
	{parameter:	{name: alloc}{description: The allocator used to allocate the buffer. {code:alloc} can be NULL, for example, if the buffer memory was statically allocated.}}
}
*/

typedef void(*VidyoVideoFrameReleaseCallback)(void* buffer, LmiSizeT size, LmiAllocator* alloc);

/**
{function visibility="public":
	{name: VidyoVideoFrameConstructFromKnownFormatWithExternalBuffer}
	{parent: VidyoVideoFrame}
	{description: Constructs a video frame with externally-allocated memory to hold the frame\'s pixel data.}
	{prototype: VidyoVideoFrame* VidyoVideoFrameConstructFromKnownFormatWithExternalBuffer(VidyoVideoFrame* x, const VidyoMediaFormat format, LmiUint8* buffer, LmiUint size, LmiAllocator* bufferAlloc, VidyoVideoFrameReleaseCallback releaseCallback, LmiUint width, LmiUint height, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: The media format of the video frame.}}
	{parameter: {name: buffer} {description: A pointer to externally allocated memory that holds the pixel data.}}
	{parameter: {name: size} {description: The size, in bytes, of the frame data.}}
	{parameter: {name: bufferAlloc} {description: External allocator for frame-buffer data.}}
	{parameter: {name: releaseCallback}{description: A callback to be called on when external buffer may be reclaimed.}}
	{parameter: {name: width} {description: The width of the video media frame in pixels.}}
	{parameter: {name: height} {description: The height of the video media frame in pixels.}}
	{parameter: {name: alloc} {description: An allocator for non-frame-buffer data.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
	{note: This constructor will not make an internal copy of the frame buffer.}
}
*/
VidyoVideoFrame* VidyoVideoFrameConstructFromKnownFormatWithExternalBuffer(VidyoVideoFrame* x, const VidyoMediaFormat format, LmiUint8* buffer, LmiUint size, LmiAllocator* bufferAlloc, VidyoVideoFrameReleaseCallback releaseCallback, LmiUint width, LmiUint height, LmiAllocator* alloc);

/**
{function apigroup="connector,simple":
	{name: VidyoVideoFrameConstructCopy}
	{parent: VidyoVideoFrame}
	{description: Constructs an VidyoVideoFrame object as a copy of another.}
	{prototype: VidyoVideoFrame *VidyoVideoFrameConstructCopy(VidyoVideoFrame *obj, const VidyoVideoFrame *other)}
	{parameter: {name: obj} {description: The VidyoVideoFrame object to construct.}}
	{parameter: {name: other} {description: The call object to make a copy of.}}
	{return: A pointer to a constructed object on success, or NULL on failure.}
}
*/

/**
{function apigroup="connector,simple":
	{name: VidyoVideoFrameDestruct}
	{parent: VidyoVideoFrame}
	{description: Destructs an VidyoVideoFrame object.}
	{prototype: void VidyoVideoFrameDestruct(VidyoVideoFrame *obj)}
	{parameter: {name: obj} {description: The VidyoVideoFrame object to destruct.}}
}
*/

/**
{function apigroup="connector,simple" visibility="private":
	{name: VidyoVideoFrameAssign}
	{parent: VidyoVideoFrame}
	{description: Assigns one VidyoVideoFrame object the value of another. }
	{prototype: VidyoVideoFrame *VidyoVideoFrameAssign(VidyoVideoFrame *obj, const VidyoVideoFrame *other)}
	{parameter: {name: obj} {description: The VidyoVideoFrame object.}}
	{parameter: {name: other} {description: The call object to make a copy of.}}
	{return: A pointer to the destination object on success, or NULL on failure.}
}
*/

/**
{function visibility="private":
	{name: VidyoVideoFrameSetUserData}
	{parent: VidyoVideoFrame}
	{description: }
	{prototype: void VidyoVideoFrameSetUserData(VidyoVideoFrame* f, LmiVoidPtr userData)}
	{parameter:
		{name: f}
		{description: }
	}
	{parameter:
		{name: userData}
		{description: }
	}
}
*/
void VidyoVideoFrameSetUserData(VidyoVideoFrame* f, LmiVoidPtr userData);

/**
{function visibility="private":
	{name: VidyoVideoFrameGetUserData}
	{parent: VidyoVideoFrame}
	{description: }
	{prototype: LmiVoidPtr VidyoVideoFrameGetUserData(const VidyoVideoFrame* f)}
	{parameter:
		{name: f}
		{description: }
	}
	{return: }
}
*/
LmiVoidPtr VidyoVideoFrameGetUserData(const VidyoVideoFrame* f);

/**
{function apigroup="connector,simple":
	{name: VidyoVideoFrameGetWidth}
	{parent: VidyoVideoFrame}
	{description: Gets the width of the frame.}
	{prototype: LmiUint VidyoVideoFrameGetWidth(const VidyoVideoFrame* f)}
	{parameter:
		{name: f}
		{description: The VidyoVideoFrame object. }
	}
	{return: Width of the frame.}
}
*/
LmiUint VidyoVideoFrameGetWidth(const VidyoVideoFrame* f);

/**
{function apigroup="connector,simple":
	{name: VidyoVideoFrameGetHeight}
	{parent: VidyoVideoFrame}
	{description: Gets the height of the frame.}
	{prototype: LmiUint VidyoVideoFrameGetHeight(const VidyoVideoFrame* f)}
	{parameter:
		{name: f}
		{description: The VidyoVideoFrame object. }
	}
	{return: Height of the frame.}
}
*/
LmiUint VidyoVideoFrameGetHeight(const VidyoVideoFrame* f);

/**
{function apigroup="connector,simple":
	{name: VidyoVideoFrameGetFormat}
	{parent: VidyoVideoFrame}
	{description: Gets the format of the frame.}
	{prototype: const LmiString* VidyoVideoFrameGetFormat(const VidyoVideoFrame* f)}
	{parameter:
		{name: f}
		{description: The VidyoVideoFrame object. }
	}
	{return: Format of the video frame.}
}
*/
const LmiString* VidyoVideoFrameGetFormat(const VidyoVideoFrame* f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetData}
 {parent: VidyoVideoFrame}
 {description: Gets the pointer to the frame\'s payload.}
 {prototype: LmiUint8* VidyoVideoFrameGetData(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint8* VidyoVideoFrameGetData(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetSize}
 {parent: VidyoVideoFrame}
 {description: Gets the size in bytes of the frame\'s payload.}
 {prototype: LmiUint VidyoVideoFrameGetSize(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetSize(const VidyoVideoFrame *f);

/**
{function apigroup="connector,simple":
{name: VidyoVideoFrameGetDataY}
{parent: VidyoVideoFrame}
{description: Gets the pointer to the frame\'s payload of the Y plane.}
{prototype: LmiUint8* VidyoVideoFrameGetDataY(const VidyoVideoFrame *f)}
{parameter:
{name: f}
{description: The VidyoVideoFrame object. }
}
{return:}
}
*/
LmiUint8* VidyoVideoFrameGetDataY(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetOffsetY}
 {parent: VidyoVideoFrame}
 {description: Gets the number of bytes from the Y plane\'s payload to the start of the pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetOffsetY(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetOffsetY(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetSizeY}
 {parent: VidyoVideoFrame}
 {description: Gets the size in bytes of the plane\'s payload.}
 {prototype: LmiUint VidyoVideoFrameGetSizeY(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetSizeY(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetPitchY}
 {parent: VidyoVideoFrame}
 {description: Gets the number of bytes between consecutive pixels in a row of the Y plane}
 {prototype: LmiUint VidyoVideoFrameGetPitchY(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetPitchY(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetWidthY}
 {parent: VidyoVideoFrame}
 {description: Gets the width in bytes of the frame\'s Y pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetWidthY(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetWidthY(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetHeightY}
 {parent: VidyoVideoFrame}
 {description: Gets the height in bytes of the frame\'s Y pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetHeightY(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetHeightY(const VidyoVideoFrame *f);

/**
{function apigroup="connector,simple":
{name: VidyoVideoFrameGetDataCb}
{parent: VidyoVideoFrame}
{description: Gets the pointer to the frame\'s payload of the Cb plane.}
{prototype: LmiUint8* VidyoVideoFrameGetDataCb(const VidyoVideoFrame *f)}
{parameter:
{name: f}
{description: The VidyoVideoFrame object. }
}
{return:}
}
*/
LmiUint8* VidyoVideoFrameGetDataCb(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetOffsetCb}
 {parent: VidyoVideoFrame}
 {description: Gets the number of bytes from the Cb plane\'s payload to the start of the pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetOffsetCb(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetOffsetCb(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetSizeCb}
 {parent: VidyoVideoFrame}
 {description: Gets the size in bytes of the plane\'s payload.}
 {prototype: LmiUint VidyoVideoFrameGetSizeCb(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetSizeCb(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetPitchCb}
 {parent: VidyoVideoFrame}
 {description: Gets the number of bytes between consecutive pixels in a row of the Cb plane.}
 {prototype: LmiUint VidyoVideoFrameGetPitchCb(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetPitchCb(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetWidthCb}
 {parent: VidyoVideoFrame}
 {description: Gets the width in bytes of the frame\'s Cb pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetWidthCb(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetWidthCb(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetHeightCb}
 {parent: VidyoVideoFrame}
 {description: Gets the height in bytes of the frame\'s Cb pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetHeightCb(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetHeightCb(const VidyoVideoFrame *f);

/**
{function apigroup="connector,simple":
{name: VidyoVideoFrameGetDataCr}
{parent: VidyoVideoFrame}
{description: Gets the pointer to the frame\'s payload of the Cr plane.}
{prototype: LmiUint8* VidyoVideoFrameGetDataCr(const VidyoVideoFrame *f)}
{parameter:
{name: f}
{description: The VidyoVideoFrame object. }
}
{return:}
}
*/
LmiUint8* VidyoVideoFrameGetDataCr(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetOffsetCr}
 {parent: VidyoVideoFrame}
 {description: Gets the number of bytes from the Cr plane\'s payload to the start of the pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetOffsetCr(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetOffsetCr(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetSizeCr}
 {parent: VidyoVideoFrame}
 {description: Gets the size in bytes of the Cr plane\'s payload.}
 {prototype: LmiUint VidyoVideoFrameGetSizeCr(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetSizeCr(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetPitchCr}
 {parent: VidyoVideoFrame}
 {description: Gets the number of bytes between consecutive pixels in a row of the Cr plane.}
 {prototype: LmiUint VidyoVideoFrameGetPitchCr(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetPitchCr(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetWidthCr}
 {parent: VidyoVideoFrame}
 {description: Gets the width in bytes of the frame\'s Cr pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetWidthCr(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetWidthCr(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetHeightCr}
 {parent: VidyoVideoFrame}
 {description: Gets the height in bytes of the frame\'s Cr pixel data.}
 {prototype: LmiUint VidyoVideoFrameGetHeightCr(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiUint VidyoVideoFrameGetHeightCr(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetElapsedTime}
 {parent: VidyoVideoFrame}
 {description: Gets the elapsed time since the beginning of frame capture that is increased by the duration of each frame.}
 {prototype: LmiTime VidyoVideoFrameGetElapsedTime(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiTime VidyoVideoFrameGetElapsedTime(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameGetTimestamp}
 {parent: VidyoVideoFrame}
 {description: Gets the wallclock timestamp associated with the creation of the audio frame object.}
 {prototype: LmiTime VidyoVideoFrameGetTimestamp(const VidyoVideoFrame *f)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {return:}
 }
 */
LmiTime VidyoVideoFrameGetTimestamp(const VidyoVideoFrame *f);

/**
 {function apigroup="connector,simple":
 {name: VidyoVideoFrameSetTimeProperties}
 {parent: VidyoVideoFrame}
 {description: Sets elapsedTime and timestamp of the video frame. In case elapsedTime and timestamp are equal to zero will set current monotonic and wall time. }
 {prototype: LmiBool VidyoVideoFrameSetTimeProperties(VidyoVideoFrame *f, LmiTime elapsedTime, LmiTime timestamp)}
 {parameter:
 {name: f}
 {description: The VidyoVideoFrame object. }
 }
 {parameter:
 {name: elapsedTime}
 {description: The elapsed time of the video frame. If zero will set current monotonic time. }
 }
 {parameter:
 {name: timestamp}
 {description: Video frame timestamp. If zero will set current wall time. }
 }
 {return:}
 }
 */
LmiBool VidyoVideoFrameSetTimeProperties(VidyoVideoFrame *f, LmiTime elapsedTime, LmiTime timestamp);


/**
{function visibility="private":
	{name: VidyoVideoFrameGetVideoFrame}
	{parent: VidyoVideoFrame}
	{description: }
	{prototype: const LmiVideoFrame* VidyoVideoFrameGetVideoFrame(const VidyoVideoFrame *f)}
	{parameter:
		{name: f}
		{description: The VidyoVideoFrame object. }
	}
	{return:}
}
*/
const LmiVideoFrame* VidyoVideoFrameGetVideoFrame(const VidyoVideoFrame *f);


#if LMI_INLINE_NEED_HEADER_FILE_DEFINITIONS
#include "VidyoVideoFrameInline.h"
#endif

LMI_END_EXTERN_C

#endif /* VIDYO_VIDEOFRAME_H_ */
