void pv_metadata_engine_test::PrintSupportedMetaDataKeys()
{

    uint32 i = 0;

    fprintf(file, "\n\nOutput for file: %s\n", iFileName);
    fprintf(file, "\nMetadata key list (count=%d):\n", iMetadataKeyList.size());

    for (i = 0; i < iMetadataKeyList.size(); ++i)
    {
        fprintf(file, "Key %d: %s\n", (i + 1), iMetadataKeyList[i].get_cstr());
    }

    fprintf(file, "\nMetadata value list (count=%d):\n", iMetadataValueList.size());

    for (i = 0; i < iMetadataValueList.size(); ++i)
    {
        fprintf(file, "Value %d:\n   Key string: %s\n", (i + 1), iMetadataValueList[i].key);

        switch (GetValTypeFromKeyString(iMetadataValueList[i].key))
        {
            case PVMI_KVPVALTYPE_CHARPTR:
                fprintf(file, "   Value:%s\n", iMetadataValueList[i].value.pChar_value);
                break;

            case PVMI_KVPVALTYPE_WCHARPTR:
            {
                // Assume string is in UCS-2 encoding so convert to UTF-8
                char tmpstr[65];
                oscl_UnicodeToUTF8(iMetadataValueList[i].value.pWChar_value,
                                   oscl_strlen(iMetadataValueList[i].value.pWChar_value), tmpstr, 65);
                tmpstr[64] = '\0';
                fprintf(file, "   Value(in UTF-8, first 64 chars):%s\n", tmpstr);
            }
            break;

            case PVMI_KVPVALTYPE_UINT32:
                fprintf(file, "   Value:%d\n", iMetadataValueList[i].value.uint32_value);
                break;

            case PVMI_KVPVALTYPE_INT32:
                fprintf(file, "   Value:%d\n", iMetadataValueList[i].value.int32_value);
                break;

            case PVMI_KVPVALTYPE_UINT8:
                fprintf(file, "   Value:%d\n", iMetadataValueList[i].value.uint8_value);
                break;

            case PVMI_KVPVALTYPE_FLOAT:
                fprintf(file, "   Value:%f\n", iMetadataValueList[i].value.float_value);
                break;

            case PVMI_KVPVALTYPE_DOUBLE:
                fprintf(file, "   Value:%f\n", iMetadataValueList[i].value.double_value);
                break;

            case PVMI_KVPVALTYPE_BOOL:
                if (iMetadataValueList[i].value.bool_value)
                {
                    fprintf(file, "   Value:true(1)\n");
                }
                else
                {
                    fprintf(file, "   Value:false(0)\n");
                }
                break;

            default:
                fprintf(file, "   Value: UNKNOWN VALUE TYPE\n");
                break;
        }

        fprintf(file, "   Length:%d  Capacity:%d\n", iMetadataValueList[i].length, iMetadataValueList[i].capacity);
    }

}
PVMFStatus PVMFFileOutputNode::VerifyAndSetConfigParameter(PvmiKvp& aParameter, bool aSetParam)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFFileOutputNode::VerifyAndSetConfigParameter() In"));

    // Determine the valtype
    PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
    if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFFileOutputNode::VerifyAndSetConfigParameter() Valtype in key string unknown"));
        return PVMFErrNotSupported;
    }

    // Retrieve the fourth component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(3, aParameter.key, compstr);

    int32 fileoutput4ind;
    for (fileoutput4ind = 0; fileoutput4ind < FILEOUTPUTNODECONFIG_BASE_NUMKEYS; ++fileoutput4ind)
    {
        // Go through each component string at 4th level
        if (pv_mime_strcmp(compstr, (char*)(FileOutputNodeConfig_BaseKeys[fileoutput4ind].iString)) >= 0)
        {
            // Break out of the for loop
            break;
        }
    }

    if (FILEOUTPUTNODECONFIG_BASE_NUMKEYS <= fileoutput4ind)
    {
        // Match couldn't be found or non-leaf node specified
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFFileOutputNode::VerifyAndSetConfigParameter() Unsupported key or non-leaf node"));
        return PVMFErrNotSupported;
    }

    // Verify the valtype
    if (keyvaltype != FileOutputNodeConfig_BaseKeys[fileoutput4ind].iValueType)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFFileOutputNode::VerifyAndSetConfigParameter() Valtype does not match for key"));
        return PVMFErrNotSupported;
    }

    switch (fileoutput4ind)
    {
        case PARAMETER1: // "parameter1"
            // Change the parameter
            if (aSetParam)
            {
                // set the parameter here
            }
            break;

        case PARAMETER2: // "parameter2"
            // change the parameter
            if (aSetParam)
            {
                // set any parameter here
            }
            break;

        default:
            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFFileOutputNode::VerifyAndSetConfigParameter() Invalid index for file output node parameter"));
            return PVMFErrNotSupported;
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFFileOutputNode::VerifyAndSetConfigParameter() Out"));
    return PVMFSuccess;
}
PVMFStatus PVMFFileOutputNode::releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFFileOutputNode::releaseParameters()"));
    OSCL_UNUSED_ARG(aSession);

    if (aParameters == NULL || aNumElements < 1)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFFileOutputNode::releaseParameters() KVP list is NULL or number of elements is 0"));
        return PVMFErrArgument;
    }

    // Count the number of components and parameters in the key
    int compcount = pv_mime_string_compcnt(aParameters[0].key);
    // Retrieve the first component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(0, aParameters[0].key, compstr);

    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/file/output")) < 0) || compcount < 3)
    {
        // First 3 component should be "x-pvmf/file/output" and there must
        // be at least four components
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFFileOutputNode::releaseParameters() Unsupported key"));
        return PVMFErrNotSupported;
    }

    // Retrieve the third component from the key string
    pv_mime_string_extract_type(3, aParameters[0].key, compstr);

    // Go through each KVP and release memory for value if allocated from heap
    for (int32 ii = 0; ii < aNumElements; ++ii)
    {
        // Next check if it is a value type that allocated memory
        PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[ii].key);
        if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN)
        {
            PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[ii].key);
            if (PVMI_KVPVALTYPE_UNKNOWN == keyvaltype)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFFileOutputNode::releaseParameters() Valtype not specified in key string"));
                return PVMFErrNotSupported;
            }

            if (((PVMI_KVPVALTYPE_CHARPTR == keyvaltype) && NULL != (aParameters[ii].value.pChar_value)))
            {
                oscl_free(aParameters[ii].value.pChar_value);
                aParameters[ii].value.pChar_value = NULL;
            }
            else if (PVMI_KVPVALTYPE_KSV == keyvaltype && NULL != aParameters[ii].value.key_specific_value)
            {
                oscl_free(aParameters[ii].value.key_specific_value);
                aParameters[ii].value.key_specific_value = NULL;
            }
            else if (PVMI_KVPVALTYPE_RANGE_UINT32 == keyvaltype && NULL != aParameters[ii].value.key_specific_value)
            {
                range_uint32* rui32 = (range_uint32*)aParameters[ii].value.key_specific_value;
                aParameters[ii].value.key_specific_value = NULL;
                oscl_free(rui32);
            }
            // @TODO Add more types if file output node starts returning more types
        }
    }

    // file output node allocated its key strings in one chunk so just free the first key string ptr
    oscl_free(aParameters[0].key);

    // Free memory for the parameter list
    oscl_free(aParameters);
    aParameters = NULL;

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFFileOutputNode::releaseParameters() Out"));
    return PVMFSuccess;
}
PVMFStatus PVMp4FFComposerNode::VerifyAndSetConfigParameter(PvmiKvp& aParameter, bool aSetParam)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMp4FFComposerNode::VerifyAndSetConfigParameter() In"));

    // Determine the valtype
    PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
    if (PVMI_KVPVALTYPE_UNKNOWN == keyvaltype)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMp4FFComposerNode::VerifyAndSetConfigParameter() Valtype in key string unknown"));
        return PVMFErrNotSupported;// key is not supported here
    }

    // Retrieve the fourth component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(3, aParameter.key, compstr);

    int32 mp4comp4ind;
    for (mp4comp4ind = 0; mp4comp4ind < MP4COMPOSERNODECONFIG_BASE_NUMKEYS; ++mp4comp4ind)
    {
        // Go through each component string at 4th level
        if (pv_mime_strcmp(compstr, (char*)(MP4ComposerNodeConfig_BaseKeys[mp4comp4ind].iString)) >= 0)
        {
            // Break out of the for loop
            break;
        }
    }

    if (MP4COMPOSERNODECONFIG_BASE_NUMKEYS <= mp4comp4ind)
    {
        // Match couldn't be found or non-leaf node specified
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMp4FFComposerNode::VerifyAndSetConfigParameter() Unsupported key or non-leaf node"));
        return PVMFErrNotSupported;
    }

    // Verify the valtype
    if (keyvaltype != MP4ComposerNodeConfig_BaseKeys[mp4comp4ind].iValueType)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMp4FFComposerNode::VerifyAndSetConfigParameter() Valtype does not match for key"));
        return PVMFErrNotSupported;
    }

    switch (mp4comp4ind)
    {
        case PRESENTATION_TIMESCALE: // "presentation-timescale"
            // Change the parameter
            if (aSetParam)
            {
                iPresentationTimescale = aParameter.value.uint32_value;
            }
            break;

        case PV_CACHE_SIZE: // "pv-cache-size"
            // change the parameter
            if (aSetParam)
            {
                // set any parameter here
                iCacheSize = aParameter.value.uint32_value ;
            }
            break;
#ifdef _TEST_AE_ERROR_HANDLING
        case ERROR_START_ADDMEMFRAG:
            // change the parameter
            if (aSetParam)
            {
                // set any parameter here
                iErrorHandlingAddMemFrag = aParameter.value.bool_value ;
            }
            break;
        case ERROR_START_ADDTRACK:
            // change the parameter
            if (aSetParam)
            {
                // set any parameter here
                iErrorHandlingAddTrack = aParameter.value.bool_value ;
            }
            break;
        case ERROR_ADDTRACK: //error in AddTrack()
            if (aSetParam)
            {
                //char* paramstr = NULL;
                char* val_key = aParameter.value.pChar_value;
                if (pv_mime_strcmp(val_key, "PVMF_MIME_H264_VIDEO_MP4") == 0)
                {
                    iErrorAddTrack = PVMF_MIME_H264_VIDEO_MP4;
                }
                if (pv_mime_strcmp(val_key, "PVMF_MIME_3GPP_TIMEDTEXT") == 0)
                {
                    iErrorAddTrack = PVMF_MIME_3GPP_TIMEDTEXT;
                }
                if (pv_mime_strcmp(val_key, "PVMF_MIME_M4V") == 0)
                {
                    iErrorAddTrack = PVMF_MIME_M4V;
                }
                if (pv_mime_strcmp(val_key, "PVMF_MIME_H2631998") == 0)
                {
                    iErrorAddTrack = PVMF_MIME_H2631998;
                }
                if (pv_mime_strcmp(val_key, "PVMF_MIME_H2632000") == 0)
                {
                    iErrorAddTrack = PVMF_MIME_H2632000;
                }
                if (pv_mime_strcmp(val_key, "PVMF_MIME_AMR_IETF") == 0)
                {
                    iErrorAddTrack = PVMF_MIME_AMR_IETF;
                }
                if (pv_mime_strcmp(val_key, "PVMF_MIME_AMRWB_IETF") == 0)
                {
                    iErrorAddTrack = PVMF_MIME_AMRWB_IETF;
                }

            }
            break;
        case ERROR_NODE_CMD:
            if (aSetParam)
            {
                iErrorNodeCmd = aParameter.value.uint32_value;
            }
            break;
        case ERROR_CREATE_COMPOSER:
            if (aSetParam)
            {
                iErrorCreateComposer = aParameter.value.bool_value ;
            }
            break;
        case ERROR_RENDERTOFILE:
            if (aSetParam)
            {
                iErrorRenderToFile = aParameter.value.bool_value ;
            }
            break;
        case ERROR_ADD_SAMPLE:
            if (aSetParam)
            {
                char* paramstr = NULL;
                OSCL_HeapString<OsclMemAllocator> mode1 = "mode=filesize";
                OSCL_HeapString<OsclMemAllocator> mode2 = "mode=duration";

                if (pv_mime_string_parse_param(aParameter.key, mode1.get_str(), paramstr) > 0)
                {
                    iFileSize = aParameter.value.uint32_value;
                    iErrorAddSample = 1;
                }
                else if (pv_mime_string_parse_param(aParameter.key, mode2.get_str(), paramstr) > 0)
                {
                    iFileDuration = aParameter.value.uint32_value;
                    iErrorAddSample = 2;
                }

            }
            break;
        case ERROR_DATAPATH_STALL:
            if (aSetParam)
            {
                iErrorDataPathStall = aParameter.value.uint32_value;
            }
            break;
#endif
        default:
            OSCL_ASSERT(0);
    }

    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMp4FFComposerNode::VerifyAndSetConfigParameter() Out"));
    return PVMFSuccess;
}