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 /*********************************************************************************/
19 /* ------------------------------------------------------------------- */
20 /* MPEG-4 Atom Utils Class */
21 /* ------------------------------------------------------------------- */
22 /*********************************************************************************/
23 /*
24 This AtomUtils Class contains sime useful methods for operating on Atoms
25 */
26
27
28 #define IMPLEMENT_AtomUtils
29 #include "oscl_base.h"
30 #include "oscl_int64_utils.h"
31 #include "atomutils.h"
32 #include "atomdefs.h"
33 #include "oscl_utf8conv.h"
34
35 // Read in the 64 bits byte by byte and take most significant byte first
36 OSCL_EXPORT_REF bool
read64(MP4_FF_FILE * fp,uint64 & data)37 AtomUtils::read64(MP4_FF_FILE *fp, uint64 &data)
38 {
39 const int32 N = 8;
40 uint8 bytes[N];
41 data = 0;
42
43 int32 retVal = 0;
44
45 retVal = (int32) fp->_pvfile.Read((void*)bytes, 1, N);
46
47 if (retVal < N)
48 {
49 return false;
50 }
51
52 uint32 low = 0;
53 uint32 high = 0;
54
55 int32 i;
56 for (i = 0; i < N / 2; i++)
57 {
58 high = (high << 8) | bytes[i];
59 }
60 for (i = N / 2; i < N; i++)
61 {
62 low = (low << 8) | bytes[i];
63 }
64 Oscl_Int64_Utils::set_uint64(data, high, low);
65 return true;
66 }
67
68
69 // Read in the 32 bits byte by byte and take most significant byte first
70 OSCL_EXPORT_REF bool
read32(MP4_FF_FILE * fp,uint32 & data)71 AtomUtils::read32(MP4_FF_FILE *fp, uint32 &data)
72 {
73 const int32 N = 4;
74 uint8 bytes[N];
75 data = 0;
76
77 int32 retVal = 0;
78
79 retVal = (int32)(fp->_pvfile.Read((void*)bytes, 1, N));
80
81 if (retVal < N)
82 return false;
83
84 for (int32 i = 0; i < N; i++)
85 data = (data << 8) | bytes[i];
86
87 return true;
88 }
89
90 // Read in the 32 bits byte by byte and take most significant byte first.
91 // This is equivalent to two read32 calls.
92 OSCL_EXPORT_REF bool
read32read32(MP4_FF_FILE * fp,uint32 & data1,uint32 & data2)93 AtomUtils::read32read32(MP4_FF_FILE *fp, uint32 &data1, uint32 &data2)
94 {
95 const int32 N = 8;
96 uint8 bytes[N];
97 data1 = 0;
98 data2 = 0;
99
100 int32 retVal = 0;
101
102 retVal = (int32)(fp->_pvfile.Read((void*)bytes, 1, N));
103
104 if (retVal < N)
105 return false;
106
107 int32 i;
108 for (i = 0; i < 4; i++)
109 data1 = (data1 << 8) | bytes[i];
110
111 for (i = 4; i < 8; i++)
112 data2 = (data2 << 8) | bytes[i];
113
114 return true;
115 }
116
117 // Read in the 24 bits byte by byte and take most significant byte first
118 OSCL_EXPORT_REF bool
read24(MP4_FF_FILE * fp,uint32 & data)119 AtomUtils::read24(MP4_FF_FILE *fp, uint32 &data)
120 {
121 const int32 N = 3;
122 uint8 bytes[N];
123 data = 0;
124
125 int32 retVal = 0;
126
127 retVal = (int32)(fp->_pvfile.Read((void*)bytes, 1, N));
128
129 if (retVal < N)
130 return false;
131
132 for (int32 i = 0; i < N; i++)
133 data = (data << 8) | bytes[i];
134
135 return true;
136 }
137
138 // Read in the 16 bits byte by byte and take most significant byte first
139 OSCL_EXPORT_REF bool
read16(MP4_FF_FILE * fp,uint16 & data)140 AtomUtils::read16(MP4_FF_FILE *fp, uint16 &data)
141 {
142 const int32 N = 2;
143 uint8 bytes[N];
144 data = 0;
145
146 int32 retVal = 0;
147
148 retVal = (int32)(fp->_pvfile.Read((void*)bytes, 1, N));
149
150 if (retVal < N)
151 return false;
152
153 for (int32 i = 0; i < N; i++)
154 data = (uint16)((data << 8) | (uint16) bytes[i]);
155
156 return true;
157 }
158
159 // Read in the 16 bits byte by byte and take most significant byte first
160 // This is equivalent to two read16 calls
161 OSCL_EXPORT_REF bool
read16read16(MP4_FF_FILE * fp,uint16 & data1,uint16 & data2)162 AtomUtils::read16read16(MP4_FF_FILE *fp, uint16 &data1, uint16 &data2)
163 {
164 const int32 N = 4;
165 uint8 bytes[N];
166 data1 = 0;
167 data2 = 0;
168
169 int32 retVal = 0;
170
171 retVal = (int32)(fp->_pvfile.Read((void*)bytes, 1, N));
172
173 if (retVal < N)
174 return false;
175
176 int32 i;
177 for (i = 0; i < 2; i++)
178 data1 = (uint16)((data1 << 8) | (uint16) bytes[i]);
179
180 for (i = 2; i < 4; i++)
181 data2 = (uint16)((data2 << 8) | (uint16) bytes[i]);
182
183 return true;
184 }
185
186 // Read in the 8 bit byte
187 OSCL_EXPORT_REF bool
read8(MP4_FF_FILE * fp,uint8 & data)188 AtomUtils::read8(MP4_FF_FILE *fp, uint8 &data)
189 {
190 data = 0;
191
192 int32 retVal = 0;
193
194 retVal = (int32)(fp->_pvfile.Read((void*) & data, 1, 1));
195
196 if (retVal < 1)
197 return false;
198
199 return true;
200 }
201
202 // Read in the 8 bit byte
203 // This is equivalent to two read8 calls
204 OSCL_EXPORT_REF bool
read8read8(MP4_FF_FILE * fp,uint8 & data1,uint8 & data2)205 AtomUtils::read8read8(MP4_FF_FILE *fp, uint8 &data1, uint8 &data2)
206 {
207 const int32 N = 2;
208 uint8 bytes[N];
209 data1 = 0;
210 data2 = 0;
211
212 int32 retVal = 0;
213
214 retVal = (int32)(fp->_pvfile.Read((void*)bytes, 1, N));
215
216 if (retVal < N)
217 return false;
218
219 data1 = bytes[0];
220 data2 = bytes[1];
221
222 return true;
223 }
224 // Read in a NULL terminated string byte by byte and take most significant byte first
225 // and convert to a OSCL_wString
226 OSCL_EXPORT_REF bool
readNullTerminatedString(MP4_FF_FILE * fp,OSCL_wString & data)227 AtomUtils::readNullTerminatedString(MP4_FF_FILE *fp, OSCL_wString& data)
228 {
229 const int MAX_BUFF_SIZE = 1024;
230 uint8 buf[MAX_BUFF_SIZE];
231 int32 index = 0;
232
233 if (!AtomUtils::read8(fp, buf[index]))
234 return false;
235
236 bool nextChar = (buf[index] == 0) ? false : true;
237
238 while (nextChar && (index < MAX_BUFF_SIZE))
239 {
240 index++;
241
242 if (!AtomUtils::read8(fp, buf[index]))
243 return false;
244
245 nextChar = (buf[index] == 0) ? false : true;
246 }
247 // String buffer filled - now create OSCL_wString
248
249 OSCL_TCHAR outbuf[MAX_BUFF_SIZE];
250 oscl_UTF8ToUnicode((const char *)buf, index, outbuf, MAX_BUFF_SIZE);
251 OSCL_wHeapString<OsclMemAllocator> temp(outbuf);
252
253 data = temp;
254 return true;
255 }
256
257 // Read in a NULL terminated UNICODE string byte by byte and take most significant byte first
258 // and convert to a OSCL_wString
259 OSCL_EXPORT_REF bool
readNullTerminatedUnicodeString(MP4_FF_FILE * fp,OSCL_wString & data)260 AtomUtils::readNullTerminatedUnicodeString(MP4_FF_FILE *fp, OSCL_wString& data)
261 {
262 const int MAX_BUFF_SIZE = 1024;
263 oscl_wchar buf[MAX_BUFF_SIZE];
264 int32 index = 0;
265
266 // Need to be careful of the byte-ordering when creating the oscl_wchar array
267 uint8 firstbyte;
268 uint8 secondbyte;
269
270 if (!AtomUtils::read8read8(fp, firstbyte, secondbyte))
271 return false;
272
273 // Allow the OS to do the bit shifting to get the correct byte ordering
274 // for the CHAR value
275 oscl_wchar *wptr = &buf[index];
276
277 *wptr = (uint16)(firstbyte << 8 | (uint16) secondbyte);
278
279 bool nextChar = (buf[index] == 0) ? false : true;
280 index += 1;
281
282 while (nextChar && (index < (int32)(MAX_BUFF_SIZE)))
283 {
284 if (!AtomUtils::read8read8(fp, firstbyte, secondbyte))
285 return false;
286
287 // Allow the OS to do the bit shifting to get the correct byte ordering
288 // for the CHAR value
289 wptr = &buf[index];
290 *wptr = (uint16)(firstbyte << 8 | (uint16) secondbyte);
291 nextChar = (buf[index] == 0) ? false : true;
292 index++;
293 }
294
295 // String (oscl_wchar) buffer filled - now create OSCL_STRING
296
297 // OSCL_STRING is a oscl_wchar string so no conversion needed
298 OSCL_wHeapString<OsclMemAllocator> temp((const OSCL_TCHAR *)buf, index - 1);
299 data = temp;
300
301 return true;
302 }
303
304 // Read in a NULL terminated ascii (8-bit char) string byte by byte and take most
305 // significant byte first and convert to a OSCL_wString
readNullTerminatedAsciiString(MP4_FF_FILE * fp,OSCL_wString & data)306 OSCL_EXPORT_REF bool AtomUtils::readNullTerminatedAsciiString(MP4_FF_FILE *fp, OSCL_wString& data)
307 {
308 return readNullTerminatedString(fp, data);
309 }
310
311 // Read in a first N Characters of string byte by byte
312 OSCL_EXPORT_REF bool
readByteData(MP4_FF_FILE * fp,uint32 length,uint8 * data)313 AtomUtils::readByteData(MP4_FF_FILE *fp, uint32 length, uint8 *data)
314 {
315 uint32 bytesRead = 0;
316
317 if (length > 0)
318 {
319 bytesRead = fp->_pvfile.Read(data, 1, length);
320 }
321 if (bytesRead < (uint32)length)
322 {
323 // read byte data failed
324 return false;
325 }
326 return true;
327 }
328
329 // Read in byte data and take most significant byte first
330 OSCL_EXPORT_REF bool
readUnicodeData(MP4_FF_FILE * fp,uint32 length,uint16 * data)331 AtomUtils::readUnicodeData(MP4_FF_FILE *fp, uint32 length, uint16 *data)
332 {
333 uint32 wordsRead;
334
335 if (length == 0)
336 return false;
337
338 wordsRead = (int32)(fp->_pvfile.Read((void*)data, 2, length));
339
340 // read byte data failed
341 if (wordsRead < (uint32)length)
342 {
343 return false;
344 }
345
346 return true;
347 }
348
349 OSCL_EXPORT_REF bool
readString(MP4_FF_FILE * fp,uint32 inLength,MP4FFParserOriginalCharEnc & CharType,OSCL_wString & data)350 AtomUtils::readString(MP4_FF_FILE *fp, uint32 inLength, MP4FFParserOriginalCharEnc &CharType, OSCL_wString& data)
351 {
352 uint32 temp = AtomUtils::peekNextNthBytes(fp, 1);
353 uint16 byteOrderMask = (uint16)((temp >> 16) & 0xFFFF);
354
355 if (byteOrderMask == BYTE_ORDER_MASK)
356 {
357 // UTF16
358 CharType = ORIGINAL_CHAR_TYPE_UTF16;
359 if (!AtomUtils::read16(fp, byteOrderMask))
360 {
361 return false;
362 }
363
364 if (inLength < BYTE_ORDER_MASK_SIZE)
365 {
366 return false;
367 }
368
369 uint32 delta = (inLength - BYTE_ORDER_MASK_SIZE);
370
371 int32 filePos = AtomUtils::getCurrentFilePosition(fp);
372
373 if (!AtomUtils::readUnicodeString(fp, delta, data))
374 {
375 return false;
376 }
377 int32 newfilePos = AtomUtils::getCurrentFilePosition(fp);
378 if (newfilePos != (int32)(filePos + delta))
379 {
380 AtomUtils::seekFromStart(fp, filePos + delta);
381 }
382 }
383 else
384 {
385 // UTF8 or Ascii
386 // Check to see if the string is actually null-terminated
387 CharType = ORIGINAL_CHAR_TYPE_UTF8;
388
389 uint32 delta = inLength;
390
391 int32 filePos = AtomUtils::getCurrentFilePosition(fp);
392
393 if (!AtomUtils::readUTF8String(fp, delta, data))
394 {
395 return false;
396 }
397 int32 newfilePos = AtomUtils::getCurrentFilePosition(fp);
398 if (newfilePos != (int32)(filePos + delta))
399 {
400 AtomUtils::seekFromStart(fp, filePos + delta);
401 }
402 }
403 return true;
404 }
405
406 OSCL_EXPORT_REF bool
readUTF8String(MP4_FF_FILE * fp,uint32 inLength,OSCL_wString & data)407 AtomUtils::readUTF8String(MP4_FF_FILE *fp, uint32 inLength, OSCL_wString& data)
408 {
409 const int MAX_BUFF_SIZE = 1024;
410 uint8 buf[MAX_BUFF_SIZE];
411
412 uint32 max_length = (uint32)MAX_BUFF_SIZE;
413 if (inLength > max_length)
414 {
415 inLength = max_length;
416 }
417
418 uint32 index = 0;
419 bool nextChar = true;
420
421 while (nextChar && (index < inLength))
422 {
423
424 if (!AtomUtils::read8(fp, buf[index]))
425 return false;
426
427 nextChar = (buf[index] == 0) ? false : true;
428
429 index++;
430
431 }
432 // String buffer filled - now create ZString
433
434 OSCL_TCHAR outbuf[MAX_BUFF_SIZE];
435 oscl_UTF8ToUnicode((const char *)buf, (int32)index, outbuf, MAX_BUFF_SIZE);
436 OSCL_wHeapString<OsclMemAllocator> temp(outbuf);
437
438 data = temp;
439 return true;
440 }
441
442 OSCL_EXPORT_REF bool
readAsciiString(MP4_FF_FILE * fp,uint32 inLength,OSCL_wString & data)443 AtomUtils::readAsciiString(MP4_FF_FILE *fp, uint32 inLength, OSCL_wString& data)
444 {
445 return (AtomUtils::readUTF8String(fp, inLength, data));
446 }
447
448 OSCL_EXPORT_REF bool
readUnicodeString(MP4_FF_FILE * fp,uint32 inLength,OSCL_wString & data)449 AtomUtils::readUnicodeString(MP4_FF_FILE *fp, uint32 inLength, OSCL_wString& data)
450 {
451 // make inLength an even.
452 inLength -= (inLength & 1);
453
454 if (inLength == 0)
455 {
456 data = NULL;
457 return true;
458 }
459
460 const int MAX_BUFF_SIZE = 1024;
461 oscl_wchar buf[MAX_BUFF_SIZE];
462 if (inLength > MAX_BUFF_SIZE * sizeof(oscl_wchar))
463 {
464 inLength = MAX_BUFF_SIZE;
465 }
466
467 uint32 wlength = inLength / 2;
468
469 uint32 index = 0;
470
471 // Need to be careful of the byte-ordering when creating the oscl_wchar array
472 uint8 firstbyte;
473 uint8 secondbyte;
474
475 oscl_wchar *wptr;
476
477 bool nextChar = true;
478
479 while (nextChar && (index < wlength))
480 {
481 if (!AtomUtils::read8read8(fp, firstbyte, secondbyte))
482 return false;
483
484 // Allow the OS to do the bit shifting to get the correct byte ordering
485 // for the CHAR value
486 wptr = &buf[index];
487 *wptr = (uint16)(firstbyte << 8 | (uint16) secondbyte);
488 nextChar = (buf[index] == 0) ? false : true;
489 index++;
490 }
491
492 // if it is a NULL terminated string, don't count the last NULL as length.
493 if (nextChar == false)
494 {
495 index --;
496 }
497
498 // OSCL_STRING is a oscl_wchar string so no conversion needed
499 OSCL_wHeapString<OsclMemAllocator> temp((const OSCL_TCHAR *)buf, index);
500 data = temp;
501
502 return true;
503 }
504
505 OSCL_EXPORT_REF uint32
getNumberOfBytesUsedToStoreSizeOfClass(uint32 contentSize)506 AtomUtils::getNumberOfBytesUsedToStoreSizeOfClass(uint32 contentSize)
507 {
508 // The actual _sizeOfClass value includes the size of the class's contents PLUS
509 // the number of bytes needed to store the _sizeOfClass field. The parameter
510 // contentSize represents the number of bytes needed to store ONLY the members
511 // of the class NOT including the _sizeOfClass field.
512 if (contentSize <= 0x7e) return 1; // _sizeOfClass field can be rendered in 1 byte (7 LS bits)
513 else if (contentSize <= 0x3ffd) return 2; // _sizeOfClass field can be rendered in 2 bytes (7 LS bits each)
514 else if (contentSize <= 0x1ffffc) return 3; // _sizeOfClass field can be rendered in 3 bytes (7 LS bits each)
515 else if (contentSize <= 0xfffffffb) return 4; // _sizeOfClass field can be rendered in 4 bytes (7 LS bits each)
516 else return 0; // ERROR condition
517 }
518
519
520 // Returns the atom type from parsing the input stream
521 OSCL_EXPORT_REF void
getNextAtomType(MP4_FF_FILE * fp,uint32 & size,uint32 & type)522 AtomUtils::getNextAtomType(MP4_FF_FILE *fp, uint32 &size, uint32 &type)
523 {
524 size = 0;
525 type = UNKNOWN_ATOM;
526
527 int32 filePointer;
528 filePointer = AtomUtils::getCurrentFilePosition(fp);
529
530 if (filePointer > (fp->_fileSize - 8))
531 {
532 return;
533 }
534
535 if (!AtomUtils::read32read32(fp, size, type))
536 {
537 size = 0;
538 type = UNKNOWN_ATOM;
539 return;
540 }
541
542 if (type == MOVIE_ATOM ||
543 type == MOVIE_HEADER_ATOM ||
544 type == TRACK_ATOM ||
545 type == TRACK_HEADER_ATOM ||
546 type == TRACK_REFERENCE_ATOM ||
547 type == MEDIA_ATOM ||
548 type == EDIT_ATOM ||
549 type == EDIT_LIST_ATOM ||
550 type == MEDIA_HEADER_ATOM ||
551 type == HANDLER_ATOM ||
552 type == MEDIA_INFORMATION_ATOM ||
553 type == VIDEO_MEDIA_HEADER_ATOM ||
554 type == SOUND_MEDIA_HEADER_ATOM ||
555 type == HINT_MEDIA_HEADER_ATOM ||
556 type == MPEG4_MEDIA_HEADER_ATOM ||
557 type == NULL_MEDIA_HEADER_ATOM ||
558 type == DATA_INFORMATION_ATOM ||
559 type == DATA_REFERENCE_ATOM ||
560 type == DATA_ENTRY_URL_ATOM ||
561 type == DATA_ENTRY_URN_ATOM ||
562 type == SAMPLE_TABLE_ATOM ||
563 type == TIME_TO_SAMPLE_ATOM ||
564 type == COMPOSITION_OFFSET_ATOM ||
565 type == SAMPLE_DESCRIPTION_ATOM ||
566 type == ESD_ATOM ||
567 type == SAMPLE_SIZE_ATOM ||
568 type == SAMPLE_TO_CHUNK_ATOM ||
569 type == CHUNK_OFFSET_ATOM ||
570 type == SYNC_SAMPLE_ATOM ||
571 type == SHADOW_SYNC_SAMPLE_ATOM ||
572 type == DEGRADATION_PRIORITY_ATOM ||
573 type == OBJECT_DESCRIPTOR_ATOM ||
574 type == MEDIA_DATA_ATOM ||
575 type == FREE_SPACE_ATOM ||
576 type == SKIP_ATOM ||
577 type == USER_DATA_ATOM ||
578 type == FILE_TYPE_ATOM ||
579 type == PVUSER_DATA_ATOM ||
580 type == PV_CONTENT_TYPE_ATOM ||
581 type == AMR_SAMPLE_ENTRY_ATOM ||
582 type == AMRWB_SAMPLE_ENTRY_ATOM ||
583 type == H263_SAMPLE_ENTRY_ATOM ||
584 type == AUDIO_SAMPLE_ENTRY ||
585 type == VIDEO_SAMPLE_ENTRY ||
586 type == MPEG_SAMPLE_ENTRY ||
587 type == UUID_ATOM ||
588 type == AMR_SPECIFIC_ATOM ||
589 type == H263_SPECIFIC_ATOM ||
590
591
592 type == COPYRIGHT_ATOM ||
593 type == FONT_TABLE_ATOM ||
594 type == HINT_TRACK_REFERENCE_TYPE ||
595 type == DPND_TRACK_REFERENCE_TYPE ||
596 type == IPIR_TRACK_REFERENCE_TYPE ||
597 type == MPOD_TRACK_REFERENCE_TYPE ||
598 type == SYNC_TRACK_REFERENCE_TYPE ||
599 type == ASSET_INFO_TITLE_ATOM ||
600 type == ASSET_INFO_DESCP_ATOM ||
601 type == ASSET_INFO_PERF_ATOM ||
602 type == ASSET_INFO_AUTHOR_ATOM ||
603 type == ASSET_INFO_GENRE_ATOM ||
604 type == ASSET_INFO_RATING_ATOM ||
605 type == ASSET_INFO_CLSF_ATOM ||
606 type == ASSET_INFO_KEYWORD_ATOM ||
607 type == ASSET_INFO_LOCATION_ATOM ||
608 type == ASSET_INFO_ALBUM_ATOM ||
609 type == ASSET_INFO_YRRC_ATOM ||
610 type == TEXT_SAMPLE_ENTRY ||
611 type == AVC_SAMPLE_ENTRY ||
612 type == AVC_CONFIGURATION_BOX ||
613 type == MPEG4_BITRATE_BOX ||
614 type == MPEG4_EXTENSION_DESCRIPTORS_BOX ||
615 type == ENCRYPTED_AUDIO_SAMPLE_ENTRY ||
616 type == ENCRYPTED_VIDEO_SAMPLE_ENTRY ||
617 type == PROTECTION_SCHEME_INFO_BOX ||
618 type == ORIGINAL_FORMAT_BOX ||
619 type == SCHEME_TYPE_BOX ||
620 type == SCHEME_INFORMATION_BOX ||
621 type == MUTABLE_DRM_INFORMATION ||
622 type == OMADRM_TRANSACTION_TRACKING_BOX ||
623 type == OMADRM_RIGHTS_OBJECT_BOX ||
624 type == OMADRM_KMS_BOX ||
625
626
627 type == MOVIE_EXTENDS_ATOM ||
628 type == MOVIE_EXTENDS_HEADER_ATOM ||
629 type == TRACK_EXTENDS_ATOM ||
630 type == MOVIE_FRAGMENT_ATOM ||
631 type == MOVIE_FRAGMENT_HEADER_ATOM ||
632 type == TRACK_FRAGMENT_ATOM ||
633 type == TRACK_FRAGMENT_HEADER_ATOM ||
634 type == TRACK_FRAGMENT_RUN_ATOM ||
635 type == MOVIE_FRAGMENT_RANDOM_ACCESS_ATOM ||
636 type == MOVIE_FRAGMENT_RANDOM_ACCESS_OFFSET_ATOM ||
637 type == TRACK_FRAGMENT_RANDOM_ACCESS_ATOM ||
638
639 type == META_DATA_ATOM ||
640 type == ITUNES_ILST_ATOM ||
641 type == ITUNES_ILST_DATA_ATOM ||
642 type == ITUNES_SONG_TITLE_ATOM ||
643 type == ITUNES_TRACK_SUBTITLE_ATOM ||
644 type == ITUNES_COMPILATION_ATOM ||
645 type == ITUNES_ENCODER_TOOL_ATOM ||
646 type == ITUNES_ENCODEDBY_ATOM ||
647 type == ITUNES_FREE_FORM_ATOM ||
648 type == ITUNES_ALBUM_ARTIST_ATOM ||
649 type == ITUNES_COMPOSER_ATOM ||
650 type == ITUNES_ALBUM_ATOM ||
651 type == ITUNES_GROUPING1_ATOM ||
652 type == ITUNES_GROUPING2_ATOM ||
653 type == ITUNES_GENRE1_ATOM ||
654 type == ITUNES_GENRE2_ATOM ||
655 type == ITUNES_TRACK_NUMBER_ATOM ||
656 type == ITUNES_DISK_NUMBER_ATOM ||
657 type == ITUNES_YEAR_ATOM ||
658 type == ITUNES_COMMENT_ATOM ||
659 type == ITUNES_LYRICS_ATOM ||
660 type == ITUNES_ART_WORK_ATOM ||
661 type == ITUNES_BPM_ATOM ||
662 type == ITUNES_MEAN_ATOM ||
663 type == ITUNES_FREE_FORM_DATA_NAME_ATOM ||
664 type == ITUNES_COPYRIGHT_ATOM ||
665 type == ITUNES_DESCRIPTION_ATOM ||
666 type == ITUNES_CONTENT_RATING_ATOM ||
667 type == ITUNES_ARTIST1_ATOM ||
668 type == ITUNES_ARTIST2_ATOM ||
669
670
671
672 type == PIXELASPECTRATIO_BOX)
673 {
674 return;
675 }
676 else
677 {
678 type = UNKNOWN_ATOM;
679 }
680 return;
681 }
682
683 OSCL_EXPORT_REF uint32
getMediaTypeFromHandlerType(uint32 handlerType)684 AtomUtils::getMediaTypeFromHandlerType(uint32 handlerType)
685 {
686 if (
687 handlerType == MEDIA_TYPE_AUDIO ||
688 handlerType == MEDIA_TYPE_VISUAL ||
689 handlerType == MEDIA_TYPE_HINT ||
690 handlerType == MEDIA_TYPE_OBJECT_DESCRIPTOR ||
691 handlerType == MEDIA_TYPE_CLOCK_REFERENCE ||
692 handlerType == MEDIA_TYPE_SCENE_DESCRIPTION ||
693 handlerType == MEDIA_TYPE_MPEG7 ||
694 handlerType == MEDIA_TYPE_OBJECT_CONTENT_INFO ||
695 handlerType == MEDIA_TYPE_IPMP ||
696 handlerType == MEDIA_TYPE_MPEG_J ||
697 handlerType == MEDIA_TYPE_TEXT
698 )
699 {
700 return handlerType;
701 }
702 else
703 {
704 return MEDIA_TYPE_UNKNOWN;
705 }
706 }
707
708 OSCL_EXPORT_REF uint32
getNumberOfBytesUsedToStoreContent(uint32 sizeOfClass)709 AtomUtils::getNumberOfBytesUsedToStoreContent(uint32 sizeOfClass)
710 {
711 // The content in a descriptor class is stored immediately after the descriptor tag
712 if (sizeOfClass <= 0x7f) return sizeOfClass - 2; // _sizeOfClass field is 1 byte (7 LS bits)
713 else if (sizeOfClass <= 0x3fff) return sizeOfClass - 3; // _sizeOfClass is 2 bytes (7 LS bits each)
714 else if (sizeOfClass <= 0x1fffff) return sizeOfClass - 4; // _sizeOfClass is 3 bytes (7 LS bits each)
715 else if (sizeOfClass <= 0x0fffffff) return sizeOfClass - 5; // _sizeOfClass is 4 bytes (7 LS bits each)
716 else return 0; // ERROR condition
717 }
718
getNextAtomSize(MP4_FF_FILE * fp)719 OSCL_EXPORT_REF int32 AtomUtils::getNextAtomSize(MP4_FF_FILE *fp)
720 {
721 uint32 size;
722 AtomUtils::read32(fp, size);
723
724 AtomUtils::rewindFilePointerByN(fp, 4);
725 return size;
726 }
727
728 // Peeks and returns the next Nth tag (32 bits) from the file
peekNextNthBytes(MP4_FF_FILE * fp,int32 n)729 OSCL_EXPORT_REF uint32 AtomUtils::peekNextNthBytes(MP4_FF_FILE *fp, int32 n)
730 {
731 uint32 tag = 0;
732 for (int32 i = 0; i < n; i++)
733 {
734 AtomUtils::read32(fp, tag);
735 }
736 AtomUtils::rewindFilePointerByN(fp, (4*n));
737 return tag;
738 }
739
740 // Peeks and returns the next Nth bytes (8 bits) from the file
peekNextByte(MP4_FF_FILE * fp)741 OSCL_EXPORT_REF uint8 AtomUtils::peekNextByte(MP4_FF_FILE *fp)
742 {
743 uint8 tag = 0;
744 AtomUtils::read8(fp, tag);
745 AtomUtils::rewindFilePointerByN(fp, 1);
746 return tag;
747 }
748
seekFromCurrPos(MP4_FF_FILE * fp,uint32 n)749 OSCL_EXPORT_REF void AtomUtils::seekFromCurrPos(MP4_FF_FILE *fp, uint32 n)
750 {
751 fp->_pvfile.Seek(n, Oscl_File::SEEKCUR);
752 }
753
seekFromStart(MP4_FF_FILE * fp,uint32 n)754 OSCL_EXPORT_REF void AtomUtils::seekFromStart(MP4_FF_FILE *fp, uint32 n)
755 {
756 fp->_pvfile.Seek(n, Oscl_File::SEEKSET);
757 }
758
seekToEnd(MP4_FF_FILE * fp)759 OSCL_EXPORT_REF void AtomUtils::seekToEnd(MP4_FF_FILE *fp)
760 {
761 fp->_pvfile.Seek(0, Oscl_File::SEEKEND);
762 }
763
rewindFilePointerByN(MP4_FF_FILE * fp,uint32 n)764 OSCL_EXPORT_REF void AtomUtils::rewindFilePointerByN(MP4_FF_FILE *fp, uint32 n)
765 {
766 fp->_pvfile.Seek((-1 *(int32) n), Oscl_File::SEEKCUR);
767 }
768
getCurrentFilePosition(MP4_FF_FILE * fp)769 OSCL_EXPORT_REF int32 AtomUtils::getCurrentFilePosition(MP4_FF_FILE *fp)
770 {
771 return (fp->_pvfile.Tell());
772 }
773
774
OpenMP4File(OSCL_wString & filename,uint32 mode,MP4_FF_FILE * fp)775 OSCL_EXPORT_REF int32 AtomUtils::OpenMP4File(OSCL_wString& filename,
776 uint32 mode,
777 MP4_FF_FILE *fp)
778 {
779 OSCL_UNUSED_ARG(mode);
780 if (fp != NULL)
781 {
782 return (fp->_pvfile.Open(filename.get_cstr(),
783 Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
784 *(fp->_fileServSession)));
785 }
786 return -1;
787 }
788
CloseMP4File(MP4_FF_FILE * fp)789 OSCL_EXPORT_REF int32 AtomUtils::CloseMP4File(MP4_FF_FILE *fp)
790 {
791 if (fp != NULL)
792 {
793 return (fp->_pvfile.Close());
794 }
795 return -1;
796 }
797
Flush(MP4_FF_FILE * fp)798 OSCL_EXPORT_REF int32 AtomUtils::Flush(MP4_FF_FILE *fp)
799 {
800 if (fp != NULL)
801 {
802 return (fp->_pvfile.Flush());
803 }
804 return -1;
805 }
806
getCurrentFileSize(MP4_FF_FILE * fp,uint32 & aCurrentSize)807 OSCL_EXPORT_REF bool AtomUtils::getCurrentFileSize(MP4_FF_FILE *fp, uint32& aCurrentSize)
808 {
809 if (fp != NULL)
810 {
811 aCurrentSize = 0;
812 uint32 aRemBytes = 0;
813 if (fp->_pvfile.GetRemainingBytes(aRemBytes))
814 {
815 uint32 currPos = (uint32)(fp->_pvfile.Tell());
816 aCurrentSize = currPos + aRemBytes;
817 fp->_fileSize = aCurrentSize;
818 return true;
819 }
820 }
821 return false;
822 }
823
824 OSCL_EXPORT_REF bool
read32(uint8 * & buf,uint32 & data)825 AtomUtils::read32(uint8 *&buf, uint32 &data)
826 {
827 const int32 N = 4;
828 data = 0;
829
830 for (int32 i = 0; i < N; i++)
831 data = (data << 8) | buf[i];
832
833 buf += N;
834 return true;
835 }
836
837 // Read in the 32 bits byte by byte and take most significant byte first.
838 // This is equivalent to two read32 calls.
839 OSCL_EXPORT_REF bool
read32read32(uint8 * & buf,uint32 & data1,uint32 & data2)840 AtomUtils::read32read32(uint8 *&buf, uint32 &data1, uint32 &data2)
841 {
842 const int32 N = 8;
843 data1 = 0;
844 data2 = 0;
845
846 int32 i;
847 for (i = 0; i < 4; i++)
848 data1 = (data1 << 8) | buf[i];
849
850 for (i = 4; i < 8; i++)
851 data2 = (data2 << 8) | buf[i];
852
853 buf += N;
854 return true;
855 }
856
857 // Read in the 16 bits byte by byte and take most significant byte first
858 OSCL_EXPORT_REF bool
read16(uint8 * & buf,uint16 & data)859 AtomUtils::read16(uint8 *&buf, uint16 &data)
860 {
861 const int32 N = 2;
862 data = 0;
863
864 for (int32 i = 0; i < N; i++)
865 data = (uint16)((data << 8) | (uint16) buf[i]);
866
867 buf += N;
868 return true;
869 }
870
871 // Read in the 8 bit byte
872 OSCL_EXPORT_REF bool
read8(uint8 * & buf,uint8 & data)873 AtomUtils::read8(uint8 *&buf, uint8 &data)
874 {
875 data = 0;
876 data = *buf;
877 buf++;
878 return true;
879 }
880
881 // Read in byte data and take most significant byte first
882 OSCL_EXPORT_REF bool
readByteData(uint8 * & buf,uint32 length,uint8 * data)883 AtomUtils::readByteData(uint8 *&buf, uint32 length, uint8 *data)
884 {
885 oscl_memcpy(data, buf, length);
886
887 buf += length;
888 return true;
889 }
890
891 OSCL_EXPORT_REF uint32
getNextAtomType(uint8 * buf)892 AtomUtils::getNextAtomType(uint8 *buf)
893 {
894 uint32 size;
895 uint32 type;
896 if (!AtomUtils::read32read32(buf, size, type))
897 {
898 return UNKNOWN_ATOM;
899 }
900
901 // Rewinding the stream back to atom start
902 buf -= 8;
903
904 if (type == MOVIE_ATOM ||
905 type == MOVIE_HEADER_ATOM ||
906 type == TRACK_ATOM ||
907 type == TRACK_HEADER_ATOM ||
908 type == TRACK_REFERENCE_ATOM ||
909 type == MEDIA_ATOM ||
910 type == EDIT_ATOM ||
911 type == EDIT_LIST_ATOM ||
912 type == MEDIA_HEADER_ATOM ||
913 type == HANDLER_ATOM ||
914 type == MEDIA_INFORMATION_ATOM ||
915 type == VIDEO_MEDIA_HEADER_ATOM ||
916 type == SOUND_MEDIA_HEADER_ATOM ||
917 type == HINT_MEDIA_HEADER_ATOM ||
918 type == MPEG4_MEDIA_HEADER_ATOM ||
919 type == NULL_MEDIA_HEADER_ATOM ||
920 type == DATA_INFORMATION_ATOM ||
921 type == DATA_REFERENCE_ATOM ||
922 type == DATA_ENTRY_URL_ATOM ||
923 type == DATA_ENTRY_URN_ATOM ||
924 type == SAMPLE_TABLE_ATOM ||
925 type == TIME_TO_SAMPLE_ATOM ||
926 type == COMPOSITION_OFFSET_ATOM ||
927 type == SAMPLE_DESCRIPTION_ATOM ||
928 type == ESD_ATOM ||
929 type == SAMPLE_SIZE_ATOM ||
930 type == SAMPLE_TO_CHUNK_ATOM ||
931 type == CHUNK_OFFSET_ATOM ||
932 type == SYNC_SAMPLE_ATOM ||
933 type == SHADOW_SYNC_SAMPLE_ATOM ||
934 type == DEGRADATION_PRIORITY_ATOM ||
935 type == OBJECT_DESCRIPTOR_ATOM ||
936 type == MEDIA_DATA_ATOM ||
937 type == FREE_SPACE_ATOM ||
938 type == SKIP_ATOM ||
939 type == USER_DATA_ATOM ||
940 type == FILE_TYPE_ATOM ||
941 type == PVUSER_DATA_ATOM ||
942 type == PVUSER_DATA_ATOM ||
943 type == AMR_SAMPLE_ENTRY_ATOM ||
944 type == AMRWB_SAMPLE_ENTRY_ATOM ||
945 type == H263_SAMPLE_ENTRY_ATOM ||
946 type == AUDIO_SAMPLE_ENTRY ||
947 type == VIDEO_SAMPLE_ENTRY ||
948 type == MPEG_SAMPLE_ENTRY ||
949 type == UUID_ATOM ||
950 type == AMR_SPECIFIC_ATOM ||
951 type == H263_SPECIFIC_ATOM ||
952 type == COPYRIGHT_ATOM ||
953 type == TEXT_SAMPLE_ENTRY ||
954 type == FONT_TABLE_ATOM ||
955 type == TEXT_STYLE_BOX ||
956 type == TEXT_HIGHLIGHT_BOX ||
957 type == TEXT_HILIGHT_COLOR_BOX ||
958 type == TEXT_KARAOKE_BOX ||
959 type == TEXT_SCROLL_DELAY_BOX ||
960 type == TEXT_HYPER_TEXT_BOX ||
961 type == TEXT_OVER_RIDE_BOX ||
962 type == TEXT_BLINK_BOX ||
963 type == HINT_TRACK_REFERENCE_TYPE ||
964 type == DPND_TRACK_REFERENCE_TYPE ||
965 type == IPIR_TRACK_REFERENCE_TYPE ||
966 type == MPOD_TRACK_REFERENCE_TYPE ||
967 type == SYNC_TRACK_REFERENCE_TYPE ||
968 type == ASSET_INFO_TITLE_ATOM ||
969 type == ASSET_INFO_DESCP_ATOM ||
970 type == ASSET_INFO_PERF_ATOM ||
971 type == ASSET_INFO_AUTHOR_ATOM ||
972 type == ASSET_INFO_GENRE_ATOM ||
973 type == ASSET_INFO_RATING_ATOM ||
974 type == ASSET_INFO_CLSF_ATOM ||
975 type == ASSET_INFO_KEYWORD_ATOM ||
976 type == ASSET_INFO_LOCATION_ATOM ||
977 type == ASSET_INFO_ALBUM_ATOM ||
978 type == ASSET_INFO_YRRC_ATOM)
979 {
980 return type;
981 }
982 else
983 {
984 return UNKNOWN_ATOM; // ERROR condition
985 }
986 }
987
getNextAtomSize(uint8 * buf)988 OSCL_EXPORT_REF int32 AtomUtils::getNextAtomSize(uint8 *buf)
989 {
990 uint32 size;
991 AtomUtils::read32(buf, size);
992
993 return size;
994 }
995
996
getContentLength(MP4_FF_FILE * fp)997 OSCL_EXPORT_REF uint32 AtomUtils::getContentLength(MP4_FF_FILE *fp)
998 {
999 // this returns the content length if known
1000 return fp->_pvfile.GetContentLength();
1001 }
1002
1003
getFileBufferingCapacity(MP4_FF_FILE * fp)1004 OSCL_EXPORT_REF uint32 AtomUtils::getFileBufferingCapacity(MP4_FF_FILE *fp)
1005 {
1006 // this returns the data stream cache size
1007 return fp->_pvfile.GetFileBufferingCapacity();
1008 }
1009
1010
skipFromStart(MP4_FF_FILE * fp,uint32 n)1011 OSCL_EXPORT_REF void AtomUtils::skipFromStart(MP4_FF_FILE *fp, uint32 n)
1012 {
1013 fp->_pvfile.Skip(n, Oscl_File::SEEKSET);
1014 }
1015
1016
getCurrentByteRange(MP4_FF_FILE * fp,uint32 & aCurrentFirstByteOffset,uint32 & aCurrentLastByteOffset)1017 OSCL_EXPORT_REF void AtomUtils::getCurrentByteRange(MP4_FF_FILE *fp, uint32& aCurrentFirstByteOffset, uint32& aCurrentLastByteOffset)
1018 {
1019 // this returns the byte range in the data stream cache
1020 // first and last offset inclusive
1021 fp->_pvfile.GetCurrentByteRange(aCurrentFirstByteOffset, aCurrentLastByteOffset);
1022 }
1023
1024
1025
1026