libmp4.h 42.6 KB
Newer Older
1
2
3
/*****************************************************************************
 * libmp4.h : LibMP4 library for mp4 module for vlc
 *****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2001-2004, 2010 the VideoLAN team
5
 *
6
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
Laurent Aimar's avatar
Laurent Aimar committed
7
 *
8
9
10
11
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
Laurent Aimar's avatar
Laurent Aimar committed
12
 *
13
14
15
16
17
18
19
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
dionoea's avatar
dionoea committed
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22

23
24
25
#ifndef _VLC_MP4_H
#define _VLC_MP4_H 1

26
27
#include <vlc_es.h>

28
#define ATOM_root VLC_FOURCC( 'r', 'o', 'o', 't' )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define ATOM_uuid VLC_FOURCC( 'u', 'u', 'i', 'd' )

#define ATOM_ftyp VLC_FOURCC( 'f', 't', 'y', 'p' )
#define ATOM_moov VLC_FOURCC( 'm', 'o', 'o', 'v' )
#define ATOM_foov VLC_FOURCC( 'f', 'o', 'o', 'v' )
#define ATOM_cmov VLC_FOURCC( 'c', 'm', 'o', 'v' )
#define ATOM_dcom VLC_FOURCC( 'd', 'c', 'o', 'm' )
#define ATOM_cmvd VLC_FOURCC( 'c', 'm', 'v', 'd' )

#define ATOM_moof VLC_FOURCC( 'm', 'o', 'o', 'f' )
#define ATOM_mdat VLC_FOURCC( 'm', 'd', 'a', 't' )
#define ATOM_skip VLC_FOURCC( 's', 'k', 'i', 'p' )
#define ATOM_free VLC_FOURCC( 'f', 'r', 'e', 'e' )
#define ATOM_udta VLC_FOURCC( 'u', 'd', 't', 'a' )
#define ATOM_wide VLC_FOURCC( 'w', 'i', 'd', 'e' )

45
46
#define ATOM_data VLC_FOURCC( 'd', 'a', 't', 'a' )

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#define ATOM_trak VLC_FOURCC( 't', 'r', 'a', 'k' )
#define ATOM_mvhd VLC_FOURCC( 'm', 'v', 'h', 'd' )
#define ATOM_tkhd VLC_FOURCC( 't', 'k', 'h', 'd' )
#define ATOM_tref VLC_FOURCC( 't', 'r', 'e', 'f' )
#define ATOM_mdia VLC_FOURCC( 'm', 'd', 'i', 'a' )
#define ATOM_mdhd VLC_FOURCC( 'm', 'd', 'h', 'd' )
#define ATOM_hdlr VLC_FOURCC( 'h', 'd', 'l', 'r' )
#define ATOM_minf VLC_FOURCC( 'm', 'i', 'n', 'f' )
#define ATOM_vmhd VLC_FOURCC( 'v', 'm', 'h', 'd' )
#define ATOM_smhd VLC_FOURCC( 's', 'm', 'h', 'd' )
#define ATOM_hmhd VLC_FOURCC( 'h', 'm', 'h', 'd' )
#define ATOM_dinf VLC_FOURCC( 'd', 'i', 'n', 'f' )
#define ATOM_url  VLC_FOURCC( 'u', 'r', 'l', ' ' )
#define ATOM_urn  VLC_FOURCC( 'u', 'r', 'n', ' ' )
#define ATOM_dref VLC_FOURCC( 'd', 'r', 'e', 'f' )
#define ATOM_stbl VLC_FOURCC( 's', 't', 'b', 'l' )
#define ATOM_stts VLC_FOURCC( 's', 't', 't', 's' )
#define ATOM_ctts VLC_FOURCC( 'c', 't', 't', 's' )
#define ATOM_stsd VLC_FOURCC( 's', 't', 's', 'd' )
#define ATOM_stsz VLC_FOURCC( 's', 't', 's', 'z' )
#define ATOM_stz2 VLC_FOURCC( 's', 't', 'z', '2' )
#define ATOM_stsc VLC_FOURCC( 's', 't', 's', 'c' )
#define ATOM_stco VLC_FOURCC( 's', 't', 'c', 'o' )
#define ATOM_co64 VLC_FOURCC( 'c', 'o', '6', '4' )
#define ATOM_stss VLC_FOURCC( 's', 't', 's', 's' )
#define ATOM_stsh VLC_FOURCC( 's', 't', 's', 'h' )
#define ATOM_stdp VLC_FOURCC( 's', 't', 'd', 'p' )
#define ATOM_padb VLC_FOURCC( 'p', 'a', 'd', 'b' )
#define ATOM_edts VLC_FOURCC( 'e', 'd', 't', 's' )
#define ATOM_elst VLC_FOURCC( 'e', 'l', 's', 't' )
#define ATOM_mvex VLC_FOURCC( 'm', 'v', 'e', 'x' )
78
#define ATOM_sdtp VLC_FOURCC( 's', 'd', 't', 'p' )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
79
#define ATOM_trex VLC_FOURCC( 't', 'r', 'e', 'x' )
80
#define ATOM_mehd VLC_FOURCC( 'm', 'e', 'h', 'd' )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
81
82
#define ATOM_mfhd VLC_FOURCC( 'm', 'f', 'h', 'd' )
#define ATOM_traf VLC_FOURCC( 't', 'r', 'a', 'f' )
83
#define ATOM_sidx VLC_FOURCC( 's', 'i', 'd', 'x' )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
84
85
86
87
#define ATOM_tfhd VLC_FOURCC( 't', 'f', 'h', 'd' )
#define ATOM_trun VLC_FOURCC( 't', 'r', 'u', 'n' )
#define ATOM_cprt VLC_FOURCC( 'c', 'p', 'r', 't' )
#define ATOM_iods VLC_FOURCC( 'i', 'o', 'd', 's' )
88
#define ATOM_pasp VLC_FOURCC( 'p', 'a', 's', 'p' )
89
90
91
#define ATOM_mfra VLC_FOURCC( 'm', 'f', 'r', 'a' )
#define ATOM_mfro VLC_FOURCC( 'm', 'f', 'r', 'o' )
#define ATOM_tfra VLC_FOURCC( 't', 'f', 'r', 'a' )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

#define ATOM_nmhd VLC_FOURCC( 'n', 'm', 'h', 'd' )
#define ATOM_mp2v VLC_FOURCC( 'm', 'p', '2', 'v' )
#define ATOM_mp4v VLC_FOURCC( 'm', 'p', '4', 'v' )
#define ATOM_mp4a VLC_FOURCC( 'm', 'p', '4', 'a' )
#define ATOM_mp4s VLC_FOURCC( 'm', 'p', '4', 's' )
#define ATOM_vide VLC_FOURCC( 'v', 'i', 'd', 'e' )
#define ATOM_soun VLC_FOURCC( 's', 'o', 'u', 'n' )
#define ATOM_hint VLC_FOURCC( 'h', 'i', 'n', 't' )
#define ATOM_hdv2 VLC_FOURCC( 'h', 'd', 'v', '2' )

#define ATOM_dpnd VLC_FOURCC( 'd', 'p', 'n', 'd' )
#define ATOM_ipir VLC_FOURCC( 'i', 'p', 'i', 'r' )
#define ATOM_mpod VLC_FOURCC( 'm', 'p', 'o', 'd' )
#define ATOM_hnti VLC_FOURCC( 'h', 'n', 't', 'i' )
#define ATOM_rtp  VLC_FOURCC( 'r', 't', 'p', ' ' )

#define ATOM_isom VLC_FOURCC( 'i', 's', 'o', 'm' )
#define ATOM_3gp4 VLC_FOURCC( '3', 'g', 'p', '4' )
#define ATOM_esds VLC_FOURCC( 'e', 's', 'd', 's' )

#define ATOM__mp3 VLC_FOURCC( '.', 'm', 'p', '3' )
#define ATOM_ms02 VLC_FOURCC( 'm', 's', 0x0, 0x02 )
#define ATOM_ms11 VLC_FOURCC( 'm', 's', 0x0, 0x11 )
#define ATOM_ms55 VLC_FOURCC( 'm', 's', 0x0, 0x55 )
#define ATOM_twos VLC_FOURCC( 't', 'w', 'o', 's' )
#define ATOM_sowt VLC_FOURCC( 's', 'o', 'w', 't' )
#define ATOM_QDMC VLC_FOURCC( 'Q', 'D', 'M', 'C' )
#define ATOM_QDM2 VLC_FOURCC( 'Q', 'D', 'M', '2' )
#define ATOM_ima4 VLC_FOURCC( 'i', 'm', 'a', '4' )
#define ATOM_IMA4 VLC_FOURCC( 'I', 'M', 'A', '4' )
#define ATOM_dvi  VLC_FOURCC( 'd', 'v', 'i', ' ' )
#define ATOM_MAC3 VLC_FOURCC( 'M', 'A', 'C', '3' )
#define ATOM_MAC6 VLC_FOURCC( 'M', 'A', 'C', '6' )
#define ATOM_alaw VLC_FOURCC( 'a', 'l', 'a', 'w' )
#define ATOM_ulaw VLC_FOURCC( 'u', 'l', 'a', 'w' )
#define ATOM_Qclp VLC_FOURCC( 'Q', 'c', 'l', 'p' )
#define ATOM_samr VLC_FOURCC( 's', 'a', 'm', 'r' )
#define ATOM_sawb VLC_FOURCC( 's', 'a', 'w', 'b' )
#define ATOM_OggS VLC_FOURCC( 'O', 'g', 'g', 'S' )
#define ATOM_alac VLC_FOURCC( 'a', 'l', 'a', 'c' )
#define ATOM_dac3 VLC_FOURCC( 'd', 'a', 'c', '3' )
#define ATOM_dec3 VLC_FOURCC( 'd', 'e', 'c', '3' )
135
#define ATOM_dvc1 VLC_FOURCC( 'd', 'v', 'c', '1' )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#define ATOM_enda VLC_FOURCC( 'e', 'n', 'd', 'a' )
#define ATOM_gnre VLC_FOURCC( 'g', 'n', 'r', 'e' )
#define ATOM_trkn VLC_FOURCC( 't', 'r', 'k', 'n' )

#define ATOM_zlib VLC_FOURCC( 'z', 'l', 'i', 'b' )
#define ATOM_SVQ1 VLC_FOURCC( 'S', 'V', 'Q', '1' )
#define ATOM_SVQ3 VLC_FOURCC( 'S', 'V', 'Q', '3' )
#define ATOM_ZyGo VLC_FOURCC( 'Z', 'y', 'G', 'o' )
#define ATOM_3IV1 VLC_FOURCC( '3', 'I', 'V', '1' )
#define ATOM_3iv1 VLC_FOURCC( '3', 'i', 'v', '1' )
#define ATOM_3IV2 VLC_FOURCC( '3', 'I', 'V', '2' )
#define ATOM_3iv2 VLC_FOURCC( '3', 'i', 'v', '2' )
#define ATOM_3IVD VLC_FOURCC( '3', 'I', 'V', 'D' )
#define ATOM_3ivd VLC_FOURCC( '3', 'i', 'v', 'd' )
#define ATOM_3VID VLC_FOURCC( '3', 'V', 'I', 'D' )
#define ATOM_3vid VLC_FOURCC( '3', 'v', 'i', 'd' )
#define ATOM_h263 VLC_FOURCC( 'h', '2', '6', '3' )
#define ATOM_s263 VLC_FOURCC( 's', '2', '6', '3' )
#define ATOM_DIVX VLC_FOURCC( 'D', 'I', 'V', 'X' )
#define ATOM_XVID VLC_FOURCC( 'X', 'V', 'I', 'D' )
#define ATOM_cvid VLC_FOURCC( 'c', 'v', 'i', 'd' )
#define ATOM_mjpa VLC_FOURCC( 'm', 'j', 'p', 'a' )
#define ATOM_mjpb VLC_FOURCC( 'm', 'j', 'q', 't' )
#define ATOM_mjqt VLC_FOURCC( 'm', 'j', 'h', 't' )
#define ATOM_mjht VLC_FOURCC( 'm', 'j', 'p', 'b' )
#define ATOM_VP31 VLC_FOURCC( 'V', 'P', '3', '1' )
#define ATOM_vp31 VLC_FOURCC( 'v', 'p', '3', '1' )
#define ATOM_h264 VLC_FOURCC( 'h', '2', '6', '4' )
#define ATOM_qdrw VLC_FOURCC( 'q', 'd', 'r', 'w' )

#define ATOM_avc1 VLC_FOURCC( 'a', 'v', 'c', '1' )
#define ATOM_avcC VLC_FOURCC( 'a', 'v', 'c', 'C' )
#define ATOM_m4ds VLC_FOURCC( 'm', '4', 'd', 's' )

#define ATOM_dvc  VLC_FOURCC( 'd', 'v', 'c', ' ' )
#define ATOM_dvp  VLC_FOURCC( 'd', 'v', 'p', ' ' )
#define ATOM_dv5n VLC_FOURCC( 'd', 'v', '5', 'n' )
#define ATOM_dv5p VLC_FOURCC( 'd', 'v', '5', 'p' )
#define ATOM_raw  VLC_FOURCC( 'r', 'a', 'w', ' ' )

#define ATOM_jpeg VLC_FOURCC( 'j', 'p', 'e', 'g' )

#define ATOM_yv12 VLC_FOURCC( 'y', 'v', '1', '2' )
#define ATOM_yuv2 VLC_FOURCC( 'y', 'u', 'v', '2' )

#define ATOM_rmra VLC_FOURCC( 'r', 'm', 'r', 'a' )
#define ATOM_rmda VLC_FOURCC( 'r', 'm', 'd', 'a' )
#define ATOM_rdrf VLC_FOURCC( 'r', 'd', 'r', 'f' )
#define ATOM_rmdr VLC_FOURCC( 'r', 'm', 'd', 'r' )
#define ATOM_rmvc VLC_FOURCC( 'r', 'm', 'v', 'c' )
#define ATOM_rmcd VLC_FOURCC( 'r', 'm', 'c', 'd' )
#define ATOM_rmqu VLC_FOURCC( 'r', 'm', 'q', 'u' )
#define ATOM_alis VLC_FOURCC( 'a', 'l', 'i', 's' )

#define ATOM_gmhd VLC_FOURCC( 'g', 'm', 'h', 'd' )
#define ATOM_wave VLC_FOURCC( 'w', 'a', 'v', 'e' )

#define ATOM_drms VLC_FOURCC( 'd', 'r', 'm', 's' )
#define ATOM_sinf VLC_FOURCC( 's', 'i', 'n', 'f' )
#define ATOM_schi VLC_FOURCC( 's', 'c', 'h', 'i' )
#define ATOM_user VLC_FOURCC( 'u', 's', 'e', 'r' )
#define ATOM_key  VLC_FOURCC( 'k', 'e', 'y', ' ' )
#define ATOM_iviv VLC_FOURCC( 'i', 'v', 'i', 'v' )
#define ATOM_name VLC_FOURCC( 'n', 'a', 'm', 'e' )
#define ATOM_priv VLC_FOURCC( 'p', 'r', 'i', 'v' )
#define ATOM_drmi VLC_FOURCC( 'd', 'r', 'm', 'i' )
#define ATOM_frma VLC_FOURCC( 'f', 'r', 'm', 'a' )
#define ATOM_skcr VLC_FOURCC( 's', 'k', 'c', 'r' )

#define ATOM_text VLC_FOURCC( 't', 'e', 'x', 't' )
#define ATOM_tx3g VLC_FOURCC( 't', 'x', '3', 'g' )
#define ATOM_subp VLC_FOURCC( 's', 'u', 'b', 'p' )
#define ATOM_sbtl VLC_FOURCC( 's', 'b', 't', 'l' )

#define ATOM_0xa9nam VLC_FOURCC( 0xa9, 'n', 'a', 'm' )
#define ATOM_0xa9aut VLC_FOURCC( 0xa9, 'a', 'u', 't' )
#define ATOM_0xa9cpy VLC_FOURCC( 0xa9, 'c', 'p', 'y' )
#define ATOM_0xa9inf VLC_FOURCC( 0xa9, 'i', 'n', 'f' )
#define ATOM_0xa9ART VLC_FOURCC( 0xa9, 'A', 'R', 'T' )
#define ATOM_0xa9des VLC_FOURCC( 0xa9, 'd', 'e', 's' )
#define ATOM_0xa9dir VLC_FOURCC( 0xa9, 'd', 'i', 'r' )
#define ATOM_0xa9cmt VLC_FOURCC( 0xa9, 'c', 'm', 't' )
#define ATOM_0xa9req VLC_FOURCC( 0xa9, 'r', 'e', 'q' )
#define ATOM_0xa9day VLC_FOURCC( 0xa9, 'd', 'a', 'y' )
#define ATOM_0xa9fmt VLC_FOURCC( 0xa9, 'f', 'm', 't' )
#define ATOM_0xa9prd VLC_FOURCC( 0xa9, 'p', 'r', 'd' )
#define ATOM_0xa9prf VLC_FOURCC( 0xa9, 'p', 'r', 'f' )
#define ATOM_0xa9src VLC_FOURCC( 0xa9, 's', 'r', 'c' )
#define ATOM_0xa9alb VLC_FOURCC( 0xa9, 'a', 'l', 'b' )
#define ATOM_0xa9dis VLC_FOURCC( 0xa9, 'd', 'i', 's' )
#define ATOM_0xa9enc VLC_FOURCC( 0xa9, 'e', 'n', 'c' )
#define ATOM_0xa9trk VLC_FOURCC( 0xa9, 't', 'r', 'k' )
#define ATOM_0xa9url VLC_FOURCC( 0xa9, 'u', 'r', 'l' )
#define ATOM_0xa9dsa VLC_FOURCC( 0xa9, 'd', 's', 'a' )
#define ATOM_0xa9hst VLC_FOURCC( 0xa9, 'h', 's', 't' )
#define ATOM_0xa9ope VLC_FOURCC( 0xa9, 'o', 'p', 'e' )
#define ATOM_0xa9wrt VLC_FOURCC( 0xa9, 'w', 'r', 't' )
#define ATOM_0xa9com VLC_FOURCC( 0xa9, 'c', 'o', 'm' )
#define ATOM_0xa9gen VLC_FOURCC( 0xa9, 'g', 'e', 'n' )
#define ATOM_0xa9too VLC_FOURCC( 0xa9, 't', 'o', 'o' )
#define ATOM_0xa9wrn VLC_FOURCC( 0xa9, 'w', 'r', 'n' )
#define ATOM_0xa9swr VLC_FOURCC( 0xa9, 's', 'w', 'r' )
#define ATOM_0xa9mak VLC_FOURCC( 0xa9, 'm', 'a', 'k' )
#define ATOM_0xa9mod VLC_FOURCC( 0xa9, 'm', 'o', 'd' )
#define ATOM_0xa9PRD VLC_FOURCC( 0xa9, 'P', 'R', 'D' )
#define ATOM_0xa9grp VLC_FOURCC( 0xa9, 'g', 'r', 'p' )
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#define ATOM_0xa9lyr VLC_FOURCC( 0xa9, 'l', 'y', 'r' )
#define ATOM_0xa9gen VLC_FOURCC( 0xa9, 'g', 'e', 'n' )
#define ATOM_0xa9st3 VLC_FOURCC( 0xa9, 's', 't', '3' )
#define ATOM_0xa9ard VLC_FOURCC( 0xa9, 'a', 'r', 'd' )
#define ATOM_0xa9arg VLC_FOURCC( 0xa9, 'a', 'r', 'g' )
#define ATOM_0xa9cak VLC_FOURCC( 0xa9, 'c', 'a', 'k' )
#define ATOM_0xa9con VLC_FOURCC( 0xa9, 'c', 'o', 'n' )
#define ATOM_0xa9des VLC_FOURCC( 0xa9, 'd', 'e', 's' )
#define ATOM_0xa9lnt VLC_FOURCC( 0xa9, 'l', 'n', 't' )
#define ATOM_0xa9phg VLC_FOURCC( 0xa9, 'p', 'h', 'g' )
#define ATOM_0xa9pub VLC_FOURCC( 0xa9, 'p', 'u', 'b' )
#define ATOM_0xa9sne VLC_FOURCC( 0xa9, 's', 'n', 'e' )
#define ATOM_0xa9sol VLC_FOURCC( 0xa9, 's', 'o', 'l' )
#define ATOM_0xa9thx VLC_FOURCC( 0xa9, 't', 'h', 'x' )
#define ATOM_0xa9xpd VLC_FOURCC( 0xa9, 'x', 'p', 'd' )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
257
258
259
260
261
262
263
#define ATOM_chpl VLC_FOURCC( 'c', 'h', 'p', 'l' )
#define ATOM_WLOC VLC_FOURCC( 'W', 'L', 'O', 'C' )

#define ATOM_meta VLC_FOURCC( 'm', 'e', 't', 'a' )
#define ATOM_ilst VLC_FOURCC( 'i', 'l', 's', 't' )

#define ATOM_chap VLC_FOURCC( 'c', 'h', 'a', 'p' )
264

265
/* Do you want some debug information on all read boxes ? */
266
//#define MP4_VERBOSE  1
267

