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
38 static const char PVMP4_ALL_METADATA_KEY[] = "all";
39 static const char PVMP4METADATA_CLIP_TYPE_KEY[] = "clip-type";
40 static const char PVMP4METADATA_ALBUM_KEY[] = "album";
41 static const char PVMP4METADATA_COMMENT_KEY[] = "comment";
42
43
44 static const char PVMP4METADATA_LOCATION_KEY[] = "location;format=3GPP_LOCATION";
45 static const char PVMP4METADATA_YEAR_KEY[] = "year";
46 static const char PVMP4METADATA_AUTHOR_KEY[] = "author";
47 static const char PVMP4METADATA_ARTIST_KEY[] = "artist";
48 static const char PVMP4METADATA_GENRE_KEY[] = "genre";
49 static const char PVMP4METADATA_KEYWORD_KEY[] = "keyword";
50 static const char PVMP4METADATA_CLASSIFICATION_KEY[] = "classification";
51 static const char PVMP4METADATA_TITLE_KEY[] = "title";
52 static const char PVMP4METADATA_DESCRIPTION_KEY[] = "description";
53 static const char PVMP4METADATA_RATING_KEY[] = "rating";
54 static const char PVMP4METADATA_COPYRIGHT_KEY[] = "copyright";
55 static const char PVMP4METADATA_VERSION_KEY[] = "version";
56 static const char PVMP4METADATA_DATE_KEY[] = "date";
57 static const char PVMP4METADATA_DURATION_KEY[] = "duration";
58 static const char PVMP4METADATA_NUMTRACKS_KEY[] = "num-tracks";
59 static const char PVMP4METADATA_IS_MOOF_KEY[] = "movie-fragments-present";
60
61 static const char PVMP4METADATA_TOOL_KEY[] = "tool";
62 static const char PVMP4METADATA_WRITER_KEY[] = "writer";
63 static const char PVMP4METADATA_GROUPING_KEY[] = "grouping";
64 static const char PVMP4METADATA_TRACKDATA_KEY[] = "track data";
65 static const char PVMP4METADATA_COMPILATION_KEY[] = "compilation";
66 static const char PVMP4METADATA_TEMPO_KEY[] = "tempo";
67 static const char PVMP4METADATA_COVER_KEY[] = "cover";
68 static const char PVMP4METADATA_DISKDATA_KEY[] = "disk";
69 static const char PVMP4METADATA_FREEFORMDATA_KEY[] = "free form data";
70 static const char PVMP4METADATA_CDDBID_KEY[] = "CD identifier";
71 static const char PVMP4METADATA_LYRICS_KEY[] = "lyrics";
72 static const char PVMP4METADATA_RANDOM_ACCESS_DENIED_KEY[] = "random-access-denied";
73 //////////////////////////////////////////////////////////
74
75 static const char PVMP4METADATA_TRACKINFO_TYPE_KEY[] = "track-info/type";
76 static const char PVMP4METADATA_TRACKINFO_TRACKID_KEY[] = "track-info/track-id";
77 static const char PVMP4METADATA_TRACKINFO_DURATION_KEY[] = "track-info/duration";
78 static const char PVMP4METADATA_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate";
79 static const char PVMP4METADATA_TRACKINFO_SAMPLECOUNT_KEY[] = "track-info/num-samples";
80 static const char PVMP4METADATA_TRACKINFO_SELECTED_KEY[] = "track-info/selected";
81
82 static const char PVMP4METADATA_TRACKINFO_AUDIO_FORMAT_KEY[] = "track-info/audio/format";
83 static const char PVMP4METADATA_TRACKINFO_AUDIO_NUMCHANNELS_KEY[] = "track-info/audio/channels";
84 static const char PVMP4METADATA_TRACKINFO_SAMPLERATE_KEY[] = "track-info/sample-rate";
85 static const char PVMP4METADATA_TRACKINFO_AUDIO_BITS_PER_SAMPLE_KEY[] = "track-info/audio/bits-per-sample";
86
87 static const char PVMP4METADATA_TRACKINFO_VIDEO_FORMAT_KEY[] = "track-info/video/format";
88 static const char PVMP4METADATA_TRACKINFO_VIDEO_WIDTH_KEY[] = "track-info/video/width";
89 static const char PVMP4METADATA_TRACKINFO_VIDEO_HEIGHT_KEY[] = "track-info/video/height";
90 static const char PVMP4METADATA_TRACKINFO_VIDEO_PROFILE_KEY[] = "track-info/video/profile";
91 static const char PVMP4METADATA_TRACKINFO_VIDEO_LEVEL_KEY[] = "track-info/video/level";
92 static const char PVMP4METADATA_TRACKINFO_FRAME_RATE_KEY[] = "track-info/frame-rate";
93 static const char PVMP4METADATA_TRACKINFO_TRACK_NUMBER_KEY[] = "track-info/track-number";
94 static const char PVMP4METADATA_TRACKINFO_NUM_KEY_SAMPLES_KEY[] = "track-info/num-key-samples";
95
96 static const char PVMP4METADATA_MAJORBRAND_KEY[] = "mp4ff/major-brand";
97 static const char PVMP4METADATA_COMPATIBLEBRAND_KEY[] = "mp4ff/compatible-brand";
98
99 static const char PVMP4METADATA_SEMICOLON[] = ";";
100 static const char PVMP4METADATA_TIMESCALE[] = "timescale=";
101 static const char PVMP4METADATA_INDEX[] = "index=";
102 static const char PVMP4METADATA_LANG_CODE[] = "iso-639-2-lang=";
103 static const char PVMP4METADATA_NOT_SOTRABLE[] = "not-storable";
104 static const char PVMP4METADATA_MAXSIZE[] = "maxsize=";
105 static const char PVMP4METADATA_REQ_SIZE[] = "reqsize=";
106 static 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
GetNumMetadataKeys(char * aQueryKeyString)115 uint32 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
GetNumMetadataValues(PVMFMetadataList & aKeyList)148 uint32 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
GetNodeMetadataKeys(PVMFSessionId aSessionId,PVMFMetadataList & aKeyList,uint32 starting_index,int32 max_entries,char * query_key,const OsclAny * aContext)1017 PVMFCommandId 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
GetNodeMetadataValues(PVMFSessionId aSessionId,PVMFMetadataList & aKeyList,Oscl_Vector<PvmiKvp,OsclMemAllocator> & aValueList,uint32 starting_index,int32 max_entries,const OsclAny * aContext)1027 PVMFCommandId 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
ReleaseNodeMetadataKeys(PVMFMetadataList &,uint32,uint32)1037 PVMFStatus 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
ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp,OsclMemAllocator> & aValueList,uint32 start,uint32 end)1046 PVMFStatus 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
PushToAvailableMetadataKeysList(const char * aKeystr,char * aOptionalParam)1132 void 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
CountMetaDataKeys()1153 int32 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
InitMetaData()1351 PVMFStatus 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
1652 PVMFStatus
DoGetMetadataKeys(PVMFMP4FFParserNodeCommand & aCmd)1653 PVMFMP4FFParserNode::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
CompleteGetMetadataKeys(PVMFMP4FFParserNodeCommand & aCmd)1670 PVMFStatus 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
DoGetMetadataValues(PVMFMP4FFParserNodeCommand & aCmd)1787 PVMFStatus 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
CompleteGetMetaDataValues()5161 void 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
AddToValueList(Oscl_Vector<PvmiKvp,OsclMemAllocator> & aValueList,PvmiKvp & aNewValue)5180 int32 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
DeleteAPICStruct(PvmfApicStruct * & aAPICStruct)5187 void PVMFMP4FFParserNode::DeleteAPICStruct(PvmfApicStruct*& aAPICStruct)
5188 {
5189 OSCL_ARRAY_DELETE(aAPICStruct->iGraphicData);
5190 OSCL_DELETE(aAPICStruct);
5191 aAPICStruct = NULL;
5192 }
5193
GetIndexParamValues(const char * aString,uint32 & aStartIndex,uint32 & aEndIndex)5194 PVMFStatus 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
getLanguageCode(uint16 langcode,int8 * LangCode)5226 void 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
CreateDurationInfoMsg(uint32 adurationms)5235 void 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
PushKVPToMetadataValueList(Oscl_Vector<PvmiKvp,OsclMemAllocator> * aVecPtr,PvmiKvp & aKvpVal)5247 PVMFStatus 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
CreateNewArray(uint32 ** aTrackidList,uint32 aNumTracks)5264 PVMFStatus 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
PushValueToList(Oscl_Vector<OSCL_HeapString<OsclMemAllocator>,OsclMemAllocator> & aRefMetaDataKeys,PVMFMetadataList * & aKeyListPtr,uint32 aLcv)5272 PVMFStatus 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