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