Laurent Aimar's avatar
Laurent Aimar committed
268

269
270
271
272
struct MP4_Box_s;


/* uuid Universal Unique IDentifiers */
Laurent Aimar's avatar
Laurent Aimar committed
273
typedef struct UUID_s
274
{
275
    uint8_t b[16];
276
277
278
279
} UUID_t;

/* specific structure for all boxes */

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
typedef struct MP4_Box_data_tfxd_s
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint64_t i_fragment_duration;
    uint64_t i_fragment_abs_time;

} MP4_Box_data_tfxd_t;

typedef struct TfrfBoxDataFields_s
{
    uint64_t i_fragment_duration;
    uint64_t i_fragment_abs_time;

} TfrfBoxDataFields_t;

typedef struct MP4_Box_data_tfrf_s
{
    uint8_t  i_version;
    uint8_t  i_fragment_count;
    uint32_t i_flags;

    TfrfBoxDataFields_t *p_tfrf_data_fields;

} MP4_Box_data_tfrf_t;

307
308
typedef struct MP4_Box_data_ftyp_s
{
309
310
    uint32_t i_major_brand;
    uint32_t i_minor_version;
311

312
313
    uint32_t i_compatible_brands_count;
    uint32_t *i_compatible_brands;
314
315
316
317
318

} MP4_Box_data_ftyp_t;

