Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 // -*- c++ -*-
     19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     20 //
     21 //                 M P 3   F I L E   P A R S E R
     22 //
     23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     24 
     25 
     26 /**
     27  *  @file imp3ff.cpp
     28  *  @brief This file contains the implementation of the MP3 File Format
     29  *  interface. It initializes and maintains the MP3 File Format Library
     30  */
     31 
     32 //----------------------------------------------------------------------
     33 // Include Files
     34 //----------------------------------------------------------------------
     35 
     36 #include "imp3ff.h"
     37 #include "mp3fileio.h"
     38 #include "mp3utils.h"
     39 #include "mp3parser.h"
     40 #include "oscl_mem.h"
     41 #include "oscl_utf8conv.h"
     42 #include "pvmi_kvp_util.h"
     43 #include "pvmi_kvp.h"
     44 #include "pvmf_format_type.h"
     45 #include "pv_mime_string_utils.h"
     46 // Constant character strings for metadata keys
     47 static const char PVMP3METADATA_TITLE_KEY[] = "title";
     48 static const char PVMP3METADATA_ARTIST_KEY[] = "artist";
     49 static const char PVMP3METADATA_ALBUM_KEY[] = "album";
     50 static const char PVMP3METADATA_YEAR_KEY[] = "year";
     51 static const char PVMP3METADATA_COMMENT_KEY[] = "comment";
     52 static const char PVMP3METADATA_COPYRIGHT_KEY[] = "copyright";
     53 static const char PVMP3METADATA_GENRE_KEY[] = "genre";
     54 static const char PVMP3METADATA_TRACKINFO_TRACKNUMBER_KEY[] = "track-info/track-number";
     55 static const char PVMP3METADATA_DURATION_KEY[] = "duration";
     56 static const char PVMP3METADATA_DURATION_FROM_METADATA_KEY[] = "duration-from-metadata";
     57 static const char PVMP3METADATA_NUMTRACKS_KEY[] = "num-tracks";
     58 static const char PVMP3METADATA_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate";
     59 static const char PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY[] = "track-info/sample-rate";
     60 static const char PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY[] = "track-info/audio/format";
     61 static const char PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY[] = "track-info/audio/channels";
     62 static const char PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY[] = "track-info/audio/channel-mode";
     63 static const char PVMP3METADATA_BITRATE_KEY[] = "bit-rate";
     64 static const char PVMP3METADATA_SAMPLERATE_KEY[] = "sample-rate";
     65 static const char PVMP3METADATA_FORMAT_KEY[] = "format";
     66 static const char PVMP3METADATA_CHANNELS_KEY[] = "channels";
     67 static const char PVMP3METADATA_CHANNEL_MODE_KEY[] = "channel-mode";
     68 static const char PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY[] = "random-access-denied";
     69 static const char PVMP3METADATA_SEMICOLON[] = ";";
     70 static const char PVMP3METADATA_CHARENCUTF8[] = "char-encoding=UTF8";
     71 static const char PVMP3METADATA_CHARENCUTF16BE[] = "char-encoding=UTF16BE";
     72 static const char PVMP3METADATA_FORMATID3V1[] = "format=id3v1";
     73 static const char PVMP3METADATA_FORMATID3V11[] = "format=id3v1.1";
     74 static const char PVMP3METADATA_TIMESCALE1000[] = "timescale=1000";
     75 static const char PVMP3METADATA_INDEX0[] = "index=0";
     76 static const char PVMP3METADATA_UNKNOWN[] = "unknown";
     77 static const char PVMP3METADATA_COMPUTE[] = "compute=true";
     78 
     79 // Use default DLL entry point for Symbian
     80 #include "oscl_dll.h"
     81 OSCL_DLL_ENTRY_POINT_DEFAULT()
     82 
     83 //----------------------------------------------------------------------
     84 // Defines
     85 //----------------------------------------------------------------------
     86 
     87 //----------------------------------------------------------------------
     88 // Type Declarations
     89 //----------------------------------------------------------------------
     90 
     91 //----------------------------------------------------------------------
     92 // Global Constant Definitions
     93 //----------------------------------------------------------------------
     94 
     95 //----------------------------------------------------------------------
     96 // Global Data Definitions
     97 //----------------------------------------------------------------------
     98 
     99 //----------------------------------------------------------------------
    100 // Static Variable Definitions
    101 //----------------------------------------------------------------------
    102 
    103 
    104 OSCL_EXPORT_REF IMpeg3File::IMpeg3File(OSCL_wString& filename, MP3ErrorType &bSuccess, Oscl_FileServer* fileServSession, PVMFCPMPluginAccessInterfaceFactory*aCPM, OsclFileHandle*aFileHandle, bool enableCRC) :
    105         pMP3Parser(NULL)
    106 {
    107     bSuccess = MP3_SUCCESS;
    108 
    109     // Initialize the metadata related variables
    110     iAvailableMetadataKeys.reserve(14);
    111     iAvailableMetadataKeys.clear();
    112 
    113     iEnableCrcCalc = enableCRC;
    114     // Open the specified MP3 file
    115     iMP3File.SetCPM(aCPM);
    116     iMP3File.SetFileHandle(aFileHandle);
    117     if (iMP3File.Open(filename.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *fileServSession) != 0)
    118     {
    119         bSuccess = MP3_FILE_OPEN_ERR;
    120         return;
    121     }
    122 
    123     if (!aCPM)
    124     {
    125         iScanFP.SetCPM(aCPM);
    126         iScanFP.SetFileHandle(aFileHandle);
    127         if (iScanFP.Open(filename.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *fileServSession) != 0)
    128         {
    129             bSuccess = MP3_FILE_OPEN_ERR;
    130             return;
    131         }
    132     }
    133 
    134     int32 leavecode = OsclErrNone;
    135     OSCL_TRY(leavecode, pMP3Parser = OSCL_NEW(MP3Parser, (&iMP3File)););
    136     if (pMP3Parser && OsclErrNone == leavecode)
    137         bSuccess = MP3_SUCCESS;
    138     else
    139         bSuccess = MP3_ERROR_UNKNOWN;
    140 }
    141 
    142 OSCL_EXPORT_REF IMpeg3File::IMpeg3File(MP3ErrorType &bSuccess): pMP3Parser(NULL)
    143 {
    144     int32 leavecode = OsclErrNone;
    145     OSCL_TRY(leavecode, pMP3Parser = OSCL_NEW(MP3Parser, ()););
    146     if (pMP3Parser && OsclErrNone == leavecode)
    147         bSuccess = MP3_SUCCESS;
    148     else
    149         bSuccess = MP3_ERROR_UNKNOWN;
    150 }
    151 
    152 OSCL_EXPORT_REF IMpeg3File::~IMpeg3File()
    153 {
    154     iAvailableMetadataKeys.clear();
    155 
    156     if (pMP3Parser != NULL)
    157     {
    158         OSCL_DELETE(pMP3Parser);
    159         pMP3Parser = NULL;
    160     }
    161 
    162     if (iScanFP.IsOpen())
    163     {
    164         iScanFP.Close();
    165     }
    166     if (iMP3File.IsOpen())
    167     {
    168         iMP3File.Close();
    169     }
    170 }
    171 
    172 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::ParseMp3File()
    173 {
    174     MP3ErrorType mp3Err = MP3_SUCCESS;
    175 
    176     // Parse the mp3 clip
    177     mp3Err = pMP3Parser->ParseMP3File(&iMP3File, iEnableCrcCalc);
    178     if (mp3Err == MP3_INSUFFICIENT_DATA)
    179     {
    180         // not enough data was available to parse the clip
    181         return mp3Err;
    182     }
    183     else if (mp3Err != MP3_SUCCESS)
    184     {
    185         // some other error occured while parsing the clip.
    186         // parsing can not proceed further
    187         OSCL_DELETE(pMP3Parser);
    188         pMP3Parser = NULL;
    189         iMP3File.Close();
    190         return mp3Err;
    191     }
    192     else
    193     {
    194         // parsing of clip was successful, id3 frames can now be fetched
    195         PvmiKvpSharedPtrVector id3Frames;
    196         pMP3Parser->GetMetaData(id3Frames);
    197 
    198         // Populate metadata key list vector
    199         int32 leavecode = OsclErrNone;
    200         for (uint32 p = 0; p < id3Frames.size(); p++)
    201         {
    202             OSCL_HeapString<OsclMemAllocator> keystr((const char *)((*id3Frames[p]).key), oscl_strlen((const char *)((*id3Frames[p]).key)));
    203             leavecode = PushKVPKey(keystr, iAvailableMetadataKeys);
    204             if (OsclErrNone != leavecode)
    205             {
    206                 return MP3_ERR_NO_MEMORY;
    207             }
    208 
    209         }
    210 
    211         bool metadataDuration = true;
    212         if (pMP3Parser->GetDuration(metadataDuration) > 0)
    213         {
    214             leavecode = OsclErrNone;
    215             leavecode = PushKVPKey(PVMP3METADATA_DURATION_FROM_METADATA_KEY, iAvailableMetadataKeys);
    216             if (OsclErrNone != leavecode)
    217             {
    218                 return MP3_ERR_NO_MEMORY;
    219             }
    220         }
    221 
    222         // Following keys are available when the MP3 file has been parsed
    223         leavecode = OsclErrNone;
    224         leavecode = PushKVPKey(PVMP3METADATA_DURATION_KEY, iAvailableMetadataKeys);
    225         if (OsclErrNone != leavecode)
    226         {
    227             return MP3_ERR_NO_MEMORY;
    228         }
    229 
    230         leavecode = OsclErrNone;
    231         leavecode = PushKVPKey(PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY, iAvailableMetadataKeys);
    232         if (OsclErrNone != leavecode)
    233         {
    234             return MP3_ERR_NO_MEMORY;
    235         }
    236 
    237         leavecode = OsclErrNone;
    238         leavecode = PushKVPKey(PVMP3METADATA_NUMTRACKS_KEY, iAvailableMetadataKeys);
    239         if (OsclErrNone != leavecode)
    240         {
    241             return MP3_ERR_NO_MEMORY;
    242         }
    243 
    244         leavecode = OsclErrNone;
    245         leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY, iAvailableMetadataKeys);
    246         if (OsclErrNone != leavecode)
    247         {
    248             return MP3_ERR_NO_MEMORY;
    249         }
    250 
    251         MP3ContentFormatType mp3info;
    252         if (GetConfigDetails(mp3info) == MP3_SUCCESS)
    253         {
    254             if (mp3info.Bitrate > 0)
    255             {
    256                 leavecode = OsclErrNone;
    257                 leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_BITRATE_KEY, iAvailableMetadataKeys);
    258                 if (OsclErrNone != leavecode)
    259                 {
    260                     return MP3_ERR_NO_MEMORY;
    261                 }
    262             }
    263             if (mp3info.SamplingRate > 0)
    264             {
    265                 leavecode = OsclErrNone;
    266                 leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY, iAvailableMetadataKeys);
    267                 if (OsclErrNone != leavecode)
    268                 {
    269                     return MP3_ERR_NO_MEMORY;
    270                 }
    271             }
    272             if (mp3info.NumberOfChannels > 0)
    273             {
    274                 leavecode = OsclErrNone;
    275                 leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY, iAvailableMetadataKeys);
    276                 if (OsclErrNone != leavecode)
    277                 {
    278                     return MP3_ERR_NO_MEMORY;
    279                 }
    280             }
    281             // valid channel mode is present
    282             if (mp3info.ChannelMode <= MP3_CHANNEL_MODE_MONO)
    283             {
    284                 leavecode = 0;
    285                 leavecode = PushKVPKey(PVMP3METADATA_CHANNEL_MODE_KEY, iAvailableMetadataKeys);
    286                 if (OsclErrNone != leavecode)
    287                 {
    288                     return MP3_ERR_NO_MEMORY;
    289                 }
    290             }
    291         }
    292     }
    293     return mp3Err;
    294 }
    295 
    296 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetConfigDetails(MP3ContentFormatType &mp3Config)
    297 {
    298     if (pMP3Parser)
    299     {
    300         MP3ConfigInfoType mp3ConfigHdr;
    301         if (pMP3Parser->GetMP3FileHeader(&mp3ConfigHdr))
    302         {
    303             mp3Config.Bitrate          = mp3ConfigHdr.BitRate;
    304             mp3Config.FrameSize        = mp3ConfigHdr.FrameLengthInBytes;
    305             mp3Config.NumberOfChannels = mp3ConfigHdr.NumberOfChannels;
    306             mp3Config.SamplingRate     = mp3ConfigHdr.SamplingRate;
    307             mp3Config.FrameSizeUnComp  = mp3ConfigHdr.FrameSizeUnComp;
    308             mp3Config.FileSizeInBytes  = pMP3Parser->GetFileSize();
    309             mp3Config.ChannelMode      = pMP3Parser->GetChannelMode();
    310             return MP3_SUCCESS;
    311         }
    312     }
    313     return MP3_ERROR_UNKNOWN;
    314 }
    315 
    316 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetNextMediaSample(uint8 *buf, uint32 size, uint32& framesize, uint32& timestamp)
    317 {
    318     if (pMP3Parser != NULL)
    319     {
    320         return (pMP3Parser->GetNextMediaSample(buf, size, framesize, timestamp));
    321     }
    322     else
    323     {
    324         return MP3_ERROR_UNKNOWN;
    325     }
    326 }
    327 
    328 OSCL_EXPORT_REF uint32 IMpeg3File::ResetPlayback(uint32 time)
    329 {
    330     if (pMP3Parser != NULL)
    331     {
    332         return pMP3Parser->SeekToTimestamp(time);
    333     }
    334     else
    335     {
    336         return 0;
    337     }
    338 }
    339 
    340 OSCL_EXPORT_REF int32 IMpeg3File::GetNextBundledAccessUnits(uint32 *n, GAU *pgau, MP3ErrorType &err)
    341 {
    342     if (pMP3Parser != NULL)
    343     {
    344         return pMP3Parser->GetNextBundledAccessUnits(n, pgau, err);
    345     }
    346     else
    347     {
    348         return 0;
    349     }
    350 }
    351 
    352 OSCL_EXPORT_REF int32 IMpeg3File::PeekNextBundledAccessUnits(uint32 *n, MediaMetaInfo *mInfo)
    353 {
    354     if (pMP3Parser != NULL)
    355     {
    356         return pMP3Parser->PeekNextBundledAccessUnits(n, mInfo);
    357     }
    358     else
    359     {
    360         return 0;
    361     }
    362 }
    363 
    364 OSCL_EXPORT_REF int32 IMpeg3File::GetNumTracks()
    365 {
    366     return 1;
    367 }
    368 
    369 OSCL_EXPORT_REF uint32 IMpeg3File::GetDuration() const
    370 {
    371     if (pMP3Parser != NULL)
    372     {
    373         return pMP3Parser->GetDuration();
    374     }
    375     else
    376     {
    377         return 0;
    378     }
    379 }
    380 
    381 OSCL_EXPORT_REF int32 IMpeg3File::ConvertSizeToTime(uint32 aFileSize, uint32& aNPTInMS) const
    382 {
    383     if (pMP3Parser != NULL)
    384     {
    385         return pMP3Parser->ConvertSizeToTime(aFileSize, aNPTInMS);
    386     }
    387     else
    388     {
    389         return -1;
    390     }
    391 }
    392 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetMetadataSize(uint32 &aSize)
    393 {
    394     if (pMP3Parser != NULL)
    395     {
    396         return pMP3Parser->GetMetadataSize(aSize);
    397     }
    398     return MP3_ERROR_UNKNOWN;
    399 }
    400 
    401 OSCL_EXPORT_REF uint32 IMpeg3File::GetMinBytesRequired(bool aNextBytes)
    402 {
    403     if (pMP3Parser != NULL)
    404     {
    405         return pMP3Parser->GetMinBytesRequired(aNextBytes);
    406     }
    407     return 0;
    408 }
    409 
    410 OSCL_EXPORT_REF uint32 IMpeg3File::GetTimestampForCurrentSample()
    411 {
    412     if (pMP3Parser != NULL)
    413     {
    414         return pMP3Parser->GetTimestampForCurrentSample();
    415     }
    416     else
    417     {
    418         return 0;
    419     }
    420 }
    421 
    422 OSCL_EXPORT_REF uint32  IMpeg3File::SeekToTimestamp(uint32 timestamp)
    423 {
    424     if (pMP3Parser != NULL)
    425     {
    426         return pMP3Parser->SeekToTimestamp(timestamp);
    427     }
    428     else
    429     {
    430         return 0;
    431     }
    432 }
    433 
    434 OSCL_EXPORT_REF uint32  IMpeg3File::SeekPointFromTimestamp(uint32& timestamp)
    435 {
    436     if (pMP3Parser != NULL)
    437     {
    438         return pMP3Parser->SeekPointFromTimestamp(timestamp);
    439     }
    440     else
    441     {
    442         return 0;
    443     }
    444 }
    445 
    446 OSCL_EXPORT_REF uint32  IMpeg3File::GetFileOffsetForAutoResume(uint32& timestamp)
    447 {
    448     if (pMP3Parser != NULL)
    449     {
    450         return pMP3Parser->GetFileOffsetForAutoResume(timestamp);
    451     }
    452     else
    453     {
    454         return 0;
    455     }
    456 }
    457 
    458 OSCL_EXPORT_REF uint32 IMpeg3File::GetTimescale() const
    459 {
    460     return 1000;
    461 }
    462 
    463 OSCL_EXPORT_REF uint8 IMpeg3File::RandomAccessDenied()
    464 {
    465     return false;
    466 }
    467 
    468 OSCL_EXPORT_REF int32 IMpeg3File::GetNumSampleEntries()
    469 {
    470     if (pMP3Parser != NULL)
    471     {
    472         return pMP3Parser->GetSampleCountInFile();
    473     }
    474     else
    475     {
    476         return 0;
    477     }
    478 }
    479 
    480 OSCL_EXPORT_REF int32  IMpeg3File::GetMaxBufferSizeDB()
    481 {
    482     if (pMP3Parser != NULL)
    483     {
    484         return pMP3Parser->GetMaximumDecodeBufferSize();
    485     }
    486     else
    487     {
    488         return 0;
    489     }
    490 }
    491 
    492 OSCL_EXPORT_REF uint8 const * IMpeg3File::GetDecoderSpecificInfoContent() const
    493 {
    494     if (pMP3Parser != NULL)
    495     {
    496         return pMP3Parser->GetDecoderSpecificInfoContent();
    497     }
    498     else
    499     {
    500         return 0;
    501     }
    502 }
    503 
    504 OSCL_EXPORT_REF uint32 IMpeg3File::GetDecoderSpecificInfoSize()
    505 {
    506     if (pMP3Parser != NULL)
    507     {
    508         return pMP3Parser->GetDecoderSpecificInfoSize();
    509     }
    510     else
    511     {
    512         return 0;
    513     }
    514 }
    515 
    516 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::SetFileSize(const uint32 aFileSize)
    517 {
    518     MP3ErrorType errCode = MP3_ERROR_UNKNOWN;
    519     if (pMP3Parser != NULL)
    520     {
    521         errCode = pMP3Parser->SetFileSize(aFileSize);
    522     }
    523     return errCode;
    524 }
    525 
    526 OSCL_EXPORT_REF uint32 IMpeg3File::GetNumMetadataKeys(char* aQueryKeyString)
    527 {
    528     uint32 num_entries = 0;
    529 
    530     if (aQueryKeyString == NULL)
    531     {
    532         // No query key so just return all the available keys
    533         num_entries = iAvailableMetadataKeys.size();
    534     }
    535     else
    536     {
    537         // Determine the number of metadata keys based on the query key string provided
    538         for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
    539         {
    540             // Check if the key matches the query key
    541             if (oscl_strstr(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) != NULL)
    542             {
    543                 num_entries++;
    544             }
    545         }
    546     }
    547 
    548     return num_entries;
    549 }
    550 
    551 OSCL_EXPORT_REF uint32 IMpeg3File::GetNumMetadataValues(PVMFMetadataList& aKeyList)
    552 {
    553     PvmiKvpSharedPtrVector iFrame;
    554 
    555     uint32 numKeys = aKeyList.size();
    556     if (numKeys == 0)
    557     {
    558         aKeyList = iAvailableMetadataKeys;
    559         numKeys = aKeyList.size();
    560     }
    561 
    562     uint32 numvalentries = 0;
    563     for (uint32 lcv = 0; lcv < numKeys; lcv++)
    564     {
    565         if (pMP3Parser->IsID3Frame(aKeyList[lcv]))
    566         {
    567             ++numvalentries;
    568         }
    569         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_KEY) == 0)
    570         {
    571             // Duration
    572             if (pMP3Parser)
    573             {
    574                 // Increment the counter for the number of values found so far
    575                 ++numvalentries;
    576             }
    577         }
    578         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY) == 0)
    579         {
    580             if (pMP3Parser)
    581             {
    582                 // Increment the counter for the number of values found so far
    583                 ++numvalentries;
    584             }
    585         }
    586         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_NUMTRACKS_KEY) == 0)
    587         {
    588             // Number of tracks
    589             if (pMP3Parser)
    590             {
    591                 // Increment the counter for the number of values found so far
    592                 ++numvalentries;
    593             }
    594         }
    595         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_BITRATE_KEY) == 0 ||
    596                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_BITRATE_KEY) == 0)
    597         {
    598             // Bitrate
    599             MP3ContentFormatType mp3info;
    600             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
    601             {
    602                 // Increment the counter for the number of values found so far
    603                 ++numvalentries;
    604             }
    605         }
    606         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_SAMPLERATE_KEY) == 0 ||
    607                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) == 0)
    608         {
    609             // Sampling rate
    610             MP3ContentFormatType mp3info;
    611             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
    612             {
    613                 // Increment the counter for the number of values found so far
    614                 ++numvalentries;
    615             }
    616         }
    617         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_FORMAT_KEY) == 0 ||
    618                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0)
    619         {
    620             // Format
    621             // Increment the counter for the number of values found so far
    622             ++numvalentries;
    623         }
    624         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNELS_KEY) == 0 ||
    625                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) == 0)
    626         {
    627             // Channels
    628             MP3ContentFormatType mp3info;
    629             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
    630             {
    631                 // Increment the counter for the number of values found so far
    632                 ++numvalentries;
    633             }
    634         }
    635         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNEL_MODE_KEY) == 0 ||
    636                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) == 0)
    637         {
    638             // Channel mode
    639             MP3ContentFormatType mp3info;
    640             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
    641             {
    642                 // Increment the counter for the number of values found so far
    643                 ++numvalentries;
    644             }
    645         }
    646     }  // End of for loop
    647     return numvalentries;
    648 }
    649 
    650 OSCL_EXPORT_REF PVMFStatus IMpeg3File::GetMetadataKeys(PVMFMetadataList& aKeyList, uint32 aStartingKeyIndex, int32 aMaxKeyEntries, char* aQueryKeyString)
    651 {
    652     // Check parameters
    653     if ((aStartingKeyIndex > (iAvailableMetadataKeys.size() - 1)) || aMaxKeyEntries == 0)
    654     {
    655         // Invalid starting index and/or max entries
    656         return PVMFErrArgument;
    657     }
    658 
    659     // Copy the requested keys
    660     uint32 num_entries = 0;
    661     int32 num_added = 0;
    662     int32 leavecode = OsclErrNone;
    663     for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
    664     {
    665         if (aQueryKeyString == NULL)
    666         {
    667             // No query key so this key is counted
    668             ++num_entries;
    669             if (num_entries > aStartingKeyIndex)
    670             {
    671                 // Past the starting index so copy the key
    672                 leavecode = OsclErrNone;
    673                 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv].get_cstr(), aKeyList);
    674                 if (OsclErrNone != leavecode)
    675                 {
    676                     return PVMFErrNoMemory;
    677                 }
    678                 num_added++;
    679             }
    680         }
    681         else
    682         {
    683             // Check if the key matches the query key
    684             if (oscl_strstr(iAvailableMetadataKeys[lcv].get_cstr(), aQueryKeyString) != NULL)
    685             {
    686                 // This key is counted
    687                 ++num_entries;
    688                 if (num_entries > aStartingKeyIndex)
    689                 {
    690                     // Past the starting index so copy the key
    691                     leavecode = OsclErrNone;
    692                     leavecode = PushKVPKey(iAvailableMetadataKeys[lcv].get_cstr(), aKeyList);
    693                     if (OsclErrNone != leavecode)
    694                     {
    695                         return PVMFErrNoMemory;
    696                     }
    697                     num_added++;
    698                 }
    699             }
    700         }
    701 
    702         // Check if max number of entries have been copied
    703         if (aMaxKeyEntries > 0 && num_added >= aMaxKeyEntries)
    704         {
    705             break;
    706         }
    707     }
    708 
    709     return PVMFSuccess;
    710 }
    711 
    712 OSCL_EXPORT_REF PVMFStatus IMpeg3File::GetMetadataValues(PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
    713         uint32 aStartingValueIndex, int32 aMaxValueEntries)
    714 {
    715     uint32 numKeys = aKeyList.size();
    716     PvmiKvpSharedPtrVector iFrame;
    717     PVMFMetadataList parsedKeys;
    718     if (numKeys == 0 || aStartingValueIndex > (numKeys - 1) || aMaxValueEntries == 0)
    719     {
    720         return PVMFErrArgument;
    721     }
    722 
    723     uint32 numvalentries = 0;
    724     int32 numentriesadded = 0;
    725     bool gotvalue = false;
    726     uint32 lcv = 0;
    727     for (lcv = 0; lcv < numKeys; lcv++)
    728     {
    729         //check if this key has already been parsed.
    730         for (uint32 pks = 0; pks < parsedKeys.size(); pks++)
    731         {
    732             if (pv_mime_strcmp(parsedKeys[pks].get_cstr(), aKeyList[lcv].get_cstr()) >= 0)
    733             {
    734                 gotvalue = true; //key already parsed.
    735                 break;
    736             }
    737         }
    738 
    739         if (gotvalue)   //get next key since this key has already been parsed.
    740         {
    741             gotvalue = false;
    742             continue;
    743         }
    744         pMP3Parser->GetMetaData(aKeyList[lcv], iFrame);
    745         if (iFrame.size() > 1) //multiple id3 frames exist for this key.
    746         {
    747             parsedKeys.push_back(aKeyList[lcv]);
    748         }
    749 
    750         while (iFrame.size() > 0)
    751         {
    752             PvmiKvp KeyVal;
    753             KeyVal.key = NULL;
    754             KeyVal.length = 0;
    755             char *key = (*(iFrame.back())).key;
    756             int32 len = (*(iFrame.back())).length;
    757 
    758             ++numvalentries;
    759 
    760             int32 leavecode = OsclErrNone;
    761             KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, oscl_strlen(key) + 1);
    762 
    763             if (OsclErrNone != leavecode)
    764             {
    765                 // allocation failed
    766                 return PVMFErrNoMemory;
    767             }
    768 
    769             oscl_strncpy(KeyVal.key , key, oscl_strlen(key) + 1);
    770             KeyVal.length = len;
    771             KeyVal.capacity = (*(iFrame.back())).capacity;
    772 
    773             if (KeyVal.length > 0)
    774             {
    775                 PvmiKvpValueType ValueType = GetValTypeFromKeyString(key);
    776                 leavecode = OsclErrNone;
    777                 switch (ValueType)
    778                 {
    779 
    780                     case PVMI_KVPVALTYPE_WCHARPTR:
    781                         KeyVal.value.pWChar_value = (oscl_wchar*) AllocateKVPKeyArray(leavecode, ValueType, len);
    782                         oscl_strncpy(KeyVal.value.pWChar_value , (*(iFrame.back())).value.pWChar_value, len);
    783                         KeyVal.value.pWChar_value[len] = 0;
    784                         break;
    785                     case PVMI_KVPVALTYPE_CHARPTR:
    786                         KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode, ValueType, len);
    787                         oscl_strncpy(KeyVal.value.pChar_value , (*(iFrame.back())).value.pChar_value, len);
    788                         KeyVal.value.pChar_value[len] = 0;
    789                         break;
    790                     case PVMI_KVPVALTYPE_UINT8PTR:
    791                         KeyVal.value.pUint8_value = (uint8*) AllocateKVPKeyArray(leavecode, ValueType, len);
    792                         oscl_memcpy(KeyVal.value.pUint8_value, (uint8*)(*(iFrame.back())).value.pUint8_value, len);
    793                         break;
    794                     case PVMI_KVPVALTYPE_UINT32:
    795                         KeyVal.value.uint32_value = (*(iFrame.back())).value.uint32_value;
    796                         break;
    797                     case PVMI_KVPVALTYPE_KSV:
    798                         KeyVal.value.key_specific_value = (*(iFrame.back())).value.key_specific_value;
    799                         break;
    800                     default:
    801                         break;
    802                 }
    803 
    804                 if (OsclErrNone != leavecode)
    805                 {
    806                     // allocation failed
    807                     return PVMFErrNoMemory;
    808                 }
    809 
    810                 leavecode = OsclErrNone;
    811                 leavecode = PushKVPValue(KeyVal, aValueList);
    812                 if (OsclErrNone != leavecode)
    813                 {
    814                     // push kvp failed
    815                     return PVMFErrNoMemory;
    816                 }
    817                 ++numentriesadded;
    818             }
    819             iFrame.pop_back();
    820         }
    821     }
    822 
    823     for (lcv = 0; lcv < numKeys; lcv++)
    824     {
    825 
    826         int32 leavecode = OsclErrNone;
    827         PvmiKvp KeyVal;
    828         KeyVal.key = NULL;
    829         uint32 KeyLen = 0;
    830 
    831         if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_KEY))
    832         {
    833             // Duration
    834             if (pMP3Parser)
    835             {
    836                 // Increment the counter for the number of values found so far
    837                 ++numvalentries;
    838 
    839                 // Create a value entry if past the starting index
    840                 if (numvalentries > aStartingValueIndex)
    841                 {
    842                     uint32 duration = 0;
    843                     // decision for walking the entire file in order to calculate
    844                     // clip duration is made here. currently complete file is scanned
    845                     // when compute flag is not present , Compute clip duration by default
    846                     duration = pMP3Parser->GetDuration();
    847 
    848                     if (duration > 0)
    849                     {
    850                         KeyLen = oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1; // for "duration;"
    851                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
    852                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32;"
    853                         KeyLen += oscl_strlen(PVMP3METADATA_TIMESCALE1000) + 1; // for "timescale=1000" and NULL terminator
    854 
    855                         // Allocate memory for the string
    856                         leavecode = OsclErrNone;
    857                         KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
    858                         if (OsclErrNone == leavecode)
    859                         {
    860                             // Copy the key string
    861                             oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
    862                             oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
    863                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
    864                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
    865                             oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
    866                             oscl_strncat(KeyVal.key, PVMP3METADATA_TIMESCALE1000, oscl_strlen(PVMP3METADATA_TIMESCALE1000));
    867                             KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
    868                             // Copy the value
    869                             KeyVal.value.uint32_value = pMP3Parser->GetDuration();
    870                             // Set the length and capacity
    871                             KeyVal.length = 1;
    872                             KeyVal.capacity = 1;
    873                         }
    874                         else
    875                         {
    876                             // Memory allocation failed
    877                             KeyVal.key = NULL;
    878                             break;
    879                         }
    880                     }
    881                     else
    882                     {
    883                         KeyLen = oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1; // for "duration;"
    884                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
    885                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*;"
    886 
    887                         // Allocate memory for the string
    888                         leavecode = OsclErrNone;
    889                         KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
    890 
    891                         if (OsclErrNone == leavecode)
    892                         {
    893                             oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
    894                             oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
    895                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
    896                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
    897 
    898                             KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
    899 
    900                         }
    901                         else
    902                         {
    903                             // Memory allocation failed
    904                             KeyVal.key = NULL;
    905                             break;
    906                         }
    907 
    908                         uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMP3METADATA_UNKNOWN)) + 1; // Add value string plus one for NULL terminator
    909                         leavecode = OsclErrNone;
    910                         KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, valuelen);
    911 
    912                         if (OsclErrNone == leavecode)
    913                         {
    914                             // Copy the value
    915                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMP3METADATA_UNKNOWN), valuelen);
    916                             KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
    917                             // Set the length and capacity
    918                             KeyVal.length = valuelen;
    919                             KeyVal.capacity = valuelen;
    920                         }
    921                         else
    922                         {
    923                             // Memory allocation failed
    924                             KeyVal.key = NULL;
    925                             break;
    926                         }
    927                     }
    928                 }
    929             }
    930         }
    931         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY))
    932         {
    933             // Duration
    934             if (pMP3Parser)
    935             {
    936                 // Increment the counter for the number of values found so far
    937                 ++numvalentries;
    938 
    939                 // Create a value entry if past the starting index
    940                 if (numvalentries > aStartingValueIndex)
    941                 {
    942                     KeyLen = oscl_strlen(PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY) + 1; // for "random-access-denied;"
    943                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
    944                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING_CONSTCHAR) + 1; // for "bool;"
    945 
    946                     // Allocate memory for the string
    947                     leavecode = OsclErrNone;
    948                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
    949                     if (OsclErrNone == leavecode)
    950                     {
    951                         // Copy the key string
    952                         oscl_strncpy(KeyVal.key, PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY, oscl_strlen(PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY) + 1);
    953                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
    954                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
    955                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_BOOL_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
    956                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
    957                         // Copy the value
    958                         KeyVal.value.bool_value = pMP3Parser->GetDuration() > 0 ? false : true;
    959                         // Set the length and capacity
    960                         KeyVal.length = 1;
    961                         KeyVal.capacity = 1;
    962                     }
    963                     else
    964                     {
    965                         // Memory allocation failed
    966                         KeyVal.key = NULL;
    967                         break;
    968                     }
    969                 }
    970             }
    971         }
    972         else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_FROM_METADATA_KEY))
    973         {
    974             // Duration
    975             if (pMP3Parser)
    976             {
    977                 // Increment the counter for the number of values found so far
    978                 ++numvalentries;
    979 
    980                 // Create a value entry if past the starting index
    981                 if (numvalentries > aStartingValueIndex)
    982                 {
    983                     uint32 duration = 0;
    984                     // decision for walking the entire file in order to calculate
    985                     // clip duration is made here. currently complete file is scanned
    986                     // when compute flag is not present , Compute clip duration by default
    987                     bool metadataDuration = true;
    988                     duration = pMP3Parser->GetDuration(metadataDuration);
    989 
    990                     if (duration > 0)
    991                     {
    992                         KeyLen = oscl_strlen(PVMP3METADATA_DURATION_FROM_METADATA_KEY) + 1; // for "duration;"
    993                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
    994                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32;"
    995                         KeyLen += oscl_strlen(PVMP3METADATA_TIMESCALE1000) + 1; // for "timescale=1000" and NULL terminator
    996 
    997                         // Allocate memory for the string
    998                         leavecode = OsclErrNone;
    999                         KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1000                         if (OsclErrNone == leavecode)
   1001                         {
   1002                             // Copy the key string
   1003                             oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_FROM_METADATA_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
   1004                             oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1005                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1006                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   1007                             oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1008                             oscl_strncat(KeyVal.key, PVMP3METADATA_TIMESCALE1000, oscl_strlen(PVMP3METADATA_TIMESCALE1000));
   1009                             KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1010                             // Copy the value
   1011                             KeyVal.value.uint32_value = pMP3Parser->GetDuration();
   1012                             // Set the length and capacity
   1013                             KeyVal.length = 1;
   1014                             KeyVal.capacity = 1;
   1015                         }
   1016                         else
   1017                         {
   1018                             // Memory allocation failed
   1019                             KeyVal.key = NULL;
   1020                             break;
   1021                         }
   1022                     }
   1023                     else
   1024                     {
   1025                         KeyLen = oscl_strlen(PVMP3METADATA_DURATION_FROM_METADATA_KEY) + 1; // for "duration;"
   1026                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   1027                         KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*;"
   1028 
   1029                         // Allocate memory for the string
   1030                         leavecode = OsclErrNone;
   1031                         KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1032 
   1033 
   1034                         if (OsclErrNone == leavecode)
   1035                         {
   1036                             oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_FROM_METADATA_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
   1037                             oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1038                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1039                             oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
   1040 
   1041                             KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1042                         }
   1043                         else
   1044                         {
   1045                             // Memory allocation failed
   1046                             KeyVal.key = NULL;
   1047                             break;
   1048                         }
   1049 
   1050                         uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMP3METADATA_UNKNOWN)) + 1; // Add value string plus one for NULL terminator
   1051                         leavecode = OsclErrNone;
   1052                         KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, valuelen);
   1053 
   1054                         if (OsclErrNone == leavecode)
   1055                         {
   1056                             // Copy the value
   1057                             oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMP3METADATA_UNKNOWN), valuelen);
   1058                             KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
   1059                             // Set the length and capacity
   1060                             KeyVal.length = valuelen;
   1061                             KeyVal.capacity = valuelen;
   1062                         }
   1063                         else
   1064                         {
   1065                             // Memory allocation failed
   1066                             KeyVal.key = NULL;
   1067                             break;
   1068                         }
   1069                     }
   1070                 }
   1071             }
   1072         }
   1073         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_NUMTRACKS_KEY) == 0)
   1074         {
   1075             // Number of tracks
   1076             if (pMP3Parser)
   1077             {
   1078                 // Increment the counter for the number of values found so far
   1079                 ++numvalentries;
   1080 
   1081                 // Create a value entry if past the starting index
   1082                 if (numvalentries > aStartingValueIndex)
   1083                 {
   1084                     KeyLen = oscl_strlen(PVMP3METADATA_NUMTRACKS_KEY) + 1; // for "num-tracks;"
   1085                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   1086                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   1087 
   1088                     // Allocate memory for the string
   1089                     leavecode = OsclErrNone;
   1090                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1091 
   1092                     if (OsclErrNone == leavecode)
   1093                     {
   1094                         // Copy the key string
   1095                         oscl_strncpy(KeyVal.key, PVMP3METADATA_NUMTRACKS_KEY, oscl_strlen(PVMP3METADATA_NUMTRACKS_KEY) + 1);
   1096                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1097                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1098                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   1099                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1100                         // Copy the value
   1101                         KeyVal.value.uint32_value = 1; // Number of tracks supported in PV MP3 parser would always be 1
   1102                         // Set the length and capacity
   1103                         KeyVal.length = 1;
   1104                         KeyVal.capacity = 1;
   1105                     }
   1106                     else
   1107                     {
   1108                         // Memory allocation failed
   1109                         KeyVal.key = NULL;
   1110                         break;
   1111                     }
   1112                 }
   1113             }
   1114         }
   1115         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_BITRATE_KEY) == 0 ||
   1116                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_BITRATE_KEY) == 0)
   1117         {
   1118             // Bitrate
   1119             MP3ContentFormatType mp3info;
   1120             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
   1121             {
   1122                 // Increment the counter for the number of values found so far
   1123                 ++numvalentries;
   1124 
   1125                 // Create a value entry if past the starting index
   1126                 if (numvalentries > aStartingValueIndex)
   1127                 {
   1128                     KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_BITRATE_KEY) + 1; // for "track-info/bitrate;"
   1129                     KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
   1130                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   1131                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   1132 
   1133                     // Allocate memory for the string
   1134                     leavecode = OsclErrNone;
   1135                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1136 
   1137                     if (OsclErrNone == leavecode)
   1138                     {
   1139                         // Copy the key string
   1140                         oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_BITRATE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_BITRATE_KEY) + 1);
   1141                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1142                         oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
   1143                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1144                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1145                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   1146                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1147                         // Copy the value
   1148                         KeyVal.value.uint32_value = mp3info.Bitrate;
   1149                         // Set the length and capacity
   1150                         KeyVal.length = 1;
   1151                         KeyVal.capacity = 1;
   1152                     }
   1153                     else
   1154                     {
   1155                         // Memory allocation failed
   1156                         KeyVal.key = NULL;
   1157                         break;
   1158                     }
   1159                 }
   1160             }
   1161         }
   1162         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_SAMPLERATE_KEY) == 0 ||
   1163                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) == 0)
   1164         {
   1165             // Sampling rate
   1166             MP3ContentFormatType mp3info;
   1167             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
   1168             {
   1169                 // Increment the counter for the number of values found so far
   1170                 ++numvalentries;
   1171 
   1172                 // Create a value entry if past the starting index
   1173                 if (numvalentries > aStartingValueIndex)
   1174                 {
   1175                     KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) + 1; // for "track-info/samplingrate;"
   1176                     KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
   1177                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   1178                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   1179 
   1180                     // Allocate memory for the string
   1181                     leavecode = 0;
   1182                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1183 
   1184                     if (OsclErrNone == leavecode)
   1185                     {
   1186                         // Copy the key string
   1187                         oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) + 1);
   1188                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1189                         oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
   1190                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1191                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1192                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   1193                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1194                         // Copy the value
   1195                         KeyVal.value.uint32_value = mp3info.SamplingRate;
   1196                         // Set the length and capacity
   1197                         KeyVal.length = 1;
   1198                         KeyVal.capacity = 1;
   1199                     }
   1200                     else
   1201                     {
   1202                         // Memory allocation failed
   1203                         KeyVal.key = NULL;
   1204                         break;
   1205                     }
   1206                 }
   1207             }
   1208         }
   1209         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_FORMAT_KEY) == 0 ||
   1210                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0)
   1211         {
   1212             // Format
   1213             // Increment the counter for the number of values found so far
   1214             ++numvalentries;
   1215 
   1216             // Create a value entry if past the starting index
   1217             if (numvalentries > aStartingValueIndex)
   1218             {
   1219                 KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) + 1; // for "track-info/audio/format;"
   1220                 KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
   1221                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   1222                 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator
   1223 
   1224                 uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_MP3)) + 1; // Add value string plus one for NULL terminator
   1225                 // Allocate memory for the strings
   1226                 int32 leavecode1 = OsclErrNone;
   1227                 leavecode = OsclErrNone;
   1228                 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1229                 if (OsclErrNone == leavecode)
   1230                 {
   1231                     KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode1, PVMI_KVPVALTYPE_CHARPTR, valuelen);
   1232                 }
   1233 
   1234                 if (OsclErrNone == leavecode && OsclErrNone == leavecode1)
   1235                 {
   1236                     // Copy the key string
   1237                     oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) + 1);
   1238                     oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1239                     oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
   1240                     oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1241                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1242                     oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
   1243                     KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1244                     // Copy the value
   1245                     oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_MP3), valuelen);
   1246                     KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
   1247                     // Set the length and capacity
   1248                     KeyVal.length = valuelen;
   1249                     KeyVal.capacity = valuelen;
   1250                 }
   1251                 else
   1252                 {
   1253                     // Memory allocation failed so clean up
   1254                     if (KeyVal.key)
   1255                     {
   1256                         OSCL_ARRAY_DELETE(KeyVal.key);
   1257                         KeyVal.key = NULL;
   1258                     }
   1259                     if (KeyVal.value.pChar_value)
   1260                     {
   1261                         OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
   1262                     }
   1263                     break;
   1264                 }
   1265             }
   1266         }
   1267         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNELS_KEY) == 0 ||
   1268                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) == 0)
   1269         {
   1270             // Channels
   1271             MP3ContentFormatType mp3info;
   1272             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
   1273             {
   1274                 // Increment the counter for the number of values found so far
   1275                 ++numvalentries;
   1276 
   1277                 // Create a value entry if past the starting index
   1278                 if (numvalentries > aStartingValueIndex)
   1279                 {
   1280                     KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) + 1; // for "track-info/audio/channels;"
   1281                     KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
   1282                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   1283                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   1284 
   1285                     // Allocate memory for the string
   1286                     leavecode = OsclErrNone;
   1287                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1288 
   1289                     if (OsclErrNone == leavecode)
   1290                     {
   1291                         // Copy the key string
   1292                         oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) + 1);
   1293                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1294                         oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
   1295                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1296                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1297                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   1298                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1299                         // Copy the value
   1300                         KeyVal.value.uint32_value = mp3info.NumberOfChannels;
   1301                         // Set the length and capacity
   1302                         KeyVal.length = 1;
   1303                         KeyVal.capacity = 1;
   1304                     }
   1305                     else
   1306                     {
   1307                         // Memory allocation failed
   1308                         KeyVal.key = NULL;
   1309                         break;
   1310                     }
   1311                 }
   1312             }
   1313         }
   1314         else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNEL_MODE_KEY) == 0 ||
   1315                  oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) == 0)
   1316         {
   1317             // Channel mode
   1318             MP3ContentFormatType mp3info;
   1319             if (GetConfigDetails(mp3info) == MP3_SUCCESS)
   1320             {
   1321                 // Increment the counter for the number of values found so far
   1322                 ++numvalentries;
   1323 
   1324                 // Create a value entry if past the starting index
   1325                 if (numvalentries > aStartingValueIndex)
   1326                 {
   1327                     KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) + 1; // for "track-info/audio/channel-mode;"
   1328                     KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
   1329                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
   1330                     KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
   1331 
   1332                     // Allocate memory for the string
   1333                     leavecode = 0;
   1334                     KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
   1335 
   1336                     if (leavecode == 0)
   1337                     {
   1338                         // Copy the key string
   1339                         oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) + 1);
   1340                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1341                         oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
   1342                         oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
   1343                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
   1344                         oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
   1345                         KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
   1346                         // Copy the value
   1347                         KeyVal.value.uint32_value = mp3info.ChannelMode;
   1348                         // Set the length and capacity
   1349                         KeyVal.length = 1;
   1350                         KeyVal.capacity = 1;
   1351                     }
   1352                     else
   1353                     {
   1354                         // Memory allocation failed
   1355                         KeyVal.key = NULL;
   1356                         break;
   1357                     }
   1358                 }
   1359             }
   1360         }
   1361 
   1362         // Add the KVP to the list if the key string was created
   1363         if (KeyVal.key != NULL)
   1364         {
   1365             leavecode = OsclErrNone;
   1366             leavecode = PushKVPValue(KeyVal, aValueList);
   1367             if (OsclErrNone != leavecode)
   1368             {
   1369                 // push kvp failed
   1370                 return PVMFErrNoMemory;
   1371             }
   1372 
   1373             // Increment the counter for number of value entries added to the list
   1374             ++numentriesadded;
   1375             // Check if the max number of value entries were added
   1376             if (aMaxValueEntries > 0 && numentriesadded >= aMaxValueEntries)
   1377             {
   1378                 // Maximum number of values added so break out of the loop
   1379                 break;
   1380             }
   1381         }
   1382 
   1383     }  // End of for loop
   1384 
   1385     return PVMFSuccess;
   1386 }
   1387 
   1388 OSCL_EXPORT_REF PVMFStatus IMpeg3File::ReleaseMetadataValue(PvmiKvp& aValueKVP)
   1389 {
   1390     if (aValueKVP.key == NULL)
   1391     {
   1392         return PVMFErrArgument;
   1393     }
   1394 
   1395     switch (GetValTypeFromKeyString(aValueKVP.key))
   1396     {
   1397         case PVMI_KVPVALTYPE_WCHARPTR:
   1398             if ((aValueKVP.value.pWChar_value != NULL) && (aValueKVP.length != 0))
   1399             {
   1400                 OSCL_ARRAY_DELETE(aValueKVP.value.pWChar_value);
   1401                 aValueKVP.value.pWChar_value = NULL;
   1402 
   1403             }
   1404             break;
   1405 
   1406         case PVMI_KVPVALTYPE_CHARPTR:
   1407             if ((aValueKVP.value.pChar_value != NULL) && (aValueKVP.length != 0))
   1408             {
   1409                 OSCL_ARRAY_DELETE(aValueKVP.value.pChar_value);
   1410                 aValueKVP.value.pChar_value = NULL;
   1411             }
   1412             break;
   1413 
   1414         case PVMI_KVPVALTYPE_UINT8PTR:
   1415             if ((aValueKVP.value.pUint8_value != NULL) && (aValueKVP.length != 0))
   1416             {
   1417                 OSCL_ARRAY_DELETE(aValueKVP.value.pUint8_value);
   1418                 aValueKVP.value.pUint8_value = NULL;
   1419             }
   1420 
   1421             break;
   1422 
   1423         case PVMI_KVPVALTYPE_UINT32:
   1424         case PVMI_KVPVALTYPE_UINT8:
   1425             // No memory to free for these valtypes
   1426             break;
   1427 
   1428         default:
   1429             // Should not get a value that wasn't created from here
   1430             break;
   1431     }
   1432 
   1433     OSCL_ARRAY_DELETE(aValueKVP.key);
   1434     aValueKVP.key = NULL;
   1435 
   1436     return PVMFSuccess;
   1437 }
   1438 
   1439 
   1440 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::IsMp3File(OSCL_wString& aFileName,
   1441         PVMFCPMPluginAccessInterfaceFactory *aCPMAccessFactory,
   1442         uint32 aInitSearchFileSize)
   1443 {
   1444     MP3ErrorType errCode = MP3_ERROR_UNKNOWN_OBJECT;
   1445 
   1446     MP3_FF_FILE fileStruct;
   1447     MP3_FF_FILE *fp = &fileStruct;
   1448 
   1449     fp->_pvfile.SetCPM(aCPMAccessFactory);
   1450 
   1451     // open the dummy file
   1452     if (MP3Utils::OpenFile(aFileName,
   1453                            Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
   1454                            fp) != 0)
   1455     {
   1456         errCode = MP3_FILE_OPEN_FAILED;
   1457         return errCode;
   1458     }
   1459     // create the file parser object to recognize the clip
   1460     MP3Parser* mp3Parser = NULL;
   1461     mp3Parser = OSCL_NEW(MP3Parser, ());
   1462 
   1463     errCode = (mp3Parser) ? MP3_SUCCESS : MP3_ERROR_UNKNOWN;
   1464 
   1465     // File was opened successfully, clip recognition can proceed
   1466     if (errCode == MP3_SUCCESS)
   1467     {
   1468         errCode = mp3Parser->IsMp3File(fp, aInitSearchFileSize);
   1469         //deallocate the MP3Parser object created
   1470         if (mp3Parser)
   1471         {
   1472             delete mp3Parser;
   1473             mp3Parser = NULL;
   1474         }
   1475     }
   1476     // close the file
   1477     MP3Utils::CloseFile(&(fp->_pvfile)); //Close the MP3 File
   1478     return errCode;
   1479 }
   1480 
   1481 
   1482 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::RequestReadCapacityNotification(PvmiDataStreamObserver& aObserver,
   1483         uint32 aFileOffset,
   1484         OsclAny* aContextData)
   1485 {
   1486     uint32 capacity = 0;
   1487     uint32 currFilePosn = MP3Utils::getCurrentFilePosition(&iMP3File);
   1488     if (aFileOffset > currFilePosn)
   1489     {
   1490         capacity = (aFileOffset - currFilePosn);
   1491         bool retVal =
   1492             iMP3File.RequestReadCapacityNotification(aObserver, capacity, aContextData);
   1493         if (retVal)
   1494         {
   1495             return MP3_SUCCESS;
   1496         }
   1497     }
   1498     return MP3_END_OF_FILE;
   1499 }
   1500 
   1501 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::ScanMP3File(uint32 aFramesToScan)
   1502 {
   1503     if (pMP3Parser && iScanFP.IsOpen())
   1504         return pMP3Parser->ScanMP3File(&iScanFP, aFramesToScan);
   1505     return MP3_ERROR_UNKNOWN;
   1506 }
   1507 
   1508 OsclAny* IMpeg3File::AllocateKVPKeyArray(int32& aLeaveCode, PvmiKvpValueType aValueType, int32 aNumElements)
   1509 {
   1510     int32 leaveCode = OsclErrNone;
   1511     OsclAny* aBuffer = NULL;
   1512     switch (aValueType)
   1513     {
   1514         case PVMI_KVPVALTYPE_WCHARPTR:
   1515             OSCL_TRY(leaveCode,
   1516                      aBuffer = (oscl_wchar*) OSCL_ARRAY_NEW(oscl_wchar, aNumElements + 1);
   1517                     );
   1518             break;
   1519 
   1520         case PVMI_KVPVALTYPE_CHARPTR:
   1521             OSCL_TRY(leaveCode,
   1522                      aBuffer = (char*) OSCL_ARRAY_NEW(char, aNumElements + 1);
   1523                     );
   1524             break;
   1525         case PVMI_KVPVALTYPE_UINT8PTR:
   1526             OSCL_TRY(leaveCode,
   1527                      aBuffer = (uint8*) OSCL_ARRAY_NEW(uint8, aNumElements);
   1528                     );
   1529             break;
   1530         default:
   1531             break;
   1532     }
   1533     aLeaveCode = leaveCode;
   1534     return aBuffer;
   1535 }
   1536 
   1537 
   1538 int32 IMpeg3File::PushKVPValue(PvmiKvp aKVP, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList)
   1539 {
   1540     int32 leavecode = OsclErrNone;
   1541     OSCL_TRY(leavecode, aValueList.push_back(aKVP));
   1542     if (OsclErrNone != leavecode)
   1543     {
   1544         ReleaseMetadataValue(aKVP);
   1545     }
   1546     return leavecode;
   1547 }
   1548 
   1549 int32 IMpeg3File::PushKVPKey(const char* aString, PVMFMetadataList& aKeyList)
   1550 {
   1551     int32 leavecode = OsclErrNone;
   1552     OSCL_TRY(leavecode, aKeyList.push_back(aString));
   1553     return leavecode;
   1554 }
   1555 
   1556 int32 IMpeg3File::PushKVPKey(OSCL_HeapString<OsclMemAllocator>& aString, Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator>& aKeyList)
   1557 {
   1558     int32 leavecode = OsclErrNone;
   1559     OSCL_TRY(leavecode, aKeyList.push_back(aString));
   1560     return leavecode;
   1561 }
   1562