diff -r a36789189b53 -r 095bea5f582e 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 Tue Aug 31 15:43:02 2010 +0300 @@ -0,0 +1,713 @@ +/* + * 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: Metadata Extraction Interface Implementation + * + */ + +#include +#include +#include +#include + +#include "xametadataextractionitf.h" +#include "xadebug.h" + +#include "xametadataadaptation.h" + +#include "xaadaptationmmf.h" +#include "xametadataadaptctxmmf.h" +#include "xamediaplayeradaptctxmmf.h" +#include "cmetadatautilityitf.h" + +/* 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; + } + +static void* GetMetadataUtilityContext(XAAdaptationMMFCtx* adaptCtx) + { + if (adaptCtx) + { + switch (adaptCtx->baseObj.ctxId) + { + case XAMediaPlayerAdaptation: + return ((XAMediaPlayerAdaptationMMFCtx*) adaptCtx)->mmfMetadataContext; + case XAMDAdaptation: + return ((XAMetadataAdaptationMMFCtx*) adaptCtx)->mmfContext; + default: + break; + } + + } + 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 + { + + if (impl->adaptCtx) + { + + if (impl->adaptCtx->fwtype == FWMgrFWMMF) + { + void *mmfCtx = GetMetadataUtilityContext( + (XAAdaptationMMFCtx*) impl->adaptCtx); + if (mmfCtx) + { + res = mmf_get_item_count(mmfCtx, pItemCount); + } + else + { + res = XA_RESULT_PARAMETER_INVALID; + } + } + else + { + if (impl->filteringOn) + { + *pItemCount = impl->filteredcount; + } + else + { + *pItemCount = impl->currentTags.itemcount; + } + res = XA_RESULT_SUCCESS; + } + } + else + { + res = XA_RESULT_INTERNAL_ERROR; + } + + 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; + + if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF) + { + void *mmfCtx = GetMetadataUtilityContext( + (XAAdaptationMMFCtx*) impl->adaptCtx); + if (mmfCtx) + { + res = mmf_get_key_size(mmfCtx, index, pKeySize); + } + else + { + res = XA_RESULT_PARAMETER_INVALID; + } + } + else + { + /* 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; + } + + /* size = size of struct + size of data - 1 (struct size already includes one char) */ + *pKeySize = sizeof(XAMetadataInfo) + + impl->currentTags.mdeKeys[newidx]->size - 1; + } + + 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; + + XAuint32 neededsize = 0; + + 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; + } + + memset(pKey, 0, keySize); + + if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF) + { + void *mmfCtx = GetMetadataUtilityContext( + (XAAdaptationMMFCtx*) impl->adaptCtx); + if (mmfCtx) + { + res = mmf_get_key(mmfCtx, index, keySize, pKey); + } + else + { + res = XA_RESULT_PARAMETER_INVALID; + } + } + else + { + + /* 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; + } + + /* 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 */ + + 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; + + if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF) + { + void *mmfCtx = GetMetadataUtilityContext( + (XAAdaptationMMFCtx*) impl->adaptCtx); + if (mmfCtx) + { + res = mmf_get_value_size(mmfCtx, index, pValueSize); + } + else + { + res = XA_RESULT_PARAMETER_INVALID; + } + } + else + { + /* 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; + } + + /* size = size of struct + size of data - 1 (struct size already includes one char) */ + *pValueSize = sizeof(XAMetadataInfo) + + impl->currentTags.mdeValues[newidx]->size - 1; + } + + 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; + + XAuint32 neededsize = 0; + + 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; + } + + memset(pValue, 0, valueSize); + + if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF) + { + void *mmfCtx = GetMetadataUtilityContext( + (XAAdaptationMMFCtx*) impl->adaptCtx); + if (mmfCtx) + { + res = mmf_get_value(mmfCtx, index, valueSize, pValue); + } + else + { + res = XA_RESULT_PARAMETER_INVALID; + } + } + else + { + /* 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; + } + + /* 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 */ + + 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; + + XAuint32 idx = 0; + XAuint8 matchMask = 0; + + XAMetadataExtractionItfImpl *impl = NULL; + const XAchar* parsedkey; + impl = GetImpl(self); + + DEBUG_API("->XAMetadataExtractionItfImpl_AddKeyFilter"); + + if (!impl) + { + DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); + DEBUG_API("<-XAMetadataExtractionItfImpl_AddKeyFilter"); + return XA_RESULT_PARAMETER_INVALID; + } + else + { + + if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF) + { + DEBUG_API("<-XAMetadataExtractionItfImpl_AddKeyFilter Not Supported in MMF"); + res = 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; + } + } + } + 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; + + XAuint32 idx = 0; + + DEBUG_API("->XAMetadataExtractionItfImpl_ClearKeyFilter"); + impl = GetImpl(self); + if (!impl) + { + DEBUG_ERR("XA_RESULT_PARAMETER_INVALID"); + res = XA_RESULT_PARAMETER_INVALID; + } + else + { + + if (impl->adaptCtx && impl->adaptCtx->fwtype == FWMgrFWMMF) + { + DEBUG_API("<-XAMetadataExtractionItfImpl_ClearKeyFilter Not Supported in MMF"); + res = XA_RESULT_PARAMETER_INVALID; + } + else + { + if (impl->tagmatchesfilter) + { + + for (idx = 0; idx < impl->currentTags.itemcount; idx++) + { + impl->tagmatchesfilter[idx] = XA_BOOLEAN_FALSE; + } + + } + impl->filteredcount = 0; + impl->filteringOn = XA_BOOLEAN_FALSE; + } + } + + DEBUG_API_A1("<-XAMetadataExtractionItfImpl_ClearKeyFilter (%d)", (int)res); + return res; + } + +/***************************************************************************** + * XAMetadataExtractionItfImpl -specific methods + *****************************************************************************/ + +/* 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; + + if (self->adaptCtx->fwtype != FWMgrFWMMF) + { + XAAdaptationBase_AddEventHandler(adaptCtx, + &XAMetadataExtractionItfImp_AdaptCb, XA_METADATAEVENTS, + self); + } + + self->self = self; + } + + DEBUG_API("<-XAMetadataExtractionItfImpl_Create"); + return self; + } + +/* 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); + + if (self->adaptCtx->fwtype != FWMgrFWMMF) + { + XAAdaptationBase_RemoveEventHandler(self->adaptCtx, + &XAMetadataExtractionItfImp_AdaptCb); + XAMetadataAdapt_FreeImplTagList(&(self->currentTags), XA_BOOLEAN_TRUE); + + if (self->tagmatchesfilter) + { + free(self->tagmatchesfilter); + } + } + + free(self); + DEBUG_API("<-XAMetadataExtractionItfImpl_Free"); + } + +/* 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( + (XAAdaptationGstCtx*) 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"); + } + +/* For given index over filtered array, return index over whole array + */ +XAresult CheckAndUnfilterIndex(XAMetadataExtractionItfImpl *impl, + XAuint32 oldidx, XAuint32 *newidx) + { + DEBUG_API("->CheckAndUnfilterIndex"); + + 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; + } + + DEBUG_API("<-CheckAndUnfilterIndex"); + return XA_RESULT_SUCCESS; + } +