typedef struct MP4_Box_data_mvhd_s
{
319
320
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
321

322
323
324
325
326
327
328
329
330
331
332
333
    uint64_t i_creation_time;
    uint64_t i_modification_time;
    uint32_t i_timescale;
    uint64_t i_duration;

    int32_t  i_rate;
    int16_t  i_volume;
    int16_t  i_reserved1;
    uint32_t i_reserved2[2];
    int32_t  i_matrix[9];
    uint32_t i_predefined[6];
    uint32_t i_next_track_id;
334
335
336
337
338
339
340
341

} MP4_Box_data_mvhd_t;

#define MP4_TRACK_ENABLED    0x000001
#define MP4_TRACK_IN_MOVIE   0x000002
#define MP4_TRACK_IN_PREVIEW 0x000004
typedef struct MP4_Box_data_tkhd_s
{
342
343
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
344

345
346
347
348
349
    uint64_t i_creation_time;
    uint64_t i_modification_time;
    uint32_t i_track_ID;
    uint32_t i_reserved;
    uint64_t i_duration;
Laurent Aimar's avatar
Laurent Aimar committed
350

351
352
353
    uint32_t i_reserved2[2];
    int16_t  i_layer;
    int16_t  i_predefined;
Laurent Aimar's avatar
Laurent Aimar committed
354

355
356
357
358
359
    int16_t  i_volume;
    uint16_t i_reserved3;
    int32_t  i_matrix[9];
    int32_t  i_width;
    int32_t  i_height;
360
    float    f_rotation;
Laurent Aimar's avatar
Laurent Aimar committed
361

362
363
364
365
} MP4_Box_data_tkhd_t;

typedef struct MP4_Box_data_mdhd_s
{
366
367
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
368

369
370
371
372
    uint64_t i_creation_time;
    uint64_t i_modification_time;
    uint32_t i_timescale;
    uint64_t i_duration;
373
374

    /* one bit for pad */
375
    uint16_t      i_language_code;
376
    /* unsigned int(5)[3] language difference with 0x60*/
Laurent Aimar's avatar
Laurent Aimar committed
377
    unsigned char i_language[3];
378
    uint16_t i_predefined;
379
380
381
382
383

} MP4_Box_data_mdhd_t;

