/**
{file:
	{name: LmiMediaFrame.h}
	{description: }
	{copyright:
		(c) 2012-2015 Vidyo, Inc.,
		433 Hackensack Avenue,
		Hackensack, NJ  07601.

		All rights reserved.

		The information contained herein is proprietary to Vidyo, Inc.
		and shall not be reproduced, copied (in whole or in part), adapted,
		modified, disseminated, transmitted, transcribed, stored in a retrieval
		system, or translated into any language in any form by any means
		without the express written consent of Vidyo, Inc.
		                  ***** CONFIDENTIAL *****
	}
}
*/
#ifndef LMI_MEDIAFRAME_H
#define LMI_MEDIAFRAME_H

#include <Lmi/Utils/LmiTypes.h>
#include <Lmi/Utils/LmiAllocator.h>
#include <Lmi/Utils/LmiMediaType.h>
#include <Lmi/Utils/LmiMediaFormat.h>
#include <Lmi/Utils/LmiList.h>
#include <Lmi/Utils/LmiLocation.h>
#include <Lmi/Os/LmiSharedPtr.h>
#include <Lmi/Os/LmiProperties.h>

LMI_BEGIN_EXTERN_C

/* #define LMI_MEDIAFRAME_DO_DUMMYALLOC 1 */

#define LMI_MEDIAFRAMEGENERATION_INVALID  ( 0xffffffff )
#define LMI_MEDIAFRAMEGENERATIONROUND_INVALID  ( 0xffffffff )

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

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

/**
{function:
 	{name: LmiMediaFrameReleaseDeallocate}
 	{parent: LmiMediaFrame}
 	{description: An instance of LmiMediaFrameReleaseCallback that simply calls LmiAllocatorDeallocate on its specified allocator.  This can be passed as the releaseCallback for LmiMediaFrameConstructWithExternalBuffer (and derived functions) if the buffer was allocated with LmiAllocatorAllocate.}
 	{prototype: void LmiMediaFrameReleaseDeallocate(void* buffer, LmiSizeT size, LmiAllocator* alloc)}
 	{parameter:
 		{name: buffer}
 		{description: The buffer to be released.}
 	}
  	{parameter:
 		{name: size}
 		{description: The size of the buffer.}
 	}
  	{parameter:
 		{name: alloc}
 		{description: The allocator used to allocate the buffer.}
 	}
}
*/
void LmiMediaFrameReleaseDeallocate(void* buffer, LmiSizeT size, LmiAllocator* alloc);

/**
{type visibility="private":
	{name: LmiMediaFrameImpl}
	{parent: LmiMediaFrame}
	{description: Shared implementation object for media frames.}
}
*/

typedef struct {
	LmiMediaType mediaType;
	LmiMediaFormat format;
	void *buffer;
	LmiSizeT size;
	LmiMediaFrameReleaseCallback releaseCallback;
	LmiProperties properties;
	LmiAllocator* bufferAlloc;
	LmiAllocator* alloc;
} LmiMediaFrameImpl;

