diff -r 71ca22bcf22a -r 5a06f39ad45b khronosfws/openmax_al/src/common/xametadataextractionitf.c --- /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 +#include +#include +#include + +#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( keySizecurrentTags.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( valueSizecurrentTags.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(*newidxcurrentTags.itemcount) + { + if(impl->tagmatchesfilter[*newidx]) i++; + if(icurrentTags.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; +} + +