typedef struct MP4_Box_data_hdlr_s
{
384
385
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
386

387
    uint32_t i_predefined;
Laurent Aimar's avatar
Laurent Aimar committed
388
389
    uint32_t i_handler_type; /* "vide" "soun" "hint" "odsm"
                           "crsm" "sdsm" "m7sm" "ocsm"
390
                           "ipsm" "mjsm" */
Laurent Aimar's avatar
Laurent Aimar committed
391

392
393
394
395
396
397
    unsigned char *psz_name; /* in UTF-8 */

} MP4_Box_data_hdlr_t;

typedef struct MP4_Box_data_vmhd_s
{
398
399
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
400

401
    int16_t  i_graphics_mode;
Laurent Aimar's avatar
Laurent Aimar committed
402
    int16_t  i_opcolor[3];
403
404
405
406
407

} MP4_Box_data_vmhd_t;

typedef struct MP4_Box_data_smhd_s
{
408
409
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
410

411
412
    int16_t  i_balance;
    int16_t  i_reserved;
413
414
415
416
417

} MP4_Box_data_smhd_t;

typedef struct MP4_Box_data_hmhd_s
{
418
419
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
420

421
422
423
424
425
    uint16_t i_max_PDU_size;
    uint16_t i_avg_PDU_size;
    uint32_t i_max_bitrate;
    uint32_t i_avg_bitrate;
    uint32_t i_reserved;
426
427
428
429
430

} MP4_Box_data_hmhd_t;

typedef struct MP4_Box_data_url_s
{
431
432
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
433

zorglub's avatar
zorglub committed
434
    char *psz_location;
Laurent Aimar's avatar
Laurent Aimar committed
435

436
437
438
439
} MP4_Box_data_url_t;

typedef struct MP4_Box_data_urn_s
{
440
441
    uint8_t  i_version;
    uint32_t i_flags;
442

zorglub's avatar
zorglub committed
443
444
    char *psz_name;
    char *psz_location;
Laurent Aimar's avatar
Laurent Aimar committed
445

446
447
448
449
} MP4_Box_data_urn_t;

typedef struct MP4_Box_data_dref_s
{
450
451
    uint8_t  i_version;
    uint32_t i_flags;
452

453
    uint32_t i_entry_count;
454
455
456
457
458
/* XXX it's also a container with i_entry_count entry */
} MP4_Box_data_dref_t;

typedef struct MP4_Box_data_stts_s
{
459
460
    uint8_t  i_version;
    uint32_t i_flags;
461

462
463
464
    uint32_t i_entry_count;
    uint32_t *i_sample_count; /* these are array */
    int32_t  *i_sample_delta;
465
466
467
468
469

} MP4_Box_data_stts_t;

typedef struct MP4_Box_data_ctts_s
{
470
471
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
472

473
    uint32_t i_entry_count;
474

475
476
    uint32_t *i_sample_count; /* these are array */
    int32_t  *i_sample_offset;
477
478
479
480
481
482

} MP4_Box_data_ctts_t;


typedef struct MP4_Box_data_sample_soun_s
{
483
484
    uint8_t  i_reserved1[6];
    uint16_t i_data_reference_index;
485

486
487
488
489
490
    //uint32_t i_reserved2[2];
    uint16_t i_qt_version;
    uint16_t i_qt_revision_level;
    uint32_t i_qt_vendor;

491
492
493
494
495
496
    uint16_t i_channelcount;
    uint16_t i_samplesize;
    uint16_t i_predefined;
    uint16_t i_reserved3;
    uint16_t i_sampleratehi; /* timescale of track */
    uint16_t i_sampleratelo;
497
498
499
500
501
502

    /* for version 1 (i_reserved1[0] == 1) */
    uint32_t i_sample_per_packet;
    uint32_t i_bytes_per_packet;
    uint32_t i_bytes_per_frame;
    uint32_t i_bytes_per_sample;
503
504
505
506
507

    /* XXX hack */
    int     i_qt_description;
    uint8_t *p_qt_description;

508
509
510
511
} MP4_Box_data_sample_soun_t;

typedef struct MP4_Box_data_sample_vide_s
{
512
513
    uint8_t  i_reserved1[6];
    uint16_t i_data_reference_index;
514

515
516
517
518
519
520
    uint16_t i_qt_version;
    uint16_t i_qt_revision_level;
    uint32_t i_qt_vendor;

    uint32_t i_qt_temporal_quality;
    uint32_t i_qt_spatial_quality;
521

522
523
    int16_t  i_width;
    int16_t  i_height;
524

525
526
    uint32_t i_horizresolution;
    uint32_t i_vertresolution;
527

528
529
530
    uint32_t i_qt_data_size;
    uint16_t i_qt_frame_count;

531
532
    uint8_t  i_compressorname[32];
    int16_t  i_depth;
533

534
535
536
537
538
539
    int16_t  i_qt_color_table;

    /* XXX hack ImageDescription */
    int     i_qt_image_description;
    uint8_t *p_qt_image_description;

540
541
} MP4_Box_data_sample_vide_t;

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
#define MP4_TEXT_DISPLAY_FLAG_DONT_DISPLAY       (1<<0)
#define MP4_TEXT_DISPLAY_FLAG_AUTO_SCALE         (1<<1)
#define MP4_TEXT_DISPLAY_FLAG_CLIP_TO_TEXT_BOX   (1<<2)
#define MP4_TEXT_DISPLAY_FLAG_USE_MOVIE_BG_COLOR (1<<3)
#define MP4_TEXT_DISPLAY_FLAG_SHRINK_TEXT_BOX_TO_FIT (1<<4)
#define MP4_TEXT_DISPLAY_FLAG_SCROLL_IN          (1<<5)
#define MP4_TEXT_DISPLAY_FLAG_SCROLL_OUT         (1<<6)
#define MP4_TEXT_DISPLAY_FLAG_HORIZONTAL_SCROLL  (1<<7)
#define MP4_TEXT_DISPLAY_FLAG_REVERSE_SCROLL     (1<<8)
#define MP4_TEXT_DISPLAY_FLAG_CONTINUOUS_SCROLL  (1<<9)
#define MP4_TEXT_DISPLAY_FLAG_FLOW_HORIZONTAL    (1<<10)
#define MP4_TEXT_DISPLAY_FLAG_CONTINUOUS_KARAOKE (1<<11)
#define MP4_TEXT_DISPLAY_FLAG_DROP_SHADOW        (1<<12)
#define MP4_TEXT_DISPLAY_FLAG_ANTI_ALIAS         (1<<13)
#define MP4_TEXT_DISPLAY_FLAG_KEYED_TEXT         (1<<14)
#define MP4_TEXT_DISPLAY_FLAG_INVERSE_HILITE     (1<<15)
#define MP4_TEXT_DISPLAY_FLAG_COLOR_HILITE       (1<<16)
#define MP4_TEXT_DISPLAY_FLAG_WRITE_VERTICALLY   (1<<17)

561
562
typedef struct
{
563
564
565
    uint32_t i_reserved1;
    uint16_t i_reserved2;

566
567
    uint16_t i_data_reference_index;

568
569
570
571
572
573
    uint32_t i_display_flags;   // TextDescription and Tx3gDescription

    int8_t i_justification_horizontal; // left(0), centered(1), right(-1)
    int8_t i_justification_vertical;   // top(0), centered(1), bottom(-1)

    uint16_t i_background_color[4];
574

575
576
577
578
    uint16_t i_text_box_top;
    uint16_t i_text_box_left;
    uint16_t i_text_box_bottom;
    uint16_t i_text_box_right;
579

580
    // TODO to complete
581
582
} MP4_Box_data_sample_text_t;

583
584
typedef struct MP4_Box_data_sample_hint_s
{
585
586
    uint8_t  i_reserved1[6];
    uint16_t i_data_reference_index;
587

588
    uint8_t *p_data;
589
590
591
592
593

} MP4_Box_data_sample_hint_t;

typedef struct MP4_Box_data_moviehintinformation_rtp_s
{
594
    uint32_t i_description_format;
595
596
597
598
599
600
601
602
    unsigned char *psz_text;

} MP4_Box_data_moviehintinformation_rtp_t;



typedef struct MP4_Box_data_stsd_s
{
603
604
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
605

606
    uint32_t i_entry_count;
607
608

    /* it contains SampleEntry handled as if it was Box */
Laurent Aimar's avatar
Laurent Aimar committed
609

610
611
612
613
614
} MP4_Box_data_stsd_t;


