| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| // -*- c++ -*- |
| // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
| // |
| // M P 3 F I L E P A R S E R |
| // |
| // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
| |
| |
| /** |
| * @file imp3ff.cpp |
| * @brief This file contains the implementation of the MP3 File Format |
| * interface. It initializes and maintains the MP3 File Format Library |
| */ |
| |
| //---------------------------------------------------------------------- |
| // Include Files |
| //---------------------------------------------------------------------- |
| |
| #include "imp3ff.h" |
| #include "mp3fileio.h" |
| #include "mp3utils.h" |
| #include "mp3parser.h" |
| #include "oscl_mem.h" |
| #include "oscl_utf8conv.h" |
| #include "pvmi_kvp_util.h" |
| #include "pvmi_kvp.h" |
| #include "pvmf_format_type.h" |
| #include "pv_mime_string_utils.h" |
| // Constant character strings for metadata keys |
| static const char PVMP3METADATA_TITLE_KEY[] = "title"; |
| static const char PVMP3METADATA_ARTIST_KEY[] = "artist"; |
| static const char PVMP3METADATA_ALBUM_KEY[] = "album"; |
| static const char PVMP3METADATA_YEAR_KEY[] = "year"; |
| static const char PVMP3METADATA_COMMENT_KEY[] = "comment"; |
| static const char PVMP3METADATA_COPYRIGHT_KEY[] = "copyright"; |
| static const char PVMP3METADATA_GENRE_KEY[] = "genre"; |
| static const char PVMP3METADATA_TRACKNUMBER_KEY[] = "tracknumber"; |
| static const char PVMP3METADATA_DURATION_KEY[] = "duration"; |
| static const char PVMP3METADATA_DURATION_FROM_METADATA_KEY[] = "duration-from-metadata"; |
| static const char PVMP3METADATA_NUMTRACKS_KEY[] = "num-tracks"; |
| static const char PVMP3METADATA_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate"; |
| static const char PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY[] = "track-info/sample-rate"; |
| static const char PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY[] = "track-info/audio/format"; |
| static const char PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY[] = "track-info/audio/channels"; |
| static const char PVMP3METADATA_BITRATE_KEY[] = "bit-rate"; |
| static const char PVMP3METADATA_SAMPLERATE_KEY[] = "sample-rate"; |
| static const char PVMP3METADATA_FORMAT_KEY[] = "format"; |
| static const char PVMP3METADATA_CHANNELS_KEY[] = "channels"; |
| static const char PVMP3METADATA_SEMICOLON[] = ";"; |
| static const char PVMP3METADATA_CHARENCUTF8[] = "char-encoding=UTF8"; |
| static const char PVMP3METADATA_CHARENCUTF16BE[] = "char-encoding=UTF16BE"; |
| static const char PVMP3METADATA_FORMATID3V1[] = "format=id3v1"; |
| static const char PVMP3METADATA_FORMATID3V11[] = "format=id3v1.1"; |
| static const char PVMP3METADATA_TIMESCALE1000[] = "timescale=1000"; |
| static const char PVMP3METADATA_INDEX0[] = "index=0"; |
| static const char PVMP3METADATA_UNKNOWN[] = "unknown"; |
| static const char PVMP3METADATA_COMPUTE[] = "compute=true"; |
| |
| |
| // Use default DLL entry point for Symbian |
| #include "oscl_dll.h" |
| OSCL_DLL_ENTRY_POINT_DEFAULT() |
| |
| //---------------------------------------------------------------------- |
| // Defines |
| //---------------------------------------------------------------------- |
| |
| //---------------------------------------------------------------------- |
| // Type Declarations |
| //---------------------------------------------------------------------- |
| |
| //---------------------------------------------------------------------- |
| // Global Constant Definitions |
| //---------------------------------------------------------------------- |
| |
| //---------------------------------------------------------------------- |
| // Global Data Definitions |
| //---------------------------------------------------------------------- |
| |
| //---------------------------------------------------------------------- |
| // Static Variable Definitions |
| //---------------------------------------------------------------------- |
| |
| |
| OSCL_EXPORT_REF IMpeg3File::IMpeg3File(OSCL_wString& filename, MP3ErrorType &bSuccess, Oscl_FileServer* fileServSession, PVMFCPMPluginAccessInterfaceFactory*aCPM, OsclFileHandle*aFileHandle, bool enableCRC) : |
| pMP3Parser(NULL) |
| { |
| bSuccess = MP3_SUCCESS; |
| |
| // Initialize the metadata related variables |
| iAvailableMetadataKeys.reserve(14); |
| iAvailableMetadataKeys.clear(); |
| |
| iEnableCrcCalc = enableCRC; |
| // Open the specified MP3 file |
| iMP3File.SetCPM(aCPM); |
| iMP3File.SetFileHandle(aFileHandle); |
| if (iMP3File.Open(filename.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *fileServSession) != 0) |
| { |
| bSuccess = MP3_FILE_OPEN_ERR; |
| return; |
| } |
| |
| if (!aCPM) |
| { |
| iScanFP.SetCPM(aCPM); |
| iScanFP.SetFileHandle(aFileHandle); |
| if (iScanFP.Open(filename.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *fileServSession) != 0) |
| { |
| bSuccess = MP3_FILE_OPEN_ERR; |
| return; |
| } |
| } |
| |
| int32 leavecode = 0; |
| OSCL_TRY(leavecode, pMP3Parser = OSCL_NEW(MP3Parser, (&iMP3File));); |
| if (pMP3Parser && leavecode == 0) |
| bSuccess = MP3_SUCCESS; |
| else |
| bSuccess = MP3_ERROR_UNKNOWN; |
| } |
| |
| OSCL_EXPORT_REF IMpeg3File::IMpeg3File(MP3ErrorType &bSuccess): pMP3Parser(NULL) |
| { |
| int32 leavecode = 0; |
| OSCL_TRY(leavecode, pMP3Parser = OSCL_NEW(MP3Parser, ());); |
| if (pMP3Parser && leavecode == 0) |
| bSuccess = MP3_SUCCESS; |
| else |
| bSuccess = MP3_ERROR_UNKNOWN; |
| } |
| |
| OSCL_EXPORT_REF IMpeg3File::~IMpeg3File() |
| { |
| iAvailableMetadataKeys.clear(); |
| |
| if (pMP3Parser != NULL) |
| { |
| OSCL_DELETE(pMP3Parser); |
| pMP3Parser = NULL; |
| } |
| |
| if (iScanFP.IsOpen()) |
| { |
| iScanFP.Close(); |
| } |
| if (iMP3File.IsOpen()) |
| { |
| iMP3File.Close(); |
| } |
| } |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::ParseMp3File() |
| { |
| MP3ErrorType mp3Err = MP3_SUCCESS; |
| |
| // Parse the mp3 clip |
| mp3Err = pMP3Parser->ParseMP3File(&iMP3File, iEnableCrcCalc); |
| if (mp3Err == MP3_INSUFFICIENT_DATA) |
| { |
| // not enough data was available to parse the clip |
| return mp3Err; |
| } |
| else if (mp3Err != MP3_SUCCESS) |
| { |
| // some other error occured while parsing the clip. |
| // parsing can not proceed further |
| OSCL_DELETE(pMP3Parser); |
| pMP3Parser = NULL; |
| iMP3File.Close(); |
| return mp3Err; |
| } |
| else |
| { |
| // parsing of clip was successful, id3 frames can now be fetched |
| PvmiKvpSharedPtrVector id3Frames; |
| pMP3Parser->GetMetaData(id3Frames); |
| |
| // Populate metadata key list vector |
| int32 leavecode = 0; |
| for (uint32 p = 0;p < id3Frames.size();p++) |
| { |
| OSCL_HeapString<OsclMemAllocator> keystr((const char *)((*id3Frames[p]).key), oscl_strlen((const char *)((*id3Frames[p]).key))); |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(keystr)); |
| } |
| |
| bool metadataDuration = true; |
| if (pMP3Parser->GetDuration(metadataDuration) > 0) |
| { |
| leavecode = 0; |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMP3METADATA_DURATION_FROM_METADATA_KEY)); |
| } |
| |
| // Following keys are available when the MP3 file has been parsed |
| if (pMP3Parser->GetDuration() >= 0) |
| { |
| leavecode = 0; |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMP3METADATA_DURATION_KEY)); |
| } |
| |
| leavecode = 0; |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMP3METADATA_NUMTRACKS_KEY)); |
| leavecode = 0; |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY)); |
| |
| MP3ContentFormatType mp3info; |
| if (GetConfigDetails(mp3info) == MP3_SUCCESS) |
| { |
| if (mp3info.Bitrate > 0) |
| { |
| leavecode = 0; |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMP3METADATA_TRACKINFO_BITRATE_KEY)); |
| } |
| if (mp3info.SamplingRate > 0) |
| { |
| leavecode = 0; |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY)); |
| } |
| if (mp3info.NumberOfChannels > 0) |
| { |
| leavecode = 0; |
| OSCL_TRY(leavecode, iAvailableMetadataKeys.push_back(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY)); |
| } |
| } |
| } |
| return mp3Err; |
| } |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetConfigDetails(MP3ContentFormatType &mp3Config) |
| { |
| if (pMP3Parser) |
| { |
| MP3ConfigInfoType mp3ConfigHdr; |
| if (pMP3Parser->GetMP3FileHeader(&mp3ConfigHdr)) |
| { |
| mp3Config.Bitrate = mp3ConfigHdr.BitRate; |
| mp3Config.FrameSize = mp3ConfigHdr.FrameLengthInBytes; |
| mp3Config.NumberOfChannels = mp3ConfigHdr.NumberOfChannels; |
| mp3Config.SamplingRate = mp3ConfigHdr.SamplingRate; |
| mp3Config.FrameSizeUnComp = mp3ConfigHdr.FrameSizeUnComp; |
| mp3Config.FileSizeInBytes = pMP3Parser->GetFileSize(); |
| return MP3_SUCCESS; |
| } |
| } |
| return MP3_ERROR_UNKNOWN; |
| } |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetNextMediaSample(uint8 *buf, uint32 size, uint32& framesize, uint32& timestamp) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return (pMP3Parser->GetNextMediaSample(buf, size, framesize, timestamp)); |
| } |
| else |
| { |
| return MP3_ERROR_UNKNOWN; |
| } |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::ResetPlayback(uint32 time) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->SeekToTimestamp(time); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF int32 IMpeg3File::GetNextBundledAccessUnits(uint32 *n, GAU *pgau, MP3ErrorType &err) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetNextBundledAccessUnits(n, pgau, err); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF int32 IMpeg3File::PeekNextBundledAccessUnits(uint32 *n, MediaMetaInfo *mInfo) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->PeekNextBundledAccessUnits(n, mInfo); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF int32 IMpeg3File::GetNumTracks() |
| { |
| return 1; |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetDuration() const |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetDuration(); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetMetadataSize(int32 &aSize) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetMetadataSize(aSize); |
| } |
| return MP3_ERROR_UNKNOWN; |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetMinBytesRequired() |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetMinBytesRequired(); |
| } |
| return 0; |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetTimestampForCurrentSample() |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetTimestampForCurrentSample(); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::SeekToTimestamp(uint32 timestamp) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->SeekToTimestamp(timestamp); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::SeekPointFromTimestamp(uint32& timestamp) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->SeekPointFromTimestamp(timestamp); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetFileOffsetForAutoResume(uint32& timestamp) |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetFileOffsetForAutoResume(timestamp); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetTimescale() const |
| { |
| return 1000; |
| } |
| |
| OSCL_EXPORT_REF uint8 IMpeg3File::RandomAccessDenied() |
| { |
| return false; |
| } |
| |
| OSCL_EXPORT_REF int32 IMpeg3File::GetNumSampleEntries() |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetSampleCountInFile(); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF int32 IMpeg3File::GetMaxBufferSizeDB() |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetMaximumDecodeBufferSize(); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF uint8 const * IMpeg3File::GetDecoderSpecificInfoContent() const |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetDecoderSpecificInfoContent(); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetDecoderSpecificInfoSize() |
| { |
| if (pMP3Parser != NULL) |
| { |
| return pMP3Parser->GetDecoderSpecificInfoSize(); |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::SetFileSize(const uint32 aFileSize) |
| { |
| MP3ErrorType errCode = MP3_ERROR_UNKNOWN; |
| if (pMP3Parser != NULL) |
| { |
| errCode = pMP3Parser->SetFileSize(aFileSize); |
| } |
| return errCode; |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetNumMetadataKeys(char* aQueryKeyString) |
| { |
| uint32 num_entries = 0; |
| |
| if (aQueryKeyString == NULL) |
| { |
| // No query key so just return all the available keys |
| num_entries = iAvailableMetadataKeys.size(); |
| } |
| else |
| { |
| // Determine the number of metadata keys based on the query key string provided |
| for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++) |
| { |
| // Check if the key matches the query key |
| if (oscl_strstr(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) != NULL) |
| { |
| num_entries++; |
| } |
| } |
| } |
| |
| return num_entries; |
| } |
| |
| OSCL_EXPORT_REF uint32 IMpeg3File::GetNumMetadataValues(PVMFMetadataList& aKeyList) |
| { |
| PvmiKvpSharedPtrVector iFrame; |
| |
| uint32 numKeys = aKeyList.size(); |
| if (numKeys == 0) |
| { |
| aKeyList = iAvailableMetadataKeys; |
| numKeys = aKeyList.size(); |
| } |
| |
| uint32 numvalentries = 0; |
| for (uint32 lcv = 0; lcv < numKeys; lcv++) |
| { |
| if (pMP3Parser->IsID3Frame(aKeyList[lcv])) |
| { |
| ++numvalentries; |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_KEY) == 0) |
| { |
| // Duration |
| if (pMP3Parser) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_NUMTRACKS_KEY) == 0) |
| { |
| // Number of tracks |
| if (pMP3Parser) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_BITRATE_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_BITRATE_KEY) == 0) |
| { |
| // Bitrate |
| MP3ContentFormatType mp3info; |
| if (GetConfigDetails(mp3info) == MP3_SUCCESS) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_SAMPLERATE_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) == 0) |
| { |
| // Sampling rate |
| MP3ContentFormatType mp3info; |
| if (GetConfigDetails(mp3info) == MP3_SUCCESS) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_FORMAT_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0) |
| { |
| // Format |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNELS_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) == 0) |
| { |
| // Channels |
| MP3ContentFormatType mp3info; |
| if (GetConfigDetails(mp3info) == MP3_SUCCESS) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| } |
| } |
| } // End of for loop |
| return numvalentries; |
| } |
| |
| OSCL_EXPORT_REF PVMFStatus IMpeg3File::GetMetadataKeys(PVMFMetadataList& aKeyList, uint32 aStartingKeyIndex, int32 aMaxKeyEntries, char* aQueryKeyString) |
| { |
| // Check parameters |
| if ((aStartingKeyIndex > (iAvailableMetadataKeys.size() - 1)) || aMaxKeyEntries == 0) |
| { |
| // Invalid starting index and/or max entries |
| return PVMFErrArgument; |
| } |
| |
| // Copy the requested keys |
| uint32 num_entries = 0; |
| int32 num_added = 0; |
| int32 leavecode = 0; |
| for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++) |
| { |
| if (aQueryKeyString == NULL) |
| { |
| // No query key so this key is counted |
| ++num_entries; |
| if (num_entries > aStartingKeyIndex) |
| { |
| // Past the starting index so copy the key |
| leavecode = 0; |
| OSCL_TRY(leavecode, aKeyList.push_back(iAvailableMetadataKeys[lcv].get_cstr())); |
| OSCL_FIRST_CATCH_ANY(leavecode, |
| return PVMFErrNoMemory); |
| num_added++; |
| } |
| } |
| else |
| { |
| // Check if the key matches the query key |
| if (oscl_strstr(iAvailableMetadataKeys[lcv].get_cstr(), aQueryKeyString) != NULL) |
| { |
| // This key is counted |
| ++num_entries; |
| if (num_entries > aStartingKeyIndex) |
| { |
| // Past the starting index so copy the key |
| leavecode = 0; |
| OSCL_TRY(leavecode, aKeyList.push_back(iAvailableMetadataKeys[lcv])); |
| OSCL_FIRST_CATCH_ANY(leavecode, |
| return PVMFErrNoMemory); |
| num_added++; |
| } |
| } |
| } |
| |
| // Check if max number of entries have been copied |
| if (aMaxKeyEntries > 0 && num_added >= aMaxKeyEntries) |
| { |
| break; |
| } |
| } |
| |
| return PVMFSuccess; |
| } |
| |
| OSCL_EXPORT_REF PVMFStatus IMpeg3File::GetMetadataValues(PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, |
| uint32 aStartingValueIndex, int32 aMaxValueEntries) |
| { |
| uint32 numKeys = aKeyList.size(); |
| PvmiKvpSharedPtrVector iFrame; |
| PVMFMetadataList parsedKeys; |
| if (numKeys == 0 || aStartingValueIndex > (numKeys - 1) || aMaxValueEntries == 0) |
| { |
| return PVMFErrArgument; |
| } |
| |
| uint32 numvalentries = 0; |
| int32 numentriesadded = 0; |
| bool gotvalue = false; |
| uint32 lcv = 0; |
| for (lcv = 0; lcv < numKeys; lcv++) |
| { |
| //check if this key has already been parsed. |
| for (uint32 pks = 0; pks < parsedKeys.size(); pks++) |
| { |
| if (pv_mime_strcmp(parsedKeys[pks].get_cstr(), aKeyList[lcv].get_cstr()) >= 0) |
| { |
| gotvalue = true; //key already parsed. |
| break; |
| } |
| } |
| |
| if (gotvalue) //get next key since this key has already been parsed. |
| { |
| gotvalue = false; |
| continue; |
| } |
| pMP3Parser->GetMetaData(aKeyList[lcv], iFrame); |
| if (iFrame.size() > 1) //multiple id3 frames exist for this key. |
| { |
| parsedKeys.push_back(aKeyList[lcv]); |
| } |
| |
| while (iFrame.size() > 0) |
| { |
| PvmiKvp KeyVal; |
| KeyVal.key = NULL; |
| KeyVal.length = 0; |
| char *key = (*(iFrame.back())).key; |
| int32 len = (*(iFrame.back())).length; |
| |
| ++numvalentries; |
| |
| int32 leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, oscl_strlen(key) + 1); |
| ); |
| |
| oscl_strncpy(KeyVal.key , key, oscl_strlen(key) + 1); |
| KeyVal.length = len; |
| KeyVal.capacity = (*(iFrame.back())).capacity; |
| |
| if (KeyVal.length > 0) |
| { |
| PvmiKvpValueType ValueType = GetValTypeFromKeyString(key); |
| |
| switch (ValueType) |
| { |
| |
| case PVMI_KVPVALTYPE_WCHARPTR: |
| leavecode = 0; |
| |
| OSCL_TRY(leavecode, |
| KeyVal.value.pWChar_value = OSCL_ARRAY_NEW(oscl_wchar, len + 1); |
| ); |
| |
| oscl_strncpy(KeyVal.value.pWChar_value , (*(iFrame.back())).value.pWChar_value, len); |
| KeyVal.value.pWChar_value[len] = 0; |
| break; |
| |
| case PVMI_KVPVALTYPE_CHARPTR: |
| leavecode = 0; |
| |
| OSCL_TRY(leavecode, |
| KeyVal.value.pChar_value = OSCL_ARRAY_NEW(char, len + 1); |
| ); |
| |
| oscl_strncpy(KeyVal.value.pChar_value , (*(iFrame.back())).value.pChar_value, len); |
| KeyVal.value.pChar_value[len] = 0; |
| break; |
| |
| case PVMI_KVPVALTYPE_UINT8PTR: |
| leavecode = 0; |
| |
| OSCL_TRY(leavecode, |
| KeyVal.value.pUint8_value = OSCL_ARRAY_NEW(uint8, len); |
| ); |
| oscl_memcpy(KeyVal.value.pUint8_value, (uint8*)(*(iFrame.back())).value.pUint8_value, len); |
| break; |
| |
| |
| case PVMI_KVPVALTYPE_UINT32: |
| KeyVal.value.uint32_value = (*(iFrame.back())).value.uint32_value; |
| break; |
| case PVMI_KVPVALTYPE_KSV: |
| KeyVal.value.key_specific_value = (*(iFrame.back())).value.key_specific_value; |
| break; |
| default: |
| break; |
| } |
| leavecode = 0; |
| OSCL_TRY(leavecode, aValueList.push_back(KeyVal)); |
| OSCL_FIRST_CATCH_ANY(leavecode, ReleaseMetadataValue(KeyVal); |
| break;); |
| ++numentriesadded; |
| } |
| iFrame.pop_back(); |
| } |
| } |
| |
| for (lcv = 0; lcv < numKeys; lcv++) |
| { |
| |
| int32 leavecode = 0; |
| PvmiKvp KeyVal; |
| KeyVal.key = NULL; |
| uint32 KeyLen = 0; |
| |
| if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_KEY)) |
| { |
| // Duration |
| if (pMP3Parser) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| |
| // Create a value entry if past the starting index |
| if (numvalentries > aStartingValueIndex) |
| { |
| uint32 duration = 0; |
| // decision for walking the entire file in order to calculate |
| // clip duration is made here. currently complete file is scanned |
| // when compute flag is not present , Compute clip duration by default |
| duration = pMP3Parser->GetDuration(); |
| |
| if (duration > 0) |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1; // for "duration;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32;" |
| KeyLen += oscl_strlen(PVMP3METADATA_TIMESCALE1000) + 1; // for "timescale=1000" and NULL terminator |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| if (leavecode == 0) |
| { |
| // Copy the key string |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_TIMESCALE1000, oscl_strlen(PVMP3METADATA_TIMESCALE1000)); |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| // Copy the value |
| KeyVal.value.uint32_value = pMP3Parser->GetDuration(); |
| // Set the length and capacity |
| KeyVal.length = 1; |
| KeyVal.capacity = 1; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| else |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1; // for "duration;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*;" |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| |
| |
| if (leavecode == 0) |
| { |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR)); |
| |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| |
| uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMP3METADATA_UNKNOWN)) + 1; // Add value string plus one for NULL terminator |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.value.pChar_value = OSCL_ARRAY_NEW(char, valuelen); |
| ); |
| |
| if (leavecode == 0) |
| { |
| // Copy the value |
| oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMP3METADATA_UNKNOWN), valuelen); |
| KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR; |
| // Set the length and capacity |
| KeyVal.length = valuelen; |
| KeyVal.capacity = valuelen; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| } |
| } |
| } |
| else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_FROM_METADATA_KEY)) |
| { |
| // Duration |
| if (pMP3Parser) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| |
| // Create a value entry if past the starting index |
| if (numvalentries > aStartingValueIndex) |
| { |
| uint32 duration = 0; |
| // decision for walking the entire file in order to calculate |
| // clip duration is made here. currently complete file is scanned |
| // when compute flag is not present , Compute clip duration by default |
| bool metadataDuration = true; |
| duration = pMP3Parser->GetDuration(metadataDuration); |
| |
| if (duration > 0) |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_DURATION_FROM_METADATA_KEY) + 1; // for "duration;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32;" |
| KeyLen += oscl_strlen(PVMP3METADATA_TIMESCALE1000) + 1; // for "timescale=1000" and NULL terminator |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| if (leavecode == 0) |
| { |
| // Copy the key string |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_FROM_METADATA_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_TIMESCALE1000, oscl_strlen(PVMP3METADATA_TIMESCALE1000)); |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| // Copy the value |
| KeyVal.value.uint32_value = pMP3Parser->GetDuration(); |
| // Set the length and capacity |
| KeyVal.length = 1; |
| KeyVal.capacity = 1; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| else |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_DURATION_FROM_METADATA_KEY) + 1; // for "duration;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*;" |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| |
| |
| if (leavecode == 0) |
| { |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_FROM_METADATA_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR)); |
| |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| |
| uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMP3METADATA_UNKNOWN)) + 1; // Add value string plus one for NULL terminator |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.value.pChar_value = OSCL_ARRAY_NEW(char, valuelen); |
| ); |
| |
| if (leavecode == 0) |
| { |
| // Copy the value |
| oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMP3METADATA_UNKNOWN), valuelen); |
| KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR; |
| // Set the length and capacity |
| KeyVal.length = valuelen; |
| KeyVal.capacity = valuelen; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| } |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_NUMTRACKS_KEY) == 0) |
| { |
| // Number of tracks |
| if (pMP3Parser) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| |
| // Create a value entry if past the starting index |
| if (numvalentries > aStartingValueIndex) |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_NUMTRACKS_KEY) + 1; // for "num-tracks;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| |
| if (leavecode == 0) |
| { |
| // Copy the key string |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_NUMTRACKS_KEY, oscl_strlen(PVMP3METADATA_NUMTRACKS_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| // Copy the value |
| KeyVal.value.uint32_value = 1; // Number of tracks supported in PV MP3 parser would always be 1 |
| // Set the length and capacity |
| KeyVal.length = 1; |
| KeyVal.capacity = 1; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_BITRATE_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_BITRATE_KEY) == 0) |
| { |
| // Bitrate |
| MP3ContentFormatType mp3info; |
| if (GetConfigDetails(mp3info) == MP3_SUCCESS) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| |
| // Create a value entry if past the starting index |
| if (numvalentries > aStartingValueIndex) |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_BITRATE_KEY) + 1; // for "track-info/bitrate;" |
| KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| |
| if (leavecode == 0) |
| { |
| // Copy the key string |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_BITRATE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_BITRATE_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| // Copy the value |
| KeyVal.value.uint32_value = mp3info.Bitrate; |
| // Set the length and capacity |
| KeyVal.length = 1; |
| KeyVal.capacity = 1; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_SAMPLERATE_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) == 0) |
| { |
| // Sampling rate |
| MP3ContentFormatType mp3info; |
| if (GetConfigDetails(mp3info) == MP3_SUCCESS) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| |
| // Create a value entry if past the starting index |
| if (numvalentries > aStartingValueIndex) |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) + 1; // for "track-info/samplingrate;" |
| KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| |
| if (leavecode == 0) |
| { |
| // Copy the key string |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| // Copy the value |
| KeyVal.value.uint32_value = mp3info.SamplingRate; |
| // Set the length and capacity |
| KeyVal.length = 1; |
| KeyVal.capacity = 1; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_FORMAT_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0) |
| { |
| // Format |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| |
| // Create a value entry if past the starting index |
| if (numvalentries > aStartingValueIndex) |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) + 1; // for "track-info/audio/format;" |
| KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator |
| |
| uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_MP3)) + 1; // Add value string plus one for NULL terminator |
| // Allocate memory for the strings |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| KeyVal.value.pChar_value = OSCL_ARRAY_NEW(char, valuelen); |
| ); |
| |
| if (leavecode == 0) |
| { |
| // Copy the key string |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR)); |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| // Copy the value |
| oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_MP3), valuelen); |
| KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR; |
| // Set the length and capacity |
| KeyVal.length = valuelen; |
| KeyVal.capacity = valuelen; |
| } |
| else |
| { |
| // Memory allocation failed so clean up |
| if (KeyVal.key) |
| { |
| OSCL_ARRAY_DELETE(KeyVal.key); |
| KeyVal.key = NULL; |
| } |
| if (KeyVal.value.pChar_value) |
| { |
| OSCL_ARRAY_DELETE(KeyVal.value.pChar_value); |
| } |
| break; |
| } |
| } |
| } |
| else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNELS_KEY) == 0 || |
| oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) == 0) |
| { |
| // Channels |
| MP3ContentFormatType mp3info; |
| if (GetConfigDetails(mp3info) == MP3_SUCCESS) |
| { |
| // Increment the counter for the number of values found so far |
| ++numvalentries; |
| |
| // Create a value entry if past the starting index |
| if (numvalentries > aStartingValueIndex) |
| { |
| KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) + 1; // for "track-info/audio/channels;" |
| KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" |
| KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator |
| |
| // Allocate memory for the string |
| leavecode = 0; |
| OSCL_TRY(leavecode, |
| KeyVal.key = OSCL_ARRAY_NEW(char, KeyLen); |
| ); |
| |
| if (leavecode == 0) |
| { |
| // Copy the key string |
| oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) + 1); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0)); |
| oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); |
| oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); |
| KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; |
| // Copy the value |
| KeyVal.value.uint32_value = mp3info.NumberOfChannels; |
| // Set the length and capacity |
| KeyVal.length = 1; |
| KeyVal.capacity = 1; |
| } |
| else |
| { |
| // Memory allocation failed |
| KeyVal.key = NULL; |
| break; |
| } |
| } |
| } |
| } |
| |
| // Add the KVP to the list if the key string was created |
| if (KeyVal.key != NULL) |
| { |
| leavecode = 0; |
| OSCL_TRY(leavecode, aValueList.push_back(KeyVal)); |
| OSCL_FIRST_CATCH_ANY(leavecode, |
| ReleaseMetadataValue(KeyVal); |
| break;); |
| |
| // Increment the counter for number of value entries added to the list |
| ++numentriesadded; |
| // Check if the max number of value entries were added |
| if (aMaxValueEntries > 0 && numentriesadded >= aMaxValueEntries) |
| { |
| // Maximum number of values added so break out of the loop |
| break; |
| } |
| } |
| |
| } // End of for loop |
| |
| return PVMFSuccess; |
| } |
| |
| OSCL_EXPORT_REF PVMFStatus IMpeg3File::ReleaseMetadataValue(PvmiKvp& aValueKVP) |
| { |
| if (aValueKVP.key == NULL) |
| { |
| return PVMFErrArgument; |
| } |
| |
| switch (GetValTypeFromKeyString(aValueKVP.key)) |
| { |
| case PVMI_KVPVALTYPE_WCHARPTR: |
| if ((aValueKVP.value.pWChar_value != NULL) && (aValueKVP.length != 0)) |
| { |
| OSCL_ARRAY_DELETE(aValueKVP.value.pWChar_value); |
| aValueKVP.value.pWChar_value = NULL; |
| |
| } |
| break; |
| |
| case PVMI_KVPVALTYPE_CHARPTR: |
| if ((aValueKVP.value.pChar_value != NULL) && (aValueKVP.length != 0)) |
| { |
| OSCL_ARRAY_DELETE(aValueKVP.value.pChar_value); |
| aValueKVP.value.pChar_value = NULL; |
| } |
| break; |
| |
| case PVMI_KVPVALTYPE_UINT8PTR: |
| if ((aValueKVP.value.pUint8_value != NULL) && (aValueKVP.length != 0)) |
| { |
| OSCL_ARRAY_DELETE(aValueKVP.value.pUint8_value); |
| aValueKVP.value.pUint8_value = NULL; |
| } |
| |
| break; |
| |
| case PVMI_KVPVALTYPE_UINT32: |
| case PVMI_KVPVALTYPE_UINT8: |
| // No memory to free for these valtypes |
| break; |
| |
| default: |
| // Should not get a value that wasn't created from here |
| break; |
| } |
| |
| OSCL_ARRAY_DELETE(aValueKVP.key); |
| aValueKVP.key = NULL; |
| |
| return PVMFSuccess; |
| } |
| |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::IsMp3File(OSCL_wString& aFileName, |
| PVMFCPMPluginAccessInterfaceFactory *aCPMAccessFactory, |
| uint32 aInitSearchFileSize) |
| { |
| MP3ErrorType errCode = MP3_ERROR_UNKNOWN_OBJECT; |
| |
| MP3_FF_FILE fileStruct; |
| MP3_FF_FILE *fp = &fileStruct; |
| |
| fp->_pvfile.SetCPM(aCPMAccessFactory); |
| |
| // open the dummy file |
| if (MP3Utils::OpenFile(aFileName, |
| Oscl_File::MODE_READ | Oscl_File::MODE_BINARY, |
| fp) != 0) |
| { |
| errCode = MP3_FILE_OPEN_FAILED; |
| return errCode; |
| } |
| // create the file parser object to recognize the clip |
| MP3Parser* mp3Parser = NULL; |
| mp3Parser = OSCL_NEW(MP3Parser, ()); |
| |
| errCode = (mp3Parser) ? MP3_SUCCESS : MP3_ERROR_UNKNOWN; |
| |
| // File was opened successfully, clip recognition can proceed |
| if (errCode == MP3_SUCCESS) |
| { |
| errCode = mp3Parser->IsMp3File(fp, aInitSearchFileSize); |
| //deallocate the MP3Parser object created |
| if (mp3Parser) |
| { |
| delete mp3Parser; |
| mp3Parser = NULL; |
| } |
| } |
| // close the file |
| MP3Utils::CloseFile(&(fp->_pvfile)); //Close the MP3 File |
| return errCode; |
| } |
| |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::RequestReadCapacityNotification(PvmiDataStreamObserver& aObserver, |
| uint32 aFileOffset, |
| OsclAny* aContextData) |
| { |
| uint32 capacity = 0; |
| uint32 currFilePosn = MP3Utils::getCurrentFilePosition(&iMP3File); |
| uint32 currFileSize = 0; |
| if (aFileOffset > currFilePosn) |
| { |
| capacity = (aFileOffset - currFilePosn); |
| bool retVal = |
| iMP3File.RequestReadCapacityNotification(aObserver, capacity, aContextData); |
| if (retVal) |
| { |
| return MP3_SUCCESS; |
| } |
| } |
| return MP3_END_OF_FILE; |
| } |
| |
| OSCL_EXPORT_REF MP3ErrorType IMpeg3File::ScanMP3File(uint32 aFramesToScan) |
| { |
| if (pMP3Parser && iScanFP.IsOpen()) |
| return pMP3Parser->ScanMP3File(&iScanFP, aFramesToScan); |
| return MP3_ERROR_UNKNOWN; |
| } |
| |