RDK Documentation (Open Sourced RDK Components)
isobmffbox.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2019 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 /**
21 * @file isobmffbox.cpp
22 * @brief Source file for ISO Base Media File Format Boxes
23 */
24 
25 #include "isobmffbox.h"
26 #include "AampConfig.h"
27 #include "AampUtils.h"
28 #include <stddef.h>
29 #include <inttypes.h>
30 
31 /**
32  * @brief Read a string from buffer and return it
33  */
34 uint32_t ReadCStringLen(const uint8_t* buffer, uint32_t bufferLen)
35 {
36  int retLen = -1;
37  if(buffer && bufferLen > 0)
38  {
39  for(int i=0; i < bufferLen; i++)
40  {
41  if(buffer[i] == '\0')
42  {
43  retLen = i+1;
44  break;
45  }
46  }
47  }
48  return retLen;
49 }
50 
51 /**
52  * @brief Utility function to read 8 bytes from a buffer
53  */
54 uint64_t ReadUint64(uint8_t *buf)
55 {
56  uint64_t val = READ_U32(buf);
57  val = (val<<32) | (uint32_t)READ_U32(buf);
58  return val;
59 }
60 
61 /**
62  * @brief Utility function to write 8 bytes to a buffer
63  */
64 void WriteUint64(uint8_t *dst, uint64_t val)
65 {
66  uint32_t msw = (uint32_t)(val>>32);
67  WRITE_U32(dst, msw); dst+=4;
68  WRITE_U32(dst, val);
69 }
70 
71 /**
72  * @brief Box constructor
73  */
74 Box::Box(uint32_t sz, const char btype[4]) : offset(0), size(sz), type{}
75 {
76  memcpy(type,btype,4);
77 }
78 
79 /**
80  * @brief Set box's offset from the beginning of the buffer
81  */
82 void Box::setOffset(uint32_t os)
83 {
84  offset = os;
85 }
86 
87 /**
88  * @brief Get box offset
89  */
90 uint32_t Box::getOffset() const
91 {
92  return offset;
93 }
94 
95 /**
96  * @brief To check if box has any child boxes
97  */
99 {
100  return false;
101 }
102 
103 /**
104  * @brief Get children of this box
105  */
106 const std::vector<Box*> *Box::getChildren()
107 {
108  return NULL;
109 }
110 
111 /**
112  * @brief Get box size
113  */
114 uint32_t Box::getSize() const
115 {
116  return size;
117 }
118 
119 /**
120  * @brief Get box type
121  */
122 const char *Box::getType()
123 {
124  return type;
125 }
126 
127 /**
128  * @brief Get box type
129  */
130 const char* Box::getBoxType() const
131 {
132  if ((!IS_TYPE(type, MOOV)) ||
133  (!IS_TYPE(type, MDIA)) ||
134  (!IS_TYPE(type, MOOF)) ||
135  (!IS_TYPE(type, TRAF)) ||
136  (!IS_TYPE(type, TFDT)) ||
137  (!IS_TYPE(type, MVHD)) ||
138  (!IS_TYPE(type, MDHD)) ||
139  (!IS_TYPE(type, TFDT)) ||
140  (!IS_TYPE(type, FTYP)) ||
141  (!IS_TYPE(type, STYP)) ||
142  (!IS_TYPE(type, SIDX)) ||
143  (!IS_TYPE(type, PRFT)) ||
144  (!IS_TYPE(type, MDAT)))
145  {
146  return "UKWN";
147  }
148  return type;
149 }
150 
151 /**
152  * @fn constructBox
153  * @brief Static function to construct a Box object
154  * @param[in] hdr - pointer to box
155  * @param[in] maxSz - box size
156  * @param[in] mLOgObj - log object
157  * @param[in] correctBoxSize - flag to check if box size needs to be corrected
158  * @param[in] newTrackId - new track id to overwrite the existing track id, when value is -1, it will not override
159  * @return newly constructed Box object
160  */
161 Box* Box::constructBox(uint8_t *hdr, uint32_t maxSz, AampLogManager *mLogObj, bool correctBoxSize, int newTrackId)
162 {
163  L_RESTART:
164  uint8_t *hdr_start = hdr;
165  uint32_t size = 0;
166  uint8_t type[5];
167  if(maxSz < 4)
168  {
169  AAMPLOG_TRACE("Box data < 4 bytes. Can't determine Size & Type");
170  return new Box(maxSz, (const char *)"UKWN");
171  }
172  else if(maxSz >= 4 && maxSz < 8)
173  {
174  AAMPLOG_TRACE("Box Size between >4 but <8 bytes. Can't determine Type");
175  //size = READ_U32(hdr);
176  return new Box(maxSz, (const char *)"UKWN");
177  }
178  else
179  {
180  size = READ_U32(hdr);
181  READ_U8(type, hdr, 4);
182  type[4] = '\0';
183  }
184 
185  if (size > maxSz)
186  {
187  if(correctBoxSize)
188  {
189  //Fix box size to handle cases like receiving whole file for HTTP range requests
190  AAMPLOG_WARN("Box[%s] fixing size error:size[%u] > maxSz[%u]", type, size, maxSz);
191  hdr = hdr_start;
192  WRITE_U32(hdr,maxSz);
193  goto L_RESTART;
194  }
195  else
196  {
197 #ifdef AAMP_DEBUG_BOX_CONSTRUCT
198  AAMPLOG_WARN("Box[%s] Size error:size[%u] > maxSz[%u]",type, size, maxSz);
199 #endif
200  }
201  }
202  else if (IS_TYPE(type, MOOV))
203  {
204  return GenericContainerBox::constructContainer(size, MOOV, hdr, newTrackId);
205  }
206  else if (IS_TYPE(type, TRAK))
207  {
208  return TrakBox::constructTrakBox(size,hdr, newTrackId);
209  }
210  else if (IS_TYPE(type, MDIA))
211  {
212  return GenericContainerBox::constructContainer(size, MDIA, hdr, newTrackId);
213  }
214  else if (IS_TYPE(type, MOOF))
215  {
216  return GenericContainerBox::constructContainer(size, MOOF, hdr, newTrackId);
217  }
218  else if (IS_TYPE(type, TRAF))
219  {
220  return GenericContainerBox::constructContainer(size, TRAF, hdr, newTrackId);
221  }
222  else if (IS_TYPE(type, TFHD))
223  {
224  return TfhdBox::constructTfhdBox(size, hdr);
225  }
226  else if (IS_TYPE(type, TFDT))
227  {
228  return TfdtBox::constructTfdtBox(size, hdr);
229  }
230  else if (IS_TYPE(type, TRUN))
231  {
232  return TrunBox::constructTrunBox(size, hdr);
233  }
234  else if (IS_TYPE(type, MVHD))
235  {
236  return MvhdBox::constructMvhdBox(size, hdr);
237  }
238  else if (IS_TYPE(type, MDHD))
239  {
240  return MdhdBox::constructMdhdBox(size, hdr);
241  }
242  else if (IS_TYPE(type, EMSG))
243  {
244  return EmsgBox::constructEmsgBox(size, hdr);
245  }
246  else if (IS_TYPE(type, PRFT))
247  {
248  return PrftBox::constructPrftBox(size, hdr);
249  }
250 
251  return new Box(size, (const char *)type);
252 }
253 
254 /**
255  * @brief GenericContainerBox constructor
256  */
257 GenericContainerBox::GenericContainerBox(uint32_t sz, const char btype[4]) : Box(sz, btype), children()
258 {
259 
260 }
261 
262 /**
263  * @brief GenericContainerBox destructor
264  */
266 {
267  for (unsigned int i = children.size(); i>0;)
268  {
269  --i;
270  SAFE_DELETE(children.at(i));
271  children.pop_back();
272  }
273  children.clear();
274 }
275 
276 /**
277  * @brief Add a box as a child box
278  */
280 {
281  children.push_back(box);
282 }
283 
284 /**
285  * @brief To check if box has any child boxes
286  */
288 {
289  return true;
290 }
291 
292 /**
293  * @brief Get children of this box
294  */
295 const std::vector<Box*> *GenericContainerBox::getChildren()
296 {
297  return &children;
298 }
299 
300 
301 /**
302  * @fn constructContainer
303  * @brief Static function to construct a GenericContainerBox object
304  * @param[in] sz - box size
305  * @param[in] btype - box type
306  * @param[in] ptr - pointer to box
307  * @param[in] newTrackId - new track id to overwrite the existing track id, when value is -1, it will not override
308  * @return newly constructed GenericContainerBox object
309  */
310 GenericContainerBox* GenericContainerBox::constructContainer(uint32_t sz, const char btype[4], uint8_t *ptr, int newTrackId)
311 {
312  GenericContainerBox *cbox = new GenericContainerBox(sz, btype);
313  uint32_t curOffset = sizeof(uint32_t) + sizeof(uint32_t); //Sizes of size & type fields
314  while (curOffset < sz)
315  {
316  Box *box = Box::constructBox(ptr, sz-curOffset, nullptr, false, newTrackId );
317  box->setOffset(curOffset);
318  cbox->addChildren(box);
319  curOffset += box->getSize();
320  ptr += box->getSize();
321  }
322  return cbox;
323 }
324 
325 /**
326  * @brief FullBox constructor
327  */
328 FullBox::FullBox(uint32_t sz, const char btype[4], uint8_t ver, uint32_t f) : Box(sz, btype), version(ver), flags(f)
329 {
330 
331 }
332 
333 /**
334  * @brief MvhdBox constructor
335  */
336 MvhdBox::MvhdBox(uint32_t sz, uint32_t tScale) : FullBox(sz, Box::MVHD, 0, 0), timeScale(tScale)
337 {
338 
339 }
340 
341 /**
342  * @brief MvhdBox constructor
343  */
344 MvhdBox::MvhdBox(FullBox &fbox, uint32_t tScale) : FullBox(fbox), timeScale(tScale)
345 {
346 
347 }
348 
349 /**
350  * @brief Set TimeScale value
351  */
352 void MvhdBox::setTimeScale(uint32_t tScale)
353 {
354  timeScale = tScale;
355 }
356 
357 /**
358  * @brief Get TimeScale value
359  */
361 {
362  return timeScale;
363 }
364 
365 /**
366  * @brief Static function to construct a MvhdBox object
367  */
368 MvhdBox* MvhdBox::constructMvhdBox(uint32_t sz, uint8_t *ptr)
369 {
370  uint8_t version = READ_VERSION(ptr);
371  uint32_t flags = READ_FLAGS(ptr);
372  uint64_t tScale;
373 
374  uint32_t skip = sizeof(uint32_t)*2;
375  if (1 == version)
376  {
377  //Skipping creation_time &modification_time
378  skip = sizeof(uint64_t)*2;
379  }
380  ptr += skip;
381 
382  tScale = READ_U32(ptr);
383 
384  FullBox fbox(sz, Box::MVHD, version, flags);
385  return new MvhdBox(fbox, tScale);
386 }
387 
388 /**
389  * @brief MdhdBox constructor
390  */
391 MdhdBox::MdhdBox(uint32_t sz, uint32_t tScale) : FullBox(sz, Box::MDHD, 0, 0), timeScale(tScale)
392 {
393 
394 }
395 
396 /**
397  * @brief MdhdBox constructor
398  */
399 MdhdBox::MdhdBox(FullBox &fbox, uint32_t tScale) : FullBox(fbox), timeScale(tScale)
400 {
401 
402 }
403 
404 /**
405  * @brief Set TimeScale value
406  */
407 void MdhdBox::setTimeScale(uint32_t tScale)
408 {
409  timeScale = tScale;
410 }
411 
412 /**
413  * @brief Get TimeScale value
414  */
416 {
417  return timeScale;
418 }
419 
420 /**
421  * @brief Static function to construct a MdhdBox object
422  */
423 MdhdBox* MdhdBox::constructMdhdBox(uint32_t sz, uint8_t *ptr)
424 {
425  uint8_t version = READ_VERSION(ptr);
426  uint32_t flags = READ_FLAGS(ptr);
427  uint32_t tScale;
428 
429  uint32_t skip = sizeof(uint32_t)*2;
430  if (1 == version)
431  {
432  //Skipping creation_time &modification_time
433  skip = sizeof(uint64_t)*2;
434  }
435  ptr += skip;
436 
437  tScale = READ_U32(ptr);
438 
439  FullBox fbox(sz, Box::MDHD, version, flags);
440  return new MdhdBox(fbox, tScale);
441 }
442 
443 /**
444  * @brief TfdtBox constructor
445  */
446 TfdtBox::TfdtBox(uint32_t sz, uint64_t mdt) : FullBox(sz, Box::TFDT, 0, 0), baseMDT(mdt)
447 {
448 
449 }
450 
451 /**
452  * @brief TfdtBox constructor
453  */
454 TfdtBox::TfdtBox(FullBox &fbox, uint64_t mdt) : FullBox(fbox), baseMDT(mdt)
455 {
456 
457 }
458 
459 /**
460  * @brief Set BaseMediaDecodeTime value
461  */
462 void TfdtBox::setBaseMDT(uint64_t mdt)
463 {
464  baseMDT = mdt;
465 }
466 
467 /**
468  * @brief Get BaseMediaDecodeTime value
469  */
471 {
472  return baseMDT;
473 }
474 
475 /**
476  * @brief Static function to construct a TfdtBox object
477  */
478 TfdtBox* TfdtBox::constructTfdtBox(uint32_t sz, uint8_t *ptr)
479 {
480  uint8_t version = READ_VERSION(ptr);
481  uint32_t flags = READ_FLAGS(ptr);
482  uint64_t mdt;
483 
484  if (1 == version)
485  {
486  mdt = READ_BMDT64(ptr);
487  }
488  else
489  {
490  mdt = (uint32_t)READ_U32(ptr);
491  }
492  FullBox fbox(sz, Box::TFDT, version, flags);
493  return new TfdtBox(fbox, mdt);
494 }
495 
496 /**
497  * @brief EmsgBox constructor
498  */
499 EmsgBox::EmsgBox(uint32_t sz, uint32_t tScale, uint32_t evtDur, uint32_t _id) : FullBox(sz, Box::EMSG, 0, 0)
500  , timeScale(tScale), eventDuration(evtDur), id(_id)
501  , presentationTimeDelta(0), presentationTime(0)
502  , schemeIdUri(nullptr), value(nullptr), messageData(nullptr), messageLen(0)
503 {
504 
505 }
506 
507 /**
508  * @brief EmsgBox constructor
509  */
510 EmsgBox::EmsgBox(FullBox &fbox, uint32_t tScale, uint32_t evtDur, uint32_t _id, uint64_t presTime, uint32_t presTimeDelta) : FullBox(fbox)
511  , timeScale(tScale), eventDuration(evtDur), id(_id)
512  , presentationTimeDelta(presTimeDelta), presentationTime(presTime)
513  , schemeIdUri(nullptr), value(nullptr), messageData(nullptr), messageLen(0)
514 {
515 
516 }
517 
518 /**
519  * @brief EmsgBox dtor
520  */
522 {
523  if (messageData)
524  {
525  free(messageData);
526  }
527 
528  if (schemeIdUri)
529  {
530  free(schemeIdUri);
531  }
532 
533  if (value)
534  {
535  free(value);
536  }
537 }
538 
539 /**
540  * @brief Set TimeScale value
541  */
542 void EmsgBox::setTimeScale(uint32_t tScale)
543 {
544  timeScale = tScale;
545 }
546 
547 /**
548  * @brief Get schemeIdUri
549  */
551 {
552  return timeScale;
553 }
554 
555 /**
556  * @brief Set eventDuration value
557  */
558 void EmsgBox::setEventDuration(uint32_t evtDur)
559 {
560  eventDuration = evtDur;
561 }
562 
563 /**
564  * @brief Get eventDuration
565  */
567 {
568  return eventDuration;
569 }
570 
571 /**
572  * @brief Set id
573  */
574 void EmsgBox::setId(uint32_t _id)
575 {
576  id = _id;
577 }
578 
579 /**
580  * @brief Get id
581  */
582 uint32_t EmsgBox::getId()
583 {
584  return id;
585 }
586 
587 /**
588  * @brief Set presentationTimeDelta
589  */
590 void EmsgBox::setPresentationTimeDelta(uint32_t presTimeDelta)
591 {
592  presentationTimeDelta = presTimeDelta;
593 }
594 
595 /**
596  * @brief Get presentationTimeDelta
597  */
599 {
600  return presentationTimeDelta;
601 }
602 
603 /**
604  * @brief Set presentationTime
605  */
606 void EmsgBox::setPresentationTime(uint64_t presTime)
607 {
608  presentationTime = presTime;
609 }
610 
611 /**
612  * @brief Get presentationTime
613  */
615 {
616  return presentationTime;
617 }
618 
619 /**
620  * @brief Set schemeIdUri
621  */
622 void EmsgBox::setSchemeIdUri(uint8_t* schemeIdURI)
623 {
624  schemeIdUri = schemeIdURI;
625 }
626 
627 /**
628  * @brief Get schemeIdUri
629  */
631 {
632  return schemeIdUri;
633 }
634 
635 /**
636  * @brief Set value
637  */
638 void EmsgBox::setValue(uint8_t* schemeIdValue)
639 {
640  value = schemeIdValue;
641 }
642 
643 /**
644  * @brief Get value
645  */
647 {
648  return value;
649 }
650 
651 /**
652  * @brief Set Message
653  */
654 void EmsgBox::setMessage(uint8_t* message, uint32_t len)
655 {
656  messageData = message;
657  messageLen = len;
658 }
659 
660 /**
661  * @brief Get Message
662  */
664 {
665  return messageData;
666 }
667 
668 /**
669  * @brief Get Message length
670  */
672 {
673  return messageLen;
674 }
675 
676 /**
677  * @brief Static function to construct a EmsgBox object
678  */
679 EmsgBox* EmsgBox::constructEmsgBox(uint32_t sz, uint8_t *ptr)
680 {
681  uint8_t version = READ_VERSION(ptr);
682  uint32_t flags = READ_FLAGS(ptr);
683  // Calculationg remaining size,
684  // flags(3bytes)+ version(1byte)+ box_header(type and size)(8bytes)
685  uint32_t remainingSize = sz - ((sizeof(uint32_t))+(sizeof(uint64_t)));
686 
687  uint64_t presTime = 0;
688  uint32_t presTimeDelta = 0;
689  uint32_t tScale;
690  uint32_t evtDur;
691  uint32_t boxId;
692 
693  uint8_t* schemeId = nullptr;
694  uint8_t* schemeIdValue = nullptr;
695 
696  uint8_t* message = nullptr;
697  FullBox fbox(sz, Box::EMSG, version, flags);
698 
699  /*
700  * Extraction is done as per https://aomediacodec.github.io/id3-emsg/
701  */
702  if (1 == version)
703  {
704  tScale = READ_U32(ptr);
705  // Read 64 bit value
706  presTime = READ_64(ptr);
707  evtDur = READ_U32(ptr);
708  boxId = READ_U32(ptr);
709  remainingSize -= ((sizeof(uint32_t)*3) + sizeof(uint64_t));
710  uint32_t schemeIdLen = ReadCStringLen(ptr, remainingSize);
711  if(schemeIdLen > 0)
712  {
713  schemeId = (uint8_t*) malloc(sizeof(uint8_t)*schemeIdLen);
714  READ_U8(schemeId, ptr, schemeIdLen);
715  remainingSize -= (sizeof(uint8_t) * schemeIdLen);
716  uint32_t schemeIdValueLen = ReadCStringLen(ptr, remainingSize);
717  if (schemeIdValueLen > 0)
718  {
719  schemeIdValue = (uint8_t*) malloc(sizeof(uint8_t)*schemeIdValueLen);
720  READ_U8(schemeIdValue, ptr, schemeIdValueLen);
721  remainingSize -= (sizeof(uint8_t) * schemeIdValueLen);
722  }
723  }
724  }
725  else if(0 == version)
726  {
727  uint32_t schemeIdLen = ReadCStringLen(ptr, remainingSize);
728  if(schemeIdLen)
729  {
730  schemeId = (uint8_t*) malloc(sizeof(uint8_t)*schemeIdLen);
731  READ_U8(schemeId, ptr, schemeIdLen);
732  remainingSize -= (sizeof(uint8_t) * schemeIdLen);
733  uint32_t schemeIdValueLen = ReadCStringLen(ptr, remainingSize);
734  if (schemeIdValueLen)
735  {
736  schemeIdValue = (uint8_t*) malloc(sizeof(uint8_t)*schemeIdValueLen);
737  READ_U8(schemeIdValue, ptr, schemeIdValueLen);
738  remainingSize -= (sizeof(uint8_t) * schemeIdValueLen);
739  }
740  }
741  tScale = READ_U32(ptr);
742  presTimeDelta = READ_U32(ptr);
743  evtDur = READ_U32(ptr);
744  boxId = READ_U32(ptr);
745  remainingSize -= (sizeof(uint32_t)*4);
746  }
747  else
748  {
749  AAMPLOG_WARN("Unsupported emsg box version");
750  return new EmsgBox(fbox, 0, 0, 0, 0, 0);
751  }
752 
753  EmsgBox* retBox = new EmsgBox(fbox, tScale, evtDur, boxId, presTime, presTimeDelta);
754  if(retBox)
755  {
756  // Extract remaining message
757  if(remainingSize > 0)
758  {
759  message = (uint8_t*) malloc(sizeof(uint8_t)*remainingSize);
760  READ_U8(message, ptr, remainingSize);
761  if(message)
762  {
763  retBox->setMessage(message, remainingSize);
764  }
765  }
766 
767  // Save schemeIdUri and value if present
768  if (schemeId)
769  {
770  retBox->setSchemeIdUri(schemeId);
771  if(schemeIdValue)
772  {
773  retBox->setValue(schemeIdValue);
774  }
775  }
776  else
777  {
778  if(schemeIdValue)
779  {
780  free(schemeIdValue);
781  }
782  }
783  }
784  else
785  {
786  if (schemeId)
787  {
788  free(schemeId);
789  }
790  if(schemeIdValue)
791  {
792  free(schemeIdValue);
793  }
794  }
795  return retBox;
796 }
797 
798 /**
799  * @brief TrunBox constructor
800  */
801 TrunBox::TrunBox(uint32_t sz, uint64_t sampleDuration) : FullBox(sz, Box::TRUN, 0, 0), duration(sampleDuration)
802 {
803 }
804 
805 /**
806  * @brief TrunBox constructor
807  */
808 TrunBox::TrunBox(FullBox &fbox, uint64_t sampleDuration) : FullBox(fbox), duration(sampleDuration)
809 {
810 }
811 
812 /**
813  * @brief Set SampleDuration value
814  */
815 void TrunBox::setSampleDuration(uint64_t sampleDuration)
816 {
817  duration = sampleDuration;
818 }
819 
820 /**
821  * @brief Get sampleDuration value
822  */
824 {
825  return duration;
826 }
827 
828 /**
829  * @brief Static function to construct a TrunBox object
830  */
831 TrunBox* TrunBox::constructTrunBox(uint32_t sz, uint8_t *ptr)
832 {
833  const uint32_t TRUN_FLAG_DATA_OFFSET_PRESENT = 0x0001;
834  const uint32_t TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT = 0x0004;
835  const uint32_t TRUN_FLAG_SAMPLE_DURATION_PRESENT = 0x0100;
836  const uint32_t TRUN_FLAG_SAMPLE_SIZE_PRESENT = 0x0200;
837  const uint32_t TRUN_FLAG_SAMPLE_FLAGS_PRESENT = 0x0400;
838  const uint32_t TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT = 0x0800;
839 
840  uint8_t version = READ_VERSION(ptr);
841  uint32_t flags = READ_FLAGS(ptr);
842  uint64_t sampleDuration = 0;//1001000; //fix-Me
843  uint32_t sample_count = 0;
844  uint32_t sample_duration = 0;
845  uint32_t sample_size = 0;
846  uint32_t sample_flags = 0;
847  uint32_t sample_composition_time_offset = 0;
848  uint32_t discard;
849  uint32_t totalSampleDuration = 0;
850 
851  uint32_t record_fields_count = 0;
852 
853  // count the number of bits set to 1 in the second byte of the flags
854  for (unsigned int i=0; i<8; i++)
855  {
856  if (flags & (1<<(i+8))) ++record_fields_count;
857  }
858 
859  sample_count = READ_U32(ptr);
860 
861  discard = READ_U32(ptr);
862 
863  for (unsigned int i=0; i<sample_count; i++)
864  {
865  if (flags & TRUN_FLAG_SAMPLE_DURATION_PRESENT)
866  {
867  sample_duration = READ_U32(ptr);
868  totalSampleDuration += sample_duration;
869  }
870  if (flags & TRUN_FLAG_SAMPLE_SIZE_PRESENT)
871  {
872  sample_size = READ_U32(ptr);
873  }
874  if (flags & TRUN_FLAG_SAMPLE_FLAGS_PRESENT)
875  {
876  sample_flags = READ_U32(ptr);
877  }
878  if (flags & TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT)
879  {
880  sample_composition_time_offset = READ_U32(ptr);
881  }
882  }
883  FullBox fbox(sz, Box::TRUN, version, flags);
884  return new TrunBox(fbox, totalSampleDuration);
885 }
886 
887 /**
888  * @brief TfhdBox constructor
889  */
890 TfhdBox::TfhdBox(uint32_t sz, uint64_t default_duration) : FullBox(sz, Box::TFHD, 0, 0), duration(default_duration)
891 {
892 
893 }
894 
895 /**
896  * @brief TfhdBox constructor
897  */
898 TfhdBox::TfhdBox(FullBox &fbox, uint64_t default_duration) : FullBox(fbox), duration(default_duration)
899 {
900 
901 }
902 
903 /**
904  * @brief Set Sample Duration value
905  */
906 void TfhdBox::setSampleDuration(uint64_t default_duration)
907 {
908  duration = default_duration;
909 }
910 
911 /**
912  * @brief Get SampleDuration value
913  */
915 {
916  return duration;
917 }
918 
919 /**
920  * @brief Static function to construct a TfdtBox object
921  */
922 TfhdBox* TfhdBox::constructTfhdBox(uint32_t sz, uint8_t *ptr)
923 {
924  uint8_t version = READ_VERSION(ptr); //8
925  uint32_t flags = READ_FLAGS(ptr); //24
926 
927  const uint32_t TFHD_FLAG_BASE_DATA_OFFSET_PRESENT = 0x00001;
928  const uint32_t TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX_PRESENT = 0x00002;
929  const uint32_t TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT = 0x00008;
930  const uint32_t TFHD_FLAG_DEFAULT_SAMPLE_SIZE_PRESENT = 0x00010;
931  const uint32_t TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT = 0x00020;
932  const uint32_t TFHD_FLAG_DURATION_IS_EMPTY = 0x10000;
933  const uint32_t TFHD_FLAG_DEFAULT_BASE_IS_MOOF = 0x20000;
934 
935  uint32_t TrackId;
936  uint32_t BaseDataOffset;
937  uint32_t SampleDescriptionIndex;
938  uint32_t DefaultSampleDuration;
939  uint32_t DefaultSampleSize;
940  uint32_t DefaultSampleFlags;
941 
942  TrackId = READ_U32(ptr);
943  if (flags & TFHD_FLAG_BASE_DATA_OFFSET_PRESENT) {
944  BaseDataOffset = READ_64(ptr);
945  } else {
946  BaseDataOffset = 0;
947  }
948  if (flags & TFHD_FLAG_SAMPLE_DESCRIPTION_INDEX_PRESENT) {
949  SampleDescriptionIndex = READ_U32(ptr);
950  } else {
951  SampleDescriptionIndex = 1;
952  }
953  if (flags & TFHD_FLAG_DEFAULT_SAMPLE_DURATION_PRESENT) {
954  DefaultSampleDuration = READ_U32(ptr);
955  } else {
956  DefaultSampleDuration = 0;
957  }
958  if (flags & TFHD_FLAG_DEFAULT_SAMPLE_SIZE_PRESENT) {
959  DefaultSampleSize = READ_U32(ptr);
960  } else {
961  DefaultSampleSize = 0;
962  }
963  if (flags & TFHD_FLAG_DEFAULT_SAMPLE_FLAGS_PRESENT) {
964  DefaultSampleFlags = READ_U32(ptr);
965  } else {
966  DefaultSampleFlags = 0;
967  }
968 
969 // logprintf("TFHD constructTfhdBox TrackId: %d",TrackId );
970 // logprintf("TFHD constructTfhdBox BaseDataOffset: %d",BaseDataOffset );
971 // logprintf("TFHD constructTfhdBox SampleDescriptionIndex: %d",SampleDescriptionIndex);
972 // logprintf("TFHD constructTfhdBox DefaultSampleDuration: %d",DefaultSampleDuration );
973 // logprintf("TFHD constructTfhdBox DefaultSampleSize: %d",DefaultSampleSize );
974 // logprintf("TFHD constructTfhdBox DefaultSampleFlags: %d",DefaultSampleFlags );
975 
976  FullBox fbox(sz, Box::TFHD, version, flags);
977  return new TfhdBox(fbox, DefaultSampleDuration);
978 }
979 
980 /**
981  * @brief PrftBox constructor
982  */
983 PrftBox::PrftBox(uint32_t sz, uint32_t trackId, uint64_t ntpTs, uint64_t mediaTime) : FullBox(sz, Box::PRFT, 0, 0), track_id(trackId), ntp_ts(ntpTs), media_time(mediaTime)
984 {
985 
986 }
987 
988 /**
989  * @brief PrftBox constructor
990  */
991 PrftBox::PrftBox(FullBox &fbox, uint32_t trackId, uint64_t ntpTs, uint64_t mediaTime) : FullBox(fbox), track_id(trackId), ntp_ts(ntpTs), media_time(mediaTime)
992 {
993 
994 }
995 
996 /**
997  * @brief Set Track Id value
998  */
999 void PrftBox::setTrackId(uint32_t trackId)
1000 {
1001  track_id = trackId;
1002 }
1003 
1004 /**
1005  * @brief Get Track id value
1006  */
1008 {
1009  return track_id;
1010 }
1011 
1012 /**
1013  * @brief Set NTP Ts value
1014  */
1015 void PrftBox::setNtpTs(uint64_t ntpTs)
1016 {
1017  ntp_ts = ntpTs;
1018 }
1019 
1020 /**
1021  * @brief Get ntp Timestamp value
1022  */
1024 {
1025  return ntp_ts;
1026 }
1027 
1028 /**
1029  * @brief Set Sample Duration value
1030  */
1031 void PrftBox::setMediaTime(uint64_t mediaTime)
1032 {
1033  media_time = mediaTime;
1034 }
1035 
1036 /**
1037  * @brief Get SampleDuration value
1038  */
1040 {
1041  return media_time;
1042 }
1043 
1044 /**
1045  * @brief Static function to construct a PrftBox object
1046  */
1047 PrftBox* PrftBox::constructPrftBox(uint32_t sz, uint8_t *ptr)
1048 {
1049  uint8_t version = READ_VERSION(ptr); //8
1050  uint32_t flags = READ_FLAGS(ptr); //24
1051 
1052  uint32_t track_id = 0; // reference track ID
1053  track_id = READ_U32(ptr);
1054  uint64_t ntp_ts = 0; // NTP time stamp
1055  ntp_ts = READ_64(ptr);
1056  uint64_t pts = 0; //media time
1057  pts = READ_64(ptr);
1058 // logprintf("PRFT constructPrftBox TrackId: %d",track_id );
1059 // logprintf("PRFT constructPrftBox Ntp TS: %llu",ntp_ts );
1060 // logprintf("PRFT constructPrftBox Media Time: %ld",pts);
1061  FullBox fbox(sz, Box::PRFT, version, flags);
1062 
1063  return new PrftBox(fbox, track_id, ntp_ts, pts);
1064 }
1065 
1066 /**
1067  * @fn constructTrakBox
1068  * @param[in] sz - box size
1069  * @param[in] ptr - pointer to box
1070  * @param[in] newTrackId - new track id to overwrite the existing track id, when value is -1, it will not override
1071  * @return newly constructed trak object
1072  */
1073 TrakBox* TrakBox::constructTrakBox(uint32_t sz, uint8_t *ptr, int newTrackId)
1074 {
1075  TrakBox *cbox = new TrakBox(sz);
1076  uint32_t curOffset = sizeof(uint32_t) + sizeof(uint32_t); //Sizes of size & type fields
1077  while (curOffset < sz)
1078  {
1079  Box *box = Box::constructBox(ptr, sz-curOffset);
1080  box->setOffset(curOffset);
1081 
1082  if (IS_TYPE(box->getType(),TKHD))
1083  {
1084  uint8_t *tkhd_start = ptr;
1085  ptr += curOffset;
1086  uint8_t version = READ_VERSION(ptr);
1087  uint32_t skip = 3; // size of flags
1088  if (1 == version)
1089  {
1090  skip += sizeof(uint64_t) * 2; //CreationTime + ModificationTime
1091  }
1092  else
1093  {
1094  skip += sizeof(uint32_t) * 2; //CreationTime + ModificationTime
1095  }
1096  ptr += skip;
1097  if(-1 != newTrackId)
1098  {
1099  WRITE_U32(ptr, newTrackId);
1100  }
1101  cbox->track_id = READ_U32(ptr);
1102  ptr = tkhd_start;
1103  }
1104  cbox->addChildren(box);
1105  curOffset += box->getSize();
1106  ptr += box->getSize();
1107  }
1108  return cbox;
1109 }
MvhdBox::setTimeScale
void setTimeScale(uint32_t tScale)
Set TimeScale value.
Definition: isobmffbox.cpp:352
GenericContainerBox::addChildren
void addChildren(Box *box)
Add a box as a child box.
Definition: isobmffbox.cpp:279
TfdtBox::setBaseMDT
void setBaseMDT(uint64_t mdt)
Set BaseMediaDecodeTime value.
Definition: isobmffbox.cpp:462
TfdtBox::getBaseMDT
uint64_t getBaseMDT()
Get BaseMediaDecodeTime value.
Definition: isobmffbox.cpp:470
EmsgBox::setId
void setId(uint32_t _id)
Set id.
Definition: isobmffbox.cpp:574
GenericContainerBox::constructContainer
static GenericContainerBox * constructContainer(uint32_t sz, const char btype[4], uint8_t *ptr, int newTrackId=-1)
Definition: isobmffbox.cpp:310
PrftBox::setNtpTs
void setNtpTs(uint64_t ntpTs)
Set NTP Ts value.
Definition: isobmffbox.cpp:1015
EmsgBox::getSchemeIdUri
uint8_t * getSchemeIdUri()
Get schemeIdUri.
Definition: isobmffbox.cpp:630
EmsgBox::getPresentationTimeDelta
uint32_t getPresentationTimeDelta()
Get presentationTimeDelta.
Definition: isobmffbox.cpp:598
MdhdBox::constructMdhdBox
static MdhdBox * constructMdhdBox(uint32_t sz, uint8_t *ptr)
Static function to construct a MdhdBox object.
Definition: isobmffbox.cpp:423
EmsgBox
Class for ISO BMFF EMSG Box.
Definition: isobmffbox.h:472
Box::Box
Box(uint32_t sz, const char btype[4])
Box constructor.
Definition: isobmffbox.cpp:74
TrunBox::TrunBox
TrunBox(uint32_t sz, uint64_t sampleDuration)
TrunBox constructor.
Definition: isobmffbox.cpp:801
ReadUint64
uint64_t ReadUint64(uint8_t *buf)
Utility function to read 8 bytes from a buffer.
Definition: isobmffbox.cpp:54
MdhdBox
Class for ISO BMFF MDHD Box.
Definition: isobmffbox.h:369
FullBox::FullBox
FullBox(uint32_t sz, const char btype[4], uint8_t ver, uint32_t f)
FullBox constructor.
Definition: isobmffbox.cpp:328
PrftBox::PrftBox
PrftBox(uint32_t sz, uint32_t trackId, uint64_t ntpTs, uint64_t mediaTime)
PrftBox constructor.
Definition: isobmffbox.cpp:983
Box::getBoxType
const char * getBoxType() const
Get box type.
Definition: isobmffbox.cpp:130
TrakBox::constructTrakBox
static TrakBox * constructTrakBox(uint32_t sz, uint8_t *ptr, int newTrackId=-1)
Definition: isobmffbox.cpp:1073
Box::type
char type[5]
Definition: isobmffbox.h:95
EmsgBox::~EmsgBox
~EmsgBox()
EmsgBox dtor.
Definition: isobmffbox.cpp:521
Box::offset
uint32_t offset
Definition: isobmffbox.h:93
Box::size
uint32_t size
Definition: isobmffbox.h:94
EmsgBox::EmsgBox
EmsgBox(uint32_t sz, uint32_t tScale, uint32_t evtDur, uint32_t _id)
EmsgBox constructor.
Definition: isobmffbox.cpp:499
Box::constructBox
static Box * constructBox(uint8_t *hdr, uint32_t maxSz, AampLogManager *mLOgObj=NULL, bool correctBoxSize=false, int newTrackId=-1)
Definition: isobmffbox.cpp:161
EmsgBox::setTimeScale
void setTimeScale(uint32_t tScale)
Set TimeScale value.
Definition: isobmffbox.cpp:542
TfdtBox
Class for ISO BMFF TFDT Box.
Definition: isobmffbox.h:421
Box::hasChildren
virtual bool hasChildren()
To check if box has any child boxes.
Definition: isobmffbox.cpp:98
PrftBox::constructPrftBox
static PrftBox * constructPrftBox(uint32_t sz, uint8_t *ptr)
Static function to construct a PrftBox object.
Definition: isobmffbox.cpp:1047
AampLogManager
AampLogManager Class.
Definition: AampLogManager.h:150
EmsgBox::getEventDuration
uint32_t getEventDuration()
Get eventDuration.
Definition: isobmffbox.cpp:566
MvhdBox::MvhdBox
MvhdBox(uint32_t sz, uint32_t tScale)
MvhdBox constructor.
Definition: isobmffbox.cpp:336
EmsgBox::getMessageLen
uint32_t getMessageLen()
Get Message length.
Definition: isobmffbox.cpp:671
EmsgBox::setEventDuration
void setEventDuration(uint32_t evtDur)
Set eventDuration value.
Definition: isobmffbox.cpp:558
Box
Base Class for ISO BMFF Box.
Definition: isobmffbox.h:90
EmsgBox::getId
uint32_t getId()
Get id.
Definition: isobmffbox.cpp:582
TfhdBox::TfhdBox
TfhdBox(uint32_t sz, uint64_t sample_duration)
TfhdBox constructor.
Definition: isobmffbox.cpp:890
Box::getOffset
uint32_t getOffset() const
Get box offset.
Definition: isobmffbox.cpp:90
GenericContainerBox
Class for ISO BMFF Box container Eg: MOOV, MOOF, TRAK, MDIA.
Definition: isobmffbox.h:203
TrunBox::constructTrunBox
static TrunBox * constructTrunBox(uint32_t sz, uint8_t *ptr)
Static function to construct a TrunBox object.
Definition: isobmffbox.cpp:831
EmsgBox::getTimeScale
uint32_t getTimeScale()
Get schemeIdUri.
Definition: isobmffbox.cpp:550
PrftBox::getNtpTs
uint64_t getNtpTs()
Get ntp Timestamp value.
Definition: isobmffbox.cpp:1023
Box::setOffset
void setOffset(uint32_t os)
Set box's offset from the beginning of the buffer.
Definition: isobmffbox.cpp:82
EmsgBox::setPresentationTimeDelta
void setPresentationTimeDelta(uint32_t presTimeDelta)
Set presentationTimeDelta.
Definition: isobmffbox.cpp:590
EmsgBox::setPresentationTime
void setPresentationTime(uint64_t presTime)
Set presentationTime.
Definition: isobmffbox.cpp:606
GenericContainerBox::hasChildren
bool hasChildren() override
To check if box has any child boxes.
Definition: isobmffbox.cpp:287
Box::getSize
uint32_t getSize() const
Get box size.
Definition: isobmffbox.cpp:114
TrakBox::TrakBox
TrakBox(uint32_t sz)
Trak constructor.
Definition: isobmffbox.h:270
TfhdBox::setSampleDuration
void setSampleDuration(uint64_t sample_duration)
Set Sample Duration value.
Definition: isobmffbox.cpp:906
GenericContainerBox::~GenericContainerBox
virtual ~GenericContainerBox()
GenericContainerBox destructor.
Definition: isobmffbox.cpp:265
TfhdBox
Class for ISO BMFF TFHD Box.
Definition: isobmffbox.h:725
EmsgBox::getMessage
uint8_t * getMessage()
Get Message.
Definition: isobmffbox.cpp:663
GenericContainerBox::GenericContainerBox
GenericContainerBox(uint32_t sz, const char btype[4])
GenericContainerBox constructor.
Definition: isobmffbox.cpp:257
AampConfig.h
Configurations for AAMP.
MvhdBox::constructMvhdBox
static MvhdBox * constructMvhdBox(uint32_t sz, uint8_t *ptr)
Static function to construct a MvhdBox object.
Definition: isobmffbox.cpp:368
TfdtBox::TfdtBox
TfdtBox(uint32_t sz, uint64_t mdt)
TfdtBox constructor.
Definition: isobmffbox.cpp:446
GenericContainerBox::getChildren
const std::vector< Box * > * getChildren() override
Get children of this box.
Definition: isobmffbox.cpp:295
isobmffbox.h
Header file for ISO Base Media File Format Boxes.
PrftBox::setMediaTime
void setMediaTime(uint64_t mediaTime)
Set Sample Duration value.
Definition: isobmffbox.cpp:1031
EmsgBox::setValue
void setValue(uint8_t *schemeIdValue)
Set value.
Definition: isobmffbox.cpp:638
AAMPLOG_TRACE
#define AAMPLOG_TRACE(FORMAT,...)
AAMP logging defines, this can be enabled through setLogLevel() as per the need.
Definition: AampLogManager.h:83
TfhdBox::constructTfhdBox
static TfhdBox * constructTfhdBox(uint32_t sz, uint8_t *ptr)
Static function to construct a TfdtBox object.
Definition: isobmffbox.cpp:922
Box::getChildren
virtual const std::vector< Box * > * getChildren()
Get children of this box.
Definition: isobmffbox.cpp:106
MvhdBox
Class for ISO BMFF MVHD Box.
Definition: isobmffbox.h:318
PrftBox::getMediaTime
uint64_t getMediaTime()
Get SampleDuration value.
Definition: isobmffbox.cpp:1039
EmsgBox::getValue
uint8_t * getValue()
Get value.
Definition: isobmffbox.cpp:646
PrftBox::getTrackId
uint32_t getTrackId()
Get Track id value.
Definition: isobmffbox.cpp:1007
TrunBox::setSampleDuration
void setSampleDuration(uint64_t sampleDuration)
Set SampleDuration value.
Definition: isobmffbox.cpp:815
TrakBox
Class for ISO BMFF TRAK container.
Definition: isobmffbox.h:260
Box::getType
const char * getType()
Get box type.
Definition: isobmffbox.cpp:122
EmsgBox::setSchemeIdUri
void setSchemeIdUri(uint8_t *schemeIdURI)
Set schemeIdUri.
Definition: isobmffbox.cpp:622
FullBox
Class for single ISO BMFF Box Eg: FTYP, MDHD, MVHD, TFDT.
Definition: isobmffbox.h:295
TrunBox::getSampleDuration
uint64_t getSampleDuration()
Get sampleDuration value.
Definition: isobmffbox.cpp:823
PrftBox::setTrackId
void setTrackId(uint32_t trackId)
Set Track Id value.
Definition: isobmffbox.cpp:999
MdhdBox::setTimeScale
void setTimeScale(uint32_t tScale)
Set TimeScale value.
Definition: isobmffbox.cpp:407
PrftBox
Class for ISO BMFF TFHD Box.
Definition: isobmffbox.h:776
EmsgBox::constructEmsgBox
static EmsgBox * constructEmsgBox(uint32_t sz, uint8_t *ptr)
Static function to construct a EmsgBox object.
Definition: isobmffbox.cpp:679
MvhdBox::getTimeScale
uint32_t getTimeScale()
Get TimeScale value.
Definition: isobmffbox.cpp:360
MdhdBox::MdhdBox
MdhdBox(uint32_t sz, uint32_t tScale)
MdhdBox constructor.
Definition: isobmffbox.cpp:391
WriteUint64
void WriteUint64(uint8_t *dst, uint64_t val)
Utility function to write 8 bytes to a buffer.
Definition: isobmffbox.cpp:64
ReadCStringLen
uint32_t ReadCStringLen(const uint8_t *buffer, uint32_t bufferLen)
Read a string from buffer and return it.
Definition: isobmffbox.cpp:34
EmsgBox::getPresentationTime
uint64_t getPresentationTime()
Get presentationTime.
Definition: isobmffbox.cpp:614
TrunBox
Class for ISO BMFF TRUN Box.
Definition: isobmffbox.h:666
MdhdBox::getTimeScale
uint32_t getTimeScale()
Get TimeScale value.
Definition: isobmffbox.cpp:415
TfhdBox::getSampleDuration
uint64_t getSampleDuration()
Get SampleDuration value.
Definition: isobmffbox.cpp:914
TfdtBox::constructTfdtBox
static TfdtBox * constructTfdtBox(uint32_t sz, uint8_t *ptr)
Static function to construct a TfdtBox object.
Definition: isobmffbox.cpp:478
EmsgBox::setMessage
void setMessage(uint8_t *message, uint32_t len)
Set Message.
Definition: isobmffbox.cpp:654