typedef struct MP4_Box_data_stsz_s
{
615
616
    uint8_t  i_version;
    uint32_t i_flags;
617

618
619
    uint32_t i_sample_size;
    uint32_t i_sample_count;
Laurent Aimar's avatar
Laurent Aimar committed
620

621
    uint32_t *i_entry_size; /* array , empty if i_sample_size != 0 */
622
623
624
625
626

} MP4_Box_data_stsz_t;

typedef struct MP4_Box_data_stz2_s
{
627
628
    uint8_t  i_version;
    uint32_t i_flags;
629

630
631
632
    uint32_t i_sample_size; /* 24 bits */
    uint8_t  i_field_size;
    uint32_t i_sample_count;
633

634
    uint32_t *i_entry_size; /* array: unsigned int(i_field_size) entry_size */
635
636
637
638
639

} MP4_Box_data_stz2_t;

typedef struct MP4_Box_data_stsc_s
{
640
641
    uint8_t  i_version;
    uint32_t i_flags;
642

643
    uint32_t i_entry_count;
644

645
646
647
    uint32_t *i_first_chunk; /* theses are arrays */
    uint32_t *i_samples_per_chunk;
    uint32_t *i_sample_description_index;
Laurent Aimar's avatar
Laurent Aimar committed
648

649
650
651
652
653
} MP4_Box_data_stsc_t;


typedef struct MP4_Box_data_co64_s
{
654
655
    uint8_t  i_version;
    uint32_t i_flags;
656

657
    uint32_t i_entry_count;
Laurent Aimar's avatar
Laurent Aimar committed
658

659
    uint64_t *i_chunk_offset;
660
661
662
663
664
665

} MP4_Box_data_co64_t;


typedef struct MP4_Box_data_stss_s
{
666
667
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
668

669
    uint32_t i_entry_count;
Laurent Aimar's avatar
Laurent Aimar committed
670

671
    uint32_t *i_sample_number;
Laurent Aimar's avatar
Laurent Aimar committed
672

673
674
675
676
} MP4_Box_data_stss_t;

typedef struct MP4_Box_data_stsh_s
{
677
678
    uint8_t  i_version;
    uint32_t i_flags;
679

680
    uint32_t i_entry_count;
Laurent Aimar's avatar
Laurent Aimar committed
681

682
683
    uint32_t *i_shadowed_sample_number;
    uint32_t *i_sync_sample_number;
684
685
686
687
688

} MP4_Box_data_stsh_t;

typedef struct MP4_Box_data_stdp_s
{
689
690
    uint8_t  i_version;
    uint32_t i_flags;
691

692
    uint16_t *i_priority;
693
694
695
696
697

} MP4_Box_data_stdp_t;

typedef struct MP4_Box_data_padb_s
{
698
699
    uint8_t  i_version;
    uint32_t i_flags;
700

701
    uint32_t i_sample_count;
702

703
704
705
706
    uint16_t *i_reserved1;   /* 1bit  */
    uint16_t *i_pad2;        /* 3bits */
    uint16_t *i_reserved2;   /* 1bit  */
    uint16_t *i_pad1;        /* 3bits */
Laurent Aimar's avatar
Laurent Aimar committed
707

708
709
710
711
712
713

} MP4_Box_data_padb_t;


typedef struct MP4_Box_data_elst_s
{
714
715
    uint8_t  i_version;
    uint32_t i_flags;
716

717
    uint32_t i_entry_count;
718

719
720
721
722
    uint64_t *i_segment_duration;
    int64_t  *i_media_time;
    uint16_t *i_media_rate_integer;
    uint16_t *i_media_rate_fraction;
723

Laurent Aimar's avatar
Laurent Aimar committed
724

725
726
727
728
} MP4_Box_data_elst_t;

typedef struct MP4_Box_data_cprt_s
{
729
730
    uint8_t  i_version;
    uint32_t i_flags;
731
732
    /* 1 pad bit */
    unsigned char i_language[3];
Laurent Aimar's avatar
Laurent Aimar committed
733

zorglub's avatar
zorglub committed
734
    char *psz_notice;
735
736
737
738
739
740
} MP4_Box_data_cprt_t;


/* DecoderConfigDescriptor */
typedef struct MP4_descriptor_decoder_config_s
{
741
742
743
744
745
746
    uint8_t i_objectTypeIndication;
    uint8_t i_streamType;
    int     b_upStream;
    int     i_buffer_sizeDB;
    int     i_max_bitrate;
    int     i_avg_bitrate;
Laurent Aimar's avatar
Laurent Aimar committed
747

748
749
    int     i_decoder_specific_info_len;
    uint8_t *p_decoder_specific_info;
750
    /* some other stuff */
Laurent Aimar's avatar
Laurent Aimar committed
751

752
753
754
755
} MP4_descriptor_decoder_config_t;

typedef struct MP4_descriptor_SL_config_s
{
756
757

    int i_dummy; /* ANSI C forbids empty structures */
Laurent Aimar's avatar
Laurent Aimar committed
758

759
760
761
762
763
} MP4_descriptor_SL_config_t;


typedef struct MP4_descriptor_ES_s
{
764
765
766
767
768
    uint16_t i_ES_ID;
    int      b_stream_dependence;
    int      b_url;
    int      b_OCRstream;
    int      i_stream_priority;
769

770
    int      i_depend_on_ES_ID; /* if b_stream_dependence set */
771
772
773

    unsigned char *psz_URL;

774
    uint16_t i_OCR_ES_ID;       /* if b_OCRstream */
775
    MP4_descriptor_decoder_config_t *p_decConfigDescr;
Laurent Aimar's avatar
Laurent Aimar committed
776

777
778
779
780
781
782
783
784
785
    MP4_descriptor_SL_config_t *p_slConfigDescr;

    /* some other stuff ... */

} MP4_descriptor_ES_t;

/* ES descriptor */
typedef struct MP4_Box_data_esds_s
{
786
787
    uint8_t  i_version;
    uint32_t i_flags;
Laurent Aimar's avatar
Laurent Aimar committed
788

789
    MP4_descriptor_ES_t es_descriptor;
Laurent Aimar's avatar
Laurent Aimar committed
790

791
792
793
794
795
} MP4_Box_data_esds_t;


typedef struct MP4_Box_data_dcom_s
{
796
    uint32_t i_algorithm; /* fourcc */
Laurent Aimar's avatar
Laurent Aimar committed
797

798
799
800
801
} MP4_Box_data_dcom_t;

typedef struct MP4_Box_data_cmvd_s
{
802
803
    uint32_t i_uncompressed_size;
    uint32_t i_compressed_size;
804

805
806
    int     b_compressed; /* Set to 1 if compressed data, 0 if uncompressed */
    uint8_t *p_data;
807
808
809
810
811
812

} MP4_Box_data_cmvd_t;

typedef struct MP4_Box_data_cmov_s
{
    struct MP4_Box_s *p_moov; /* uncompressed moov */
813

814
815
} MP4_Box_data_cmov_t;

Iain Wade's avatar
Iain Wade committed
816
817
818
819
820
821
822
823
824
825
826
827
typedef struct
{
    uint32_t i_type;
} MP4_Box_data_frma_t;

typedef struct
{
    uint32_t i_init;
    uint32_t i_encr;
    uint32_t i_decr;
} MP4_Box_data_skcr_t;

828
typedef struct
829
830
831
832
833
834
835
836
837
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint32_t i_ref_type;
    char     *psz_ref;

} MP4_Box_data_rdrf_t;

838
typedef struct
839
840
841
842
843
844
845
846
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint32_t i_rate;

} MP4_Box_data_rmdr_t;

847
typedef struct
848
849
850
851
852
853
854
855
856
857
858
859
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint32_t i_gestaltType;
    uint32_t i_val1;
    uint32_t i_val2;
    uint16_t i_checkType;   /* 0: val1 is version min
                               1: gestalt value & val2 == val1 */

} MP4_Box_data_rmvc_t;

860
typedef struct
861
862
863
864
865
866
867
{
    uint8_t  i_version;
    uint32_t i_flags;


} MP4_Box_data_rmcd_t;

868
typedef struct
869
870
871
872
873
{
    uint32_t i_quality;

} MP4_Box_data_rmqu_t;

