--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/khronosfws/openmax_al/src/common/xametadataextractionitf.c Fri Apr 16 15:29:42 2010 +0300
@@ -0,0 +1,576 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "xametadataextractionitf.h"
+#include "xadebug.h"
+#ifdef _GSTREAMER_BACKEND_
+#include "XAMetadataAdaptation.h"
+#endif
+/* XAMetadataExtractionItfImpl* GetImpl(XAMetadataExtractionItf self)
+ * Description: Validate interface pointer and cast it to implementation pointer.
+ **/
+static XAMetadataExtractionItfImpl* GetImpl(XAMetadataExtractionItf self)
+{
+ if( self )
+ {
+ XAMetadataExtractionItfImpl* impl = (XAMetadataExtractionItfImpl*)(*self);
+ if( impl && (impl == impl->self) )
+ {
+ return impl;
+ }
+ }
+ return NULL;
+}
+
+/*****************************************************************************
+ * Base interface XAMetadataExtractionItf implementation
+ *****************************************************************************/
+
+/*
+ * Returns the number of metadata items within the current scope of the object.
+ * @XAuint32 *pItemCount
+ * Number of metadata items. Must be non-NULL
+ */
+XAresult XAMetadataExtractionItfImpl_GetItemCount(XAMetadataExtractionItf self,
+ XAuint32 *pItemCount)
+{
+ XAMetadataExtractionItfImpl *impl = NULL;
+ XAresult res = XA_RESULT_SUCCESS;
+ DEBUG_API("->XAMetadataExtractionItfImpl_GetItemCount");
+
+ impl = GetImpl(self);
+ /* check parameters */
+ if( !impl || !pItemCount )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ res = XA_RESULT_PARAMETER_INVALID;
+ }
+ else
+ {
+#ifdef _GSTREAMER_BACKEND_
+ if( impl->adaptCtx )
+ {
+ if(impl->filteringOn)
+ {
+ *pItemCount = impl->filteredcount;
+ }
+ else
+ {
+ *pItemCount = impl->currentTags.itemcount;
+ }
+ res = XA_RESULT_SUCCESS;
+ }
+ else
+ {
+ res = XA_RESULT_INTERNAL_ERROR;
+ }
+#endif
+ DEBUG_INFO_A1("itemCount = %d", (int)*pItemCount);
+ }
+
+ DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetItemCount (%d)", (int)res);
+ return res;
+}
+
+/*
+ * Returns the byte size of a given metadata key
+ *
+ * @XAuint32 index
+ * Metadata item Index. Range is [0, GetItemCount)
+ * @XAuint32 *pKeySize
+ * Address to store key size. size must be greater than 0. Must be non-NULL
+ */
+XAresult XAMetadataExtractionItfImpl_GetKeySize(XAMetadataExtractionItf self,
+ XAuint32 index,
+ XAuint32 *pKeySize)
+{
+ XAMetadataExtractionItfImpl *impl = NULL;
+ XAresult res = XA_RESULT_SUCCESS;
+ XAuint32 newidx = 0;
+ DEBUG_API("->XAMetadataExtractionItfImpl_GetKeySize");
+
+ impl = GetImpl(self);
+ if( !impl || !pKeySize )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetKeySize");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+ *pKeySize = 0;
+
+ /* check index and return unfiltered index */
+ if( CheckAndUnfilterIndex(impl,index,&newidx) != XA_RESULT_SUCCESS )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetKeySize");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+#ifdef _GSTREAMER_BACKEND_
+ /* size = size of struct + size of data - 1 (struct size already includes one char) */
+ *pKeySize = sizeof(XAMetadataInfo) + impl->currentTags.mdeKeys[newidx]->size - 1;
+#endif
+ DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetKeySize (%d)", (int)res);
+ return res;
+}
+
+/*
+ * Returns a XAMetadataInfo structure and associated data referenced by the structure for a key.
+ * @XAuint32 index
+ * Metadata item Index. Range is [0, GetItemCount())
+ * @XAuint32 keySize
+ * Size of the memory block passed as key. Range is [1, GetKeySize].
+ * @XAMetadataInfo *pKey
+ * Address to store the key. Must be non-NULL
+ */
+XAresult XAMetadataExtractionItfImpl_GetKey(XAMetadataExtractionItf self,
+ XAuint32 index,
+ XAuint32 keySize,
+ XAMetadataInfo *pKey)
+{
+ XAMetadataExtractionItfImpl *impl = NULL;
+ XAresult res = XA_RESULT_SUCCESS;
+ XAuint32 newidx = 0;
+#ifdef _GSTREAMER_BACKEND_
+ XAuint32 neededsize = 0;
+#endif
+ XAuint32 newdatasize = 0;
+ DEBUG_API("->XAMetadataExtractionItfImpl_GetKey");
+
+ impl = GetImpl(self);
+ if( !impl || !pKey )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetKey");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+
+ /* check index and return unfiltered index */
+ if(CheckAndUnfilterIndex(impl,index,&newidx) != XA_RESULT_SUCCESS)
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetKey");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+
+ memset(pKey,0,keySize);
+#ifdef _GSTREAMER_BACKEND_
+ /* needed size = size of struct + size of data - 1 (struct size already includes one char) */
+ neededsize = sizeof(XAMetadataInfo) + impl->currentTags.mdeKeys[newidx]->size - 1;
+ if( keySize<neededsize )
+ { /* cannot fit all of key data */
+ newdatasize = impl->currentTags.mdeKeys[newidx]->size - (neededsize-keySize);
+ DEBUG_ERR("XA_RESULT_BUFFER_INSUFFICIENT");
+ res = XA_RESULT_BUFFER_INSUFFICIENT;
+ }
+ else
+ {
+ newdatasize = impl->currentTags.mdeKeys[newidx]->size;
+ res = XA_RESULT_SUCCESS;
+ }
+ /* copy data up to given size */
+ memcpy(pKey,impl->currentTags.mdeKeys[newidx],keySize-1);
+ /* ensure null-termination */
+#endif
+ memset(pKey->data+newdatasize-1,0,1);
+ pKey->size = newdatasize;
+
+ DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetKey (%d)", (int)res);
+ return res;
+}
+
+
+/*
+ * Returns the byte size of a given metadata value
+ * @XAuint32 index
+ * Metadata item Index. Range is [0, GetItemCount())
+ * @XAuint32 *pValueSize
+ * Address to store value size. size must be greater than 0. Must be non-NULL
+ */
+XAresult XAMetadataExtractionItfImpl_GetValueSize(XAMetadataExtractionItf self,
+ XAuint32 index,
+ XAuint32 *pValueSize)
+{
+ XAMetadataExtractionItfImpl *impl = NULL;
+ XAresult res = XA_RESULT_SUCCESS;
+ XAuint32 newidx = 0;
+ DEBUG_API("->XAMetadataExtractionItfImpl_GetValueSize");
+
+ impl = GetImpl(self);
+ if( !impl || !pValueSize )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetValueSize");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+ *pValueSize = 0;
+
+ /* check index and return unfiltered index */
+ if(CheckAndUnfilterIndex(impl,index,&newidx) != XA_RESULT_SUCCESS)
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetValueSize");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+#ifdef _GSTREAMER_BACKEND_
+ /* size = size of struct + size of data - 1 (struct size already includes one char) */
+ *pValueSize = sizeof(XAMetadataInfo) + impl->currentTags.mdeValues[newidx]->size - 1;
+#endif
+ DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetValueSize (%d)", (int)res);
+ return res;
+}
+
+/*
+ * Returns a XAMetadataInfo structure and associated data referenced by the structure for a value.
+ * @XAuint32 index
+ * Metadata item Index. Range is [0, GetItemCount())
+ * @XAuint32 valueSize
+ * Size of the memory block passed as value. Range is [0, GetValueSize]
+ * @XAMetadataInfo *pValue
+ * Address to store the value. Must be non-NULL
+ */
+XAresult XAMetadataExtractionItfImpl_GetValue(XAMetadataExtractionItf self,
+ XAuint32 index,
+ XAuint32 valueSize,
+ XAMetadataInfo *pValue)
+{
+ XAMetadataExtractionItfImpl *impl = NULL;
+ XAresult res = XA_RESULT_SUCCESS;
+ XAuint32 newidx = 0;
+#ifdef _GSTREAMER_BACKEND_
+ XAuint32 neededsize = 0;
+#endif
+ XAuint32 newdatasize = 0;
+ DEBUG_API("->XAMetadataExtractionItfImpl_GetValue");
+
+ impl = GetImpl(self);
+ if( !impl || !pValue )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetValue");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+
+ /* check index and return unfiltered index */
+ if(CheckAndUnfilterIndex(impl,index,&newidx) != XA_RESULT_SUCCESS)
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_GetValue");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+
+ memset(pValue,0,valueSize);
+#ifdef _GSTREAMER_BACKEND_
+ /* needed size = size of struct + size of data - 1 (struct size already includes one char) */
+ neededsize = sizeof(XAMetadataInfo) + impl->currentTags.mdeValues[newidx]->size - 1;
+ if( valueSize<neededsize )
+ { /* cannot fit all of key data */
+ newdatasize = impl->currentTags.mdeValues[newidx]->size - (neededsize-valueSize);
+ DEBUG_ERR("XA_RESULT_BUFFER_INSUFFICIENT");
+ res = XA_RESULT_BUFFER_INSUFFICIENT;
+ }
+ else
+ {
+ newdatasize = impl->currentTags.mdeValues[newidx]->size;
+ res = XA_RESULT_SUCCESS;
+ }
+ /* copy data up to given size */
+ memcpy(pValue,impl->currentTags.mdeValues[newidx],valueSize-1);
+ /* ensure null-termination */
+#endif
+ memset(pValue->data+newdatasize-1,0,1);
+
+ pValue->size = newdatasize;
+
+ DEBUG_API_A1("<-XAMetadataExtractionItfImpl_GetValue (%d)",(int)res);
+ return res;
+}
+
+
+/*
+ * Adds a filter for a specific key
+ * @XAuint32 keySize
+ * Size in bytes, of the pKey parameter. Ignored if filtering by key is disabled
+ * @const void *pKey
+ * The key to filter by. The entire key must match. Ignored if filtering by key is disabled.
+ * @XAuint32 keyEncoding
+ * Character encoding of the pKey parameter. Ignored if filtering by key is disabled
+ * @const XAchar *pValueLangCountry
+ * Language / country code of the value to filter by. Ignored if filtering by language / country is disabled
+ * @XAuint32 valueEncoding
+ * Encoding of the value to filter by. Ignored if filtering by encoding is disabled
+ * @XAuint8 filterMask
+ * Bitmask indicating which criteria to filter by. Should be one of the XA_METADATA_FILTER macros
+ */
+XAresult XAMetadataExtractionItfImpl_AddKeyFilter(XAMetadataExtractionItf self,
+ XAuint32 keySize,
+ const void *pKey,
+ XAuint32 keyEncoding,
+ const XAchar *pValueLangCountry,
+ XAuint32 valueEncoding,
+ XAuint8 filterMask)
+{
+ XAresult res = XA_RESULT_SUCCESS;
+
+
+#ifdef _GSTREAMER_BACKEND_
+ XAMetadataExtractionItfImpl *impl = NULL;
+ const XAchar* parsedkey;
+ impl = GetImpl(self);
+#endif
+ DEBUG_API("->XAMetadataExtractionItfImpl_AddKeyFilter");
+
+#ifdef _GSTREAMER_BACKEND_
+ XAuint32 idx = 0;
+ XAuint8 matchMask = 0;
+ if( !impl )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-XAMetadataExtractionItfImpl_AddKeyFilter");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+ else
+ {
+ impl->filteringOn = XA_BOOLEAN_TRUE;
+ for(idx=0; idx < impl->currentTags.itemcount; idx++)
+ {
+ if((filterMask & XA_METADATA_FILTER_KEY) && pKey)
+ {
+ parsedkey = XAMetadataAdapt_ParseKhronosKey(pKey);
+ if( strcmp((char*)parsedkey,
+ (char*)impl->currentTags.mdeKeys[idx]->data) == 0 )
+ {
+ matchMask |= XA_METADATA_FILTER_KEY;
+ }
+ }
+ if(filterMask & XA_METADATA_FILTER_LANG && pValueLangCountry)
+ {
+ if( strcmp((char*)pValueLangCountry,
+ (char*)impl->currentTags.mdeKeys[idx]->langCountry) == 0 )
+ {
+ matchMask |= XA_METADATA_FILTER_LANG;
+ }
+ }
+ if(filterMask & XA_METADATA_FILTER_ENCODING)
+ {
+ if(keyEncoding==impl->currentTags.mdeKeys[idx]->encoding)
+ {
+ matchMask |= XA_METADATA_FILTER_ENCODING;
+ }
+ if(valueEncoding==impl->currentTags.mdeValues[idx]->encoding)
+ {
+ matchMask |= XA_METADATA_FILTER_ENCODING;
+ }
+ }
+ /* check if all filters apply */
+ if(filterMask == matchMask)
+ {
+ if(impl->tagmatchesfilter[idx] == XA_BOOLEAN_FALSE)
+ {
+ impl->tagmatchesfilter[idx] = XA_BOOLEAN_TRUE;
+ impl->filteredcount++;
+ }
+ }
+ /*reset matchmask*/
+ matchMask=0;
+ }
+ }
+#endif
+ DEBUG_API_A1("<-XAMetadataExtractionItfImpl_AddKeyFilter (%d)", (int)res);
+ return res;
+ }
+
+/*
+ * Clears the key filter
+ */
+XAresult XAMetadataExtractionItfImpl_ClearKeyFilter(XAMetadataExtractionItf self)
+{
+ XAMetadataExtractionItfImpl *impl = NULL;
+ XAresult res = XA_RESULT_SUCCESS;
+#ifdef _GSTREAMER_BACKEND_
+ XAuint32 idx = 0;
+#endif
+ DEBUG_API("->XAMetadataExtractionItfImpl_ClearKeyFilter");
+ impl = GetImpl(self);
+ if( !impl )
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ res = XA_RESULT_PARAMETER_INVALID;
+ }
+ else
+ {
+ if(impl->tagmatchesfilter)
+ {
+#ifdef _GSTREAMER_BACKEND_
+ for(idx=0; idx < impl->currentTags.itemcount; idx++)
+ {
+ impl->tagmatchesfilter[idx] = XA_BOOLEAN_FALSE;
+ }
+#endif
+ }
+ impl->filteredcount = 0;
+ impl->filteringOn = XA_BOOLEAN_FALSE;
+ }
+
+ DEBUG_API_A1("<-XAMetadataExtractionItfImpl_ClearKeyFilter (%d)", (int)res);
+ return res;
+}
+
+/*****************************************************************************
+ * XAMetadataExtractionItfImpl -specific methods
+ *****************************************************************************/
+#ifdef _GSTREAMER_BACKEND_
+/* XAMetadataExtractionItfImpl* XAMetadataExtractionItfImpl_Create()
+ * Description: Allocate and initialize XAMetadataExtractionItfImpl
+ */
+XAMetadataExtractionItfImpl* XAMetadataExtractionItfImpl_Create(XAAdaptationBaseCtx *adaptCtx)
+{
+ XAMetadataExtractionItfImpl *self = NULL;
+ DEBUG_API("->XAMetadataExtractionItfImpl_Create");
+
+ self = (XAMetadataExtractionItfImpl*)calloc(1,sizeof(XAMetadataExtractionItfImpl));
+
+ if( self )
+ {
+ /* init itf default implementation */
+ self->itf.GetItemCount = XAMetadataExtractionItfImpl_GetItemCount;
+ self->itf.GetKeySize = XAMetadataExtractionItfImpl_GetKeySize;
+ self->itf.GetKey = XAMetadataExtractionItfImpl_GetKey;
+ self->itf.GetValueSize = XAMetadataExtractionItfImpl_GetValueSize;
+ self->itf.GetValue = XAMetadataExtractionItfImpl_GetValue;
+ self->itf.AddKeyFilter = XAMetadataExtractionItfImpl_AddKeyFilter;
+ self->itf.ClearKeyFilter = XAMetadataExtractionItfImpl_ClearKeyFilter;
+
+ /* init variables */
+ self->filteredcount = 0;
+ self->filteringOn = XA_BOOLEAN_FALSE;
+
+ self->adaptCtx = adaptCtx;
+ XAAdaptationBase_AddEventHandler( adaptCtx, &XAMetadataExtractionItfImp_AdaptCb, XA_METADATAEVENTS, self );
+
+ self->self = self;
+ }
+
+ DEBUG_API("<-XAMetadataExtractionItfImpl_Create");
+ return self;
+}
+#endif
+/* void XAMetadataExtractionItfImpl_Free(XAMetadataExtractionItfImpl* self)
+ * Description: Free all resources reserved at XAMetadataExtractionItfImpl_Create
+ */
+void XAMetadataExtractionItfImpl_Free(XAMetadataExtractionItfImpl* self)
+{
+ DEBUG_API("->XAMetadataExtractionItfImpl_Free");
+ assert(self==self->self);
+#ifdef _GSTREAMER_BACKEND_
+ XAAdaptationBase_RemoveEventHandler( self->adaptCtx, &XAMetadataExtractionItfImp_AdaptCb );
+ XAMetadataAdapt_FreeImplTagList(&(self->currentTags), XA_BOOLEAN_TRUE);
+#endif
+ if(self->tagmatchesfilter)
+ {
+ free(self->tagmatchesfilter);
+ }
+ free(self);
+ DEBUG_API("<-XAMetadataExtractionItfImpl_Free");
+}
+
+#ifdef _GSTREAMER_BACKEND_
+/* With this method, adaptation infroms that new tags are found (e.g. if source,
+ * has changed, live stream contains metadata...)
+ */
+void XAMetadataExtractionItfImp_AdaptCb( void *pHandlerCtx, XAAdaptEvent *event )
+{
+ XAMetadataExtractionItfImpl* impl = NULL;
+ DEBUG_API("->XAMetadataExtractionItfImp_AdaptCb");
+ impl = (XAMetadataExtractionItfImpl*)pHandlerCtx;
+ if(!impl)
+ {
+ DEBUG_ERR("XAMetadataExtractionItfImp_AdaptCb, invalid context pointer!");
+ DEBUG_API("<-XAMetadataExtractionItfImp_AdaptCb");
+ return;
+ }
+ if( event && event->eventid == XA_ADAPT_MDE_TAGS_AVAILABLE )
+ {
+ /* get the tag list */
+ XAMetadataExtractionItfAdapt_FillTagList( impl->adaptCtx, &(impl->currentTags) );
+ if(impl->tagmatchesfilter)
+ {
+ free(impl->tagmatchesfilter);
+ }
+ impl->tagmatchesfilter = calloc(impl->currentTags.itemcount,sizeof(XAboolean));
+ impl->filteredcount = 0;
+ }
+ else
+ {
+ DEBUG_INFO("unhandled");
+ }
+ DEBUG_API("<-XAMetadataExtractionItfImp_AdaptCb");
+}
+
+#endif
+/* For given index over filtered array, return index over whole array
+ */
+XAresult CheckAndUnfilterIndex(XAMetadataExtractionItfImpl *impl,
+ XAuint32 oldidx, XAuint32 *newidx)
+{
+ DEBUG_API("->CheckAndUnfilterIndex");
+#ifdef _GSTREAMER_BACKEND_
+ if( impl->filteringOn )
+ {
+ XAint16 i=-1;
+ if(oldidx>=impl->filteredcount)
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-CheckAndUnfilterIndex");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+ *newidx=0;
+ while(*newidx<impl->currentTags.itemcount)
+ {
+ if(impl->tagmatchesfilter[*newidx]) i++;
+ if(i<oldidx) (*newidx)++;
+ else break;
+ }
+ if(*newidx==impl->currentTags.itemcount)
+ {
+ /* should not end up here */
+ *newidx=0;
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-CheckAndUnfilterIndex");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+ }
+ else
+ {
+ if(oldidx>=impl->currentTags.itemcount)
+ {
+ DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+ DEBUG_API("<-CheckAndUnfilterIndex");
+ return XA_RESULT_PARAMETER_INVALID;
+ }
+ *newidx=oldidx;
+ }
+#endif
+ DEBUG_API("<-CheckAndUnfilterIndex");
+ return XA_RESULT_SUCCESS;
+}
+
+