LmiMediaFrameImpl *LmiMediaFrameImplConstruct(LmiMediaFrameImpl *f, void *buffer, LmiSizeT size, const LmiMediaFormat *frameFormat, LmiMediaType mediaType, const LmiProperties* properties, LmiAllocator* bufferAlloc, LmiAllocator *alloc);
LmiMediaFrameImpl *LmiMediaFrameImplConstructWithExternalBuffer(LmiMediaFrameImpl *f, void *buffer, LmiSizeT size, LmiAllocator* bufferAlloc, LmiMediaFrameReleaseCallback releaseCallback, const LmiMediaFormat *frameFormat, LmiMediaType mediaType, const LmiProperties* properties, LmiAllocator *alloc);
void LmiMediaFrameImplDestruct(LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION LmiMediaType LmiMediaFrameImplGetType(const LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION const LmiMediaFormat *LmiMediaFrameImplGetFormat(const LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION void LmiMediaFrameImplSetBuffer(LmiMediaFrameImpl *f, void *buffer);
const void *LmiMediaFrameImplGetBuffer(const LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION LmiSizeT LmiMediaFrameImplGetSize(const LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION const LmiProperties *LmiMediaFrameImplGetPropertiesConst(const LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION LmiProperties *LmiMediaFrameImplGetProperties(LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION LmiAllocator *LmiMediaFrameImplGetAllocator(const LmiMediaFrameImpl *f);
LMI_INLINE_DECLARATION LmiAllocator *LmiMediaFrameImplGetBufferAllocator(const LmiMediaFrameImpl *f);


#if LMI_MEDIAFRAME_DO_DUMMYALLOC
Declare_LmiSharedPtr_DummyAlloc(LmiMediaFrameImpl)
#else
Declare_LmiSharedPtr(LmiMediaFrameImpl)
#endif

/**
{type:
	{name: LmiMediaFrame}
	{parent: MediaCommon}
	{include: Lmi/Media/Common/LmiMediaFrame.h}
	{description: Media Frame is a base class that stores a void pointer or an object containing the media frame data for different source types.
		When the format is one of the internal LMI formats such as MEDIA_FORMAT_LmiPcmFrame, the media frame will retain a reference counted copy.
		For media frames with contiguous data buffers, a valid size must be provided and the data will be copied and stored internally.
		If the media frame is located in static memory or the memory will be managed externally, isExternal parameter should be set to LMI_TRUE and a copy will not be made.}
}
*/
typedef struct {
	LmiSharedPtr(LmiMediaFrameImpl) impl;
} LmiMediaFrame;

/**
{function visibility="public":
	{name: LmiMediaFrameConstruct}
	{parent: LmiMediaFrame}
	{description: Constructs a media frame object.}
	{prototype: LmiMediaFrame *LmiMediaFrameConstruct(LmiMediaFrame *f, void *buffer, LmiSizeT size, const LmiMediaFormat *frameFormat, LmiMediaType mediaType, const LmiProperties* properties, LmiAllocator *alloc)}
	{parameter: {name: f} {description: A media frame object to construct.}}
	{parameter: {name: buffer} {description: A void pointer to the media frame data, or NULL.}}
	{parameter: {name: size} {description: Size of data in bytes.}}
	{parameter: {name: frameFormat} {description: Media format of the media frame.}}
	{parameter: {name: mediaType} {description: The type of the media frame.}}
	{parameter: {name: properties} {description: A pointer to properties to associate with the media frame or NULL.}}
	{parameter: {name: alloc} {description: An allocator to be used for memory.}}
	{return: A pointer to a constructed object on success, or NULL on failure.}
	{note: This constructor allocates new internal memory for its buffer.  If the buffer parameter is not NULL, its
		contents (up to size) are copied to the internal data.}
}
*/
LmiMediaFrame *LmiMediaFrameConstruct(LmiMediaFrame *f, void *buffer, LmiSizeT size, const LmiMediaFormat *frameFormat, LmiMediaType mediaType, const LmiProperties* properties, LmiAllocator *alloc);

/**
{function visibility="public":
	{name: LmiMediaFrameConstructWithExternalBuffer}
	{parent: LmiMediaFrame}
	{description: Constructs a media frame object with externally-allocated memory.}
	{prototype: LmiMediaFrame *LmiMediaFrameConstructWithExternalBuffer(LmiMediaFrame *f, void *buffer, LmiSizeT size, LmiAllocator* bufferAlloc, LmiMediaFrameReleaseCallback releaseCallback, const LmiMediaFormat *frameFormat, LmiMediaType mediaType, const LmiProperties* properties, LmiAllocator *alloc)}
	{parameter: {name: f} {description: A media frame object to construct.}}
	{parameter: {name: buffer} {description: A void pointer to the media frame data.}}
	{parameter: {name: size} {description: Size of data in bytes.}}
	{parameter: {name: bufferAlloc} {description: The allocator used to allocate {code:buffer}.  May be NULL.}}
	{parameter: {name: releaseCallback} {description: A callback to be called on LmiMediaFrameDestruct so that memory may be reclaimed.}}
	{parameter: {name: frameFormat} {description: Media format of the media frame.}}
	{parameter: {name: mediaType} {description: The type of the media frame.}}
	{parameter: {name: properties} {description: A pointer to properties to associate with the media frame or NULL.}}
	{parameter: {name: alloc} {description: An allocator to be used for memory.}}
	{return: A pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiMediaFrame *LmiMediaFrameConstructWithExternalBuffer(LmiMediaFrame *f, void *buffer, LmiSizeT size, LmiAllocator* bufferAlloc, LmiMediaFrameReleaseCallback releaseCallback, const LmiMediaFormat *frameFormat, LmiMediaType mediaType, const LmiProperties* properties, LmiAllocator *alloc);

/**
{function visibility="private":
	{name: LmiMediaFrameConstructWithImpl}
	{parent: LmiMediaFrame}
	{description: Constructs a media frame object.}
	{prototype: LmiMediaFrame *LmiMediaFrameConstructWithImpl(LmiMediaFrame *f, LmiMediaFrameImpl *impl, LmiSharedPtrDeleterCallback deleter, LmiAllocator *alloc)}
	{parameter: {name: f} {description: A media frame object to construct.}}
	{parameter: {name: impl} {description: A pointer to the memory containing media frame impl.}}
	{parameter: {name: deleter} {description: Pointer to the deleter function.}}
	{parameter: {name: alloc} {description: An allocator to be used for memory.}}
	{return: A pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiMediaFrame *LmiMediaFrameConstructWithImpl(LmiMediaFrame *f, LmiMediaFrameImpl *impl, LmiSharedPtrDeleterCallback deleter, LmiAllocator *alloc);

/**
{function visibility="public":
	{name: LmiMediaFrameConstructCopy}
	{parent: LmiMediaFrame}
	{description: Constructs a copy of a media frame object.}
	{prototype: LmiMediaFrame *LmiMediaFrameConstructCopy(LmiMediaFrame *d, const LmiMediaFrame *s)}
	{parameter: {name: d} {description: A media frame object to construct.}}
	{parameter: {name: s} {description: A media frame object to construct from.}}
	{return: A pointer to a constructed object on success, or NULL on failure.}
}
*/
LmiMediaFrame *LmiMediaFrameConstructCopy(LmiMediaFrame *d, const LmiMediaFrame *s);

/**
{function visibility="public":
	{name: LmiMediaFrameDestruct}
	{parent: LmiMediaFrame}
	{description: Destructs a media frame object.}
	{prototype: void LmiMediaFrameDestruct(LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object to destruct.}}
}
*/
void LmiMediaFrameDestruct(LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameAssign}
	{parent: LmiMediaFrame}
	{description: Assigns a media frame object to another.}
	{prototype: LmiMediaFrame *LmiMediaFrameAssign(LmiMediaFrame *d, const LmiMediaFrame *s)}
	{parameter: {name: d} {description: A media frame object to assign.}}
	{parameter: {name: s} {description: A media frame object to assign from.}}
	{return: A pointer to an assigned object on success, or NULL on failure.}
}
*/
LmiMediaFrame *LmiMediaFrameAssign(LmiMediaFrame *d, const LmiMediaFrame *s);

/**
{function visibility="public":
	{name: LmiMediaFrameEqual}
	{parent: LmiMediaFrame}
	{description: Compare a media frame object to another.}
	{prototype: LmiBool LmiMediaFrameEqual(const LmiMediaFrame *d, const LmiMediaFrame *s)}
	{parameter: {name: d} {description: A media frame object to compare.}}
	{parameter: {name: s} {description: A media frame object to compare.}}
	{return: LMI_TRUE if the pcm frame objects are equal, LMI_FALSE otherwise.}
}
*/
LmiBool LmiMediaFrameEqual(const LmiMediaFrame *d, const LmiMediaFrame *s);

/**
{function visibility="public":
	{name: LmiMediaFrameLess}
	{parent: LmiMediaFrame}
	{description: Compare a media frame object to another.}
	{prototype: LmiBool LmiMediaFrameLess(const LmiMediaFrame *d, const LmiMediaFrame *s)}
	{parameter: {name: d} {description: A media frame object to compare.}}
	{parameter: {name: s} {description: A media frame object to compare.}}
	{return: LMI_TRUE if d less than s, LMI_FALSE otherwise.}
}
*/
LmiBool LmiMediaFrameLess(const LmiMediaFrame *d, const LmiMediaFrame *s);

/**
 {function visibility="public":
	{name: LmiMediaFrameSwap}
	{parent: LmiMediaFrame}
	{description: Swap the values of two media frame objects.}
	{prototype: LmiBool LmiMediaFrameSwap(LmiMediaFrame *a, LmiMediaFrame *b)}
	{parameter: {name: a} {description: A media frame object to swap.}}
	{parameter: {name: b} {description: A media frame object to compare.}}
	{return: LMI_TRUE if the two frames were successfully swapped, LMI_FALSE otherwise.}
 }
 */
LmiBool LmiMediaFrameSwap(LmiMediaFrame *d, LmiMediaFrame *s);


Declare_LmiList(LmiMediaFrame)

/**
{function visibility="private":
	{name: LmiMediaFrameGetImpl}
	{parent: LmiMediaFrame}
	{description: Gets the impl of the media frame object.}
	{prototype: LmiMediaFrameImpl *LmiMediaFrameGetImpl(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: Impl of the media frame object on success, or NULL on failure.}
}
*/
LMI_INLINE_DECLARATION LmiMediaFrameImpl *LmiMediaFrameGetImpl(const LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameGetType}
	{parent: LmiMediaFrame}
	{description: Gets the type of a media frame object.}
	{prototype: LmiMediaType LmiMediaFrameGetType(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: The type of the media frame object.}
}
*/
LMI_INLINE_DECLARATION LmiMediaType LmiMediaFrameGetType(const LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameGetTypeCStr}
	{parent: LmiMediaFrame}
	{description: Gets the type of a media frame object.}
	{prototype: const char *LmiMediaFrameGetTypeCStr(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: The type as a C string of the media frame object.}
}
*/
LMI_INLINE_DECLARATION const char *LmiMediaFrameGetTypeCStr(const LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameGetFormat}
	{parent: LmiMediaFrame}
	{description: Gets the format of a media frame object.}
	{prototype: const LmiMediaFormat *LmiMediaFrameGetFormat(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: Format of a media frame object.}
}
*/
LMI_INLINE_DECLARATION const LmiMediaFormat *LmiMediaFrameGetFormat(const LmiMediaFrame *f);

/**
{function visibility="private":
	{name: LmiMediaFrameSetBuffer}
	{parent: LmiMediaFrame}
	{description: Sets void pointer to the media frame object\'s data.}
	{prototype: void LmiMediaFrameSetBuffer(LmiMediaFrame *f, void *buffer)}
	{parameter: {name: f} {description: A media frame object.}}
	{parameter: {name: buffer} {description: A pointer to the media frame object\'s data.}}
}
*/
LMI_INLINE_DECLARATION void LmiMediaFrameSetBuffer(LmiMediaFrame *f, void *buffer);

/**
{function visibility="public":
	{name: LmiMediaFrameGetBuffer}
	{parent: LmiMediaFrame}
	{description: Gets void pointer to the media frame object\'s data.}
	{prototype: const void *LmiMediaFrameGetBuffer(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: A pointer to the media frame object\'s data.}
}
*/
LMI_INLINE_DECLARATION const void *LmiMediaFrameGetBuffer(const LmiMediaFrame *f);

/**
{function visibility="private":
	{name: LmiMediaFrameGetSize}
	{parent: LmiMediaFrame}
	{description: Gets the size in bytes of the media frame object.}
	{prototype: LmiSizeT LmiMediaFrameGetSize(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: Media frame object.}}
	{return: Size in bytes of the media frame object.}
	{note: The size will be 0 for internal LMI formats such as MEDIA_FORMAT_LmiYuv420Image or MEDIA_FORMAT_LmiPcmFrame.}
}
*/
LMI_INLINE_DECLARATION LmiSizeT LmiMediaFrameGetSize(const LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameGetAllocator}
	{parent: LmiMediaFrame}
	{description: Gets allocator used to create media frame object.}
	{prototype: LmiAllocator *LmiMediaFrameGetAllocator(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: Allocator used to create media frame object.}
}
*/
LMI_INLINE_DECLARATION LmiAllocator *LmiMediaFrameGetAllocator(const LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameGetBufferAllocator}
	{parent: LmiMediaFrame}
	{description: Gets allocator used to allocate media frame buffer.}
	{prototype: LmiAllocator *LmiMediaFrameGetBufferAllocator(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: Allocator used to allocate media frame's buffer.}
}
*/
LMI_INLINE_DECLARATION LmiAllocator *LmiMediaFrameGetBufferAllocator(const LmiMediaFrame *f);



/**
{function visibility="public":
	{name: LmiMediaFrameGetPropertiesConst}
	{parent: LmiMediaFrame}
	{description: Gets a const pointer to the properties of the media frame object.}
	{prototype: const LmiProperties *LmiMediaFrameGetPropertiesConst(const LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: A const pointer to the media frame object\'s properties.}
}
*/
LMI_INLINE_DECLARATION const LmiProperties *LmiMediaFrameGetPropertiesConst(const LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameGetProperties}
	{parent: LmiMediaFrame}
	{description: Gets a pointer to the properties of the media frame object.}
	{prototype: LmiProperties *LmiMediaFrameGetProperties(LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: A pointer to the media frame object\'s properties.}
}
*/
LMI_INLINE_DECLARATION LmiProperties *LmiMediaFrameGetProperties(LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameIsExclusive}
	{parent: LmiMediaFrame}
	{description: Checks the exclusivity of the media frame object.}
	{prototype: LmiBool LmiMediaFrameIsExclusive(LmiMediaFrame *f)}
	{parameter: {name: f} {description: A media frame object.}}
	{return: LMI_TRUE if the frame is exclusive.}
}
*/
LMI_INLINE_DECLARATION LmiBool LmiMediaFrameIsExclusive(LmiMediaFrame *f);

/**
{function visibility="public":
	{name: LmiMediaFrameSetTimeProperties}
	{parent: LmiMediaFrame}
	{description: Sets time properties on the media frame (typically supplied by the capturer or RTP).}
 	{prototype: LmiBool LmiMediaFrameSetTimeProperties(LmiMediaFrame* x, LmiTime elapsedTime, LmiTime timestamp)}
	{parameter: {name: x} {description: Media frame object.}}
	{parameter: {name: elapsedTime} {description: The elapsed time of the media frame.}}
	{parameter: {name: timestamp} {description: The wallclock timestamp associated with the creation of the media frame.}}
 	{return: Return 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.}
}
*/
LmiBool LmiMediaFrameSetTimeProperties(LmiMediaFrame* x, LmiTime elapsedTime, LmiTime timestamp);

/**
{function visibility="public":
	{name: LmiMediaFrameSetLocationProperties}
	{parent: LmiMediaFrame}
	{description: Sets location properties on the media frame.}
 	{prototype: LmiBool LmiMediaFrameSetLocationProperties(LmiMediaFrame* x, const LmiLocation* location)}
	{parameter: {name: x} {description: Media frame object.}}
	{parameter: {name: location} {description: The location of the media frame.}}
 	{return: Return LMI_TRUE on success, or LMI_FALSE if the properties could not be set.}
}
*/
LmiBool LmiMediaFrameSetLocationProperties(LmiMediaFrame* x, const LmiLocation* location);
/**
{function visibility="public":
	{name: LmiMediaFrameSetCodecMimeTypeProperty}
	{parent: LmiMediaFrame}
	{description: Sets the \"codec MIME type\" property on the media frame.}
 	{prototype: LmiBool LmiMediaFrameSetCodecMimeTypeProperty(LmiMediaFrame* x, const LmiString* codecMimeType)}
	{parameter: {name: x} {description: Media 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.}
}
*/
LmiBool LmiMediaFrameSetCodecMimeTypeProperty(LmiMediaFrame* x, const LmiString* codecMimeType);

/**
{function visibility="public":
	{name: LmiMediaFrameSetCodecMimeTypePropertyCStr}
	{parent: LmiMediaFrame}
	{description: Sets \"codec MIME type\" property.}
 	{prototype: LmiBool LmiMediaFrameSetCodecMimeTypePropertyCStr(LmiMediaFrame* x, const char* codecMimeType)}
	{parameter: {name: x} {description: Media 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.}
}
*/
LmiBool LmiMediaFrameSetCodecMimeTypePropertyCStr(LmiMediaFrame* x, const char* codecMimeType);

/* TODO: ???? Get a better explanation of "elapsed time" and "timestamp" from Gene.*/
/* 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: LmiMediaFrameGetElapsedTime}
	{parent: LmiMediaFrame}
	{description: Gets the elapsed time property of a media frame object.}
	{prototype: LmiTime LmiMediaFrameGetElapsedTime(const LmiMediaFrame* x)}
	{parameter: {name: x} {description: Media frame object.}}
 	{return: Returns the elapsed time.}
}
*/
LmiTime LmiMediaFrameGetElapsedTime(const LmiMediaFrame* x);

/**
{function visibility="public":
	{name: LmiMediaFrameGetTimestamp}
	{parent: LmiMediaFrame}
	{description: Gets the RTP timestamp property of a media frame object.}
	{prototype: LmiTime LmiMediaFrameGetTimestamp(const LmiMediaFrame* x)}
	{parameter: {name: x} {description: Media frame object.}}
 	{return: Returns the RTP timestamp.}
}
*/
LmiTime LmiMediaFrameGetTimestamp(const LmiMediaFrame* x);

/**
{function visibility="public":
	{name: LmiMediaFrameGetCodecMimeType}
	{parent: LmiMediaFrame}
	{description: Gets the codec MIME type property of a media frame object.  This property indicates the codec that was used to decode the media frame.}
	{prototype: LmiBool LmiMediaFrameGetCodecMimeType(const LmiMediaFrame* x, LmiString* codecMimeType)}
	{parameter: {name: x} {description: Media 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.}
}
*/
LmiBool LmiMediaFrameGetCodecMimeType(const LmiMediaFrame* x, LmiString* codecMimeType);

LMI_END_EXTERN_C

#if LMI_INLINE_NEED_HEADER_FILE_DEFINITIONS
#include <Lmi/Media/Common/LmiMediaFrameInline.h>
#endif

#endif