874
875
typedef struct MP4_Box_data_mfhd_s
{
F. Yhuel's avatar
F. Yhuel committed
876
877
    uint8_t  i_version;
    uint32_t i_flags;
878

F. Yhuel's avatar
F. Yhuel committed
879
    uint32_t i_sequence_number;
880
881
882

} MP4_Box_data_mfhd_t;

883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
typedef struct MP4_Box_sidx_item_s
{
    bool     b_reference_type;
    uint32_t i_referenced_size;
    uint32_t i_subsegment_duration;
    bool     b_starts_with_SAP;
    uint8_t  i_SAP_type;
    uint32_t i_SAP_delta_time;

} MP4_Box_sidx_item_t;

typedef struct MP4_Box_data_sidx_s
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint32_t i_reference_ID;
    uint32_t i_timescale;
    uint64_t i_earliest_presentation_time;
    uint64_t i_first_offset;
    uint16_t i_reference_count;

    MP4_Box_sidx_item_t *p_items;

} MP4_Box_data_sidx_t;

909
910
911
912
913
#define MP4_TFHD_BASE_DATA_OFFSET     (1LL<<0)
#define MP4_TFHD_SAMPLE_DESC_INDEX    (1LL<<1)
#define MP4_TFHD_DFLT_SAMPLE_DURATION (1LL<<3)
#define MP4_TFHD_DFLT_SAMPLE_SIZE     (1LL<<4)
#define MP4_TFHD_DFLT_SAMPLE_FLAGS    (1LL<<5)
Frédéric Yhuel's avatar
Frédéric Yhuel committed
914
#define MP4_TFHD_DURATION_IS_EMPTY    (1LL<<16)
915
916
917
typedef struct MP4_Box_data_tfhd_s
{
    uint8_t  i_version;
Frédéric Yhuel's avatar
Frédéric Yhuel committed
918
    bool     b_empty;
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
    uint32_t i_flags;
    uint32_t i_track_ID;

    /* optional fields */
    uint64_t i_base_data_offset;
    uint32_t i_sample_description_index;
    uint32_t i_default_sample_duration;
    uint32_t i_default_sample_size;
    uint32_t i_default_sample_flags;

} MP4_Box_data_tfhd_t;

#define MP4_TRUN_DATA_OFFSET         (1<<0)
#define MP4_TRUN_FIRST_FLAGS         (1<<2)
#define MP4_TRUN_SAMPLE_DURATION     (1<<8)
#define MP4_TRUN_SAMPLE_SIZE         (1<<9)
#define MP4_TRUN_SAMPLE_FLAGS        (1<<10)
#define MP4_TRUN_SAMPLE_TIME_OFFSET  (1<<11)
typedef struct MP4_descriptor_trun_sample_t
{
    uint32_t i_duration;
    uint32_t i_size;
    uint32_t i_flags;
    uint32_t i_composition_time_offset;
} MP4_descriptor_trun_sample_t;

typedef struct MP4_Box_data_trun_s
{
    uint8_t  i_version;
    uint32_t i_flags;
    uint32_t i_sample_count;

    /* optional fields */
952
    int32_t i_data_offset;
953
954
955
956
957
958
959
    uint32_t i_first_sample_flags;

    MP4_descriptor_trun_sample_t *p_samples;

} MP4_Box_data_trun_t;


960
961
962
963
964
965
typedef struct
{
    char *psz_text;

} MP4_Box_data_0xa9xxx_t;

966
967
968
969
970
971
typedef struct
{
    char *psz_text;

} MP4_Box_data_name_t;

972
973
974
975
976
977
978
typedef struct
{
    uint32_t i_entry_count;
    uint32_t *i_track_ID;

} MP4_Box_data_tref_generic_t;

979
980
981
982
983
984
985
986
987
988
989
990
991
typedef struct
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint8_t i_chapter;
    struct
    {
        char    *psz_name;
        int64_t  i_start;
    } chapter[256];
} MP4_Box_data_chpl_t;

992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
typedef struct
{
    uint8_t i_version;
    uint8_t i_profile;
    uint8_t i_profile_compatibility;
    uint8_t i_level;

    uint8_t i_reserved1;     /* 6 bits */
    uint8_t i_length_size;

    uint8_t i_reserved2;    /* 3 bits */
    uint8_t  i_sps;
    uint16_t *i_sps_length;
    uint8_t  **sps;

    uint8_t  i_pps;
    uint16_t *i_pps_length;
    uint8_t  **pps;

    /* XXX: Hack raw avcC atom payload */
    int     i_avcC;
    uint8_t *p_avcC;

} MP4_Box_data_avcC_t;

1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
typedef struct
{
    uint8_t i_fscod;
    uint8_t i_bsid;
    uint8_t i_bsmod;
    uint8_t i_acmod;
    uint8_t i_lfeon;
    uint8_t i_bitrate_code;

} MP4_Box_data_dac3_t;

1028
1029
1030
1031
1032
1033
1034
1035
1036
typedef struct
{
    uint8_t i_profile_level;

    int i_vc1;
    uint8_t *p_vc1;

} MP4_Box_data_dvc1_t;

1037
1038
1039
1040
1041
1042
typedef struct
{
    uint16_t i_little_endian;

} MP4_Box_data_enda_t;

1043
1044
1045
1046
1047
1048
typedef struct
{
    uint16_t i_genre;

} MP4_Box_data_gnre_t;

1049
1050
1051
1052
1053
1054
1055
typedef struct
{
    uint32_t i_track_number;
    uint32_t i_track_total;

} MP4_Box_data_trkn_t;

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
typedef struct
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint16_t i_object_descriptor;
    uint8_t i_OD_profile_level;
    uint8_t i_scene_profile_level;
    uint8_t i_audio_profile_level;
    uint8_t i_visual_profile_level;
    uint8_t i_graphics_profile_level;

} MP4_Box_data_iods_t;

1070
1071
1072
1073
1074
1075
typedef struct
{
    uint32_t i_horizontal_spacing;
    uint32_t i_vertical_spacing;
} MP4_Box_data_pasp_t;

1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
typedef struct
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint64_t i_fragment_duration;
} MP4_Box_data_mehd_t;

typedef struct
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint32_t i_track_ID;
    uint32_t i_default_sample_description_index;
    uint32_t i_default_sample_duration;
    uint32_t i_default_sample_size;
    uint32_t i_default_sample_flags;
} MP4_Box_data_trex_t;

typedef struct
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint8_t *p_sample_table;
} MP4_Box_data_sdtp_t;

1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
typedef struct
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint32_t i_size;
} MP4_Box_data_mfro_t;

typedef struct
{
    uint8_t  i_version;
    uint32_t i_flags;

    uint32_t i_track_ID;
    uint32_t i_number_of_entries;

    uint8_t i_length_size_of_traf_num;
    uint8_t i_length_size_of_trun_num;
    uint8_t i_length_size_of_sample_num;

    uint32_t *p_time;
    uint32_t *p_moof_offset;
    uint8_t *p_traf_number;
    uint8_t *p_trun_number;
    uint8_t *p_sample_number;
} MP4_Box_data_tfra_t;

1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
typedef struct
{
    uint64_t i_duration;
    uint32_t i_timescale;
    uint16_t i_track_ID;
    uint8_t  i_es_cat;

    uint32_t FourCC;
    uint32_t Bitrate;
    uint32_t MaxWidth;
    uint32_t MaxHeight;
    uint32_t SamplingRate;
    uint32_t Channels;
    uint32_t BitsPerSample;
    uint32_t AudioTag;
    uint16_t nBlockAlign;
1147
1148
    uint8_t  cpd_len;
    uint8_t  *CodecPrivateData;
1149
1150
} MP4_Box_data_stra_t;

1151
/*
1152
typedef struct MP4_Box_data__s
1153
{
1154
1155
    uint8_t  i_version;
    uint32_t i_flags;
1156
1157
1158
1159
1160
1161
1162
1163
1164

} MP4_Box_data__t;

*/

