1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 // -*- c++ -*-
19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
20 //
21 // M P 3 F I L E P A R S E R
22 //
23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
24
25
26 /**
27 * @file imp3ff.cpp
28 * @brief This file contains the implementation of the MP3 File Format
29 * interface. It initializes and maintains the MP3 File Format Library
30 */
31
32 //----------------------------------------------------------------------
33 // Include Files
34 //----------------------------------------------------------------------
35
36 #include "imp3ff.h"
37 #include "mp3fileio.h"
38 #include "mp3utils.h"
39 #include "mp3parser.h"
40 #include "oscl_mem.h"
41 #include "oscl_utf8conv.h"
42 #include "pvmi_kvp_util.h"
43 #include "pvmi_kvp.h"
44 #include "pvmf_format_type.h"
45 #include "pv_mime_string_utils.h"
46 // Constant character strings for metadata keys
47 static const char PVMP3METADATA_TITLE_KEY[] = "title";
48 static const char PVMP3METADATA_ARTIST_KEY[] = "artist";
49 static const char PVMP3METADATA_ALBUM_KEY[] = "album";
50 static const char PVMP3METADATA_YEAR_KEY[] = "year";
51 static const char PVMP3METADATA_COMMENT_KEY[] = "comment";
52 static const char PVMP3METADATA_COPYRIGHT_KEY[] = "copyright";
53 static const char PVMP3METADATA_GENRE_KEY[] = "genre";
54 static const char PVMP3METADATA_TRACKINFO_TRACKNUMBER_KEY[] = "track-info/track-number";
55 static const char PVMP3METADATA_DURATION_KEY[] = "duration";
56 static const char PVMP3METADATA_DURATION_FROM_METADATA_KEY[] = "duration-from-metadata";
57 static const char PVMP3METADATA_NUMTRACKS_KEY[] = "num-tracks";
58 static const char PVMP3METADATA_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate";
59 static const char PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY[] = "track-info/sample-rate";
60 static const char PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY[] = "track-info/audio/format";
61 static const char PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY[] = "track-info/audio/channels";
62 static const char PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY[] = "track-info/audio/channel-mode";
63 static const char PVMP3METADATA_BITRATE_KEY[] = "bit-rate";
64 static const char PVMP3METADATA_SAMPLERATE_KEY[] = "sample-rate";
65 static const char PVMP3METADATA_FORMAT_KEY[] = "format";
66 static const char PVMP3METADATA_CHANNELS_KEY[] = "channels";
67 static const char PVMP3METADATA_CHANNEL_MODE_KEY[] = "channel-mode";
68 static const char PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY[] = "random-access-denied";
69 static const char PVMP3METADATA_SEMICOLON[] = ";";
70 static const char PVMP3METADATA_CHARENCUTF8[] = "char-encoding=UTF8";
71 static const char PVMP3METADATA_CHARENCUTF16BE[] = "char-encoding=UTF16BE";
72 static const char PVMP3METADATA_FORMATID3V1[] = "format=id3v1";
73 static const char PVMP3METADATA_FORMATID3V11[] = "format=id3v1.1";
74 static const char PVMP3METADATA_TIMESCALE1000[] = "timescale=1000";
75 static const char PVMP3METADATA_INDEX0[] = "index=0";
76 static const char PVMP3METADATA_UNKNOWN[] = "unknown";
77 static const char PVMP3METADATA_COMPUTE[] = "compute=true";
78
79 // Use default DLL entry point for Symbian
80 #include "oscl_dll.h"
OSCL_DLL_ENTRY_POINT_DEFAULT()81 OSCL_DLL_ENTRY_POINT_DEFAULT()
82
83 //----------------------------------------------------------------------
84 // Defines
85 //----------------------------------------------------------------------
86
87 //----------------------------------------------------------------------
88 // Type Declarations
89 //----------------------------------------------------------------------
90
91 //----------------------------------------------------------------------
92 // Global Constant Definitions
93 //----------------------------------------------------------------------
94
95 //----------------------------------------------------------------------
96 // Global Data Definitions
97 //----------------------------------------------------------------------
98
99 //----------------------------------------------------------------------
100 // Static Variable Definitions
101 //----------------------------------------------------------------------
102
103
104 OSCL_EXPORT_REF IMpeg3File::IMpeg3File(OSCL_wString& filename, MP3ErrorType &bSuccess, Oscl_FileServer* fileServSession, PVMFCPMPluginAccessInterfaceFactory*aCPM, OsclFileHandle*aFileHandle, bool enableCRC) :
105 pMP3Parser(NULL)
106 {
107 bSuccess = MP3_SUCCESS;
108
109 // Initialize the metadata related variables
110 iAvailableMetadataKeys.reserve(14);
111 iAvailableMetadataKeys.clear();
112
113 iEnableCrcCalc = enableCRC;
114 // Open the specified MP3 file
115 iMP3File.SetCPM(aCPM);
116 iMP3File.SetFileHandle(aFileHandle);
117 if (iMP3File.Open(filename.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *fileServSession) != 0)
118 {
119 bSuccess = MP3_FILE_OPEN_ERR;
120 return;
121 }
122
123 if (!aCPM)
124 {
125 iScanFP.SetCPM(aCPM);
126 iScanFP.SetFileHandle(aFileHandle);
127 if (iScanFP.Open(filename.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *fileServSession) != 0)
128 {
129 bSuccess = MP3_FILE_OPEN_ERR;
130 return;
131 }
132 }
133
134 int32 leavecode = OsclErrNone;
135 OSCL_TRY(leavecode, pMP3Parser = OSCL_NEW(MP3Parser, (&iMP3File)););
136 if (pMP3Parser && OsclErrNone == leavecode)
137 bSuccess = MP3_SUCCESS;
138 else
139 bSuccess = MP3_ERROR_UNKNOWN;
140 }
141
IMpeg3File(MP3ErrorType & bSuccess)142 OSCL_EXPORT_REF IMpeg3File::IMpeg3File(MP3ErrorType &bSuccess): pMP3Parser(NULL)
143 {
144 int32 leavecode = OsclErrNone;
145 OSCL_TRY(leavecode, pMP3Parser = OSCL_NEW(MP3Parser, ()););
146 if (pMP3Parser && OsclErrNone == leavecode)
147 bSuccess = MP3_SUCCESS;
148 else
149 bSuccess = MP3_ERROR_UNKNOWN;
150 }
151
~IMpeg3File()152 OSCL_EXPORT_REF IMpeg3File::~IMpeg3File()
153 {
154 iAvailableMetadataKeys.clear();
155
156 if (pMP3Parser != NULL)
157 {
158 OSCL_DELETE(pMP3Parser);
159 pMP3Parser = NULL;
160 }
161
162 if (iScanFP.IsOpen())
163 {
164 iScanFP.Close();
165 }
166 if (iMP3File.IsOpen())
167 {
168 iMP3File.Close();
169 }
170 }
171
ParseMp3File()172 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::ParseMp3File()
173 {
174 MP3ErrorType mp3Err = MP3_SUCCESS;
175
176 // Parse the mp3 clip
177 mp3Err = pMP3Parser->ParseMP3File(&iMP3File, iEnableCrcCalc);
178 if (mp3Err == MP3_INSUFFICIENT_DATA)
179 {
180 // not enough data was available to parse the clip
181 return mp3Err;
182 }
183 else if (mp3Err != MP3_SUCCESS)
184 {
185 // some other error occured while parsing the clip.
186 // parsing can not proceed further
187 OSCL_DELETE(pMP3Parser);
188 pMP3Parser = NULL;
189 iMP3File.Close();
190 return mp3Err;
191 }
192 else
193 {
194 // parsing of clip was successful, id3 frames can now be fetched
195 PvmiKvpSharedPtrVector id3Frames;
196 pMP3Parser->GetMetaData(id3Frames);
197
198 // Populate metadata key list vector
199 int32 leavecode = OsclErrNone;
200 for (uint32 p = 0; p < id3Frames.size(); p++)
201 {
202 OSCL_HeapString<OsclMemAllocator> keystr((const char *)((*id3Frames[p]).key), oscl_strlen((const char *)((*id3Frames[p]).key)));
203 leavecode = PushKVPKey(keystr, iAvailableMetadataKeys);
204 if (OsclErrNone != leavecode)
205 {
206 return MP3_ERR_NO_MEMORY;
207 }
208
209 }
210
211 bool metadataDuration = true;
212 if (pMP3Parser->GetDuration(metadataDuration) > 0)
213 {
214 leavecode = OsclErrNone;
215 leavecode = PushKVPKey(PVMP3METADATA_DURATION_FROM_METADATA_KEY, iAvailableMetadataKeys);
216 if (OsclErrNone != leavecode)
217 {
218 return MP3_ERR_NO_MEMORY;
219 }
220 }
221
222 // Following keys are available when the MP3 file has been parsed
223 leavecode = OsclErrNone;
224 leavecode = PushKVPKey(PVMP3METADATA_DURATION_KEY, iAvailableMetadataKeys);
225 if (OsclErrNone != leavecode)
226 {
227 return MP3_ERR_NO_MEMORY;
228 }
229
230 leavecode = OsclErrNone;
231 leavecode = PushKVPKey(PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY, iAvailableMetadataKeys);
232 if (OsclErrNone != leavecode)
233 {
234 return MP3_ERR_NO_MEMORY;
235 }
236
237 leavecode = OsclErrNone;
238 leavecode = PushKVPKey(PVMP3METADATA_NUMTRACKS_KEY, iAvailableMetadataKeys);
239 if (OsclErrNone != leavecode)
240 {
241 return MP3_ERR_NO_MEMORY;
242 }
243
244 leavecode = OsclErrNone;
245 leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY, iAvailableMetadataKeys);
246 if (OsclErrNone != leavecode)
247 {
248 return MP3_ERR_NO_MEMORY;
249 }
250
251 MP3ContentFormatType mp3info;
252 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
253 {
254 if (mp3info.Bitrate > 0)
255 {
256 leavecode = OsclErrNone;
257 leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_BITRATE_KEY, iAvailableMetadataKeys);
258 if (OsclErrNone != leavecode)
259 {
260 return MP3_ERR_NO_MEMORY;
261 }
262 }
263 if (mp3info.SamplingRate > 0)
264 {
265 leavecode = OsclErrNone;
266 leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY, iAvailableMetadataKeys);
267 if (OsclErrNone != leavecode)
268 {
269 return MP3_ERR_NO_MEMORY;
270 }
271 }
272 if (mp3info.NumberOfChannels > 0)
273 {
274 leavecode = OsclErrNone;
275 leavecode = PushKVPKey(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY, iAvailableMetadataKeys);
276 if (OsclErrNone != leavecode)
277 {
278 return MP3_ERR_NO_MEMORY;
279 }
280 }
281 // valid channel mode is present
282 if (mp3info.ChannelMode <= MP3_CHANNEL_MODE_MONO)
283 {
284 leavecode = 0;
285 leavecode = PushKVPKey(PVMP3METADATA_CHANNEL_MODE_KEY, iAvailableMetadataKeys);
286 if (OsclErrNone != leavecode)
287 {
288 return MP3_ERR_NO_MEMORY;
289 }
290 }
291 }
292 }
293 return mp3Err;
294 }
295
GetConfigDetails(MP3ContentFormatType & mp3Config)296 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetConfigDetails(MP3ContentFormatType &mp3Config)
297 {
298 if (pMP3Parser)
299 {
300 MP3ConfigInfoType mp3ConfigHdr;
301 if (pMP3Parser->GetMP3FileHeader(&mp3ConfigHdr))
302 {
303 mp3Config.Bitrate = mp3ConfigHdr.BitRate;
304 mp3Config.FrameSize = mp3ConfigHdr.FrameLengthInBytes;
305 mp3Config.NumberOfChannels = mp3ConfigHdr.NumberOfChannels;
306 mp3Config.SamplingRate = mp3ConfigHdr.SamplingRate;
307 mp3Config.FrameSizeUnComp = mp3ConfigHdr.FrameSizeUnComp;
308 mp3Config.FileSizeInBytes = pMP3Parser->GetFileSize();
309 mp3Config.ChannelMode = pMP3Parser->GetChannelMode();
310 return MP3_SUCCESS;
311 }
312 }
313 return MP3_ERROR_UNKNOWN;
314 }
315
GetNextMediaSample(uint8 * buf,uint32 size,uint32 & framesize,uint32 & timestamp)316 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetNextMediaSample(uint8 *buf, uint32 size, uint32& framesize, uint32& timestamp)
317 {
318 if (pMP3Parser != NULL)
319 {
320 return (pMP3Parser->GetNextMediaSample(buf, size, framesize, timestamp));
321 }
322 else
323 {
324 return MP3_ERROR_UNKNOWN;
325 }
326 }
327
ResetPlayback(uint32 time)328 OSCL_EXPORT_REF uint32 IMpeg3File::ResetPlayback(uint32 time)
329 {
330 if (pMP3Parser != NULL)
331 {
332 return pMP3Parser->SeekToTimestamp(time);
333 }
334 else
335 {
336 return 0;
337 }
338 }
339
GetNextBundledAccessUnits(uint32 * n,GAU * pgau,MP3ErrorType & err)340 OSCL_EXPORT_REF int32 IMpeg3File::GetNextBundledAccessUnits(uint32 *n, GAU *pgau, MP3ErrorType &err)
341 {
342 if (pMP3Parser != NULL)
343 {
344 return pMP3Parser->GetNextBundledAccessUnits(n, pgau, err);
345 }
346 else
347 {
348 return 0;
349 }
350 }
351
PeekNextBundledAccessUnits(uint32 * n,MediaMetaInfo * mInfo)352 OSCL_EXPORT_REF int32 IMpeg3File::PeekNextBundledAccessUnits(uint32 *n, MediaMetaInfo *mInfo)
353 {
354 if (pMP3Parser != NULL)
355 {
356 return pMP3Parser->PeekNextBundledAccessUnits(n, mInfo);
357 }
358 else
359 {
360 return 0;
361 }
362 }
363
GetNumTracks()364 OSCL_EXPORT_REF int32 IMpeg3File::GetNumTracks()
365 {
366 return 1;
367 }
368
GetDuration() const369 OSCL_EXPORT_REF uint32 IMpeg3File::GetDuration() const
370 {
371 if (pMP3Parser != NULL)
372 {
373 return pMP3Parser->GetDuration();
374 }
375 else
376 {
377 return 0;
378 }
379 }
380
ConvertSizeToTime(uint32 aFileSize,uint32 & aNPTInMS) const381 OSCL_EXPORT_REF int32 IMpeg3File::ConvertSizeToTime(uint32 aFileSize, uint32& aNPTInMS) const
382 {
383 if (pMP3Parser != NULL)
384 {
385 return pMP3Parser->ConvertSizeToTime(aFileSize, aNPTInMS);
386 }
387 else
388 {
389 return -1;
390 }
391 }
GetMetadataSize(uint32 & aSize)392 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::GetMetadataSize(uint32 &aSize)
393 {
394 if (pMP3Parser != NULL)
395 {
396 return pMP3Parser->GetMetadataSize(aSize);
397 }
398 return MP3_ERROR_UNKNOWN;
399 }
400
GetMinBytesRequired(bool aNextBytes)401 OSCL_EXPORT_REF uint32 IMpeg3File::GetMinBytesRequired(bool aNextBytes)
402 {
403 if (pMP3Parser != NULL)
404 {
405 return pMP3Parser->GetMinBytesRequired(aNextBytes);
406 }
407 return 0;
408 }
409
GetTimestampForCurrentSample()410 OSCL_EXPORT_REF uint32 IMpeg3File::GetTimestampForCurrentSample()
411 {
412 if (pMP3Parser != NULL)
413 {
414 return pMP3Parser->GetTimestampForCurrentSample();
415 }
416 else
417 {
418 return 0;
419 }
420 }
421
SeekToTimestamp(uint32 timestamp)422 OSCL_EXPORT_REF uint32 IMpeg3File::SeekToTimestamp(uint32 timestamp)
423 {
424 if (pMP3Parser != NULL)
425 {
426 return pMP3Parser->SeekToTimestamp(timestamp);
427 }
428 else
429 {
430 return 0;
431 }
432 }
433
SeekPointFromTimestamp(uint32 & timestamp)434 OSCL_EXPORT_REF uint32 IMpeg3File::SeekPointFromTimestamp(uint32& timestamp)
435 {
436 if (pMP3Parser != NULL)
437 {
438 return pMP3Parser->SeekPointFromTimestamp(timestamp);
439 }
440 else
441 {
442 return 0;
443 }
444 }
445
GetFileOffsetForAutoResume(uint32 & timestamp)446 OSCL_EXPORT_REF uint32 IMpeg3File::GetFileOffsetForAutoResume(uint32& timestamp)
447 {
448 if (pMP3Parser != NULL)
449 {
450 return pMP3Parser->GetFileOffsetForAutoResume(timestamp);
451 }
452 else
453 {
454 return 0;
455 }
456 }
457
GetTimescale() const458 OSCL_EXPORT_REF uint32 IMpeg3File::GetTimescale() const
459 {
460 return 1000;
461 }
462
RandomAccessDenied()463 OSCL_EXPORT_REF uint8 IMpeg3File::RandomAccessDenied()
464 {
465 return false;
466 }
467
GetNumSampleEntries()468 OSCL_EXPORT_REF int32 IMpeg3File::GetNumSampleEntries()
469 {
470 if (pMP3Parser != NULL)
471 {
472 return pMP3Parser->GetSampleCountInFile();
473 }
474 else
475 {
476 return 0;
477 }
478 }
479
GetMaxBufferSizeDB()480 OSCL_EXPORT_REF int32 IMpeg3File::GetMaxBufferSizeDB()
481 {
482 if (pMP3Parser != NULL)
483 {
484 return pMP3Parser->GetMaximumDecodeBufferSize();
485 }
486 else
487 {
488 return 0;
489 }
490 }
491
GetDecoderSpecificInfoContent() const492 OSCL_EXPORT_REF uint8 const * IMpeg3File::GetDecoderSpecificInfoContent() const
493 {
494 if (pMP3Parser != NULL)
495 {
496 return pMP3Parser->GetDecoderSpecificInfoContent();
497 }
498 else
499 {
500 return 0;
501 }
502 }
503
GetDecoderSpecificInfoSize()504 OSCL_EXPORT_REF uint32 IMpeg3File::GetDecoderSpecificInfoSize()
505 {
506 if (pMP3Parser != NULL)
507 {
508 return pMP3Parser->GetDecoderSpecificInfoSize();
509 }
510 else
511 {
512 return 0;
513 }
514 }
515
SetFileSize(const uint32 aFileSize)516 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::SetFileSize(const uint32 aFileSize)
517 {
518 MP3ErrorType errCode = MP3_ERROR_UNKNOWN;
519 if (pMP3Parser != NULL)
520 {
521 errCode = pMP3Parser->SetFileSize(aFileSize);
522 }
523 return errCode;
524 }
525
GetNumMetadataKeys(char * aQueryKeyString)526 OSCL_EXPORT_REF uint32 IMpeg3File::GetNumMetadataKeys(char* aQueryKeyString)
527 {
528 uint32 num_entries = 0;
529
530 if (aQueryKeyString == NULL)
531 {
532 // No query key so just return all the available keys
533 num_entries = iAvailableMetadataKeys.size();
534 }
535 else
536 {
537 // Determine the number of metadata keys based on the query key string provided
538 for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
539 {
540 // Check if the key matches the query key
541 if (oscl_strstr(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) != NULL)
542 {
543 num_entries++;
544 }
545 }
546 }
547
548 return num_entries;
549 }
550
GetNumMetadataValues(PVMFMetadataList & aKeyList)551 OSCL_EXPORT_REF uint32 IMpeg3File::GetNumMetadataValues(PVMFMetadataList& aKeyList)
552 {
553 PvmiKvpSharedPtrVector iFrame;
554
555 uint32 numKeys = aKeyList.size();
556 if (numKeys == 0)
557 {
558 aKeyList = iAvailableMetadataKeys;
559 numKeys = aKeyList.size();
560 }
561
562 uint32 numvalentries = 0;
563 for (uint32 lcv = 0; lcv < numKeys; lcv++)
564 {
565 if (pMP3Parser->IsID3Frame(aKeyList[lcv]))
566 {
567 ++numvalentries;
568 }
569 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_KEY) == 0)
570 {
571 // Duration
572 if (pMP3Parser)
573 {
574 // Increment the counter for the number of values found so far
575 ++numvalentries;
576 }
577 }
578 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY) == 0)
579 {
580 if (pMP3Parser)
581 {
582 // Increment the counter for the number of values found so far
583 ++numvalentries;
584 }
585 }
586 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_NUMTRACKS_KEY) == 0)
587 {
588 // Number of tracks
589 if (pMP3Parser)
590 {
591 // Increment the counter for the number of values found so far
592 ++numvalentries;
593 }
594 }
595 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_BITRATE_KEY) == 0 ||
596 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_BITRATE_KEY) == 0)
597 {
598 // Bitrate
599 MP3ContentFormatType mp3info;
600 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
601 {
602 // Increment the counter for the number of values found so far
603 ++numvalentries;
604 }
605 }
606 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_SAMPLERATE_KEY) == 0 ||
607 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) == 0)
608 {
609 // Sampling rate
610 MP3ContentFormatType mp3info;
611 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
612 {
613 // Increment the counter for the number of values found so far
614 ++numvalentries;
615 }
616 }
617 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_FORMAT_KEY) == 0 ||
618 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0)
619 {
620 // Format
621 // Increment the counter for the number of values found so far
622 ++numvalentries;
623 }
624 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNELS_KEY) == 0 ||
625 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) == 0)
626 {
627 // Channels
628 MP3ContentFormatType mp3info;
629 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
630 {
631 // Increment the counter for the number of values found so far
632 ++numvalentries;
633 }
634 }
635 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNEL_MODE_KEY) == 0 ||
636 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) == 0)
637 {
638 // Channel mode
639 MP3ContentFormatType mp3info;
640 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
641 {
642 // Increment the counter for the number of values found so far
643 ++numvalentries;
644 }
645 }
646 } // End of for loop
647 return numvalentries;
648 }
649
GetMetadataKeys(PVMFMetadataList & aKeyList,uint32 aStartingKeyIndex,int32 aMaxKeyEntries,char * aQueryKeyString)650 OSCL_EXPORT_REF PVMFStatus IMpeg3File::GetMetadataKeys(PVMFMetadataList& aKeyList, uint32 aStartingKeyIndex, int32 aMaxKeyEntries, char* aQueryKeyString)
651 {
652 // Check parameters
653 if ((aStartingKeyIndex > (iAvailableMetadataKeys.size() - 1)) || aMaxKeyEntries == 0)
654 {
655 // Invalid starting index and/or max entries
656 return PVMFErrArgument;
657 }
658
659 // Copy the requested keys
660 uint32 num_entries = 0;
661 int32 num_added = 0;
662 int32 leavecode = OsclErrNone;
663 for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
664 {
665 if (aQueryKeyString == NULL)
666 {
667 // No query key so this key is counted
668 ++num_entries;
669 if (num_entries > aStartingKeyIndex)
670 {
671 // Past the starting index so copy the key
672 leavecode = OsclErrNone;
673 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv].get_cstr(), aKeyList);
674 if (OsclErrNone != leavecode)
675 {
676 return PVMFErrNoMemory;
677 }
678 num_added++;
679 }
680 }
681 else
682 {
683 // Check if the key matches the query key
684 if (oscl_strstr(iAvailableMetadataKeys[lcv].get_cstr(), aQueryKeyString) != NULL)
685 {
686 // This key is counted
687 ++num_entries;
688 if (num_entries > aStartingKeyIndex)
689 {
690 // Past the starting index so copy the key
691 leavecode = OsclErrNone;
692 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv].get_cstr(), aKeyList);
693 if (OsclErrNone != leavecode)
694 {
695 return PVMFErrNoMemory;
696 }
697 num_added++;
698 }
699 }
700 }
701
702 // Check if max number of entries have been copied
703 if (aMaxKeyEntries > 0 && num_added >= aMaxKeyEntries)
704 {
705 break;
706 }
707 }
708
709 return PVMFSuccess;
710 }
711
GetMetadataValues(PVMFMetadataList & aKeyList,Oscl_Vector<PvmiKvp,OsclMemAllocator> & aValueList,uint32 aStartingValueIndex,int32 aMaxValueEntries)712 OSCL_EXPORT_REF PVMFStatus IMpeg3File::GetMetadataValues(PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
713 uint32 aStartingValueIndex, int32 aMaxValueEntries)
714 {
715 uint32 numKeys = aKeyList.size();
716 PvmiKvpSharedPtrVector iFrame;
717 PVMFMetadataList parsedKeys;
718 if (numKeys == 0 || aStartingValueIndex > (numKeys - 1) || aMaxValueEntries == 0)
719 {
720 return PVMFErrArgument;
721 }
722
723 uint32 numvalentries = 0;
724 int32 numentriesadded = 0;
725 bool gotvalue = false;
726 uint32 lcv = 0;
727 for (lcv = 0; lcv < numKeys; lcv++)
728 {
729 //check if this key has already been parsed.
730 for (uint32 pks = 0; pks < parsedKeys.size(); pks++)
731 {
732 if (pv_mime_strcmp(parsedKeys[pks].get_cstr(), aKeyList[lcv].get_cstr()) >= 0)
733 {
734 gotvalue = true; //key already parsed.
735 break;
736 }
737 }
738
739 if (gotvalue) //get next key since this key has already been parsed.
740 {
741 gotvalue = false;
742 continue;
743 }
744 pMP3Parser->GetMetaData(aKeyList[lcv], iFrame);
745 if (iFrame.size() > 1) //multiple id3 frames exist for this key.
746 {
747 parsedKeys.push_back(aKeyList[lcv]);
748 }
749
750 while (iFrame.size() > 0)
751 {
752 PvmiKvp KeyVal;
753 KeyVal.key = NULL;
754 KeyVal.length = 0;
755 char *key = (*(iFrame.back())).key;
756 int32 len = (*(iFrame.back())).length;
757
758 ++numvalentries;
759
760 int32 leavecode = OsclErrNone;
761 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, oscl_strlen(key) + 1);
762
763 if (OsclErrNone != leavecode)
764 {
765 // allocation failed
766 return PVMFErrNoMemory;
767 }
768
769 oscl_strncpy(KeyVal.key , key, oscl_strlen(key) + 1);
770 KeyVal.length = len;
771 KeyVal.capacity = (*(iFrame.back())).capacity;
772
773 if (KeyVal.length > 0)
774 {
775 PvmiKvpValueType ValueType = GetValTypeFromKeyString(key);
776 leavecode = OsclErrNone;
777 switch (ValueType)
778 {
779
780 case PVMI_KVPVALTYPE_WCHARPTR:
781 KeyVal.value.pWChar_value = (oscl_wchar*) AllocateKVPKeyArray(leavecode, ValueType, len);
782 oscl_strncpy(KeyVal.value.pWChar_value , (*(iFrame.back())).value.pWChar_value, len);
783 KeyVal.value.pWChar_value[len] = 0;
784 break;
785 case PVMI_KVPVALTYPE_CHARPTR:
786 KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode, ValueType, len);
787 oscl_strncpy(KeyVal.value.pChar_value , (*(iFrame.back())).value.pChar_value, len);
788 KeyVal.value.pChar_value[len] = 0;
789 break;
790 case PVMI_KVPVALTYPE_UINT8PTR:
791 KeyVal.value.pUint8_value = (uint8*) AllocateKVPKeyArray(leavecode, ValueType, len);
792 oscl_memcpy(KeyVal.value.pUint8_value, (uint8*)(*(iFrame.back())).value.pUint8_value, len);
793 break;
794 case PVMI_KVPVALTYPE_UINT32:
795 KeyVal.value.uint32_value = (*(iFrame.back())).value.uint32_value;
796 break;
797 case PVMI_KVPVALTYPE_KSV:
798 KeyVal.value.key_specific_value = (*(iFrame.back())).value.key_specific_value;
799 break;
800 default:
801 break;
802 }
803
804 if (OsclErrNone != leavecode)
805 {
806 // allocation failed
807 return PVMFErrNoMemory;
808 }
809
810 leavecode = OsclErrNone;
811 leavecode = PushKVPValue(KeyVal, aValueList);
812 if (OsclErrNone != leavecode)
813 {
814 // push kvp failed
815 return PVMFErrNoMemory;
816 }
817 ++numentriesadded;
818 }
819 iFrame.pop_back();
820 }
821 }
822
823 for (lcv = 0; lcv < numKeys; lcv++)
824 {
825
826 int32 leavecode = OsclErrNone;
827 PvmiKvp KeyVal;
828 KeyVal.key = NULL;
829 uint32 KeyLen = 0;
830
831 if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_KEY))
832 {
833 // Duration
834 if (pMP3Parser)
835 {
836 // Increment the counter for the number of values found so far
837 ++numvalentries;
838
839 // Create a value entry if past the starting index
840 if (numvalentries > aStartingValueIndex)
841 {
842 uint32 duration = 0;
843 // decision for walking the entire file in order to calculate
844 // clip duration is made here. currently complete file is scanned
845 // when compute flag is not present , Compute clip duration by default
846 duration = pMP3Parser->GetDuration();
847
848 if (duration > 0)
849 {
850 KeyLen = oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1; // for "duration;"
851 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
852 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32;"
853 KeyLen += oscl_strlen(PVMP3METADATA_TIMESCALE1000) + 1; // for "timescale=1000" and NULL terminator
854
855 // Allocate memory for the string
856 leavecode = OsclErrNone;
857 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
858 if (OsclErrNone == leavecode)
859 {
860 // Copy the key string
861 oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
862 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
863 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
864 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
865 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
866 oscl_strncat(KeyVal.key, PVMP3METADATA_TIMESCALE1000, oscl_strlen(PVMP3METADATA_TIMESCALE1000));
867 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
868 // Copy the value
869 KeyVal.value.uint32_value = pMP3Parser->GetDuration();
870 // Set the length and capacity
871 KeyVal.length = 1;
872 KeyVal.capacity = 1;
873 }
874 else
875 {
876 // Memory allocation failed
877 KeyVal.key = NULL;
878 break;
879 }
880 }
881 else
882 {
883 KeyLen = oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1; // for "duration;"
884 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
885 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*;"
886
887 // Allocate memory for the string
888 leavecode = OsclErrNone;
889 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
890
891 if (OsclErrNone == leavecode)
892 {
893 oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
894 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
895 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
896 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
897
898 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
899
900 }
901 else
902 {
903 // Memory allocation failed
904 KeyVal.key = NULL;
905 break;
906 }
907
908 uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMP3METADATA_UNKNOWN)) + 1; // Add value string plus one for NULL terminator
909 leavecode = OsclErrNone;
910 KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, valuelen);
911
912 if (OsclErrNone == leavecode)
913 {
914 // Copy the value
915 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMP3METADATA_UNKNOWN), valuelen);
916 KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
917 // Set the length and capacity
918 KeyVal.length = valuelen;
919 KeyVal.capacity = valuelen;
920 }
921 else
922 {
923 // Memory allocation failed
924 KeyVal.key = NULL;
925 break;
926 }
927 }
928 }
929 }
930 }
931 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY))
932 {
933 // Duration
934 if (pMP3Parser)
935 {
936 // Increment the counter for the number of values found so far
937 ++numvalentries;
938
939 // Create a value entry if past the starting index
940 if (numvalentries > aStartingValueIndex)
941 {
942 KeyLen = oscl_strlen(PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY) + 1; // for "random-access-denied;"
943 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
944 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING_CONSTCHAR) + 1; // for "bool;"
945
946 // Allocate memory for the string
947 leavecode = OsclErrNone;
948 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
949 if (OsclErrNone == leavecode)
950 {
951 // Copy the key string
952 oscl_strncpy(KeyVal.key, PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY, oscl_strlen(PVMP3METADATA_RANDOM_ACCESS_DENIED_KEY) + 1);
953 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
954 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
955 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_BOOL_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
956 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
957 // Copy the value
958 KeyVal.value.bool_value = pMP3Parser->GetDuration() > 0 ? false : true;
959 // Set the length and capacity
960 KeyVal.length = 1;
961 KeyVal.capacity = 1;
962 }
963 else
964 {
965 // Memory allocation failed
966 KeyVal.key = NULL;
967 break;
968 }
969 }
970 }
971 }
972 else if (oscl_strstr(aKeyList[lcv].get_cstr(), PVMP3METADATA_DURATION_FROM_METADATA_KEY))
973 {
974 // Duration
975 if (pMP3Parser)
976 {
977 // Increment the counter for the number of values found so far
978 ++numvalentries;
979
980 // Create a value entry if past the starting index
981 if (numvalentries > aStartingValueIndex)
982 {
983 uint32 duration = 0;
984 // decision for walking the entire file in order to calculate
985 // clip duration is made here. currently complete file is scanned
986 // when compute flag is not present , Compute clip duration by default
987 bool metadataDuration = true;
988 duration = pMP3Parser->GetDuration(metadataDuration);
989
990 if (duration > 0)
991 {
992 KeyLen = oscl_strlen(PVMP3METADATA_DURATION_FROM_METADATA_KEY) + 1; // for "duration;"
993 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
994 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32;"
995 KeyLen += oscl_strlen(PVMP3METADATA_TIMESCALE1000) + 1; // for "timescale=1000" and NULL terminator
996
997 // Allocate memory for the string
998 leavecode = OsclErrNone;
999 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1000 if (OsclErrNone == leavecode)
1001 {
1002 // Copy the key string
1003 oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_FROM_METADATA_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
1004 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1005 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1006 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1007 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1008 oscl_strncat(KeyVal.key, PVMP3METADATA_TIMESCALE1000, oscl_strlen(PVMP3METADATA_TIMESCALE1000));
1009 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1010 // Copy the value
1011 KeyVal.value.uint32_value = pMP3Parser->GetDuration();
1012 // Set the length and capacity
1013 KeyVal.length = 1;
1014 KeyVal.capacity = 1;
1015 }
1016 else
1017 {
1018 // Memory allocation failed
1019 KeyVal.key = NULL;
1020 break;
1021 }
1022 }
1023 else
1024 {
1025 KeyLen = oscl_strlen(PVMP3METADATA_DURATION_FROM_METADATA_KEY) + 1; // for "duration;"
1026 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1027 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*;"
1028
1029 // Allocate memory for the string
1030 leavecode = OsclErrNone;
1031 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1032
1033
1034 if (OsclErrNone == leavecode)
1035 {
1036 oscl_strncpy(KeyVal.key, PVMP3METADATA_DURATION_FROM_METADATA_KEY, oscl_strlen(PVMP3METADATA_DURATION_KEY) + 1);
1037 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1038 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1039 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
1040
1041 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1042 }
1043 else
1044 {
1045 // Memory allocation failed
1046 KeyVal.key = NULL;
1047 break;
1048 }
1049
1050 uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMP3METADATA_UNKNOWN)) + 1; // Add value string plus one for NULL terminator
1051 leavecode = OsclErrNone;
1052 KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, valuelen);
1053
1054 if (OsclErrNone == leavecode)
1055 {
1056 // Copy the value
1057 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMP3METADATA_UNKNOWN), valuelen);
1058 KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
1059 // Set the length and capacity
1060 KeyVal.length = valuelen;
1061 KeyVal.capacity = valuelen;
1062 }
1063 else
1064 {
1065 // Memory allocation failed
1066 KeyVal.key = NULL;
1067 break;
1068 }
1069 }
1070 }
1071 }
1072 }
1073 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_NUMTRACKS_KEY) == 0)
1074 {
1075 // Number of tracks
1076 if (pMP3Parser)
1077 {
1078 // Increment the counter for the number of values found so far
1079 ++numvalentries;
1080
1081 // Create a value entry if past the starting index
1082 if (numvalentries > aStartingValueIndex)
1083 {
1084 KeyLen = oscl_strlen(PVMP3METADATA_NUMTRACKS_KEY) + 1; // for "num-tracks;"
1085 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1086 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
1087
1088 // Allocate memory for the string
1089 leavecode = OsclErrNone;
1090 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1091
1092 if (OsclErrNone == leavecode)
1093 {
1094 // Copy the key string
1095 oscl_strncpy(KeyVal.key, PVMP3METADATA_NUMTRACKS_KEY, oscl_strlen(PVMP3METADATA_NUMTRACKS_KEY) + 1);
1096 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1097 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1098 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1099 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1100 // Copy the value
1101 KeyVal.value.uint32_value = 1; // Number of tracks supported in PV MP3 parser would always be 1
1102 // Set the length and capacity
1103 KeyVal.length = 1;
1104 KeyVal.capacity = 1;
1105 }
1106 else
1107 {
1108 // Memory allocation failed
1109 KeyVal.key = NULL;
1110 break;
1111 }
1112 }
1113 }
1114 }
1115 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_BITRATE_KEY) == 0 ||
1116 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_BITRATE_KEY) == 0)
1117 {
1118 // Bitrate
1119 MP3ContentFormatType mp3info;
1120 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
1121 {
1122 // Increment the counter for the number of values found so far
1123 ++numvalentries;
1124
1125 // Create a value entry if past the starting index
1126 if (numvalentries > aStartingValueIndex)
1127 {
1128 KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_BITRATE_KEY) + 1; // for "track-info/bitrate;"
1129 KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
1130 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1131 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
1132
1133 // Allocate memory for the string
1134 leavecode = OsclErrNone;
1135 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1136
1137 if (OsclErrNone == leavecode)
1138 {
1139 // Copy the key string
1140 oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_BITRATE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_BITRATE_KEY) + 1);
1141 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1142 oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
1143 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1144 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1145 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1146 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1147 // Copy the value
1148 KeyVal.value.uint32_value = mp3info.Bitrate;
1149 // Set the length and capacity
1150 KeyVal.length = 1;
1151 KeyVal.capacity = 1;
1152 }
1153 else
1154 {
1155 // Memory allocation failed
1156 KeyVal.key = NULL;
1157 break;
1158 }
1159 }
1160 }
1161 }
1162 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_SAMPLERATE_KEY) == 0 ||
1163 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) == 0)
1164 {
1165 // Sampling rate
1166 MP3ContentFormatType mp3info;
1167 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
1168 {
1169 // Increment the counter for the number of values found so far
1170 ++numvalentries;
1171
1172 // Create a value entry if past the starting index
1173 if (numvalentries > aStartingValueIndex)
1174 {
1175 KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) + 1; // for "track-info/samplingrate;"
1176 KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
1177 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1178 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
1179
1180 // Allocate memory for the string
1181 leavecode = 0;
1182 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1183
1184 if (OsclErrNone == leavecode)
1185 {
1186 // Copy the key string
1187 oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_SAMPLERATE_KEY) + 1);
1188 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1189 oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
1190 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1191 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1192 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1193 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1194 // Copy the value
1195 KeyVal.value.uint32_value = mp3info.SamplingRate;
1196 // Set the length and capacity
1197 KeyVal.length = 1;
1198 KeyVal.capacity = 1;
1199 }
1200 else
1201 {
1202 // Memory allocation failed
1203 KeyVal.key = NULL;
1204 break;
1205 }
1206 }
1207 }
1208 }
1209 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_FORMAT_KEY) == 0 ||
1210 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0)
1211 {
1212 // Format
1213 // Increment the counter for the number of values found so far
1214 ++numvalentries;
1215
1216 // Create a value entry if past the starting index
1217 if (numvalentries > aStartingValueIndex)
1218 {
1219 KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) + 1; // for "track-info/audio/format;"
1220 KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
1221 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1222 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator
1223
1224 uint32 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_MP3)) + 1; // Add value string plus one for NULL terminator
1225 // Allocate memory for the strings
1226 int32 leavecode1 = OsclErrNone;
1227 leavecode = OsclErrNone;
1228 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1229 if (OsclErrNone == leavecode)
1230 {
1231 KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode1, PVMI_KVPVALTYPE_CHARPTR, valuelen);
1232 }
1233
1234 if (OsclErrNone == leavecode && OsclErrNone == leavecode1)
1235 {
1236 // Copy the key string
1237 oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_FORMAT_KEY) + 1);
1238 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1239 oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
1240 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1241 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1242 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
1243 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1244 // Copy the value
1245 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_MP3), valuelen);
1246 KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
1247 // Set the length and capacity
1248 KeyVal.length = valuelen;
1249 KeyVal.capacity = valuelen;
1250 }
1251 else
1252 {
1253 // Memory allocation failed so clean up
1254 if (KeyVal.key)
1255 {
1256 OSCL_ARRAY_DELETE(KeyVal.key);
1257 KeyVal.key = NULL;
1258 }
1259 if (KeyVal.value.pChar_value)
1260 {
1261 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
1262 }
1263 break;
1264 }
1265 }
1266 }
1267 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNELS_KEY) == 0 ||
1268 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) == 0)
1269 {
1270 // Channels
1271 MP3ContentFormatType mp3info;
1272 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
1273 {
1274 // Increment the counter for the number of values found so far
1275 ++numvalentries;
1276
1277 // Create a value entry if past the starting index
1278 if (numvalentries > aStartingValueIndex)
1279 {
1280 KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) + 1; // for "track-info/audio/channels;"
1281 KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
1282 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1283 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
1284
1285 // Allocate memory for the string
1286 leavecode = OsclErrNone;
1287 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1288
1289 if (OsclErrNone == leavecode)
1290 {
1291 // Copy the key string
1292 oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNELS_KEY) + 1);
1293 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1294 oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
1295 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1296 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1297 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1298 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1299 // Copy the value
1300 KeyVal.value.uint32_value = mp3info.NumberOfChannels;
1301 // Set the length and capacity
1302 KeyVal.length = 1;
1303 KeyVal.capacity = 1;
1304 }
1305 else
1306 {
1307 // Memory allocation failed
1308 KeyVal.key = NULL;
1309 break;
1310 }
1311 }
1312 }
1313 }
1314 else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_CHANNEL_MODE_KEY) == 0 ||
1315 oscl_strcmp(aKeyList[lcv].get_cstr(), PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) == 0)
1316 {
1317 // Channel mode
1318 MP3ContentFormatType mp3info;
1319 if (GetConfigDetails(mp3info) == MP3_SUCCESS)
1320 {
1321 // Increment the counter for the number of values found so far
1322 ++numvalentries;
1323
1324 // Create a value entry if past the starting index
1325 if (numvalentries > aStartingValueIndex)
1326 {
1327 KeyLen = oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) + 1; // for "track-info/audio/channel-mode;"
1328 KeyLen += oscl_strlen(PVMP3METADATA_INDEX0) + 1; // for "index=0;"
1329 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1330 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
1331
1332 // Allocate memory for the string
1333 leavecode = 0;
1334 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1335
1336 if (leavecode == 0)
1337 {
1338 // Copy the key string
1339 oscl_strncpy(KeyVal.key, PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY, oscl_strlen(PVMP3METADATA_TRACKINFO_AUDIO_CHANNEL_MODE_KEY) + 1);
1340 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1341 oscl_strncat(KeyVal.key, PVMP3METADATA_INDEX0, oscl_strlen(PVMP3METADATA_INDEX0));
1342 oscl_strncat(KeyVal.key, PVMP3METADATA_SEMICOLON, oscl_strlen(PVMP3METADATA_SEMICOLON));
1343 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1344 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1345 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1346 // Copy the value
1347 KeyVal.value.uint32_value = mp3info.ChannelMode;
1348 // Set the length and capacity
1349 KeyVal.length = 1;
1350 KeyVal.capacity = 1;
1351 }
1352 else
1353 {
1354 // Memory allocation failed
1355 KeyVal.key = NULL;
1356 break;
1357 }
1358 }
1359 }
1360 }
1361
1362 // Add the KVP to the list if the key string was created
1363 if (KeyVal.key != NULL)
1364 {
1365 leavecode = OsclErrNone;
1366 leavecode = PushKVPValue(KeyVal, aValueList);
1367 if (OsclErrNone != leavecode)
1368 {
1369 // push kvp failed
1370 return PVMFErrNoMemory;
1371 }
1372
1373 // Increment the counter for number of value entries added to the list
1374 ++numentriesadded;
1375 // Check if the max number of value entries were added
1376 if (aMaxValueEntries > 0 && numentriesadded >= aMaxValueEntries)
1377 {
1378 // Maximum number of values added so break out of the loop
1379 break;
1380 }
1381 }
1382
1383 } // End of for loop
1384
1385 return PVMFSuccess;
1386 }
1387
ReleaseMetadataValue(PvmiKvp & aValueKVP)1388 OSCL_EXPORT_REF PVMFStatus IMpeg3File::ReleaseMetadataValue(PvmiKvp& aValueKVP)
1389 {
1390 if (aValueKVP.key == NULL)
1391 {
1392 return PVMFErrArgument;
1393 }
1394
1395 switch (GetValTypeFromKeyString(aValueKVP.key))
1396 {
1397 case PVMI_KVPVALTYPE_WCHARPTR:
1398 if ((aValueKVP.value.pWChar_value != NULL) && (aValueKVP.length != 0))
1399 {
1400 OSCL_ARRAY_DELETE(aValueKVP.value.pWChar_value);
1401 aValueKVP.value.pWChar_value = NULL;
1402
1403 }
1404 break;
1405
1406 case PVMI_KVPVALTYPE_CHARPTR:
1407 if ((aValueKVP.value.pChar_value != NULL) && (aValueKVP.length != 0))
1408 {
1409 OSCL_ARRAY_DELETE(aValueKVP.value.pChar_value);
1410 aValueKVP.value.pChar_value = NULL;
1411 }
1412 break;
1413
1414 case PVMI_KVPVALTYPE_UINT8PTR:
1415 if ((aValueKVP.value.pUint8_value != NULL) && (aValueKVP.length != 0))
1416 {
1417 OSCL_ARRAY_DELETE(aValueKVP.value.pUint8_value);
1418 aValueKVP.value.pUint8_value = NULL;
1419 }
1420
1421 break;
1422
1423 case PVMI_KVPVALTYPE_UINT32:
1424 case PVMI_KVPVALTYPE_UINT8:
1425 // No memory to free for these valtypes
1426 break;
1427
1428 default:
1429 // Should not get a value that wasn't created from here
1430 break;
1431 }
1432
1433 OSCL_ARRAY_DELETE(aValueKVP.key);
1434 aValueKVP.key = NULL;
1435
1436 return PVMFSuccess;
1437 }
1438
1439
IsMp3File(OSCL_wString & aFileName,PVMFCPMPluginAccessInterfaceFactory * aCPMAccessFactory,uint32 aInitSearchFileSize)1440 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::IsMp3File(OSCL_wString& aFileName,
1441 PVMFCPMPluginAccessInterfaceFactory *aCPMAccessFactory,
1442 uint32 aInitSearchFileSize)
1443 {
1444 MP3ErrorType errCode = MP3_ERROR_UNKNOWN_OBJECT;
1445
1446 MP3_FF_FILE fileStruct;
1447 MP3_FF_FILE *fp = &fileStruct;
1448
1449 fp->_pvfile.SetCPM(aCPMAccessFactory);
1450
1451 // open the dummy file
1452 if (MP3Utils::OpenFile(aFileName,
1453 Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
1454 fp) != 0)
1455 {
1456 errCode = MP3_FILE_OPEN_FAILED;
1457 return errCode;
1458 }
1459 // create the file parser object to recognize the clip
1460 MP3Parser* mp3Parser = NULL;
1461 mp3Parser = OSCL_NEW(MP3Parser, ());
1462
1463 errCode = (mp3Parser) ? MP3_SUCCESS : MP3_ERROR_UNKNOWN;
1464
1465 // File was opened successfully, clip recognition can proceed
1466 if (errCode == MP3_SUCCESS)
1467 {
1468 errCode = mp3Parser->IsMp3File(fp, aInitSearchFileSize);
1469 //deallocate the MP3Parser object created
1470 if (mp3Parser)
1471 {
1472 delete mp3Parser;
1473 mp3Parser = NULL;
1474 }
1475 }
1476 // close the file
1477 MP3Utils::CloseFile(&(fp->_pvfile)); //Close the MP3 File
1478 return errCode;
1479 }
1480
1481
RequestReadCapacityNotification(PvmiDataStreamObserver & aObserver,uint32 aFileOffset,OsclAny * aContextData)1482 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::RequestReadCapacityNotification(PvmiDataStreamObserver& aObserver,
1483 uint32 aFileOffset,
1484 OsclAny* aContextData)
1485 {
1486 uint32 capacity = 0;
1487 uint32 currFilePosn = MP3Utils::getCurrentFilePosition(&iMP3File);
1488 if (aFileOffset > currFilePosn)
1489 {
1490 capacity = (aFileOffset - currFilePosn);
1491 bool retVal =
1492 iMP3File.RequestReadCapacityNotification(aObserver, capacity, aContextData);
1493 if (retVal)
1494 {
1495 return MP3_SUCCESS;
1496 }
1497 }
1498 return MP3_END_OF_FILE;
1499 }
1500
ScanMP3File(uint32 aFramesToScan)1501 OSCL_EXPORT_REF MP3ErrorType IMpeg3File::ScanMP3File(uint32 aFramesToScan)
1502 {
1503 if (pMP3Parser && iScanFP.IsOpen())
1504 return pMP3Parser->ScanMP3File(&iScanFP, aFramesToScan);
1505 return MP3_ERROR_UNKNOWN;
1506 }
1507
AllocateKVPKeyArray(int32 & aLeaveCode,PvmiKvpValueType aValueType,int32 aNumElements)1508 OsclAny* IMpeg3File::AllocateKVPKeyArray(int32& aLeaveCode, PvmiKvpValueType aValueType, int32 aNumElements)
1509 {
1510 int32 leaveCode = OsclErrNone;
1511 OsclAny* aBuffer = NULL;
1512 switch (aValueType)
1513 {
1514 case PVMI_KVPVALTYPE_WCHARPTR:
1515 OSCL_TRY(leaveCode,
1516 aBuffer = (oscl_wchar*) OSCL_ARRAY_NEW(oscl_wchar, aNumElements + 1);
1517 );
1518 break;
1519
1520 case PVMI_KVPVALTYPE_CHARPTR:
1521 OSCL_TRY(leaveCode,
1522 aBuffer = (char*) OSCL_ARRAY_NEW(char, aNumElements + 1);
1523 );
1524 break;
1525 case PVMI_KVPVALTYPE_UINT8PTR:
1526 OSCL_TRY(leaveCode,
1527 aBuffer = (uint8*) OSCL_ARRAY_NEW(uint8, aNumElements);
1528 );
1529 break;
1530 default:
1531 break;
1532 }
1533 aLeaveCode = leaveCode;
1534 return aBuffer;
1535 }
1536
1537
PushKVPValue(PvmiKvp aKVP,Oscl_Vector<PvmiKvp,OsclMemAllocator> & aValueList)1538 int32 IMpeg3File::PushKVPValue(PvmiKvp aKVP, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList)
1539 {
1540 int32 leavecode = OsclErrNone;
1541 OSCL_TRY(leavecode, aValueList.push_back(aKVP));
1542 if (OsclErrNone != leavecode)
1543 {
1544 ReleaseMetadataValue(aKVP);
1545 }
1546 return leavecode;
1547 }
1548
PushKVPKey(const char * aString,PVMFMetadataList & aKeyList)1549 int32 IMpeg3File::PushKVPKey(const char* aString, PVMFMetadataList& aKeyList)
1550 {
1551 int32 leavecode = OsclErrNone;
1552 OSCL_TRY(leavecode, aKeyList.push_back(aString));
1553 return leavecode;
1554 }
1555
PushKVPKey(OSCL_HeapString<OsclMemAllocator> & aString,Oscl_Vector<OSCL_HeapString<OsclMemAllocator>,OsclMemAllocator> & aKeyList)1556 int32 IMpeg3File::PushKVPKey(OSCL_HeapString<OsclMemAllocator>& aString, Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator>& aKeyList)
1557 {
1558 int32 leavecode = OsclErrNone;
1559 OSCL_TRY(leavecode, aKeyList.push_back(aString));
1560 return leavecode;
1561 }
1562