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#include "pvmf_mp4ffparser_node.h" 19 20#include "impeg4file.h" 21 22 23#include "media_clock_converter.h" 24 25#include "pv_mime_string_utils.h" 26 27#include "oscl_snprintf.h" 28 29#include "pvmf_duration_infomessage.h" 30 31#include "pvmi_kvp_util.h" 32 33#include "h263decoderspecificinfo.h" 34 35#include "oscl_exclusive_ptr.h" 36 37// Constant character strings for metadata keys 38static const char PVMP4_ALL_METADATA_KEY[] = "all"; 39static const char PVMP4METADATA_CLIP_TYPE_KEY[] = "clip-type"; 40static const char PVMP4METADATA_ALBUM_KEY[] = "album"; 41static const char PVMP4METADATA_COMMENT_KEY[] = "comment"; 42 43 44static const char PVMP4METADATA_LOCATION_KEY[] = "location;format=3GPP_LOCATION"; 45static const char PVMP4METADATA_YEAR_KEY[] = "year"; 46static const char PVMP4METADATA_AUTHOR_KEY[] = "author"; 47static const char PVMP4METADATA_ARTIST_KEY[] = "artist"; 48static const char PVMP4METADATA_GENRE_KEY[] = "genre"; 49static const char PVMP4METADATA_KEYWORD_KEY[] = "keyword"; 50static const char PVMP4METADATA_CLASSIFICATION_KEY[] = "classification"; 51static const char PVMP4METADATA_TITLE_KEY[] = "title"; 52static const char PVMP4METADATA_DESCRIPTION_KEY[] = "description"; 53static const char PVMP4METADATA_RATING_KEY[] = "rating"; 54static const char PVMP4METADATA_COPYRIGHT_KEY[] = "copyright"; 55static const char PVMP4METADATA_VERSION_KEY[] = "version"; 56static const char PVMP4METADATA_DATE_KEY[] = "date"; 57static const char PVMP4METADATA_DURATION_KEY[] = "duration"; 58static const char PVMP4METADATA_NUMTRACKS_KEY[] = "num-tracks"; 59static const char PVMP4METADATA_IS_MOOF_KEY[] = "movie-fragments-present"; 60 61static const char PVMP4METADATA_TOOL_KEY[] = "tool"; 62static const char PVMP4METADATA_WRITER_KEY[] = "writer"; 63static const char PVMP4METADATA_GROUPING_KEY[] = "grouping"; 64static const char PVMP4METADATA_TRACKDATA_KEY[] = "track data"; 65static const char PVMP4METADATA_COMPILATION_KEY[] = "compilation"; 66static const char PVMP4METADATA_TEMPO_KEY[] = "tempo"; 67static const char PVMP4METADATA_COVER_KEY[] = "cover"; 68static const char PVMP4METADATA_DISKDATA_KEY[] = "disk"; 69static const char PVMP4METADATA_FREEFORMDATA_KEY[] = "free form data"; 70static const char PVMP4METADATA_CDDBID_KEY[] = "CD identifier"; 71static const char PVMP4METADATA_LYRICS_KEY[] = "lyrics"; 72static const char PVMP4METADATA_RANDOM_ACCESS_DENIED_KEY[] = "random-access-denied"; 73////////////////////////////////////////////////////////// 74 75static const char PVMP4METADATA_TRACKINFO_TYPE_KEY[] = "track-info/type"; 76static const char PVMP4METADATA_TRACKINFO_TRACKID_KEY[] = "track-info/track-id"; 77static const char PVMP4METADATA_TRACKINFO_DURATION_KEY[] = "track-info/duration"; 78static const char PVMP4METADATA_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate"; 79static const char PVMP4METADATA_TRACKINFO_SAMPLECOUNT_KEY[] = "track-info/num-samples"; 80static const char PVMP4METADATA_TRACKINFO_SELECTED_KEY[] = "track-info/selected"; 81 82static const char PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY[] = "track-info/audio/format"; 83static const char PVMP4METADATA_TRACKINFO_AUDIO_NUMCHANNELS_KEY[] = "track-info/audio/channels"; 84static const char PVMP4METADATA_TRACKINFO_SAMPLERATE_KEY[] = "track-info/sample-rate"; 85static const char PVMP4METADATA_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY[] = "track-info/audio/bits-per-sample"; 86 87static const char PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY[] = "track-info/video/format"; 88static const char PVMP4METADATA_TRACKINFO_VIDEO_WIDTH_KEY[] = "track-info/video/width"; 89static const char PVMP4METADATA_TRACKINFO_VIDEO_HEIGHT_KEY[] = "track-info/video/height"; 90static const char PVMP4METADATA_TRACKINFO_VIDEO_PROFILE_KEY[] = "track-info/video/profile"; 91static const char PVMP4METADATA_TRACKINFO_VIDEO_LEVEL_KEY[] = "track-info/video/level"; 92static const char PVMP4METADATA_TRACKINFO_FRAME_RATE_KEY[] = "track-info/frame-rate"; 93static const char PVMP4METADATA_TRACKINFO_TRACK_NUMBER_KEY[] = "track-info/track-number"; 94static const char PVMP4METADATA_TRACKINFO_NUM_KEY_SAMPLES_KEY[] = "track-info/num-key-samples"; 95 96static const char PVMP4METADATA_MAJORBRAND_KEY[] = "mp4ff/major-brand"; 97static const char PVMP4METADATA_COMPATIBLEBRAND_KEY[] = "mp4ff/compatible-brand"; 98 99static const char PVMP4METADATA_SEMICOLON[] = ";"; 100static const char PVMP4METADATA_TIMESCALE[] = "timescale="; 101static const char PVMP4METADATA_INDEX[] = "index="; 102static const char PVMP4METADATA_LANG_CODE[] = "iso-639-2-lang="; 103static const char PVMP4METADATA_NOT_SOTRABLE[] = "not-storable"; 104static const char PVMP4METADATA_MAXSIZE[] = "maxsize="; 105static const char PVMP4METADATA_REQ_SIZE[] = "reqsize="; 106static const char PVMP4METADATA_ORIG_CHAR_ENC[] = "orig-char-enc="; 107 108#define PVMF_MP4_MIME_FORMAT_AUDIO_UNKNOWN "x-pvmf/audio/unknown" 109#define PVMF_MP4_MIME_FORMAT_VIDEO_UNKNOWN "x-pvmf/video/unknown" 110#define PVMF_MP4_MIME_FORMAT_UNKNOWN "x-pvmf/unknown-media/unknown" 111 112#define MILLISECOND_TIMESCALE (1000) 113#define PVMF_MP4_MAX_UINT32 (0xffffffffU) 114 115uint32 PVMFMP4FFParserNode::GetNumMetadataKeys(char* aQueryKeyString) 116{ 117 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::GetNumMetadataKeys() called")); 118 119 uint32 num_entries = 0; 120 121 if (aQueryKeyString == NULL) 122 { 123 // No query key so just return all the available keys 124 num_entries = iAvailableMetadataKeys.size(); 125 } 126 else 127 { 128 // Determine the number of metadata keys based on the query key string provided 129 for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++) 130 { 131 // Check if the key matches the query key 132 if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0) 133 { 134 num_entries++; 135 } 136 } 137 } 138 if ((iCPMMetaDataExtensionInterface != NULL) && 139 (iProtectedFile == true)) 140 { 141 num_entries += 142 iCPMMetaDataExtensionInterface->GetNumMetadataKeys(aQueryKeyString); 143 } 144 return num_entries; 145} 146 147 148uint32 PVMFMP4FFParserNode::GetNumMetadataValues(PVMFMetadataList& aKeyList) 149{ 150 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::GetNumMetadataValues() called")); 151 152 153 if (aKeyList.size() == 0) 154 { 155 return 0; 156 } 157 158 uint32 numvalentries = 0; 159 160 if ((iCPMMetaDataExtensionInterface != NULL) && 161 (iProtectedFile == true)) 162 { 163 numvalentries += 164 iCPMMetaDataExtensionInterface->GetNumMetadataValues(aKeyList); 165 } 166 167 if (iMP4FileHandle == NULL) 168 { 169 return numvalentries; 170 } 171 172 int32 iNumTracks = iMP4FileHandle->getNumTracks(); 173 uint32 iIdList[16]; 174 if (iNumTracks != iMP4FileHandle->getTrackIDList(iIdList, iNumTracks)) 175 { 176 return 0; 177 } 178 // Retrieve the track ID list 179 OsclExclusiveArrayPtr<uint32> trackidlistexclusiveptr; 180 uint32* trackidlist = NULL; 181 uint32 numTracks = (uint32)(iNumTracks); 182 PVMFStatus status = CreateNewArray(&trackidlist, numTracks); 183 if (PVMFErrNoMemory == status) 184 { 185 return PVMFErrNoMemory; 186 } 187 oscl_memset(trackidlist, 0, sizeof(uint32)*(numTracks)); 188 iMP4FileHandle->getTrackIDList(trackidlist, numTracks); 189 trackidlistexclusiveptr.set(trackidlist); 190 191 192 uint32 numkeys = aKeyList.size(); 193 for (uint32 lcv = 0; lcv < numkeys; lcv++) 194 { 195 if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_TOOL_KEY) == 0) 196 { 197 // Tool 198 // Increment the counter for the number of values found so far 199 ++numvalentries; 200 } 201 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_WRITER_KEY) == 0) 202 { 203 // Writer 204 // Increment the counter for the number of values found so far 205 ++numvalentries; 206 } 207 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_GROUPING_KEY) == 0) 208 { 209 // Grouping 210 // Increment the counter for the number of values found so far 211 ++numvalentries; 212 } 213 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKDATA_KEY) == 0) 214 { 215 // Trackdata 216 // Increment the counter for the number of values found so far 217 ++numvalentries; 218 } 219 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_COMPILATION_KEY) == 0) && (iMP4FileHandle->IsITunesCompilationPart() == true)) 220 { 221 //Compilation 222 // Increment the counter for the number of values found so far 223 ++numvalentries; 224 } 225 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_TEMPO_KEY) == 0) 226 { 227 // Tempo 228 // Increment the counter for the number of values found so far 229 ++numvalentries; 230 } 231 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_DISKDATA_KEY) == 0) 232 { 233 // Disk data 234 // Increment the counter for the number of values found so far 235 ++numvalentries; 236 } 237 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_LYRICS_KEY) == 0) 238 { 239 // Lyrics 240 // Increment the counter for the number of values found so far 241 ++numvalentries; 242 } 243 244 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_FREEFORMDATA_KEY) == 0) 245 { 246 // Free form data 247 // Increment the counter for the number of values found so far 248 ++numvalentries; 249 } 250 251 if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_AUTHOR_KEY) == 0) && 252 (iMP4FileHandle->getNumAuthor() > 0)) 253 { 254 // Author 255 // Increment the counter for the number of values found so far 256 ++numvalentries; 257 } 258 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_ALBUM_KEY) == 0) && 259 (iMP4FileHandle->getNumAlbum() > 0)) 260 { 261 // Album 262 // Increment the counter for the number of values found so far 263 ++numvalentries; 264 } 265 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_CLIP_TYPE_KEY) == 0) 266 { 267 // clip-type 268 // Increment the counter for the number of values found so far 269 ++numvalentries; 270 } 271 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_COMMENT_KEY) == 0) && 272 (iMP4FileHandle->getNumComment() > 0)) 273 { 274 // Comment 275 // Increment the counter for the number of values found so far 276 ++numvalentries; 277 } 278 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_COVER_KEY) == 0) 279 { 280 // Cover 281 // Increment the counter for the number of values found so far 282 ++numvalentries; 283 } 284 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_RANDOM_ACCESS_DENIED_KEY) == 0) 285 { 286 /* 287 * Random Access 288 * Increment the counter for the number of values found so far 289 */ 290 ++numvalentries; 291 } 292 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_IS_MOOF_KEY) == 0) 293 { 294 /* 295 * is-moof 296 * Increment the counter for the number of values found so far 297 */ 298 ++numvalentries; 299 } 300 301 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_LOCATION_KEY) == 0) 302 { 303 /* 304 * location 305 * Determine the index requested. Default to all pictures */ 306 307 uint32 NumLocations = iMP4FileHandle->getNumAssetInfoLocationAtoms(); 308 309 if (!NumLocations) 310 break; 311 312 uint32 startindex = 0; 313 uint32 endindex = (uint32)(NumLocations - 1); 314 315 /* Check if the index parameter is present */ 316 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 317 if (indexstr != NULL) 318 { 319 /* Retrieve the index values */ 320 GetIndexParamValues(indexstr, startindex, endindex); 321 } 322 /* Validate the indices */ 323 if (startindex > endindex || startindex >= (uint32)NumLocations || endindex >= (uint32)NumLocations) 324 { 325 break; 326 } 327 /* Return a KVP for each index */ 328 for (uint32 i = startindex; i <= endindex; ++i) 329 { 330 PvmiKvp trackkvp; 331 trackkvp.key = NULL; 332 /* Increment the counter for the number of values found so far */ 333 ++numvalentries; 334 } 335 } 336 337 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_ARTIST_KEY) == 0) && 338 (iMP4FileHandle->getNumArtist() > 0)) 339 { 340 // Artist 341 // Increment the counter for the number of values found so far 342 ++numvalentries; 343 } 344 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_GENRE_KEY) == 0) && 345 (iMP4FileHandle->getNumGenre() > 0)) 346 { 347 // Genre 348 // Increment the counter for the number of values found so far 349 ++numvalentries; 350 } 351 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_KEYWORD_KEY) == 0) 352 { 353 int32 numAssetInfoKeyword = iMP4FileHandle->getNumAssetInfoKeyWordAtoms(); 354 for (int32 idx = 0; idx < numAssetInfoKeyword; idx++) 355 { 356 int32 AssetInfoKeywordCount = iMP4FileHandle->getAssetInfoNumKeyWords(idx); 357 for (int32 idy = 0; idy < AssetInfoKeywordCount; idy++) 358 { 359 360 // Increment the counter for the number of values found so far 361 ++numvalentries; 362 } 363 } 364 } 365 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_CLASSIFICATION_KEY) == 0) 366 { 367 368 int32 numAssetInfoClassification = iMP4FileHandle->getNumAssetInfoClassificationAtoms(); 369 // classification 370 // Increment the counter for the number of values found so far 371 numvalentries = numvalentries + numAssetInfoClassification; 372 } 373 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_MAJORBRAND_KEY) == 0) 374 { 375 // MAJOR BRAND 376 // Increment the counter for the number of values found so far 377 ++numvalentries; 378 } 379 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_COMPATIBLEBRAND_KEY) == 0) 380 { 381 // COMPATIBLE BRAND 382 // Increment the counter for the number of values found so far 383 ++numvalentries; 384 385 Oscl_Vector<uint32, OsclMemAllocator> *Compatiblebrand_Vec = iMP4FileHandle->getCompatibiltyList(); 386 if (Compatiblebrand_Vec) 387 { 388 numvalentries += Compatiblebrand_Vec->size(); 389 } 390 } 391 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_TITLE_KEY) == 0) && 392 (iMP4FileHandle->getNumTitle() > 0)) 393 { 394 // Title 395 // Increment the counter for the number of values found so far 396 numvalentries = numvalentries + iMP4FileHandle->getNumTitle(); 397 } 398 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_DESCRIPTION_KEY) == 0) && 399 (iMP4FileHandle->getNumDescription() > 0)) 400 { 401 // Description 402 // Increment the counter for the number of values found so far 403 numvalentries = numvalentries + iMP4FileHandle->getNumDescription(); 404 } 405 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_RATING_KEY) == 0) && 406 (iMP4FileHandle->getNumRating() > 0)) 407 { 408 // Rating 409 // Increment the counter for the number of values found so far 410 numvalentries = numvalentries + iMP4FileHandle->getNumRating(); 411 } 412 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_COPYRIGHT_KEY) == 0) && 413 (iMP4FileHandle->getNumCopyright() > 0)) 414 { 415 // Copyright 416 // Increment the counter for the number of values found so far 417 numvalentries = numvalentries + iMP4FileHandle->getNumCopyright(); 418 } 419 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_VERSION_KEY) == 0) 420 { 421 // Version 422 // Increment the counter for the number of values found so far 423 ++numvalentries; 424 } 425 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_DATE_KEY) == 0) 426 { 427 // Date 428 // Increment the counter for the number of values found so far 429 ++numvalentries; 430 } 431 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_DURATION_KEY) == 0) 432 { 433 // Movie Duration 434 // Increment the counter for the number of values found so far 435 ++numvalentries; 436 } 437 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_NUMTRACKS_KEY) == 0 && 438 iMP4FileHandle->getNumTracks() > 0) 439 { 440 // Number of tracks 441 // Increment the counter for the number of values found so far 442 ++numvalentries; 443 } 444 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP4METADATA_YEAR_KEY) == 0) && 445 (iMP4FileHandle->getNumYear() > 0)) 446 { 447 // year 448 // Increment the counter for the number of values found so far 449 numvalentries = numvalentries + iMP4FileHandle->getNumYear(); 450 } 451 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_PROFILE_KEY) != NULL) 452 { 453 // profile 454 // Determine the index requested. 455 // Check if the file has at least one track 456 int32 numtracks = iMP4FileHandle->getNumTracks(); 457 if (numtracks <= 0) 458 { 459 break; 460 } 461 uint32 startindex = 0; 462 uint32 endindex = 0; 463 // Check if the index parameter is present 464 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 465 if (indexstr != NULL) 466 { 467 // Retrieve the index values 468 GetIndexParamValues(indexstr, startindex, endindex); 469 } 470 // Validate the indices - there should only be one index 471 if (startindex != endindex || startindex > (uint32)(numtracks) || endindex > (uint32)(numtracks)) 472 { 473 break; 474 } 475 //get track id from index 476 uint32 trackID = startindex + 1; 477 478 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 479 iMP4FileHandle->getTrackMIMEType(trackID, trackMIMEType); 480 481 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 482 { 483 // Increment the counter for the number of values found so far 484 ++numvalentries; 485 } 486 } 487 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_LEVEL_KEY) != NULL) 488 { 489 // level 490 // Determine the index requested. 491 // Check if the file has at least one track 492 int32 numtracks = iMP4FileHandle->getNumTracks(); 493 if (numtracks <= 0) 494 { 495 break; 496 } 497 uint32 startindex = 0; 498 uint32 endindex = 0; 499 // Check if the index parameter is present 500 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 501 if (indexstr != NULL) 502 { 503 // Retrieve the index values 504 GetIndexParamValues(indexstr, startindex, endindex); 505 } 506 // Validate the indices - there should only be one index 507 if (startindex != endindex || startindex > (uint32)(numtracks) || endindex > (uint32)(numtracks)) 508 { 509 break; 510 } 511 //get track id from index 512 uint32 trackID = startindex + 1; 513 514 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 515 iMP4FileHandle->getTrackMIMEType(trackID, trackMIMEType); 516 517 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 518 { 519 // Increment the counter for the number of values found so far 520 ++numvalentries; 521 } 522 } 523 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_FRAME_RATE_KEY) != NULL) 524 { 525 // frame-rate 526 // Determine the index requested. 527 // Check if the file has at least one track 528 int32 numtracks = iMP4FileHandle->getNumTracks(); 529 if (numtracks <= 0) 530 { 531 break; 532 } 533 uint32 startindex = 0; 534 uint32 endindex = 0; 535 // Check if the index parameter is present 536 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 537 if (indexstr != NULL) 538 { 539 // Retrieve the index values 540 GetIndexParamValues(indexstr, startindex, endindex); 541 } 542 // Validate the indices - there should only be one index 543 if (startindex != endindex || startindex > (uint32)(numtracks) || endindex > (uint32)(numtracks)) 544 { 545 break; 546 } 547 //get track id from index 548 uint32 trackID = startindex + 1; 549 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 550 551 iMP4FileHandle->getTrackMIMEType(trackID, trackMIMEType); 552 553 if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V)) == 0) || 554 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) || 555 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4)) == 0)) 556 { 557 // Increment the counter for the number of values found so far 558 ++numvalentries; 559 } 560 } 561 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_TYPE_KEY) != NULL) 562 { 563 // Track type 564 565 // Determine the index requested. Default to all tracks 566 // Check if the file has at least one track 567 int32 numtracks = iMP4FileHandle->getNumTracks(); 568 if (numtracks <= 0) 569 { 570 break; 571 } 572 uint32 startindex = 0; 573 uint32 endindex = (uint32)numtracks - 1; 574 // Check if the index parameter is present 575 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 576 if (indexstr != NULL) 577 { 578 // Retrieve the index values 579 GetIndexParamValues(indexstr, startindex, endindex); 580 } 581 // Validate the indices 582 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 583 { 584 break; 585 } 586 587 // Increment the counter for the number of values found so far 588 numvalentries += (endindex + 1 - startindex); 589 } 590 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_TRACKID_KEY) != NULL) 591 { 592 // Track ID 593 594 // Determine the index requested. Default to all tracks 595 // Check if the file has at least one track 596 int32 numtracks = iMP4FileHandle->getNumTracks(); 597 if (numtracks <= 0) 598 { 599 break; 600 } 601 uint32 startindex = 0; 602 uint32 endindex = (uint32)numtracks - 1; 603 // Check if the index parameter is present 604 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 605 if (indexstr != NULL) 606 { 607 // Retrieve the index values 608 GetIndexParamValues(indexstr, startindex, endindex); 609 } 610 // Validate the indices 611 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 612 { 613 break; 614 } 615 616 // Increment the counter for the number of values found so far 617 numvalentries += (endindex + 1 - startindex); 618 } 619 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_DURATION_KEY) != NULL) 620 { 621 // Track duration 622 623 // Determine the index requested. Default to all tracks 624 // Check if the file has at least one track 625 int32 numtracks = iMP4FileHandle->getNumTracks(); 626 if (numtracks <= 0) 627 { 628 break; 629 } 630 uint32 startindex = 0; 631 uint32 endindex = (uint32)numtracks - 1; 632 // Check if the index parameter is present 633 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 634 if (indexstr != NULL) 635 { 636 // Retrieve the index values 637 GetIndexParamValues(indexstr, startindex, endindex); 638 } 639 // Validate the indices 640 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 641 { 642 break; 643 } 644 645 // Increment the counter for the number of values found so far 646 numvalentries += (endindex + 1 - startindex); 647 } 648 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_TRACK_NUMBER_KEY) != NULL) 649 { 650 uint32 numCDTrackNumber = 0; 651 652 if (iMP4FileHandle->getITunesThisTrackNo() > 0) 653 numCDTrackNumber++; 654 655 656 if (numCDTrackNumber > 0) 657 { 658 // Track Number 659 660 // Determine the index requested. Default to all tracks 661 // Check if the file has at least one track 662 int32 numtracks = iMP4FileHandle->getNumTracks(); 663 if (numtracks <= 0) 664 { 665 break; 666 } 667 uint32 startindex = 0; 668 uint32 endindex = (uint32)numtracks - 1; 669 // Check if the index parameter is present 670 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 671 if (indexstr != NULL) 672 { 673 // Retrieve the index values 674 GetIndexParamValues(indexstr, startindex, endindex); 675 } 676 // Validate the indices 677 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 678 { 679 break; 680 } 681 682 // Increment the counter for the number of values found so far 683 numvalentries += (endindex + 1 - startindex); 684 numvalentries = numCDTrackNumber * numvalentries; 685 } 686 } 687 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_BITRATE_KEY) != NULL) 688 { 689 // Track bitrate 690 691 // Determine the index requested. Default to all tracks 692 // Check if the file has at least one track 693 int32 numtracks = iMP4FileHandle->getNumTracks(); 694 if (numtracks <= 0) 695 { 696 break; 697 } 698 uint32 startindex = 0; 699 uint32 endindex = (uint32)numtracks - 1; 700 // Check if the index parameter is present 701 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 702 if (indexstr != NULL) 703 { 704 // Retrieve the index values 705 GetIndexParamValues(indexstr, startindex, endindex); 706 } 707 // Validate the indices 708 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 709 { 710 break; 711 } 712 713 // Increment the counter for the number of values found so far 714 numvalentries += (endindex + 1 - startindex); 715 } 716 else if ((oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY) != NULL) || 717 (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY) != NULL)) 718 { 719 // Audio or video track format 720 // Set index for track type 721 uint32 tracktype = 0; // 0 unknown, 1 video, 2 audio 722 if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY) != NULL) 723 { 724 tracktype = 1; 725 } 726 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY) != NULL) 727 { 728 tracktype = 2; 729 } 730 731 // Determine the index requested. Default to all tracks 732 // Check if the file has at least one track 733 int32 numtracks = iMP4FileHandle->getNumTracks(); 734 if (numtracks <= 0) 735 { 736 break; 737 } 738 uint32 startindex = 0; 739 uint32 endindex = (uint32)numtracks - 1; 740 // Check if the index parameter is present 741 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 742 if (indexstr != NULL) 743 { 744 // Retrieve the index values 745 GetIndexParamValues(indexstr, startindex, endindex); 746 } 747 // Validate the indices 748 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 749 { 750 break; 751 } 752 753 // Return a KVP for each index 754 for (uint32 i = startindex; i <= endindex; ++i) 755 { 756 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 757 758 iMP4FileHandle->getTrackMIMEType(trackidlist[i], trackMIMEType); 759 760 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V)) == 0) 761 { 762 if (tracktype == 1) 763 { 764 ++numvalentries; 765 } 766 } 767 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 768 { 769 if (tracktype == 1) 770 { 771 ++numvalentries; 772 } 773 } 774 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4)) == 0) 775 { 776 if (tracktype == 1) 777 { 778 ++numvalentries; 779 } 780 } 781 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_MPEG4_AUDIO, oscl_strlen(PVMF_MIME_MPEG4_AUDIO)) == 0) 782 { 783 if (tracktype == 2) 784 { 785 ++numvalentries; 786 } 787 } 788 else if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMR_IETF, oscl_strlen(PVMF_MIME_AMR_IETF)) == 0) || 789 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMRWB_IETF, oscl_strlen(PVMF_MIME_AMRWB_IETF)) == 0)) 790 { 791 if (tracktype == 2) 792 { 793 ++numvalentries; 794 } 795 } 796 } 797 } 798 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_WIDTH_KEY) != NULL) 799 { 800 // Video track width 801 802 // Determine the index requested. Default to all tracks 803 // Check if the file has at least one track 804 int32 numtracks = iMP4FileHandle->getNumTracks(); 805 if (numtracks <= 0) 806 { 807 break; 808 } 809 uint32 startindex = 0; 810 uint32 endindex = (uint32)numtracks - 1; 811 // Check if the index parameter is present 812 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 813 if (indexstr != NULL) 814 { 815 // Retrieve the index values 816 GetIndexParamValues(indexstr, startindex, endindex); 817 } 818 // Validate the indices 819 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 820 { 821 break; 822 } 823 824 // Return a KVP for each index 825 for (uint32 i = startindex; i <= endindex; ++i) 826 { 827 PvmiKvp trackkvp; 828 trackkvp.key = NULL; 829 830 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_VISUAL) 831 { 832 // Increment the counter for the number of values found so far 833 numvalentries++; 834 } 835 } 836 } 837 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_HEIGHT_KEY) != NULL) 838 { 839 // Video track height 840 841 // Determine the index requested. Default to all tracks 842 // Check if the file has at least one track 843 int32 numtracks = iMP4FileHandle->getNumTracks(); 844 if (numtracks <= 0) 845 { 846 break; 847 } 848 uint32 startindex = 0; 849 uint32 endindex = (uint32)numtracks - 1; 850 // Check if the index parameter is present 851 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 852 if (indexstr != NULL) 853 { 854 // Retrieve the index values 855 GetIndexParamValues(indexstr, startindex, endindex); 856 } 857 // Validate the indices 858 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 859 { 860 break; 861 } 862 863 // Return a KVP for each index 864 for (uint32 i = startindex; i <= endindex; ++i) 865 { 866 PvmiKvp trackkvp; 867 trackkvp.key = NULL; 868 869 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_VISUAL) 870 { 871 // Increment the counter for the number of values found so far 872 numvalentries++; 873 } 874 } 875 } 876 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_SAMPLERATE_KEY) != NULL) 877 { 878 // Sampling rate (only for video tracks) 879 880 // Determine the index requested. Default to all tracks 881 // Check if the file has at least one track 882 int32 numtracks = iMP4FileHandle->getNumTracks(); 883 if (numtracks <= 0) 884 { 885 break; 886 } 887 uint32 startindex = 0; 888 uint32 endindex = (uint32)numtracks - 1; 889 // Check if the index parameter is present 890 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 891 if (indexstr != NULL) 892 { 893 // Retrieve the index values 894 GetIndexParamValues(indexstr, startindex, endindex); 895 } 896 // Validate the indices 897 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 898 { 899 break; 900 } 901 902 // Return a KVP for each index 903 for (uint32 i = startindex; i <= endindex; ++i) 904 { 905 PvmiKvp trackkvp; 906 trackkvp.key = NULL; 907 908 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_AUDIO) 909 { 910 // Increment the counter for the number of values found so far 911 numvalentries++; 912 } 913 } 914 } 915 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_SAMPLECOUNT_KEY) != NULL) 916 { 917 // Sample count 918 919 // Determine the index requested. Default to all tracks 920 // Check if the file has at least one track 921 int32 numtracks = iMP4FileHandle->getNumTracks(); 922 if (numtracks <= 0) 923 { 924 break; 925 } 926 uint32 startindex = 0; 927 uint32 endindex = (uint32)numtracks - 1; 928 // Check if the index parameter is present 929 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 930 if (indexstr != NULL) 931 { 932 // Retrieve the index values 933 GetIndexParamValues(indexstr, startindex, endindex); 934 } 935 // Validate the indices 936 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 937 { 938 break; 939 } 940 941 // Return a KVP for each index 942 for (uint32 i = startindex; i <= endindex; ++i) 943 { 944 PvmiKvp trackkvp; 945 trackkvp.key = NULL; 946 947 // Increment the counter for the number of values found so far 948 numvalentries++; 949 } 950 } 951 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_SELECTED_KEY) != NULL) 952 { 953 // Track selected info 954 955 // Determine the index requested. Default to all tracks 956 // Check if the file has at least one track 957 int32 numtracks = iMP4FileHandle->getNumTracks(); 958 if (numtracks <= 0) 959 { 960 break; 961 } 962 uint32 startindex = 0; 963 uint32 endindex = (uint32)numtracks - 1; 964 // Check if the index parameter is present 965 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 966 if (indexstr != NULL) 967 { 968 // Retrieve the index values 969 GetIndexParamValues(indexstr, startindex, endindex); 970 } 971 // Validate the indices 972 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 973 { 974 break; 975 } 976 977 // Increment the counter for the number of values found so far 978 numvalentries += (endindex + 1 - startindex); 979 } 980 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_NUM_KEY_SAMPLES_KEY) != NULL) 981 { 982 // Num-Key-Samples 983 984 // Determine the index requested. Default to all tracks 985 // Check if the file has at least one track 986 int32 numtracks = iMP4FileHandle->getNumTracks(); 987 if (numtracks <= 0) 988 { 989 break; 990 } 991 uint32 startindex = 0; 992 uint32 endindex = (uint32)numtracks - 1; 993 // Check if the index parameter is present 994 const char* indexstr = oscl_strstr(aKeyList[lcv].get_cstr(), PVMP4METADATA_INDEX); 995 if (indexstr != NULL) 996 { 997 // Retrieve the index values 998 GetIndexParamValues(indexstr, startindex, endindex); 999 } 1000 // Validate the indices 1001 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 1002 { 1003 break; 1004 } 1005 1006 // Return a KVP for each index 1007 numvalentries += endindex - startindex + 1; 1008 1009 } 1010 1011 1012 } 1013 return numvalentries; 1014} 1015 1016 1017PVMFCommandId PVMFMP4FFParserNode::GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, uint32 starting_index, int32 max_entries, char* query_key, const OsclAny* aContext) 1018{ 1019 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::GetNodeMetadataKeys() called")); 1020 1021 PVMFMP4FFParserNodeCommand cmd; 1022 cmd.PVMFMP4FFParserNodeCommand::Construct(aSessionId, PVMP4FF_NODE_CMD_GETNODEMETADATAKEYS, aKeyList, starting_index, max_entries, query_key, aContext); 1023 return QueueCommandL(cmd); 1024} 1025 1026 1027PVMFCommandId PVMFMP4FFParserNode::GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, int32 max_entries, const OsclAny* aContext) 1028{ 1029 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::GetNodeMetadataValue() called")); 1030 1031 PVMFMP4FFParserNodeCommand cmd; 1032 cmd.PVMFMP4FFParserNodeCommand::Construct(aSessionId, PVMP4FF_NODE_CMD_GETNODEMETADATAVALUES, aKeyList, aValueList, starting_index, max_entries, aContext); 1033 return QueueCommandL(cmd); 1034} 1035 1036 1037PVMFStatus PVMFMP4FFParserNode::ReleaseNodeMetadataKeys(PVMFMetadataList& , uint32 , uint32) 1038{ 1039 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::ReleaseNodeMetadataKeys() called")); 1040 1041 // Nothing needed-- there's no dynamic allocation in this node's key list 1042 return PVMFSuccess; 1043} 1044 1045 1046PVMFStatus PVMFMP4FFParserNode::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, 1047 uint32 start, 1048 uint32 end) 1049{ 1050 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues() called")); 1051 1052 if (start > end || aValueList.size() == 0) 1053 { 1054 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues() Invalid start/end index")); 1055 return PVMFErrArgument; 1056 } 1057 1058 end = iMP4ParserNodeMetadataValueCount; 1059 1060 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues() - iMP4ParserNodeMetadataValueCount=%d", iMP4ParserNodeMetadataValueCount)); 1061 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues() - Start=%d, End=%d", start, end)); 1062 1063 for (uint32 i = start; i < end; i++) 1064 { 1065 char* key = aValueList[i].key; 1066 if (key != NULL) 1067 { 1068 switch (GetValTypeFromKeyString(key)) 1069 { 1070 case PVMI_KVPVALTYPE_WCHARPTR: 1071 if (aValueList[i].value.pWChar_value != NULL) 1072 { 1073 OSCL_ARRAY_DELETE(aValueList[i].value.pWChar_value); 1074 aValueList[i].value.pWChar_value = NULL; 1075 } 1076 break; 1077 1078 case PVMI_KVPVALTYPE_CHARPTR: 1079 if (aValueList[i].value.pChar_value != NULL) 1080 { 1081 OSCL_ARRAY_DELETE(aValueList[i].value.pChar_value); 1082 aValueList[i].value.pChar_value = NULL; 1083 } 1084 break; 1085 1086 case PVMI_KVPVALTYPE_UINT32: 1087 case PVMI_KVPVALTYPE_FLOAT: 1088 case PVMI_KVPVALTYPE_BOOL: 1089 // No need to free memory for this valtype 1090 break; 1091 1092 1093 case PVMI_KVPVALTYPE_KSV: 1094 1095 1096 /* if (aValueList[i].value.key_specific_value != NULL) 1097 { 1098 1099 if( ((PvmfApicStruct *)aValueList[i].value.key_specific_value)->iGraphicData != NULL) 1100 { 1101 oscl_free(((PvmfApicStruct *)aValueList[i].value.key_specific_value)->iGraphicData); //OSCL_DEFAULT_FREE(((PvmfApicStruct *)aValueKVP.value.key_specific_value)->iGraphicMimeType); 1102 ((PvmfApicStruct *)aValueList[i].value.key_specific_value)->iGraphicData=NULL; 1103 } 1104 1105 OSCL_DELETE(((PvmfApicStruct *)aValueList[i].value.key_specific_value)); 1106 1107 aValueList[i].value.key_specific_value=NULL; 1108 1109 } 1110 */ 1111 break; 1112 1113 default: 1114 { 1115 // Should not get a value that wasn't created from this node 1116 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues - ErrKey=%s", aValueList[i].key)); 1117 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues - Key Not Created By This Node")); 1118 OSCL_ASSERT(false); 1119 } 1120 break; 1121 } 1122 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues - Deleting - Index=%d, Key=%s", i, aValueList[i].key)); 1123 OSCL_ARRAY_DELETE(aValueList[i].key); 1124 aValueList[i].key = NULL; 1125 } 1126 } 1127 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::ReleaseNodeMetadataValues() complete")); 1128 return PVMFSuccess; 1129} 1130 1131 1132void PVMFMP4FFParserNode::PushToAvailableMetadataKeysList(const char* aKeystr, char* aOptionalParam) 1133{ 1134 if (aKeystr == NULL) 1135 { 1136 return; 1137 } 1138 1139 if (aOptionalParam) 1140 { 1141 iAvailableMetadataKeys.push_front(aKeystr); 1142 iAvailableMetadataKeys[0] += aOptionalParam; 1143 } 1144 1145 else 1146 { 1147 iAvailableMetadataKeys.push_front(aKeystr); 1148 } 1149} 1150 1151 1152 1153int32 PVMFMP4FFParserNode::CountMetaDataKeys() 1154{ 1155 MP4FFParserOriginalCharEnc charType; 1156 if (iMP4FileHandle == NULL) 1157 { 1158 return -1; 1159 } 1160 1161 int32 NumMetaDataKeysAvailable = 0; 1162 1163 int32 iNumTracks = iMP4FileHandle->getNumTracks(); 1164 uint32 iIdList[16]; 1165 if (iNumTracks != iMP4FileHandle->getTrackIDList(iIdList, iNumTracks)) 1166 { 1167 return -1; 1168 } 1169 1170 1171 1172 1173 for (int32 i = iNumTracks - 1; i >= 0; i--) 1174 { 1175 uint32 trackID = iIdList[i]; 1176 1177 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 1178 1179 iMP4FileHandle->getTrackMIMEType(trackID, trackMIMEType); 1180 1181 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 1182 { 1183 //track id is a one based index 1184 NumMetaDataKeysAvailable += 2; 1185 } 1186 if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V)) == 0) || 1187 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) || 1188 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4)) == 0)) 1189 { 1190 NumMetaDataKeysAvailable += 4; 1191 } 1192 if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_MPEG4_AUDIO, oscl_strlen(PVMF_MIME_MPEG4_AUDIO)) == 0) || 1193 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMR, oscl_strlen(PVMF_MIME_AMR)) == 0) || 1194 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMR_IETF, oscl_strlen(PVMF_MIME_AMR_IETF)) == 0) || 1195 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMRWB_IETF, oscl_strlen(PVMF_MIME_AMRWB_IETF)) == 0)) 1196 { 1197 NumMetaDataKeysAvailable += 3; 1198 } 1199 } 1200 1201 if (iMP4FileHandle->getNumAuthor() > 0) 1202 { 1203 NumMetaDataKeysAvailable++; 1204 } 1205 //Common Keys 1206 if (iMP4FileHandle->getNumAlbum() > 0) 1207 { 1208 NumMetaDataKeysAvailable++; 1209 } 1210 1211 1212 if (iMP4FileHandle->getNumArtist() > 0) 1213 { 1214 NumMetaDataKeysAvailable++; 1215 } 1216 1217 if (iMP4FileHandle->getNumGenre() > 0) 1218 { 1219 NumMetaDataKeysAvailable++; 1220 } 1221 1222 1223 if (iMP4FileHandle->getNumYear() > 0) 1224 { 1225 NumMetaDataKeysAvailable++; 1226 } 1227 1228 if (iMP4FileHandle->getNumTitle() > 0) 1229 { 1230 NumMetaDataKeysAvailable++; 1231 } 1232 if (iMP4FileHandle->getNumCopyright() > 0) 1233 { 1234 NumMetaDataKeysAvailable++; 1235 } 1236 1237 if (iMP4FileHandle->getNumComment() > 0) 1238 { 1239 NumMetaDataKeysAvailable++; 1240 } 1241 1242 if (iMP4FileHandle->getNumDescription() > 0) 1243 { 1244 NumMetaDataKeysAvailable++; 1245 } 1246 1247 if (iMP4FileHandle->getNumRating() > 0) 1248 { 1249 NumMetaDataKeysAvailable++; 1250 } 1251 1252 if (iMP4FileHandle->getNumAssetInfoKeyWordAtoms() > 0) 1253 { 1254 NumMetaDataKeysAvailable++; 1255 } 1256 if (iMP4FileHandle->getNumAssetInfoClassificationAtoms() > 0) 1257 { 1258 NumMetaDataKeysAvailable++; 1259 } 1260 if (iMP4FileHandle->getCompatibiltyMajorBrand() > 0) 1261 { 1262 NumMetaDataKeysAvailable++; 1263 } 1264 1265 if (iMP4FileHandle->getCompatibiltyList() != NULL) 1266 { 1267 if (iMP4FileHandle->getCompatibiltyList()->size() > 0) 1268 { 1269 NumMetaDataKeysAvailable++; 1270 } 1271 } 1272 1273 if (iMP4FileHandle->getPVVersion(charType).get_size() > 0) 1274 { 1275 NumMetaDataKeysAvailable++; 1276 } 1277 1278 if (iMP4FileHandle->getCreationDate(charType).get_size() > 0) 1279 { 1280 NumMetaDataKeysAvailable++; 1281 } 1282 1283 if (iMP4FileHandle->getMovieDuration() > (uint64)0) 1284 { 1285 NumMetaDataKeysAvailable++; 1286 } 1287 1288 if (iMP4FileHandle->getITunesBeatsPerMinute() > 0) 1289 { 1290 NumMetaDataKeysAvailable++; 1291 } 1292 1293 if (iMP4FileHandle->getITunesCDIdentifierData(0).get_size() > 0) 1294 { 1295 NumMetaDataKeysAvailable++; 1296 } 1297 1298 if (iMP4FileHandle->getITunesGroupData().get_size() > 0) 1299 { 1300 NumMetaDataKeysAvailable++; 1301 } 1302 if (iMP4FileHandle->getITunesImageData() != NULL) 1303 { 1304 NumMetaDataKeysAvailable++; 1305 } 1306 if (iMP4FileHandle->getITunesLyrics().get_size() > 0) 1307 { 1308 NumMetaDataKeysAvailable++; 1309 } 1310 if (iMP4FileHandle->getITunesNormalizationData().get_size() > 0) 1311 { 1312 NumMetaDataKeysAvailable++; 1313 } 1314 if (iMP4FileHandle->getITunesThisDiskNo() > 0) 1315 { 1316 NumMetaDataKeysAvailable++; 1317 } 1318 if (iMP4FileHandle->getITunesThisTrackNo() > 0) 1319 { 1320 NumMetaDataKeysAvailable++; 1321 } 1322 if (iMP4FileHandle->getITunesTool().get_size() > 0) 1323 { 1324 NumMetaDataKeysAvailable++; 1325 } 1326 if (iMP4FileHandle->getITunesTotalDisks() > 0) 1327 { 1328 NumMetaDataKeysAvailable++; 1329 } 1330 if (iMP4FileHandle->getITunesTotalTracks() > 0) 1331 { 1332 NumMetaDataKeysAvailable++; 1333 } 1334 if (iMP4FileHandle->getITunesWriter().get_size() > 0) 1335 { 1336 NumMetaDataKeysAvailable++; 1337 } 1338 1339 1340 NumMetaDataKeysAvailable++; 1341 1342 int32 numtracks = iMP4FileHandle->getNumTracks(); 1343 if (numtracks > 0) 1344 { 1345 NumMetaDataKeysAvailable += 8; 1346 } 1347 return NumMetaDataKeysAvailable; 1348} 1349 1350 1351PVMFStatus PVMFMP4FFParserNode::InitMetaData() 1352{ 1353 MP4FFParserOriginalCharEnc charType; 1354 // Populate the available metadata keys based on what's available in the MP4 file 1355 if (iMP4FileHandle == NULL) 1356 { 1357 return PVMFErrNoResources; 1358 } 1359 int32 leavecode = 0; 1360 1361 int32 AvailableMetaDataKeysCount = CountMetaDataKeys(); 1362 OSCL_TRY(leavecode, iAvailableMetadataKeys.reserve(AvailableMetaDataKeysCount)); 1363 1364 int32 iNumTracks = iMP4FileHandle->getNumTracks(); 1365 uint32 iIdList[16]; 1366 1367 if (iNumTracks != iMP4FileHandle->getTrackIDList(iIdList, iNumTracks)) 1368 { 1369 return PVMFFailure; 1370 } 1371 for (int32 i = iNumTracks - 1; i >= 0; i--) 1372 { 1373 //track id is a one based index 1374 char indexparam[18]; 1375 oscl_snprintf(indexparam, 18, ";index=%d", i); 1376 indexparam[17] = '\0'; 1377 1378 uint32 trackID = iIdList[i]; 1379 1380 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 1381 1382 iMP4FileHandle->getTrackMIMEType(trackID, (OSCL_String&)trackMIMEType); 1383 1384 if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000))) == 0) 1385 { 1386 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_VIDEO_PROFILE_KEY, indexparam); 1387 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_VIDEO_LEVEL_KEY, indexparam); 1388 } 1389 1390 if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V)) == 0) || 1391 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) || 1392 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4)) == 0)) 1393 { 1394 uint64 trackduration = iMP4FileHandle->getTrackMediaDuration(trackID); 1395 uint32 samplecount = iMP4FileHandle->getSampleCountInTrack(trackID); 1396 1397 MediaClockConverter mcc(iMP4FileHandle->getTrackMediaTimescale(trackID)); 1398 mcc.update_clock(trackduration); 1399 uint32 TrackDurationInSec = mcc.get_converted_ts(1); 1400 uint32 frame_rate = 0; 1401 uint32 OverflowThreshold = PVMF_MP4_MAX_UINT32 / MILLISECOND_TIMESCALE; 1402 // If overflow could not happen, we calculate it in millisecond 1403 if (TrackDurationInSec < OverflowThreshold && samplecount < OverflowThreshold) 1404 { 1405 uint32 TrackDurationInMilliSec = mcc.get_converted_ts(MILLISECOND_TIMESCALE); 1406 if (TrackDurationInMilliSec > 0) 1407 { 1408 frame_rate = samplecount * MILLISECOND_TIMESCALE / TrackDurationInMilliSec; 1409 } 1410 } 1411 else // if overflow could happen when calculate in millisecond, we calculate it in second 1412 { 1413 if (TrackDurationInSec > 0) 1414 { 1415 frame_rate = samplecount / TrackDurationInSec; 1416 } 1417 } 1418 if (frame_rate > 0) 1419 { 1420 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_FRAME_RATE_KEY, indexparam); 1421 } 1422 if (PVMFSuccess == PopulateVideoDimensions(trackID)) 1423 { 1424 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_VIDEO_WIDTH_KEY, indexparam); 1425 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_VIDEO_HEIGHT_KEY, indexparam); 1426 } 1427 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY, indexparam); 1428 } 1429 1430 if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_MPEG4_AUDIO, oscl_strlen(PVMF_MIME_MPEG4_AUDIO)) == 0) || 1431 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMR, oscl_strlen(PVMF_MIME_AMR)) == 0) || 1432 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMR_IETF, oscl_strlen(PVMF_MIME_AMR_IETF)) == 0) || 1433 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMRWB_IETF, oscl_strlen(PVMF_MIME_AMRWB_IETF)) == 0)) 1434 { 1435 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY, indexparam); 1436 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_AUDIO_NUMCHANNELS_KEY, indexparam); 1437 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_SAMPLERATE_KEY, indexparam); 1438 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY, indexparam); 1439 } 1440 } 1441 1442 if (iMP4FileHandle->getNumAuthor() > 0) 1443 { 1444 PushToAvailableMetadataKeysList(PVMP4METADATA_AUTHOR_KEY); 1445 } 1446 1447 //Common Keys 1448 if (iMP4FileHandle->getNumAlbum() > 0) 1449 { 1450 PushToAvailableMetadataKeysList(PVMP4METADATA_ALBUM_KEY); 1451 } 1452 if (iMP4FileHandle->getNumComment() > 0) 1453 { 1454 PushToAvailableMetadataKeysList(PVMP4METADATA_COMMENT_KEY); 1455 } 1456 if (iMP4FileHandle->getNumGenre() > 0) 1457 { 1458 PushToAvailableMetadataKeysList(PVMP4METADATA_GENRE_KEY); 1459 } 1460 if (iMP4FileHandle->getNumTitle() > 0) 1461 { 1462 PushToAvailableMetadataKeysList(PVMP4METADATA_TITLE_KEY); 1463 } 1464 if (iMP4FileHandle->getNumCopyright() > 0) 1465 { 1466 PushToAvailableMetadataKeysList(PVMP4METADATA_COPYRIGHT_KEY); 1467 } 1468 if (iMP4FileHandle->getNumYear() > 0) 1469 { 1470 PushToAvailableMetadataKeysList(PVMP4METADATA_YEAR_KEY); 1471 } 1472 if (iMP4FileHandle->getNumArtist() > 0) 1473 { 1474 PushToAvailableMetadataKeysList(PVMP4METADATA_ARTIST_KEY); 1475 } 1476 if (iMP4FileHandle->getNumDescription() > 0) 1477 { 1478 PushToAvailableMetadataKeysList(PVMP4METADATA_DESCRIPTION_KEY); 1479 } 1480 1481 if (iMP4FileHandle->getNumRating() > 0) 1482 { 1483 PushToAvailableMetadataKeysList(PVMP4METADATA_RATING_KEY); 1484 } 1485 1486 1487 if (iMP4FileHandle->getNumAssetInfoLocationAtoms() > 0) 1488 { 1489 uint32 numLocations = iMP4FileHandle->getNumAssetInfoLocationAtoms(); 1490 if (numLocations > 0) 1491 { 1492 //PushToAvailableMetadataKeysList(PVMP4METADATA_LOCATION_KEY); 1493 // Create the parameter string for the index range 1494 char indexparam[18]; 1495 oscl_snprintf(indexparam, 18, ";index=0...%d", (numLocations - 1)); 1496 indexparam[17] = '\0'; 1497 1498 PushToAvailableMetadataKeysList(PVMP4METADATA_LOCATION_KEY, indexparam); 1499 } 1500 1501 } 1502 if (iMP4FileHandle->getNumAssetInfoKeyWordAtoms() > 0) 1503 { 1504 PushToAvailableMetadataKeysList(PVMP4METADATA_KEYWORD_KEY); 1505 } 1506 if (iMP4FileHandle->getNumAssetInfoClassificationAtoms() > 0) 1507 { 1508 PushToAvailableMetadataKeysList(PVMP4METADATA_CLASSIFICATION_KEY); 1509 } 1510 if (iMP4FileHandle->getCompatibiltyMajorBrand() > 0) 1511 { 1512 PushToAvailableMetadataKeysList(PVMP4METADATA_MAJORBRAND_KEY); 1513 } 1514 1515 if (iMP4FileHandle->getCompatibiltyList() != NULL) 1516 { 1517 if (iMP4FileHandle->getCompatibiltyList()->size() > 0) 1518 { 1519 PushToAvailableMetadataKeysList(PVMP4METADATA_COMPATIBLEBRAND_KEY); 1520 } 1521 } 1522 1523 if (iMP4FileHandle->getPVVersion(charType).get_size() > 0) 1524 { 1525 PushToAvailableMetadataKeysList(PVMP4METADATA_VERSION_KEY); 1526 } 1527 1528 if (iMP4FileHandle->getCreationDate(charType).get_size() > 0) 1529 { 1530 PushToAvailableMetadataKeysList(PVMP4METADATA_DATE_KEY); 1531 } 1532 1533 if (iMP4FileHandle->getMovieDuration() > (uint64)0) 1534 { 1535 PushToAvailableMetadataKeysList(PVMP4METADATA_DURATION_KEY); 1536 // Intimate the Duration info available to the engine through Informational Event. 1537 uint64 duration64 = iMP4FileHandle->getMovieDuration(); 1538 uint32 durationms = 0; 1539 uint32 duration = durationms = Oscl_Int64_Utils::get_uint64_lower32(duration64); 1540 uint32 timescale = iMP4FileHandle->getMovieTimescale(); 1541 if (timescale > 0 && timescale != 1000) 1542 { 1543 // Convert to milliseconds 1544 MediaClockConverter mcc(timescale); 1545 mcc.update_clock(duration); 1546 durationms = mcc.get_converted_ts(1000); 1547 } 1548 CreateDurationInfoMsg(durationms); 1549 } 1550 1551 if (iMP4FileHandle->getITunesBeatsPerMinute() > 0) 1552 { 1553 PushToAvailableMetadataKeysList(PVMP4METADATA_TEMPO_KEY); 1554 } 1555 1556 if (iMP4FileHandle->getITunesCDIdentifierData(0).get_size() > 0) 1557 { 1558 PushToAvailableMetadataKeysList(PVMP4METADATA_CDDBID_KEY); 1559 } 1560 if (iMP4FileHandle->getITunesGroupData().get_size() > 0) 1561 { 1562 PushToAvailableMetadataKeysList(PVMP4METADATA_GROUPING_KEY); 1563 } 1564 if (iMP4FileHandle->getITunesImageData() != NULL) 1565 { 1566 PushToAvailableMetadataKeysList(PVMP4METADATA_COVER_KEY); 1567 } 1568 if (iMP4FileHandle->getITunesLyrics().get_size() > 0) 1569 { 1570 PushToAvailableMetadataKeysList(PVMP4METADATA_LYRICS_KEY); 1571 } 1572 if (iMP4FileHandle->getITunesNormalizationData().get_size() > 0) 1573 { 1574 PushToAvailableMetadataKeysList(PVMP4METADATA_FREEFORMDATA_KEY); 1575 } 1576 if (iMP4FileHandle->getITunesThisDiskNo() > 0) 1577 { 1578 PushToAvailableMetadataKeysList(PVMP4METADATA_DISKDATA_KEY); 1579 } 1580 if (iMP4FileHandle->getITunesThisTrackNo() > 0) 1581 { 1582 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKDATA_KEY); 1583 } 1584 if (iMP4FileHandle->getITunesTool().get_size() > 0) 1585 { 1586 PushToAvailableMetadataKeysList(PVMP4METADATA_TOOL_KEY); 1587 } 1588 if (iMP4FileHandle->getITunesWriter().get_size() > 0) 1589 { 1590 PushToAvailableMetadataKeysList(PVMP4METADATA_WRITER_KEY); 1591 } 1592 if (iMP4FileHandle->IsITunesCompilationPart() != false) 1593 { 1594 PushToAvailableMetadataKeysList(PVMP4METADATA_COMPILATION_KEY); 1595 } 1596 1597 PushToAvailableMetadataKeysList(PVMP4METADATA_CLIP_TYPE_KEY); 1598 1599 PushToAvailableMetadataKeysList(PVMP4METADATA_RANDOM_ACCESS_DENIED_KEY); 1600 1601 PushToAvailableMetadataKeysList(PVMP4METADATA_IS_MOOF_KEY); 1602 1603 int32 numtracks = iMP4FileHandle->getNumTracks(); 1604 if (numtracks > 0) 1605 { 1606 PushToAvailableMetadataKeysList(PVMP4METADATA_NUMTRACKS_KEY); 1607 1608 //Create the parameter string for the index range 1609 char indexparam[18]; 1610 oscl_snprintf(indexparam, 18, ";index=0...%d", (numtracks - 1)); 1611 indexparam[17] = '\0'; 1612 1613 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_TYPE_KEY, indexparam); 1614 1615 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_TRACKID_KEY, indexparam); 1616 1617 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_DURATION_KEY, indexparam); 1618 1619 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_BITRATE_KEY, indexparam); 1620 1621 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_SAMPLECOUNT_KEY, indexparam); 1622 1623 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_SELECTED_KEY, indexparam); 1624 1625 if (iMP4FileHandle->getITunesThisTrackNo() > 0) 1626 { 1627 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_TRACK_NUMBER_KEY, indexparam); 1628 } 1629 1630 PushToAvailableMetadataKeysList(PVMP4METADATA_TRACKINFO_NUM_KEY_SAMPLES_KEY, indexparam); 1631 } 1632 1633 //set clip duration on download progress interface 1634 //applicable to PDL sessions 1635 { 1636 if (iMP4FileHandle != NULL) 1637 { 1638 MediaClockConverter mcc(iMP4FileHandle->getMovieTimescale()); 1639 uint32 movieduration = 1640 Oscl_Int64_Utils::get_uint64_lower32(iMP4FileHandle->getMovieDuration()); 1641 mcc.update_clock(movieduration); 1642 uint32 moviedurationInMS = mcc.get_converted_ts(1000); 1643 if ((download_progress_interface != NULL) && (moviedurationInMS != 0)) 1644 { 1645 download_progress_interface->setClipDuration(OSCL_CONST_CAST(uint32, moviedurationInMS)); 1646 } 1647 } 1648 } 1649 return PVMFSuccess; 1650} 1651 1652PVMFStatus 1653PVMFMP4FFParserNode::DoGetMetadataKeys(PVMFMP4FFParserNodeCommand& aCmd) 1654{ 1655 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::DoGetMetadataKeys() In")); 1656 /* Get Metadata keys from CPM for protected content only */ 1657 if ((iCPMMetaDataExtensionInterface != NULL) && 1658 (iProtectedFile == true)) 1659 { 1660 GetCPMMetaDataKeys(); 1661 return PVMFPending; 1662 } 1663 if (iMP4FileHandle == NULL) 1664 { 1665 return PVMFErrInvalidState; 1666 } 1667 return (CompleteGetMetadataKeys(aCmd)); 1668} 1669 1670PVMFStatus PVMFMP4FFParserNode::CompleteGetMetadataKeys(PVMFMP4FFParserNodeCommand& aCmd) 1671{ 1672 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::CompleteGetMetadataKeys() In")); 1673 1674 PVMFMetadataList* keylistptr = NULL; 1675 uint32 starting_index; 1676 int32 max_entries; 1677 char* query_key = NULL; 1678 1679 aCmd.PVMFMP4FFParserNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key); 1680 1681 // Check parameters 1682 if (keylistptr == NULL) 1683 { 1684 // The list pointer is invalid 1685 return PVMFErrArgument; 1686 } 1687 1688 if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0) 1689 { 1690 // Invalid starting index and/or max entries 1691 return PVMFErrArgument; 1692 } 1693 1694 // Copy the requested keys 1695 uint32 num_entries = 0; 1696 int32 num_added = 0; 1697 uint32 lcv = 0; 1698 for (lcv = 0; lcv < iCPMMetadataKeys.size(); lcv++) 1699 { 1700 if (query_key == NULL) 1701 { 1702 /* No query key so this key is counted */ 1703 ++num_entries; 1704 if (num_entries > starting_index) 1705 { 1706 /* Past the starting index so copy the key */ 1707 PVMFStatus status = PushValueToList(iCPMMetadataKeys, keylistptr, lcv); 1708 if (PVMFErrNoMemory == status) 1709 { 1710 return status; 1711 } 1712 num_added++; 1713 } 1714 } 1715 else 1716 { 1717 /* Check if the key matches the query key */ 1718 if (pv_mime_strcmp(iCPMMetadataKeys[lcv].get_cstr(), query_key) >= 0) 1719 { 1720 /* This key is counted */ 1721 ++num_entries; 1722 if (num_entries > starting_index) 1723 { 1724 /* Past the starting index so copy the key */ 1725 PVMFStatus status = PushValueToList(iCPMMetadataKeys, keylistptr, lcv); 1726 if (PVMFErrNoMemory == status) 1727 { 1728 return status; 1729 } 1730 num_added++; 1731 } 1732 } 1733 } 1734 /* Check if max number of entries have been copied */ 1735 if ((max_entries > 0) && (num_added >= max_entries)) 1736 { 1737 break; 1738 } 1739 } 1740 for (lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++) 1741 { 1742 if (query_key == NULL) 1743 { 1744 // No query key so this key is counted 1745 ++num_entries; 1746 if (num_entries > starting_index) 1747 { 1748 // Past the starting index so copy the key 1749 PVMFStatus status = PushValueToList(iAvailableMetadataKeys, keylistptr, lcv); 1750 if (PVMFErrNoMemory == status) 1751 { 1752 return status; 1753 } 1754 num_added++; 1755 } 1756 } 1757 else 1758 { 1759 // Check if the key matche the query key 1760 if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0) 1761 { 1762 // This key is counted 1763 ++num_entries; 1764 if (num_entries > starting_index) 1765 { 1766 // Past the starting index so copy the key 1767 PVMFStatus status = PushValueToList(iAvailableMetadataKeys, keylistptr, lcv); 1768 if (PVMFErrNoMemory == status) 1769 { 1770 return status; 1771 } 1772 num_added++; 1773 } 1774 } 1775 } 1776 1777 // Check if max number of entries have been copied 1778 if (max_entries > 0 && num_added >= max_entries) 1779 { 1780 break; 1781 } 1782 } 1783 return PVMFSuccess; 1784} 1785 1786 1787PVMFStatus PVMFMP4FFParserNode::DoGetMetadataValues(PVMFMP4FFParserNodeCommand& aCmd) 1788{ 1789 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFMP4FFParserNode::DoGetMetadataValues() In")); 1790 1791 PVMFMetadataList* keylistptr_in = NULL; 1792 PVMFMetadataList* keylistptr = NULL; 1793 OSCL_wHeapString<OsclMemAllocator> valuestring = NULL; 1794 Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL; 1795 uint32 starting_index; 1796 int32 max_entries; 1797 MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN; 1798 uint16 iLangCode = 0; 1799 aCmd.PVMFMP4FFParserNodeCommand::Parse(keylistptr_in, 1800 valuelistptr, 1801 starting_index, 1802 max_entries); 1803 1804 // Check the parameters 1805 if (keylistptr_in == NULL || valuelistptr == NULL) 1806 { 1807 return PVMFErrArgument; 1808 } 1809 1810 keylistptr = keylistptr_in; 1811 //If numkeys is one, just check to see if the request 1812 //is for ALL metadata 1813 if (keylistptr_in->size() == 1) 1814 { 1815 if (oscl_strncmp((*keylistptr)[0].get_cstr(), 1816 PVMP4_ALL_METADATA_KEY, 1817 oscl_strlen(PVMP4_ALL_METADATA_KEY)) == 0) 1818 { 1819 //use the complete metadata key list 1820 keylistptr = &iAvailableMetadataKeys; 1821 } 1822 } 1823 uint32 numkeys = keylistptr->size(); 1824 1825 if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0) 1826 { 1827 // Don't do anything 1828 return PVMFErrArgument; 1829 } 1830 1831 uint32 numvalentries = 0; 1832 int32 numentriesadded = 0; 1833 uint32 lcv = 0; 1834 1835 if (iMP4FileHandle != NULL) 1836 { 1837 // Retrieve the track ID list 1838 OsclExclusiveArrayPtr<uint32> trackidlistexclusiveptr; 1839 uint32* trackidlist = NULL; 1840 uint32 numTracks = (uint32)(iMP4FileHandle->getNumTracks()); 1841 PVMFStatus status = CreateNewArray(&trackidlist, numTracks); 1842 if (PVMFErrNoMemory == status) 1843 { 1844 return PVMFErrNoMemory; 1845 } 1846 oscl_memset(trackidlist, 0, sizeof(uint32)*(numTracks)); 1847 iMP4FileHandle->getTrackIDList(trackidlist, numTracks); 1848 trackidlistexclusiveptr.set(trackidlist); 1849 1850 1851 for (lcv = 0; lcv < numkeys; lcv++) 1852 { 1853 int32 leavecode = 0; 1854 PvmiKvp KeyVal; 1855 KeyVal.key = NULL; 1856 KeyVal.value.pWChar_value = NULL; 1857 KeyVal.value.pChar_value = NULL; 1858 int32 idx = 0; 1859 char orig_char_enc[2][7] = {"UTF-8", "UTF-16"}; 1860 1861 // const char *x = (*keylistptr)[lcv].get_cstr(); 1862 bool IsMetadataValAddedBefore = false; 1863 1864 if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_AUTHOR_KEY) == 0) 1865 { 1866 // Author 1867 1868 uint32 countAuthor = 0; 1869 countAuthor = iMP4FileHandle->getNumAuthor(); 1870 1871 if (countAuthor > 0) 1872 { 1873 for (idx = 0; idx < (int32)countAuthor ; idx++) 1874 { 1875 // Increment the counter for the number of values found so far 1876 ++numvalentries; 1877 1878 // Create a value entry if past the starting index 1879 if (numvalentries > starting_index) 1880 { 1881 1882 if (!iMP4FileHandle->getAuthor(idx, valuestring, iLangCode, charType)) 1883 { 1884 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::DoGetMetadataValues - getAuthor Failed")); 1885 return PVMFFailure; 1886 } 1887 1888 1889 char lang_param[43]; 1890 if (iLangCode != 0) 1891 { 1892 int8 LangCode[4]; 1893 getLanguageCode(iLangCode, LangCode); 1894 LangCode[3] = '\0'; 1895 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 1896 lang_param[20] = '\0'; 1897 } 1898 else 1899 { 1900 lang_param[0] = '\0'; 1901 } 1902 KeyVal.key = NULL; 1903 KeyVal.value.pWChar_value = NULL; 1904 KeyVal.value.pChar_value = NULL; 1905 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 1906 { 1907 char char_enc_param[22]; 1908 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 1909 char_enc_param[21] = '\0'; 1910 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 1911 } 1912 PVMFStatus retval = 1913 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 1914 PVMP4METADATA_AUTHOR_KEY, 1915 valuestring, 1916 lang_param); 1917 if (retval != PVMFSuccess && retval != PVMFErrArgument) 1918 { 1919 break; 1920 } 1921 // Add the KVP to the list if the key string was created 1922 if (KeyVal.key != NULL) 1923 { 1924 leavecode = AddToValueList(*valuelistptr, KeyVal); 1925 if (leavecode != 0) 1926 { 1927 if (KeyVal.value.pWChar_value != NULL) 1928 { 1929 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 1930 KeyVal.value.pWChar_value = NULL; 1931 } 1932 1933 OSCL_ARRAY_DELETE(KeyVal.key); 1934 KeyVal.key = NULL; 1935 } 1936 else 1937 { 1938 // Increment the value list entry counter 1939 ++numentriesadded; 1940 IsMetadataValAddedBefore = true; 1941 } 1942 1943 // Check if the max number of value entries were added 1944 if (max_entries > 0 && numentriesadded >= max_entries) 1945 { 1946 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 1947 return PVMFSuccess; 1948 } 1949 } 1950 1951 } 1952 } 1953 1954 } 1955 } 1956 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TOOL_KEY) == 0) 1957 { 1958 1959 KeyVal.key = NULL; 1960 KeyVal.value.pWChar_value = NULL; 1961 KeyVal.value.pChar_value = NULL; 1962 1963 // Increment the counter for the number of values found so far 1964 ++numvalentries; 1965 1966 // Create a value entry if past the starting index 1967 if (numvalentries > starting_index) 1968 { 1969 1970 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getITunesTool(); 1971 PVMFStatus retval = 1972 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 1973 PVMP4METADATA_TOOL_KEY, 1974 valuestring); 1975 1976 if (retval != PVMFSuccess && retval != PVMFErrArgument) 1977 { 1978 break; 1979 } 1980 else 1981 { 1982 IsMetadataValAddedBefore = false; 1983 1984 } 1985 1986 } 1987 1988 } 1989 1990 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_WRITER_KEY) == 0) 1991 { 1992 KeyVal.key = NULL; 1993 KeyVal.value.pWChar_value = NULL; 1994 KeyVal.value.pChar_value = NULL; 1995 // Increment the counter for the number of values found so far 1996 ++numvalentries; 1997 1998 // Create a value entry if past the starting index 1999 if (numvalentries > starting_index) 2000 { 2001 2002 2003 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getITunesWriter(); 2004 PVMFStatus retval = 2005 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2006 PVMP4METADATA_WRITER_KEY, 2007 valuestring); 2008 2009 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2010 { 2011 break; 2012 } 2013 else 2014 { 2015 IsMetadataValAddedBefore = false; 2016 2017 } 2018 2019 } 2020 } 2021 2022 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_GROUPING_KEY) == 0) 2023 { 2024 2025 2026 KeyVal.key = NULL; 2027 KeyVal.value.pWChar_value = NULL; 2028 KeyVal.value.pChar_value = NULL; 2029 2030 // Increment the counter for the number of values found so far 2031 ++numvalentries; 2032 2033 // Create a value entry if past the starting index 2034 if (numvalentries > starting_index) 2035 { 2036 2037 2038 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getITunesGroupData(); 2039 PVMFStatus retval = 2040 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2041 PVMP4METADATA_GROUPING_KEY, 2042 valuestring); 2043 2044 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2045 { 2046 break; 2047 } 2048 else 2049 { 2050 IsMetadataValAddedBefore = false; 2051 2052 } 2053 2054 } 2055 2056 } 2057 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKDATA_KEY) == 0) 2058 { 2059 2060 KeyVal.key = NULL; 2061 KeyVal.value.pWChar_value = NULL; 2062 KeyVal.value.pChar_value = NULL; 2063 // Increment the counter for the number of values found so far 2064 ++numvalentries; 2065 2066 // Create a value entry if past the starting index 2067 if (numvalentries > starting_index) 2068 { 2069 2070 uint32 numtracks = iMP4FileHandle->getITunesThisTrackNo(); 2071 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVMP4METADATA_TRACKDATA_KEY, numtracks); 2072 2073 2074 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2075 { 2076 break; 2077 } 2078 else 2079 { 2080 2081 IsMetadataValAddedBefore = false; 2082 2083 } 2084 2085 } 2086 2087 } 2088 2089 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_COMPILATION_KEY) == 0) 2090 { 2091 2092 KeyVal.key = NULL; 2093 KeyVal.value.pWChar_value = NULL; 2094 KeyVal.value.pChar_value = NULL; 2095 2096 // Increment the counter for the number of values found so far 2097 ++numvalentries; 2098 2099 // Create a value entry if past the starting index 2100 if (numvalentries > starting_index) 2101 { 2102 2103 2104 bool compilationPart = iMP4FileHandle->IsITunesCompilationPart(); 2105 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForBoolValue(KeyVal, PVMP4METADATA_COMPILATION_KEY, compilationPart); 2106 2107 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2108 { 2109 break; 2110 } 2111 else 2112 { 2113 2114 IsMetadataValAddedBefore = false; 2115 2116 } 2117 2118 } 2119 2120 } 2121 2122 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TEMPO_KEY) == 0) 2123 { 2124 2125 KeyVal.key = NULL; 2126 KeyVal.value.pWChar_value = NULL; 2127 KeyVal.value.pChar_value = NULL; 2128 2129 // Increment the counter for the number of values found so far 2130 ++numvalentries; 2131 2132 // Create a value entry if past the starting index 2133 if (numvalentries > starting_index) 2134 { 2135 2136 uint32 beatsperminute = iMP4FileHandle->getITunesBeatsPerMinute(); 2137 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVMP4METADATA_TEMPO_KEY, beatsperminute); 2138 2139 2140 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2141 { 2142 break; 2143 } 2144 else 2145 { 2146 2147 IsMetadataValAddedBefore = false; 2148 2149 } 2150 2151 } 2152 2153 } 2154 2155 2156 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_COVER_KEY) == 0) 2157 { 2158 2159 KeyVal.key = NULL; 2160 KeyVal.value.pWChar_value = NULL; 2161 KeyVal.value.pChar_value = NULL; 2162 2163 // Increment the counter for the number of values found so far 2164 2165 ++numvalentries; 2166 2167 // Create a value entry if past the starting index 2168 if (numvalentries > starting_index) 2169 { 2170 2171 PvmfApicStruct* imagedata = iMP4FileHandle->getITunesImageData(); 2172 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForKSVValue(KeyVal, PVMP4METADATA_COVER_KEY, OSCL_STATIC_CAST(OsclAny*, imagedata)); 2173 2174 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2175 { 2176 break; 2177 } 2178 else 2179 { 2180 2181 IsMetadataValAddedBefore = false; 2182 2183 } 2184 2185 } 2186 2187 } 2188 2189 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_DISKDATA_KEY) == 0) 2190 { 2191 2192 KeyVal.key = NULL; 2193 KeyVal.value.pWChar_value = NULL; 2194 KeyVal.value.pChar_value = NULL; 2195 2196 // Increment the counter for the number of values found so far 2197 ++numvalentries; 2198 2199 // Create a value entry if past the starting index 2200 if (numvalentries > starting_index) 2201 { 2202 2203 2204 uint32 disknum = iMP4FileHandle->getITunesThisDiskNo(); 2205 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVMP4METADATA_DISKDATA_KEY, disknum); 2206 2207 2208 2209 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2210 { 2211 break; 2212 } 2213 else 2214 { 2215 2216 IsMetadataValAddedBefore = false; 2217 2218 } 2219 2220 } 2221 2222 } 2223 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_FREEFORMDATA_KEY) == 0) 2224 { 2225 2226 KeyVal.key = NULL; 2227 KeyVal.value.pWChar_value = NULL; 2228 KeyVal.value.pChar_value = NULL; 2229 2230 // Increment the counter for the number of values found so far 2231 ++numvalentries; 2232 PVMFStatus retval; 2233 // Create a value entry if past the starting index 2234 if (numvalentries > starting_index) 2235 { 2236 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getITunesNormalizationData(); 2237 if (valuestring.get_size() > 0) 2238 { 2239 retval = 2240 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2241 PVMP4METADATA_FREEFORMDATA_KEY, 2242 valuestring); 2243 } 2244 else 2245 { 2246 OSCL_wHeapString<OsclMemAllocator> cdidentifierstring = iMP4FileHandle->getITunesCDIdentifierData(0); 2247 retval = 2248 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2249 PVMP4METADATA_FREEFORMDATA_KEY, 2250 cdidentifierstring); 2251 } 2252 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2253 { 2254 break; 2255 } 2256 else 2257 { 2258 2259 IsMetadataValAddedBefore = false; 2260 2261 } 2262 2263 } 2264 2265 } 2266 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_IS_MOOF_KEY) == 0) 2267 { 2268 /* 2269 * is-moof 2270 * Increment the counter for the number of values found so far 2271 */ 2272 ++numvalentries; 2273 2274 /* Create a value entry if past the starting index */ 2275 if (numvalentries > (uint32)starting_index) 2276 { 2277 bool is_movie_fragmnent_present = iMP4FileHandle->IsMovieFragmentsPresent(); 2278 2279 PVMFStatus retval = 2280 PVMFCreateKVPUtils::CreateKVPForBoolValue(KeyVal, 2281 PVMP4METADATA_IS_MOOF_KEY, 2282 is_movie_fragmnent_present, 2283 NULL); 2284 2285 2286 2287 2288 2289 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2290 { 2291 break; 2292 } 2293 } 2294 } 2295 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_RANDOM_ACCESS_DENIED_KEY) == 0) 2296 { 2297 /* 2298 * Random Access 2299 * Increment the counter for the number of values found so far 2300 */ 2301 ++numvalentries; 2302 2303 /* Create a value entry if past the starting index */ 2304 if (numvalentries > (uint32)starting_index) 2305 { 2306 uint64 duration64 = iMP4FileHandle->getMovieDuration(); 2307 uint32 duration = Oscl_Int64_Utils::get_uint64_lower32(duration64); 2308 bool random_access_denied = false; 2309 if (duration > 0) 2310 { 2311 random_access_denied = false; 2312 } 2313 else 2314 { 2315 random_access_denied = true; 2316 } 2317 2318 if (iMP4FileHandle->IsMovieFragmentsPresent()) 2319 { 2320 if (iDataStreamInterface != NULL) 2321 random_access_denied = true; 2322 2323 uint32* trackList = NULL; 2324 uint32 numTracks = iNodeTrackPortList.size(); 2325 CreateNewArray(&trackList, numTracks); 2326 if (trackList) 2327 { 2328 for (uint32 i = 0; i < iNodeTrackPortList.size(); i++) 2329 { 2330 // Save the track list while in this loop 2331 trackList[i] = iNodeTrackPortList[i].iTrackId; 2332 } 2333 2334 if (!iMP4FileHandle->IsTFRAPresentForAllTrack(numTracks, trackList)) 2335 random_access_denied = true; 2336 2337 OSCL_ARRAY_DELETE(trackList); 2338 } 2339 } 2340 2341 PVMFStatus retval = 2342 PVMFCreateKVPUtils::CreateKVPForBoolValue(KeyVal, 2343 PVMP4METADATA_RANDOM_ACCESS_DENIED_KEY, 2344 random_access_denied, 2345 NULL); 2346 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2347 { 2348 break; 2349 } 2350 } 2351 } 2352 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_LYRICS_KEY) == 0) 2353 { 2354 2355 KeyVal.key = NULL; 2356 KeyVal.value.pWChar_value = NULL; 2357 KeyVal.value.pChar_value = NULL; 2358 2359 // Increment the counter for the number of values found so far 2360 ++numvalentries; 2361 2362 // Create a value entry if past the starting index 2363 if (numvalentries > starting_index) 2364 { 2365 2366 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getITunesLyrics(); 2367 PVMFStatus retval = 2368 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2369 PVMP4METADATA_LYRICS_KEY, 2370 valuestring); 2371 2372 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2373 { 2374 break; 2375 } 2376 else 2377 { 2378 2379 IsMetadataValAddedBefore = false; 2380 2381 } 2382 2383 } 2384 2385 } 2386 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_CLIP_TYPE_KEY) == 0) 2387 { 2388 // clip-type 2389 // Increment the counter for the number of values found so far 2390 ++numvalentries; 2391 2392 // Create a value entry if past the starting index 2393 if (numvalentries > starting_index) 2394 { 2395 uint32 len = 0; 2396 char* clipType = NULL; 2397 if (download_progress_interface != NULL) 2398 { 2399 len = oscl_strlen("download"); 2400 clipType = OSCL_ARRAY_NEW(char, len + 1); 2401 oscl_memset(clipType, 0, len + 1); 2402 oscl_strncpy(clipType, ("download"), len); 2403 } 2404 else 2405 { 2406 len = oscl_strlen("local"); 2407 clipType = OSCL_ARRAY_NEW(char, len + 1); 2408 oscl_memset(clipType, 0, len + 1); 2409 oscl_strncpy(clipType, ("local"), len); 2410 } 2411 2412 PVMFStatus retval = 2413 PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal, 2414 PVMP4METADATA_CLIP_TYPE_KEY, 2415 clipType); 2416 2417 OSCL_ARRAY_DELETE(clipType); 2418 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2419 { 2420 break; 2421 } 2422 } 2423 } 2424 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_ALBUM_KEY) == 0) 2425 { 2426 // Album 2427 2428 uint32 countAlbum = 0; 2429 countAlbum = iMP4FileHandle->getNumAlbum(); 2430 2431 if (countAlbum > 0) 2432 { 2433 for (idx = 0; idx < (int32)countAlbum ; idx++) 2434 { 2435 // Increment the counter for the number of values found so far 2436 ++numvalentries; 2437 2438 // Create a value entry if past the starting index 2439 if (numvalentries > starting_index) 2440 { 2441 2442 if (iMP4FileHandle->getAlbum(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 2443 { 2444 2445 char lang_param[43]; 2446 if (iLangCode != 0) 2447 { 2448 int8 LangCode[4]; 2449 getLanguageCode(iLangCode, LangCode); 2450 LangCode[3] = '\0'; 2451 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 2452 lang_param[20] = '\0'; 2453 } 2454 else 2455 { 2456 lang_param[0] = '\0'; 2457 } 2458 KeyVal.key = NULL; 2459 KeyVal.value.pWChar_value = NULL; 2460 KeyVal.value.pChar_value = NULL; 2461 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 2462 { 2463 char char_enc_param[22]; 2464 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 2465 char_enc_param[21] = '\0'; 2466 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 2467 } 2468 2469 2470 PVMFStatus retval = 2471 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2472 PVMP4METADATA_ALBUM_KEY, 2473 valuestring, 2474 lang_param); 2475 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2476 { 2477 break; 2478 } 2479 // Add the KVP to the list if the key string was created 2480 if (KeyVal.key != NULL) 2481 { 2482 leavecode = AddToValueList(*valuelistptr, KeyVal); 2483 if (leavecode != 0) 2484 { 2485 if (KeyVal.value.pWChar_value != NULL) 2486 { 2487 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 2488 KeyVal.value.pWChar_value = NULL; 2489 } 2490 2491 OSCL_ARRAY_DELETE(KeyVal.key); 2492 KeyVal.key = NULL; 2493 } 2494 else 2495 { 2496 // Increment the value list entry counter 2497 ++numentriesadded; 2498 IsMetadataValAddedBefore = true; 2499 } 2500 2501 // Check if the max number of value entries were added 2502 if (max_entries > 0 && numentriesadded >= max_entries) 2503 { 2504 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 2505 return PVMFSuccess; 2506 } 2507 } 2508 } 2509 2510 } 2511 } 2512 2513 } 2514 } 2515 2516 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_COMMENT_KEY) == 0) 2517 { 2518 // Comment 2519 2520 uint32 countComment = 0; 2521 countComment = iMP4FileHandle->getNumComment(); 2522 2523 if (countComment > 0) 2524 { 2525 for (idx = 0; idx < (int32)countComment ; idx++) 2526 { 2527 // Increment the counter for the number of values found so far 2528 ++numvalentries; 2529 2530 // Create a value entry if past the starting index 2531 if (numvalentries > starting_index) 2532 { 2533 2534 if (iMP4FileHandle->getComment(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 2535 { 2536 2537 char lang_param[43]; 2538 if (iLangCode != 0) 2539 { 2540 int8 LangCode[4]; 2541 getLanguageCode(iLangCode, LangCode); 2542 LangCode[3] = '\0'; 2543 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 2544 lang_param[20] = '\0'; 2545 } 2546 else 2547 { 2548 lang_param[0] = '\0'; 2549 } 2550 KeyVal.key = NULL; 2551 KeyVal.value.pWChar_value = NULL; 2552 KeyVal.value.pChar_value = NULL; 2553 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 2554 { 2555 char char_enc_param[22]; 2556 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 2557 char_enc_param[21] = '\0'; 2558 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 2559 } 2560 PVMFStatus retval = 2561 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2562 PVMP4METADATA_COMMENT_KEY, 2563 valuestring, 2564 lang_param); 2565 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2566 { 2567 break; 2568 } 2569 // Add the KVP to the list if the key string was created 2570 if (KeyVal.key != NULL) 2571 { 2572 leavecode = AddToValueList(*valuelistptr, KeyVal); 2573 if (leavecode != 0) 2574 { 2575 if (KeyVal.value.pWChar_value != NULL) 2576 { 2577 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 2578 KeyVal.value.pWChar_value = NULL; 2579 } 2580 2581 OSCL_ARRAY_DELETE(KeyVal.key); 2582 KeyVal.key = NULL; 2583 } 2584 else 2585 { 2586 // Increment the value list entry counter 2587 ++numentriesadded; 2588 IsMetadataValAddedBefore = true; 2589 } 2590 2591 // Check if the max number of value entries were added 2592 if (max_entries > 0 && numentriesadded >= max_entries) 2593 { 2594 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 2595 return PVMFSuccess; 2596 } 2597 } 2598 } 2599 2600 } 2601 } 2602 2603 } 2604 } 2605 else if ((oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_LOCATION_KEY) != NULL)) 2606 { 2607 /* Location */ 2608 /* Determine the index requested. Default to all pictures */ 2609 uint32 startindex = 0; 2610 int32 numLocationRecords = 0; 2611 numLocationRecords = iMP4FileHandle->getNumAssetInfoLocationAtoms(); 2612 2613 uint32 endindex = numLocationRecords - 1; 2614 2615 /* Check if the index parameter is present */ 2616 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 2617 if (indexstr != NULL) 2618 { 2619 /* Retrieve the index values */ 2620 GetIndexParamValues(indexstr, startindex, endindex); 2621 } 2622 /* Validate the indices */ 2623 if (startindex > endindex || (int32)startindex >= numLocationRecords || (int32)endindex >= numLocationRecords) 2624 { 2625 break; 2626 } 2627 PvmfAssetInfo3GPPLocationStruct* pLocationRecord; 2628 2629 /* Return a KVP for each index */ 2630 for (uint32 cnt = startindex; (int32)cnt < numLocationRecords; cnt++) 2631 { 2632 pLocationRecord = iMP4FileHandle->getAssetInfoLocationStruct(cnt); 2633 char indexparam[29]; 2634 2635 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, cnt); 2636 indexparam[15] = '\0'; 2637 2638 PvmiKvp KeyVal; 2639 KeyVal.key = NULL; 2640 /* Increment the counter for the number of values found so far */ 2641 ++numvalentries; 2642 /* Add the value entry if past the starting index */ 2643 PVMFStatus retval = PVMFErrArgument; 2644 if (numvalentries > starting_index) 2645 { 2646 2647 retval = PVMFCreateKVPUtils::CreateKVPForKSVValue(KeyVal, 2648 PVMP4METADATA_LOCATION_KEY, 2649 OSCL_STATIC_CAST(OsclAny*, pLocationRecord), 2650 indexparam); 2651 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2652 { 2653 break; 2654 } 2655 } 2656 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2657 { 2658 break; 2659 } 2660 if (KeyVal.key != NULL) 2661 { 2662 PVMFStatus status = PushKVPToMetadataValueList(valuelistptr, KeyVal); 2663 if (status != PVMFSuccess) 2664 { 2665 return status; 2666 } 2667 // Increment the counter for number of value entries added to the list 2668 ++numentriesadded; 2669 IsMetadataValAddedBefore = true; 2670 2671 /* Check if the max number of value entries were added */ 2672 if (max_entries > 0 && numentriesadded >= max_entries) 2673 { 2674 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 2675 return PVMFSuccess; 2676 } 2677 } 2678 2679 } 2680 } 2681 2682 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TITLE_KEY) == 0) 2683 { 2684 // Title 2685 2686 uint32 countTitle = 0; 2687 countTitle = iMP4FileHandle->getNumTitle(); 2688 2689 if (countTitle > 0) 2690 { 2691 for (idx = 0; idx < (int32)countTitle ; idx++) 2692 { 2693 // Increment the counter for the number of values found so far 2694 ++numvalentries; 2695 2696 // Create a value entry if past the starting index 2697 if (numvalentries > starting_index) 2698 { 2699 2700 if (iMP4FileHandle->getTitle(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 2701 { 2702 2703 2704 2705 char lang_param[43]; 2706 if (iLangCode != 0) 2707 { 2708 int8 LangCode[4]; 2709 getLanguageCode(iLangCode, LangCode); 2710 LangCode[3] = '\0'; 2711 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 2712 lang_param[20] = '\0'; 2713 } 2714 else 2715 { 2716 lang_param[0] = '\0'; 2717 } 2718 KeyVal.key = NULL; 2719 KeyVal.value.pWChar_value = NULL; 2720 KeyVal.value.pChar_value = NULL; 2721 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 2722 { 2723 char char_enc_param[22]; 2724 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 2725 char_enc_param[21] = '\0'; 2726 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 2727 } 2728 PVMFStatus retval = 2729 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2730 PVMP4METADATA_TITLE_KEY, 2731 valuestring, 2732 lang_param); 2733 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2734 { 2735 break; 2736 } 2737 // Add the KVP to the list if the key string was created 2738 if (KeyVal.key != NULL) 2739 { 2740 leavecode = AddToValueList(*valuelistptr, KeyVal); 2741 if (leavecode != 0) 2742 { 2743 if (KeyVal.value.pWChar_value != NULL) 2744 { 2745 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 2746 KeyVal.value.pWChar_value = NULL; 2747 } 2748 2749 OSCL_ARRAY_DELETE(KeyVal.key); 2750 KeyVal.key = NULL; 2751 } 2752 else 2753 { 2754 // Increment the value list entry counter 2755 ++numentriesadded; 2756 IsMetadataValAddedBefore = true; 2757 } 2758 2759 // Check if the max number of value entries were added 2760 if (max_entries > 0 && numentriesadded >= max_entries) 2761 { 2762 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 2763 return PVMFSuccess; 2764 } 2765 } 2766 } 2767 2768 } 2769 } 2770 2771 } 2772 } 2773 2774 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_DESCRIPTION_KEY) == 0) 2775 { 2776 // Description 2777 2778 uint32 countDescription = 0; 2779 countDescription = iMP4FileHandle->getNumDescription(); 2780 2781 if (countDescription > 0) 2782 { 2783 for (idx = 0; idx < (int32)countDescription ; idx++) 2784 { 2785 // Increment the counter for the number of values found so far 2786 ++numvalentries; 2787 2788 // Create a value entry if past the starting index 2789 if (numvalentries > starting_index) 2790 { 2791 2792 if (iMP4FileHandle->getDescription(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 2793 { 2794 2795 2796 char lang_param[43]; 2797 if (iLangCode != 0) 2798 { 2799 int8 LangCode[4]; 2800 getLanguageCode(iLangCode, LangCode); 2801 LangCode[3] = '\0'; 2802 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 2803 lang_param[20] = '\0'; 2804 } 2805 else 2806 { 2807 lang_param[0] = '\0'; 2808 } 2809 KeyVal.key = NULL; 2810 KeyVal.value.pWChar_value = NULL; 2811 KeyVal.value.pChar_value = NULL; 2812 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 2813 { 2814 char char_enc_param[22]; 2815 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 2816 char_enc_param[21] = '\0'; 2817 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 2818 } 2819 PVMFStatus retval = 2820 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2821 PVMP4METADATA_DESCRIPTION_KEY, 2822 valuestring, 2823 lang_param); 2824 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2825 { 2826 break; 2827 } 2828 // Add the KVP to the list if the key string was created 2829 if (KeyVal.key != NULL) 2830 { 2831 leavecode = AddToValueList(*valuelistptr, KeyVal); 2832 if (leavecode != 0) 2833 { 2834 if (KeyVal.value.pWChar_value != NULL) 2835 { 2836 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 2837 KeyVal.value.pWChar_value = NULL; 2838 } 2839 2840 OSCL_ARRAY_DELETE(KeyVal.key); 2841 KeyVal.key = NULL; 2842 } 2843 else 2844 { 2845 // Increment the value list entry counter 2846 ++numentriesadded; 2847 IsMetadataValAddedBefore = true; 2848 } 2849 2850 // Check if the max number of value entries were added 2851 if (max_entries > 0 && numentriesadded >= max_entries) 2852 { 2853 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 2854 return PVMFSuccess; 2855 } 2856 } 2857 } 2858 2859 } 2860 } 2861 2862 } 2863 } 2864 2865 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_RATING_KEY) == 0) 2866 { 2867 // Rating 2868 2869 uint32 countRating = iMP4FileHandle->getNumRating(); 2870 2871 if (countRating > 0) 2872 { 2873 for (idx = 0; idx < (int32)countRating ; idx++) 2874 { 2875 // Increment the counter for the number of values found so far 2876 ++numvalentries; 2877 2878 // Create a value entry if past the starting index 2879 if (numvalentries > starting_index) 2880 { 2881 2882 if (iMP4FileHandle->getRating(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 2883 { 2884 2885 char lang_param[43]; 2886 if (iLangCode != 0) 2887 { 2888 int8 LangCode[4]; 2889 getLanguageCode(iLangCode, LangCode); 2890 LangCode[3] = '\0'; 2891 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 2892 lang_param[20] = '\0'; 2893 } 2894 else 2895 { 2896 lang_param[0] = '\0'; 2897 } 2898 KeyVal.key = NULL; 2899 KeyVal.value.pWChar_value = NULL; 2900 KeyVal.value.pChar_value = NULL; 2901 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 2902 { 2903 char char_enc_param[22]; 2904 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 2905 char_enc_param[21] = '\0'; 2906 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 2907 } 2908 PVMFStatus retval = 2909 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2910 PVMP4METADATA_RATING_KEY, 2911 valuestring, 2912 lang_param); 2913 if (retval != PVMFSuccess && retval != PVMFErrArgument) 2914 { 2915 break; 2916 } 2917 // Add the KVP to the list if the key string was created 2918 if (KeyVal.key != NULL) 2919 { 2920 leavecode = AddToValueList(*valuelistptr, KeyVal); 2921 if (leavecode != 0) 2922 { 2923 if (KeyVal.value.pWChar_value != NULL) 2924 { 2925 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 2926 KeyVal.value.pWChar_value = NULL; 2927 } 2928 2929 OSCL_ARRAY_DELETE(KeyVal.key); 2930 KeyVal.key = NULL; 2931 } 2932 else 2933 { 2934 // Increment the value list entry counter 2935 ++numentriesadded; 2936 IsMetadataValAddedBefore = true; 2937 } 2938 2939 // Check if the max number of value entries were added 2940 if (max_entries > 0 && numentriesadded >= max_entries) 2941 { 2942 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 2943 return PVMFSuccess; 2944 } 2945 } 2946 } 2947 2948 } //End of Outer If 2949 } 2950 2951 } 2952 } 2953 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_COPYRIGHT_KEY) == 0) 2954 { 2955 // Copyright 2956 2957 uint32 countCopyright = 0; 2958 countCopyright = iMP4FileHandle->getNumCopyright(); 2959 2960 if (countCopyright > 0) 2961 { 2962 for (idx = 0; idx < (int32)countCopyright ; idx++) 2963 { 2964 // Increment the counter for the number of values found so far 2965 ++numvalentries; 2966 2967 // Create a value entry if past the starting index 2968 if (numvalentries > starting_index) 2969 { 2970 2971 if (iMP4FileHandle->getCopyright(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 2972 { 2973 char lang_param[43]; 2974 if (iLangCode != 0) 2975 { 2976 int8 LangCode[4]; 2977 getLanguageCode(iLangCode, LangCode); 2978 LangCode[3] = '\0'; 2979 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 2980 lang_param[20] = '\0'; 2981 } 2982 else 2983 { 2984 lang_param[0] = '\0'; 2985 } 2986 KeyVal.key = NULL; 2987 KeyVal.value.pWChar_value = NULL; 2988 KeyVal.value.pChar_value = NULL; 2989 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 2990 { 2991 char char_enc_param[22]; 2992 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 2993 char_enc_param[21] = '\0'; 2994 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 2995 } 2996 PVMFStatus retval = 2997 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 2998 PVMP4METADATA_COPYRIGHT_KEY, 2999 valuestring, 3000 lang_param); 3001 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3002 { 3003 break; 3004 } 3005 // Add the KVP to the list if the key string was created 3006 if (KeyVal.key != NULL) 3007 { 3008 leavecode = AddToValueList(*valuelistptr, KeyVal); 3009 if (leavecode != 0) 3010 { 3011 if (KeyVal.value.pWChar_value != NULL) 3012 { 3013 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 3014 KeyVal.value.pWChar_value = NULL; 3015 } 3016 3017 OSCL_ARRAY_DELETE(KeyVal.key); 3018 KeyVal.key = NULL; 3019 } 3020 else 3021 { 3022 // Increment the value list entry counter 3023 ++numentriesadded; 3024 IsMetadataValAddedBefore = true; 3025 } 3026 3027 // Check if the max number of value entries were added 3028 if (max_entries > 0 && numentriesadded >= max_entries) 3029 { 3030 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3031 return PVMFSuccess; 3032 } 3033 } 3034 } 3035 } 3036 3037 } 3038 3039 } 3040 } 3041 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_ARTIST_KEY) == 0) 3042 { 3043 // Artist 3044 3045 uint32 countArtist = 0; 3046 countArtist = iMP4FileHandle->getNumArtist(); 3047 3048 if (countArtist > 0) 3049 { 3050 for (idx = 0; idx < (int32)countArtist ; idx++) 3051 { 3052 // Increment the counter for the number of values found so far 3053 ++numvalentries; 3054 3055 // Create a value entry if past the starting index 3056 if (numvalentries > starting_index) 3057 { 3058 3059 if (iMP4FileHandle->getArtist(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 3060 { 3061 3062 char lang_param[43]; 3063 if (iLangCode != 0) 3064 { 3065 int8 LangCode[4]; 3066 getLanguageCode(iLangCode, LangCode); 3067 LangCode[3] = '\0'; 3068 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 3069 lang_param[20] = '\0'; 3070 } 3071 else 3072 { 3073 lang_param[0] = '\0'; 3074 } 3075 KeyVal.key = NULL; 3076 KeyVal.value.pWChar_value = NULL; 3077 KeyVal.value.pChar_value = NULL; 3078 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 3079 { 3080 char char_enc_param[22]; 3081 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 3082 char_enc_param[21] = '\0'; 3083 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 3084 } 3085 PVMFStatus retval = 3086 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 3087 PVMP4METADATA_ARTIST_KEY, 3088 valuestring, 3089 lang_param); 3090 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3091 { 3092 break; 3093 } 3094 // Add the KVP to the list if the key string was created 3095 if (KeyVal.key != NULL) 3096 { 3097 leavecode = AddToValueList(*valuelistptr, KeyVal); 3098 if (leavecode != 0) 3099 { 3100 if (KeyVal.value.pWChar_value != NULL) 3101 { 3102 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 3103 KeyVal.value.pWChar_value = NULL; 3104 } 3105 3106 OSCL_ARRAY_DELETE(KeyVal.key); 3107 KeyVal.key = NULL; 3108 } 3109 else 3110 { 3111 // Increment the value list entry counter 3112 ++numentriesadded; 3113 IsMetadataValAddedBefore = true; 3114 } 3115 3116 // Check if the max number of value entries were added 3117 if (max_entries > 0 && numentriesadded >= max_entries) 3118 { 3119 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3120 return PVMFSuccess; 3121 } 3122 } 3123 } 3124 3125 } 3126 } 3127 3128 } 3129 } 3130 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_KEYWORD_KEY) == 0) 3131 { 3132 int32 numAssetInfoKeyword = iMP4FileHandle->getNumAssetInfoKeyWordAtoms(); 3133 for (idx = 0; idx < numAssetInfoKeyword; idx++) 3134 { 3135 int32 AssetInfoKeywordCount = iMP4FileHandle->getAssetInfoNumKeyWords(idx); 3136 for (int32 idy = 0; idy < AssetInfoKeywordCount; idy++) 3137 { 3138 3139 // Increment the counter for the number of values found so far 3140 ++numvalentries; 3141 3142 // Create a value entry if past the starting index 3143 if (numvalentries > starting_index) 3144 { 3145 int8 LangCode[4]; 3146 getLanguageCode(iMP4FileHandle->getAssetInfoKeyWordLangCode(idx), LangCode); 3147 LangCode[3] = '\0'; 3148 3149 char lang_param[21]; 3150 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 3151 lang_param[20] = '\0'; 3152 3153 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getAssetInfoKeyWord(idx, idy); 3154 PVMFStatus retval = 3155 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 3156 PVMP4METADATA_KEYWORD_KEY, 3157 valuestring, 3158 lang_param); 3159 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3160 { 3161 break; 3162 } 3163 // Add the KVP to the list if the key string was created 3164 if (KeyVal.key != NULL) 3165 { 3166 leavecode = AddToValueList(*valuelistptr, KeyVal); 3167 if (leavecode != 0) 3168 { 3169 if (KeyVal.value.pWChar_value != NULL) 3170 { 3171 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 3172 KeyVal.value.pWChar_value = NULL; 3173 } 3174 3175 OSCL_ARRAY_DELETE(KeyVal.key); 3176 KeyVal.key = NULL; 3177 } 3178 else 3179 { 3180 // Increment the value list entry counter 3181 ++numentriesadded; 3182 IsMetadataValAddedBefore = true; 3183 } 3184 3185 // Check if the max number of value entries were added 3186 if (max_entries > 0 && numentriesadded >= max_entries) 3187 { 3188 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3189 return PVMFSuccess; 3190 } 3191 } 3192 3193 } 3194 KeyVal.key = NULL; 3195 KeyVal.value.pWChar_value = NULL; 3196 KeyVal.value.pChar_value = NULL; 3197 } 3198 } 3199 } 3200 3201 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_GENRE_KEY) == 0) 3202 { 3203 // Genre 3204 PVMFStatus retval = PVMFFailure; 3205 uint32 countGenre = 0; 3206 countGenre = iMP4FileHandle->getNumGenre(); 3207 3208 if (countGenre > 0) 3209 { 3210 for (idx = 0; idx < (int32)countGenre ; idx++) 3211 { 3212 // Increment the counter for the number of values found so far 3213 ++numvalentries; 3214 3215 // Create a value entry if past the starting index 3216 if (numvalentries > starting_index) 3217 { 3218 3219 if (iMP4FileHandle->getGenre(idx, valuestring, iLangCode, charType) != PVMFErrArgument) 3220 { 3221 char lang_param[43]; 3222 if (iLangCode != 0) 3223 { 3224 int8 LangCode[4]; 3225 getLanguageCode(iLangCode, LangCode); 3226 LangCode[3] = '\0'; 3227 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 3228 lang_param[20] = '\0'; 3229 } 3230 else 3231 { 3232 lang_param[0] = '\0'; 3233 } 3234 KeyVal.key = NULL; 3235 KeyVal.value.pWChar_value = NULL; 3236 KeyVal.value.pChar_value = NULL; 3237 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 3238 { 3239 char char_enc_param[22]; 3240 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 3241 char_enc_param[21] = '\0'; 3242 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 3243 } 3244 retval = 3245 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 3246 PVMP4METADATA_GENRE_KEY, 3247 valuestring, 3248 lang_param); 3249 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3250 { 3251 break; 3252 } 3253 // Add the KVP to the list if the key string was created 3254 if (KeyVal.key != NULL) 3255 { 3256 leavecode = AddToValueList(*valuelistptr, KeyVal); 3257 if (leavecode != 0) 3258 { 3259 if (KeyVal.value.pWChar_value != NULL) 3260 { 3261 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 3262 KeyVal.value.pWChar_value = NULL; 3263 } 3264 3265 OSCL_ARRAY_DELETE(KeyVal.key); 3266 KeyVal.key = NULL; 3267 } 3268 else 3269 { 3270 // Increment the value list entry counter 3271 ++numentriesadded; 3272 IsMetadataValAddedBefore = true; 3273 } 3274 3275 // Check if the max number of value entries were added 3276 if (max_entries > 0 && numentriesadded >= max_entries) 3277 { 3278 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3279 return PVMFSuccess; 3280 } 3281 } 3282 } 3283 uint32 value = iMP4FileHandle->getITunesGnreID(); 3284 if ((idx == 0) && (value != 0)) 3285 { 3286 KeyVal.key = NULL; 3287 KeyVal.value.pWChar_value = NULL; 3288 KeyVal.value.pChar_value = NULL; 3289 retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVMP4METADATA_GENRE_KEY, value); 3290 3291 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3292 { 3293 break; 3294 } 3295 // Add the KVP to the list if the key string was created 3296 if (KeyVal.key != NULL) 3297 { 3298 leavecode = AddToValueList(*valuelistptr, KeyVal); 3299 if (leavecode != 0) 3300 { 3301 KeyVal.key = NULL; 3302 } 3303 else 3304 { 3305 // Increment the value list entry counter 3306 ++numentriesadded; 3307 IsMetadataValAddedBefore = true; 3308 } 3309 3310 // Check if the max number of value entries were added 3311 if (max_entries > 0 && numentriesadded >= max_entries) 3312 { 3313 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3314 return PVMFSuccess; 3315 } 3316 3317 } 3318 3319 } 3320 3321 } 3322 } 3323 3324 } 3325 } 3326 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_CLASSIFICATION_KEY) == 0) 3327 { 3328 int32 numAssetInfoClassification = iMP4FileHandle->getNumAssetInfoClassificationAtoms(); 3329 for (idx = 0; idx < numAssetInfoClassification; idx++) 3330 { 3331 // Increment the counter for the number of values found so far 3332 ++numvalentries; 3333 3334 // Create a value entry if past the starting index 3335 if (numvalentries > starting_index) 3336 { 3337 int8 LangCode[4]; 3338 getLanguageCode(iMP4FileHandle->getAssetInfoClassificationLangCode(idx), LangCode); 3339 LangCode[3] = '\0'; 3340 3341 char lang_param[43]; 3342 oscl_snprintf(lang_param, 20, ";%s%s", PVMP4METADATA_LANG_CODE, LangCode); 3343 lang_param[20] = '\0'; 3344 3345 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getAssetInfoClassificationNotice(charType, idx); 3346 if (charType != ORIGINAL_CHAR_TYPE_UNKNOWN) 3347 { 3348 char char_enc_param[22]; 3349 oscl_snprintf(char_enc_param, 22, ";%s%s", PVMP4METADATA_ORIG_CHAR_ENC, orig_char_enc[charType-1]); 3350 char_enc_param[21] = '\0'; 3351 oscl_strncat(lang_param, char_enc_param, oscl_strlen(char_enc_param)); 3352 } 3353 3354 PVMFStatus retval = 3355 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 3356 PVMP4METADATA_CLASSIFICATION_KEY, 3357 valuestring, 3358 lang_param); 3359 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3360 { 3361 break; 3362 } 3363 // Add the KVP to the list if the key string was created 3364 if (KeyVal.key != NULL) 3365 { 3366 leavecode = AddToValueList(*valuelistptr, KeyVal); 3367 if (leavecode != 0) 3368 { 3369 if (KeyVal.value.pWChar_value != NULL) 3370 { 3371 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 3372 KeyVal.value.pWChar_value = NULL; 3373 } 3374 3375 OSCL_ARRAY_DELETE(KeyVal.key); 3376 KeyVal.key = NULL; 3377 } 3378 else 3379 { 3380 // Increment the value list entry counter 3381 ++numentriesadded; 3382 IsMetadataValAddedBefore = true; 3383 } 3384 3385 // Check if the max number of value entries were added 3386 if (max_entries > 0 && numentriesadded >= max_entries) 3387 { 3388 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3389 return PVMFSuccess; 3390 } 3391 } 3392 } 3393 } 3394 } 3395 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_MAJORBRAND_KEY) == 0) 3396 { 3397 // MAJOR BRAND 3398 // Increment the counter for the number of values found so far 3399 ++numvalentries; 3400 3401 // Create a value entry if past the starting index 3402 if (numvalentries > starting_index) 3403 { 3404 char BrandCode[5]; 3405 uint32 Mbrand = iMP4FileHandle->getCompatibiltyMajorBrand(); 3406 getBrand(Mbrand, BrandCode); 3407 BrandCode[4] = '\0'; 3408 3409 PVMFStatus retval = 3410 PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal, 3411 PVMP4METADATA_MAJORBRAND_KEY, 3412 BrandCode); 3413 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3414 { 3415 break; 3416 } 3417 } 3418 } 3419 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_COMPATIBLEBRAND_KEY) == 0) 3420 { 3421 // Compatible Brand 3422 // Increment the counter for the number of values found so far 3423 ++numvalentries; 3424 3425 // Create a value entry if past the starting index 3426 if (numvalentries > starting_index) 3427 { 3428 Oscl_Vector<uint32, OsclMemAllocator> *Compatiblebrand_Vec = iMP4FileHandle->getCompatibiltyList(); 3429 uint32 idy = 0; 3430 for (idy = 0; idy < Compatiblebrand_Vec->size() ; idy++) 3431 { 3432 char BrandCode[5]; 3433 uint32 CbrandNum = (*Compatiblebrand_Vec)[idy]; 3434 getBrand(CbrandNum, BrandCode); 3435 BrandCode[4] = '\0'; 3436 KeyVal.key = NULL; 3437 KeyVal.value.pWChar_value = NULL; 3438 KeyVal.value.pChar_value = NULL; 3439 3440 PVMFStatus retval = 3441 PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal, 3442 PVMP4METADATA_COMPATIBLEBRAND_KEY, 3443 BrandCode); 3444 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3445 { 3446 break; 3447 } 3448 // Add the KVP to the list if the key string was created 3449 if (KeyVal.key != NULL) 3450 { 3451 leavecode = AddToValueList(*valuelistptr, KeyVal); 3452 if (leavecode != 0) 3453 { 3454 if (KeyVal.value.pChar_value != NULL) 3455 { 3456 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value); 3457 KeyVal.value.pChar_value = NULL; 3458 } 3459 3460 OSCL_ARRAY_DELETE(KeyVal.key); 3461 KeyVal.key = NULL; 3462 } 3463 else 3464 { 3465 // Increment the value list entry counter 3466 ++numentriesadded; 3467 IsMetadataValAddedBefore = true; 3468 } 3469 3470 // Check if the max number of value entries were added 3471 if (max_entries > 0 && numentriesadded >= max_entries) 3472 { 3473 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3474 return PVMFSuccess; 3475 } 3476 } 3477 } 3478 } 3479 } 3480 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_VERSION_KEY) == 0) 3481 { 3482 // Version 3483 // Increment the counter for the number of values found so far 3484 ++numvalentries; 3485 3486 // Create a value entry if past the starting index 3487 if (numvalentries > starting_index) 3488 { 3489 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getPVVersion(charType); 3490 PVMFStatus retval = 3491 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 3492 PVMP4METADATA_VERSION_KEY, 3493 valuestring); 3494 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3495 { 3496 break; 3497 } 3498 } 3499 } 3500 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_DATE_KEY) == 0) 3501 { 3502 // Date 3503 // Increment the counter for the number of values found so far 3504 ++numvalentries; 3505 3506 // Create a value entry if past the starting index 3507 if (numvalentries > starting_index) 3508 { 3509 OSCL_wHeapString<OsclMemAllocator> valuestring = iMP4FileHandle->getCreationDate(charType); 3510 PVMFStatus retval = 3511 PVMFCreateKVPUtils::CreateKVPForWStringValue(KeyVal, 3512 PVMP4METADATA_DATE_KEY, 3513 valuestring); 3514 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3515 { 3516 break; 3517 } 3518 } 3519 } 3520 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_PROFILE_KEY) != NULL) 3521 { 3522 // profile 3523 // Determine the index requested. 3524 // Check if the file has at least one track 3525 int32 numtracks = iMP4FileHandle->getNumTracks(); 3526 if (numtracks <= 0) 3527 { 3528 break; 3529 } 3530 uint32 startindex = 0; 3531 uint32 endindex = 0; 3532 // Check if the index parameter is present 3533 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 3534 if (indexstr != NULL) 3535 { 3536 // Retrieve the index values 3537 GetIndexParamValues(indexstr, startindex, endindex); 3538 } 3539 // Validate the indices - there should only be one index 3540 if (startindex != endindex || startindex > (uint32)(numtracks) || endindex > (uint32)(numtracks)) 3541 { 3542 break; 3543 } 3544 //get track id from index 3545 uint32 trackID = startindex + 1; 3546 uint32 iProfile = 0; 3547 3548 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 3549 3550 iMP4FileHandle->getTrackMIMEType(trackID, trackMIMEType); 3551 3552 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 3553 { 3554 H263DecoderSpecificInfo *ptr = (H263DecoderSpecificInfo *)iMP4FileHandle->getTrackDecoderSpecificInfoAtSDI(trackID, 0); 3555 iProfile = ptr->getCodecProfile(); 3556 // Increment the counter for the number of values found so far 3557 ++numvalentries; 3558 // Create a value entry if past the starting index 3559 if (numvalentries > starting_index) 3560 { 3561 char indexparam[16]; 3562 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, startindex); 3563 indexparam[15] = '\0'; 3564 3565 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, 3566 PVMP4METADATA_TRACKINFO_VIDEO_PROFILE_KEY, 3567 iProfile, 3568 indexparam); 3569 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3570 { 3571 break; 3572 } 3573 } 3574 } 3575 } 3576 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_LEVEL_KEY) != NULL) 3577 { 3578 // level 3579 // Determine the index requested. 3580 // Check if the file has at least one track 3581 int32 numtracks = iMP4FileHandle->getNumTracks(); 3582 if (numtracks <= 0) 3583 { 3584 break; 3585 } 3586 uint32 startindex = 0; 3587 uint32 endindex = 0; 3588 // Check if the index parameter is present 3589 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 3590 if (indexstr != NULL) 3591 { 3592 // Retrieve the index values 3593 GetIndexParamValues(indexstr, startindex, endindex); 3594 } 3595 // Validate the indices - there should only be one index 3596 if (startindex != endindex || startindex > (uint32)(numtracks) || endindex > (uint32)(numtracks)) 3597 { 3598 break; 3599 } 3600 //get track id from index 3601 uint32 trackID = startindex + 1; 3602 uint32 iLevel = 0; 3603 3604 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 3605 3606 iMP4FileHandle->getTrackMIMEType(trackID, trackMIMEType); 3607 3608 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 3609 { 3610 H263DecoderSpecificInfo *ptr = (H263DecoderSpecificInfo *)iMP4FileHandle->getTrackDecoderSpecificInfoAtSDI(trackID, 0); 3611 iLevel = ptr->getCodecLevel(); 3612 // Increment the counter for the number of values found so far 3613 ++numvalentries; 3614 // Create a value entry if past the starting index 3615 if (numvalentries > starting_index) 3616 { 3617 char indexparam[16]; 3618 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, startindex); 3619 indexparam[15] = '\0'; 3620 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, 3621 PVMP4METADATA_TRACKINFO_VIDEO_LEVEL_KEY, 3622 iLevel, 3623 indexparam); 3624 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3625 { 3626 break; 3627 } 3628 } 3629 } 3630 } 3631 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_FRAME_RATE_KEY) != NULL) 3632 { 3633 // level 3634 // Determine the index requested. 3635 // Check if the file has at least one track 3636 int32 numtracks = iMP4FileHandle->getNumTracks(); 3637 if (numtracks <= 0) 3638 { 3639 break; 3640 } 3641 uint32 startindex = 0; 3642 uint32 endindex = 0; 3643 // Check if the index parameter is present 3644 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 3645 if (indexstr != NULL) 3646 { 3647 // Retrieve the index values 3648 GetIndexParamValues(indexstr, startindex, endindex); 3649 } 3650 // Validate the indices - there should only be one index 3651 if (startindex != endindex || startindex > (uint32)(numtracks) || endindex > (uint32)(numtracks)) 3652 { 3653 break; 3654 } 3655 3656 //get track id from index 3657 //uint32 trackID = startindex+1; 3658 3659 uint32 iIdList[16]; 3660 iMP4FileHandle->getTrackIDList(iIdList, numtracks); 3661 uint32 trackID = iIdList[startindex]; 3662 3663 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 3664 3665 iMP4FileHandle->getTrackMIMEType(trackID, trackMIMEType); 3666 3667 if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) || 3668 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4)) == 0) || 3669 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V)) == 0)) 3670 { 3671 uint64 trackduration = iMP4FileHandle->getTrackMediaDuration(trackID); 3672 uint32 samplecount = iMP4FileHandle->getSampleCountInTrack(trackID); 3673 3674 MediaClockConverter mcc(iMP4FileHandle->getTrackMediaTimescale(trackID)); 3675 mcc.update_clock(trackduration); 3676 uint32 TrackDurationInSec = mcc.get_converted_ts(1); 3677 uint32 frame_rate = 0; 3678 3679 uint32 OverflowThreshold = PVMF_MP4_MAX_UINT32 / MILLISECOND_TIMESCALE; 3680 // If overflow could not happen, we calculate it in millisecond 3681 if (TrackDurationInSec < OverflowThreshold && samplecount < OverflowThreshold) 3682 { 3683 uint32 TrackDurationInMilliSec = mcc.get_converted_ts(MILLISECOND_TIMESCALE); 3684 if (TrackDurationInMilliSec > 0) 3685 { 3686 frame_rate = samplecount * MILLISECOND_TIMESCALE / TrackDurationInMilliSec; 3687 } 3688 else 3689 { 3690 continue; 3691 } 3692 } 3693 else // if overflow could happen when calculate in millisecond, we calculate it in second 3694 { 3695 if (TrackDurationInSec > 0) 3696 { 3697 frame_rate = samplecount / TrackDurationInSec; 3698 } 3699 else 3700 { 3701 continue; 3702 } 3703 } 3704 3705 // Increment the counter for the number of values found so far 3706 ++numvalentries; 3707 // Create a value entry if past the starting index 3708 if (numvalentries > starting_index) 3709 { 3710 char indexparam[16]; 3711 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, startindex); 3712 indexparam[15] = '\0'; 3713 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, 3714 PVMP4METADATA_TRACKINFO_FRAME_RATE_KEY, 3715 frame_rate, 3716 indexparam); 3717 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3718 { 3719 break; 3720 } 3721 } 3722 } 3723 } 3724 3725 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_DURATION_KEY) == 0 && 3726 iMP4FileHandle->getMovieDuration() > (uint64)0 && iMP4FileHandle->getMovieTimescale() > 0) 3727 { 3728 // Movie Duration 3729 // Increment the counter for the number of values found so far 3730 ++numvalentries; 3731 3732 // Create a value entry if past the starting index 3733 if (numvalentries > starting_index) 3734 { 3735 uint64 duration64 = iMP4FileHandle->getMovieDuration(); 3736 uint32 duration = Oscl_Int64_Utils::get_uint64_lower32(duration64); 3737 char timescalestr[20]; 3738 oscl_snprintf(timescalestr, 20, ";%s%d", PVMP4METADATA_TIMESCALE, iMP4FileHandle->getMovieTimescale()); 3739 timescalestr[19] = '\0'; 3740 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVMP4METADATA_DURATION_KEY, duration, timescalestr); 3741 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3742 { 3743 break; 3744 } 3745 } 3746 } 3747 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_YEAR_KEY) == 0) 3748 { 3749 // Year 3750 uint32 value = 0; 3751 uint32 countYear = 0; 3752 countYear = iMP4FileHandle->getNumYear(); 3753 3754 if (countYear > 0) 3755 { 3756 for (idx = 0; idx < (int32)countYear ; idx++) 3757 { 3758 // Increment the counter for the number of values found so far 3759 ++numvalentries; 3760 3761 // Create a value entry if past the starting index 3762 if (numvalentries > starting_index) 3763 { 3764 3765 if (!iMP4FileHandle->getYear(idx, value)) 3766 { 3767 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::DoGetMetadataValues - getYear Failed")); 3768 return PVMFFailure; 3769 } 3770 3771 PVMFStatus retval = 3772 PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, 3773 PVMP4METADATA_YEAR_KEY, value); 3774 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3775 { 3776 break; 3777 } 3778 // Add the KVP to the list if the key string was created 3779 if (KeyVal.key != NULL) 3780 { 3781 leavecode = AddToValueList(*valuelistptr, KeyVal); 3782 if (leavecode != 0) 3783 { 3784 KeyVal.key = NULL; 3785 } 3786 else 3787 { 3788 // Increment the value list entry counter 3789 ++numentriesadded; 3790 IsMetadataValAddedBefore = true; 3791 } 3792 3793 // Check if the max number of value entries were added 3794 if (max_entries > 0 && numentriesadded >= max_entries) 3795 { 3796 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 3797 return PVMFSuccess; 3798 } 3799 } 3800 3801 } 3802 } 3803 3804 } 3805 } 3806 3807 else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_NUMTRACKS_KEY) == 0 && 3808 iMP4FileHandle->getNumTracks() > 0) 3809 { 3810 // Number of tracks 3811 // Increment the counter for the number of values found so far 3812 ++numvalentries; 3813 3814 // Create a value entry if past the starting index 3815 if (numvalentries > starting_index) 3816 { 3817 uint32 numtracks = iMP4FileHandle->getNumTracks(); 3818 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVMP4METADATA_NUMTRACKS_KEY, numtracks); 3819 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3820 { 3821 break; 3822 } 3823 } 3824 } 3825 3826 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_TYPE_KEY) != NULL) 3827 { 3828 // Track type 3829 3830 // Determine the index requested. Default to all tracks 3831 // Check if the file has at least one track 3832 int32 numtracks = iMP4FileHandle->getNumTracks(); 3833 if (numtracks <= 0) 3834 { 3835 break; 3836 } 3837 uint32 startindex = 0; 3838 uint32 endindex = (uint32)numtracks - 1; 3839 // Check if the index parameter is present 3840 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 3841 if (indexstr != NULL) 3842 { 3843 // Retrieve the index values 3844 GetIndexParamValues(indexstr, startindex, endindex); 3845 } 3846 // Validate the indices 3847 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 3848 { 3849 break; 3850 } 3851 3852 // Return a KVP for each index 3853 for (uint32 i = startindex; i <= endindex; ++i) 3854 { 3855 PvmiKvp trackkvp; 3856 trackkvp.key = NULL; 3857 trackkvp.value.pChar_value = NULL; 3858 3859 char indexparam[16]; 3860 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 3861 indexparam[15] = '\0'; 3862 3863 PVMFStatus retval = PVMFErrArgument; 3864 3865 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 3866 3867 iMP4FileHandle->getTrackMIMEType(trackidlist[i], (OSCL_String&)trackMIMEType); 3868 3869 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V)) == 0) 3870 { 3871 // Increment the counter for the number of values found so far 3872 ++numvalentries; 3873 // Add the value entry if past the starting index 3874 if (numvalentries > starting_index) 3875 { 3876 retval = 3877 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, 3878 PVMP4METADATA_TRACKINFO_TYPE_KEY, 3879 _STRLIT_CHAR(PVMF_MIME_M4V), 3880 indexparam); 3881 } 3882 } 3883 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 3884 { 3885 // Increment the counter for the number of values found so far 3886 ++numvalentries; 3887 // Add the value entry if past the starting index 3888 if (numvalentries > starting_index) 3889 { 3890 retval = 3891 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, 3892 PVMP4METADATA_TRACKINFO_TYPE_KEY, 3893 _STRLIT_CHAR(PVMF_MIME_H2631998), 3894 indexparam); 3895 } 3896 } 3897 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4)) == 0) 3898 { 3899 // Increment the counter for the number of values found so far 3900 ++numvalentries; 3901 // Add the value entry if past the starting index 3902 if (numvalentries > starting_index) 3903 { 3904 retval = 3905 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_TYPE_KEY, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4), indexparam); 3906 } 3907 } 3908 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_MPEG4_AUDIO, oscl_strlen(PVMF_MIME_MPEG4_AUDIO)) == 0) 3909 { 3910 // Increment the counter for the number of values found so far 3911 ++numvalentries; 3912 // Add the value entry if past the starting index 3913 if (numvalentries > starting_index) 3914 { 3915 retval = 3916 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_TYPE_KEY, _STRLIT_CHAR(PVMF_MIME_MPEG4_AUDIO), indexparam); 3917 } 3918 } 3919 else if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMR_IETF, oscl_strlen(PVMF_MIME_AMR_IETF)) == 0) || 3920 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMRWB_IETF, oscl_strlen(PVMF_MIME_AMRWB_IETF)) == 0)) 3921 { 3922 // Increment the counter for the number of values found so far 3923 ++numvalentries; 3924 // Add the value entry if past the starting index 3925 if (numvalentries > starting_index) 3926 { 3927 retval = 3928 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_TYPE_KEY, _STRLIT_CHAR(PVMF_MIME_AMR_IETF), indexparam); 3929 } 3930 } 3931 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_3GPP_TIMEDTEXT, oscl_strlen(PVMF_MIME_3GPP_TIMEDTEXT)) == 0) 3932 { 3933 // Increment the counter for the number of values found so far 3934 ++numvalentries; 3935 // Add the value entry if past the starting index 3936 if (numvalentries > starting_index) 3937 { 3938 retval = 3939 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_TYPE_KEY, _STRLIT_CHAR(PVMF_MIME_3GPP_TIMEDTEXT), indexparam); 3940 } 3941 } 3942 else 3943 { 3944 // Increment the counter for the number of values found so far 3945 ++numvalentries; 3946 // Add the value entry if past the starting index 3947 if (numvalentries > starting_index) 3948 { 3949 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_VISUAL) 3950 { 3951 retval = 3952 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, 3953 PVMP4METADATA_TRACKINFO_TYPE_KEY, 3954 _STRLIT_CHAR(PVMF_MP4_MIME_FORMAT_VIDEO_UNKNOWN), 3955 indexparam); 3956 } 3957 else if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_AUDIO) 3958 { 3959 retval = 3960 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, 3961 PVMP4METADATA_TRACKINFO_TYPE_KEY, 3962 _STRLIT_CHAR(PVMF_MP4_MIME_FORMAT_AUDIO_UNKNOWN), 3963 indexparam); 3964 } 3965 else 3966 { 3967 retval = 3968 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, 3969 PVMP4METADATA_TRACKINFO_TYPE_KEY, 3970 _STRLIT_CHAR(PVMF_MP4_MIME_FORMAT_UNKNOWN), 3971 indexparam); 3972 3973 } 3974 3975 } 3976 3977 } 3978 3979 if (retval != PVMFSuccess && retval != PVMFErrArgument) 3980 { 3981 break; 3982 } 3983 3984 if (trackkvp.key != NULL) 3985 { 3986 leavecode = AddToValueList(*valuelistptr, trackkvp); 3987 if (leavecode != 0) 3988 { 3989 if (trackkvp.value.pChar_value != NULL) 3990 { 3991 OSCL_ARRAY_DELETE(trackkvp.value.pChar_value); 3992 trackkvp.value.pChar_value = NULL; 3993 } 3994 3995 OSCL_ARRAY_DELETE(trackkvp.key); 3996 trackkvp.key = NULL; 3997 } 3998 else 3999 { 4000 // Increment the value list entry counter 4001 ++numentriesadded; 4002 IsMetadataValAddedBefore = true; 4003 } 4004 4005 // Check if the max number of value entries were added 4006 if (max_entries > 0 && numentriesadded >= max_entries) 4007 { 4008 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4009 return PVMFSuccess; 4010 } 4011 } 4012 } 4013 } 4014 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_TRACKID_KEY) != NULL) 4015 { 4016 // Track ID 4017 4018 // Determine the index requested. Default to all tracks 4019 // Check if the file has at least one track 4020 int32 numtracks = iMP4FileHandle->getNumTracks(); 4021 if (numtracks <= 0) 4022 { 4023 break; 4024 } 4025 uint32 startindex = 0; 4026 uint32 endindex = (uint32)numtracks - 1; 4027 // Check if the index parameter is present 4028 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4029 if (indexstr != NULL) 4030 { 4031 // Retrieve the index values 4032 GetIndexParamValues(indexstr, startindex, endindex); 4033 } 4034 // Validate the indices 4035 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4036 { 4037 break; 4038 } 4039 4040 // Return a KVP for each index 4041 for (uint32 i = startindex; i <= endindex; ++i) 4042 { 4043 PvmiKvp trackkvp; 4044 trackkvp.key = NULL; 4045 4046 PVMFStatus retval = PVMFErrArgument; 4047 // Increment the counter for the number of values found so far 4048 ++numvalentries; 4049 // Add the value entry if past the starting index 4050 if (numvalentries > starting_index) 4051 { 4052 char indexparam[16]; 4053 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4054 indexparam[15] = '\0'; 4055 4056 retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_TRACKID_KEY, trackidlist[i], indexparam); 4057 } 4058 4059 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4060 { 4061 break; 4062 } 4063 4064 if (trackkvp.key != NULL) 4065 { 4066 leavecode = AddToValueList(*valuelistptr, trackkvp); 4067 if (leavecode != 0) 4068 { 4069 OSCL_ARRAY_DELETE(trackkvp.key); 4070 trackkvp.key = NULL; 4071 } 4072 else 4073 { 4074 // Increment the value list entry counter 4075 ++numentriesadded; 4076 IsMetadataValAddedBefore = true; 4077 } 4078 4079 // Check if the max number of value entries were added 4080 if (max_entries > 0 && numentriesadded >= max_entries) 4081 { 4082 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4083 return PVMFSuccess; 4084 } 4085 } 4086 } 4087 } 4088 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_DURATION_KEY) != NULL) 4089 { 4090 // Track duration 4091 4092 // Determine the index requested. Default to all tracks 4093 // Check if the file has at least one track 4094 int32 numtracks = iMP4FileHandle->getNumTracks(); 4095 if (numtracks <= 0) 4096 { 4097 break; 4098 } 4099 uint32 startindex = 0; 4100 uint32 endindex = (uint32)numtracks - 1; 4101 // Check if the index parameter is present 4102 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4103 if (indexstr != NULL) 4104 { 4105 // Retrieve the index values 4106 GetIndexParamValues(indexstr, startindex, endindex); 4107 } 4108 // Validate the indices 4109 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4110 { 4111 break; 4112 } 4113 4114 // Return a KVP for each index 4115 for (uint32 i = startindex; i <= endindex; ++i) 4116 { 4117 PvmiKvp trackkvp; 4118 trackkvp.key = NULL; 4119 4120 // Increment the counter for the number of values found so far 4121 ++numvalentries; 4122 // Add the value entry if past the starting index 4123 PVMFStatus retval = PVMFErrArgument; 4124 if (numvalentries > starting_index) 4125 { 4126 char indextimescaleparam[36]; 4127 uint32 timeScale = 0; 4128 4129 if (iParsingMode && iMP4FileHandle->IsMovieFragmentsPresent()) 4130 timeScale = iMP4FileHandle->getMovieTimescale(); 4131 else 4132 timeScale = iMP4FileHandle->getTrackMediaTimescale(trackidlist[i]); 4133 4134 oscl_snprintf(indextimescaleparam, 36, ";%s%d;%s%d", PVMP4METADATA_INDEX, i, PVMP4METADATA_TIMESCALE, timeScale); 4135 4136 indextimescaleparam[35] = '\0'; 4137 4138 uint64 trackduration64 = iMP4FileHandle->getTrackMediaDuration(trackidlist[i]); 4139 uint32 trackduration = Oscl_Int64_Utils::get_uint64_lower32(trackduration64);; 4140 4141 retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_DURATION_KEY, trackduration, indextimescaleparam); 4142 } 4143 4144 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4145 { 4146 break; 4147 } 4148 4149 if (trackkvp.key != NULL) 4150 { 4151 leavecode = AddToValueList(*valuelistptr, trackkvp); 4152 if (leavecode != 0) 4153 { 4154 OSCL_ARRAY_DELETE(trackkvp.key); 4155 trackkvp.key = NULL; 4156 } 4157 else 4158 { 4159 // Increment the value list entry counter 4160 ++numentriesadded; 4161 IsMetadataValAddedBefore = true; 4162 } 4163 4164 // Check if the max number of value entries were added 4165 if (max_entries > 0 && numentriesadded >= max_entries) 4166 { 4167 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4168 return PVMFSuccess; 4169 } 4170 } 4171 } 4172 } 4173 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_BITRATE_KEY) != NULL) 4174 { 4175 // Track bitrate 4176 4177 // Determine the index requested. Default to all tracks 4178 // Check if the file has at least one track 4179 int32 numtracks = iMP4FileHandle->getNumTracks(); 4180 if (numtracks <= 0) 4181 { 4182 break; 4183 } 4184 uint32 startindex = 0; 4185 uint32 endindex = (uint32)numtracks - 1; 4186 // Check if the index parameter is present 4187 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4188 if (indexstr != NULL) 4189 { 4190 // Retrieve the index values 4191 GetIndexParamValues(indexstr, startindex, endindex); 4192 } 4193 // Validate the indices 4194 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4195 { 4196 break; 4197 } 4198 4199 // Return a KVP for each index 4200 for (uint32 i = startindex; i <= endindex; ++i) 4201 { 4202 PvmiKvp trackkvp; 4203 trackkvp.key = NULL; 4204 4205 // Increment the counter for the number of values found so far 4206 ++numvalentries; 4207 // Add the value entry if past the starting index 4208 PVMFStatus retval = PVMFErrArgument; 4209 if (numvalentries > starting_index) 4210 { 4211 char indexparam[16]; 4212 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4213 indexparam[15] = '\0'; 4214 4215 uint32 trackbitrate = (uint32)(iMP4FileHandle->getTrackAverageBitrate(trackidlist[i])); // Always returns unsigned value 4216 4217 retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_BITRATE_KEY, trackbitrate, indexparam); 4218 } 4219 4220 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4221 { 4222 break; 4223 } 4224 4225 if (trackkvp.key != NULL) 4226 { 4227 leavecode = AddToValueList(*valuelistptr, trackkvp); 4228 if (leavecode != 0) 4229 { 4230 OSCL_ARRAY_DELETE(trackkvp.key); 4231 trackkvp.key = NULL; 4232 } 4233 else 4234 { 4235 // Increment the value list entry counter 4236 ++numentriesadded; 4237 IsMetadataValAddedBefore = true; 4238 } 4239 4240 // Check if the max number of value entries were added 4241 if (max_entries > 0 && numentriesadded >= max_entries) 4242 { 4243 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4244 return PVMFSuccess; 4245 } 4246 } 4247 } 4248 } 4249 else if ((oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_TRACK_NUMBER_KEY) != NULL) && 4250 iMP4FileHandle->getITunesThisTrackNo() > 0) 4251 { 4252 // iTunes Current Track Number 4253 // Determine the index requested. Default to all tracks 4254 // Check if the file has at least one track 4255 int32 numtracks = iMP4FileHandle->getNumTracks(); 4256 if (numtracks <= 0) 4257 { 4258 break; 4259 } 4260 uint32 startindex = 0; 4261 uint32 endindex = (uint32)numtracks - 1; 4262 // Check if the index parameter is present 4263 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4264 if (indexstr != NULL) 4265 { 4266 // Retrieve the index values 4267 GetIndexParamValues(indexstr, startindex, endindex); 4268 } 4269 // Validate the indices 4270 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4271 { 4272 break; 4273 } 4274 4275 // Return a KVP for each index 4276 for (uint32 i = startindex; i <= endindex; ++i) 4277 { 4278 PvmiKvp trackkvp; 4279 trackkvp.key = NULL; 4280 // Increment the counter for the number of values found so far 4281 ++numvalentries; 4282 // Add the value entry if past the starting index 4283 PVMFStatus retval = PVMFErrArgument; 4284 if (numvalentries > starting_index) 4285 { 4286 char indexparam[16]; 4287 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4288 indexparam[15] = '\0'; 4289 4290 uint32 track_number = iMP4FileHandle->getITunesThisTrackNo(); // Always returns unsigned value 4291 4292 char cdTrackNumber[6]; 4293 uint16 totalTrackNumber = iMP4FileHandle->getITunesTotalTracks(); 4294 oscl_snprintf(cdTrackNumber, 6, "%d/%d", track_number, totalTrackNumber); 4295 cdTrackNumber[5] = '\0'; 4296 4297 retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_TRACK_NUMBER_KEY, cdTrackNumber, indexparam); 4298 if ((retval != PVMFSuccess) && (retval != PVMFErrArgument)) 4299 { 4300 break; 4301 } 4302 4303 if (trackkvp.key != NULL) 4304 { 4305 leavecode = AddToValueList(*valuelistptr, trackkvp); 4306 if (leavecode != 0) 4307 { 4308 OSCL_ARRAY_DELETE(trackkvp.key); 4309 trackkvp.key = NULL; 4310 } 4311 else 4312 { 4313 // Increment the value list entry counter 4314 ++numentriesadded; 4315 IsMetadataValAddedBefore = true; 4316 } 4317 4318 // Check if the max number of value entries were added 4319 if (max_entries > 0 && numentriesadded >= max_entries) 4320 { 4321 4322 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4323 return PVMFSuccess; 4324 } 4325 } 4326 } 4327 } 4328 } 4329 else if ((oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY) != NULL) || 4330 (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY) != NULL)) 4331 { 4332 // Audio or video track format 4333 // Set index for track type 4334 uint32 tracktype = 0; // 0 unknown, 1 video, 2 audio 4335 if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY) != NULL) 4336 { 4337 tracktype = 1; 4338 } 4339 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY) != NULL) 4340 { 4341 tracktype = 2; 4342 } 4343 4344 // Determine the index requested. Default to all tracks 4345 // Check if the file has at least one track 4346 int32 numtracks = iMP4FileHandle->getNumTracks(); 4347 if (numtracks <= 0) 4348 { 4349 break; 4350 } 4351 uint32 startindex = 0; 4352 uint32 endindex = (uint32)numtracks - 1; 4353 // Check if the index parameter is present 4354 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4355 if (indexstr != NULL) 4356 { 4357 // Retrieve the index values 4358 GetIndexParamValues(indexstr, startindex, endindex); 4359 } 4360 // Validate the indices 4361 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4362 { 4363 break; 4364 } 4365 4366 // Return a KVP for each index 4367 for (uint32 i = startindex; i <= endindex; ++i) 4368 { 4369 PvmiKvp trackkvp; 4370 trackkvp.key = NULL; 4371 trackkvp.value.pChar_value = NULL; 4372 4373 char indexparam[16]; 4374 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4375 indexparam[15] = '\0'; 4376 4377 PVMFStatus retval = PVMFErrArgument; 4378 OSCL_HeapString<OsclMemAllocator> trackMIMEType; 4379 4380 iMP4FileHandle->getTrackMIMEType(trackidlist[i], trackMIMEType); 4381 4382 if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_M4V, oscl_strlen(PVMF_MIME_M4V)) == 0) 4383 { 4384 if (tracktype == 1) 4385 { 4386 ++numvalentries; 4387 if (numvalentries > starting_index) 4388 { 4389 retval = 4390 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_M4V), indexparam); 4391 } 4392 } 4393 } 4394 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H2632000, oscl_strlen(PVMF_MIME_H2632000)) == 0) 4395 { 4396 if (tracktype == 1) 4397 { 4398 ++numvalentries; 4399 if (numvalentries > starting_index) 4400 { 4401 retval = 4402 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_H2631998), indexparam); 4403 } 4404 } 4405 } 4406 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_H264_VIDEO_MP4, oscl_strlen(PVMF_MIME_H264_VIDEO_MP4)) == 0) 4407 { 4408 if (tracktype == 1) 4409 { 4410 ++numvalentries; 4411 if (numvalentries > starting_index) 4412 { 4413 retval = 4414 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4), indexparam); 4415 } 4416 } 4417 } 4418 else if (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_MPEG4_AUDIO, oscl_strlen(PVMF_MIME_MPEG4_AUDIO)) == 0) 4419 { 4420 if (tracktype == 2) 4421 { 4422 ++numvalentries; 4423 if (numvalentries > starting_index) 4424 { 4425 retval = 4426 PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_MPEG4_AUDIO), indexparam); 4427 } 4428 } 4429 } 4430 else if ((oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMR_IETF, oscl_strlen(PVMF_MIME_AMR_IETF)) == 0) || 4431 (oscl_strncmp(trackMIMEType.get_str(), PVMF_MIME_AMRWB_IETF, oscl_strlen(PVMF_MIME_AMRWB_IETF)) == 0)) 4432 { 4433 if (tracktype == 2) 4434 { 4435 ++numvalentries; 4436 if (numvalentries > starting_index) 4437 { 4438 retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(trackkvp, PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_AMR_IETF), indexparam); 4439 } 4440 } 4441 } 4442 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4443 { 4444 break; 4445 } 4446 4447 if (trackkvp.key != NULL) 4448 { 4449 leavecode = AddToValueList(*valuelistptr, trackkvp); 4450 if (leavecode != 0) 4451 { 4452 if (trackkvp.value.pChar_value != NULL) 4453 { 4454 OSCL_ARRAY_DELETE(trackkvp.value.pChar_value); 4455 trackkvp.value.pChar_value = NULL; 4456 } 4457 4458 OSCL_ARRAY_DELETE(trackkvp.key); 4459 trackkvp.key = NULL; 4460 } 4461 else 4462 { 4463 // Increment the value list entry counter 4464 ++numentriesadded; 4465 IsMetadataValAddedBefore = true; 4466 } 4467 4468 // Check if the max number of value entries were added 4469 if (max_entries > 0 && numentriesadded >= max_entries) 4470 { 4471 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4472 return PVMFSuccess; 4473 } 4474 } 4475 } 4476 } 4477 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_WIDTH_KEY) != NULL) 4478 { 4479 // Video track width 4480 4481 // Determine the index requested. Default to all tracks 4482 // Check if the file has at least one track 4483 int32 numtracks = iMP4FileHandle->getNumTracks(); 4484 if (numtracks <= 0) 4485 { 4486 break; 4487 } 4488 uint32 startindex = 0; 4489 uint32 endindex = (uint32)numtracks - 1; 4490 // Check if the index parameter is present 4491 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4492 if (indexstr != NULL) 4493 { 4494 // Retrieve the index values 4495 GetIndexParamValues(indexstr, startindex, endindex); 4496 } 4497 // Validate the indices 4498 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4499 { 4500 break; 4501 } 4502 4503 // Return a KVP for each index 4504 for (uint32 i = startindex; i <= endindex; ++i) 4505 { 4506 PvmiKvp trackkvp; 4507 trackkvp.key = NULL; 4508 4509 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_VISUAL) 4510 { 4511 // Increment the counter for the number of values found so far 4512 numvalentries++; 4513 4514 // Add the value entry if past the starting index 4515 if (numvalentries > starting_index) 4516 { 4517 char indexparam[16]; 4518 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4519 indexparam[15] = '\0'; 4520 4521 uint32 trackwidth = (uint32)(FindVideoDisplayWidth(trackidlist[i])); 4522 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_VIDEO_WIDTH_KEY, trackwidth, indexparam); 4523 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4524 { 4525 break; 4526 } 4527 4528 if (trackkvp.key != NULL) 4529 { 4530 leavecode = AddToValueList(*valuelistptr, trackkvp); 4531 if (leavecode != 0) 4532 { 4533 OSCL_ARRAY_DELETE(trackkvp.key); 4534 trackkvp.key = NULL; 4535 } 4536 else 4537 { 4538 // Increment the value list entry counter 4539 ++numentriesadded; 4540 IsMetadataValAddedBefore = true; 4541 } 4542 4543 // Check if the max number of value entries were added 4544 if (max_entries > 0 && numentriesadded >= max_entries) 4545 { 4546 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4547 return PVMFSuccess; 4548 } 4549 } 4550 } 4551 } 4552 } 4553 } 4554 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_VIDEO_HEIGHT_KEY) != NULL) 4555 { 4556 // Video track height 4557 4558 // Determine the index requested. Default to all tracks 4559 // Check if the file has at least one track 4560 int32 numtracks = iMP4FileHandle->getNumTracks(); 4561 if (numtracks <= 0) 4562 { 4563 break; 4564 } 4565 uint32 startindex = 0; 4566 uint32 endindex = (uint32)numtracks - 1; 4567 // Check if the index parameter is present 4568 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4569 if (indexstr != NULL) 4570 { 4571 // Retrieve the index values 4572 GetIndexParamValues(indexstr, startindex, endindex); 4573 } 4574 // Validate the indices 4575 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4576 { 4577 break; 4578 } 4579 4580 // Return a KVP for each index 4581 for (uint32 i = startindex; i <= endindex; ++i) 4582 { 4583 PvmiKvp trackkvp; 4584 trackkvp.key = NULL; 4585 4586 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_VISUAL) 4587 { 4588 // Increment the counter for the number of values found so far 4589 numvalentries++; 4590 4591 // Add the value entry if past the starting index 4592 if (numvalentries > starting_index) 4593 { 4594 char indexparam[16]; 4595 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4596 indexparam[15] = '\0'; 4597 4598 uint32 trackheight = (uint32)(FindVideoDisplayHeight(trackidlist[i])); 4599 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_VIDEO_HEIGHT_KEY, trackheight, indexparam); 4600 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4601 { 4602 break; 4603 } 4604 4605 if (trackkvp.key != NULL) 4606 { 4607 leavecode = AddToValueList(*valuelistptr, trackkvp); 4608 if (leavecode != 0) 4609 { 4610 OSCL_ARRAY_DELETE(trackkvp.key); 4611 trackkvp.key = NULL; 4612 } 4613 else 4614 { 4615 // Increment the value list entry counter 4616 ++numentriesadded; 4617 IsMetadataValAddedBefore = true; 4618 } 4619 4620 // Check if the max number of value entries were added 4621 if (max_entries > 0 && numentriesadded >= max_entries) 4622 { 4623 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4624 return PVMFSuccess; 4625 } 4626 } 4627 } 4628 } 4629 } 4630 } 4631 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_SAMPLERATE_KEY) != NULL) 4632 { 4633 // Sampling rate (only for video tracks) 4634 4635 // Determine the index requested. Default to all tracks 4636 // Check if the file has at least one track 4637 int32 numtracks = iMP4FileHandle->getNumTracks(); 4638 if (numtracks <= 0) 4639 { 4640 break; 4641 } 4642 uint32 startindex = 0; 4643 uint32 endindex = (uint32)numtracks - 1; 4644 // Check if the index parameter is present 4645 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4646 if (indexstr != NULL) 4647 { 4648 // Retrieve the index values 4649 GetIndexParamValues(indexstr, startindex, endindex); 4650 } 4651 // Validate the indices 4652 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4653 { 4654 break; 4655 } 4656 4657 // Return a KVP for each index 4658 for (uint32 i = startindex; i <= endindex; ++i) 4659 { 4660 PvmiKvp trackkvp; 4661 trackkvp.key = NULL; 4662 4663 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_AUDIO) 4664 { 4665 // Increment the counter for the number of values found so far 4666 numvalentries++; 4667 4668 // Add the value entry if past the starting index 4669 if (numvalentries > starting_index) 4670 { 4671 char indexparam[16]; 4672 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4673 indexparam[15] = '\0'; 4674 4675 uint32 samplerate = GetAudioSampleRate(trackidlist[i]); 4676 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_SAMPLERATE_KEY, samplerate, indexparam); 4677 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4678 { 4679 break; 4680 } 4681 4682 if (trackkvp.key != NULL) 4683 { 4684 leavecode = AddToValueList(*valuelistptr, trackkvp); 4685 if (leavecode != 0) 4686 { 4687 OSCL_ARRAY_DELETE(trackkvp.key); 4688 trackkvp.key = NULL; 4689 } 4690 else 4691 { 4692 // Increment the value list entry counter 4693 ++numentriesadded; 4694 IsMetadataValAddedBefore = true; 4695 } 4696 4697 // Check if the max number of value entries were added 4698 if (max_entries > 0 && numentriesadded >= max_entries) 4699 { 4700 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4701 return PVMFSuccess; 4702 } 4703 } 4704 } 4705 } 4706 } 4707 } 4708 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_SAMPLECOUNT_KEY) != NULL) 4709 { 4710 // Sample count 4711 4712 // Determine the index requested. Default to all tracks 4713 // Check if the file has at least one track 4714 int32 numtracks = iMP4FileHandle->getNumTracks(); 4715 if (numtracks <= 0) 4716 { 4717 break; 4718 } 4719 uint32 startindex = 0; 4720 uint32 endindex = (uint32)numtracks - 1; 4721 // Check if the index parameter is present 4722 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4723 if (indexstr != NULL) 4724 { 4725 // Retrieve the index values 4726 GetIndexParamValues(indexstr, startindex, endindex); 4727 } 4728 // Validate the indices 4729 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4730 { 4731 break; 4732 } 4733 4734 // Return a KVP for each index 4735 for (uint32 i = startindex; i <= endindex; ++i) 4736 { 4737 PvmiKvp trackkvp; 4738 trackkvp.key = NULL; 4739 4740 // Increment the counter for the number of values found so far 4741 ++numvalentries; 4742 // Add the value entry if past the starting index 4743 PVMFStatus retval = PVMFErrArgument; 4744 if (numvalentries > starting_index) 4745 { 4746 char indexparam[16]; 4747 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4748 indexparam[15] = '\0'; 4749 4750 uint32 samplecount = (uint32)(iMP4FileHandle->getSampleCountInTrack(trackidlist[i])); // Always returns unsigned value 4751 4752 retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_SAMPLECOUNT_KEY, samplecount, indexparam); 4753 } 4754 4755 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4756 { 4757 break; 4758 } 4759 4760 if (trackkvp.key != NULL) 4761 { 4762 leavecode = AddToValueList(*valuelistptr, trackkvp); 4763 if (leavecode != 0) 4764 { 4765 OSCL_ARRAY_DELETE(trackkvp.key); 4766 trackkvp.key = NULL; 4767 } 4768 else 4769 { 4770 // Increment the value list entry counter 4771 ++numentriesadded; 4772 IsMetadataValAddedBefore = true; 4773 } 4774 4775 // Check if the max number of value entries were added 4776 if (max_entries > 0 && numentriesadded >= max_entries) 4777 { 4778 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4779 return PVMFSuccess; 4780 } 4781 } 4782 } 4783 } 4784 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_NUM_KEY_SAMPLES_KEY) != NULL) 4785 { 4786 // Num-Key-Samples 4787 4788 // Determine the index requested. Default to all tracks 4789 // Check if the file has at least one track 4790 int32 numtracks = iMP4FileHandle->getNumTracks(); 4791 if (numtracks <= 0) 4792 { 4793 break; 4794 } 4795 uint32 startindex = 0; 4796 uint32 endindex = (uint32)numtracks - 1; 4797 // Check if the index parameter is present 4798 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4799 if (indexstr != NULL) 4800 { 4801 // Retrieve the index values 4802 GetIndexParamValues(indexstr, startindex, endindex); 4803 } 4804 // Validate the indices 4805 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4806 { 4807 break; 4808 } 4809 4810 // Return a KVP for each index 4811 for (uint32 i = startindex; i <= endindex; ++i) 4812 { 4813 PvmiKvp trackkvp; 4814 trackkvp.key = NULL; 4815 4816 // Increment the counter for the number of values found so far 4817 ++numvalentries; 4818 // Add the value entry if past the starting index 4819 PVMFStatus retval = PVMFErrArgument; 4820 if (numvalentries > starting_index) 4821 { 4822 char indexparam[16]; 4823 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4824 indexparam[15] = '\0'; 4825 4826 uint32 keySampleCount = iMP4FileHandle->getNumKeyFrames(trackidlist[i]); 4827 4828 retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_NUM_KEY_SAMPLES_KEY, keySampleCount, indexparam); 4829 } 4830 4831 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4832 { 4833 break; 4834 } 4835 4836 if (trackkvp.key != NULL) 4837 { 4838 leavecode = AddToValueList(*valuelistptr, trackkvp); 4839 if (leavecode != 0) 4840 { 4841 OSCL_ARRAY_DELETE(trackkvp.key); 4842 trackkvp.key = NULL; 4843 } 4844 else 4845 { 4846 // Increment the value list entry counter 4847 ++numentriesadded; 4848 IsMetadataValAddedBefore = true; 4849 } 4850 4851 // Check if the max number of value entries were added 4852 if (max_entries > 0 && numentriesadded >= max_entries) 4853 { 4854 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4855 return PVMFSuccess; 4856 } 4857 } 4858 } 4859 } 4860 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_AUDIO_NUMCHANNELS_KEY) != NULL) 4861 { 4862 // Determine the index requested. Default to all tracks 4863 // Check if the file has at least one track 4864 int32 numtracks = iMP4FileHandle->getNumTracks(); 4865 if (numtracks <= 0) 4866 { 4867 break; 4868 } 4869 uint32 startindex = 0; 4870 uint32 endindex = (uint32)numtracks - 1; 4871 // Check if the index parameter is present 4872 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4873 if (indexstr != NULL) 4874 { 4875 // Retrieve the index values 4876 GetIndexParamValues(indexstr, startindex, endindex); 4877 } 4878 // Validate the indices 4879 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4880 { 4881 break; 4882 } 4883 4884 // Return a KVP for each index 4885 for (uint32 i = startindex; i <= endindex; ++i) 4886 { 4887 PvmiKvp trackkvp; 4888 trackkvp.key = NULL; 4889 4890 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_AUDIO) 4891 { 4892 // Increment the counter for the number of values found so far 4893 numvalentries++; 4894 4895 // Add the value entry if past the starting index 4896 if (numvalentries > starting_index) 4897 { 4898 char indexparam[16]; 4899 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4900 indexparam[15] = '\0'; 4901 4902 uint32 numAudioChannels = (GetNumAudioChannels(trackidlist[i])); 4903 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_AUDIO_NUMCHANNELS_KEY, numAudioChannels, indexparam); 4904 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4905 { 4906 break; 4907 } 4908 4909 if (trackkvp.key != NULL) 4910 { 4911 leavecode = AddToValueList(*valuelistptr, trackkvp); 4912 if (leavecode != 0) 4913 { 4914 OSCL_ARRAY_DELETE(trackkvp.key); 4915 trackkvp.key = NULL; 4916 } 4917 else 4918 { 4919 // Increment the value list entry counter 4920 ++numentriesadded; 4921 IsMetadataValAddedBefore = true; 4922 } 4923 4924 // Check if the max number of value entries were added 4925 if (max_entries > 0 && numentriesadded >= max_entries) 4926 { 4927 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 4928 return PVMFSuccess; 4929 } 4930 } 4931 } 4932 } 4933 } 4934 } 4935 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY) != NULL) 4936 { 4937 // Determine the index requested. Default to all tracks 4938 // Check if the file has at least one track 4939 int32 numtracks = iMP4FileHandle->getNumTracks(); 4940 if (numtracks <= 0) 4941 { 4942 break; 4943 } 4944 uint32 startindex = 0; 4945 uint32 endindex = (uint32)numtracks - 1; 4946 // Check if the index parameter is present 4947 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 4948 if (indexstr != NULL) 4949 { 4950 // Retrieve the index values 4951 GetIndexParamValues(indexstr, startindex, endindex); 4952 } 4953 // Validate the indices 4954 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 4955 { 4956 break; 4957 } 4958 4959 // Return a KVP for each index 4960 for (uint32 i = startindex; i <= endindex; ++i) 4961 { 4962 PvmiKvp trackkvp; 4963 trackkvp.key = NULL; 4964 4965 if (iMP4FileHandle->getTrackMediaType(trackidlist[i]) == MEDIA_TYPE_AUDIO) 4966 { 4967 // Increment the counter for the number of values found so far 4968 numvalentries++; 4969 4970 // Add the value entry if past the starting index 4971 if (numvalentries > starting_index) 4972 { 4973 char indexparam[16]; 4974 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 4975 indexparam[15] = '\0'; 4976 4977 uint32 numbitspersample = (GetAudioBitsPerSample(trackidlist[i])); 4978 PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(trackkvp, PVMP4METADATA_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY, numbitspersample, indexparam); 4979 if (retval != PVMFSuccess && retval != PVMFErrArgument) 4980 { 4981 break; 4982 } 4983 4984 if (trackkvp.key != NULL) 4985 { 4986 leavecode = AddToValueList(*valuelistptr, trackkvp); 4987 if (leavecode != 0) 4988 { 4989 OSCL_ARRAY_DELETE(trackkvp.key); 4990 trackkvp.key = NULL; 4991 } 4992 else 4993 { 4994 // Increment the value list entry counter 4995 ++numentriesadded; 4996 IsMetadataValAddedBefore = true; 4997 } 4998 4999 // Check if the max number of value entries were added 5000 if (max_entries > 0 && numentriesadded >= max_entries) 5001 { 5002 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 5003 return PVMFSuccess; 5004 } 5005 } 5006 } 5007 } 5008 } 5009 } 5010 else if (oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_TRACKINFO_SELECTED_KEY) != NULL) 5011 { 5012 // Track selected info 5013 5014 // Determine the index requested. Default to all tracks 5015 // Check if the file has at least one track 5016 int32 numtracks = iMP4FileHandle->getNumTracks(); 5017 if (numtracks <= 0) 5018 { 5019 break; 5020 } 5021 uint32 startindex = 0; 5022 uint32 endindex = (uint32)numtracks - 1; 5023 // Check if the index parameter is present 5024 const char* indexstr = oscl_strstr((*keylistptr)[lcv].get_cstr(), PVMP4METADATA_INDEX); 5025 if (indexstr != NULL) 5026 { 5027 // Retrieve the index values 5028 GetIndexParamValues(indexstr, startindex, endindex); 5029 } 5030 // Validate the indices 5031 if (startindex > endindex || startindex >= (uint32)numtracks || endindex >= (uint32)numtracks) 5032 { 5033 break; 5034 } 5035 5036 // Return a KVP for each index 5037 for (uint32 i = startindex; i <= endindex; ++i) 5038 { 5039 PvmiKvp trackkvp; 5040 trackkvp.key = NULL; 5041 5042 PVMFStatus retval = PVMFErrArgument; 5043 // Increment the counter for the number of values found so far 5044 ++numvalentries; 5045 // Add the value entry if past the starting index 5046 if (numvalentries > starting_index) 5047 { 5048 char indexparam[16]; 5049 oscl_snprintf(indexparam, 16, ";%s%d", PVMP4METADATA_INDEX, i); 5050 indexparam[15] = '\0'; 5051 5052 // Check if the track has been selected by looking up 5053 // the current index's track ID in the NodeTrackPort vector 5054 bool trackselected = false; 5055 for (uint32 j = 0; j < iNodeTrackPortList.size(); ++j) 5056 { 5057 if ((uint32)iNodeTrackPortList[j].iTrackId == trackidlist[i]) 5058 { 5059 trackselected = true; 5060 break; 5061 } 5062 } 5063 retval = PVMFCreateKVPUtils::CreateKVPForBoolValue(trackkvp, PVMP4METADATA_TRACKINFO_SELECTED_KEY, trackselected, indexparam); 5064 } 5065 5066 if (retval != PVMFSuccess && retval != PVMFErrArgument) 5067 { 5068 break; 5069 } 5070 5071 if (trackkvp.key != NULL) 5072 { 5073 leavecode = AddToValueList(*valuelistptr, trackkvp); 5074 if (leavecode != 0) 5075 { 5076 OSCL_ARRAY_DELETE(trackkvp.key); 5077 trackkvp.key = NULL; 5078 } 5079 else 5080 { 5081 // Increment the value list entry counter 5082 ++numentriesadded; 5083 IsMetadataValAddedBefore = true; 5084 } 5085 5086 // Check if the max number of value entries were added 5087 if (max_entries > 0 && numentriesadded >= max_entries) 5088 { 5089 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 5090 return PVMFSuccess; 5091 } 5092 } 5093 } 5094 } 5095 5096 // Add the KVP to the list if the key string was created 5097 if ((KeyVal.key != NULL) && (!IsMetadataValAddedBefore)) 5098 { 5099 leavecode = AddToValueList(*valuelistptr, KeyVal); 5100 if (leavecode != 0) 5101 { 5102 switch (GetValTypeFromKeyString(KeyVal.key)) 5103 { 5104 case PVMI_KVPVALTYPE_CHARPTR: 5105 if (KeyVal.value.pChar_value != NULL) 5106 { 5107 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value); 5108 KeyVal.value.pChar_value = NULL; 5109 } 5110 break; 5111 5112 case PVMI_KVPVALTYPE_WCHARPTR: 5113 if (KeyVal.value.pWChar_value != NULL) 5114 { 5115 OSCL_ARRAY_DELETE(KeyVal.value.pWChar_value); 5116 KeyVal.value.pWChar_value = NULL; 5117 } 5118 break; 5119 5120 default: 5121 // Add more case statements if other value types are returned 5122 break; 5123 } 5124 5125 OSCL_ARRAY_DELETE(KeyVal.key); 5126 KeyVal.key = NULL; 5127 } 5128 else 5129 { 5130 // Increment the counter for number of value entries added to the list 5131 ++numentriesadded; 5132 } 5133 5134 // Check if the max number of value entries were added 5135 if (max_entries > 0 && numentriesadded >= max_entries) 5136 { 5137 // Maximum number of values added so break out of the loop 5138 //return PVMFSuccess; 5139 break; 5140 } 5141 } 5142 } 5143 iMP4ParserNodeMetadataValueCount = (*valuelistptr).size(); 5144 } 5145 5146 PVMF_MP4FFPARSERNODE_LOGERROR((0, "PVMFMP4FFParserNode::DoGetMetadataValues - NumParserNodeValues=%d", iMP4ParserNodeMetadataValueCount)); 5147 5148 if ((iCPMMetaDataExtensionInterface != NULL) && 5149 (iProtectedFile == true)) 5150 { 5151 iCPMGetMetaDataValuesCmdId = 5152 iCPMMetaDataExtensionInterface->GetNodeMetadataValues(iCPMSessionID, 5153 (*keylistptr_in), 5154 (*valuelistptr), 5155 0); 5156 return PVMFPending; 5157 } 5158 return PVMFSuccess; 5159} 5160 5161void PVMFMP4FFParserNode::CompleteGetMetaDataValues() 5162{ 5163 PVMFMetadataList* keylistptr = NULL; 5164 Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL; 5165 uint32 starting_index; 5166 int32 max_entries; 5167 5168 iCurrentCommand.front().PVMFMP4FFParserNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries); 5169 5170 for (uint32 i = 0; i < (*valuelistptr).size(); i++) 5171 { 5172 PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::CompleteGetMetaDataValues - Index=%d, Key=%s", i, (*valuelistptr)[i].key)); 5173 } 5174 5175 CommandComplete(iCurrentCommand, 5176 iCurrentCommand.front(), 5177 PVMFSuccess); 5178} 5179 5180int32 PVMFMP4FFParserNode::AddToValueList(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, PvmiKvp& aNewValue) 5181{ 5182 int32 leavecode = 0; 5183 OSCL_TRY(leavecode, aValueList.push_back(aNewValue)); 5184 return leavecode; 5185} 5186 5187void PVMFMP4FFParserNode::DeleteAPICStruct(PvmfApicStruct*& aAPICStruct) 5188{ 5189 OSCL_ARRAY_DELETE(aAPICStruct->iGraphicData); 5190 OSCL_DELETE(aAPICStruct); 5191 aAPICStruct = NULL; 5192} 5193 5194PVMFStatus PVMFMP4FFParserNode::GetIndexParamValues(const char* aString, uint32& aStartIndex, uint32& aEndIndex) 5195{ 5196 // This parses a string of the form "index=N1...N2" and extracts the integers N1 and N2. 5197 // If string is of the format "index=N1" then N2=N1 5198 5199 if (aString == NULL) 5200 { 5201 return PVMFErrArgument; 5202 } 5203 5204 // Go to end of "index=" 5205 char* n1string = (char*)aString + 6; 5206 5207 PV_atoi(n1string, 'd', oscl_strlen(n1string), aStartIndex); 5208 5209 const char* n2string = oscl_strstr(aString, _STRLIT_CHAR("...")); 5210 5211 if (n2string == NULL) 5212 { 5213 aEndIndex = aStartIndex; 5214 } 5215 else 5216 { 5217 // Go to end of "index=N1..." 5218 n2string += 3; 5219 5220 PV_atoi(n2string, 'd', oscl_strlen(n2string), aEndIndex); 5221 } 5222 5223 return PVMFSuccess; 5224} 5225 5226void PVMFMP4FFParserNode::getLanguageCode(uint16 langcode, int8 *LangCode) 5227{ 5228 //ISO-639-2/T 3-char Lang Code 5229 oscl_memset(LangCode, 0, 4); 5230 LangCode[0] = 0x60 + ((langcode >> 10) & 0x1F); 5231 LangCode[1] = 0x60 + ((langcode >> 5) & 0x1F); 5232 LangCode[2] = 0x60 + ((langcode) & 0x1F); 5233} 5234 5235void PVMFMP4FFParserNode::CreateDurationInfoMsg(uint32 adurationms) 5236{ 5237 int32 leavecode = 0; 5238 PVMFDurationInfoMessage* eventmsg = NULL; 5239 OSCL_TRY(leavecode, eventmsg = OSCL_NEW(PVMFDurationInfoMessage, (adurationms))); 5240 PVMFNodeInterface::ReportInfoEvent(PVMFInfoDurationAvailable, NULL, OSCL_STATIC_CAST(PVInterface*, eventmsg)); 5241 if (eventmsg) 5242 { 5243 eventmsg->removeRef(); 5244 } 5245} 5246 5247PVMFStatus PVMFMP4FFParserNode::PushKVPToMetadataValueList(Oscl_Vector<PvmiKvp, OsclMemAllocator>* aVecPtr, PvmiKvp& aKvpVal) 5248{ 5249 if (aVecPtr == NULL) 5250 { 5251 return PVMFErrArgument; 5252 } 5253 int32 leavecode = 0; 5254 OSCL_TRY(leavecode, aVecPtr->push_back(aKvpVal);); 5255 if (leavecode != 0) 5256 { 5257 OSCL_ARRAY_DELETE(aKvpVal.key); 5258 aKvpVal.key = NULL; 5259 return PVMFErrNoMemory; 5260 } 5261 return PVMFSuccess; 5262} 5263 5264PVMFStatus PVMFMP4FFParserNode::CreateNewArray(uint32** aTrackidList, uint32 aNumTracks) 5265{ 5266 int32 leavecode = 0; 5267 OSCL_TRY(leavecode, *aTrackidList = OSCL_ARRAY_NEW(uint32, aNumTracks);); 5268 OSCL_FIRST_CATCH_ANY(leavecode, return PVMFErrNoMemory;); 5269 return PVMFSuccess; 5270} 5271 5272PVMFStatus PVMFMP4FFParserNode::PushValueToList(Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> &aRefMetaDataKeys, PVMFMetadataList *&aKeyListPtr, uint32 aLcv) 5273{ 5274 int32 leavecode = 0; 5275 OSCL_TRY(leavecode, aKeyListPtr->push_back(aRefMetaDataKeys[aLcv])); 5276 OSCL_FIRST_CATCH_ANY(leavecode, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFMP4FFParserNode::PushValueToList() Memory allocation failure when copying metadata key")); return PVMFErrNoMemory); 5277 return PVMFSuccess; 5278} 5279