1 /*******************************************************************************
2  mp4_io.h - A library for general MPEG4 I/O.
3 
4  Copyright (C) 2007-2009 CodeShop B.V.
5  http://www.code-shop.com
6 
7  For licensing see the LICENSE file
8 ******************************************************************************/
9 
10 #ifndef MP4_IO_H_AKW
11 #define MP4_IO_H_AKW
12 
13 #include "mod_streaming_export.h"
14 
15 #ifndef _MSC_VER
16 #include <inttypes.h>
17 #else
18 #include "inttypes.h"
19 #endif
20 #include <stdio.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #ifdef UNUSED
27 #elif defined(__GNUC__)
28 # define UNUSED(x) UNUSED_ ## x __attribute__((unused))
29 #elif defined(__LCLINT__)
30 # define UNUSED(x) /*@unused@*/ x
31 #else
32 # define UNUSED(x) x
33 #endif
34 
35 #ifdef WIN32
36 #define ftello _ftelli64
37 #define fseeko _fseeki64
38 // #define strdup _strdup
39 #endif
40 
41 #define ATOM_PREAMBLE_SIZE 8
42 
43 #define MAX_TRACKS 8
44 
45 #define FOURCC(a, b, c, d) ((uint32_t)(a) << 24) + \
46                            ((uint32_t)(b) << 16) + \
47                            ((uint32_t)(c) << 8) + \
48                            ((uint32_t)(d))
49 
50 #define MP4_INFO(fmt, ...) \
51   if(mp4_context->verbose_ > 2) \
52   { \
53     mp4_log_trace("%s.%d: (info) "fmt, remove_path(__FILE__), __LINE__, __VA_ARGS__); \
54   }
55 
56 #define MP4_WARNING(fmt, ...) \
57   if(mp4_context->verbose_ > 1) \
58   { \
59     mp4_log_trace("%s.%d: (warning) "fmt, remove_path(__FILE__), __LINE__, __VA_ARGS__); \
60   }
61 
62 #define MP4_ERROR(fmt, ...) \
63   if(mp4_context->verbose_ > 0) \
64   { \
65     mp4_log_trace("%s.%d: (error) "fmt, remove_path(__FILE__), __LINE__, __VA_ARGS__); \
66   }
67 
68 MOD_STREAMING_DLL_LOCAL extern uint64_t atoi64(const char* val);
69 
70 MOD_STREAMING_DLL_LOCAL extern const char* remove_path(const char *path);
71 MOD_STREAMING_DLL_LOCAL extern void mp4_log_trace(const char* fmt, ...);
72 
73 MOD_STREAMING_DLL_LOCAL extern unsigned int read_8(unsigned char const* buffer);
74 MOD_STREAMING_DLL_LOCAL extern unsigned char* write_8(unsigned char* buffer, unsigned int v);
75 MOD_STREAMING_DLL_LOCAL extern uint16_t read_16(unsigned char const* buffer);
76 MOD_STREAMING_DLL_LOCAL extern unsigned char* write_16(unsigned char* buffer, unsigned int v);
77 MOD_STREAMING_DLL_LOCAL extern unsigned int read_24(unsigned char const* buffer);
78 MOD_STREAMING_DLL_LOCAL extern unsigned char* write_24(unsigned char* buffer, unsigned int v);
79 MOD_STREAMING_DLL_LOCAL extern uint32_t read_32(unsigned char const* buffer);
80 MOD_STREAMING_DLL_LOCAL extern unsigned char* write_32(unsigned char* buffer, uint32_t v);
81 MOD_STREAMING_DLL_LOCAL extern uint64_t read_64(unsigned char const* buffer);
82 MOD_STREAMING_DLL_LOCAL extern unsigned char* write_64(unsigned char* buffer, uint64_t v);
83 MOD_STREAMING_DLL_LOCAL extern uint32_t read_n(unsigned char const* buffer, unsigned int n);
84 MOD_STREAMING_DLL_LOCAL extern unsigned char* write_n(unsigned char* buffer, unsigned int n, uint32_t v);
85 
86 struct mem_range_t
87 {
88   int read_only_;
89   uint64_t filesize_;
90   int fd_;
91 
92   // original base mapping
93   void* mmap_addr_;
94   uint64_t mmap_offset_;
95   uint64_t mmap_size_;
96 
97 #ifdef WIN32
98   void* fileMapHandle_;
99 #endif
100 };
101 typedef struct mem_range_t mem_range_t;
102 
103 MOD_STREAMING_DLL_LOCAL extern mem_range_t* mem_range_init_read(char const* filename);
104 MOD_STREAMING_DLL_LOCAL extern mem_range_t* mem_range_init_write(char const* filename,
105                                   uint64_t offset, uint64_t len);
106 MOD_STREAMING_DLL_LOCAL extern void* mem_range_map(mem_range_t* mem_range, uint64_t offset, uint32_t len);
107 MOD_STREAMING_DLL_LOCAL extern void mem_range_exit(mem_range_t* mem_range);
108 
109 struct mp4_atom_t
110 {
111   uint32_t type_;
112   uint32_t short_size_;
113   uint64_t size_;
114   uint64_t start_;
115   uint64_t end_;
116 };
117 typedef struct mp4_atom_t mp4_atom_t;
118 
119 struct mp4_context_t;
120 MOD_STREAMING_DLL_LOCAL extern
121 int mp4_atom_read_header(struct mp4_context_t const* mp4_context,
122                          FILE* infile, mp4_atom_t* atom);
123 MOD_STREAMING_DLL_LOCAL extern
124 int mp4_atom_write_header(unsigned char* outbuffer,
125                           mp4_atom_t const* atom);
126 
127 struct unknown_atom_t
128 {
129   void* atom_;
130   struct unknown_atom_t* next_;
131 };
132 typedef struct unknown_atom_t unknown_atom_t;
133 MOD_STREAMING_DLL_LOCAL extern unknown_atom_t* unknown_atom_init(void);
134 MOD_STREAMING_DLL_LOCAL extern void unknown_atom_exit(unknown_atom_t* atom);
135 
136 struct moov_t
137 {
138   struct unknown_atom_t* unknown_atoms_;
139   struct mvhd_t* mvhd_;
140   unsigned int tracks_;
141   struct trak_t* traks_[MAX_TRACKS];
142   struct mvex_t* mvex_;
143 
144   int is_indexed_;
145 };
146 typedef struct moov_t moov_t;
147 MOD_STREAMING_DLL_LOCAL extern moov_t* moov_init(void);
148 MOD_STREAMING_DLL_LOCAL extern void moov_exit(moov_t* atom);
149 
150 struct mvhd_t
151 {
152   unsigned int version_;
153   unsigned int flags_;
154   uint64_t creation_time_;      // seconds since midnite, Jan .1 1904 (UTC)
155   uint64_t modification_time_;  // seconds since midnite, Jan .1 1904 (UTC)
156   uint32_t timescale_;          // time units that pass in one second
157   uint64_t duration_;           // duration of the longest track
158   uint32_t rate_;               // preferred playback rate (16.16)
159   uint16_t volume_;             // preferred playback volume (8.8)
160   uint16_t reserved1_;
161   uint32_t reserved2_[2];
162   uint32_t matrix_[9];
163   uint32_t predefined_[6];
164   uint32_t next_track_id_;
165 };
166 typedef struct mvhd_t mvhd_t;
167 MOD_STREAMING_DLL_LOCAL extern mvhd_t* mvhd_init(void);
168 MOD_STREAMING_DLL_LOCAL extern mvhd_t* mvhd_copy(mvhd_t const* rhs);
169 MOD_STREAMING_DLL_LOCAL extern void mvhd_exit(mvhd_t* atom);
170 
171 struct trak_t
172 {
173   struct unknown_atom_t* unknown_atoms_;
174   struct tkhd_t* tkhd_;
175   struct mdia_t* mdia_;
176   struct edts_t* edts_;
177 
178   unsigned int chunks_size_;
179   struct chunks_t* chunks_;
180 
181   unsigned int samples_size_;
182   struct samples_t* samples_;
183 
184   // current pts when reading fragments
185 //  uint64_t fragment_pts_;
186 };
187 typedef struct trak_t trak_t;
188 MOD_STREAMING_DLL_LOCAL extern trak_t* trak_init(void);
189 MOD_STREAMING_DLL_LOCAL extern unsigned int trak_bitrate(trak_t const* trak);
190 MOD_STREAMING_DLL_LOCAL extern void trak_exit(trak_t* trak);
191 
192 struct tkhd_t
193 {
194   unsigned int version_;
195   unsigned int flags_;
196   uint64_t creation_time_;      // seconds since midnite, Jan .1 1904 (UTC)
197   uint64_t modification_time_;  // seconds since midnite, Jan .1 1904 (UTC)
198   uint32_t track_id_;
199   uint32_t reserved_;
200   uint64_t duration_;           // duration of this track (mvhd.timescale)
201   uint32_t reserved2_[2];
202   uint16_t layer_;              // front-to-back ordering
203   uint16_t predefined_;
204   uint16_t volume_;             // relative audio volume (8.8)
205   uint16_t reserved3_;
206   uint32_t matrix_[9];          // transformation matrix
207   uint32_t width_;              // visual presentation width (16.16)
208   uint32_t height_;             // visual presentation height (16.16)
209 };
210 typedef struct tkhd_t tkhd_t;
211 MOD_STREAMING_DLL_LOCAL extern tkhd_t* tkhd_init(void);
212 MOD_STREAMING_DLL_LOCAL extern tkhd_t* tkhd_copy(tkhd_t const* rhs);
213 MOD_STREAMING_DLL_LOCAL extern void tkhd_exit(tkhd_t* tkhd);
214 
215 struct mdia_t
216 {
217   struct unknown_atom_t* unknown_atoms_;
218   struct mdhd_t* mdhd_;
219   struct hdlr_t* hdlr_;
220   struct minf_t* minf_;
221 };
222 typedef struct mdia_t mdia_t;
223 MOD_STREAMING_DLL_LOCAL extern mdia_t* mdia_init(void);
224 MOD_STREAMING_DLL_LOCAL extern void mdia_exit(mdia_t* atom);
225 
226 struct elst_table_t
227 {
228   uint64_t segment_duration_;
229   int64_t media_time_;
230   int16_t media_rate_integer_;
231   int16_t media_rate_fraction_;
232 };
233 typedef struct elst_table_t elst_table_t;
234 
235 struct elst_t
236 {
237   unsigned int version_;
238   unsigned int flags_;
239   uint32_t entry_count_;
240   struct elst_table_t* table_;
241 };
242 typedef struct elst_t elst_t;
243 MOD_STREAMING_DLL_LOCAL extern elst_t* elst_init(void);
244 MOD_STREAMING_DLL_LOCAL extern void elst_exit(elst_t* atom);
245 
246 struct edts_t
247 {
248   struct unknown_atom_t* unknown_atoms_;
249   struct elst_t* elst_;
250 };
251 typedef struct edts_t edts_t;
252 MOD_STREAMING_DLL_LOCAL extern edts_t* edts_init(void);
253 MOD_STREAMING_DLL_LOCAL extern void edts_exit(edts_t* atom);
254 
255 struct mdhd_t
256 {
257   unsigned int version_;
258   unsigned int flags_;
259   uint64_t creation_time_;      // seconds since midnite, Jan .1 1904 (UTC)
260   uint64_t modification_time_;  // seconds since midnite, Jan .1 1904 (UTC)
261   uint32_t timescale_;          // time units that pass in one second
262   uint64_t duration_;           // duration of this media
263   unsigned int language_[3];    // language code for this media (ISO 639-2/T)
264   uint16_t predefined_;
265 };
266 typedef struct mdhd_t mdhd_t;
267 MOD_STREAMING_DLL_LOCAL extern struct mdhd_t* mdhd_init(void);
268 MOD_STREAMING_DLL_LOCAL extern mdhd_t* mdhd_copy(mdhd_t const* rhs);
269 MOD_STREAMING_DLL_LOCAL extern void mdhd_exit(struct mdhd_t* mdhd);
270 
271 struct hdlr_t
272 {
273   unsigned int version_;
274   unsigned int flags_;
275   uint32_t predefined_;
276   uint32_t handler_type_;       // format of the contents ('vide', 'soun', ...)
277   uint32_t reserved1_;
278   uint32_t reserved2_;
279   uint32_t reserved3_;
280   char* name_;                  // human-readable name for the track type (UTF8)
281 };
282 typedef struct hdlr_t hdlr_t;
283 MOD_STREAMING_DLL_LOCAL extern hdlr_t* hdlr_init(void);
284 MOD_STREAMING_DLL_LOCAL extern hdlr_t* hdlr_copy(hdlr_t const* rhs);
285 MOD_STREAMING_DLL_LOCAL extern void hdlr_exit(hdlr_t* atom);
286 
287 struct minf_t
288 {
289   struct unknown_atom_t* unknown_atoms_;
290   struct vmhd_t* vmhd_;
291   struct smhd_t* smhd_;
292   struct dinf_t* dinf_;
293   struct stbl_t* stbl_;
294 };
295 typedef struct minf_t minf_t;
296 MOD_STREAMING_DLL_LOCAL extern minf_t* minf_init(void);
297 MOD_STREAMING_DLL_LOCAL extern void minf_exit(minf_t* atom);
298 
299 struct vmhd_t
300 {
301   unsigned int version_;
302   unsigned int flags_;
303   uint16_t graphics_mode_;      // composition mode (0=copy)
304   uint16_t opcolor_[3];
305 };
306 typedef struct vmhd_t vmhd_t;
307 MOD_STREAMING_DLL_LOCAL extern vmhd_t* vmhd_init(void);
308 MOD_STREAMING_DLL_LOCAL extern vmhd_t* vmhd_copy(vmhd_t* rhs);
309 MOD_STREAMING_DLL_LOCAL extern void vmhd_exit(vmhd_t* atom);
310 
311 struct smhd_t
312 {
313   unsigned int version_;
314   unsigned int flags_;
315   uint16_t balance_;            // place mono audio tracks in stereo space (8.8)
316   uint16_t reserved_;
317 };
318 typedef struct smhd_t smhd_t;
319 MOD_STREAMING_DLL_LOCAL extern smhd_t* smhd_init(void);
320 MOD_STREAMING_DLL_LOCAL extern smhd_t* smhd_copy(smhd_t* rhs);
321 MOD_STREAMING_DLL_LOCAL extern void smhd_exit(smhd_t* atom);
322 
323 struct dinf_t
324 {
325   struct dref_t* dref_;         // declares the location of the media info
326 };
327 typedef struct dinf_t dinf_t;
328 MOD_STREAMING_DLL_LOCAL extern dinf_t* dinf_init(void);
329 MOD_STREAMING_DLL_LOCAL extern dinf_t* dinf_copy(dinf_t* rhs);
330 MOD_STREAMING_DLL_LOCAL extern void dinf_exit(dinf_t* atom);
331 
332 struct dref_table_t
333 {
334   unsigned int flags_;          // 0x000001 is self contained
335   char* name_;                  // name is a URN
336   char* location_;              // location is a URL
337 };
338 typedef struct dref_table_t dref_table_t;
339 MOD_STREAMING_DLL_LOCAL extern void dref_table_init(dref_table_t* entry);
340 MOD_STREAMING_DLL_LOCAL extern void dref_table_assign(dref_table_t* lhs, dref_table_t const* rhs);
341 MOD_STREAMING_DLL_LOCAL extern void dref_table_exit(dref_table_t* entry);
342 
343 struct dref_t
344 {
345   unsigned int version_;
346   unsigned int flags_;
347   unsigned int entry_count_;
348   dref_table_t* table_;
349 };
350 typedef struct dref_t dref_t;
351 MOD_STREAMING_DLL_LOCAL extern dref_t* dref_init(void);
352 MOD_STREAMING_DLL_LOCAL extern dref_t* dref_copy(dref_t const* rhs);
353 MOD_STREAMING_DLL_LOCAL extern void dref_exit(dref_t* atom);
354 
355 struct stbl_t
356 {
357   struct unknown_atom_t* unknown_atoms_;
358   struct stsd_t* stsd_;         // sample description
359   struct stts_t* stts_;         // decoding time-to-sample
360   struct stss_t* stss_;         // sync sample
361   struct stsc_t* stsc_;         // sample-to-chunk
362   struct stsz_t* stsz_;         // sample size
363   struct stco_t* stco_;         // chunk offset
364   struct ctts_t* ctts_;         // composition time-to-sample
365 };
366 typedef struct stbl_t stbl_t;
367 MOD_STREAMING_DLL_LOCAL extern stbl_t* stbl_init(void);
368 MOD_STREAMING_DLL_LOCAL extern void stbl_exit(stbl_t* atom);
369 MOD_STREAMING_DLL_LOCAL extern
370 unsigned int stbl_get_nearest_keyframe(stbl_t const* stbl, unsigned int sample);
371 
372 struct stsd_t
373 {
374   unsigned int version_;
375   unsigned int flags_;
376   uint32_t entries_;
377   struct sample_entry_t* sample_entries_;
378 };
379 typedef struct stsd_t stsd_t;
380 MOD_STREAMING_DLL_LOCAL extern stsd_t* stsd_init(void);
381 MOD_STREAMING_DLL_LOCAL extern stsd_t* stsd_copy(stsd_t const* rhs);
382 MOD_STREAMING_DLL_LOCAL extern void stsd_exit(stsd_t* atom);
383 
384 struct video_sample_entry_t
385 {
386   uint16_t version_;
387   uint16_t revision_level_;
388   uint32_t vendor_;
389   uint32_t temporal_quality_;
390   uint32_t spatial_quality_;
391   uint16_t width_;
392   uint16_t height_;
393   uint32_t horiz_resolution_;   // pixels per inch (16.16)
394   uint32_t vert_resolution_;    // pixels per inch (16.16)
395   uint32_t data_size_;
396   uint16_t frame_count_;        // number of frames in each sample
397   uint8_t compressor_name_[32]; // informative purposes (pascal string)
398   uint16_t depth_;              // images are in colour with no alpha (24)
399   int16_t color_table_id_;
400 };
401 typedef struct video_sample_entry_t video_sample_entry_t;
402 MOD_STREAMING_DLL_LOCAL extern video_sample_entry_t* video_sample_entry_init(void);
403 
404 struct audio_sample_entry_t
405 {
406   uint16_t version_;
407   uint16_t revision_;
408   uint32_t vendor_;
409   uint16_t channel_count_;      // mono(1), stereo(2)
410   uint16_t sample_size_;        // (bits)
411   uint16_t compression_id_;
412   uint16_t packet_size_;
413   uint32_t samplerate_;         // sampling rate (16.16)
414 };
415 typedef struct audio_sample_entry_t audio_sample_entry_t;
416 MOD_STREAMING_DLL_LOCAL extern audio_sample_entry_t* audio_sample_entry_init(void);
417 
418 struct sample_entry_t
419 {
420   unsigned int len_;
421   uint32_t fourcc_;
422   unsigned char* buf_;
423 
424   struct video_sample_entry_t* video_;
425   struct audio_sample_entry_t* audio_;
426 //struct hint_sample_entry_t* hint_;
427 
428   unsigned int codec_private_data_length_;
429   unsigned char const* codec_private_data_;
430 
431   // avcC
432   unsigned int nal_unit_length_;
433   unsigned int sps_length_;
434   unsigned char* sps_;
435   unsigned int pps_length_;
436   unsigned char* pps_;
437 
438   // sound (WAVEFORMATEX) structure
439   uint16_t wFormatTag;
440   uint16_t nChannels;
441   uint32_t nSamplesPerSec;
442   uint32_t nAvgBytesPerSec;
443   uint16_t nBlockAlign;
444   uint16_t wBitsPerSample;
445 
446   unsigned int samplerate_hi_;
447   unsigned int samplerate_lo_;
448 
449   // esds
450   unsigned int max_bitrate_;
451   unsigned int avg_bitrate_;
452 };
453 typedef struct sample_entry_t sample_entry_t;
454 MOD_STREAMING_DLL_LOCAL extern
455 void sample_entry_init(sample_entry_t* sample_entry);
456 MOD_STREAMING_DLL_LOCAL extern
457 void sample_entry_assign(sample_entry_t* lhs, sample_entry_t const* rhs);
458 MOD_STREAMING_DLL_LOCAL extern
459 void sample_entry_exit(sample_entry_t* sample_entry);
460 MOD_STREAMING_DLL_LOCAL extern
461 void sample_entry_get_adts(sample_entry_t const* sample_entry,
462                            unsigned int sample_size, uint8_t* buf);
463 
464 struct stts_t
465 {
466   unsigned int version_;
467   unsigned int flags_;
468   uint32_t entries_;
469   struct stts_table_t* table_;
470 };
471 typedef struct stts_t stts_t;
472 MOD_STREAMING_DLL_LOCAL extern stts_t* stts_init(void);
473 MOD_STREAMING_DLL_LOCAL extern void stts_exit(stts_t* atom);
474 MOD_STREAMING_DLL_LOCAL extern unsigned int stts_get_sample(stts_t const* stts, uint64_t time);
475 MOD_STREAMING_DLL_LOCAL extern uint64_t stts_get_time(stts_t const* stts, unsigned int sample);
476 MOD_STREAMING_DLL_LOCAL extern uint64_t stts_get_duration(stts_t const* stts);
477 MOD_STREAMING_DLL_LOCAL extern unsigned int stts_get_samples(stts_t const* stts);
478 
479 struct stts_table_t
480 {
481   uint32_t sample_count_;
482   uint32_t sample_duration_;
483 };
484 typedef struct stts_table_t stts_table_t;
485 
486 struct stss_t
487 {
488   unsigned int version_;
489   unsigned int flags_;
490   uint32_t entries_;
491   uint32_t* sample_numbers_;
492 };
493 typedef struct stss_t stss_t;
494 MOD_STREAMING_DLL_LOCAL extern stss_t* stss_init(void);
495 MOD_STREAMING_DLL_LOCAL extern void stss_exit(stss_t* atom);
496 MOD_STREAMING_DLL_LOCAL extern
497 unsigned int stss_get_nearest_keyframe(stss_t const* stss, unsigned int sample);
498 
499 struct stsc_t
500 {
501   unsigned int version_;
502   unsigned int flags_;
503   uint32_t entries_;
504   struct stsc_table_t* table_;
505 };
506 typedef struct stsc_t stsc_t;
507 MOD_STREAMING_DLL_LOCAL extern stsc_t* stsc_init(void);
508 MOD_STREAMING_DLL_LOCAL extern void stsc_exit(stsc_t* atom);
509 
510 struct stsc_table_t
511 {
512   uint32_t chunk_;
513   uint32_t samples_;
514   uint32_t id_;
515 };
516 typedef struct stsc_table_t stsc_table_t;
517 
518 struct stsz_t
519 {
520   unsigned int version_;
521   unsigned int flags_;
522   uint32_t sample_size_;
523   uint32_t entries_;
524   uint32_t* sample_sizes_;
525 };
526 typedef struct stsz_t stsz_t;
527 MOD_STREAMING_DLL_LOCAL extern stsz_t* stsz_init(void);
528 MOD_STREAMING_DLL_LOCAL extern void stsz_exit(stsz_t* atom);
529 
530 struct stco_t
531 {
532   unsigned int version_;
533   unsigned int flags_;
534   uint32_t entries_;
535   uint64_t* chunk_offsets_;
536 
537   void* stco_inplace_;          // newly generated stco (patched inplace)
538 };
539 typedef struct stco_t stco_t;
540 MOD_STREAMING_DLL_LOCAL extern stco_t* stco_init(void);
541 MOD_STREAMING_DLL_LOCAL extern void stco_exit(stco_t* atom);
542 
543 struct ctts_t
544 {
545   unsigned int version_;
546   unsigned int flags_;
547   uint32_t entries_;
548   struct ctts_table_t* table_;
549 };
550 typedef struct ctts_t ctts_t;
551 MOD_STREAMING_DLL_LOCAL extern ctts_t* ctts_init(void);
552 MOD_STREAMING_DLL_LOCAL extern void ctts_exit(ctts_t* atom);
553 MOD_STREAMING_DLL_LOCAL extern unsigned int ctts_get_samples(ctts_t const* ctts);
554 
555 struct ctts_table_t
556 {
557   uint32_t sample_count_;
558   uint32_t sample_offset_;
559 };
560 typedef struct ctts_table_t ctts_table_t;
561 
562 struct samples_t
563 {
564   uint64_t pts_;                // decoding/presentation time
565   unsigned int size_;           // size in bytes
566   uint64_t pos_;                // byte offset
567   unsigned int cto_;            // composition time offset
568 
569   unsigned int is_ss_:1;        // sync sample
570   unsigned int is_smooth_ss_:1; // sync sample for smooth streaming
571 };
572 typedef struct samples_t samples_t;
573 
574 struct chunks_t
575 {
576   unsigned int sample_;         // number of the first sample in the chunk
577   unsigned int size_;           // number of samples in the chunk
578   int id_;                      // not used
579   uint64_t pos_;                // start byte position of chunk
580 };
581 typedef struct chunks_t chunks_t;
582 
583 MOD_STREAMING_DLL_LOCAL extern
584 uint64_t moov_time_to_trak_time(uint64_t t, long moov_time_scale,
585                                 long trak_time_scale);
586 MOD_STREAMING_DLL_LOCAL extern
587 uint64_t trak_time_to_moov_time(uint64_t t, long moov_time_scale,
588                                 long trak_time_scale);
589 
590 struct mvex_t
591 {
592   struct unknown_atom_t* unknown_atoms_;
593   unsigned int tracks_;
594   struct trex_t* trexs_[MAX_TRACKS];
595 };
596 typedef struct mvex_t mvex_t;
597 MOD_STREAMING_DLL_LOCAL extern mvex_t* mvex_init(void);
598 MOD_STREAMING_DLL_LOCAL extern void mvex_exit(mvex_t* mvex);
599 
600 struct trex_t
601 {
602   unsigned int version_;
603   unsigned int flags_;
604   uint32_t track_id_;
605   uint32_t default_sample_description_index_;
606   uint32_t default_sample_duration_;
607   uint32_t default_sample_size_;
608   uint32_t default_sample_flags_;
609 };
610 typedef struct trex_t trex_t;
611 MOD_STREAMING_DLL_LOCAL extern trex_t* trex_init(void);
612 MOD_STREAMING_DLL_LOCAL extern void trex_exit(trex_t* trex);
613 
614 struct moof_t
615 {
616   struct unknown_atom_t* unknown_atoms_;
617   struct mfhd_t* mfhd_;
618   unsigned int tracks_;
619   struct traf_t* trafs_[MAX_TRACKS];
620 };
621 typedef struct moof_t moof_t;
622 MOD_STREAMING_DLL_LOCAL extern moof_t* moof_init(void);
623 MOD_STREAMING_DLL_LOCAL extern void moof_exit(moof_t* atom);
624 
625 struct mfhd_t
626 {
627   unsigned int version_;
628   unsigned int flags_;
629   // the ordinal number of this fragment, in increasing order
630   uint32_t sequence_number_;
631 };
632 typedef struct mfhd_t mfhd_t;
633 MOD_STREAMING_DLL_LOCAL extern mfhd_t* mfhd_init(void);
634 MOD_STREAMING_DLL_LOCAL extern void mfhd_exit(mfhd_t* atom);
635 
636 struct traf_t
637 {
638   struct unknown_atom_t* unknown_atoms_;
639   struct tfhd_t* tfhd_;
640   struct trun_t* trun_;
641   struct uuid0_t* uuid0_;
642   struct uuid1_t* uuid1_;
643 };
644 typedef struct traf_t traf_t;
645 MOD_STREAMING_DLL_LOCAL extern traf_t* traf_init(void);
646 MOD_STREAMING_DLL_LOCAL extern void traf_exit(traf_t* atom);
647 
648 struct tfhd_t
649 {
650   unsigned int version_;
651   unsigned int flags_;
652   uint32_t track_id_;
653   // all the following are optional fields
654   uint64_t base_data_offset_;
655   uint32_t sample_description_index_;
656   uint32_t default_sample_duration_;
657   uint32_t default_sample_size_;
658   uint32_t default_sample_flags_;
659 };
660 typedef struct tfhd_t tfhd_t;
661 MOD_STREAMING_DLL_LOCAL extern tfhd_t* tfhd_init(void);
662 MOD_STREAMING_DLL_LOCAL extern void tfhd_exit(tfhd_t* atom);
663 
664 struct tfra_table_t
665 {
666   uint64_t time_;
667   uint64_t moof_offset_;
668   uint32_t traf_number_;
669   uint32_t trun_number_;
670   uint32_t sample_number_;
671 };
672 typedef struct tfra_table_t tfra_table_t;
673 
674 struct tfra_t
675 {
676   unsigned int version_;
677   unsigned int flags_;
678   uint32_t track_id_;
679   unsigned int length_size_of_traf_num_;
680   unsigned int length_size_of_trun_num_;
681   unsigned int length_size_of_sample_num_;
682   uint32_t number_of_entry_;
683   struct tfra_table_t* table_;
684 };
685 typedef struct tfra_t tfra_t;
686 MOD_STREAMING_DLL_LOCAL extern tfra_t* tfra_init(void);
687 MOD_STREAMING_DLL_LOCAL extern void tfra_exit(tfra_t* tfra);
688 MOD_STREAMING_DLL_LOCAL extern void tfra_add(tfra_t* tfra, tfra_table_t const* table);
689 
690 struct mfra_t
691 {
692   struct unknown_atom_t* unknown_atoms_;
693   unsigned int tracks_;
694   struct tfra_t* tfras_[MAX_TRACKS];
695 };
696 typedef struct mfra_t mfra_t;
697 MOD_STREAMING_DLL_LOCAL extern mfra_t* mfra_init(void);
698 MOD_STREAMING_DLL_LOCAL extern void mfra_exit(mfra_t* atom);
699 
700 struct trun_table_t
701 {
702   uint32_t sample_duration_;
703   uint32_t sample_size_;
704   uint32_t sample_flags_;
705   uint32_t sample_composition_time_offset_;
706 };
707 typedef struct trun_table_t trun_table_t;
708 
709 struct trun_t
710 {
711   unsigned int version_;
712   unsigned int flags_;
713   // the number of samples being added in this fragment; also the number of rows
714   // in the following table (the rows can be empty)
715   uint32_t sample_count_;
716   // is added to the implicit or explicit data_offset established in the track
717   // fragment header
718   int32_t data_offset_;
719   // provides a set of flags for the first sample only of this run
720   uint32_t first_sample_flags_;
721 
722   trun_table_t* table_;
723 
724   // additional info for uuid
725 //  trak_t const* trak_;
726 //  unsigned int start_;
727   struct trun_t* next_;
728 };
729 typedef struct trun_t trun_t;
730 MOD_STREAMING_DLL_LOCAL extern struct trun_t* trun_init(void);
731 MOD_STREAMING_DLL_LOCAL extern void trun_exit(struct trun_t* atom);
732 
733 struct uuid0_t
734 {
735   uint64_t pts_;
736   uint64_t duration_;
737 };
738 typedef struct uuid0_t uuid0_t;
739 MOD_STREAMING_DLL_LOCAL extern uuid0_t* uuid0_init(void);
740 MOD_STREAMING_DLL_LOCAL extern void uuid0_exit(uuid0_t* atom);
741 
742 struct uuid1_t
743 {
744   unsigned int entries_;
745   uint64_t pts_[2];
746   uint64_t duration_[2];
747 };
748 typedef struct uuid1_t uuid1_t;
749 MOD_STREAMING_DLL_LOCAL extern uuid1_t* uuid1_init(void);
750 MOD_STREAMING_DLL_LOCAL extern void uuid1_exit(uuid1_t* atom);
751 
752 // random access structure similar to mfra, but with size field
753 struct rxs_t
754 {
755   uint64_t time_;
756   uint64_t offset_;
757   uint64_t size_;
758 };
759 typedef struct rxs_t rxs_t;
760 
761 #define MP4_ELEMENTARY_STREAM_DESCRIPTOR_TAG   3
762 #define MP4_DECODER_CONFIG_DESCRIPTOR_TAG      4
763 #define MP4_DECODER_SPECIFIC_DESCRIPTOR_TAG    5
764 
765 #define MP4_MPEG4Audio                      0x40
766 #define MP4_MPEG2AudioMain                  0x66
767 #define MP4_MPEG2AudioLowComplexity         0x67
768 #define MP4_MPEG2AudioScaleableSamplingRate 0x68
769 #define MP4_MPEG2AudioPart3                 0x69
770 #define MP4_MPEG1Audio                      0x6b
771 
772 struct mp4_context_t
773 {
774   char* filename_;
775   FILE* infile;
776 
777   int verbose_;
778 
779   // the atoms as found in the stream
780   mp4_atom_t ftyp_atom;
781   mp4_atom_t moov_atom;
782   mp4_atom_t mdat_atom;
783   mp4_atom_t mfra_atom;
784 
785   // the actual binary data
786   unsigned char* moov_data;
787   unsigned char* mfra_data;
788 
789   // the parsed atoms
790   moov_t* moov;
791 
792   // the file offset of a moof atom, used for base_data_offset
793   uint64_t moof_offset_;
794 };
795 typedef struct mp4_context_t mp4_context_t;
796 
797 enum mp4_open_flags
798 {
799   MP4_OPEN_MOOV = 0x00000001,
800   MP4_OPEN_MOOF = 0x00000002,
801   MP4_OPEN_MDAT = 0x00000004,
802   MP4_OPEN_MFRA = 0x00000008,
803   MP4_OPEN_ALL  = 0x0000000f
804 };
805 typedef enum mp4_open_flags mp4_open_flags;
806 
807 MOD_STREAMING_DLL_LOCAL extern
808 mp4_context_t* mp4_open(const char* filename, int64_t filesize,
809                         mp4_open_flags flags, int verbose);
810 
811 MOD_STREAMING_DLL_LOCAL extern void mp4_close(mp4_context_t* mp4_context);
812 
813 #ifdef __cplusplus
814 } /* extern C definitions */
815 #endif
816 
817 #endif // MP4_IO_H_AKW
818 
819 // End Of File
820 
821