typedef union MP4_Box_data_s
{
    MP4_Box_data_ftyp_t *p_ftyp;
    MP4_Box_data_mvhd_t *p_mvhd;
1165
    MP4_Box_data_mfhd_t *p_mfhd;
1166
    MP4_Box_data_sidx_t *p_sidx;
1167
1168
    MP4_Box_data_tfhd_t *p_tfhd;
    MP4_Box_data_trun_t *p_trun;
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
    MP4_Box_data_tkhd_t *p_tkhd;
    MP4_Box_data_mdhd_t *p_mdhd;
    MP4_Box_data_hdlr_t *p_hdlr;
    MP4_Box_data_vmhd_t *p_vmhd;
    MP4_Box_data_smhd_t *p_smhd;
    MP4_Box_data_hmhd_t *p_hmhd;
    MP4_Box_data_url_t  *p_url;
    MP4_Box_data_urn_t  *p_urn;
    MP4_Box_data_dref_t *p_dref;
    MP4_Box_data_stts_t *p_stts;
    MP4_Box_data_ctts_t *p_ctts;
    MP4_Box_data_stsd_t *p_stsd;
1181
1182
1183
1184
1185
1186
1187
1188
    MP4_Box_data_sample_vide_t *p_sample_vide;
    MP4_Box_data_sample_soun_t *p_sample_soun;
    MP4_Box_data_sample_text_t *p_sample_text;
    MP4_Box_data_sample_hint_t *p_sample_hint;

    MP4_Box_data_esds_t *p_esds;
    MP4_Box_data_avcC_t *p_avcC;
    MP4_Box_data_dac3_t *p_dac3;
1189
    MP4_Box_data_dvc1_t *p_dvc1;
1190
1191
1192
    MP4_Box_data_enda_t *p_enda;
    MP4_Box_data_gnre_t *p_gnre;
    MP4_Box_data_trkn_t *p_trkn;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
1193
    MP4_Box_data_iods_t *p_iods;
1194
    MP4_Box_data_pasp_t *p_pasp;
1195
1196
1197
    MP4_Box_data_trex_t *p_trex;
    MP4_Box_data_mehd_t *p_mehd;
    MP4_Box_data_sdtp_t *p_sdtp;
1198

1199
1200
    MP4_Box_data_tfra_t *p_tfra;
    MP4_Box_data_mfro_t *p_mfro;
1201
    MP4_Box_data_stra_t *p_stra;
1202

1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
    MP4_Box_data_stsz_t *p_stsz;
    MP4_Box_data_stz2_t *p_stz2;
    MP4_Box_data_stsc_t *p_stsc;
    MP4_Box_data_co64_t *p_co64;
    MP4_Box_data_stss_t *p_stss;
    MP4_Box_data_stsh_t *p_stsh;
    MP4_Box_data_stdp_t *p_stdp;
    MP4_Box_data_padb_t *p_padb;
    MP4_Box_data_elst_t *p_elst;
    MP4_Box_data_cprt_t *p_cprt;

    MP4_Box_data_dcom_t *p_dcom;
    MP4_Box_data_cmvd_t *p_cmvd;
    MP4_Box_data_cmov_t *p_cmov;

    MP4_Box_data_moviehintinformation_rtp_t p_moviehintinformation_rtp;
1219

Iain Wade's avatar
Iain Wade committed
1220
1221
1222
    MP4_Box_data_frma_t *p_frma;
    MP4_Box_data_skcr_t *p_skcr;

1223
1224
1225
1226
1227
    MP4_Box_data_rdrf_t *p_rdrf;
    MP4_Box_data_rmdr_t *p_rmdr;
    MP4_Box_data_rmqu_t *p_rmqu;
    MP4_Box_data_rmvc_t *p_rmvc;

1228
    MP4_Box_data_0xa9xxx_t *p_0xa9xxx;
1229
    MP4_Box_data_chpl_t *p_chpl;
1230
    MP4_Box_data_tref_generic_t *p_tref_generic;
1231
    MP4_Box_data_name_t *p_name;
1232

1233
1234
1235
    MP4_Box_data_tfrf_t *p_tfrf;
    MP4_Box_data_tfxd_t *p_tfxd;

1236
1237
1238
1239
1240
1241
1242
1243
    void                *p_data; /* for unknow type */
} MP4_Box_data_t;



/* the most basic structure */
typedef struct MP4_Box_s
{
1244
    off_t        i_pos;      /* absolute position */
Laurent Aimar's avatar
Laurent Aimar committed
1245

1246
1247
    uint32_t     i_type;
    uint32_t     i_shortsize;
1248

1249
    UUID_t       i_uuid;  /* Set if i_type == "uuid" */
Laurent Aimar's avatar
Laurent Aimar committed
1250

1251
    uint64_t     i_size; /* always set so use it */
1252

Laurent Aimar's avatar
Laurent Aimar committed
1253
    MP4_Box_data_t   data;   /* union of pointers on extended data depending
1254
                                on i_type (or i_usertype) */
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264

    struct MP4_Box_s *p_father; /* pointer on the father Box */

    struct MP4_Box_s *p_first;  /* pointer on the first child Box */
    struct MP4_Box_s *p_last;

    struct MP4_Box_s *p_next;   /* pointer on the next boxes at the same level */

} MP4_Box_t;

1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
/* Contain all information about a chunk */
typedef struct
{
    uint64_t     i_offset; /* absolute position of this chunk in the file */
    uint32_t     i_sample_description_index; /* index for SampleEntry to use */
    uint32_t     i_sample_count; /* how many samples in this chunk */
    uint32_t     i_sample_first; /* index of the first sample in this chunk */
    uint32_t     i_sample; /* index of the next sample to read in this chunk */

    /* now provide way to calculate pts, dts, and offset without too
        much memory and with fast access */

    /* with this we can calculate dts/pts without waste memory */
    uint64_t     i_first_dts;   /* DTS of the first sample */
    uint64_t     i_last_dts;    /* DTS of the last sample */
    uint32_t     *p_sample_count_dts;
    uint32_t     *p_sample_delta_dts;   /* dts delta */

    uint32_t     *p_sample_count_pts;
    int32_t      *p_sample_offset_pts;  /* pts-dts */

    uint8_t      **p_sample_data;     /* set when b_fragmented is true */
    uint32_t     *p_sample_size;
    /* TODO if needed add pts
        but quickly *add* support for edts and seeking */

} mp4_chunk_t;

 /* Contain all needed information for read all track with vlc */
typedef struct
{
    unsigned int i_track_ID;/* this should be unique */

    int b_ok;               /* The track is usable */
    int b_enable;           /* is the trak enable by default */
    bool b_selected;  /* is the trak being played */
    bool b_chapter;   /* True when used for chapter only */

    bool b_mac_encoding;

    es_format_t fmt;
    es_out_id_t *p_es;

    /* display size only ! */
    int i_width;
    int i_height;
    float f_rotation;

    /* more internal data */
    uint64_t        i_timescale;    /* time scale for this track only */
    uint16_t        current_qid;    /* Smooth Streaming quality level ID */

    /* elst */
    int             i_elst;         /* current elst */
    int64_t         i_elst_time;    /* current elst start time (in movie time scale)*/
    MP4_Box_t       *p_elst;        /* elst (could be NULL) */

    /* give the next sample to read, i_chunk is to find quickly where
      the sample is located */
    uint32_t         i_sample;       /* next sample to read */
    uint32_t         i_chunk;        /* chunk where next sample is stored */
    /* total count of chunk and sample */
    uint32_t         i_chunk_count;
    uint32_t         i_sample_count;

    mp4_chunk_t    *chunk; /* always defined  for each chunk */
    mp4_chunk_t    *cchunk; /* current chunk if b_fragmented is true */

    /* sample size, p_sample_size defined only if i_sample_size == 0
        else i_sample_size is size for all sample */
    uint32_t         i_sample_size;
    uint32_t         *p_sample_size; /* XXX perhaps add file offset if take
                                    too much time to do sumations each time*/

    uint32_t     i_sample_first; /* i_sample_first value
                                                   of the next chunk */
    uint64_t     i_first_dts;    /* i_first_dts value
                                                   of the next chunk */

    MP4_Box_t *p_stbl;  /* will contain all timing information */
    MP4_Box_t *p_stsd;  /* will contain all data to initialize decoder */
    MP4_Box_t *p_sample;/* point on actual sdsd */

    bool b_drms;
1349
1350
    bool b_has_non_empty_cchunk;
    bool b_codec_need_restart;
1351
1352
1353
1354
1355
    void      *p_drms;
    MP4_Box_t *p_skcr;

} mp4_track_t;

1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
static inline size_t mp4_box_headersize( MP4_Box_t *p_box )
{
    return 8
        + ( p_box->i_shortsize == 1 ? 8 : 0 )
        + ( p_box->i_type == ATOM_uuid ? 16 : 0 );
}

