/**
{file:
	{name: LmiVideoFrame.h}
	{description: Defines LmiVideoFrame functions.}
	{copyright:
		(c) 2010-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.
		                  ***** CONFIDENTIAL *****
	}
}
*/
#ifndef LMI_VIDEOFRAME_H
#define LMI_VIDEOFRAME_H

#include <Lmi/Utils/LmiAllocator.h>
#include <Lmi/Utils/LmiMediaFormat.h>
#include <Lmi/Utils/LmiLocation.h>
#include <Lmi/Os/LmiTime.h>
#include <Lmi/Os/LmiSharedPtr.h>
#include <Lmi/Media/Common/LmiMediaFrame.h>
#include <Lmi/Os/LmiQueue.h>

LMI_BEGIN_EXTERN_C

/**
{type visibility="public":
	{name: LmiVideoPlane}
	{parent: VideoCommon}
	{include: Lmi/Video/Common/LmiVideoFrame.h}
	{description: Describes a plane of a video frame.}
}
*/
typedef struct {
	void* buffer;
	LmiSizeT size;
	LmiSizeT width;
	LmiSizeT height;
	LmiSizeT pitch;
	LmiSizeT pixelPitch;
	LmiSizeT offset;
} LmiVideoPlane;

/**
{function:
	{name: LmiVideoPlaneConstruct}
	{parent: LmiVideoPlane}
	{description: Constructs an LmiVideoPlane using an external buffer as the plane\'s buffer.}
 	{prototype: LmiVideoPlane* LmiVideoPlaneConstruct(LmiVideoPlane* x, void* buffer, LmiSizeT size, LmiSizeT width, LmiSizeT height, LmiSizeT pitch, LmiSizeT offset)}
	{parameter:
		{name: x}
		{description: The object to construct.}
	}
 	{parameter:
		{name: buffer}
		{description: A pointer to the buffer to store as the plane buffer.  This buffer will not be deallocated by LmiVideoPlaneDestruct. }
	}
	{parameter:
		{name: size}
		{description: The size in bytes of the buffer.}
	}
	{parameter:
		{name: width}
		{description: The width in pixels of the plane.}
	}
	{parameter:
		{name: height}
		{description: The number of pitch sized rows in the plane buffer.}
	}
 	{parameter:
		{name: pitch}
		{description: The number of bytes in each row of the plane buffer.}
	}
	{parameter:
		{name: offset}
		{description: The number of bytes of padding before any rows of the image. }
	}
	{return: Returns a pointer to the constructed object or NULL on error.}
}
*/
LMI_INLINE_DECLARATION LmiVideoPlane* LmiVideoPlaneConstruct(LmiVideoPlane* x, void* buffer, LmiSizeT size, LmiSizeT width, LmiSizeT height, LmiSizeT pitch, LmiSizeT offset);

/**
{function:
	{name: LmiVideoPlaneConstructWithPixelPitch}
	{parent: LmiVideoPlane}
	{description: Constructs an LmiVideoPlane using an external buffer as the plane\'s buffer, passing in a pixel pitch.}
 	{prototype: LmiVideoPlane* LmiVideoPlaneConstructWithPixelPitch(LmiVideoPlane* x, void* buffer, LmiSizeT size, LmiSizeT width, LmiSizeT height, LmiSizeT pitch, LmiSizeT offset, LmiSizeT pixelPitch)}
	{parameter:
		{name: x}
		{description: The object to construct.}
	}
 	{parameter:
		{name: buffer}
		{description: A pointer to the buffer to store as the plane buffer.  This buffer will not be deallocated by LmiVideoPlaneDestruct. }
	}
	{parameter:
		{name: size}
		{description: The size in bytes of the buffer.}
	}
	{parameter:
		{name: width}
		{description: The width in pixels of the plane.}
	}
	{parameter:
		{name: height}
		{description: The number of pitch sized rows in the plane buffer.}
	}
 	{parameter:
		{name: pitch}
		{description: The number of bytes in each row of the plane buffer.}
	}
	{parameter:
		{name: offset}
		{description: The number of bytes of padding before any rows of the image. }
	}
	{parameter:
		{name: pixelPitch}
		{description: The number of bytes between consecutive pixels within one row of the image. }
	}
	{return: Returns a pointer to the constructed object or NULL on error.}
}
*/
LMI_INLINE_DECLARATION LmiVideoPlane* LmiVideoPlaneConstructWithPixelPitch(LmiVideoPlane* x, void* buffer, LmiSizeT size, LmiSizeT width, LmiSizeT height, LmiSizeT pitch, LmiSizeT offset, LmiSizeT pixelPitch);

/**
{function:
	{name: LmiVideoPlaneConstructCopy}
	{parent: LmiVideoPlane}
	{description: Construct a plane from another plane.}
	{prototype: LmiVideoPlane* LmiVideoPlaneConstructCopy(LmiVideoPlane* x, const LmiVideoPlane* y)}
	{parameter:
		{name: x}
		{description: A plane to construct.}
	}
	{parameter:
		{name: y}
		{description: A plane to copy from.}
	}
	{return: Returns a pointer to the constructed plane.}
}
*/
LMI_INLINE_DECLARATION LmiVideoPlane* LmiVideoPlaneConstructCopy(LmiVideoPlane* x, const LmiVideoPlane* y);

/**
{function:
	{name: LmiVideoPlaneDestruct}
	{parent: LmiVideoPlane}
	{description: Destruct an LmiVideoPlane. }
	{prototype: void LmiVideoPlaneDestruct(LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: The plane to destruct.}
	}
}
*/
LMI_INLINE_DECLARATION void LmiVideoPlaneDestruct(LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneAssign}
	{parent: LmiVideoPlane}
	{description: Assign one plane to another.}
	{prototype: LmiVideoPlane* LmiVideoPlaneAssign(LmiVideoPlane* x, const LmiVideoPlane* y)}
	{parameter:
		{name: x}
		{description: A plane to assign to.}
	}
	{parameter:
		{name: y}
		{description: A plane to assign from.}
	}
	{return: Returns a pointer to the assigned-to plane.}
}
*/
LMI_INLINE_DECLARATION LmiVideoPlane* LmiVideoPlaneAssign(LmiVideoPlane* x, const LmiVideoPlane* y);

/* Provided only for container support, should never be called */
LMI_INLINE_DECLARATION LmiBool LmiVideoPlaneEqual(const LmiVideoPlane* x, const LmiVideoPlane* y);

