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