#define MP4_GETX_PRIVATE(dst, code, size) do { \
    if( (i_read) >= (size) ) { dst = (code); p_peek += (size); } \
    else { dst = 0; }   \
    i_read -= (size);   \
  } while(0)

#define MP4_GET1BYTE( dst )  MP4_GETX_PRIVATE( dst, *p_peek, 1 )
#define MP4_GET2BYTES( dst ) MP4_GETX_PRIVATE( dst, GetWBE(p_peek), 2 )
#define MP4_GET3BYTES( dst ) MP4_GETX_PRIVATE( dst, Get24bBE(p_peek), 3 )
#define MP4_GET4BYTES( dst ) MP4_GETX_PRIVATE( dst, GetDWBE(p_peek), 4 )
#define MP4_GET8BYTES( dst ) MP4_GETX_PRIVATE( dst, GetQWBE(p_peek), 8 )
#define MP4_GETFOURCC( dst ) MP4_GETX_PRIVATE( dst, \
                VLC_FOURCC(p_peek[0],p_peek[1],p_peek[2],p_peek[3]), 4)

#define MP4_GETVERSIONFLAGS( p_void ) \
    MP4_GET1BYTE( p_void->i_version ); \
    MP4_GET3BYTES( p_void->i_flags )

#define MP4_GETSTRINGZ( p_str )         \
    if( (i_read > 0) && (p_peek[0]) )   \
    {       \
        const int __i_copy__ = strnlen( (char*)p_peek, i_read-1 );  \
        p_str = malloc( __i_copy__+1 );               \
        if( p_str ) \
        { \
             memcpy( p_str, p_peek, __i_copy__ ); \
             p_str[__i_copy__] = 0; \
        } \
        p_peek += __i_copy__ + 1;   \
        i_read -= __i_copy__ + 1;   \
    }       \
    else    \
    {       \
        p_str = NULL; \
    }

#define MP4_READBOX_ENTER( MP4_Box_data_TYPE_t ) \
    int64_t  i_read = p_box->i_size; \
    uint8_t *p_peek, *p_buff; \
    int i_actually_read; \
    if( !( p_peek = p_buff = malloc( i_read ) ) ) \
    { \
        return( 0 ); \
    } \
    i_actually_read = stream_Read( p_stream, p_peek, i_read ); \
    if( i_actually_read < 0 || (int64_t)i_actually_read < i_read )\
    { \
        msg_Warn( p_stream, "MP4_READBOX_ENTER: I got %i bytes, "\
        "but I requested %"PRId64"", i_actually_read, i_read );\
        free( p_buff ); \
        return( 0 ); \
    } \
    p_peek += mp4_box_headersize( p_box ); \
    i_read -= mp4_box_headersize( p_box ); \
    if( !( p_box->data.p_data = calloc( 1, sizeof( MP4_Box_data_TYPE_t ) ) ) ) \
    { \
        free( p_buff ); \
        return( 0 ); \
    }

#define MP4_READBOX_EXIT( i_code ) \
    do \
    { \
        free( p_buff ); \
        if( i_read < 0 ) \
            msg_Warn( p_stream, "Not enough data" ); \
        return( i_code ); \
    } while (0)


/* This macro is used when we want to printf the box type
 * APPLE annotation box is :
 *  either 0xA9 + 24-bit ASCII text string (and 0xA9 isn't printable)
 *  either 32-bit ASCII text string
 */
#define MP4_BOX_TYPE_ASCII() ( ((char*)&p_box->i_type)[0] != (char)0xA9 )

static inline uint32_t Get24bBE( const uint8_t *p )
{
    return( ( p[0] <<16 ) + ( p[1] <<8 ) + p[2] );
}

static inline void GetUUID( UUID_t *p_uuid, const uint8_t *p_buff )
{
    memcpy( p_uuid, p_buff, 16 );
}

static inline int CmpUUID( const UUID_t *u1, const UUID_t *u2 )
{
    return memcmp( u1, u2, 16 );
}

static inline void CreateUUID( UUID_t *p_uuid, uint32_t i_fourcc )
{
    /* made by 0xXXXXXXXX-0011-0010-8000-00aa00389b71
            where XXXXXXXX is the fourcc */
    /* FIXME implement this */
    (void)p_uuid;
    (void)i_fourcc;
}

static const UUID_t TfrfBoxUUID = {
                { 0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
                  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f } };

static const UUID_t TfxdBoxUUID = {
                { 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
1470
                  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2 } };
1471

1472
1473
1474
1475
1476
1477
1478
static const UUID_t SmooBoxUUID = {
                { 0xe1, 0xda, 0x72, 0xba, 0x24, 0xd7, 0x43, 0xc3,
                  0xa6, 0xa5, 0x1b, 0x57, 0x59, 0xa1, 0xa9, 0x2c } };

static const UUID_t StraBoxUUID = {
                { 0xb0, 0x3e, 0xf7, 0x70, 0x33, 0xbd, 0x4b, 0xac,
                  0x96, 0xc7, 0xbf, 0x25, 0xf9, 0x7e, 0x24, 0x47 } };
1479

1480
MP4_Box_t *MP4_BoxGetSmooBox( stream_t * );
1481
1482
1483
1484
1485
1486
1487
1488

/*****************************************************************************
 * MP4_BoxGetNextChunk : Parse the entire moof box.
 *****************************************************************************
 *  The first box is a virtual box "root" and is the father of the boxes
 *  'moof' and, possibly, 'sidx'.
 *****************************************************************************/
MP4_Box_t *MP4_BoxGetNextChunk( stream_t * );
1489
1490

/*****************************************************************************
1491
 * MP4_BoxGetRoot : Parse the entire file, and create all boxes in memory
1492
 *****************************************************************************
Laurent Aimar's avatar
Laurent Aimar committed
1493
1494
 *  The first box is a virtual box "root" and is the father for all first
 *  level boxes
1495
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
1496
MP4_Box_t *MP4_BoxGetRoot( stream_t * );
1497
1498
1499

/*****************************************************************************
 * MP4_FreeBox : free memory allocated after read with MP4_ReadBox
1500
 *               or MP4_BoxGetRoot, this means also children boxes
Laurent Aimar's avatar
Laurent Aimar committed
1501
1502
 * XXX : all children have to be allocated by a malloc !! and
 *         p_box is freed
1503
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
1504
void MP4_BoxFree( stream_t *, MP4_Box_t *p_box );
1505
1506
1507

/*****************************************************************************
 * MP4_DumpBoxStructure: print the structure of the p_box
1508
 *****************************************************************************
ivoire's avatar
ivoire committed
1509
 * Useful while debugging
1510
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
1511
void MP4_BoxDumpStructure( stream_t *p_input, MP4_Box_t *p_box );
1512
1513
1514
1515
1516
1517

/*****************************************************************************
 * MP4_BoxGet: find a box given a path relative to p_box
 *****************************************************************************
 * Path Format: . .. / as usual
 *              [number] to specifie box number ex: trak[12]
Laurent Aimar's avatar
Laurent Aimar committed
1518
 *
1519
 * ex: /moov/trak[12]
Laurent Aimar's avatar
Laurent Aimar committed
1520
 *     ../mdia
1521
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
1522
MP4_Box_t *MP4_BoxGet( MP4_Box_t *p_box, const char *psz_fmt, ... );
Laurent Aimar's avatar
Laurent Aimar committed
1523

1524
1525
1526
1527
1528
/*****************************************************************************
 * MP4_BoxCount: find number of box given a path relative to p_box
 *****************************************************************************
 * Path Format: . .. / as usual
 *              [number] to specifie box number ex: trak[12]
Laurent Aimar's avatar
Laurent Aimar committed
1529
 *
1530
 * ex: /moov/trak
Laurent Aimar's avatar
Laurent Aimar committed
1531
 *     ../mdia
1532
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
1533
int MP4_BoxCount( MP4_Box_t *p_box, const char *psz_fmt, ... );
1534

1535
/* Internal functions exposed for MKV demux */
sigmunau's avatar
sigmunau committed
1536
1537
int MP4_ReadBoxCommon( stream_t *p_stream, MP4_Box_t *p_box );
int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box );
1538
void MP4_FreeBox_sample_vide( MP4_Box_t *p_box );
1539
1540

#endif