/**
{function:
	{name: LmiVideoPlaneGetBufferConst}
	{parent: LmiVideoPlane}
	{description: Gets a const pointer to the plane\'s buffer.}
	{prototype: const void* LmiVideoPlaneGetBufferConst(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane. }
	}
	{return: Returns a const pointer the plane\'s buffer. }
}
*/
LMI_INLINE_DECLARATION const void* LmiVideoPlaneGetBufferConst(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetBuffer}
	{parent: LmiVideoPlane}
	{description: Gets a pointer to the plane\'s buffer.}
	{prototype: void* LmiVideoPlaneGetBuffer(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane. }
	}
	{return: Returns a pointer to the plane\'s buffer. }
}
*/
LMI_INLINE_DECLARATION void* LmiVideoPlaneGetBuffer(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneSetBuffer}
	{parent: LmiVideoPlane}
	{description: Sets the pointer to the plane\'s buffer.}
	{prototype: void LmiVideoPlaneSetBuffer(LmiVideoPlane* x, void *buffer)}
	{parameter:
		{name: x}
		{description: A plane. }
	}
	{parameter:
		{name: buffer}
		{description: Pointer to a buffer. }
	}
}
*/
LMI_INLINE_DECLARATION void LmiVideoPlaneSetBuffer(LmiVideoPlane* x, void *buffer);

/**
{function:
	{name: LmiVideoPlaneGetSize}
	{parent: LmiVideoPlane}
	{description: Gets the plane\'s size in bytes.  This is equivalent to: {code:LmiVideoPlaneGetOffset(x) + (LmiVideoPlaneGetPitch(x) * LmiVideoPlaneGetHeight(x))}. }
	{prototype: LmiSizeT LmiVideoPlaneGetSize(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane.}
	}
	{return: Returns the plane\'s size in bytes. }
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoPlaneGetSize(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetImageConst}
	{parent: LmiVideoPlane}
	{description: Gets a const pointer to the plane\'s image.  This is equivalent to {code:LmiVideoPlaneGetBufferConst(x) + LmiVideoPlaneGetOffset(x)}.}
	{prototype: const void* LmiVideoPlaneGetImageConst(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane. }
	}
	{return: Returns a const pointer the plane\'s buffer. }
}
*/
LMI_INLINE_DECLARATION const void* LmiVideoPlaneGetImageConst(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetImage}
	{parent: LmiVideoPlane}
	{description: Gets a pointer to the plane\'s image.  This is equivalent to {code:LmiVideoPlaneGetBuffer(x) + LmiVideoPlaneGetOffset(x)}.}
	{prototype: void* LmiVideoPlaneGetImage(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane. }
	}
	{return: Returns a const pointer the plane\'s buffer. }
}
*/
LMI_INLINE_DECLARATION void* LmiVideoPlaneGetImage(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetWidth}
	{parent: LmiVideoPlane}
	{description: Gets the plane\'s width. The plane\'s width is the number of pixels in each row of the plane\'s image.  The width can not be translated into bytes or correlated to the plane\'s pitch without understanding the format of the plane\'s image.}
	{prototype: LmiSizeT LmiVideoPlaneGetWidth(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane.}
	}
	{return: Returns the plane\'s width.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoPlaneGetWidth(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetHeight}
	{parent: LmiVideoPlane}
	{description: Get the plane\'s height. The plane\'s height is the number of rows of {italic:pitch} bytes in the plane\'s image.}
	{prototype: LmiSizeT LmiVideoPlaneGetHeight(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane.}
	}
	{return: Returns the plane\'s height.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoPlaneGetHeight(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetPitch}
	{parent: LmiVideoPlane}
	{description: Gets the plane\'s pitch in bytes. The plane\'s pitch is the number of bytes in each row of the plane\'s image.}
	{prototype: LmiSizeT LmiVideoPlaneGetPitch(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane.}
	}
	{return: Returns the plane\'s pitch in bytes.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoPlaneGetPitch(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetOffset}
	{parent: LmiVideoPlane}
	{description: Gets the plane\'s offset in bytes. The plane\'s offset is the number of bytes before any row of the plane\'s image.}
	{prototype: LmiSizeT LmiVideoPlaneGetOffset(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane.}
	}
	{return: Returns the plane\'s offset in bytes.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoPlaneGetOffset(const LmiVideoPlane* x);

/**
{function:
	{name: LmiVideoPlaneGetPixelPitch}
	{parent: LmiVideoPlane}
	{description: Gets the plane\'s pixel pitch in bytes. The plane\'s pixel pitch is the number of bytes between consecutive pixels in a row of the plane.}
	{prototype: LmiSizeT LmiVideoPlaneGetPixelPitch(const LmiVideoPlane* x)}
	{parameter:
		{name: x}
		{description: A plane.}
	}
	{return: Returns the plane\'s pixel pitch in bytes.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoPlaneGetPixelPitch(const LmiVideoPlane* x);

struct LmiVideoFrame_;

/**
	{type visibility="private":
		{name: LmiVideoFrameImpl}
		{parent: LmiVideoFrame}
		{description: Reference-counted internal implementation for LmiVideoFrame.}
	}
*/
typedef struct {
	LmiMediaFrameImpl base;	/* Contains the format, buffer and size for the frame\'s pixel data */
	LmiSizeT width;
	LmiSizeT height;
	LmiSizeT nPlanes;
	LmiVideoPlane plane[4];
} LmiVideoFrameImpl;

LmiVideoFrameImpl *LmiVideoFrameImplConstructCopy(LmiVideoFrameImpl *x, const LmiVideoFrameImpl *orig);
void LmiVideoFrameImplDestruct(LmiVideoFrameImpl *x);

/**
{type:
	{name: LmiVideoFrame}
	{parent: VideoCommon}
	{derivation-of: LmiMediaFrame}
	{include: Lmi/Video/Common/LmiVideoFrame.h}
	{description: Describes a video frame.}
}
*/
typedef struct LmiVideoFrame_ {
	LmiMediaFrame base;
} LmiVideoFrame;

/**
 {function visibility="public":
	{name: LmiVideoFrameConstruct}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame from planar pixel data.
		If input planes have a non-NULL buffer pointer, the planar pixel data is copied into the video frame.
		Otherwise, the video frame\'s planes will remain uninitialized.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstruct(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, LmiVideoPlane plane[], LmiSizeT nPlanes, const LmiProperties* properties, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: The media format of the frame.}}
	{parameter: {name: width} {description: The width of the frame.}}
	{parameter: {name: height} {description: The height of the frame.}}
	{parameter: {name: plane} {description: An array of planes.}}
	{parameter: {name: nPlanes} {description: The number of planes.}}
	{parameter: {name: properties} {description: A pointer to the properties to associate with the video frame or NULL.}}
	{parameter: {name: alloc} {description: An allocator to be used for memory.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
 }
 */
LMI_INLINE_DECLARATION LmiVideoFrame* LmiVideoFrameConstruct(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, LmiVideoPlane plane[], LmiSizeT nPlanes, const LmiProperties* properties, LmiAllocator* alloc);

/**
 {function visibility="public":
	{name: LmiVideoFrameConstructWithFrameAllocator}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame from planar pixel data, using separate memory allocators for pixel data and other data.
		If input planes have a non-NULL buffer pointer, the planar pixel data is copied into the video frame.
		Otherwise, the video frame\'s planes will remain uninitialized.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructWithFrameAllocator(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, LmiVideoPlane plane[], LmiSizeT nPlanes, const LmiProperties* properties, LmiAllocator* frameAlloc, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: The media format of the frame.}}
	{parameter: {name: width} {description: The width of the frame.}}
	{parameter: {name: height} {description: The height of the frame.}}
	{parameter: {name: plane} {description: An array of planes.}}
	{parameter: {name: nPlanes} {description: The number of planes.}}
	{parameter: {name: properties} {description: A pointer to the properties to associate with the video frame or NULL.}}
	{parameter: {name: frameAlloc} {description: An allocator to be used for pixel-data.}}
	{parameter: {name: alloc} {description: An allocator to be used for non-pixel-data memory.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
 }
 */
LmiVideoFrame* LmiVideoFrameConstructWithFrameAllocator(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, LmiVideoPlane plane[], LmiSizeT nPlanes, const LmiProperties* properties, LmiAllocator* frameAlloc, LmiAllocator* alloc);



/**
{function visibility="public":
	{name: LmiVideoFrameConstructWithExternalBuffer}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame using externally allocated memory to hold the frame\'s pixel data.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructWithExternalBuffer(LmiVideoFrame* x, const LmiMediaFormat* format, void *buffer, LmiSizeT size, LmiAllocator* bufferAlloc, LmiMediaFrameReleaseCallback releaseCallback,  LmiSizeT width, LmiSizeT height, LmiVideoPlane plane[], LmiSizeT nPlanes, const LmiProperties* properties, 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: The allocator used to allocate {code:buffer}.  May be NULL.  If non-NULL, this allocator will be used to re-allocate the buffer's memory if the buffer is reallocated (with LmiVideoFrameMakeExclusive or similar).}}
	{parameter: {name: releaseCallback} {description: A callback to be called on LmiVideoFrameDestruct so that memory 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: plane} {description: An array of planes.}}
	{parameter: {name: nPlanes} {description: The number of planes.}}
	{parameter: {name: properties} {description: A pointer to the properties to associate with the video frame or NULL.}}
	{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.}
}
*/
LmiVideoFrame* LmiVideoFrameConstructWithExternalBuffer(LmiVideoFrame* x, const LmiMediaFormat* format, void *buffer, LmiSizeT size, LmiAllocator* bufferAlloc, LmiMediaFrameReleaseCallback releaseCallback,  LmiSizeT width, LmiSizeT height, LmiVideoPlane plane[], LmiSizeT nPlanes, const LmiProperties* properties, LmiAllocator* alloc);

/**
{function visibility="public":
	{name: LmiVideoFrameConstructFromKnownFormat}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame based on a single buffer of known format.  The pixel data is copied into the video frame.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructFromKnownFormat(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, void* imageBuffer, LmiSizeT imageSize, const LmiProperties* properties, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: The media format of the video frame.  This must be a format recognized by LmiVideoFrameIsMediaFormatSupported.}}
	{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: imageBuffer} {description: A pointer to the first byte of the image data.  This need not be the same as the memory pointed to by the allocBuffer parameter.}}
	{parameter: {name: imageSize} {description: The size, in bytes, of the image data.  This need not be the same as the value given by the allocSize parameter.}}
	{parameter: {name: properties} {description: A pointer to the properties to associate with the video frame or NULL.}}
	{parameter: {name: alloc} {description: An allocator.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION LmiVideoFrame* LmiVideoFrameConstructFromKnownFormat(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, void* imageBuffer, LmiSizeT imageSize, const LmiProperties* properties, LmiAllocator* alloc);

/**
{function visibility="public":
	{name: LmiVideoFrameConstructFromKnownFormatWithFrameAllocator}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame based on a single buffer of known format, using separate memory allocators for pixel data and other data.  The pixel data is copied into the video frame.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructFromKnownFormatWithFrameAllocator(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, void* imageBuffer, LmiSizeT imageSize, const LmiProperties* properties, LmiAllocator* frameAlloc, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: The media format of the video frame.  This must be a format recognized by LmiVideoFrameIsMediaFormatSupported.}}
	{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: imageBuffer} {description: A pointer to the first byte of the image data.  This need not be the same as the memory pointed to by the allocBuffer parameter.}}
	{parameter: {name: imageSize} {description: The size, in bytes, of the image data.  This need not be the same as the value given by the allocSize parameter.}}
	{parameter: {name: properties} {description: A pointer to the properties to associate with the video frame or NULL.}}
	{parameter: {name: frameAlloc} {description: An allocator to be used for pixel-data.}}
	{parameter: {name: alloc} {description: An allocator to be used for non-pixel-data memory.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiVideoFrame* LmiVideoFrameConstructFromKnownFormatWithFrameAllocator(LmiVideoFrame* x, const LmiMediaFormat* format, LmiSizeT width, LmiSizeT height, void* imageBuffer, LmiSizeT imageSize, const LmiProperties* properties, LmiAllocator* frameAlloc, LmiAllocator* alloc);




/**
{function visibility="public":
	{name: LmiVideoFrameConstructFromKnownFormatWithExternalBuffer}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame using externally allocated memory to hold the frame\'s pixel data, based on a single buffer of known format.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructFromKnownFormatWithExternalBuffer(LmiVideoFrame* x, const LmiMediaFormat* format, void *allocBuffer, LmiSizeT allocSize, LmiAllocator* bufferAlloc, LmiMediaFrameReleaseCallback releaseCallback, LmiSizeT width, LmiSizeT height, void* imageBuffer, LmiSizeT imageSize, const LmiProperties* properties, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: The media format of the video frame.  This must be a format recognized by LmiVideoFrameIsMediaFormatSupported.}}
	{parameter: {name: allocBuffer} {description: A pointer to externally allocated memory that holds the pixel data.}}
	{parameter: {name: allocSize} {description: The size, in bytes, of the externally allocated memory holding the pixel data.}}
	{parameter: {name: bufferAlloc} {description: The allocator used to allocate {code:buffer}.  May be NULL.  If non-NULL, this allocator will be used to re-allocate the buffer's memory if the buffer is reallocated (with LmiVideoFrameMakeExclusive or similar).}}
	{parameter: {name: releaseCallback} {description: A callback to be called on LmiVideoFrameDestruct so that memory 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: imageBuffer} {description: A pointer to the first byte of the image data.  This need not be the same as the memory pointed to by the allocBuffer parameter.}}
	{parameter: {name: imageSize} {description: The size, in bytes, of the image data.  This need not be the same as the value given by the allocSize parameter.}}
	{parameter: {name: properties} {description: A pointer to the properties to associate with the video frame or NULL.}}
	{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.}
}
*/
LmiVideoFrame* LmiVideoFrameConstructFromKnownFormatWithExternalBuffer(LmiVideoFrame* x, const LmiMediaFormat* format, void *allocBuffer, LmiSizeT allocSize, LmiAllocator* bufferAlloc, LmiMediaFrameReleaseCallback releaseCallback, LmiSizeT width, LmiSizeT height, void* imageBuffer, LmiSizeT imageSize, const LmiProperties* properties, LmiAllocator* alloc);

/**
 {function visibility="public":
	{name: LmiVideoFrameConstructFromFrame}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame by format conversion from a source video frame.}
	{prototype: LmiVideoFrame *LmiVideoFrameConstructFromFrame(LmiVideoFrame *x, const LmiMediaFormat *format, const LmiVideoFrame *src, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: Format of video frame to be constructed.}}
	{parameter: {name: src} {description: Source video frame for the format conversion.}}
	{parameter: {name: alloc} {description: An allocator to be used for memory.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
 }
 */
LmiVideoFrame *LmiVideoFrameConstructFromFrame(LmiVideoFrame *x, const LmiMediaFormat *format, const LmiVideoFrame *src, LmiAllocator* alloc);

/**
{function visibility="public":
	{name: LmiVideoFrameConstructFromFrameAndFlip}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame by format conversion from a source video frame.}
	{prototype: LmiVideoFrame *LmiVideoFrameConstructFromFrameAndFlip(LmiVideoFrame *x, const LmiMediaFormat *format, const LmiVideoFrame *src, LmiBool flip, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: Format of video frame to be constructed.}}
	{parameter: {name: src} {description: Source video frame for the format conversion.}}
	{parameter: {name: flip} {description: Flip video frame during conversion.}}
	{parameter: {name: alloc} {description: An allocator to be used for memory.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiVideoFrame *LmiVideoFrameConstructFromFrameAndFlip(LmiVideoFrame *x, const LmiMediaFormat *format, const LmiVideoFrame *src, LmiBool flip, LmiAllocator* alloc);

/**
	{function visibility="public":
		{name: LmiVideoFrameConstructFromUri}
		{parent: LmiVideoFrame}
		{description: Constructs a video frame from a URI.}
		{prototype: LmiVideoFrame* LmiVideoFrameConstructFromUri(LmiVideoFrame* x, const LmiString* uri, LmiAllocator* alloc)}
		{parameter: {name: x} {description: A video frame object to construct.}}
		{parameter: {name: uri} {description: A URI referencing an image.  Note: Currently, only "data" URIs
			encoding image/jpeg images in base64 are supported.}}
		{parameter: {name: alloc} {description: An allocator to be used for memory.}}
		{return: Returns a pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiVideoFrame* LmiVideoFrameConstructFromUri(LmiVideoFrame* x, const LmiString* uri, LmiAllocator* alloc);

/**
 {function visibility="public":
	{name: LmiVideoFrameConstructI420FromVideoFrame}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame for an encoder by construct copy or format conversion from a source video frame.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructI420FromVideoFrame(LmiVideoFrame *x, const LmiVideoFrame *src)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: src} {description: Source video frame for the construct copy or format conversion.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
 }
 */
LmiVideoFrame* LmiVideoFrameConstructI420FromVideoFrame(LmiVideoFrame *x, const LmiVideoFrame *src);

/**
{function visibility="public":
	{name: LmiVideoFrameConstructI420FromVideoFrameAndFlip}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame for an encoder by construct copy or format conversion from a source video frame.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructI420FromVideoFrameAndFlip(LmiVideoFrame *x, const LmiVideoFrame *src, LmiBool flip)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: src} {description: Source video frame for the construct copy or format conversion.}}
	{parameter: {name: flip} {description: Flip video frame during conversion.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiVideoFrame* LmiVideoFrameConstructI420FromVideoFrameAndFlip(LmiVideoFrame *x, const LmiVideoFrame *src, LmiBool flip);

/*
	{function visibility="public":
		{name: LmiVideoFrameConstructNull}
		{parent: LmiVideoFrame}
		{description: Construct a null video frame -- with format "NULL", size 0x0, no planes, and n
o properties.}
		{prototype: LmiVideoFrame* LmiVideoFrameConstructNull(LmiVideoFrame* x, LmiAllocator* alloc)}
		{parameter: {name: x} {description: A video frame object to construct.}}
		{parameter: {name: alloc} {description: An allocator to be used for memory.}}
		{return: Returns a pointer to a constructed object on success, or NULL on failure.}
	}
*/
LmiVideoFrame* LmiVideoFrameConstructNull(LmiVideoFrame* x, LmiAllocator* alloc);


/* private */
LmiVideoFrame *LmiVideoFrameConstructFromBmpFile(LmiVideoFrame *frame, const char *fileName, LmiAllocator *alloc);
LmiVideoFrame* LmiVideoFrameConstructFromFile(LmiVideoFrame* x, const LmiMediaFormat* format, LmiFile* file, LmiAllocator* alloc);

/**
{type visibility="public":
    {name: LmiImageRotationDegree}
	{parent: LmiVideoFrameTransformParameters}
	{description: Degrees of image rotation.}
}
*/
typedef LmiUint LmiImageRotationDegree;

#define   LMI_IMAGE_ROTATION_0     (0)
#define   LMI_IMAGE_ROTATION_90   (90)
#define   LMI_IMAGE_ROTATION_180 (180)
#define   LMI_IMAGE_ROTATION_270 (270)
#define   LMI_IMAGE_ROTATION_360 (360)

/**
{type visibility="public":
 	{name: LmiVideoQuality}
 	{parent: VideoCommon}
 	{description: This enumeration describes abstract quality grades for a video image.}
 	{value: {name: LMI_VIDEOQUALITY_Unknown} {description: quality is not determined.}}
 	{value: {name: LMI_VIDEOQUALITY_Low} {description: low-quality video.}}
 	{value: {name: LMI_VIDEOQUALITY_Medium} {description: medium-quality video.}}
 	{value: {name: LMI_VIDEOQUALITY_High} {description: high-quality video.}}
 	{value: {name: LMI_VIDEOQUALITY_Pristine} {description: pristine-quality video.}}
}
 */
typedef enum {
	LMI_VIDEOQUALITY_Unknown,
	LMI_VIDEOQUALITY_Low,
	LMI_VIDEOQUALITY_Medium,
	LMI_VIDEOQUALITY_High,
	LMI_VIDEOQUALITY_Pristine
} LmiVideoQuality;

/**
{type visibility="public":
    {name: LmiVideoFrameDitherLevel}
	{parent: LmiVideoFrameTransformParameters}
	{description: Dither levels.}
	{value:
		{name: LMI_VIDEOFRAMEDITHERLEVEL_Off}
		{description: No dithering.}
	}
	{value:
		{name: LMI_VIDEOFRAMEDITHERLEVEL_0}
		{description: Dither level 0.}
	}
	{value:
		{name: LMI_VIDEOFRAMEDITHERLEVEL_1}
		{description: Dither level 1.}
	}
	{value:
		{name: LMI_VIDEOFRAMEDITHERLEVEL_2}
		{description: Dither level 2.}
	}
}
*/
typedef enum {
    LMI_VIDEOFRAMEDITHERLEVEL_Off = 0,
    LMI_VIDEOFRAMEDITHERLEVEL_0,
    LMI_VIDEOFRAMEDITHERLEVEL_1,
    LMI_VIDEOFRAMEDITHERLEVEL_2
} LmiVideoFrameDitherLevel;

/**
{type visibility="public":
    {name: LmiVideoFrameSharpenLevel}
	{parent: LmiVideoFrameTransformParameters}
	{description: Image sharpening levels.}
	{value:
		{name: LMI_VIDEOFRAMESHARPENLEVEL_Off}
		{description: No image sharpening.}
	}
	{value:
		{name: LMI_VIDEOFRAMESHARPENLEVEL_1}
		{description: The weakest sharpening level.}
	}
	{value:
		{name: LMI_VIDEOFRAMESHARPENLEVEL_2}
		{description: The sencond weakest sharpening level.}
	}
	{value:
		{name: LMI_VIDEOFRAMESHARPENLEVEL_3}
		{description: The third weakest sharpening level.}
	}
	{value:
		{name: LMI_VIDEOFRAMESHARPENLEVEL_4}
		{description: The third strongest sharpening level; this or LMI_VIDEOFRAMESHARPENLEVEL_3 is most recommended}
	}
	{value:
		{name: LMI_VIDEOFRAMESHARPENLEVEL_5}
		{description: The second strongest sharpening level; most likely will result in obvious amplification of noise.}
	}
	{value:
		{name: LMI_VIDEOFRAMESHARPENLEVEL_6}
		{description: The strongest sharpening level; results in obvious amplification of noise.}
	}
}
*/
typedef enum {
    LMI_VIDEOFRAMESHARPENLEVEL_Off = 0,
    LMI_VIDEOFRAMESHARPENLEVEL_1 = 1,
    LMI_VIDEOFRAMESHARPENLEVEL_2,
    LMI_VIDEOFRAMESHARPENLEVEL_3,
    LMI_VIDEOFRAMESHARPENLEVEL_4,
    LMI_VIDEOFRAMESHARPENLEVEL_5,
    LMI_VIDEOFRAMESHARPENLEVEL_6
} LmiVideoFrameSharpenLevel;

/**
	{type visibility="public":
		{name: LmiVideoFrameMarginParameters}
		{parent: VideoCommon}
		{include: Lmi/Video/Common/LmiVideoFrame.h}
		{description: An object describing margin sizes in a video frame.}
	}
*/
typedef struct {
	LmiSizeT left;
	LmiSizeT right;
	LmiSizeT top;
	LmiSizeT bottom;
} LmiVideoFrameMarginParameters;

/**
	{type visibility="public":
		{name: LmiVideoFrameTransformParameters}
		{parent: VideoCommon}
		{include: Lmi/Video/Common/LmiVideoFrame.h}
		{description: An object describing a transformation of a video frame.}
	}
*/
typedef struct {
	LmiSizeT inputWidth;    //input view, check wxh==0
	LmiSizeT inputHeight;
	LmiSizeT inputOffsetLeft;  //must be multiple of 2
	LmiSizeT inputOffsetTop;

	LmiSizeT resizeWidth;  //resize, check wxh==0
	LmiSizeT resizeHeight;

	LmiImageRotationDegree rotationDegrees;  //rotate, check==0

	LmiBool mirror;  //mirror, check==0

	LmiVideoFrameMarginParameters margin; //margins, check all==0

	LmiVideoFrameDitherLevel ditherLevel;
	LmiVideoFrameSharpenLevel sharpenLevel;
} LmiVideoFrameTransformParameters;


/**
	{function:
		{name: LmiVideoFrameTransformParametersConstructDefault}
		{parent: LmiVideoFrameTransformParameters}
		{description: Construct a video frame transform parameters object, initialized to the null transform.}
		{prototype: LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersConstructDefault(LmiVideoFrameTransformParameters* p, LmiAllocator *a)}
		{parameter:
			{name: p}
			{description: The video transform parameters object to construct.}}
		{parameter:
			{name: a}
			{description: Allocator. (Unused, NULL acceptable)}}
		{return: Returns the transform parameters object, or NULL on failure.}
	}
*/
LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersConstructDefault(LmiVideoFrameTransformParameters* p, LmiAllocator *a);

/**
	{function:
		{name: LmiVideoFrameTransformParametersConstruct}
		{parent: LmiVideoFrameTransformParameters}
		{description: Construct a video frame transform parameters object, initialized to the null transform.}
		{prototype: LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersConstruct(LmiVideoFrameTransformParameters* p)}
		{parameter:
			{name: p}
			{description: The video transform parameters object to construct.}}
		{return: Returns the transform parameters object, or NULL on failure.}
	}
*/
LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersConstruct(LmiVideoFrameTransformParameters* p);


/**
	{function:
		{name: LmiVideoFrameTransformParametersDestruct}
		{parent: LmiVideoFrameTransformParameters}
		{description: Destruct a video frame transform parameters object.}
		{prototype: void LmiVideoFrameTransformParametersDestruct(LmiVideoFrameTransformParameters* p)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object to destruct.}}
	}
*/
void LmiVideoFrameTransformParametersDestruct(LmiVideoFrameTransformParameters* p);

/**
	{function:
		{name: LmiVideoFrameTransformParametersConstructCopy}
		{parent: LmiVideoFrameTransformParameters}
		{description: Construct a video frame transform parameters object with copied values from a source object.}
		{prototype: LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersConstructCopy(LmiVideoFrameTransformParameters* p, const LmiVideoFrameTransformParameters* src)}
		{parameter:
			{name: p}
			{description: The video transform parameters object to construct.}}
		{parameter:
			{name: src}
			{description: The parameter object source to copy from.}}
		{return: Returns the transform parameters object.}
	}
*/
LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersConstructCopy(LmiVideoFrameTransformParameters* p, const LmiVideoFrameTransformParameters* src);

/**
	{function:
		{name: LmiVideoFrameTransformParametersAssign}
		{parent: LmiVideoFrameTransformParameters}
		{description: Copy video frame transform parameters from a source object to the destination.}
		{prototype: LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersAssign(LmiVideoFrameTransformParameters* p, const LmiVideoFrameTransformParameters* src)}
		{parameter:
			{name: p}
			{description: The video transform parameters object to be overwritten.}}
		{parameter:
			{name: src}
			{description: The parameter object source to copy from.}}
		{return: Returns the transform parameters object.}
	}
*/
LmiVideoFrameTransformParameters* LmiVideoFrameTransformParametersAssign(LmiVideoFrameTransformParameters* p, const LmiVideoFrameTransformParameters* src);


/**
	{function:
		{name: LmiVideoFrameTransformParametersSetInputView}
		{parent: LmiVideoFrameTransformParameters}
		{description: Set a video frame transform parameters object\'s input cropping parameters.}
		{prototype: LmiBool LmiVideoFrameTransformParametersSetInputView(LmiVideoFrameTransformParameters* p, LmiSizeT inputWidth, LmiSizeT inputHeight, LmiSizeT inputOffsetLeft, LmiSizeT inputOffsetTop)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to set cropping parameters.}}
		{parameter:
			{name: inputWidth}
			{description: The width of the cropped input image, in pixels.}}
		{parameter:
			{name: inputHeight}
			{description: The height of the cropped input image, in pixels.}}
		{parameter:
			{name: inputOffsetLeft}
			{description: The offset from the left side of the input image, in pixels.}}
		{parameter:
			{name: inputOffsetTop}
			{description: The offset from the top of the input image, in pixels.}}
		{return: Returns LMI_TRUE if the value was successfully set, LMI_FALSE if not.}
		{note: The input width plus the input left offset must not be more than the source image width, and
		the input height plus input top offset must not be more than the source image height, or the image transformation will fail.}
		{note: If both the input width and input height are set to 0, input cropping will be disabled.  This is the default.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersSetInputView(LmiVideoFrameTransformParameters* p, LmiSizeT inputWidth, LmiSizeT inputHeight, LmiSizeT inputOffsetLeft, LmiSizeT inputOffsetTop);


/**
	{function:
		{name: LmiVideoFrameTransformParametersSetResize}
		{parent: LmiVideoFrameTransformParameters}
		{description: Set a video frame transform parameters object\'s resize parameters.}
		{prototype: LmiBool LmiVideoFrameTransformParametersSetResize(LmiVideoFrameTransformParameters* p, LmiSizeT resizeWidth, LmiSizeT resizeHeight)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to set resize parameters.}}
		{parameter:
			{name: resizeWidth}
			{description: The width the image will be resized to.}}
		{parameter:
			{name: resizeHeight}
			{description: The height the image will be resized to.}}
		{return: Returns LMI_TRUE if the value was successfully set, LMI_FALSE if not.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersSetResize(LmiVideoFrameTransformParameters* p, LmiSizeT resizeWidth, LmiSizeT resizeHeight);


/**
	{function:
		{name: LmiVideoFrameTransformParametersSetRotation}
		{parent: LmiVideoFrameTransformParameters}
		{description: Set a video frame transform parameters object\'s rotation parameter.}
		{prototype: LmiBool LmiVideoFrameTransformParametersSetRotation(LmiVideoFrameTransformParameters* p, LmiImageRotationDegree rotationDegrees)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to set the rotation parameter.}}
		{parameter:
			{name: rotationDegrees}
			{description: The amount of rotation to apply.  Must be 0, 90, 180, or 270.}}
		{return: Returns LMI_TRUE if successfully set; LMI_FALSE if not.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersSetRotation(LmiVideoFrameTransformParameters* p, LmiImageRotationDegree rotationDegrees);


/**
	{function:
		{name: LmiVideoFrameTransformParametersSetMirror}
		{parent: LmiVideoFrameTransformParameters}
		{description: Set a video frame transform parameters object\'s mirroring parameter.}
		{prototype: LmiBool LmiVideoFrameTransformParametersSetMirror(LmiVideoFrameTransformParameters* p, LmiBool mirror)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to enable or disable mirroring.}}
		{parameter:
			{name: mirror}
			{description: Whether mirroring should be applied.}}
		{return: Returns LMI_TRUE if successfully set; LMI_FALSE if not.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersSetMirror(LmiVideoFrameTransformParameters* p, LmiBool mirror);


/**
	{function:
		{name: LmiVideoFrameTransformParametersSetMargin}
		{parent: LmiVideoFrameTransformParameters}
		{description: Set a video frame transform parameters object\'s margin parameters.}
		{prototype: LmiBool LmiVideoFrameTransformParametersSetMargin(LmiVideoFrameTransformParameters* p, LmiSizeT marginLeft, LmiSizeT marginRight, LmiSizeT marginTop, LmiSizeT marginBottom)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to set margin parameters.}}
		{parameter:
			{name: marginLeft}
			{description: The minimum amount of margin (in pixels) to apply to the left of the image.}}
		{parameter:
			{name: marginRight}
			{description: The minimum amount of margin (in pixels) to apply to the right of the image.}}
		{parameter:
			{name: marginTop}
			{description: The minimum amount of margin (in pixels) to apply above the image.}}
		{parameter:
			{name: marginBottom}
			{description: The minimum amount of margin (in pixels) to apply below the image.}}
		{return: Returns LMI_TRUE if successfully set; LMI_FALSE if not.}
		{note: Margins are memory allocated which is not part of the image, but which may be
			safely written to or read from (with unspecified values, unless previously written to).}
		{note: Images may be allocated with additional margins beyond those requested, if required for image transformations or the like.}
		{note: The function LmiVideoFrameConvertFormatWithTransform validates that the destination
			image has the margins requested.}
		{note: On multi-planar formats, margin sizes for higher planes are adjusted analogously with the image
			pixel width/height.}
		{note: Margins may not be applied to compressed formats (those without meaningful pitches).}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersSetMargin(LmiVideoFrameTransformParameters* p, LmiSizeT marginLeft, LmiSizeT marginRight, LmiSizeT marginTop, LmiSizeT marginBottom);


/**
	{function:
		{name: LmiVideoFrameTransformParametersSetDitherLevel}
		{parent: LmiVideoFrameTransformParameters}
		{description: Set a video frame transform parameters object\'s dither parameter.}
		{prototype: LmiBool LmiVideoFrameTransformParametersSetDitherLevel(LmiVideoFrameTransformParameters* p, LmiVideoFrameDitherLevel ditherLevel)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to set the dither parameter.}}
		{parameter:
			{name: ditherLevel}
			{description: The dither level to set.}}
		{return: Returns LMI_TRUE if successfully set; LMI_FALSE if not.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersSetDitherLevel(LmiVideoFrameTransformParameters* p, LmiVideoFrameDitherLevel ditherLevel);

/**
	{function:
		{name: LmiVideoFrameTransformParametersSetSharpenLevel}
		{parent: LmiVideoFrameTransformParameters}
		{description: Set a video frame transform parameters object\'s sharpen parameter.}
		{prototype: LmiBool LmiVideoFrameTransformParametersSetSharpenLevel(LmiVideoFrameTransformParameters* p, LmiVideoFrameSharpenLevel sharpenLevel)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to set the sharpen parameter.}}
		{parameter:
			{name: sharpenLevel}
			{description: The sharpen level to set.}}
		{return: Returns LMI_TRUE if successfully set; LMI_FALSE if not.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersSetSharpenLevel(LmiVideoFrameTransformParameters* p, LmiVideoFrameSharpenLevel sharpenLevel);

/**
	{function:
		{name: LmiVideoFrameTransformParametersGetInputView}
		{parent: LmiVideoFrameTransformParameters}
		{description: Get a video frame transform parameters object\'s input cropping parameters.}
		{prototype: LmiBool LmiVideoFrameTransformParametersGetInputView(const LmiVideoFrameTransformParameters* p, LmiSizeT* inputWidth, LmiSizeT* inputHeight, LmiSizeT* inputOffsetLeft, LmiSizeT* inputOffsetTop)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object from which to get input cropping parameters.}}
		{parameter:
			{name: inputWidth}
			{description: The width of the cropped input image, in pixels.}}
		{parameter:
			{name: inputHeight}
			{description: The height of the cropped input image, in pixels.}}
		{parameter:
			{name: inputOffsetLeft}
			{description: The offset from the left side of the input image, in pixels.}}
		{parameter:
			{name: inputOffsetTop}
			{description: The offset from the top of the input image, in pixels.}}
		{return: Returns LMI_TRUE if the value was successfully retrieved, LMI_FALSE if not.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersGetInputView(const LmiVideoFrameTransformParameters* p, LmiSizeT* inputWidth, LmiSizeT* inputHeight, LmiSizeT* inputOffsetLeft, LmiSizeT* inputOffsetTop);


/**
	{function:
		{name: LmiVideoFrameTransformParametersGetResize}
		{parent: LmiVideoFrameTransformParameters}
		{description: Get a video frame transform parameters object\'s resize parameters.}
		{prototype: LmiBool LmiVideoFrameTransformParametersGetResize(const LmiVideoFrameTransformParameters* p, LmiSizeT* resizeWidth, LmiSizeT* resizeHeight)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object from which to get resize parameters.}}
		{parameter:
			{name: resizeWidth}
			{description: The width the image will be resized to.}}
		{parameter:
			{name: resizeHeight}
			{description: The height the image will be resized to.}}
		{return: Returns LMI_TRUE if the value was successfully retrieved, LMI_FALSE if not.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersGetResize(const LmiVideoFrameTransformParameters* p, LmiSizeT* resizeWidth, LmiSizeT* resizeHeight);


/**
	{function:
		{name: LmiVideoFrameTransformParametersGetRotation}
		{parent: LmiVideoFrameTransformParameters}
		{description: Get a video frame transform parameters object\'s rotation parameter.}
		{prototype: LmiImageRotationDegree LmiVideoFrameTransformParametersGetRotation(const LmiVideoFrameTransformParameters* p)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to get the rotation parameter.}}
		{return: returns the amount of rotation being applied.  Will be 0, 90, 180, or 270.}
	}
*/
LMI_INLINE_DECLARATION LmiImageRotationDegree LmiVideoFrameTransformParametersGetRotation(const LmiVideoFrameTransformParameters* p);


/**
	{function:
		{name: LmiVideoFrameTransformParametersGetMirror}
		{parent: LmiVideoFrameTransformParameters}
		{description: Get a video frame transform parameters object\'s mirroring parameter.}
		{prototype: LmiBool LmiVideoFrameTransformParametersGetMirror(const LmiVideoFrameTransformParameters* p)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to enable or disable mirroring.}}
		{return: Returns whether mirroring should be applied.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersGetMirror(const LmiVideoFrameTransformParameters* p);


/**
	{function:
		{name: LmiVideoFrameTransformParametersGetMargin}
		{parent: LmiVideoFrameTransformParameters}
		{description: Get a video frame transform parameters object\'s margin parameters.}
		{prototype: LmiBool LmiVideoFrameTransformParametersGetMargin(const LmiVideoFrameTransformParameters* p, LmiSizeT* marginLeft, LmiSizeT* marginRight, LmiSizeT* marginTop, LmiSizeT* marginBottom)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to get margin parameters.}}
		{parameter:
			{name: marginLeft}
			{description: The minimum amount of margin (in pixels) to apply to the left of the image.}}
		{parameter:
			{name: marginRight}
			{description: The minimum amount of margin (in pixels) to apply to the right of the image.}}
		{parameter:
			{name: marginTop}
			{description: The minimum amount of margin (in pixels) to apply above the image.}}
		{parameter:
			{name: marginBottom}
			{description: The minimum amount of margin (in pixels) to apply below the image.}}
		{return: Returns LMI_TRUE if successfully get; LMI_FALSE if not.}
		{note: Margins are memory allocated which is not part of the image, but which may be
			safely written to or read from (with unspecified values, unless previously written to).}
		{note: On multi-planar formats, margin sizes for higher planes are adjusted analogously with the image
			pixel width/height.}
	}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameTransformParametersGetMargin(const LmiVideoFrameTransformParameters* p, LmiSizeT* marginLeft, LmiSizeT* marginRight, LmiSizeT* marginTop, LmiSizeT* marginBottom);


/**
	{function:
		{name: LmiVideoFrameTransformParametersGetDitherLevel}
		{parent: LmiVideoFrameTransformParameters}
		{description: Get a video frame transform parameters object\'s dither parameter.}
		{prototype: LmiVideoFrameDitherLevel LmiVideoFrameTransformParametersGetDitherLevel(const LmiVideoFrameTransformParameters* p)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to get the dither parameter.}}
		{return: Returns the dither level.}
	}
*/
LMI_INLINE_DECLARATION LmiVideoFrameDitherLevel LmiVideoFrameTransformParametersGetDitherLevel(const LmiVideoFrameTransformParameters* p);

/**
	{function:
		{name: LmiVideoFrameTransformParametersGetSharpenLevel}
		{parent: LmiVideoFrameTransformParameters}
		{description: Get a video frame transform parameters object\'s sharpen parameter.}
		{prototype: LmiVideoFrameSharpenLevel LmiVideoFrameTransformParametersGetSharpenLevel(const LmiVideoFrameTransformParameters* p)}
		{parameter:
			{name: p}
			{description: The video frame transform parameters object for which to get the sharpen parameter.}}
		{return: Returns the sharpen level.}
	}
*/
LMI_INLINE_DECLARATION LmiVideoFrameSharpenLevel LmiVideoFrameTransformParametersGetSharpenLevel(const LmiVideoFrameTransformParameters* p);

/**
 {function visibility="public":
	{name: LmiVideoFrameConstructFromFrameAndTransform}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame by color conversion, if necessary, from a source video frame plus other image transformations.}
	{prototype: LmiVideoFrame *LmiVideoFrameConstructFromFrameAndTransform(LmiVideoFrame *x, const LmiMediaFormat *format, const LmiVideoFrameTransformParameters *p, const LmiVideoFrame *src, LmiAllocator* frameAlloc, LmiAllocator* alloc)}
	{parameter: {name: x} {description: A video frame object to construct.}}
	{parameter: {name: format} {description: Format of video frame to be constructed.}}
	{parameter: {name: p} {description: Parameters describing how to transform source frame into destination. If NULL, video frame will be constructed with no transformations.}}
	{parameter: {name: src} {description: Source video frame for the format conversion.}}
 	{parameter: {name: frameAlloc} {description: Allocator of transformed video frame.}}
	{parameter: {name: alloc} {description: Allocator of frame properties.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
 }
 */
LmiVideoFrame *LmiVideoFrameConstructFromFrameAndTransform(LmiVideoFrame *x, const LmiMediaFormat *format, const LmiVideoFrameTransformParameters *p, const LmiVideoFrame *src, LmiAllocator *frameAlloc, LmiAllocator* alloc);

/**
{function visibility="public":
	{name: LmiVideoFrameDestruct}
	{parent: LmiVideoFrame}
	{description: Destructs an object that contains a media frame for a video source.}
	{prototype: void LmiVideoFrameDestruct(LmiVideoFrame* x)}
	{parameter: {name: x} {description: A video media frame object to destruct.}}
}
*/
void LmiVideoFrameDestruct(LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameConstructCopy}
	{parent: LmiVideoFrame}
	{description: Constructs a copy of an object that contains a media frame for a video source.}
	{prototype: LmiVideoFrame* LmiVideoFrameConstructCopy(LmiVideoFrame* x, const LmiVideoFrame* y)}
	{parameter: {name: x} {description: A video media frame object to construct.}}
	{parameter: {name: y} {description: A video media frame object to construct from.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiVideoFrame* LmiVideoFrameConstructCopy(LmiVideoFrame* x, const LmiVideoFrame* y);

/**
{function visibility="public":
	{name: LmiVideoFrameConstructFromMediaFrame}
	{parent: LmiVideoFrame}
	{description: Constructs a video frame from the media frame object of source type video.}
	{prototype: LmiVideoFrame *LmiVideoFrameConstructFromMediaFrame(LmiVideoFrame *f, const LmiMediaFrame *mediaFrame)}
	{parameter: {name: f} {description: A video frame object to construct.}}
	{parameter: {name: mediaFrame} {description: A media frame object.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
 }
 */
LmiVideoFrame *LmiVideoFrameConstructFromMediaFrame(LmiVideoFrame *f, const LmiMediaFrame *mediaFrame);


/**
{function visibility="public":
	{name: LmiVideoFrameAssign}
	{parent: LmiVideoFrame}
	{description: Assigns one video frame to another.}
	{prototype: LmiVideoFrame* LmiVideoFrameAssign(LmiVideoFrame* x, const LmiVideoFrame* y)}
	{parameter: {name: x} {description: A video media frame object to assign.}}
	{parameter: {name: y} {description: A video media frame object to assign from.}}
	{return: Returns a pointer to an assigned object on success, or NULL on failure.}
}
*/
LmiVideoFrame* LmiVideoFrameAssign(LmiVideoFrame* x, const LmiVideoFrame* y);

/**
{function visibility="public":
	{name: LmiVideoFrameSwap}
	{parent: LmiVideoFrame}
	{description: Swap the contents of two video frames.}
	{prototype: LmiBool LmiVideoFrameSwap(LmiVideoFrame* x, LmiVideoFrame* y)}
	{parameter: {name: x} {description: The first video media frame object to swap.}}
	{parameter: {name: y} {description: The second video media frame object to swap.}}
	{return: Returns LMI_TRUE if the swap was successful, else LMI_FALSE.}
}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameSwap(LmiVideoFrame* x, LmiVideoFrame* y);

/**
{function visibility="public":
	{name: LmiVideoFrameGetMediaFrame}
	{parent: LmiVideoFrame}
	{description: Gets a pointer to the base LmiMediaFrame object.}
	{prototype: const LmiMediaFrame *LmiVideoFrameGetMediaFrame(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns a pointer to LmiMediaFrame object on success, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION const LmiMediaFrame *LmiVideoFrameGetMediaFrame(const LmiVideoFrame* x);

/**
 {function visibility="private":
	{name: LmiVideoFrameGetImpl}
	{parent: LmiVideoFrame}
	{description: Gets the impl of the video frame object.}
	{prototype: LmiVideoFrameImpl *LmiVideoFrameGetImpl(const LmiVideoFrame *f)}
	{parameter: {name: f} {description: A video frame object.}}
	{return: Impl of the video frame object on success, or NULL on failure (including
		if the frame was default-constructed).}
 }
 */
LMI_INLINE_DECLARATION LmiVideoFrameImpl *LmiVideoFrameGetImpl(const LmiVideoFrame *f);

/**
 {function visibility="public":
	{name: LmiVideoFrameMakeExclusive}
	{parent: LmiVideoFrame}
	{description: If the video frame is not the exclusive owner (only reference), to its image and properties (frame data),
		then make the video frame refer to a newly-allocated copy of the frame's data.}
	{prototype: LmiBool LmiVideoFrameMakeExclusive(LmiVideoFrame* f)}
	{parameter: {name: f} {description: A video frame object.}}
	{return: Returns LMI_TRUE on success, else LMI_FALSE.  On failure, the frame is unchanged.}
    {note: Except in very unusual circumstances, a caller should ensure
		that it is the exclusive owner of a video frame before writing to it.}
  	{note: that if the orginal frame\'s buffer was allocated externally (by having been constructed by
 		LmiVideoFrameConstructWithExternalBuffer or LmiVideoFrameConstructFromKnownFormatWithExternalBuffer), the
 		releaseCallback will be not be called when the last reference is released for the newly-allocated buffer of
 		the frame.  However, other video frame references to the original buffer will call the releaseCallback when
 		the last reference is released.}
}
*/
LmiBool LmiVideoFrameMakeExclusive(LmiVideoFrame* f);

/**
 {function visibility="public":
	{name: LmiVideoFrameMakeExclusiveWithoutBufferCopy}
	{parent: LmiVideoFrame}
 	{description: If the video frame is not the exclusive owner (only reference), to its image and properties (frame data),
		then make the video frame refer to a newly-allocated buffer, but do not copy the original buffers content (leaving
 		it undefined).  The intent is that the application will immediately fill that frame\'s buffer after making it
 		exclusive, thus making the copy unnecessary.}
	{prototype: LmiBool LmiVideoFrameMakeExclusiveWithoutBufferCopy(LmiVideoFrame* f)}
	{parameter: {name: f} {description: A video frame object.}}
	{return: Returns LMI_TRUE on success, else LMI_FALSE.  On failure, the frame is unchanged.}
	{note: Except in very unusual circumstances, a caller should ensure
		that it is the exclusive owner of a video frame before writing to it.}
 	{note: that if the orginal frame\'s buffer was allocated externally (by having been constructed by
 		LmiVideoFrameConstructWithExternalBuffer or LmiVideoFrameConstructFromKnownFormatWithExternalBuffer), the
 		releaseCallback will be not be called when the last reference is released for the newly-allocated buffer of
 		the frame.  However, other video frame references to the original buffer will call the releaseCallback when
 		the last reference is released.}
 }
 */
LmiBool LmiVideoFrameMakeExclusiveWithoutBufferCopy(LmiVideoFrame* f);

/**
{function visibility="public":
	{name: LmiVideoFrameGetFormat}
	{parent: LmiVideoFrame}
	{description: Gets the media format of the video frame.}
	{prototype: const LmiMediaFormat* LmiVideoFrameGetFormat(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns a pointer to the the video frame\'s media format on success, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION const LmiMediaFormat* LmiVideoFrameGetFormat(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetBuffer}
	{parent: LmiVideoFrame}
	{description: Gets a pointer to the video frame\'s buffer.}
	{prototype: const void *LmiVideoFrameGetBuffer(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns a pointer to the media frame\'s buffer on success, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION const void *LmiVideoFrameGetBuffer(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetSize}
	{parent: LmiVideoFrame}
	{description: Gets the size of the video frame\'s buffer.}
	{prototype: LmiSizeT LmiVideoFrameGetSize(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns the size, in bytes, of the video frame\'s buffer.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetSize(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetAllocator}
	{parent: LmiVideoFrame}
	{description: Gets the allocator of a video frame.}
	{prototype: LmiAllocator *LmiVideoFrameGetAllocator(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns the allocator of a video frame.}
}
*/
LMI_INLINE_DECLARATION LmiAllocator *LmiVideoFrameGetAllocator(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetBufferAllocator}
	{parent: LmiVideoFrame}
	{description: Gets the allocator of a video frame's buffer.}
	{prototype: LmiAllocator *LmiVideoFrameGetBufferAllocator(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns the allocator of a video frame's buffer.}
	{note: This is the allocator passed to the frameAlloc parameter of the LmiVideoFrameConstructWithFrameAllocator functions, or the bufferAlloc parameter of the LmiVideoFrameConstructWithExternalBuffer functions.}
}
*/
LMI_INLINE_DECLARATION LmiAllocator *LmiVideoFrameGetBufferAllocator(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetWidth}
	{parent: LmiVideoFrame}
	{description: Gets the width of the video frame.}
	{prototype: LmiSizeT LmiVideoFrameGetWidth(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns the width of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetWidth(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetHeight}
	{parent: LmiVideoFrame}
	{description: Gets the height of the video frame.}
	{prototype: LmiSizeT LmiVideoFrameGetHeight(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns the height of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetHeight(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetNumPlanes}
	{parent: LmiVideoFrame}
	{description: Gets the number of video planes.}
	{prototype: LmiSizeT LmiVideoFrameGetNumPlanes(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns the number of video planes.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetNumPlanes(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPropertiesConst}
	{parent: LmiVideoFrame}
	{description: Gets a const pointer to the video frame\'s properties.}
	{prototype: const LmiProperties *LmiVideoFrameGetPropertiesConst(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns a const pointer to the video frame\'s properties.}
}
*/
LMI_INLINE_DECLARATION const LmiProperties *LmiVideoFrameGetPropertiesConst(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetProperties}
	{parent: LmiVideoFrame}
	{description: Gets a pointer to the video frame\'s properties.}
	{prototype: LmiProperties *LmiVideoFrameGetProperties(LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
	{return: Returns a pointer to the video frame\'s properties.}
}
*/
LMI_INLINE_DECLARATION LmiProperties *LmiVideoFrameGetProperties(LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneBufferConst}
	{parent: LmiVideoFrame}
	{description: Gets a const pointer to the nth plane buffer of the video frame.}
	{prototype: const void *LmiVideoFrameGetPlaneBufferConst(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns a const pointer to the nth plane buffer of the video frame on success, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION const void *LmiVideoFrameGetPlaneBufferConst(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneBuffer}
	{parent: LmiVideoFrame}
	{description: Gets a pointer to the nth plane buffer of the video frame.}
	{prototype: void *LmiVideoFrameGetPlaneBuffer(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns a pointer to the nth plane buffer of the video frame on success, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION void *LmiVideoFrameGetPlaneBuffer(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneSize}
	{parent: LmiVideoFrame}
	{description: Gets the size in bytes of the nth plane buffer of the video frame.}
	{prototype: LmiSizeT LmiVideoFrameGetPlaneSize(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns the size in bytes of the nth plane buffer of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetPlaneSize(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneImageConst}
	{parent: LmiVideoFrame}
	{description: Gets a const pointer to the nth plane\'s image.  This is equivalent to {code:LmiVideoFrameGetPlaneBufferConst(x) + LmiVideoFrameGetPlaneOffset(x)}.}
	{prototype: const void *LmiVideoFrameGetPlaneImageConst(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns a const pointer to the nth plane\'s image, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION const void *LmiVideoFrameGetPlaneImageConst(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneImage}
	{parent: LmiVideoFrame}
	{description: Gets a pointer to the nth plane\'s image.  This is equivalent to {code:LmiVideoFrameGetPlaneBuffer(x) + LmiVideoFrameGetPlaneOffset(x)}.}
	{prototype: void *LmiVideoFrameGetPlaneImage(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns a pointer to the nth plane\'s image, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION void *LmiVideoFrameGetPlaneImage(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneWidth}
	{parent: LmiVideoFrame}
	{description: Gets the width of the nth plane of the video frame.}
	{prototype: LmiSizeT LmiVideoFrameGetPlaneWidth(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns the width of the nth plane of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetPlaneWidth(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneHeight}
	{parent: LmiVideoFrame}
	{description: Gets the height of the nth plane of the video frame.}
	{prototype: LmiSizeT LmiVideoFrameGetPlaneHeight(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns the height of the nth plane of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetPlaneHeight(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlanePitch}
	{parent: LmiVideoFrame}
	{description: Gets the pitch, in bytes, of the nth plane of the video frame.}
	{prototype: LmiSizeT LmiVideoFrameGetPlanePitch(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns the pitch, in bytes, of the nth plane of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetPlanePitch(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlaneOffset}
	{parent: LmiVideoFrame}
	{description: Gets the offset, in bytes, of the nth plane of the video frame.  The offset is the number of bytes from the plane\'s buffer to the start of the pixel data.}
	{prototype: LmiSizeT LmiVideoFrameGetPlaneOffset(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns the offset, in bytes, of the nth plane of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetPlaneOffset(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPlanePixelPitch}
	{parent: LmiVideoFrame}
	{description: Gets the pixel pitch, in bytes, of the nth plane of the video frame.  The pixel pitch is the number of bytes between consecutive pixels in a row of the plane.}
	{prototype: LmiSizeT LmiVideoFrameGetPlanePixelPitch(const LmiVideoFrame* x, LmiSizeT n)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: n} {description: The video plane index.}}
	{return: Returns the pixel pitch, in bytes, of the nth plane of the video frame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiVideoFrameGetPlanePixelPitch(const LmiVideoFrame* x, LmiSizeT n);

/**
{function visibility="public":
	{name: LmiVideoFrameDeduceFormatByPixelPitch}
	{parent: LmiVideoFrame}
	{description: If a video frame\'s planes have pixel pitches greater than 1, try to deduce
		the frame actually consists of fewer planes using a known interleaved format.  If so,
		alter the frame\'s plane pointers, and format, accordingly.}
	{prototype: LmiBool LmiVideoFrameDeduceFormatByPixelPitch(LmiVideoFrame* f)}
	{parameter: {name: f} {description: Video frame object.}}
	{return: LMI_TRUE if the frame\'s format was successfully deduced, or if it did not
		have a pixel pitch greater than 1; LMI_FALSE otherwise.}
	{note: This alters the video frame in place; because LmiVideoFrame is a shared pointer, all references to this frame will be altered.  If there may be other users of this video frame, the caller should call LmiVideoFrameMakeExclusive first.}
	{note: This will not perform any memory copies.}
}
*/
LmiBool LmiVideoFrameDeduceFormatByPixelPitch(LmiVideoFrame* f);


/**
{function visibility="public":
	{name: LmiVideoFrameSetImageProperties}
	{parent: LmiVideoFrame}
	{description: Sets image properties that detail the video frame\'s pixel aspect ratio, rotation, mirror state, image quality, and interpolation state.}
	{prototype: LmiBool LmiVideoFrameSetImageProperties(LmiVideoFrame* x, LmiSizeT pixelWidth, LmiSizeT pixelHeight, LmiUint rotation, LmiBool mirrored, LmiVideoQuality quality, LmiBool interpolated)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: pixelWidth} {description: The width of the pixel aspect ratio of the image.}}
	{parameter: {name: pixelHeight} {description: The height of the pixel aspect ratio of the image.}}
 	{parameter: {name: rotation} {description: The rotation of the image in degrees.}}
  	{parameter: {name: mirrored} {description: If set to LMI_TRUE the image is mirrored.}}
 	{parameter: {name: quality} {description: The quality of image.}}
	{parameter: {name: interpolated} {description: If set to LMI_TRUE the image is interpolated.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
}
*/
LmiBool LmiVideoFrameSetImageProperties(LmiVideoFrame* x, LmiSizeT pixelWidth, LmiSizeT pixelHeight,
  LmiUint rotation, LmiBool mirrored, LmiVideoQuality quality, LmiBool interpolated);

/**
{function visibility="public":
	{name: LmiVideoFrameSetRotationRelativeToInterface}
	{parent: LmiVideoFrame}
	{description: Sets the \"rotationRelativeToInterface\" property of a video frame.
	  The rotationRelativeToInterface is the number of degrees the image is rotated relative to the interface.
	  This property will differ from the video frame\'s \"rotation\" property (rotation relative to gravity)
	  when the application\'s interface has a fixed orientation (ex. Portrait) or
	  when the orientation lock is enabled and the device is not oriented to the interface\'s orientation.}
	{prototype: LmiBool LmiVideoFrameSetRotationRelativeToInterface(LmiVideoFrame* x, LmiUint rotationRelativeToInterface)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: rotationRelativeToInterface} {description: The property value to set, in degrees.}}
	{return: Returns LMI_TRUE on success, or LMI_FALSE if the property could not be set.}
}
*/
LmiBool LmiVideoFrameSetRotationRelativeToInterface(LmiVideoFrame* x, LmiUint rotationRelativeToInterface);

/**
{function visibility="public":
	{name: LmiVideoFrameSetRotation}
	{parent: LmiVideoFrame}
	{description: Sets the rotation property of the video frame.}
	{prototype: LmiBool LmiVideoFrameSetRotation(LmiVideoFrame* x, LmiUint rotation)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: rotation} {description: The rotation of the image, in degrees.}}
	{return: Returns LMI_TRUE on success, or LMI_FALSE if the property could not be set.}
}
*/
LmiBool LmiVideoFrameSetRotation(LmiVideoFrame* x, LmiUint rotation);
LmiBool LmiVideoFrameSetRotationCcw(LmiVideoFrame* x, LmiUint rotation);

/**
{function visibility="public":
	{name: LmiVideoFrameSetMirrored}
	{parent: LmiVideoFrame}
	{description: Sets the mirrored property of a video frame.}
	{prototype: LmiBool LmiVideoFrameSetMirrored(LmiVideoFrame* x, LmiBool isMirrored)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: isMirrored} {description: Whether the image is mirrored.}}
	{return: Returns LMI_TRUE on success, or LMI_FALSE if the property could not be set.}
}
*/
LmiBool LmiVideoFrameSetMirrored(LmiVideoFrame *x, LmiBool isMirrored);

/**
{function visibility="public":
	{name: LmiVideoFrameSetTimeProperties}
	{parent: LmiVideoFrame}
	{description: Sets time properties on the video frame (typically supplied by the the camera capture or RTP).}
 	{prototype: LmiBool LmiVideoFrameSetTimeProperties(LmiVideoFrame* x, LmiTime elapsedTime, LmiTime timestamp)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: elapsedTime} {description: The elapsed time of the video frame.}}
	{parameter: {name: timestamp} {description: The wallclock timestamp associated with the creation of the video frame.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
	{note: elapsedTime increments monotonically for every frame and can be used for jitter calculations and clock skew.
	As an example, for 33ms (30 fps) frames the elapsedTime will increment in exactly 33ms intervals according to the
	clock of the source that produced the frame.}
	{note: timestamp is taken from the system clock at the moment of frame creation. It can be used to synchronize multiple
	frame sources that were stamped with the same system clock.}
}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameSetTimeProperties(LmiVideoFrame* x, LmiTime elapsedTime, LmiTime timestamp);

/**
{function visibility="public":
	{name: LmiVideoFrameSetLocationProperties}
	{parent: LmiVideoFrame}
	{description: Sets location properties on the video frame.}
 	{prototype: LmiBool LmiVideoFrameSetLocationProperties(LmiVideoFrame* x, const LmiLocation* location)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: location} {description: The location of the video frame.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameSetLocationProperties(LmiVideoFrame* x, const LmiLocation* location);

/**
{function visibility="public":
	{name: LmiVideoFrameSetGenerationProperties}
	{parent: LmiVideoFrame}
	{description: Sets \"generation\" properties on the video frame.}
 	{prototype: LmiBool LmiVideoFrameSetGenerationProperties(LmiVideoFrame* x, LmiUint generationRound, LmiUint generationRank, LmiUint generationSize)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: generationRound} {description: Identifies the number of times the ranker has ranked video streams.}}
	{parameter: {name: generationRank} {description: Indicates the rank of the video stream the video frame is a part of, relative to the other video streams.}}
 	{parameter: {name: generationSize} {description: Indicates the number of video streams that were ranked in this round.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
}
*/
LmiBool LmiVideoFrameSetGenerationProperties(LmiVideoFrame* x, LmiUint generationRound, LmiUint generationRank, LmiUint generationSize);

/**
{function visibility="public":
	{name: LmiVideoFrameSetCodecMimeTypeProperty}
	{parent: LmiVideoFrame}
	{description: Sets the \"codec MIME type\" property on the video frame.}
 	{prototype: LmiBool LmiVideoFrameSetCodecMimeTypeProperty(LmiVideoFrame* x, const LmiString* codecMimeType)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: codecMimeType} {description: the codec MIME type.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameSetCodecMimeTypeProperty(LmiVideoFrame* x, const LmiString* codecMimeType);

/**
{function visibility="public":
	{name: LmiVideoFrameSetCodecMimeTypePropertyCStr}
	{parent: LmiVideoFrame}
	{description: Sets \"codec MIME type\" property.}
 	{prototype: LmiBool LmiVideoFrameSetCodecMimeTypePropertyCStr(LmiVideoFrame* x, const char* codecMimeType)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: codecMimeType} {description: the codec MIME type.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameSetCodecMimeTypePropertyCStr(LmiVideoFrame* x, const char* codecMimeType);

/**
	{function visibility="public":
		{name: LmiVideoFrameSetScalabilityProperties}
		{parent: LmiVideoFrame}
		{description: Set the scalability properties of a video frame.}
		{prototype: LmiBool LmiVideoFrameSetScalabilityProperties(LmiVideoFrame* x, LmiSizeT activeSpatialLayers, LmiSizeT maxSpatialLayers, LmiSizeT temporalLayer)}
		{parameter:
			{name: x}
			{description: The video frame whose scalability properties to set.}}
		{parameter:
			{name: activeSpatialLayers}
			{description: The number of active spatial layers of the frame.}}
		{parameter:
			{name: maxSpatialLayers}
			{description: The total number of spatial layers in the original frame; may be more than activeSpatialLayers.}}
		{parameter:
			{name: temporalLayer}
			{description: The temporal layer of the frame.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
	}
*/
LmiBool LmiVideoFrameSetScalabilityProperties(LmiVideoFrame* x, LmiSizeT activeSpatialLayers, LmiSizeT maxSpatialLayers, LmiSizeT temporalLayer);


/**
	{function visibility="public":
		{name: LmiVideoFrameSetConcealedProperty}
		{parent: LmiVideoFrame}
		{description: Set whether concealment has been done on a video frame.}
		{prototype: LmiBool LmiVideoFrameSetConcealedProperty(LmiVideoFrame* x, LmiBool concealed)}
		{parameter:
			{name: x}
			{description: The video frame on which to set whether concealment has been done.}}
		{parameter:
			{name: concealed}
			{description: Whether concealment has been done on the frame.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the property could not be set.}
	}
*/
LmiBool LmiVideoFrameSetConcealedProperty(LmiVideoFrame* x, LmiBool concealed);

/**
	{function visibility="public":
		{name: LmiVideoFrameSetMovementAlertProperty}
		{parent: LmiVideoFrame}
		{description: Set movement alert value for a video frame.}
		{prototype: LmiBool LmiVideoFrameSetMovementAlertProperty(LmiVideoFrame* x, LmiUint alert)}
		{parameter:
			{name: x}
			{description: The video frame.}}
		{parameter:
			{name: alert}
			{description: Value indicating movement detection result.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the property could not be set.}
	}
*/
LmiBool LmiVideoFrameSetMovementAlertProperty(LmiVideoFrame* x, LmiUint alert);

/**
	{function visibility="public":
		{name: LmiVideoFrameSetLayerProperties}
		{parent: LmiVideoFrame}
		{description: Set properties of a spatial layer of a video frame.}
		{prototype: LmiBool LmiVideoFrameSetLayerProperties(LmiVideoFrame* x, LmiSizeT layer, LmiSizeT width, LmiSizeT height, LmiBool precise, LmiFloat64 fps, LmiUint qp)}
		{parameter:
			{name: x}
			{description: The video frame on which to set spatial layer properties.}}
		{parameter:
			{name: layer}
			{description: The spatial layer on which to set properties.  Should be less than the maxSpatialLayers parameter of LmiVideoFrameSetScalabilityProperties.}}
		{parameter:
			{name: width}
			{description: The width of the layer, in pixels.}}
		{parameter:
			{name: height}
			{description: The height of the layer, in pixels.}}
		{parameter:
			{name: precise}
			{description: Whether the width and height of the layer are known precisely.  (In some cases, these are not known for layers that are not currently being received.)}}
		{parameter:
			{name: fps}
			{description: The total FPS of the spatial layer, in frames per second.}}
		{parameter:
			{name: qp}
			{description: The quantization parameter with which the layer was encoded.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
	}
*/
LmiBool LmiVideoFrameSetLayerProperties(LmiVideoFrame* x, LmiSizeT layer, LmiSizeT width, LmiSizeT height, LmiBool precise, LmiFloat64 fps, LmiUint qp);


/**
	{function visibility="public":
		{name: LmiVideoFrameSetLayerConcealedProperty}
		{parent: LmiVideoFrame}
		{description: Set whether concealment has been done on a layer of a video frame.}
		{prototype: LmiBool LmiVideoFrameSetLayerConcealedProperty(LmiVideoFrame* x, LmiSizeT layer, LmiBool concealed)}
		{parameter:
			{name: x}
			{description: The video frame on which to set whether concealment has been done.}}
		{parameter:
			{name: layer}
			{description: The spatial layer on which to set whether concealment has been done.  Should be less than the maxSpatialLayers parameter of LmiVideoFrameSetScalabilityProperties.}}
		{parameter:
			{name: concealed}
			{description: Whether concealment has been done on the layer.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the property could not be set.}
	}
*/
LmiBool LmiVideoFrameSetLayerConcealedProperty(LmiVideoFrame* x, LmiSizeT layer, LmiBool concealed);

/**
{function visibility="public":
	{name: LmiVideoFrameGetPixelAspectRatio}
	{parent: LmiVideoFrame}
	{description: Gets the pixel aspect ratio width and height properties of a video frame.}
	{prototype: LmiBool LmiVideoFrameGetPixelAspectRatio(const LmiVideoFrame* x, LmiSizeT *pixelWidth, LmiSizeT *pixelHeight)}
	{parameter: {name: x} {description: Video frame object.}}
	{parameter: {name: pixelWidth} {description: A pointer to where the pixel aspect width will be returned.}}
	{parameter: {name: pixelHeight} {description: A pointer to where the pixel aspect height will be returned.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties are not found.}
}
*/
LmiBool LmiVideoFrameGetPixelAspectRatio(const LmiVideoFrame* x, LmiSizeT *pixelWidth, LmiSizeT *pixelHeight);

/* TODO: ???? This should get included in the appropriate docblocks */
/*
 {note: elapsedTime increments monotonically for every frame and can be used for jitter calculations and clock skew.
 As an example, for 33ms frames (30fps) the elapsedTime will increment in exactly 33ms intervals according to the
 clock of the source that produced the frame.}
 {note: timeStamp is taken from the system clock at the moment of frame creation. It can be used to synchronize multiple
 frame sources that were stamped with the same system clock.}
 */

/**
{function visibility="public":
	{name: LmiVideoFrameGetElapsedTime}
	{parent: LmiVideoFrame}
	{description: Gets the elapsed time property of a video frame.}
	{prototype: LmiTime LmiVideoFrameGetElapsedTime(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
 	{return: Returns the elapsed time.}
}
*/
LMI_INLINE_DECLARATION LmiTime LmiVideoFrameGetElapsedTime(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetTimestamp}
	{parent: LmiVideoFrame}
	{description: Gets the RTP timestamp property of a video frame.}
	{prototype: LmiTime LmiVideoFrameGetTimestamp(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
 	{return: Returns the RTP timestamp.}
}
*/
LMI_INLINE_DECLARATION LmiTime LmiVideoFrameGetTimestamp(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetRotation}
	{parent: LmiVideoFrame}
	{description: Gets the \"rotation\" property of a video frame. The rotation is the number of degrees the image is rotated relative to gravity.}
	{prototype: LmiUint LmiVideoFrameGetRotation(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
 	{return: Returns rotation property in degrees.}
}
*/
LmiUint LmiVideoFrameGetRotation(const LmiVideoFrame* x);
LmiUint LmiVideoFrameGetRotationCcw(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetRotationRelativeToInterface}
	{parent: LmiVideoFrame}
	{description: Gets the \"rotationRelativeToInterface\" property of a video frame. The rotationRelativeToInterface is the number of degrees the image is rotated relative to the interface. This property will differ from the video frame\'s \"rotation\" property (rotation relative to gravity) when the application\'s interface has a fixed
 	  orientation (ex. Portrait) or the orientation lock is enabled and the device is not oriented to the interface\'s orientation.}
	{prototype: LmiUint LmiVideoFrameGetRotationRelativeToInterface(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
 	{return: Returns rotationRelativeToInterface property in degrees or 0 if the property is not set.  If distinguishing whether the property is not set or whether it is set to
 	  set 0 is needed, use LmiVideoFrameGetProperties or LmiVideoFrameGetPropertiesConst and query the property directly.}
}
*/
LmiUint LmiVideoFrameGetRotationRelativeToInterface(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameIsMirrored}
	{parent: LmiVideoFrame}
	{description: Gets the mirrored property of a video frame.}
	{prototype: LmiBool LmiVideoFrameIsMirrored(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
 	{return: Returns LMI_TRUE if the image in the video frame is mirrored, or LMI_FALSE if it is not.}
}
*/
LmiBool LmiVideoFrameIsMirrored(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetQuality}
	{parent: LmiVideoFrame}
	{description: Gets the quality property of a video frame.}
	{prototype: LmiVideoQuality LmiVideoFrameGetQuality(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
 	{return: Returns the quality of the video frame.}
}
*/
LmiVideoQuality LmiVideoFrameGetQuality(const LmiVideoFrame* x);
/**
{function visibility="public":
	{name: LmiVideoFrameIsInterpolated}
	{parent: LmiVideoFrame}
	{description: Gets the interpolated property of a video frame.}
	{prototype: LmiBool LmiVideoFrameIsInterpolated(const LmiVideoFrame* x)}
	{parameter: {name: x} {description: Video frame object.}}
 	{return: Returns LMI_TRUE if the image in the video frame was interpolated, or LMI_FALSE if it was not.}
}
*/
LmiBool LmiVideoFrameIsInterpolated(const LmiVideoFrame* x);

/**
{function visibility="public":
	{name: LmiVideoFrameGetGeneration}
	{parent: LmiVideoFrame}
	{description: Gets the generation properties of a video frame.  The generation properties indicate the ranking of the video stream this video frame is a part of, relative to the other video streams.  This ranking is typically determined by speech detection and gain of the audio stream(s) associated with the video stream.  There are three properties that describe the video frames \"generation\".  The {code:generationRound} identifies the number of times the ranker has ranked video streams. The {code:generationRank} indicates the rank of the video stream this video frame is a part of, relative to the other video streams.  The {code:generationRank} can only be compared to other video frames from the same round. The {code:generationSize} indicates the number of video streams that were ranked in this round.}
	{prototype: LmiBool LmiVideoFrameGetGeneration(const LmiVideoFrame* x, LmiUint* generationRound, LmiUint* generationRank, LmiUint* generationSize)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: generationRound} {description: A pointer to where the generation round will be returned.}}
	{parameter: {name: generationRank} {description: A pointer to where the generation rank will be returned.}}
 	{parameter: {name: generationSize} {description: A pointer to where the generation size will be returned.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties are not found.}
}
*/
LmiBool LmiVideoFrameGetGeneration(const LmiVideoFrame* x, LmiUint* generationRound, LmiUint* generationRank, LmiUint* generationSize);

/**
{function visibility="public":
	{name: LmiVideoFrameGetCodecMimeType}
	{parent: LmiVideoFrame}
	{description: Gets the codec MIME type property of a video frame.  This property indicates the codec that was used to decode the video frame.}
	{prototype: LmiBool LmiVideoFrameGetCodecMimeType(const LmiVideoFrame* x, LmiString* codecMimeType)}
	{parameter: {name: x} {description: Video frame object.}}
 	{parameter: {name: codecMimeType} {description: A pointer to where the codec MIME type will be returned.}}
 	{return: Returns LMI_TRUE on success, or LMI_FALSE if the property is not found.}
}
*/
LMI_INLINE_DECLARATION LmiBool LmiVideoFrameGetCodecMimeType(const LmiVideoFrame* x, LmiString* codecMimeType);


/* TODO - docblocks */
/**
	{function:
		{name: LmiVideoFrameGetScalabilityProperties}
		{parent: LmiVideoFrame}
		{description: Get the scalability properties of a video frame.}
		{prototype: LmiBool LmiVideoFrameGetScalabilityProperties(const LmiVideoFrame* x, LmiSizeT* activeSpatialLayers, LmiSizeT* maxSpatialLayers, LmiSizeT* temporalLayer)}
		{parameter:
			{name: x}
			{description: The video frame object whose scalability properties to get.}}
		{parameter:
			{name: activeSpatialLayers}
			{description: A pointer to where the number of active spatial layers of the frame will be returned.}}
		{parameter:
			{name: maxSpatialLayers}
			{description: A pointer to where the total number of spatial layers in the original frame will be returned.  May be more than activeSpatialLayers.}}
		{parameter:
			{name: temporalLayer}
			{description: A pointer to where the temporal layer of the frame will be returned.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties are not found.}
	}
*/
LmiBool LmiVideoFrameGetScalabilityProperties(const LmiVideoFrame* x, LmiSizeT* activeSpatialLayers, LmiSizeT* maxSpatialLayers, LmiSizeT* temporalLayer);


/**
	{function:
		{name: LmiVideoFrameGetConcealedProperty}
		{parent: LmiVideoFrame}
		{description: Get whether concealment has been done on a video frame.}
		{prototype: LmiBool LmiVideoFrameGetConcealedProperty(const LmiVideoFrame* x, LmiBool* concealed)}
		{parameter:
			{name: x}
			{description: The video frame object whose concealed property to get.}}
		{parameter:
			{name: concealed}
			{description: A pointer to where whether concealment has been done on the frame will be returned.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the property is not found.}
	}
*/
LmiBool LmiVideoFrameGetConcealedProperty(const LmiVideoFrame* x, LmiBool* concealed);

/**
	{function:
		{name: LmiVideoFrameGetMovementAlertProperty}
		{parent: LmiVideoFrame}
		{description: Get movement alert value a video frame.}
		{prototype: LmiBool LmiVideoFrameGetMovementAlertProperty(const LmiVideoFrame* x, LmiUint* alert)}
		{parameter:
			{name: x}
			{description: The video frame queried for movement.}}
		{parameter:
			{name: alert}
			{description: A destination pointer to output movement alert value.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the property is not found.}
	}
*/
LmiBool LmiVideoFrameGetMovementAlertProperty(const LmiVideoFrame* x, LmiUint* alert);

/**
	{function:
		{name: LmiVideoFrameGetLayerProperties}
		{parent: LmiVideoFrame}
		{description: Get properties of a spatial layer of a video frame.}
		{prototype: LmiBool LmiVideoFrameGetLayerProperties(const LmiVideoFrame* x, LmiSizeT layer, LmiSizeT* width, LmiSizeT* height, LmiBool* precise, LmiFloat64* fps, LmiUint* qp)}
		{parameter:
			{name: x}
			{description: The video frame on whose spatial layer properties to get.}}
		{parameter:
			{name: layer}
			{description: The spatial layer for which to get properties.  Should be less than the maxSpatialLayers property returned by LmiVideoFrameGetScalabilityProperties.}}
		{parameter:
			{name: width}
			{description: A pointer to where the width of the layer, in pixels, will be returned.}}
		{parameter:
			{name: height}
			{description: A pointer to where the height of the layer, in pixels, will be returned.}}
		{parameter:
			{name: precise}
			{description: A pointer to where whether the width and height of the layer are known precisely will be returned.  (In some cases, these are not known for layers that are not currently being received.)}}
		{parameter:
			{name: fps}
			{description: A pointer to where the total FPS of the spatial layer, in frames per second, will be returned.}}
		{parameter:
			{name: qp}
			{description: A pointer to where the quantization parameter with which the layer was encoded will be returned.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the properties are not found.}
	}
*/
LmiBool LmiVideoFrameGetLayerProperties(const LmiVideoFrame* x, LmiSizeT layer, LmiSizeT* width, LmiSizeT* height, LmiBool* precise, LmiFloat64* fps, LmiUint* qp);


/**
	{function:
		{name: LmiVideoFrameGetLayerConcealedProperty}
		{parent: LmiVideoFrame}
		{description: Get whether concealment has been done on a layer of a video frame.}
		{prototype: LmiBool LmiVideoFrameGetLayerConcealedProperty(const LmiVideoFrame* x, LmiSizeT layer, LmiBool* concealed)}
		{parameter:
			{name: x}
			{description: The video frame on which to get whether concealment has been done.}}
		{parameter:
			{name: layer}
			{description: The spatial layer for which to get whether concealment has been done.  Should be less than the maxSpatialLayers property returned by LmiVideoFrameGetScalabilityProperties.}}
		{parameter:
			{name: concealed}
			{description: A pointer to where whether concealment has been done on the layer will be returned.}}
		{return: Returns LMI_TRUE on success, or LMI_FALSE if the property is not found.}
	}
*/
LmiBool LmiVideoFrameGetLayerConcealedProperty(const LmiVideoFrame* x, LmiSizeT layer, LmiBool* concealed);

/**
{function visibility="private":
	{name: LmiVideoFrameConvertFormat}
	{parent: LmiVideoFrame}
	{description: Convert video frame data in source to destination with specified format. Either source or destination must be LMI_MEDIAFORMAT_I420.}
	{prototype: LmiBool LmiVideoFrameConvertFormat(LmiVideoFrame *d, const LmiVideoFrame *s, const LmiMediaFormat *format)}
	{parameter: {name: d} {description: Video frame object of destination.}}
	{parameter: {name: s} {description: Video frame object of source.}}
	{parameter: {name: format} {description: Format of video frame to be constructed. If NULL, use existing format in destination.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
	{note: If destination has insufficient storage or incorrect format, it will be reconstructed.}
}
*/
LmiBool LmiVideoFrameConvertFormat(LmiVideoFrame *d, const LmiVideoFrame *s, const LmiMediaFormat *format);

/**
{function visibility="private":
	{name: LmiVideoFrameConvertFormatWithTransform}
	{parent: LmiVideoFrame}
	{description: Convert video frame data in source into format specified in destination, with transformations applied as necessary.}
	{prototype: LmiBool LmiVideoFrameConvertFormatWithTransform(LmiVideoFrame *d, const LmiVideoFrame *s, const LmiMediaFormat *format, const LmiVideoFrameTransformParameters* p)}
	{parameter: {name: d} {description: Video frame object of destination.  This must have the appropriate size and pitch given the source frame and the transform}}
	{parameter: {name: s} {description: Video frame object of source.}}
	{parameter: {name: format} {description: Format of video frame to be constructed. If NULL, use existing format in destination.}}
	{parameter: {name: p} {description: Parameters describing how to transform source frame into destination. If NULL, video frame will be converted with no transformations.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
	{note: Temporary memory may be allocated for intermediate steps of the transformation if more than one transformation step is specified, or if both the source and destination formats are not LMI_MEDIAFORMAT_I420.}
	{note: If destination has insufficient storage or incorrect format, it will be reconstructed.}
}
*/
LmiBool LmiVideoFrameConvertFormatWithTransform(LmiVideoFrame *d, const LmiVideoFrame *s, const LmiMediaFormat *format, const LmiVideoFrameTransformParameters* p);

/**
{function:
	{name: LmiVideoFrameIsMediaFormatSupported}
	{parent: LmiVideoFrame}
	{description: Determine whether a given media format is supported.  Supported means that the media format can be converted by the LmiVideoFrame into I420 (the format necessary for input to a video codecs encoder).}
	{prototype: LmiBool LmiVideoFrameIsMediaFormatSupported(const LmiMediaFormat *mediaFormat)}
	{parameter: {name: mediaFormat} {description: The media format to check.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameIsMediaFormatSupported(const LmiMediaFormat *mediaFormat);

/**
{function:
	{name: LmiVideoFrameGetMediaFormats}
	{parent: LmiVideoFrame}
	{description: Gets a list of all supported media formats.  Supported media formats are those for which LmiVideoFrame has conversion routines to convert the media into I420 (the format necessary for input to a video codec encoder).}
	{prototype: LmiBool LmiVideoFrameGetMediaFormats(LmiVector(LmiMediaFormat) *mediaFormats)}
	{parameter: {name: mediaFormats} {description: A vector into which the list of supported media formats is returned.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameGetMediaFormats(LmiVector(LmiMediaFormat) *mediaFormats);

/**
{function:
	{name: LmiVideoFrameGetEfficiencyIndex}
	{parent: LmiVideoFrame}
	{description: Gets the efficiency index of the given media format.  This provides a measure of how efficiently the given media format can be converted to I420. Note: Lower numbers are better. }
	{prototype: LmiSizeT LmiVideoFrameGetEfficiencyIndex(const LmiMediaFormat *mediaFormat)}
	{parameter: {name: mediaFormat} {description: The media format whose efficiency index is requested.}}
 	{return: Returns the efficiency index of the given media format or ~0 if the media format is not supported.}
}
*/
LmiSizeT LmiVideoFrameGetEfficiencyIndex(const LmiMediaFormat *mediaFormat);

/**
{function visibility="public":
	{name: LmiVideoFrameCrop}
	{parent: LmiVideoFrame}
	{description: Crop a video frame\'s image in-place to the specified dimensions.}
	{prototype: LmiBool LmiVideoFrameCrop(LmiVideoFrame *x, LmiSizeT cropWidth, LmiSizeT cropHeight, LmiDistanceT offsetX, LmiDistanceT offsetY)}
	{parameter: {name: x} {description: A video frame object to be cropped.  This may be in any supported uncompressed media format.}}
	{parameter: {name: cropWidth} {description: Width of cropped frame.}}
	{parameter: {name: cropHeight} {description: Height of cropped frame.}}
	{parameter: {name: offsetX} {description: Left offset of cropped frame\'s start pixel.}}
	{parameter: {name: offsetY} {description: Top offset of cropped frame\'s start pixel.}}
	{return: Returns LMI_TRUE if cropping was successful or LMI_FALSE otherwise.}
	{note: This crops the video frame in place; because LmiVideoFrame is a shared pointer, all references to this frame will be cropped.  If there may be other users of this video frame, the caller should call LmiVideoFrameMakeExclusive first.}
}
*/
LmiBool LmiVideoFrameCrop(LmiVideoFrame *x, LmiSizeT cropWidth, LmiSizeT cropHeight, LmiDistanceT offsetX, LmiDistanceT offsetY);

/**
{function visibility="private":
	{name: LmiVideoFrameResize}
	{parent: LmiVideoFrame}
	{description: Resize video frame data in source into dimensions specified in destination. Both source and destination must be LMI_MEDIAFORMAT_I420.}
	{prototype: LmiBool LmiVideoFrameResize(LmiVideoFrame *d, const LmiVideoFrame *s)}
	{parameter: {name: d} {description: Video frame object of destination.}}
	{parameter: {name: s} {description: Video frame object of source.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameResize(LmiVideoFrame *d, const LmiVideoFrame *s);

/**
{function visibility="private":
	{name: LmiVideoFrameRotate}
	{parent: LmiVideoFrame}
	{description: Rotate video frame data in source into destination. Destination must have correct dimensions. Both source and destination must be LMI_MEDIAFORMAT_I420.}
	{prototype: LmiBool LmiVideoFrameRotate(LmiVideoFrame *d, const LmiVideoFrame *s, LmiImageRotationDegree rotationDegree)}
	{parameter: {name: d} {description: Video frame object of destination.}}
	{parameter: {name: s} {description: Video frame object of source.}}
	{parameter: {name: rotationDegree} {description: Degrees to rotate frame. Will be rounded to nearest multiple of 90.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameRotate(LmiVideoFrame *d, const LmiVideoFrame *s, LmiImageRotationDegree rotationDegree);

/**
{function visibility="public":
	{name: LmiVideoFrameMirror}
	{parent: LmiVideoFrame}
	{description: Mirror video frame data in source into destination. Destination must have correct dimensions. Both source and destination must be LMI_MEDIAFORMAT_I420.}
	{prototype: LmiBool LmiVideoFrameMirror(LmiVideoFrame *d, const LmiVideoFrame *s)}
	{parameter: {name: d} {description: Video frame object of destination.}}
	{parameter: {name: s} {description: Video frame object of source.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameMirror(LmiVideoFrame *d, const LmiVideoFrame *s);

/**
{function visibility="public":
	{name: LmiVideoFrameSharpen}
	{parent: LmiVideoFrame}
	{description: Sharpen video frame data in source into destination. Destination must have correct dimensions.  Both source and destination must be LMI_MEDIAFORMAT_I420.}
	{prototype: LmiBool LmiVideoFrameSharpen(LmiVideoFrame *d, const LmiVideoFrame *s, LmiVideoFrame* tmp, LmiVideoFrameSharpenLevel sharpenLevel)}
	{parameter: {name: d} {description: Video frame object of destination.}}
	{parameter: {name: s} {description: Video frame object of source.}}
	{parameter: {name: tmp} {description: Optional video frame object to hold temporary data.  Must be a Y8 or I420 image with dimensions at least those of the source frame.  Chroma planes are ignored.  If NULL, a temporary buffer will be allocated.}}
	{parameter: {name: sharpenLevel} {description: Degree of sharpening to apply.  Must not be LMI_VIDEOFRAMESHARPENLEVEL_Off.}}
 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameSharpen(LmiVideoFrame *d, const LmiVideoFrame *s, LmiVideoFrame* tmp, LmiVideoFrameSharpenLevel sharpenLevel);

/**
	{function visibility="public":
		{name: LmiVideoFrameComputeNormalizationTransformParameters}
		{parent: LmiVideoFrame}
		{description: Compute the transform parameters necessary to normalize a video frame --
			make it un-rotated and un-mirrored -- based on its current rotation and mirrored
			properties.}
		{prototype: LmiBool LmiVideoFrameComputeNormalizationTransformParameters(const LmiVideoFrame* f, LmiVideoFrameTransformParameters* p)}
		{parameter: {name: f} {description: Video frame from which to get properties.}}
		{parameter: {name: p} {description: Transform parameters to set.}}
	 	{return: Returns LMI_TRUE on success or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameComputeNormalizationTransformParameters(const LmiVideoFrame* f, LmiVideoFrameTransformParameters* p);

/**
	{function visibility="public":
		{name: LmiVideoFrameHasSufficientImageSize}
		{parent: LmiVideoFrame}
		{description: Check if a video frame\'s image (not counting offsets) is large enough to contain an image of given width and height.}
		{prototype: LmiBool LmiVideoFrameHasSufficientImageSize(const LmiVideoFrame *x, LmiSizeT width, LmiSizeT height)}
		{parameter: {name: x} {description: Video frame to test.}}
		{parameter: {name: width} {description: Width criterion.}}
		{parameter: {name: height} {description: Height criterion.}}
	 	{return: Returns LMI_TRUE if the video frame is large enough or LMI_FALSE otherwise.}
}
*/
LmiBool LmiVideoFrameHasSufficientImageSize(const LmiVideoFrame *x, LmiSizeT width, LmiSizeT height);

Declare_LmiFifo(LmiVideoFrame)

LMI_END_EXTERN_C

#if LMI_INLINE_NEED_HEADER_FILE_DEFINITIONS
#include <Lmi/Video/Common/LmiVideoFrameInline.h>
#endif

#endif /* LMI_VIDEOFRAME_H */
