demux: mp4: add support for AV1
[vlc.git] / modules / demux / mp4 / libmp4.c
1 /*****************************************************************************
2  * libmp4.c : LibMP4 library for mp4 module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001-2004, 2010 VLC authors and VideoLAN
5  *
6  * Author: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include <vlc_common.h>
28 #include <vlc_stream.h>                               /* vlc_stream_Peek*/
29 #include <vlc_strings.h>                              /* vlc_ascii_tolower */
30
31 #ifdef HAVE_ZLIB_H
32 #   include <zlib.h>                                  /* for compressed moov */
33 #endif
34
35 #include "libmp4.h"
36 #include "languages.h"
37 #include <math.h>
38 #include <assert.h>
39 #include <limits.h>
40
41 /* Some assumptions:
42  * The input method HAS to be seekable
43  */
44
45 /* convert 16.16 fixed point to floating point */
46 static double conv_fx( int32_t fx ) {
47     double fp = fx;
48     fp /= 65536.;
49     return fp;
50 }
51
52 /* some functions for mp4 encoding of variables */
53 #ifdef MP4_VERBOSE
54 static char * MP4_Time2Str( stime_t i_duration, uint32_t i_scale )
55 {
56     uint64_t i_time = (i_scale > 0) ? i_duration / i_scale : 0;
57     unsigned h = ( i_time /( 60*60 ) ) % 60;
58     unsigned m = ( i_time / 60 ) % 60;
59     unsigned s = i_time % 60;
60     unsigned ms = (i_scale) ? (1000*i_duration / i_scale) % 1000 : 0;
61
62     char *out;
63     if( asprintf( &out, "%u:%.2u:%.2u:%.3u", h, m, s, ms ) < 0 )
64         return NULL;
65     return out;
66 }
67 #endif
68
69 #define MP4_GETX_PRIVATE(dst, code, size) \
70     do \
71     { \
72         if( (i_read) >= (size) ) \
73         { \
74             dst = (code); \
75             p_peek += (size); \
76             i_read -= (size); \
77         } \
78         else \
79         { \
80             dst = 0; \
81             i_read = 0; \
82         } \
83     } while(0)
84
85 #define MP4_GET1BYTE( dst )  MP4_GETX_PRIVATE( dst, *p_peek, 1 )
86 #define MP4_GET2BYTES( dst ) MP4_GETX_PRIVATE( dst, GetWBE(p_peek), 2 )
87 #define MP4_GET3BYTES( dst ) MP4_GETX_PRIVATE( dst, Get24bBE(p_peek), 3 )
88 #define MP4_GET4BYTES( dst ) MP4_GETX_PRIVATE( dst, GetDWBE(p_peek), 4 )
89 #define MP4_GET8BYTES( dst ) MP4_GETX_PRIVATE( dst, GetQWBE(p_peek), 8 )
90
91 #define MP4_GET2BYTESLE( dst ) MP4_GETX_PRIVATE( dst, GetWLE(p_peek), 2 )
92 #define MP4_GET4BYTESLE( dst ) MP4_GETX_PRIVATE( dst, GetDWLE(p_peek), 4 )
93 #define MP4_GET8BYTESLE( dst ) MP4_GETX_PRIVATE( dst, GetQWLE(p_peek), 8 )
94 #define MP4_GETFOURCC( dst )   MP4_GET4BYTESLE( dst )
95
96 #define MP4_GETVERSIONFLAGS( p_void ) \
97     MP4_GET1BYTE( p_void->i_version ); \
98     MP4_GET3BYTES( p_void->i_flags )
99
100 static char *mp4_getstringz( uint8_t **restrict in, uint64_t *restrict size )
101 {
102     assert( *size <= SSIZE_MAX );
103
104     if( *size == 0 )
105         return NULL;
106
107     if( *in == 0 ) /* Null string stored */
108     {
109         *in += 1;
110         *size -= 1;
111         return NULL;
112     }
113
114     size_t len = strnlen( (const char *)*in, *size );
115     if( len == 0 || len >= *size )
116         return NULL;
117
118     len++;
119
120     char *ret = malloc( len );
121     if( likely(ret != NULL) )
122         memcpy( ret, *in, len );
123     *in += len;
124     *size -= len;
125     return ret;
126 }
127
128 #define MP4_GETSTRINGZ( p_str ) \
129     do \
130         (p_str) = mp4_getstringz( &p_peek, &i_read ); \
131     while(0)
132
133 /* This macro is used when we want to printf the box type
134  * APPLE annotation box is :
135  *  either 0xA9 + 24-bit ASCII text string (and 0xA9 isn't printable)
136  *  either 32-bit ASCII text string
137  */
138 #define MP4_BOX_TYPE_ASCII() ( ((char*)&p_box->i_type)[0] != (char)0xA9 )
139
140 static inline uint32_t Get24bBE( const uint8_t *p )
141 {
142     return( ( p[0] <<16 ) + ( p[1] <<8 ) + p[2] );
143 }
144
145 static inline void GetUUID( UUID_t *p_uuid, const uint8_t *p_buff )
146 {
147     memcpy( p_uuid, p_buff, 16 );
148 }
149
150 static uint8_t *mp4_readbox_enter_common( stream_t *s, MP4_Box_t *box,
151                                           size_t typesize,
152                                           void (*release)( MP4_Box_t * ),
153                                           uint64_t readsize )
154 {
155     const size_t headersize = mp4_box_headersize( box );
156
157     if( unlikely(readsize < headersize) || unlikely(readsize > SSIZE_MAX) )
158         return NULL;
159
160     uint8_t *buf = malloc( readsize );
161     if( unlikely(buf == NULL) )
162         return NULL;
163
164     ssize_t val = vlc_stream_Read( s, buf, readsize );
165     if( (size_t)val != readsize )
166     {
167         msg_Warn( s, "mp4: wanted %"PRIu64" bytes, got %zd", readsize, val );
168         goto error;
169     }
170
171     box->data.p_payload = malloc( typesize );
172     if( unlikely(box->data.p_payload == NULL) )
173         goto error;
174
175     memset( box->data.p_payload, 0, typesize );
176     box->pf_free = release;
177     return buf;
178 error:
179     free( buf );
180     return NULL;
181 }
182
183 static uint8_t *mp4_readbox_enter_partial( stream_t *s, MP4_Box_t *box,
184                                            size_t typesize,
185                                            void (*release)( MP4_Box_t * ),
186                                            uint64_t *restrict readsize )
187 {
188     if( (uint64_t)*readsize > box->i_size )
189         *readsize = box->i_size;
190
191     return mp4_readbox_enter_common( s, box, typesize, release, *readsize );
192 }
193
194 static uint8_t *mp4_readbox_enter( stream_t *s, MP4_Box_t *box,
195                                    size_t typesize,
196                                    void (*release)( MP4_Box_t * ) )
197 {
198     uint64_t readsize = box->i_size;
199     return mp4_readbox_enter_common( s, box, typesize, release, readsize );
200 }
201
202
203 #define MP4_READBOX_ENTER_PARTIAL( MP4_Box_data_TYPE_t, maxread, release ) \
204     uint64_t i_read = (maxread); \
205     uint8_t *p_buff = mp4_readbox_enter_partial( p_stream, p_box, \
206         sizeof( MP4_Box_data_TYPE_t ), release, &i_read ); \
207     if( unlikely(p_buff == NULL) ) \
208         return 0; \
209     const size_t header_size = mp4_box_headersize( p_box ); \
210     uint8_t *p_peek = p_buff + header_size; \
211     i_read -= header_size
212
213 #define MP4_READBOX_ENTER( MP4_Box_data_TYPE_t, release ) \
214     uint8_t *p_buff = mp4_readbox_enter( p_stream, p_box, \
215         sizeof(MP4_Box_data_TYPE_t), release ); \
216     if( unlikely(p_buff == NULL) ) \
217         return 0; \
218     uint64_t i_read = p_box->i_size; \
219     const size_t header_size = mp4_box_headersize( p_box ); \
220     uint8_t *p_peek = p_buff + header_size; \
221     i_read -= header_size
222
223 #define MP4_READBOX_EXIT( i_code ) \
224     do \
225     { \
226         free( p_buff ); \
227         return( i_code ); \
228     } while (0)
229
230 /*****************************************************************************
231  * Some prototypes.
232  *****************************************************************************/
233 static MP4_Box_t *MP4_ReadBox( stream_t *p_stream, MP4_Box_t *p_father );
234 static MP4_Box_t *MP4_ReadBoxUsing( stream_t *p_stream, MP4_Box_t *p_father,
235                                     int(*MP4_ReadBox_function)(stream_t *, MP4_Box_t *) );
236 static int MP4_Box_Read_Specific( stream_t *p_stream, MP4_Box_t *p_box, MP4_Box_t *p_father );
237 static int MP4_PeekBoxHeader( stream_t *p_stream, MP4_Box_t *p_box );
238
239 int MP4_Seek( stream_t *p_stream, uint64_t i_pos )
240 {
241     bool b_canseek = false;
242     if ( vlc_stream_Control( p_stream, STREAM_CAN_SEEK, &b_canseek ) != VLC_SUCCESS ||
243          b_canseek )
244     {
245         /* can seek or don't know */
246         return vlc_stream_Seek( p_stream, i_pos );
247     }
248     /* obviously can't seek then */
249
250     int64_t i_current_pos = vlc_stream_Tell( p_stream );
251     if ( i_current_pos < 0 || i_pos < (uint64_t)i_current_pos )
252         return VLC_EGENERIC;
253
254     size_t i_toread = i_pos - i_current_pos;
255     if( i_toread == 0 )
256         return VLC_SUCCESS;
257     else if( i_toread > (1<<17) )
258         return VLC_EGENERIC;
259
260     if( vlc_stream_Read( p_stream, NULL, i_toread ) != (ssize_t)i_toread )
261         return VLC_EGENERIC;
262     return VLC_SUCCESS;
263 }
264
265 static void MP4_BoxAddChild( MP4_Box_t *p_parent, MP4_Box_t *p_childbox )
266 {
267     if( !p_parent->p_first )
268             p_parent->p_first = p_childbox;
269     else
270             p_parent->p_last->p_next = p_childbox;
271     p_parent->p_last = p_childbox;
272     p_childbox->p_father = p_parent;
273 }
274
275 MP4_Box_t * MP4_BoxExtract( MP4_Box_t **pp_chain, uint32_t i_type )
276 {
277     MP4_Box_t *p_box = *pp_chain;
278     while( p_box )
279     {
280         if( p_box->i_type == i_type )
281         {
282             *pp_chain = p_box->p_next;
283             p_box->p_next = NULL;
284             return p_box;
285         }
286         pp_chain = &p_box->p_next;
287         p_box = p_box->p_next;
288     }
289     return NULL;
290 }
291
292 /* Don't use vlc_stream_Seek directly */
293 #undef vlc_stream_Seek
294 #define vlc_stream_Seek(a,b) __NO__
295
296 /*****************************************************************************
297  * MP4_PeekBoxHeader : Load only common parameters for all boxes
298  *****************************************************************************
299  * p_box need to be an already allocated MP4_Box_t, and all data
300  *  will only be peek not read
301  *
302  * RETURN : 0 if it fail, 1 otherwise
303  *****************************************************************************/
304 static int MP4_PeekBoxHeader( stream_t *p_stream, MP4_Box_t *p_box )
305 {
306     int      i_read;
307     const uint8_t  *p_peek;
308
309     if( ( ( i_read = vlc_stream_Peek( p_stream, &p_peek, 32 ) ) < 8 ) )
310     {
311         return 0;
312     }
313     p_box->i_pos = vlc_stream_Tell( p_stream );
314
315     p_box->data.p_payload = NULL;
316     p_box->p_father = NULL;
317     p_box->p_first  = NULL;
318     p_box->p_last  = NULL;
319     p_box->p_next   = NULL;
320
321     MP4_GET4BYTES( p_box->i_shortsize );
322     MP4_GETFOURCC( p_box->i_type );
323
324     /* Now special case */
325
326     if( p_box->i_shortsize == 1 )
327     {
328         if( i_read < 8 )
329             return 0;
330         /* get the true size on 64 bits */
331         MP4_GET8BYTES( p_box->i_size );
332     }
333     else
334     {
335         p_box->i_size = p_box->i_shortsize;
336         /* XXX size of 0 means that the box extends to end of file */
337     }
338
339     if( UINT64_MAX - p_box->i_size < p_box->i_pos )
340         return 0;
341
342     if( p_box->i_type == ATOM_uuid )
343     {
344         if( i_read < 16 )
345             return 0;
346         /* get extented type on 16 bytes */
347         GetUUID( &p_box->i_uuid, p_peek );
348     }
349
350 #ifdef MP4_ULTRA_VERBOSE
351     if( p_box->i_size )
352     {
353         if MP4_BOX_TYPE_ASCII()
354             msg_Dbg( p_stream, "found Box: %4.4s size %"PRId64" %"PRId64,
355                     (char*)&p_box->i_type, p_box->i_size, p_box->i_pos );
356         else
357             msg_Dbg( p_stream, "found Box: c%3.3s size %"PRId64,
358                     (char*)&p_box->i_type+1, p_box->i_size );
359     }
360 #endif
361
362     return 1;
363 }
364
365 /*****************************************************************************
366  * MP4_ReadBoxRestricted : Reads box from current position
367  *****************************************************************************
368  * if p_box == NULL, box is invalid or failed, position undefined
369  * on success, position is past read box or EOF
370  *****************************************************************************/
371 static MP4_Box_t *MP4_ReadBoxRestricted( stream_t *p_stream, MP4_Box_t *p_father,
372                                          const uint32_t onlytypes[], const uint32_t nottypes[],
373                                          bool *pb_restrictionhit )
374 {
375     MP4_Box_t peekbox = { 0 };
376     if ( !MP4_PeekBoxHeader( p_stream, &peekbox ) )
377         return NULL;
378
379     if( peekbox.i_size < 8 )
380     {
381         msg_Warn( p_stream, "found an invalid sized %"PRIu64" box %4.4s @%"PRIu64 ,
382                   peekbox.i_size, (char *) &peekbox.i_type, vlc_stream_Tell(p_stream) );
383         return NULL;
384     }
385
386     for( size_t i=0; nottypes && nottypes[i]; i++ )
387     {
388         if( nottypes[i] == peekbox.i_type )
389         {
390             *pb_restrictionhit = true;
391             return NULL;
392         }
393     }
394
395     for( size_t i=0; onlytypes && onlytypes[i]; i++ )
396     {
397         if( onlytypes[i] != peekbox.i_type )
398         {
399             *pb_restrictionhit = true;
400             return NULL;
401         }
402     }
403
404     /* if father's size == 0, it means unknown or infinite size,
405      * and we skip the followong check */
406     if( p_father && p_father->i_size > 0 )
407     {
408         const uint64_t i_box_next = peekbox.i_size + peekbox.i_pos;
409         const uint64_t i_father_next = p_father->i_size + p_father->i_pos;
410         /* check if it's within p-father */
411         if( i_box_next > i_father_next )
412         {
413             msg_Warn( p_stream, "out of bound child %4.4s", (char*) &peekbox.i_type );
414             return NULL; /* out of bound */
415         }
416     }
417
418     /* Everything seems OK */
419     MP4_Box_t *p_box = (MP4_Box_t *) malloc( sizeof(MP4_Box_t) );
420     if( !p_box )
421         return NULL;
422     *p_box = peekbox;
423
424     const uint64_t i_next = p_box->i_pos + p_box->i_size;
425     p_box->p_father = p_father;
426     if( MP4_Box_Read_Specific( p_stream, p_box, p_father ) != VLC_SUCCESS )
427     {
428         msg_Warn( p_stream, "Failed reading box %4.4s", (char*) &peekbox.i_type );
429         MP4_BoxFree( p_box );
430         p_box = NULL;
431     }
432
433     /* Check is we consumed all data */
434     if( vlc_stream_Tell( p_stream ) < i_next )
435     {
436         MP4_Seek( p_stream, i_next - 1 ); /*  since past seek can fail when hitting EOF */
437         MP4_Seek( p_stream, i_next );
438         if( vlc_stream_Tell( p_stream ) < i_next - 1 ) /* Truncated box */
439         {
440             msg_Warn( p_stream, "truncated box %4.4s discarded", (char*) &peekbox.i_type );
441             MP4_BoxFree( p_box );
442             p_box = NULL;
443         }
444     }
445
446     if ( p_box )
447         MP4_BoxAddChild( p_father, p_box );
448
449     return p_box;
450 }
451
452 /*****************************************************************************
453  * For all known box a loader is given,
454  * you have to be already read container header
455  * without container size, file position on exit is unknown
456  *****************************************************************************/
457 static int MP4_ReadBoxContainerChildrenIndexed( stream_t *p_stream,
458                MP4_Box_t *p_container, const uint32_t stoplist[],
459                const uint32_t excludelist[], bool b_indexed )
460 {
461     /* Size of root container is set to 0 when unknown, for exemple
462      * with a DASH stream. In that case, we skip the following check */
463     if( (p_container->i_size || p_container->p_father)
464             && ( vlc_stream_Tell( p_stream ) + ((b_indexed)?16:8) >
465         (uint64_t)(p_container->i_pos + p_container->i_size) )
466       )
467     {
468         /* there is no box to load */
469         return 0;
470     }
471
472     uint64_t i_last_pos = 0; /* used to detect read failure loops */
473     const uint64_t i_end = p_container->i_pos + p_container->i_size;
474     MP4_Box_t *p_box = NULL;
475     bool b_onexclude = false;
476     bool b_continue;
477     do
478     {
479         b_continue = false;
480         if ( p_container->i_size )
481         {
482             const uint64_t i_tell = vlc_stream_Tell( p_stream );
483             if( i_tell + ((b_indexed)?16:8) >= i_end )
484                 break;
485         }
486
487         uint32_t i_index = 0;
488         if ( b_indexed )
489         {
490             uint8_t read[8];
491             if ( vlc_stream_Read( p_stream, read, 8 ) < 8 )
492                 break;
493             i_index = GetDWBE(&read[4]);
494         }
495         b_onexclude = false; /* If stopped due exclude list */
496         if( (p_box = MP4_ReadBoxRestricted( p_stream, p_container, NULL, excludelist, &b_onexclude )) )
497         {
498             b_continue = true;
499             p_box->i_index = i_index;
500             for(size_t i=0; stoplist && stoplist[i]; i++)
501             {
502                 if( p_box->i_type == stoplist[i] )
503                     return 1;
504             }
505         }
506
507         const uint64_t i_tell = vlc_stream_Tell( p_stream );
508         if ( p_container->i_size && i_tell >= i_end )
509         {
510             assert( i_tell == i_end );
511             break;
512         }
513
514         if ( !p_box )
515         {
516             /* Continue with next if box fails to load */
517             if( i_last_pos == i_tell )
518                 break;
519             i_last_pos = i_tell;
520             b_continue = true;
521         }
522
523     } while( b_continue );
524
525     /* Always move to end of container */
526     if ( !b_onexclude &&  p_container->i_size )
527     {
528         const uint64_t i_tell = vlc_stream_Tell( p_stream );
529         if ( i_tell != i_end )
530             MP4_Seek( p_stream, i_end );
531     }
532
533     return 1;
534 }
535
536 int MP4_ReadBoxContainerRestricted( stream_t *p_stream, MP4_Box_t *p_container,
537                                     const uint32_t stoplist[], const uint32_t excludelist[] )
538 {
539     return MP4_ReadBoxContainerChildrenIndexed( p_stream, p_container,
540                                                 stoplist, excludelist, false );
541 }
542
543 int MP4_ReadBoxContainerChildren( stream_t *p_stream, MP4_Box_t *p_container,
544                                   const uint32_t stoplist[] )
545 {
546     return MP4_ReadBoxContainerChildrenIndexed( p_stream, p_container,
547                                                 stoplist, NULL, false );
548 }
549
550 static void MP4_BoxOffsetUp( MP4_Box_t *p_box, uint64_t i_offset )
551 {
552     while(p_box)
553     {
554         p_box->i_pos += i_offset;
555         MP4_BoxOffsetUp( p_box->p_first, i_offset );
556         p_box = p_box->p_next;
557     }
558 }
559
560 /* Reads within an already read/in memory box (containers without having to seek) */
561 static int MP4_ReadBoxContainerRawInBox( stream_t *p_stream, MP4_Box_t *p_container,
562                                          uint8_t *p_buffer, uint64_t i_size, uint64_t i_offset )
563 {
564     if(!p_container)
565         return 0;
566     stream_t *p_substream = vlc_stream_MemoryNew( p_stream, p_buffer, i_size,
567                                                   true );
568     if( !p_substream )
569         return 0;
570     MP4_Box_t *p_last = p_container->p_last;
571     MP4_ReadBoxContainerChildren( p_substream, p_container, NULL );
572     vlc_stream_Delete( p_substream );
573     /* do pos fixup */
574     if( p_container )
575     {
576         MP4_Box_t *p_box = p_last ? p_last : p_container->p_first;
577         MP4_BoxOffsetUp(p_box, i_offset);
578     }
579
580     return 1;
581 }
582
583 static int MP4_ReadBoxContainer( stream_t *p_stream, MP4_Box_t *p_container )
584 {
585     if( p_container->i_size &&
586         ( p_container->i_size <= (size_t)mp4_box_headersize(p_container ) + 8 ) )
587     {
588         /* container is empty, 8 stand for the first header in this box */
589         return 1;
590     }
591
592     /* enter box */
593     if ( MP4_Seek( p_stream, p_container->i_pos +
594                       mp4_box_headersize( p_container ) ) )
595         return 0;
596     return MP4_ReadBoxContainerChildren( p_stream, p_container, NULL );
597 }
598
599 static int MP4_ReadBoxSkip( stream_t *p_stream, MP4_Box_t *p_box )
600 {
601     /* XXX sometime moov is hidden in a free box */
602     if( p_box->p_father &&
603         p_box->p_father->i_type == ATOM_root &&
604         p_box->i_type == ATOM_free )
605     {
606         const uint8_t *p_peek;
607         size_t header_size = mp4_box_headersize( p_box ) + 4;
608         vlc_fourcc_t i_fcc;
609
610         ssize_t i_read = vlc_stream_Peek( p_stream, &p_peek, 44 );
611         if( unlikely(i_read < (ssize_t)header_size) )
612             return 0;
613
614         p_peek += header_size;
615         i_read -= header_size;
616
617         if( i_read >= 8 )
618         {
619             i_fcc = VLC_FOURCC( p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
620
621             if( i_fcc == ATOM_cmov || i_fcc == ATOM_mvhd )
622             {
623                 msg_Warn( p_stream, "detected moov hidden in a free box ..." );
624
625                 p_box->i_type = ATOM_foov;
626                 return MP4_ReadBoxContainer( p_stream, p_box );
627             }
628         }
629     }
630
631     /* Nothing to do */
632 #ifdef MP4_ULTRA_VERBOSE
633     if MP4_BOX_TYPE_ASCII()
634         msg_Dbg( p_stream, "skip box: \"%4.4s\"", (char*)&p_box->i_type );
635     else
636         msg_Dbg( p_stream, "skip box: \"c%3.3s\"", (char*)&p_box->i_type+1 );
637 #endif
638     return 1;
639 }
640
641 static int MP4_ReadBox_ilst( stream_t *p_stream, MP4_Box_t *p_box )
642 {
643     if( p_box->i_size < 8 || vlc_stream_Read( p_stream, NULL, 8 ) < 8 )
644         return 0;
645
646     /* Find our handler */
647     if ( !p_box->i_handler && p_box->p_father )
648     {
649         const MP4_Box_t *p_sibling = p_box->p_father->p_first;
650         while( p_sibling )
651         {
652             if ( p_sibling->i_type == ATOM_hdlr && p_sibling->data.p_hdlr )
653             {
654                 p_box->i_handler = p_sibling->data.p_hdlr->i_handler_type;
655                 break;
656             }
657             p_sibling = p_sibling->p_next;
658         }
659     }
660
661     switch( p_box->i_handler )
662     {
663     case 0:
664         msg_Warn( p_stream, "no handler for ilst atom" );
665         return 0;
666     case HANDLER_mdta:
667         return MP4_ReadBoxContainerChildrenIndexed( p_stream, p_box, NULL, NULL, true );
668     case HANDLER_mdir:
669         return MP4_ReadBoxContainerChildren( p_stream, p_box, NULL );
670     default:
671         msg_Warn( p_stream, "Unknown ilst handler type '%4.4s'", (char*)&p_box->i_handler );
672         return 0;
673     }
674 }
675
676 static void MP4_FreeBox_ftyp( MP4_Box_t *p_box )
677 {
678     free( p_box->data.p_ftyp->i_compatible_brands );
679 }
680
681 static int MP4_ReadBox_ftyp( stream_t *p_stream, MP4_Box_t *p_box )
682 {
683     MP4_READBOX_ENTER( MP4_Box_data_ftyp_t, MP4_FreeBox_ftyp );
684
685     MP4_GETFOURCC( p_box->data.p_ftyp->i_major_brand );
686     MP4_GET4BYTES( p_box->data.p_ftyp->i_minor_version );
687
688     p_box->data.p_ftyp->i_compatible_brands_count = i_read / 4;
689     if( p_box->data.p_ftyp->i_compatible_brands_count > 0 )
690     {
691         uint32_t *tab = p_box->data.p_ftyp->i_compatible_brands =
692             vlc_alloc( p_box->data.p_ftyp->i_compatible_brands_count,
693                        sizeof(uint32_t) );
694
695         if( unlikely( tab == NULL ) )
696             MP4_READBOX_EXIT( 0 );
697
698         for( unsigned i = 0; i < p_box->data.p_ftyp->i_compatible_brands_count; i++ )
699         {
700             MP4_GETFOURCC( tab[i] );
701         }
702     }
703     else
704     {
705         p_box->data.p_ftyp->i_compatible_brands = NULL;
706     }
707
708     MP4_READBOX_EXIT( 1 );
709 }
710
711
712 static int MP4_ReadBox_mvhd(  stream_t *p_stream, MP4_Box_t *p_box )
713 {
714     MP4_READBOX_ENTER( MP4_Box_data_mvhd_t, NULL );
715
716     MP4_GETVERSIONFLAGS( p_box->data.p_mvhd );
717
718     if( p_box->data.p_mvhd->i_version )
719     {
720         MP4_GET8BYTES( p_box->data.p_mvhd->i_creation_time );
721         MP4_GET8BYTES( p_box->data.p_mvhd->i_modification_time );
722         MP4_GET4BYTES( p_box->data.p_mvhd->i_timescale );
723         MP4_GET8BYTES( p_box->data.p_mvhd->i_duration );
724     }
725     else
726     {
727         MP4_GET4BYTES( p_box->data.p_mvhd->i_creation_time );
728         MP4_GET4BYTES( p_box->data.p_mvhd->i_modification_time );
729         MP4_GET4BYTES( p_box->data.p_mvhd->i_timescale );
730         MP4_GET4BYTES( p_box->data.p_mvhd->i_duration );
731     }
732     MP4_GET4BYTES( p_box->data.p_mvhd->i_rate );
733     MP4_GET2BYTES( p_box->data.p_mvhd->i_volume );
734     MP4_GET2BYTES( p_box->data.p_mvhd->i_reserved1 );
735
736
737     for( unsigned i = 0; i < 2; i++ )
738     {
739         MP4_GET4BYTES( p_box->data.p_mvhd->i_reserved2[i] );
740     }
741     for( unsigned i = 0; i < 9; i++ )
742     {
743         MP4_GET4BYTES( p_box->data.p_mvhd->i_matrix[i] );
744     }
745     for( unsigned i = 0; i < 6; i++ )
746     {
747         MP4_GET4BYTES( p_box->data.p_mvhd->i_predefined[i] );
748     }
749
750     MP4_GET4BYTES( p_box->data.p_mvhd->i_next_track_id );
751
752
753 #ifdef MP4_VERBOSE
754     char *psz_duration = MP4_Time2Str( p_box->data.p_mvhd->i_duration, p_box->data.p_mvhd->i_timescale );
755     msg_Dbg( p_stream, "read box: \"mvhd\" timescale %"PRIu32" duration %"PRIu64" (%s) rate %.2f volume %.2f",
756                   p_box->data.p_mvhd->i_timescale,
757                   p_box->data.p_mvhd->i_duration,
758                   psz_duration,
759                   (float)p_box->data.p_mvhd->i_rate / (1<<16 ),
760                   (float)p_box->data.p_mvhd->i_volume / 256 );
761     free( psz_duration );
762 #endif
763     MP4_READBOX_EXIT( 1 );
764 }
765
766 static int MP4_ReadBox_mfhd(  stream_t *p_stream, MP4_Box_t *p_box )
767 {
768     MP4_READBOX_ENTER( MP4_Box_data_mfhd_t, NULL );
769
770     MP4_GETVERSIONFLAGS( p_box->data.p_mvhd );
771
772     MP4_GET4BYTES( p_box->data.p_mfhd->i_sequence_number );
773
774 #ifdef MP4_VERBOSE
775     msg_Dbg( p_stream, "read box: \"mfhd\" sequence number %d",
776                   p_box->data.p_mfhd->i_sequence_number );
777 #endif
778     MP4_READBOX_EXIT( 1 );
779 }
780
781 static int MP4_ReadBox_tfxd(  stream_t *p_stream, MP4_Box_t *p_box )
782 {
783     MP4_READBOX_ENTER( MP4_Box_data_tfxd_t, NULL );
784
785     MP4_Box_data_tfxd_t *p_tfxd_data = p_box->data.p_tfxd;
786     MP4_GETVERSIONFLAGS( p_tfxd_data );
787
788     if( p_tfxd_data->i_version == 0 )
789     {
790         MP4_GET4BYTES( p_tfxd_data->i_fragment_abs_time );
791         MP4_GET4BYTES( p_tfxd_data->i_fragment_duration );
792     }
793     else
794     {
795         MP4_GET8BYTES( p_tfxd_data->i_fragment_abs_time );
796         MP4_GET8BYTES( p_tfxd_data->i_fragment_duration );
797     }
798
799 #ifdef MP4_VERBOSE
800     msg_Dbg( p_stream, "read box: \"tfxd\" version %d, flags 0x%x, "\
801             "fragment duration %"PRIu64", fragment abs time %"PRIu64,
802                 p_tfxd_data->i_version,
803                 p_tfxd_data->i_flags,
804                 p_tfxd_data->i_fragment_duration,
805                 p_tfxd_data->i_fragment_abs_time
806            );
807 #endif
808
809     MP4_READBOX_EXIT( 1 );
810 }
811
812 static void MP4_FreeBox_tfrf( MP4_Box_t *p_box )
813 {
814     free( p_box->data.p_tfrf->p_tfrf_data_fields );
815 }
816
817 static int MP4_ReadBox_tfrf(  stream_t *p_stream, MP4_Box_t *p_box )
818 {
819     MP4_READBOX_ENTER( MP4_Box_data_tfxd_t, MP4_FreeBox_tfrf );
820
821     MP4_Box_data_tfrf_t *p_tfrf_data = p_box->data.p_tfrf;
822     MP4_GETVERSIONFLAGS( p_tfrf_data );
823
824     MP4_GET1BYTE( p_tfrf_data->i_fragment_count );
825
826     p_tfrf_data->p_tfrf_data_fields = calloc( p_tfrf_data->i_fragment_count,
827                                               sizeof( TfrfBoxDataFields_t ) );
828     if( !p_tfrf_data->p_tfrf_data_fields )
829         MP4_READBOX_EXIT( 0 );
830
831     for( uint8_t i = 0; i < p_tfrf_data->i_fragment_count; i++ )
832     {
833         TfrfBoxDataFields_t *TfrfBoxDataField = &p_tfrf_data->p_tfrf_data_fields[i];
834         if( p_tfrf_data->i_version == 0 )
835         {
836             MP4_GET4BYTES( TfrfBoxDataField->i_fragment_abs_time );
837             MP4_GET4BYTES( TfrfBoxDataField->i_fragment_duration );
838         }
839         else
840         {
841             MP4_GET8BYTES( TfrfBoxDataField->i_fragment_abs_time );
842             MP4_GET8BYTES( TfrfBoxDataField->i_fragment_duration );
843         }
844     }
845
846 #ifdef MP4_VERBOSE
847     msg_Dbg( p_stream, "read box: \"tfrf\" version %d, flags 0x%x, "\
848             "fragment count %"PRIu8, p_tfrf_data->i_version,
849                 p_tfrf_data->i_flags, p_tfrf_data->i_fragment_count );
850
851     for( uint8_t i = 0; i < p_tfrf_data->i_fragment_count; i++ )
852     {
853         TfrfBoxDataFields_t *TfrfBoxDataField = &p_tfrf_data->p_tfrf_data_fields[i];
854         msg_Dbg( p_stream, "\"tfrf\" fragment duration %"PRIu64", "\
855                                     "fragment abs time %"PRIu64,
856                     TfrfBoxDataField->i_fragment_duration,
857                     TfrfBoxDataField->i_fragment_abs_time );
858     }
859
860 #endif
861
862     MP4_READBOX_EXIT( 1 );
863 }
864
865 static int MP4_ReadBox_XML360( stream_t *p_stream, MP4_Box_t *p_box )
866 {
867     MP4_READBOX_ENTER( MP4_Box_data_360_t, NULL );
868
869     MP4_Box_data_360_t *p_360_data = p_box->data.p_360;
870
871     /* Copy the string for pattern matching as it does not end
872     with a '\0' in the stream. */
873     char *psz_rdf = strndup((char *)p_peek, i_read);
874
875     if ( unlikely( !psz_rdf ) )
876         MP4_READBOX_EXIT( 0 );
877
878     /* Try to find the string "GSpherical:Spherical" because the v1
879     spherical video spec says the tag must be there. */
880
881     if ( strcasestr( psz_rdf, "Gspherical:Spherical" ) )
882         p_360_data->i_projection_mode = PROJECTION_MODE_EQUIRECTANGULAR;
883
884     /* Try to find the stero mode. */
885     if ( strcasestr( psz_rdf, "left-right" ) )
886     {
887         msg_Dbg( p_stream, "Left-right stereo mode" );
888         p_360_data->e_stereo_mode = XML360_STEREOSCOPIC_LEFT_RIGHT;
889     }
890
891     if ( strcasestr( psz_rdf, "top-bottom" ) )
892     {
893         msg_Dbg( p_stream, "Top-bottom stereo mode" );
894         p_360_data->e_stereo_mode = XML360_STEREOSCOPIC_TOP_BOTTOM;
895     }
896
897     free( psz_rdf );
898
899     MP4_READBOX_EXIT( 1 );
900 }
901
902 static int MP4_ReadBox_st3d( stream_t *p_stream, MP4_Box_t *p_box )
903 {
904     MP4_READBOX_ENTER( MP4_Box_data_st3d_t, NULL );
905
906     uint8_t i_version;
907     MP4_GET1BYTE( i_version );
908     if ( i_version != 0 )
909         MP4_READBOX_EXIT( 0 );
910
911     uint32_t i_flags;
912     VLC_UNUSED( i_flags );
913     MP4_GET3BYTES( i_flags );
914
915     MP4_Box_data_st3d_t *p_data = p_box->data.p_st3d;
916     MP4_GET1BYTE( p_data->i_stereo_mode );
917
918     MP4_READBOX_EXIT( 1 );
919 }
920
921 static int MP4_ReadBox_prhd( stream_t *p_stream, MP4_Box_t *p_box )
922 {
923     MP4_READBOX_ENTER( MP4_Box_data_prhd_t, NULL );
924
925     uint8_t i_version;
926     MP4_GET1BYTE( i_version );
927     if (i_version != 0)
928         MP4_READBOX_EXIT( 0 );
929
930     uint32_t i_flags;
931     VLC_UNUSED( i_flags );
932     MP4_GET3BYTES( i_flags );
933
934     MP4_Box_data_prhd_t *p_data = p_box->data.p_prhd;
935     int32_t fixed16_16;
936     MP4_GET4BYTES( fixed16_16 );
937     p_data->f_pose_yaw_degrees   = (float) fixed16_16 / 65536.0f;
938
939     MP4_GET4BYTES( fixed16_16 );
940     p_data->f_pose_pitch_degrees = (float) fixed16_16 / 65536.0f;
941
942     MP4_GET4BYTES( fixed16_16 );
943     p_data->f_pose_roll_degrees  = (float) fixed16_16 / 65536.0f;
944
945     MP4_READBOX_EXIT( 1 );
946 }
947
948 static int MP4_ReadBox_equi( stream_t *p_stream, MP4_Box_t *p_box )
949 {
950     MP4_READBOX_ENTER( MP4_Box_data_equi_t, NULL );
951
952     uint8_t i_version;
953     MP4_GET1BYTE( i_version );
954     if (i_version != 0)
955         MP4_READBOX_EXIT( 0 );
956
957     uint32_t i_flags;
958     VLC_UNUSED( i_flags );
959     MP4_GET3BYTES( i_flags );
960
961     MP4_Box_data_equi_t *p_data = p_box->data.p_equi;
962     MP4_GET4BYTES( p_data->i_projection_bounds_top );
963     MP4_GET4BYTES( p_data->i_projection_bounds_bottom );
964     MP4_GET4BYTES( p_data->i_projection_bounds_left );
965     MP4_GET4BYTES( p_data->i_projection_bounds_right );
966
967     MP4_READBOX_EXIT( 1 );
968 }
969
970 static int MP4_ReadBox_cbmp( stream_t *p_stream, MP4_Box_t *p_box )
971 {
972     MP4_READBOX_ENTER( MP4_Box_data_cbmp_t, NULL );
973
974     uint8_t i_version;
975     MP4_GET1BYTE( i_version );
976     if (i_version != 0)
977         MP4_READBOX_EXIT( 0 );
978
979     uint32_t i_flags;
980     VLC_UNUSED( i_flags );
981     MP4_GET3BYTES( i_flags );
982
983     MP4_Box_data_cbmp_t *p_data = p_box->data.p_cbmp;
984     MP4_GET4BYTES( p_data->i_layout );
985     MP4_GET4BYTES( p_data->i_padding );
986
987     MP4_READBOX_EXIT( 1 );
988 }
989
990 static void MP4_FreeBox_sidx( MP4_Box_t *p_box )
991 {
992     free( p_box->data.p_sidx->p_items );
993 }
994
995 static int MP4_ReadBox_sidx(  stream_t *p_stream, MP4_Box_t *p_box )
996 {
997     MP4_READBOX_ENTER( MP4_Box_data_sidx_t, MP4_FreeBox_sidx );
998
999     MP4_Box_data_sidx_t *p_sidx_data = p_box->data.p_sidx;
1000     MP4_GETVERSIONFLAGS( p_sidx_data );
1001
1002     MP4_GET4BYTES( p_sidx_data->i_reference_ID );
1003     MP4_GET4BYTES( p_sidx_data->i_timescale );
1004
1005     if( p_sidx_data->i_version == 0 )
1006     {
1007         MP4_GET4BYTES( p_sidx_data->i_earliest_presentation_time );
1008         MP4_GET4BYTES( p_sidx_data->i_first_offset );
1009     }
1010     else
1011     {
1012         MP4_GET8BYTES( p_sidx_data->i_earliest_presentation_time );
1013         MP4_GET8BYTES( p_sidx_data->i_first_offset );
1014     }
1015
1016     uint16_t i_reserved, i_count;
1017
1018     VLC_UNUSED(i_reserved);
1019     MP4_GET2BYTES( i_reserved );
1020     MP4_GET2BYTES( i_count );
1021     if( i_count == 0 )
1022         MP4_READBOX_EXIT( 1 );
1023
1024     p_sidx_data->i_reference_count = i_count;
1025     p_sidx_data->p_items = vlc_alloc( i_count, sizeof( MP4_Box_sidx_item_t ) );
1026     if( unlikely(p_sidx_data->p_items == NULL) )
1027         MP4_READBOX_EXIT( 0 );
1028
1029     for( unsigned i = 0; i < i_count; i++ )
1030     {
1031         MP4_Box_sidx_item_t *item = p_sidx_data->p_items + i;
1032         uint32_t tmp;
1033
1034         MP4_GET4BYTES( tmp );
1035         item->b_reference_type = tmp >> 31;
1036         item->i_referenced_size = tmp & 0x7fffffff;
1037         MP4_GET4BYTES( item->i_subsegment_duration );
1038
1039         MP4_GET4BYTES( tmp );
1040         item->b_starts_with_SAP = tmp >> 31;
1041         item->i_SAP_type = (tmp >> 24) & 0x70;
1042         item->i_SAP_delta_time = tmp & 0xfffffff;
1043     }
1044
1045 #ifdef MP4_VERBOSE
1046     msg_Dbg( p_stream, "read box: \"sidx\" version %d, flags 0x%x, "\
1047             "ref_ID %"PRIu32", timescale %"PRIu32", ref_count %"PRIu16", "\
1048             "first subsegmt duration %"PRIu32,
1049                 p_sidx_data->i_version,
1050                 p_sidx_data->i_flags,
1051                 p_sidx_data->i_reference_ID,
1052                 p_sidx_data->i_timescale,
1053                 p_sidx_data->i_reference_count,
1054                 p_sidx_data->p_items[0].i_subsegment_duration
1055            );
1056 #endif
1057
1058     MP4_READBOX_EXIT( 1 );
1059 }
1060
1061 static int MP4_ReadBox_tfhd(  stream_t *p_stream, MP4_Box_t *p_box )
1062 {
1063     MP4_READBOX_ENTER( MP4_Box_data_tfhd_t, NULL );
1064
1065     MP4_GETVERSIONFLAGS( p_box->data.p_tfhd );
1066
1067     if( p_box->data.p_tfhd->i_version != 0 )
1068     {
1069         msg_Warn( p_stream, "'tfhd' box with version != 0. "\
1070                 " Don't know what to do with that, please patch" );
1071         MP4_READBOX_EXIT( 0 );
1072     }
1073
1074     MP4_GET4BYTES( p_box->data.p_tfhd->i_track_ID );
1075
1076     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_DURATION_IS_EMPTY )
1077     {
1078         msg_Dbg( p_stream, "'duration-is-empty' flag is present "\
1079                 "=> no samples for this time interval." );
1080         p_box->data.p_tfhd->b_empty = true;
1081     }
1082     else
1083         p_box->data.p_tfhd->b_empty = false;
1084
1085     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_BASE_DATA_OFFSET )
1086         MP4_GET8BYTES( p_box->data.p_tfhd->i_base_data_offset );
1087     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_SAMPLE_DESC_INDEX )
1088         MP4_GET4BYTES( p_box->data.p_tfhd->i_sample_description_index );
1089     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_DFLT_SAMPLE_DURATION )
1090         MP4_GET4BYTES( p_box->data.p_tfhd->i_default_sample_duration );
1091     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_DFLT_SAMPLE_SIZE )
1092         MP4_GET4BYTES( p_box->data.p_tfhd->i_default_sample_size );
1093     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_DFLT_SAMPLE_FLAGS )
1094         MP4_GET4BYTES( p_box->data.p_tfhd->i_default_sample_flags );
1095
1096 #ifdef MP4_VERBOSE
1097     char psz_base[128] = "\0";
1098     char psz_desc[128] = "\0";
1099     char psz_dura[128] = "\0";
1100     char psz_size[128] = "\0";
1101     char psz_flag[128] = "\0";
1102     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_BASE_DATA_OFFSET )
1103         snprintf(psz_base, sizeof(psz_base), "base offset %"PRId64, p_box->data.p_tfhd->i_base_data_offset);
1104     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_SAMPLE_DESC_INDEX )
1105         snprintf(psz_desc, sizeof(psz_desc), "sample description index %d", p_box->data.p_tfhd->i_sample_description_index);
1106     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_DFLT_SAMPLE_DURATION )
1107         snprintf(psz_dura, sizeof(psz_dura), "sample duration %d", p_box->data.p_tfhd->i_default_sample_duration);
1108     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_DFLT_SAMPLE_SIZE )
1109         snprintf(psz_size, sizeof(psz_size), "sample size %d", p_box->data.p_tfhd->i_default_sample_size);
1110     if( p_box->data.p_tfhd->i_flags & MP4_TFHD_DFLT_SAMPLE_FLAGS )
1111         snprintf(psz_flag, sizeof(psz_flag), "sample flags 0x%x", p_box->data.p_tfhd->i_default_sample_flags);
1112
1113     msg_Dbg( p_stream, "read box: \"tfhd\" version %d flags 0x%x track ID %d %s %s %s %s %s",
1114                 p_box->data.p_tfhd->i_version,
1115                 p_box->data.p_tfhd->i_flags,
1116                 p_box->data.p_tfhd->i_track_ID,
1117                 psz_base, psz_desc, psz_dura, psz_size, psz_flag );
1118 #endif
1119
1120     MP4_READBOX_EXIT( 1 );
1121 }
1122
1123 static void MP4_FreeBox_trun( MP4_Box_t *p_box )
1124 {
1125     free( p_box->data.p_trun->p_samples );
1126 }
1127
1128 static int MP4_ReadBox_trun(  stream_t *p_stream, MP4_Box_t *p_box )
1129 {
1130     uint32_t count;
1131
1132     MP4_READBOX_ENTER( MP4_Box_data_trun_t, MP4_FreeBox_trun );
1133     MP4_Box_data_trun_t *p_trun = p_box->data.p_trun;
1134     MP4_GETVERSIONFLAGS( p_trun );
1135     MP4_GET4BYTES( count );
1136
1137     if( p_trun->i_flags & MP4_TRUN_DATA_OFFSET )
1138         MP4_GET4BYTES( p_trun->i_data_offset );
1139     if( p_trun->i_flags & MP4_TRUN_FIRST_FLAGS )
1140         MP4_GET4BYTES( p_trun->i_first_sample_flags );
1141
1142     uint64_t i_entry_size =
1143         !!(p_trun->i_flags & MP4_TRUN_SAMPLE_DURATION) +
1144         !!(p_trun->i_flags & MP4_TRUN_SAMPLE_SIZE) +
1145         !!(p_trun->i_flags & MP4_TRUN_SAMPLE_FLAGS) +
1146         !!(p_trun->i_flags & MP4_TRUN_SAMPLE_TIME_OFFSET);
1147
1148     if( i_entry_size * 4 * count > i_read )
1149         MP4_READBOX_EXIT( 0 );
1150
1151     p_trun->p_samples = vlc_alloc( count, sizeof(MP4_descriptor_trun_sample_t) );
1152     if ( p_trun->p_samples == NULL )
1153         MP4_READBOX_EXIT( 0 );
1154     p_trun->i_sample_count = count;
1155
1156     for( unsigned int i = 0; i < count; i++ )
1157     {
1158         MP4_descriptor_trun_sample_t *p_sample = &p_trun->p_samples[i];
1159         if( p_trun->i_flags & MP4_TRUN_SAMPLE_DURATION )
1160             MP4_GET4BYTES( p_sample->i_duration );
1161         if( p_trun->i_flags & MP4_TRUN_SAMPLE_SIZE )
1162             MP4_GET4BYTES( p_sample->i_size );
1163         if( p_trun->i_flags & MP4_TRUN_SAMPLE_FLAGS )
1164             MP4_GET4BYTES( p_sample->i_flags );
1165         if( p_trun->i_flags & MP4_TRUN_SAMPLE_TIME_OFFSET )
1166             MP4_GET4BYTES( p_sample->i_composition_time_offset.v0 );
1167     }
1168
1169 #ifdef MP4_ULTRA_VERBOSE
1170     msg_Dbg( p_stream, "read box: \"trun\" version %u flags 0x%x sample count %"PRIu32,
1171                   p_trun->i_version,
1172                   p_trun->i_flags,
1173                   p_trun->i_sample_count );
1174
1175     for( unsigned int i = 0; i < count; i++ )
1176     {
1177         MP4_descriptor_trun_sample_t *p_sample = &p_trun->p_samples[i];
1178         msg_Dbg( p_stream, "read box: \"trun\" sample %4.4u flags 0x%x "\
1179             "duration %"PRIu32" size %"PRIu32" composition time offset %"PRIu32,
1180                         i, p_sample->i_flags, p_sample->i_duration,
1181                         p_sample->i_size, p_sample->i_composition_time_offset );
1182     }
1183 #endif
1184
1185     MP4_READBOX_EXIT( 1 );
1186 }
1187
1188 static int MP4_ReadBox_tfdt( stream_t *p_stream, MP4_Box_t *p_box )
1189 {
1190     MP4_READBOX_ENTER( MP4_Box_data_tfdt_t, NULL );
1191     if( i_read < 8 )
1192         MP4_READBOX_EXIT( 0 );
1193
1194     MP4_GETVERSIONFLAGS( p_box->data.p_tfdt );
1195
1196     if( p_box->data.p_tfdt->i_version == 0 )
1197         MP4_GET4BYTES( p_box->data.p_tfdt->i_base_media_decode_time );
1198     else if( p_box->data.p_tfdt->i_version == 1 )
1199         MP4_GET8BYTES( p_box->data.p_tfdt->i_base_media_decode_time );
1200     else
1201         MP4_READBOX_EXIT( 0 );
1202
1203     MP4_READBOX_EXIT( 1 );
1204 }
1205
1206 static int MP4_ReadBox_tkhd(  stream_t *p_stream, MP4_Box_t *p_box )
1207 {
1208     MP4_READBOX_ENTER( MP4_Box_data_tkhd_t, NULL );
1209
1210     MP4_GETVERSIONFLAGS( p_box->data.p_tkhd );
1211
1212     if( p_box->data.p_tkhd->i_version )
1213     {
1214         MP4_GET8BYTES( p_box->data.p_tkhd->i_creation_time );
1215         MP4_GET8BYTES( p_box->data.p_tkhd->i_modification_time );
1216         MP4_GET4BYTES( p_box->data.p_tkhd->i_track_ID );
1217         MP4_GET4BYTES( p_box->data.p_tkhd->i_reserved );
1218         MP4_GET8BYTES( p_box->data.p_tkhd->i_duration );
1219     }
1220     else
1221     {
1222         MP4_GET4BYTES( p_box->data.p_tkhd->i_creation_time );
1223         MP4_GET4BYTES( p_box->data.p_tkhd->i_modification_time );
1224         MP4_GET4BYTES( p_box->data.p_tkhd->i_track_ID );
1225         MP4_GET4BYTES( p_box->data.p_tkhd->i_reserved );
1226         MP4_GET4BYTES( p_box->data.p_tkhd->i_duration );
1227     }
1228
1229     for( unsigned i = 0; i < 2; i++ )
1230     {
1231         MP4_GET4BYTES( p_box->data.p_tkhd->i_reserved2[i] );
1232     }
1233     MP4_GET2BYTES( p_box->data.p_tkhd->i_layer );
1234     MP4_GET2BYTES( p_box->data.p_tkhd->i_predefined );
1235     MP4_GET2BYTES( p_box->data.p_tkhd->i_volume );
1236     MP4_GET2BYTES( p_box->data.p_tkhd->i_reserved3 );
1237
1238     for( unsigned i = 0; i < 9; i++ )
1239     {
1240         MP4_GET4BYTES( p_box->data.p_tkhd->i_matrix[i] );
1241     }
1242     MP4_GET4BYTES( p_box->data.p_tkhd->i_width );
1243     MP4_GET4BYTES( p_box->data.p_tkhd->i_height );
1244
1245     double rotation = 0;//angle in degrees to be rotated clockwise
1246     double scale[2];    // scale factor; sx = scale[0] , sy = scale[1]
1247     int32_t *matrix = p_box->data.p_tkhd->i_matrix;
1248
1249     scale[0] = sqrt(conv_fx(matrix[0]) * conv_fx(matrix[0]) +
1250                     conv_fx(matrix[3]) * conv_fx(matrix[3]));
1251     scale[1] = sqrt(conv_fx(matrix[1]) * conv_fx(matrix[1]) +
1252                     conv_fx(matrix[4]) * conv_fx(matrix[4]));
1253
1254     if( likely(scale[0] > 0 && scale[1] > 0) )
1255     {
1256         rotation = atan2(conv_fx(matrix[1]) / scale[1],
1257                          conv_fx(matrix[0]) / scale[0]) * 180 / M_PI;
1258         if (rotation < 0)
1259             rotation += 360.;
1260     }
1261
1262     p_box->data.p_tkhd->f_rotation = rotation;
1263
1264 #ifdef MP4_VERBOSE
1265     double translate[2];// amount to translate; tx = translate[0] , ty = translate[1]
1266
1267     translate[0] = conv_fx(matrix[6]);
1268     translate[1] = conv_fx(matrix[7]);
1269
1270     msg_Dbg( p_stream, "read box: \"tkhd\" track #%"PRIu32" duration %"PRIu64" layer %d "
1271                        "volume %3.1f rotation %3.1f scale %.2fx%.2f translate +%.2f+%.2f size %ux%u. "
1272                        "Matrix: %i %i %i %i %i %i %i %i %i",
1273                   p_box->data.p_tkhd->i_track_ID,
1274                   p_box->data.p_tkhd->i_duration,
1275                   p_box->data.p_tkhd->i_layer,
1276                   (float)p_box->data.p_tkhd->i_volume / 256 ,
1277                   rotation,
1278                   scale[0],
1279                   scale[1],
1280                   translate[0],
1281                   translate[1],
1282                   (unsigned)p_box->data.p_tkhd->i_width / BLOCK16x16,
1283                   (unsigned)p_box->data.p_tkhd->i_height / BLOCK16x16,
1284                   p_box->data.p_tkhd->i_matrix[0],
1285                   p_box->data.p_tkhd->i_matrix[1],
1286                   p_box->data.p_tkhd->i_matrix[2],
1287                   p_box->data.p_tkhd->i_matrix[3],
1288                   p_box->data.p_tkhd->i_matrix[4],
1289                   p_box->data.p_tkhd->i_matrix[5],
1290                   p_box->data.p_tkhd->i_matrix[6],
1291                   p_box->data.p_tkhd->i_matrix[7],
1292                   p_box->data.p_tkhd->i_matrix[8] );
1293 #endif
1294     MP4_READBOX_EXIT( 1 );
1295 }
1296
1297 static int MP4_ReadBox_load( stream_t *p_stream, MP4_Box_t *p_box )
1298 {
1299     if ( p_box->i_size != 24 )
1300         return 0;
1301     MP4_READBOX_ENTER( MP4_Box_data_load_t, NULL );
1302     MP4_GET4BYTES( p_box->data.p_load->i_start_time );
1303     MP4_GET4BYTES( p_box->data.p_load->i_duration );
1304     MP4_GET4BYTES( p_box->data.p_load->i_flags );
1305     MP4_GET4BYTES( p_box->data.p_load->i_hints );
1306     MP4_READBOX_EXIT( 1 );
1307 }
1308
1309 static int MP4_ReadBox_mdhd( stream_t *p_stream, MP4_Box_t *p_box )
1310 {
1311     uint16_t i_language;
1312     MP4_READBOX_ENTER( MP4_Box_data_mdhd_t, NULL );
1313
1314     MP4_GETVERSIONFLAGS( p_box->data.p_mdhd );
1315
1316     if( p_box->data.p_mdhd->i_version )
1317     {
1318         MP4_GET8BYTES( p_box->data.p_mdhd->i_creation_time );
1319         MP4_GET8BYTES( p_box->data.p_mdhd->i_modification_time );
1320         MP4_GET4BYTES( p_box->data.p_mdhd->i_timescale );
1321         MP4_GET8BYTES( p_box->data.p_mdhd->i_duration );
1322     }
1323     else
1324     {
1325         MP4_GET4BYTES( p_box->data.p_mdhd->i_creation_time );
1326         MP4_GET4BYTES( p_box->data.p_mdhd->i_modification_time );
1327         MP4_GET4BYTES( p_box->data.p_mdhd->i_timescale );
1328         MP4_GET4BYTES( p_box->data.p_mdhd->i_duration );
1329     }
1330
1331     MP4_GET2BYTES( i_language );
1332     decodeQtLanguageCode( i_language, p_box->data.p_mdhd->rgs_language,
1333                           &p_box->data.p_mdhd->b_mac_encoding );
1334
1335     MP4_GET2BYTES( p_box->data.p_mdhd->i_quality );
1336
1337 #ifdef MP4_VERBOSE
1338     char *psz_duration = MP4_Time2Str( p_box->data.p_mdhd->i_duration, p_box->data.p_mdhd->i_timescale );
1339     msg_Dbg( p_stream, "read box: \"mdhd\" timescale %"PRIu32" duration %"PRIu64" (%s) language %3.3s",
1340                   p_box->data.p_mdhd->i_timescale,
1341                   p_box->data.p_mdhd->i_duration,
1342                   psz_duration,
1343                   (char*) &p_box->data.p_mdhd->rgs_language );
1344     free( psz_duration );
1345 #endif
1346     MP4_READBOX_EXIT( 1 );
1347 }
1348
1349 static void MP4_FreeBox_hdlr( MP4_Box_t *p_box )
1350 {
1351     free( p_box->data.p_hdlr->psz_name );
1352 }
1353
1354 static int MP4_ReadBox_hdlr( stream_t *p_stream, MP4_Box_t *p_box )
1355 {
1356     int32_t i_reserved;
1357     VLC_UNUSED(i_reserved);
1358
1359     MP4_READBOX_ENTER( MP4_Box_data_hdlr_t, MP4_FreeBox_hdlr );
1360
1361     MP4_GETVERSIONFLAGS( p_box->data.p_hdlr );
1362
1363     MP4_GETFOURCC( p_box->data.p_hdlr->i_predefined );
1364     MP4_GETFOURCC( p_box->data.p_hdlr->i_handler_type );
1365
1366     MP4_GET4BYTES( i_reserved );
1367     MP4_GET4BYTES( i_reserved );
1368     MP4_GET4BYTES( i_reserved );
1369     p_box->data.p_hdlr->psz_name = NULL;
1370
1371     if( i_read >= SSIZE_MAX )
1372         MP4_READBOX_EXIT( 0 );
1373
1374     if( i_read > 0 )
1375     {
1376         size_t i_copy;
1377
1378         /* Yes, I love .mp4 :( */
1379         if( p_box->data.p_hdlr->i_predefined == VLC_FOURCC( 'm', 'h', 'l', 'r' ) )
1380         {
1381             uint8_t i_len;
1382
1383             MP4_GET1BYTE( i_len );
1384             i_copy = (i_len <= i_read) ? i_len : i_read;
1385         }
1386         else
1387             i_copy = i_read;
1388
1389         uint8_t *psz = p_box->data.p_hdlr->psz_name = malloc( i_copy + 1 );
1390         if( unlikely( psz == NULL ) )
1391             MP4_READBOX_EXIT( 0 );
1392
1393         memcpy( psz, p_peek, i_copy );
1394         p_box->data.p_hdlr->psz_name[i_copy] = '\0';
1395     }
1396
1397 #ifdef MP4_VERBOSE
1398         msg_Dbg( p_stream, "read box: \"hdlr\" handler type: \"%4.4s\" name: \"%s\"",
1399                    (char*)&p_box->data.p_hdlr->i_handler_type,
1400                    p_box->data.p_hdlr->psz_name );
1401
1402 #endif
1403     MP4_READBOX_EXIT( 1 );
1404 }
1405
1406 static int MP4_ReadBox_vmhd( stream_t *p_stream, MP4_Box_t *p_box )
1407 {
1408     MP4_READBOX_ENTER( MP4_Box_data_vmhd_t, NULL );
1409
1410     MP4_GETVERSIONFLAGS( p_box->data.p_vmhd );
1411
1412     MP4_GET2BYTES( p_box->data.p_vmhd->i_graphics_mode );
1413     for( unsigned i = 0; i < 3; i++ )
1414     {
1415         MP4_GET2BYTES( p_box->data.p_vmhd->i_opcolor[i] );
1416     }
1417
1418 #ifdef MP4_VERBOSE
1419     msg_Dbg( p_stream, "read box: \"vmhd\" graphics-mode %d opcolor (%d, %d, %d)",
1420                       p_box->data.p_vmhd->i_graphics_mode,
1421                       p_box->data.p_vmhd->i_opcolor[0],
1422                       p_box->data.p_vmhd->i_opcolor[1],
1423                       p_box->data.p_vmhd->i_opcolor[2] );
1424 #endif
1425     MP4_READBOX_EXIT( 1 );
1426 }
1427
1428 static int MP4_ReadBox_smhd( stream_t *p_stream, MP4_Box_t *p_box )
1429 {
1430     MP4_READBOX_ENTER( MP4_Box_data_smhd_t, NULL );
1431
1432     MP4_GETVERSIONFLAGS( p_box->data.p_smhd );
1433
1434
1435
1436     MP4_GET2BYTES( p_box->data.p_smhd->i_balance );
1437
1438     MP4_GET2BYTES( p_box->data.p_smhd->i_reserved );
1439
1440 #ifdef MP4_VERBOSE
1441     msg_Dbg( p_stream, "read box: \"smhd\" balance %f",
1442                       (float)p_box->data.p_smhd->i_balance / 256 );
1443 #endif
1444     MP4_READBOX_EXIT( 1 );
1445 }
1446
1447
1448 static int MP4_ReadBox_hmhd( stream_t *p_stream, MP4_Box_t *p_box )
1449 {
1450     MP4_READBOX_ENTER( MP4_Box_data_hmhd_t, NULL );
1451
1452     MP4_GETVERSIONFLAGS( p_box->data.p_hmhd );
1453
1454     MP4_GET2BYTES( p_box->data.p_hmhd->i_max_PDU_size );
1455     MP4_GET2BYTES( p_box->data.p_hmhd->i_avg_PDU_size );
1456
1457     MP4_GET4BYTES( p_box->data.p_hmhd->i_max_bitrate );
1458     MP4_GET4BYTES( p_box->data.p_hmhd->i_avg_bitrate );
1459
1460     MP4_GET4BYTES( p_box->data.p_hmhd->i_reserved );
1461
1462 #ifdef MP4_VERBOSE
1463     msg_Dbg( p_stream, "read box: \"hmhd\" maxPDU-size %d avgPDU-size %d max-bitrate %d avg-bitrate %d",
1464                       p_box->data.p_hmhd->i_max_PDU_size,
1465                       p_box->data.p_hmhd->i_avg_PDU_size,
1466                       p_box->data.p_hmhd->i_max_bitrate,
1467                       p_box->data.p_hmhd->i_avg_bitrate );
1468 #endif
1469     MP4_READBOX_EXIT( 1 );
1470 }
1471
1472 static void MP4_FreeBox_url( MP4_Box_t *p_box )
1473 {
1474     free( p_box->data.p_url->psz_location );
1475 }
1476
1477 static int MP4_ReadBox_url( stream_t *p_stream, MP4_Box_t *p_box )
1478 {
1479     MP4_READBOX_ENTER( MP4_Box_data_url_t, MP4_FreeBox_url );
1480
1481     MP4_GETVERSIONFLAGS( p_box->data.p_url );
1482     MP4_GETSTRINGZ( p_box->data.p_url->psz_location );
1483
1484 #ifdef MP4_VERBOSE
1485     msg_Dbg( p_stream, "read box: \"url\" url: %s",
1486                        p_box->data.p_url->psz_location );
1487
1488 #endif
1489     MP4_READBOX_EXIT( 1 );
1490 }
1491
1492 static void MP4_FreeBox_urn( MP4_Box_t *p_box )
1493 {
1494     free( p_box->data.p_urn->psz_name );
1495     free( p_box->data.p_urn->psz_location );
1496 }
1497
1498 static int MP4_ReadBox_urn( stream_t *p_stream, MP4_Box_t *p_box )
1499 {
1500     MP4_READBOX_ENTER( MP4_Box_data_urn_t, MP4_FreeBox_urn );
1501
1502     MP4_GETVERSIONFLAGS( p_box->data.p_urn );
1503
1504     MP4_GETSTRINGZ( p_box->data.p_urn->psz_name );
1505     MP4_GETSTRINGZ( p_box->data.p_urn->psz_location );
1506
1507 #ifdef MP4_VERBOSE
1508     msg_Dbg( p_stream, "read box: \"urn\" name %s location %s",
1509                       p_box->data.p_urn->psz_name,
1510                       p_box->data.p_urn->psz_location );
1511 #endif
1512     MP4_READBOX_EXIT( 1 );
1513 }
1514
1515 static int MP4_ReadBox_LtdContainer( stream_t *p_stream, MP4_Box_t *p_box )
1516 {
1517     MP4_READBOX_ENTER_PARTIAL( MP4_Box_data_lcont_t, 16, NULL );
1518     if( i_read < 8 )
1519         MP4_READBOX_EXIT( 0 );
1520
1521     MP4_GETVERSIONFLAGS( p_box->data.p_lcont );
1522     if( p_box->data.p_lcont->i_version != 0 )
1523         MP4_READBOX_EXIT( 0 );
1524     MP4_GET4BYTES( p_box->data.p_lcont->i_entry_count );
1525
1526     uint32_t i_entry = 0;
1527     i_read = p_box->i_size - 16;
1528     while (i_read > 8 && i_entry < p_box->data.p_lcont->i_entry_count )
1529     {
1530         MP4_Box_t *p_childbox = MP4_ReadBox( p_stream, p_box );
1531         if( !p_childbox )
1532             break;
1533         MP4_BoxAddChild( p_box, p_childbox );
1534         i_entry++;
1535
1536         if( i_read < p_childbox->i_size )
1537             MP4_READBOX_EXIT( 0 );
1538
1539         i_read -= p_childbox->i_size;
1540     }
1541
1542     if (i_entry != p_box->data.p_lcont->i_entry_count)
1543         p_box->data.p_lcont->i_entry_count = i_entry;
1544
1545 #ifdef MP4_VERBOSE
1546     msg_Dbg( p_stream, "read box: \"%4.4s\" entry-count %d", (char *)&p_box->i_type,
1547                         p_box->data.p_lcont->i_entry_count );
1548
1549 #endif
1550
1551     if ( MP4_Seek( p_stream, p_box->i_pos + p_box->i_size ) )
1552         MP4_READBOX_EXIT( 0 );
1553
1554     MP4_READBOX_EXIT( 1 );
1555 }
1556
1557 static void MP4_FreeBox_stts( MP4_Box_t *p_box )
1558 {
1559     free( p_box->data.p_stts->pi_sample_count );
1560     free( p_box->data.p_stts->pi_sample_delta );
1561 }
1562
1563 static int MP4_ReadBox_stts( stream_t *p_stream, MP4_Box_t *p_box )
1564 {
1565     uint32_t count;
1566
1567     MP4_READBOX_ENTER( MP4_Box_data_stts_t, MP4_FreeBox_stts );
1568
1569     MP4_GETVERSIONFLAGS( p_box->data.p_stts );
1570     MP4_GET4BYTES( count );
1571
1572     if( UINT64_C(8) * count > i_read )
1573     {
1574         /*count = i_read / 8;*/
1575         MP4_READBOX_EXIT( 0 );
1576     }
1577
1578     p_box->data.p_stts->pi_sample_count = vlc_alloc( count, sizeof(uint32_t) );
1579     p_box->data.p_stts->pi_sample_delta = vlc_alloc( count, sizeof(int32_t) );
1580     p_box->data.p_stts->i_entry_count = count;
1581
1582     if( p_box->data.p_stts->pi_sample_count == NULL
1583      || p_box->data.p_stts->pi_sample_delta == NULL )
1584     {
1585         MP4_READBOX_EXIT( 0 );
1586     }
1587
1588     for( uint32_t i = 0; i < count; i++ )
1589     {
1590         MP4_GET4BYTES( p_box->data.p_stts->pi_sample_count[i] );
1591         MP4_GET4BYTES( p_box->data.p_stts->pi_sample_delta[i] );
1592     }
1593
1594 #ifdef MP4_VERBOSE
1595     msg_Dbg( p_stream, "read box: \"stts\" entry-count %d",
1596                       p_box->data.p_stts->i_entry_count );
1597
1598 #endif
1599     MP4_READBOX_EXIT( 1 );
1600 }
1601
1602
1603 static void MP4_FreeBox_ctts( MP4_Box_t *p_box )
1604 {
1605     free( p_box->data.p_ctts->pi_sample_count );
1606     free( p_box->data.p_ctts->pi_sample_offset );
1607 }
1608
1609 static int MP4_ReadBox_ctts( stream_t *p_stream, MP4_Box_t *p_box )
1610 {
1611     uint32_t count;
1612
1613     MP4_READBOX_ENTER( MP4_Box_data_ctts_t, MP4_FreeBox_ctts );
1614
1615     MP4_GETVERSIONFLAGS( p_box->data.p_ctts );
1616     MP4_GET4BYTES( count );
1617
1618     if( UINT64_C(8) * count > i_read )
1619         MP4_READBOX_EXIT( 0 );
1620
1621     p_box->data.p_ctts->pi_sample_count = vlc_alloc( count, sizeof(uint32_t) );
1622     p_box->data.p_ctts->pi_sample_offset = vlc_alloc( count, sizeof(int32_t) );
1623     if( unlikely(p_box->data.p_ctts->pi_sample_count == NULL
1624               || p_box->data.p_ctts->pi_sample_offset == NULL) )
1625         MP4_READBOX_EXIT( 0 );
1626     p_box->data.p_ctts->i_entry_count = count;
1627
1628     for( uint32_t i = 0; i < count; i++ )
1629     {
1630         MP4_GET4BYTES( p_box->data.p_ctts->pi_sample_count[i] );
1631         MP4_GET4BYTES( p_box->data.p_ctts->pi_sample_offset[i] );
1632     }
1633
1634 #ifdef MP4_VERBOSE
1635     msg_Dbg( p_stream, "read box: \"ctts\" entry-count %"PRIu32, count );
1636
1637 #endif
1638     MP4_READBOX_EXIT( 1 );
1639 }
1640
1641 static int MP4_ReadBox_cslg( stream_t *p_stream, MP4_Box_t *p_box )
1642 {
1643     MP4_READBOX_ENTER( MP4_Box_data_cslg_t, NULL );
1644
1645     unsigned i_version, i_flags;
1646     MP4_GET1BYTE( i_version );
1647     MP4_GET3BYTES( i_flags );
1648     VLC_UNUSED(i_flags);
1649
1650     if( i_version > 1 )
1651         MP4_READBOX_EXIT( 0 );
1652
1653 #define READ_CSLG(readbytes) {\
1654     readbytes( p_box->data.p_cslg->ct_to_dts_shift );\
1655     readbytes( p_box->data.p_cslg->i_least_delta );\
1656     readbytes( p_box->data.p_cslg->i_max_delta );\
1657     readbytes( p_box->data.p_cslg->i_composition_starttime );\
1658     readbytes( p_box->data.p_cslg->i_composition_endtime ); }
1659
1660     if( i_version == 0 )
1661         READ_CSLG(MP4_GET4BYTES)
1662     else
1663         READ_CSLG(MP4_GET8BYTES)
1664
1665     MP4_READBOX_EXIT( 1 );
1666 }
1667
1668 static uint64_t MP4_ReadLengthDescriptor( uint8_t **restrict bufp,
1669                                           uint64_t *restrict lenp )
1670 {
1671     unsigned char *buf = *bufp;
1672     uint64_t len = *lenp;
1673     unsigned char b;
1674     uint64_t value = 0;
1675
1676     do
1677     {
1678         if (unlikely(len == 0))
1679             return -1; /* end of bit stream */
1680         if (unlikely(value > (UINT64_MAX >> 7)))
1681             return -1; /* integer overflow */
1682
1683         b = *(buf++);
1684         len--;
1685         value = (value << 7) + (b & 0x7f);
1686     }
1687     while (b & 0x80);
1688
1689     *bufp = buf;
1690     *lenp = len;
1691     return value;
1692 }
1693
1694
1695 static void MP4_FreeBox_esds( MP4_Box_t *p_box )
1696 {
1697     free( p_box->data.p_esds->es_descriptor.psz_URL );
1698     if( p_box->data.p_esds->es_descriptor.p_decConfigDescr )
1699     {
1700         free( p_box->data.p_esds->es_descriptor.p_decConfigDescr->p_decoder_specific_info );
1701         free( p_box->data.p_esds->es_descriptor.p_decConfigDescr );
1702     }
1703 }
1704
1705 static int MP4_ReadBox_esds( stream_t *p_stream, MP4_Box_t *p_box )
1706 {
1707 #define es_descriptor p_box->data.p_esds->es_descriptor
1708     uint64_t i_len;
1709     unsigned int i_flags;
1710     unsigned int i_type;
1711
1712     MP4_READBOX_ENTER( MP4_Box_data_esds_t, MP4_FreeBox_esds );
1713
1714     MP4_GETVERSIONFLAGS( p_box->data.p_esds );
1715
1716
1717     MP4_GET1BYTE( i_type );
1718     if( i_type == 0x03 ) /* MP4ESDescrTag ISO/IEC 14496-1 8.3.3 */
1719     {
1720         i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );
1721         if( unlikely(i_len == UINT64_C(-1)) )
1722             MP4_READBOX_EXIT( 0 );
1723
1724 #ifdef MP4_VERBOSE
1725         msg_Dbg( p_stream, "found esds MPEG4ESDescr (%"PRIu64" bytes)",
1726                  i_len );
1727 #endif
1728
1729         MP4_GET2BYTES( es_descriptor.i_ES_ID );
1730         MP4_GET1BYTE( i_flags );
1731         es_descriptor.b_stream_dependence = ( (i_flags&0x80) != 0);
1732         es_descriptor.b_url = ( (i_flags&0x40) != 0);
1733         es_descriptor.b_OCRstream = ( (i_flags&0x20) != 0);
1734
1735         es_descriptor.i_stream_priority = i_flags&0x1f;
1736         if( es_descriptor.b_stream_dependence )
1737         {
1738             MP4_GET2BYTES( es_descriptor.i_depend_on_ES_ID );
1739         }
1740         if( es_descriptor.b_url && i_read > 0 )
1741         {
1742             uint8_t i_url;
1743
1744             MP4_GET1BYTE( i_url );
1745             if( i_url > i_read )
1746                 MP4_READBOX_EXIT( 1 );
1747             es_descriptor.psz_URL = malloc( (unsigned) i_url + 1 );
1748             if( es_descriptor.psz_URL )
1749             {
1750                 memcpy( es_descriptor.psz_URL, p_peek, i_url );
1751                 es_descriptor.psz_URL[i_url] = 0;
1752             }
1753             p_peek += i_url;
1754             i_read -= i_url;
1755         }
1756         else
1757         {
1758             es_descriptor.psz_URL = NULL;
1759         }
1760         if( es_descriptor.b_OCRstream )
1761         {
1762             MP4_GET2BYTES( es_descriptor.i_OCR_ES_ID );
1763         }
1764         MP4_GET1BYTE( i_type ); /* get next type */
1765     }
1766
1767     if( i_type != 0x04)/* MP4DecConfigDescrTag ISO/IEC 14496-1 8.3.4 */
1768     {
1769          es_descriptor.p_decConfigDescr = NULL;
1770          MP4_READBOX_EXIT( 1 ); /* rest isn't interesting up to now */
1771     }
1772
1773     i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );
1774     if( unlikely(i_len == UINT64_C(-1)) )
1775         MP4_READBOX_EXIT( 0 );
1776 #ifdef MP4_VERBOSE
1777     msg_Dbg( p_stream, "found esds MP4DecConfigDescr (%"PRIu64" bytes)",
1778              i_len );
1779 #endif
1780
1781     es_descriptor.p_decConfigDescr =
1782             calloc( 1, sizeof( MP4_descriptor_decoder_config_t ));
1783     if( unlikely( es_descriptor.p_decConfigDescr == NULL ) )
1784         MP4_READBOX_EXIT( 0 );
1785
1786     MP4_GET1BYTE( es_descriptor.p_decConfigDescr->i_objectProfileIndication );
1787     MP4_GET1BYTE( i_flags );
1788     es_descriptor.p_decConfigDescr->i_streamType = i_flags >> 2;
1789     es_descriptor.p_decConfigDescr->b_upStream = ( i_flags >> 1 )&0x01;
1790     MP4_GET3BYTES( es_descriptor.p_decConfigDescr->i_buffer_sizeDB );
1791     MP4_GET4BYTES( es_descriptor.p_decConfigDescr->i_max_bitrate );
1792     MP4_GET4BYTES( es_descriptor.p_decConfigDescr->i_avg_bitrate );
1793     MP4_GET1BYTE( i_type );
1794     if( i_type !=  0x05 )/* MP4DecSpecificDescrTag ISO/IEC 14496-1 8.3.5 */
1795     {
1796         es_descriptor.p_decConfigDescr->i_decoder_specific_info_len = 0;
1797         es_descriptor.p_decConfigDescr->p_decoder_specific_info  = NULL;
1798         MP4_READBOX_EXIT( 1 );
1799     }
1800
1801     i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );
1802     if( unlikely(i_len == UINT64_C(-1)) )
1803         MP4_READBOX_EXIT( 0 );
1804 #ifdef MP4_VERBOSE
1805     msg_Dbg( p_stream, "found esds MP4DecSpecificDescr (%"PRIu64" bytes)",
1806              i_len );
1807 #endif
1808     if( i_len > i_read )
1809         MP4_READBOX_EXIT( 0 );
1810
1811     es_descriptor.p_decConfigDescr->i_decoder_specific_info_len = i_len;
1812     es_descriptor.p_decConfigDescr->p_decoder_specific_info = malloc( i_len );
1813     if( unlikely( es_descriptor.p_decConfigDescr->p_decoder_specific_info == NULL ) )
1814         MP4_READBOX_EXIT( 0 );
1815
1816     memcpy( es_descriptor.p_decConfigDescr->p_decoder_specific_info,
1817             p_peek, i_len );
1818
1819     MP4_READBOX_EXIT( 1 );
1820 #undef es_descriptor
1821 }
1822
1823 static void MP4_FreeBox_av1C( MP4_Box_t *p_box )
1824 {
1825     MP4_Box_data_av1C_t *p_av1C = p_box->data.p_av1C;
1826     free( p_av1C->p_av1C );
1827 }
1828
1829 static int MP4_ReadBox_av1C( stream_t *p_stream, MP4_Box_t *p_box )
1830 {
1831     MP4_Box_data_av1C_t *p_av1C;
1832
1833     MP4_READBOX_ENTER( MP4_Box_data_av1C_t, MP4_FreeBox_av1C );
1834     p_av1C = p_box->data.p_av1C;
1835
1836     if( i_read < 4 ||
1837        p_peek[0] != 0x81 ) /* marker / version */
1838         MP4_READBOX_EXIT( 0 );
1839
1840     p_av1C->p_av1C = malloc( i_read );
1841     if( p_av1C->p_av1C )
1842     {
1843         memcpy( p_av1C->p_av1C, p_peek, i_read );
1844         p_av1C->i_av1C = i_read;
1845     }
1846
1847     uint8_t i_8b;
1848     MP4_GET1BYTE( i_8b ); /* marker / version */
1849
1850     MP4_GET1BYTE( i_8b );
1851     p_av1C->i_profile = i_8b >> 5;
1852     p_av1C->i_level = i_8b & 0x1F;
1853
1854     MP4_GET1BYTE( i_8b );
1855     MP4_GET1BYTE( i_8b );
1856
1857     if( i_8b & 0x10 ) /* delay flag */
1858         p_av1C->i_presentation_delay = 1 + (i_8b & 0x0F);
1859     else
1860         p_av1C->i_presentation_delay = 0;
1861
1862     MP4_READBOX_EXIT( 1 );
1863 }
1864
1865 static void MP4_FreeBox_avcC( MP4_Box_t *p_box )
1866 {
1867     MP4_Box_data_avcC_t *p_avcC = p_box->data.p_avcC;
1868     free( p_avcC->p_avcC );
1869 }
1870
1871 static int MP4_ReadBox_avcC( stream_t *p_stream, MP4_Box_t *p_box )
1872 {
1873     MP4_Box_data_avcC_t *p_avcC;
1874
1875     MP4_READBOX_ENTER( MP4_Box_data_avcC_t, MP4_FreeBox_avcC );
1876     p_avcC = p_box->data.p_avcC;
1877
1878     if( i_read > 0 )
1879     {
1880         p_avcC->p_avcC = malloc( i_read );
1881         if( p_avcC->p_avcC )
1882         {
1883             memcpy( p_avcC->p_avcC, p_peek, i_read );
1884             p_avcC->i_avcC = i_read;
1885         }
1886     }
1887
1888     MP4_GET1BYTE( p_avcC->i_version );
1889     MP4_GET1BYTE( p_avcC->i_profile );
1890     MP4_GET1BYTE( p_avcC->i_profile_compatibility );
1891     MP4_GET1BYTE( p_avcC->i_level );
1892 #ifdef MP4_VERBOSE
1893     msg_Dbg( p_stream,
1894              "read box: \"avcC\" version=%d profile=0x%x level=0x%x",
1895              p_avcC->i_version, p_avcC->i_profile, p_avcC->i_level );
1896 #endif
1897     MP4_READBOX_EXIT( 1 );
1898 }
1899
1900 static void MP4_FreeBox_vpcC( MP4_Box_t *p_box )
1901 {
1902     free( p_box->data.p_vpcC->p_codec_init_data );
1903 }
1904
1905 static int MP4_ReadBox_vpcC( stream_t *p_stream, MP4_Box_t *p_box )
1906 {
1907     MP4_READBOX_ENTER( MP4_Box_data_vpcC_t, MP4_FreeBox_vpcC );
1908     MP4_Box_data_vpcC_t *p_vpcC = p_box->data.p_vpcC;
1909
1910     if( p_box->i_size < 6 )
1911         MP4_READBOX_EXIT( 0 );
1912
1913     MP4_GET1BYTE( p_vpcC->i_version );
1914     if( p_vpcC->i_version > 1 )
1915         MP4_READBOX_EXIT( 0 );
1916
1917     MP4_GET1BYTE( p_vpcC->i_profile );
1918     MP4_GET1BYTE( p_vpcC->i_level );
1919     MP4_GET1BYTE( p_vpcC->i_bit_depth );
1920
1921     /* Deprecated one
1922        https://github.com/webmproject/vp9-dash/blob/master/archive/VPCodecISOMediaFileFormatBinding-v0.docx */
1923     if( p_vpcC->i_version == 0 )
1924     {
1925         p_vpcC->i_color_primaries = p_vpcC->i_bit_depth & 0x0F;
1926         p_vpcC->i_bit_depth >>= 4;
1927         MP4_GET1BYTE( p_vpcC->i_chroma_subsampling );
1928         p_vpcC->i_xfer_function = ( p_vpcC->i_chroma_subsampling & 0x0F ) >> 1;
1929         p_vpcC->i_fullrange = p_vpcC->i_chroma_subsampling & 0x01;
1930         p_vpcC->i_chroma_subsampling >>= 4;
1931     }
1932     else
1933     {
1934         p_vpcC->i_chroma_subsampling = ( p_vpcC->i_bit_depth & 0x0F ) >> 1;
1935         p_vpcC->i_fullrange = p_vpcC->i_bit_depth & 0x01;
1936         p_vpcC->i_bit_depth >>= 4;
1937         MP4_GET1BYTE( p_vpcC->i_color_primaries );
1938         MP4_GET1BYTE( p_vpcC->i_xfer_function );
1939         MP4_GET1BYTE( p_vpcC->i_matrix_coeffs );
1940     }
1941
1942     MP4_GET2BYTES( p_vpcC->i_codec_init_datasize );
1943     if( p_vpcC->i_codec_init_datasize > i_read )
1944         p_vpcC->i_codec_init_datasize = i_read;
1945
1946     if( p_vpcC->i_codec_init_datasize )
1947     {
1948         p_vpcC->p_codec_init_data = malloc( i_read );
1949         if( !p_vpcC->p_codec_init_data )
1950             MP4_READBOX_EXIT( 0 );
1951         memcpy( p_vpcC->p_codec_init_data, p_peek, i_read );
1952     }
1953
1954     MP4_READBOX_EXIT( 1 );
1955 }
1956
1957 static int MP4_ReadBox_SmDm( stream_t *p_stream, MP4_Box_t *p_box )
1958 {
1959     MP4_READBOX_ENTER( MP4_Box_data_SmDm_t, NULL );
1960     MP4_Box_data_SmDm_t *p_SmDm = p_box->data.p_SmDm;
1961
1962     /* SmDm: version/flags RGB */
1963     /* mdcv: version/flags GBR or not */
1964     if( p_box->i_type != ATOM_mdcv )
1965     {
1966         uint8_t i_version;
1967         uint32_t i_flags;
1968         MP4_GET1BYTE( i_version );
1969         MP4_GET3BYTES( i_flags );
1970         VLC_UNUSED(i_flags);
1971         if( i_version != 0 )
1972             MP4_READBOX_EXIT( 0 );
1973     }
1974
1975     const uint8_t RGB2GBR[3] = {2,0,1};
1976     for(int i=0; i<6; i++)
1977     {
1978         int index = (p_box->i_type != ATOM_mdcv) ? RGB2GBR[i/2] + i%2 : i;
1979         MP4_GET2BYTES( p_SmDm->primaries[index] );
1980
1981         /* convert from fixed point to 0.00002 resolution */
1982         if(p_box->i_type != ATOM_mdcv)
1983             p_SmDm->primaries[index] = 50000 *
1984                     (double)p_SmDm->primaries[index] / (double)(1<<16);
1985     }
1986     for(int i=0; i<2; i++)
1987     {
1988         MP4_GET2BYTES( p_SmDm->white_point[i] );
1989         if(p_box->i_type != ATOM_mdcv)
1990             p_SmDm->white_point[i] = 50000 *
1991                     (double)p_SmDm->white_point[i] / (double)(1<<16);
1992     }
1993
1994     MP4_GET4BYTES( p_SmDm->i_luminanceMax );
1995     MP4_GET4BYTES( p_SmDm->i_luminanceMin );
1996     if(p_box->i_type != ATOM_mdcv)
1997     {
1998         p_SmDm->i_luminanceMax = 10000 *
1999                 (double)p_SmDm->i_luminanceMax / (double) (1<<8);
2000         p_SmDm->i_luminanceMin = 10000 *
2001                 (double)p_SmDm->i_luminanceMin / (double) (1<<14);
2002     }
2003
2004     MP4_READBOX_EXIT( 1 );
2005 }
2006
2007 static int MP4_ReadBox_CoLL( stream_t *p_stream, MP4_Box_t *p_box )
2008 {
2009     MP4_READBOX_ENTER( MP4_Box_data_CoLL_t, NULL );
2010     MP4_Box_data_CoLL_t *p_CoLL = p_box->data.p_CoLL;
2011
2012     if( p_box->i_type != ATOM_clli )
2013     {
2014         uint8_t i_version;
2015         uint32_t i_flags;
2016         MP4_GET1BYTE( i_version );
2017         MP4_GET3BYTES( i_flags );
2018         VLC_UNUSED(i_flags);
2019         if( i_version != 0 )
2020             MP4_READBOX_EXIT( 0 );
2021     }
2022
2023     MP4_GET2BYTES( p_CoLL->i_maxCLL );
2024     MP4_GET2BYTES( p_CoLL->i_maxFALL );
2025     MP4_READBOX_EXIT( 1 );
2026 }
2027
2028 static void MP4_FreeBox_WMA2( MP4_Box_t *p_box )
2029 {
2030     free( p_box->data.p_WMA2->p_extra );
2031 }
2032
2033 static int MP4_ReadBox_WMA2( stream_t *p_stream, MP4_Box_t *p_box )
2034 {
2035     MP4_READBOX_ENTER( MP4_Box_data_WMA2_t, MP4_FreeBox_WMA2 );
2036
2037     MP4_Box_data_WMA2_t *p_WMA2 = p_box->data.p_WMA2;
2038
2039     MP4_GET2BYTESLE( p_WMA2->Format.wFormatTag );
2040     MP4_GET2BYTESLE( p_WMA2->Format.nChannels );
2041     MP4_GET4BYTESLE( p_WMA2->Format.nSamplesPerSec );
2042     MP4_GET4BYTESLE( p_WMA2->Format.nAvgBytesPerSec );
2043     MP4_GET2BYTESLE( p_WMA2->Format.nBlockAlign );
2044     MP4_GET2BYTESLE( p_WMA2->Format.wBitsPerSample );
2045
2046     uint16_t i_cbSize;
2047     MP4_GET2BYTESLE( i_cbSize );
2048
2049     if( i_cbSize > i_read )
2050         goto error;
2051
2052     p_WMA2->i_extra = i_cbSize;
2053     if ( p_WMA2->i_extra )
2054     {
2055         p_WMA2->p_extra = malloc( p_WMA2->i_extra );
2056         if ( ! p_WMA2->p_extra )
2057             goto error;
2058         memcpy( p_WMA2->p_extra, p_peek, p_WMA2->i_extra );
2059     }
2060
2061     MP4_READBOX_EXIT( 1 );
2062
2063 error:
2064     MP4_READBOX_EXIT( 0 );
2065 }
2066
2067 static void MP4_FreeBox_strf( MP4_Box_t *p_box )
2068 {
2069     free( p_box->data.p_strf->p_extra );
2070 }
2071
2072 static int MP4_ReadBox_strf( stream_t *p_stream, MP4_Box_t *p_box )
2073 {
2074     MP4_READBOX_ENTER( MP4_Box_data_strf_t, MP4_FreeBox_strf );
2075
2076     MP4_Box_data_strf_t *p_strf = p_box->data.p_strf;
2077
2078     if( i_read < 40 )
2079         goto error;
2080
2081     MP4_GET4BYTESLE( p_strf->bmiHeader.biSize );
2082     MP4_GET4BYTESLE( p_strf->bmiHeader.biWidth );
2083     MP4_GET4BYTESLE( p_strf->bmiHeader.biHeight );
2084     MP4_GET2BYTESLE( p_strf->bmiHeader.biPlanes );
2085     MP4_GET2BYTESLE( p_strf->bmiHeader.biBitCount );
2086     MP4_GETFOURCC( p_strf->bmiHeader.biCompression );
2087     MP4_GET4BYTESLE( p_strf->bmiHeader.biSizeImage );
2088     MP4_GET4BYTESLE( p_strf->bmiHeader.biXPelsPerMeter );
2089     MP4_GET4BYTESLE( p_strf->bmiHeader.biYPelsPerMeter );
2090     MP4_GET4BYTESLE( p_strf->bmiHeader.biClrUsed );
2091     MP4_GET4BYTESLE( p_strf->bmiHeader.biClrImportant );
2092
2093     p_strf->i_extra = i_read;
2094     if ( p_strf->i_extra )
2095     {
2096         p_strf->p_extra = malloc( p_strf->i_extra );
2097         if ( ! p_strf->p_extra )
2098             goto error;
2099         memcpy( p_strf->p_extra, p_peek, i_read );
2100     }
2101
2102     MP4_READBOX_EXIT( 1 );
2103
2104 error:
2105     MP4_READBOX_EXIT( 0 );
2106 }
2107
2108 static int MP4_ReadBox_ASF( stream_t *p_stream, MP4_Box_t *p_box )
2109 {
2110     MP4_READBOX_ENTER( MP4_Box_data_ASF_t, NULL );
2111
2112     MP4_Box_data_ASF_t *p_asf = p_box->data.p_asf;
2113
2114     if (i_read != 8)
2115         MP4_READBOX_EXIT( 0 );
2116
2117     MP4_GET1BYTE( p_asf->i_stream_number );
2118     /* remaining is unknown */
2119
2120     MP4_READBOX_EXIT( 1 );
2121 }
2122
2123 static void MP4_FreeBox_sbgp( MP4_Box_t *p_box )
2124 {
2125     MP4_Box_data_sbgp_t *p_sbgp = p_box->data.p_sbgp;
2126     free( p_sbgp->entries.pi_sample_count );
2127     free( p_sbgp->entries.pi_group_description_index );
2128 }
2129
2130 static int MP4_ReadBox_sbgp( stream_t *p_stream, MP4_Box_t *p_box )
2131 {
2132     MP4_READBOX_ENTER( MP4_Box_data_sbgp_t, MP4_FreeBox_sbgp );
2133     MP4_Box_data_sbgp_t *p_sbgp = p_box->data.p_sbgp;
2134     uint32_t i_flags;
2135
2136     if ( i_read < 12 )
2137         MP4_READBOX_EXIT( 0 );
2138
2139     MP4_GET1BYTE( p_sbgp->i_version );
2140     MP4_GET3BYTES( i_flags );
2141     if( i_flags != 0 )
2142         MP4_READBOX_EXIT( 0 );
2143
2144     MP4_GETFOURCC( p_sbgp->i_grouping_type );
2145
2146     if( p_sbgp->i_version == 1 )
2147     {
2148         if( i_read < 8 )
2149             MP4_READBOX_EXIT( 0 );
2150         MP4_GET4BYTES( p_sbgp->i_grouping_type_parameter );
2151     }
2152
2153     MP4_GET4BYTES( p_sbgp->i_entry_count );
2154     if( p_sbgp->i_entry_count > i_read / (4 + 4) )
2155         p_sbgp->i_entry_count = i_read / (4 + 4);
2156
2157     p_sbgp->entries.pi_sample_count = vlc_alloc( p_sbgp->i_entry_count, sizeof(uint32_t) );
2158     p_sbgp->entries.pi_group_description_index = vlc_alloc( p_sbgp->i_entry_count, sizeof(uint32_t) );
2159
2160     if( !p_sbgp->entries.pi_sample_count || !p_sbgp->entries.pi_group_description_index )
2161     {
2162         MP4_FreeBox_sbgp( p_box );
2163         MP4_READBOX_EXIT( 0 );
2164     }
2165
2166     for( uint32_t i=0; i<p_sbgp->i_entry_count; i++ )
2167     {
2168         MP4_GET4BYTES( p_sbgp->entries.pi_sample_count[i] );
2169         MP4_GET4BYTES( p_sbgp->entries.pi_group_description_index[i] );
2170     }
2171
2172 #ifdef MP4_VERBOSE
2173     msg_Dbg( p_stream,
2174         "read box: \"sbgp\" grouping type %4.4s", (char*) &p_sbgp->i_grouping_type );
2175  #ifdef MP4_ULTRA_VERBOSE
2176     for (uint32_t i = 0; i < p_sbgp->i_entry_count; i++)
2177         msg_Dbg( p_stream, "\t samples %" PRIu32 " group %" PRIu32,
2178                  p_sbgp->entries.pi_sample_count[i],
2179                  p_sbgp->entries.pi_group_description_index[i] );
2180  #endif
2181 #endif
2182
2183     MP4_READBOX_EXIT( 1 );
2184 }
2185
2186 static void MP4_FreeBox_sgpd( MP4_Box_t *p_box )
2187 {
2188     MP4_Box_data_sgpd_t *p_sgpd = p_box->data.p_sgpd;
2189     free( p_sgpd->p_entries );
2190 }
2191
2192 static int MP4_ReadBox_sgpd( stream_t *p_stream, MP4_Box_t *p_box )
2193 {
2194     MP4_READBOX_ENTER( MP4_Box_data_sgpd_t, MP4_FreeBox_sgpd );
2195     MP4_Box_data_sgpd_t *p_sgpd = p_box->data.p_sgpd;
2196     uint32_t i_flags;
2197     uint32_t i_default_length = 0;
2198
2199     if ( i_read < 8 )
2200         MP4_READBOX_EXIT( 0 );
2201
2202     MP4_GET1BYTE( p_sgpd->i_version );
2203     MP4_GET3BYTES( i_flags );
2204     if( i_flags != 0 )
2205         MP4_READBOX_EXIT( 0 );
2206
2207     MP4_GETFOURCC( p_sgpd->i_grouping_type );
2208
2209     switch( p_sgpd->i_grouping_type )
2210     {
2211         case SAMPLEGROUP_rap:
2212             break;
2213
2214         default:
2215 #ifdef MP4_VERBOSE
2216     msg_Dbg( p_stream,
2217         "read box: \"sgpd\" grouping type %4.4s (unimplemented)", (char*) &p_sgpd->i_grouping_type );
2218 #endif
2219             MP4_READBOX_EXIT( 1 );
2220     }
2221
2222     if( p_sgpd->i_version == 1 )
2223     {
2224         if( i_read < 8 )
2225             MP4_READBOX_EXIT( 0 );
2226         MP4_GET4BYTES( i_default_length );
2227     }
2228     else if( p_sgpd->i_version >= 2 )
2229     {
2230         if( i_read < 8 )
2231             MP4_READBOX_EXIT( 0 );
2232         MP4_GET4BYTES( p_sgpd->i_default_sample_description_index );
2233     }
2234
2235     MP4_GET4BYTES( p_sgpd->i_entry_count );
2236
2237     p_sgpd->p_entries = vlc_alloc( p_sgpd->i_entry_count, sizeof(*p_sgpd->p_entries) );
2238     if( !p_sgpd->p_entries )
2239         MP4_READBOX_EXIT( 0 );
2240
2241     uint32_t i = 0;
2242     for( ; i<p_sgpd->i_entry_count; i++ )
2243     {
2244         uint32_t i_description_length = i_default_length;
2245         if( p_sgpd->i_version == 1 && i_default_length == 0 )
2246         {
2247             if( i_read < 4 )
2248                 break;
2249             MP4_GET4BYTES( i_description_length );
2250         }
2251
2252         if( p_sgpd->i_version == 1 && i_read < i_description_length )
2253             break;
2254
2255         switch( p_sgpd->i_grouping_type )
2256         {
2257             case SAMPLEGROUP_rap:
2258                 {
2259                     if( i_read < 1 )
2260                     {
2261                         p_sgpd->i_entry_count = 0;
2262                         MP4_FreeBox_sgpd( p_box );
2263                         MP4_READBOX_EXIT( 0 );
2264                     }
2265                     uint8_t i_data;
2266                     MP4_GET1BYTE( i_data );
2267                     p_sgpd->p_entries[i].rap.i_num_leading_samples_known = i_data & 0x80;
2268                     p_sgpd->p_entries[i].rap.i_num_leading_samples = i_data & 0x7F;
2269                 }
2270                 break;
2271
2272             default:
2273                 assert(0);
2274         }
2275     }
2276
2277     if( i != p_sgpd->i_entry_count )
2278         p_sgpd->i_entry_count = i;
2279
2280 #ifdef MP4_VERBOSE
2281     msg_Dbg( p_stream,
2282         "read box: \"sgpd\" grouping type %4.4s", (char*) &p_sgpd->i_grouping_type );
2283 #endif
2284
2285     MP4_READBOX_EXIT( 1 );
2286 }
2287
2288 static void MP4_FreeBox_stsdext_chan( MP4_Box_t *p_box )
2289 {
2290     MP4_Box_data_chan_t *p_chan = p_box->data.p_chan;
2291     free( p_chan->layout.p_descriptions );
2292 }
2293
2294 static int MP4_ReadBox_stsdext_chan( stream_t *p_stream, MP4_Box_t *p_box )
2295 {
2296     MP4_READBOX_ENTER( MP4_Box_data_chan_t, MP4_FreeBox_stsdext_chan );
2297     MP4_Box_data_chan_t *p_chan = p_box->data.p_chan;
2298
2299     if ( i_read < 16 )
2300         MP4_READBOX_EXIT( 0 );
2301
2302     MP4_GET1BYTE( p_chan->i_version );
2303     MP4_GET3BYTES( p_chan->i_channels_flags );
2304     MP4_GET4BYTES( p_chan->layout.i_channels_layout_tag );
2305     MP4_GET4BYTES( p_chan->layout.i_channels_bitmap );
2306     MP4_GET4BYTES( p_chan->layout.i_channels_description_count );
2307
2308     size_t i_descsize = 8 + 3 * sizeof(float);
2309     if ( i_read < p_chan->layout.i_channels_description_count * i_descsize )
2310         MP4_READBOX_EXIT( 0 );
2311
2312     p_chan->layout.p_descriptions =
2313         vlc_alloc( p_chan->layout.i_channels_description_count, i_descsize );
2314
2315     if ( !p_chan->layout.p_descriptions )
2316         MP4_READBOX_EXIT( 0 );
2317
2318     uint32_t i;
2319     for( i=0; i<p_chan->layout.i_channels_description_count; i++ )
2320     {
2321         if ( i_read < 20 )
2322             break;
2323         MP4_GET4BYTES( p_chan->layout.p_descriptions[i].i_channel_label );
2324         MP4_GET4BYTES( p_chan->layout.p_descriptions[i].i_channel_flags );
2325         MP4_GET4BYTES( p_chan->layout.p_descriptions[i].f_coordinates[0] );
2326         MP4_GET4BYTES( p_chan->layout.p_descriptions[i].f_coordinates[1] );
2327         MP4_GET4BYTES( p_chan->layout.p_descriptions[i].f_coordinates[2] );
2328     }
2329     if ( i<p_chan->layout.i_channels_description_count )
2330         p_chan->layout.i_channels_description_count = i;
2331
2332 #ifdef MP4_VERBOSE
2333     msg_Dbg( p_stream,
2334              "read box: \"chan\" flags=0x%x tag=0x%x bitmap=0x%x descriptions=%u",
2335              p_chan->i_channels_flags, p_chan->layout.i_channels_layout_tag,
2336              p_chan->layout.i_channels_bitmap, p_chan->layout.i_channels_description_count );
2337 #endif
2338     MP4_READBOX_EXIT( 1 );
2339 }
2340
2341 static int MP4_ReadBox_dec3( stream_t *p_stream, MP4_Box_t *p_box )
2342 {
2343     MP4_READBOX_ENTER( MP4_Box_data_dec3_t, NULL );
2344
2345     MP4_Box_data_dec3_t *p_dec3 = p_box->data.p_dec3;
2346
2347     unsigned i_header;
2348     MP4_GET2BYTES( i_header );
2349
2350     p_dec3->i_data_rate = i_header >> 3;
2351     p_dec3->i_num_ind_sub = (i_header & 0x7) + 1;
2352     for (uint8_t i = 0; i < p_dec3->i_num_ind_sub; i++) {
2353         MP4_GET3BYTES( i_header );
2354         p_dec3->stream[i].i_fscod = ( i_header >> 22 ) & 0x03;
2355         p_dec3->stream[i].i_bsid  = ( i_header >> 17 ) & 0x01f;
2356         p_dec3->stream[i].i_bsmod = ( i_header >> 12 ) & 0x01f;
2357         p_dec3->stream[i].i_acmod = ( i_header >> 9 ) & 0x07;
2358         p_dec3->stream[i].i_lfeon = ( i_header >> 8 ) & 0x01;
2359         p_dec3->stream[i].i_num_dep_sub = (i_header >> 1) & 0x0f;
2360         if (p_dec3->stream[i].i_num_dep_sub) {
2361             MP4_GET1BYTE( p_dec3->stream[i].i_chan_loc );
2362             p_dec3->stream[i].i_chan_loc |= (i_header & 1) << 8;
2363         } else
2364             p_dec3->stream[i].i_chan_loc = 0;
2365     }
2366
2367 #ifdef MP4_VERBOSE
2368     msg_Dbg( p_stream,
2369         "read box: \"dec3\" bitrate %dkbps %d independent substreams",
2370             p_dec3->i_data_rate, p_dec3->i_num_ind_sub);
2371
2372     for (uint8_t i = 0; i < p_dec3->i_num_ind_sub; i++)
2373         msg_Dbg( p_stream,
2374                 "\tstream %d: bsid=0x%x bsmod=0x%x acmod=0x%x lfeon=0x%x "
2375                 "num dependent subs=%d chan_loc=0x%x",
2376                 i, p_dec3->stream[i].i_bsid, p_dec3->stream[i].i_bsmod, p_dec3->stream[i].i_acmod,
2377                 p_dec3->stream[i].i_lfeon, p_dec3->stream[i].i_num_dep_sub, p_dec3->stream[i].i_chan_loc );
2378 #endif
2379     MP4_READBOX_EXIT( 1 );
2380 }
2381
2382 static int MP4_ReadBox_dac3( stream_t *p_stream, MP4_Box_t *p_box )
2383 {
2384     MP4_Box_data_dac3_t *p_dac3;
2385     MP4_READBOX_ENTER( MP4_Box_data_dac3_t, NULL );
2386
2387     p_dac3 = p_box->data.p_dac3;
2388
2389     unsigned i_header;
2390     MP4_GET3BYTES( i_header );
2391
2392     p_dac3->i_fscod = ( i_header >> 22 ) & 0x03;
2393     p_dac3->i_bsid  = ( i_header >> 17 ) & 0x01f;
2394     p_dac3->i_bsmod = ( i_header >> 14 ) & 0x07;
2395     p_dac3->i_acmod = ( i_header >> 11 ) & 0x07;
2396     p_dac3->i_lfeon = ( i_header >> 10 ) & 0x01;
2397     p_dac3->i_bitrate_code = ( i_header >> 5) & 0x1f;
2398
2399 #ifdef MP4_VERBOSE
2400     msg_Dbg( p_stream,
2401              "read box: \"dac3\" fscod=0x%x bsid=0x%x bsmod=0x%x acmod=0x%x lfeon=0x%x bitrate_code=0x%x",
2402              p_dac3->i_fscod, p_dac3->i_bsid, p_dac3->i_bsmod, p_dac3->i_acmod, p_dac3->i_lfeon, p_dac3->i_bitrate_code );
2403 #endif
2404     MP4_READBOX_EXIT( 1 );
2405 }
2406
2407 static void MP4_FreeBox_dvc1( MP4_Box_t *p_box )
2408 {
2409     free( p_box->data.p_dvc1->p_vc1 );
2410 }
2411
2412 static int MP4_ReadBox_dvc1( stream_t *p_stream, MP4_Box_t *p_box )
2413 {
2414     MP4_READBOX_ENTER( MP4_Box_data_dvc1_t, MP4_FreeBox_dvc1 );
2415     if( i_read < 7 )
2416         MP4_READBOX_EXIT( 0 );
2417
2418     MP4_Box_data_dvc1_t *p_dvc1 = p_box->data.p_dvc1;
2419     MP4_GET1BYTE( p_dvc1->i_profile_level );
2420     p_dvc1->i_vc1 = i_read; /* Header + profile_level */
2421     if( p_dvc1->i_vc1 > 0 && (p_dvc1->p_vc1 = malloc( p_dvc1->i_vc1 )) )
2422         memcpy( p_dvc1->p_vc1, p_peek, i_read );
2423
2424 #ifdef MP4_VERBOSE
2425     msg_Dbg( p_stream,
2426              "read box: \"dvc1\" profile=%"PRIu8, (p_dvc1->i_profile_level & 0xf0) >> 4 );
2427 #endif
2428
2429     MP4_READBOX_EXIT( 1 );
2430 }
2431
2432 static int MP4_ReadBox_fiel( stream_t *p_stream, MP4_Box_t *p_box )
2433 {
2434     MP4_Box_data_fiel_t *p_fiel;
2435     MP4_READBOX_ENTER( MP4_Box_data_fiel_t, NULL );
2436     p_fiel = p_box->data.p_fiel;
2437     if(i_read < 2)
2438         MP4_READBOX_EXIT( 0 );
2439     if(p_peek[0] == 1)
2440     {
2441         p_fiel->i_flags = BLOCK_FLAG_SINGLE_FIELD;
2442     }
2443     else if(p_peek[0] == 2) /* Interlaced */
2444     {
2445         /*
2446          * 0 – There is only one field.
2447          * 1 – T is displayed earliest, T is stored first in the file.
2448          * 6 – B is displayed earliest, B is stored first in the file.
2449          * 9 – B is displayed earliest, T is stored first in the file.
2450          * 14 – T is displayed earliest, B is stored first in the file.
2451         */
2452         if(p_peek[1] == 1 || p_peek[1] == 9)
2453             p_fiel->i_flags = BLOCK_FLAG_TOP_FIELD_FIRST;
2454         else if(p_peek[1] == 6 || p_peek[1] == 14)
2455             p_fiel->i_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST;
2456     }
2457     MP4_READBOX_EXIT( 1 );
2458 }
2459
2460 static int MP4_ReadBox_enda( stream_t *p_stream, MP4_Box_t *p_box )
2461 {
2462     MP4_Box_data_enda_t *p_enda;
2463     MP4_READBOX_ENTER( MP4_Box_data_enda_t, NULL );
2464
2465     p_enda = p_box->data.p_enda;
2466
2467     MP4_GET2BYTES( p_enda->i_little_endian );
2468
2469 #ifdef MP4_VERBOSE
2470     msg_Dbg( p_stream,
2471              "read box: \"enda\" little_endian=%d", p_enda->i_little_endian );
2472 #endif
2473     MP4_READBOX_EXIT( 1 );
2474 }
2475
2476 static void MP4_FreeBox_sample_soun( MP4_Box_t *p_box )
2477 {
2478     free( p_box->data.p_sample_soun->p_qt_description );
2479 }
2480
2481 static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box )
2482 {
2483     p_box->i_handler = ATOM_soun;
2484     MP4_READBOX_ENTER( MP4_Box_data_sample_soun_t, MP4_FreeBox_sample_soun );
2485     p_box->data.p_sample_soun->p_qt_description = NULL;
2486
2487     size_t i_actually_read = i_read + header_size;
2488
2489     /* Sanity check needed because the "wave" box does also contain an
2490      * "mp4a" box that we don't understand. */
2491     if( i_read < 28 )
2492     {
2493         MP4_READBOX_EXIT( 1 );
2494     }
2495
2496     for( unsigned i = 0; i < 6 ; i++ )
2497     {
2498         MP4_GET1BYTE( p_box->data.p_sample_soun->i_reserved1[i] );
2499     }
2500
2501     MP4_GET2BYTES( p_box->data.p_sample_soun->i_data_reference_index );
2502
2503     /*
2504      * XXX hack -> produce a copy of the nearly complete chunk
2505      */
2506     p_box->data.p_sample_soun->i_qt_description = 0;
2507     p_box->data.p_sample_soun->p_qt_description = NULL;
2508     if( i_read > 0 )
2509     {
2510         p_box->data.p_sample_soun->p_qt_description = malloc( i_read );
2511         if( p_box->data.p_sample_soun->p_qt_description )
2512         {
2513             p_box->data.p_sample_soun->i_qt_description = i_read;
2514             memcpy( p_box->data.p_sample_soun->p_qt_description, p_peek, i_read );
2515         }
2516     }
2517
2518     MP4_GET2BYTES( p_box->data.p_sample_soun->i_qt_version );
2519     MP4_GET2BYTES( p_box->data.p_sample_soun->i_qt_revision_level );
2520     MP4_GET4BYTES( p_box->data.p_sample_soun->i_qt_vendor );
2521
2522     MP4_GET2BYTES( p_box->data.p_sample_soun->i_channelcount );
2523     MP4_GET2BYTES( p_box->data.p_sample_soun->i_samplesize );
2524     MP4_GET2BYTES( p_box->data.p_sample_soun->i_compressionid );
2525     MP4_GET2BYTES( p_box->data.p_sample_soun->i_reserved3 );
2526     MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratehi );
2527     MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratelo );
2528
2529 #ifdef MP4_VERBOSE
2530     msg_Dbg( p_stream,
2531              "read box: \"soun\" stsd qt_version %"PRIu16" compid=%"PRIx16,
2532              p_box->data.p_sample_soun->i_qt_version,
2533              p_box->data.p_sample_soun->i_compressionid );
2534 #endif
2535     /* @36 bytes */
2536     if( p_box->data.p_sample_soun->i_qt_version == 1 && i_read >= 16 )
2537     {
2538         /* SoundDescriptionV1 */
2539         MP4_GET4BYTES( p_box->data.p_sample_soun->i_sample_per_packet );
2540         MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_packet );
2541         MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_frame );
2542         MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_sample );
2543
2544 #ifdef MP4_VERBOSE
2545         msg_Dbg( p_stream,
2546                  "read box: \"soun\" V1 sample/packet=%d bytes/packet=%d "
2547                  "bytes/frame=%d bytes/sample=%d",
2548                  p_box->data.p_sample_soun->i_sample_per_packet,
2549                  p_box->data.p_sample_soun->i_bytes_per_packet,
2550                  p_box->data.p_sample_soun->i_bytes_per_frame,
2551                  p_box->data.p_sample_soun->i_bytes_per_sample );
2552 #endif
2553         /* @52 bytes */
2554     }
2555     else if( p_box->data.p_sample_soun->i_qt_version == 2 && i_read >= 36 )
2556     {
2557         /* SoundDescriptionV2 */
2558         double f_sample_rate;
2559         int64_t i_dummy64;
2560         uint32_t i_channel, i_extoffset, i_dummy32;
2561
2562         /* Checks */
2563         if ( p_box->data.p_sample_soun->i_channelcount != 0x3  ||
2564              p_box->data.p_sample_soun->i_samplesize != 0x0010 ||
2565              p_box->data.p_sample_soun->i_compressionid != 0xFFFE ||
2566              p_box->data.p_sample_soun->i_reserved3 != 0x0     ||
2567              p_box->data.p_sample_soun->i_sampleratehi != 0x1  ||//65536
2568              p_box->data.p_sample_soun->i_sampleratelo != 0x0 )  //remainder
2569         {
2570             msg_Err( p_stream, "invalid stsd V2 box defaults" );
2571             MP4_READBOX_EXIT( 0 );
2572         }
2573         /* !Checks */
2574
2575         MP4_GET4BYTES( i_extoffset ); /* offset to stsd extentions */
2576         MP4_GET8BYTES( i_dummy64 );
2577         memcpy( &f_sample_rate, &i_dummy64, 8 );
2578         msg_Dbg( p_stream, "read box: %f Hz", f_sample_rate );
2579         /* Rounding error with lo, but we don't care since we do not support fractional audio rate */
2580         p_box->data.p_sample_soun->i_sampleratehi = (uint32_t)f_sample_rate;
2581         p_box->data.p_sample_soun->i_sampleratelo = (f_sample_rate - p_box->data.p_sample_soun->i_sampleratehi);
2582
2583         MP4_GET4BYTES( i_channel );
2584         p_box->data.p_sample_soun->i_channelcount = i_channel;
2585
2586         MP4_GET4BYTES( i_dummy32 );
2587         if ( i_dummy32 != 0x7F000000 )
2588         {
2589             msg_Err( p_stream, "invalid stsd V2 box" );
2590             MP4_READBOX_EXIT( 0 );
2591         }
2592
2593         MP4_GET4BYTES( p_box->data.p_sample_soun->i_constbitsperchannel );
2594         MP4_GET4BYTES( p_box->data.p_sample_soun->i_formatflags );
2595         MP4_GET4BYTES( p_box->data.p_sample_soun->i_constbytesperaudiopacket );
2596         MP4_GET4BYTES( p_box->data.p_sample_soun->i_constLPCMframesperaudiopacket );
2597
2598 #ifdef MP4_VERBOSE
2599         msg_Dbg( p_stream, "read box: \"soun\" V2 rate=%f bitsperchannel=%u "
2600                            "flags=%u bytesperpacket=%u lpcmframesperpacket=%u",
2601                  f_sample_rate,
2602                  p_box->data.p_sample_soun->i_constbitsperchannel,
2603                  p_box->data.p_sample_soun->i_formatflags,
2604                  p_box->data.p_sample_soun->i_constbytesperaudiopacket,
2605                  p_box->data.p_sample_soun->i_constLPCMframesperaudiopacket );
2606 #endif
2607         /* @72 bytes + */
2608         if( i_extoffset > i_actually_read )
2609             i_extoffset = i_actually_read;
2610         p_peek = &p_buff[i_extoffset];
2611         i_read = i_actually_read - i_extoffset;
2612     }
2613     else
2614     {
2615         p_box->data.p_sample_soun->i_sample_per_packet = 0;
2616         p_box->data.p_sample_soun->i_bytes_per_packet = 0;
2617         p_box->data.p_sample_soun->i_bytes_per_frame = 0;
2618         p_box->data.p_sample_soun->i_bytes_per_sample = 0;
2619
2620 #ifdef MP4_VERBOSE
2621         msg_Dbg( p_stream, "read box: \"soun\" V0 or qt1/2 (rest=%"PRIu64")",
2622                  i_read );
2623 #endif
2624         /* @36 bytes */
2625     }
2626
2627     if( p_box->i_type == ATOM_drms )
2628     {
2629         msg_Warn( p_stream, "DRM protected streams are not supported." );
2630         MP4_READBOX_EXIT( 0 );
2631     }
2632
2633     if( p_box->i_type == ATOM_samr || p_box->i_type == ATOM_sawb )
2634     {
2635         /* Ignore channelcount for AMR (3gpp AMRSpecificBox) */
2636         p_box->data.p_sample_soun->i_channelcount = 1;
2637     }
2638
2639     /* Loads extensions */
2640     MP4_ReadBoxContainerRawInBox( p_stream, p_box, p_peek, i_read,
2641                                   p_box->i_pos + p_peek - p_buff ); /* esds/wave/... */
2642
2643 #ifdef MP4_VERBOSE
2644     msg_Dbg( p_stream, "read box: \"soun\" in stsd channel %d "
2645              "sample size %d sample rate %f",
2646              p_box->data.p_sample_soun->i_channelcount,
2647              p_box->data.p_sample_soun->i_samplesize,
2648              (float)p_box->data.p_sample_soun->i_sampleratehi +
2649              (float)p_box->data.p_sample_soun->i_sampleratelo / BLOCK16x16 );
2650
2651 #endif
2652     MP4_READBOX_EXIT( 1 );
2653 }
2654
2655 static void MP4_FreeBox_sample_vide( MP4_Box_t *p_box )
2656 {
2657     free( p_box->data.p_sample_vide->p_qt_image_description );
2658 }
2659
2660 int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box )
2661 {
2662     p_box->i_handler = ATOM_vide;
2663     MP4_READBOX_ENTER( MP4_Box_data_sample_vide_t, MP4_FreeBox_sample_vide );
2664
2665     size_t i_actually_read = i_read + header_size;
2666
2667     for( unsigned i = 0; i < 6 ; i++ )
2668     {
2669         MP4_GET1BYTE( p_box->data.p_sample_vide->i_reserved1[i] );
2670     }
2671
2672     MP4_GET2BYTES( p_box->data.p_sample_vide->i_data_reference_index );
2673
2674     /*
2675      * XXX hack -> produce a copy of the nearly complete chunk
2676      */
2677     if( i_read > 0 )
2678     {
2679         p_box->data.p_sample_vide->p_qt_image_description = malloc( i_read );
2680         if( unlikely( p_box->data.p_sample_vide->p_qt_image_description == NULL ) )
2681             MP4_READBOX_EXIT( 0 );
2682         p_box->data.p_sample_vide->i_qt_image_description = i_read;
2683         memcpy( p_box->data.p_sample_vide->p_qt_image_description,
2684                 p_peek, i_read );
2685     }
2686     else
2687     {
2688         p_box->data.p_sample_vide->i_qt_image_description = 0;
2689         p_box->data.p_sample_vide->p_qt_image_description = NULL;
2690     }
2691
2692     MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_version );
2693     MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_revision_level );
2694     MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_vendor );
2695
2696     MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_temporal_quality );
2697     MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_spatial_quality );
2698
2699     MP4_GET2BYTES( p_box->data.p_sample_vide->i_width );
2700     MP4_GET2BYTES( p_box->data.p_sample_vide->i_height );
2701
2702     MP4_GET4BYTES( p_box->data.p_sample_vide->i_horizresolution );
2703     MP4_GET4BYTES( p_box->data.p_sample_vide->i_vertresolution );
2704
2705     MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_data_size );
2706     MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_frame_count );
2707
2708     if ( i_read < 32 )
2709         MP4_READBOX_EXIT( 0 );
2710     if( p_peek[0] <= 31 ) // Must be Pascal String
2711     {
2712         memcpy( &p_box->data.p_sample_vide->sz_compressorname, &p_peek[1], p_peek[0] );
2713         p_box->data.p_sample_vide->sz_compressorname[p_peek[0]] = 0;
2714     }
2715     p_peek += 32; i_read -= 32;
2716
2717     MP4_GET2BYTES( p_box->data.p_sample_vide->i_depth );
2718     MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_color_table );
2719
2720     if( p_box->i_type == ATOM_drmi )
2721     {
2722         msg_Warn( p_stream, "DRM protected streams are not supported." );
2723         MP4_READBOX_EXIT( 0 );
2724     }
2725
2726     if( i_actually_read > 78 && p_peek - p_buff > 78 )
2727     {
2728         MP4_ReadBoxContainerRawInBox( p_stream, p_box, p_peek, i_read,
2729                                       p_box->i_pos + p_peek - p_buff );
2730     }
2731
2732 #ifdef MP4_VERBOSE
2733     msg_Dbg( p_stream, "read box: \"vide\" in stsd %dx%d depth %d (%s)",
2734                       p_box->data.p_sample_vide->i_width,
2735                       p_box->data.p_sample_vide->i_height,
2736                       p_box->data.p_sample_vide->i_depth,
2737                       p_box->data.p_sample_vide->sz_compressorname );
2738
2739 #endif
2740     MP4_READBOX_EXIT( 1 );
2741 }
2742
2743 static int MP4_ReadBox_sample_mp4s( stream_t *p_stream, MP4_Box_t *p_box )
2744 {
2745     p_box->i_handler = ATOM_text;
2746     MP4_READBOX_ENTER_PARTIAL( MP4_Box_data_sample_text_t, 16, NULL );
2747     (void) p_peek;
2748     if( i_read < 8 )
2749         MP4_READBOX_EXIT( 0 );
2750
2751     MP4_ReadBoxContainerChildren( p_stream, p_box, NULL );
2752
2753     if ( MP4_Seek( p_stream, p_box->i_pos + p_box->i_size ) )
2754         MP4_READBOX_EXIT( 0 );
2755
2756     MP4_READBOX_EXIT( 1 );
2757 }
2758
2759 static void MP4_FreeBox_sample_hint( MP4_Box_t *p_box )
2760 {
2761     free( p_box->data.p_sample_hint->p_data );
2762 }
2763
2764 static int MP4_ReadBox_sample_hint8( stream_t *p_stream, MP4_Box_t *p_box )
2765 {
2766     MP4_READBOX_ENTER_PARTIAL( MP4_Box_data_sample_hint_t, 24, MP4_FreeBox_sample_hint );
2767
2768     for( unsigned i = 0; i < 6 ; i++ )
2769     {
2770         MP4_GET1BYTE( p_box->data.p_sample_hint->i_reserved1[i] );
2771     }
2772
2773     MP4_GET2BYTES( p_box->data.p_sample_hint->i_data_reference_index );
2774
2775     if( !(p_box->data.p_sample_hint->p_data = malloc(8)) )
2776         MP4_READBOX_EXIT( 0 );
2777
2778     MP4_GET8BYTES( *(p_box->data.p_sample_hint->p_data) );
2779
2780     MP4_ReadBoxContainerChildren(p_stream, p_box, NULL);
2781
2782     if ( MP4_Seek( p_stream, p_box->i_pos + p_box->i_size ) )
2783         MP4_READBOX_EXIT( 0 );
2784
2785     MP4_READBOX_EXIT( 1 );
2786 }
2787
2788 static void MP4_FreeBox_sample_text( MP4_Box_t *p_box )
2789 {
2790     free( p_box->data.p_sample_text->p_data );
2791 }
2792
2793 static int MP4_ReadBox_sample_text( stream_t *p_stream, MP4_Box_t *p_box )
2794 {
2795     p_box->i_handler = ATOM_text;
2796     MP4_READBOX_ENTER( MP4_Box_data_sample_text_t, MP4_FreeBox_sample_text );
2797
2798     MP4_GET4BYTES( p_box->data.p_sample_text->i_reserved1 );
2799     MP4_GET2BYTES( p_box->data.p_sample_text->i_reserved2 );
2800
2801     MP4_GET2BYTES( p_box->data.p_sample_text->i_data_reference_index );
2802
2803     if( i_read )
2804     {
2805         p_box->data.p_sample_text->p_data = malloc( i_read );
2806         if( !p_box->data.p_sample_text->p_data )
2807             MP4_READBOX_EXIT( 0 );
2808         memcpy( p_box->data.p_sample_text->p_data, p_peek, i_read );
2809     }
2810     p_box->data.p_sample_text->i_data = i_read;
2811
2812 #ifdef MP4_VERBOSE
2813     msg_Dbg( p_stream, "read box: \"text\" in stsd text" );
2814 #endif
2815     MP4_READBOX_EXIT( 1 );
2816 }
2817
2818 static int MP4_ReadBox_sample_clcp( stream_t *p_stream, MP4_Box_t *p_box )
2819 {
2820     p_box->i_handler = ATOM_clcp;
2821     MP4_READBOX_ENTER( MP4_Box_data_sample_clcp_t, NULL );
2822
2823     if( i_read < 8 )
2824         MP4_READBOX_EXIT( 0 );
2825
2826     for( int i=0; i<6; i++ )
2827         MP4_GET1BYTE( p_box->data.p_sample_clcp->i_reserved1[i] );
2828     MP4_GET2BYTES( p_box->data.p_sample_clcp->i_data_reference_index );
2829
2830 #ifdef MP4_VERBOSE
2831     msg_Dbg( p_stream, "read box: \"clcp\" in stsd" );
2832 #endif
2833     MP4_READBOX_EXIT( 1 );
2834 }
2835
2836 static void MP4_FreeBox_stsz( MP4_Box_t *p_box )
2837 {
2838     free( p_box->data.p_stsz->i_entry_size );
2839 }
2840
2841 static int MP4_ReadBox_stsz( stream_t *p_stream, MP4_Box_t *p_box )
2842 {
2843     uint32_t count;
2844
2845     MP4_READBOX_ENTER( MP4_Box_data_stsz_t, MP4_FreeBox_stsz );
2846
2847     MP4_GETVERSIONFLAGS( p_box->data.p_stsz );
2848
2849     MP4_GET4BYTES( p_box->data.p_stsz->i_sample_size );
2850     MP4_GET4BYTES( count );
2851     p_box->data.p_stsz->i_sample_count = count;
2852
2853     if( p_box->data.p_stsz->i_sample_size == 0 )
2854     {
2855         if( UINT64_C(4) * count > i_read )
2856             MP4_READBOX_EXIT( 0 );
2857
2858         p_box->data.p_stsz->i_entry_size =
2859             vlc_alloc( count, sizeof(uint32_t) );
2860         if( unlikely( !p_box->data.p_stsz->i_entry_size ) )
2861             MP4_READBOX_EXIT( 0 );
2862
2863         for( uint32_t i = 0; i < count; i++ )
2864         {
2865             MP4_GET4BYTES( p_box->data.p_stsz->i_entry_size[i] );
2866         }
2867     }
2868     else
2869         p_box->data.p_stsz->i_entry_size = NULL;
2870
2871 #ifdef MP4_VERBOSE
2872     msg_Dbg( p_stream, "read box: \"stsz\" sample-size %d sample-count %d",
2873                       p_box->data.p_stsz->i_sample_size,
2874                       p_box->data.p_stsz->i_sample_count );
2875
2876 #endif
2877     MP4_READBOX_EXIT( 1 );
2878 }
2879
2880 static void MP4_FreeBox_stsc( MP4_Box_t *p_box )
2881 {
2882     free( p_box->data.p_stsc->i_first_chunk );
2883     free( p_box->data.p_stsc->i_samples_per_chunk );
2884     free( p_box->data.p_stsc->i_sample_description_index );
2885 }
2886
2887 static int MP4_ReadBox_stsc( stream_t *p_stream, MP4_Box_t *p_box )
2888 {
2889     uint32_t count;
2890
2891     MP4_READBOX_ENTER( MP4_Box_data_stsc_t, MP4_FreeBox_stsc );
2892
2893     MP4_GETVERSIONFLAGS( p_box->data.p_stsc );
2894     MP4_GET4BYTES( count );
2895
2896     if( UINT64_C(12) * count > i_read )
2897         MP4_READBOX_EXIT( 0 );
2898
2899     p_box->data.p_stsc->i_first_chunk = vlc_alloc( count, sizeof(uint32_t) );
2900     p_box->data.p_stsc->i_samples_per_chunk = vlc_alloc( count,
2901                                                          sizeof(uint32_t) );
2902     p_box->data.p_stsc->i_sample_description_index = vlc_alloc( count,
2903                                                             sizeof(uint32_t) );
2904     if( unlikely( p_box->data.p_stsc->i_first_chunk == NULL
2905      || p_box->data.p_stsc->i_samples_per_chunk == NULL
2906      || p_box->data.p_stsc->i_sample_description_index == NULL ) )
2907     {
2908         MP4_READBOX_EXIT( 0 );
2909     }
2910     p_box->data.p_stsc->i_entry_count = count;
2911
2912     for( uint32_t i = 0; i < count;i++ )
2913     {
2914         MP4_GET4BYTES( p_box->data.p_stsc->i_first_chunk[i] );
2915         MP4_GET4BYTES( p_box->data.p_stsc->i_samples_per_chunk[i] );
2916         MP4_GET4BYTES( p_box->data.p_stsc->i_sample_description_index[i] );
2917     }
2918
2919 #ifdef MP4_VERBOSE
2920     msg_Dbg( p_stream, "read box: \"stsc\" entry-count %d",
2921                       p_box->data.p_stsc->i_entry_count );
2922
2923 #endif
2924     MP4_READBOX_EXIT( 1 );
2925 }
2926
2927 static void MP4_FreeBox_sdp( MP4_Box_t *p_box )
2928 {
2929     free( p_box->data.p_sdp->psz_text );
2930 }
2931
2932 static int MP4_ReadBox_sdp( stream_t *p_stream, MP4_Box_t *p_box )
2933 {
2934    MP4_READBOX_ENTER( MP4_Box_data_sdp_t, MP4_FreeBox_sdp );
2935
2936    MP4_GETSTRINGZ( p_box->data.p_sdp->psz_text );
2937
2938    MP4_READBOX_EXIT( 1 );
2939 }
2940
2941 static void MP4_FreeBox_rtp( MP4_Box_t *p_box )
2942 {
2943     free( p_box->data.p_moviehintinformation_rtp->psz_text );
2944 }
2945
2946 static int MP4_ReadBox_rtp( stream_t *p_stream, MP4_Box_t *p_box )
2947 {
2948     MP4_READBOX_ENTER( MP4_Box_data_moviehintinformation_rtp_t, MP4_FreeBox_rtp );
2949
2950     MP4_GET4BYTES( p_box->data.p_moviehintinformation_rtp->i_description_format );
2951
2952     MP4_GETSTRINGZ( p_box->data.p_moviehintinformation_rtp->psz_text );
2953
2954     MP4_READBOX_EXIT( 1 );
2955 }
2956
2957 static int MP4_ReadBox_tims( stream_t *p_stream, MP4_Box_t *p_box )
2958 {
2959     MP4_READBOX_ENTER( MP4_Box_data_tims_t, NULL );
2960
2961     MP4_GET4BYTES( p_box->data.p_tims->i_timescale );
2962
2963     MP4_READBOX_EXIT( 1 );
2964 }
2965
2966 static int MP4_ReadBox_tsro( stream_t *p_stream, MP4_Box_t *p_box )
2967 {
2968     MP4_READBOX_ENTER( MP4_Box_data_tsro_t, NULL );
2969
2970     MP4_GET4BYTES( p_box->data.p_tsro->i_offset );
2971
2972     MP4_READBOX_EXIT( 1 );
2973 }
2974
2975 static int MP4_ReadBox_tssy( stream_t *p_stream, MP4_Box_t *p_box )
2976 {
2977     MP4_READBOX_ENTER( MP4_Box_data_tssy_t,  NULL );
2978
2979     MP4_GET1BYTE( p_box->data.p_tssy->i_reserved_timestamp_sync );
2980
2981     MP4_READBOX_EXIT( 1 );
2982 }
2983
2984 static void MP4_FreeBox_stco_co64( MP4_Box_t *p_box )
2985 {
2986     free( p_box->data.p_co64->i_chunk_offset );
2987 }
2988
2989 static int MP4_ReadBox_stco_co64( stream_t *p_stream, MP4_Box_t *p_box )
2990 {
2991     const bool sixtyfour = p_box->i_type != ATOM_stco;
2992     uint32_t count;
2993
2994     MP4_READBOX_ENTER( MP4_Box_data_co64_t, MP4_FreeBox_stco_co64 );
2995
2996     MP4_GETVERSIONFLAGS( p_box->data.p_co64 );
2997     MP4_GET4BYTES( count );
2998
2999     if( (sixtyfour ? UINT64_C(8) : UINT64_C(4)) * count > i_read )
3000         MP4_READBOX_EXIT( 0 );
3001
3002     p_box->data.p_co64->i_chunk_offset = vlc_alloc( count, sizeof(uint64_t) );
3003     if( unlikely(p_box->data.p_co64->i_chunk_offset == NULL) )
3004         MP4_READBOX_EXIT( 0 );
3005     p_box->data.p_co64->i_entry_count = count;
3006
3007     for( uint32_t i = 0; i < count; i++ )
3008     {
3009         if( sixtyfour )
3010             MP4_GET8BYTES( p_box->data.p_co64->i_chunk_offset[i] );
3011         else
3012             MP4_GET4BYTES( p_box->data.p_co64->i_chunk_offset[i] );
3013     }
3014
3015 #ifdef MP4_VERBOSE
3016     msg_Dbg( p_stream, "read box: \"co64\" entry-count %d",
3017                       p_box->data.p_co64->i_entry_count );
3018
3019 #endif
3020     MP4_READBOX_EXIT( 1 );
3021 }
3022
3023 static void MP4_FreeBox_stss( MP4_Box_t *p_box )
3024 {
3025     free( p_box->data.p_stss->i_sample_number );
3026 }
3027
3028 static int MP4_ReadBox_stss( stream_t *p_stream, MP4_Box_t *p_box )
3029 {
3030     uint32_t count;
3031
3032     MP4_READBOX_ENTER( MP4_Box_data_stss_t, MP4_FreeBox_stss );
3033
3034     MP4_GETVERSIONFLAGS( p_box->data.p_stss );
3035     MP4_GET4BYTES( count );
3036
3037     if( UINT64_C(4) * count > i_read )
3038         MP4_READBOX_EXIT( 0 );
3039
3040     p_box->data.p_stss->i_sample_number = vlc_alloc( count, sizeof(uint32_t) );
3041     if( unlikely( p_box->data.p_stss->i_sample_number == NULL ) )
3042         MP4_READBOX_EXIT( 0 );
3043     p_box->data.p_stss->i_entry_count = count;
3044
3045     for( uint32_t i = 0; i < count; i++ )
3046     {
3047         MP4_GET4BYTES( p_box->data.p_stss->i_sample_number[i] );
3048         /* XXX in libmp4 sample begin at 0 */
3049         p_box->data.p_stss->i_sample_number[i]--;
3050     }
3051
3052 #ifdef MP4_VERBOSE
3053     msg_Dbg( p_stream, "read box: \"stss\" entry-count %d",
3054                       p_box->data.p_stss->i_entry_count );
3055
3056 #endif
3057     MP4_READBOX_EXIT( 1 );
3058 }
3059
3060 static void MP4_FreeBox_stsh( MP4_Box_t *p_box )
3061 {
3062     free( p_box->data.p_stsh->i_shadowed_sample_number );
3063     free( p_box->data.p_stsh->i_sync_sample_number );
3064 }
3065
3066 static int MP4_ReadBox_stsh( stream_t *p_stream, MP4_Box_t *p_box )
3067 {
3068     uint32_t count;
3069
3070     MP4_READBOX_ENTER( MP4_Box_data_stsh_t, MP4_FreeBox_stsh );
3071
3072     MP4_GETVERSIONFLAGS( p_box->data.p_stsh );
3073     MP4_GET4BYTES( count );
3074
3075     if( UINT64_C(8) * count > i_read )
3076         MP4_READBOX_EXIT( 0 );
3077
3078     p_box->data.p_stsh->i_shadowed_sample_number = vlc_alloc( count,
3079                                                             sizeof(uint32_t) );
3080     p_box->data.p_stsh->i_sync_sample_number = vlc_alloc( count,
3081                                                           sizeof(uint32_t) );
3082     if( p_box->data.p_stsh->i_shadowed_sample_number == NULL
3083      || p_box->data.p_stsh->i_sync_sample_number == NULL )
3084         MP4_READBOX_EXIT( 0 );
3085     p_box->data.p_stsh->i_entry_count = count;
3086
3087     for( uint32_t i = 0; i < p_box->data.p_stss->i_entry_count; i++ )
3088     {
3089         MP4_GET4BYTES( p_box->data.p_stsh->i_shadowed_sample_number[i] );
3090         MP4_GET4BYTES( p_box->data.p_stsh->i_sync_sample_number[i] );
3091     }
3092
3093 #ifdef MP4_VERBOSE
3094     msg_Dbg( p_stream, "read box: \"stsh\" entry-count %d",
3095                       p_box->data.p_stsh->i_entry_count );
3096 #endif
3097     MP4_READBOX_EXIT( 1 );
3098 }
3099
3100 static void MP4_FreeBox_stdp( MP4_Box_t *p_box )
3101 {
3102     free( p_box->data.p_stdp->i_priority );
3103 }
3104
3105 static int MP4_ReadBox_stdp( stream_t *p_stream, MP4_Box_t *p_box )
3106 {
3107     MP4_READBOX_ENTER( MP4_Box_data_stdp_t, MP4_FreeBox_stdp );
3108
3109     MP4_GETVERSIONFLAGS( p_box->data.p_stdp );
3110
3111     p_box->data.p_stdp->i_priority =
3112         calloc( i_read / 2, sizeof(uint16_t) );
3113
3114     if( unlikely( !p_box->data.p_stdp->i_priority ) )
3115         MP4_READBOX_EXIT( 0 );
3116
3117     for( unsigned i = 0; i < i_read / 2 ; i++ )
3118     {
3119         MP4_GET2BYTES( p_box->data.p_stdp->i_priority[i] );
3120     }
3121
3122 #ifdef MP4_VERBOSE
3123     msg_Dbg( p_stream, "read box: \"stdp\" entry-count %"PRId64,
3124                       i_read / 2 );
3125
3126 #endif
3127     MP4_READBOX_EXIT( 1 );
3128 }
3129
3130 static void MP4_FreeBox_elst( MP4_Box_t *p_box )
3131 {
3132     free( p_box->data.p_elst->i_segment_duration );
3133     free( p_box->data.p_elst->i_media_time );
3134     free( p_box->data.p_elst->i_media_rate_integer );
3135     free( p_box->data.p_elst->i_media_rate_fraction );
3136 }
3137
3138 static int MP4_ReadBox_elst( stream_t *p_stream, MP4_Box_t *p_box )
3139 {
3140     uint32_t count;
3141
3142     MP4_READBOX_ENTER( MP4_Box_data_elst_t, MP4_FreeBox_elst );
3143
3144     MP4_GETVERSIONFLAGS( p_box->data.p_elst );
3145     MP4_GET4BYTES( count );
3146
3147     if( count == 0 )
3148         MP4_READBOX_EXIT( 1 );
3149
3150     uint32_t i_entries_max = i_read / ((p_box->data.p_elst->i_version == 1) ? 20 : 12);
3151     if( count > i_entries_max )
3152         count = i_entries_max;
3153
3154     p_box->data.p_elst->i_segment_duration = vlc_alloc( count,
3155                                                         sizeof(uint64_t) );
3156     p_box->data.p_elst->i_media_time = vlc_alloc( count, sizeof(int64_t) );
3157     p_box->data.p_elst->i_media_rate_integer = vlc_alloc( count,
3158                                                           sizeof(uint16_t) );
3159     p_box->data.p_elst->i_media_rate_fraction = vlc_alloc( count,
3160                                                            sizeof(uint16_t) );
3161     if( p_box->data.p_elst->i_segment_duration == NULL
3162      || p_box->data.p_elst->i_media_time == NULL
3163      || p_box->data.p_elst->i_media_rate_integer == NULL
3164      || p_box->data.p_elst->i_media_rate_fraction == NULL )
3165     {
3166         MP4_READBOX_EXIT( 0 );
3167     }
3168     p_box->data.p_elst->i_entry_count = count;
3169
3170     for( uint32_t i = 0; i < count; i++ )
3171     {
3172         uint64_t segment_duration;
3173         int64_t media_time;
3174
3175         if( p_box->data.p_elst->i_version == 1 )
3176         {
3177             union { int64_t s; uint64_t u; } u;
3178
3179             MP4_GET8BYTES( segment_duration );
3180             MP4_GET8BYTES( u.u );
3181             media_time = u.s;
3182         }
3183         else
3184         {
3185             union { int32_t s; uint32_t u; } u;
3186
3187             MP4_GET4BYTES( segment_duration );
3188             MP4_GET4BYTES( u.u );
3189             media_time = u.s;
3190         }
3191
3192         p_box->data.p_elst->i_segment_duration[i] = segment_duration;
3193         p_box->data.p_elst->i_media_time[i] = media_time;
3194         MP4_GET2BYTES( p_box->data.p_elst->i_media_rate_integer[i] );
3195         MP4_GET2BYTES( p_box->data.p_elst->i_media_rate_fraction[i] );
3196     }
3197
3198 #ifdef MP4_VERBOSE
3199     msg_Dbg( p_stream, "read box: \"elst\" entry-count %" PRIu32,
3200              p_box->data.p_elst->i_entry_count );
3201 #endif
3202     MP4_READBOX_EXIT( 1 );
3203 }
3204
3205 static void MP4_FreeBox_cprt( MP4_Box_t *p_box )
3206 {
3207     free( p_box->data.p_cprt->psz_notice );
3208 }
3209
3210 static int MP4_ReadBox_cprt( stream_t *p_stream, MP4_Box_t *p_box )
3211 {
3212     uint16_t i_language;
3213     bool b_mac;
3214
3215     MP4_READBOX_ENTER( MP4_Box_data_cprt_t, MP4_FreeBox_cprt );
3216
3217     MP4_GETVERSIONFLAGS( p_box->data.p_cprt );
3218
3219     MP4_GET2BYTES( i_language );
3220     decodeQtLanguageCode( i_language, p_box->data.p_cprt->rgs_language, &b_mac );
3221
3222     MP4_GETSTRINGZ( p_box->data.p_cprt->psz_notice );
3223
3224 #ifdef MP4_VERBOSE
3225     msg_Dbg( p_stream, "read box: \"cprt\" language %3.3s notice %s",
3226                       p_box->data.p_cprt->rgs_language,
3227                       p_box->data.p_cprt->psz_notice );
3228
3229 #endif
3230     MP4_READBOX_EXIT( 1 );
3231 }
3232
3233 static int MP4_ReadBox_dcom( stream_t *p_stream, MP4_Box_t *p_box )
3234 {
3235     MP4_READBOX_ENTER( MP4_Box_data_dcom_t, NULL );
3236
3237     MP4_GETFOURCC( p_box->data.p_dcom->i_algorithm );
3238 #ifdef MP4_VERBOSE
3239     msg_Dbg( p_stream,
3240              "read box: \"dcom\" compression algorithm : %4.4s",
3241                       (char*)&p_box->data.p_dcom->i_algorithm );
3242 #endif
3243     MP4_READBOX_EXIT( 1 );
3244 }
3245
3246 static void MP4_FreeBox_cmvd( MP4_Box_t *p_box )
3247 {
3248     free( p_box->data.p_cmvd->p_data );
3249 }
3250
3251 static int MP4_ReadBox_cmvd( stream_t *p_stream, MP4_Box_t *p_box )
3252 {
3253     MP4_READBOX_ENTER( MP4_Box_data_cmvd_t, MP4_FreeBox_cmvd );
3254
3255     MP4_GET4BYTES( p_box->data.p_cmvd->i_uncompressed_size );
3256
3257     p_box->data.p_cmvd->i_compressed_size = i_read;
3258
3259     if( !( p_box->data.p_cmvd->p_data = malloc( i_read ) ) )
3260         MP4_READBOX_EXIT( 0 );
3261
3262     /* now copy compressed data */
3263     memcpy( p_box->data.p_cmvd->p_data, p_peek,i_read);
3264
3265     p_box->data.p_cmvd->b_compressed = 1;
3266
3267 #ifdef MP4_VERBOSE
3268     msg_Dbg( p_stream, "read box: \"cmvd\" compressed data size %d",
3269                       p_box->data.p_cmvd->i_compressed_size );
3270 #endif
3271
3272     MP4_READBOX_EXIT( 1 );
3273 }
3274
3275 static int MP4_ReadBox_cmov( stream_t *p_stream, MP4_Box_t *p_box )
3276 {
3277     MP4_Box_t *p_dcom;
3278     MP4_Box_t *p_cmvd;
3279
3280 #ifdef HAVE_ZLIB_H
3281     stream_t *p_stream_memory;
3282     z_stream z_data;
3283     uint8_t *p_data;
3284     int i_result;
3285 #endif
3286
3287     if( !( p_box->data.p_cmov = calloc(1, sizeof( MP4_Box_data_cmov_t ) ) ) )
3288         return 0;
3289
3290     if( !p_box->p_father ||
3291         ( p_box->p_father->i_type != ATOM_moov &&
3292           p_box->p_father->i_type != ATOM_foov ) )
3293     {
3294         msg_Warn( p_stream, "Read box: \"cmov\" box alone" );
3295         return 1;
3296     }
3297
3298     if( !MP4_ReadBoxContainer( p_stream, p_box ) )
3299     {
3300         return 0;
3301     }
3302
3303     if( ( p_dcom = MP4_BoxGet( p_box, "dcom" ) ) == NULL ||
3304         ( p_cmvd = MP4_BoxGet( p_box, "cmvd" ) ) == NULL ||
3305         p_cmvd->data.p_cmvd->p_data == NULL )
3306     {
3307         msg_Warn( p_stream, "read box: \"cmov\" incomplete" );
3308         return 0;
3309     }
3310
3311     if( p_dcom->data.p_dcom->i_algorithm != ATOM_zlib )
3312     {
3313         msg_Dbg( p_stream, "read box: \"cmov\" compression algorithm : %4.4s "
3314                  "not supported", (char*)&p_dcom->data.p_dcom->i_algorithm );
3315         return 0;
3316     }
3317
3318 #ifndef HAVE_ZLIB_H
3319     msg_Dbg( p_stream, "read box: \"cmov\" zlib unsupported" );
3320     return 0;
3321
3322 #else
3323     /* decompress data */
3324     /* allocate a new buffer */
3325     if( !( p_data = malloc( p_cmvd->data.p_cmvd->i_uncompressed_size ) ) )
3326         return 0;
3327     /* init default structures */
3328     z_data.next_in   = p_cmvd->data.p_cmvd->p_data;
3329     z_data.avail_in  = p_cmvd->data.p_cmvd->i_compressed_size;
3330     z_data.next_out  = p_data;
3331     z_data.avail_out = p_cmvd->data.p_cmvd->i_uncompressed_size;
3332     z_data.zalloc    = (alloc_func)Z_NULL;
3333     z_data.zfree     = (free_func)Z_NULL;
3334     z_data.opaque    = (voidpf)Z_NULL;
3335
3336     /* init zlib */
3337     if( inflateInit( &z_data ) != Z_OK )
3338     {
3339         msg_Err( p_stream, "read box: \"cmov\" error while uncompressing" );
3340         free( p_data );
3341         return 0;
3342     }
3343
3344     /* uncompress */
3345     i_result = inflate( &z_data, Z_NO_FLUSH );
3346     if( i_result != Z_OK && i_result != Z_STREAM_END )
3347     {
3348         msg_Err( p_stream, "read box: \"cmov\" error while uncompressing" );
3349         free( p_data );
3350         return 0;
3351     }
3352
3353     if( p_cmvd->data.p_cmvd->i_uncompressed_size != z_data.total_out )
3354     {
3355         msg_Warn( p_stream, "read box: \"cmov\" uncompressing data size "
3356                   "mismatch" );
3357     }
3358     p_cmvd->data.p_cmvd->i_uncompressed_size = z_data.total_out;
3359
3360     /* close zlib */
3361     if( inflateEnd( &z_data ) != Z_OK )
3362     {
3363         msg_Warn( p_stream, "read box: \"cmov\" error while uncompressing "
3364                   "data (ignored)" );
3365     }
3366
3367     free( p_cmvd->data.p_cmvd->p_data );
3368     p_cmvd->data.p_cmvd->p_data = p_data;
3369     p_cmvd->data.p_cmvd->b_compressed = 0;
3370
3371     msg_Dbg( p_stream, "read box: \"cmov\" box successfully uncompressed" );
3372
3373     /* now create a memory stream */
3374     p_stream_memory =
3375         vlc_stream_MemoryNew( VLC_OBJECT(p_stream),
3376                               p_cmvd->data.p_cmvd->p_data,
3377                               p_cmvd->data.p_cmvd->i_uncompressed_size, true );
3378
3379     /* and read uncompressd moov */
3380     p_box->data.p_cmov->p_moov = MP4_ReadBox( p_stream_memory, NULL );
3381
3382     vlc_stream_Delete( p_stream_memory );
3383
3384 #ifdef MP4_VERBOSE
3385     msg_Dbg( p_stream, "read box: \"cmov\" compressed movie header completed");
3386 #endif
3387
3388     return p_box->data.p_cmov->p_moov ? 1 : 0;
3389 #endif /* HAVE_ZLIB_H */
3390 }
3391
3392 static void MP4_FreeBox_rdrf( MP4_Box_t *p_box )
3393 {
3394     free( p_box->data.p_rdrf->psz_ref );
3395 }
3396
3397 static int MP4_ReadBox_rdrf( stream_t *p_stream, MP4_Box_t *p_box )
3398 {
3399     uint32_t i_len;
3400     MP4_READBOX_ENTER( MP4_Box_data_rdrf_t, MP4_FreeBox_rdrf );
3401
3402     MP4_GETVERSIONFLAGS( p_box->data.p_rdrf );
3403     MP4_GETFOURCC( p_box->data.p_rdrf->i_ref_type );
3404     MP4_GET4BYTES( i_len );
3405     i_len++;
3406
3407     if( i_len > 0 )
3408     {
3409         p_box->data.p_rdrf->psz_ref = malloc( i_len );
3410         if( p_box->data.p_rdrf->psz_ref == NULL )
3411             MP4_READBOX_EXIT( 0 );
3412         i_len--;
3413
3414         for( unsigned i = 0; i < i_len; i++ )
3415         {
3416             MP4_GET1BYTE( p_box->data.p_rdrf->psz_ref[i] );
3417         }
3418         p_box->data.p_rdrf->psz_ref[i_len] = '\0';
3419     }
3420     else
3421     {
3422         p_box->data.p_rdrf->psz_ref = NULL;
3423     }
3424
3425 #ifdef MP4_VERBOSE
3426     msg_Dbg( p_stream,
3427             "read box: \"rdrf\" type:%4.4s ref %s",
3428             (char*)&p_box->data.p_rdrf->i_ref_type,
3429             p_box->data.p_rdrf->psz_ref );
3430 #endif
3431     MP4_READBOX_EXIT( 1 );
3432 }
3433
3434
3435
3436 static int MP4_ReadBox_rmdr( stream_t *p_stream, MP4_Box_t *p_box )
3437 {
3438     MP4_READBOX_ENTER( MP4_Box_data_rmdr_t, NULL );
3439
3440     MP4_GETVERSIONFLAGS( p_box->data.p_rmdr );
3441
3442     MP4_GET4BYTES( p_box->data.p_rmdr->i_rate );
3443
3444 #ifdef MP4_VERBOSE
3445     msg_Dbg( p_stream,
3446              "read box: \"rmdr\" rate:%d",
3447              p_box->data.p_rmdr->i_rate );
3448 #endif
3449     MP4_READBOX_EXIT( 1 );
3450 }
3451
3452 static int MP4_ReadBox_rmqu( stream_t *p_stream, MP4_Box_t *p_box )
3453 {
3454     MP4_READBOX_ENTER( MP4_Box_data_rmqu_t, NULL );
3455
3456     MP4_GET4BYTES( p_box->data.p_rmqu->i_quality );
3457
3458 #ifdef MP4_VERBOSE
3459     msg_Dbg( p_stream,
3460              "read box: \"rmqu\" quality:%d",
3461              p_box->data.p_rmqu->i_quality );
3462 #endif
3463     MP4_READBOX_EXIT( 1 );
3464 }
3465
3466 static int MP4_ReadBox_rmvc( stream_t *p_stream, MP4_Box_t *p_box )
3467 {
3468     MP4_READBOX_ENTER( MP4_Box_data_rmvc_t, NULL );
3469     MP4_GETVERSIONFLAGS( p_box->data.p_rmvc );
3470
3471     MP4_GETFOURCC( p_box->data.p_rmvc->i_gestaltType );
3472     MP4_GET4BYTES( p_box->data.p_rmvc->i_val1 );
3473     MP4_GET4BYTES( p_box->data.p_rmvc->i_val2 );
3474     MP4_GET2BYTES( p_box->data.p_rmvc->i_checkType );
3475
3476 #ifdef MP4_VERBOSE
3477     msg_Dbg( p_stream,
3478              "read box: \"rmvc\" gestaltType:%4.4s val1:0x%x val2:0x%x checkType:0x%x",
3479              (char*)&p_box->data.p_rmvc->i_gestaltType,
3480              p_box->data.p_rmvc->i_val1,p_box->data.p_rmvc->i_val2,
3481              p_box->data.p_rmvc->i_checkType );
3482 #endif
3483
3484     MP4_READBOX_EXIT( 1 );
3485 }
3486
3487 static int MP4_ReadBox_frma( stream_t *p_stream, MP4_Box_t *p_box )
3488 {
3489     MP4_READBOX_ENTER( MP4_Box_data_frma_t, NULL );
3490
3491     MP4_GETFOURCC( p_box->data.p_frma->i_type );
3492
3493 #ifdef MP4_VERBOSE
3494     msg_Dbg( p_stream, "read box: \"frma\" i_type:%4.4s",
3495              (char *)&p_box->data.p_frma->i_type );
3496 #endif
3497
3498     MP4_READBOX_EXIT( 1 );
3499 }
3500
3501 static int MP4_ReadBox_skcr( stream_t *p_stream, MP4_Box_t *p_box )
3502 {
3503     MP4_READBOX_ENTER( MP4_Box_data_skcr_t, NULL );
3504
3505     MP4_GET4BYTES( p_box->data.p_skcr->i_init );
3506     MP4_GET4BYTES( p_box->data.p_skcr->i_encr );
3507     MP4_GET4BYTES( p_box->data.p_skcr->i_decr );
3508
3509 #ifdef MP4_VERBOSE
3510     msg_Dbg( p_stream, "read box: \"skcr\" i_init:%d i_encr:%d i_decr:%d",
3511              p_box->data.p_skcr->i_init,
3512              p_box->data.p_skcr->i_encr,
3513              p_box->data.p_skcr->i_decr );
3514 #endif
3515
3516     MP4_READBOX_EXIT( 1 );
3517 }
3518
3519 static int MP4_ReadBox_drms( stream_t *p_stream, MP4_Box_t *p_box )
3520 {
3521     VLC_UNUSED(p_box);
3522     /* ATOMs 'user', 'key', 'iviv', and 'priv' will be skipped,
3523      * so unless data decrypt itself by magic, there will be no playback,
3524      * but we never know... */
3525     msg_Warn( p_stream, "DRM protected streams are not supported." );
3526     return 1;
3527 }
3528
3529 static void MP4_FreeBox_Binary( MP4_Box_t *p_box )
3530 {
3531     free( p_box->data.p_binary->p_blob );
3532 }
3533
3534 static int MP4_ReadBox_Binary( stream_t *p_stream, MP4_Box_t *p_box )
3535 {
3536     MP4_READBOX_ENTER( MP4_Box_data_binary_t, MP4_FreeBox_Binary );
3537     i_read = __MIN( i_read, UINT32_MAX );
3538     if ( i_read > 0 )
3539     {
3540         p_box->data.p_binary->p_blob = malloc( i_read );
3541         if ( p_box->data.p_binary->p_blob )
3542         {
3543             memcpy( p_box->data.p_binary->p_blob, p_peek, i_read );
3544             p_box->data.p_binary->i_blob = i_read;
3545         }
3546     }
3547     MP4_READBOX_EXIT( 1 );
3548 }
3549
3550 static void MP4_FreeBox_data( MP4_Box_t *p_box )
3551 {
3552     free( p_box->data.p_data->p_blob );
3553 }
3554
3555 static int MP4_ReadBox_data( stream_t *p_stream, MP4_Box_t *p_box )
3556 {
3557     MP4_READBOX_ENTER( MP4_Box_data_data_t, MP4_FreeBox_data );
3558     MP4_Box_data_data_t *p_data = p_box->data.p_data;
3559
3560     if ( i_read < 8 || i_read - 8 > UINT32_MAX )
3561         MP4_READBOX_EXIT( 0 );
3562
3563     uint8_t i_type;
3564     MP4_GET1BYTE( i_type );
3565     if ( i_type != 0 )
3566     {
3567 #ifdef MP4_VERBOSE
3568         msg_Dbg( p_stream, "skipping unknown 'data' atom with type %"PRIu8, i_type );
3569 #endif
3570         MP4_READBOX_EXIT( 0 );
3571     }
3572
3573     MP4_GET3BYTES( p_data->e_wellknowntype );
3574     MP4_GET2BYTES( p_data->locale.i_country );
3575     MP4_GET2BYTES( p_data->locale.i_language );
3576 #ifdef MP4_VERBOSE
3577         msg_Dbg( p_stream, "read 'data' atom: knowntype=%"PRIu32", country=%"PRIu16" lang=%"PRIu16
3578                  ", size %"PRIu64" bytes", p_data->e_wellknowntype,
3579                  p_data->locale.i_country, p_data->locale.i_language, i_read );
3580 #endif
3581     p_box->data.p_data->p_blob = malloc( i_read );
3582     if ( !p_box->data.p_data->p_blob )
3583         MP4_READBOX_EXIT( 0 );
3584
3585     p_box->data.p_data->i_blob = i_read;
3586     memcpy( p_box->data.p_data->p_blob, p_peek, i_read);
3587
3588     MP4_READBOX_EXIT( 1 );
3589 }
3590
3591 static int MP4_ReadBox_Metadata( stream_t *p_stream, MP4_Box_t *p_box )
3592 {
3593     const uint8_t *p_peek;
3594     if ( vlc_stream_Peek( p_stream, &p_peek, 16 ) < 16 )
3595         return 0;
3596     if ( vlc_stream_Read( p_stream, NULL, 8 ) < 8 )
3597         return 0;
3598     const uint32_t stoplist[] = { ATOM_data, 0 };
3599     return MP4_ReadBoxContainerChildren( p_stream, p_box, stoplist );
3600 }
3601
3602 /* Chapter support */
3603 static void MP4_FreeBox_chpl( MP4_Box_t *p_box )
3604 {
3605     MP4_Box_data_chpl_t *p_chpl = p_box->data.p_chpl;
3606     for( unsigned i = 0; i < p_chpl->i_chapter; i++ )
3607         free( p_chpl->chapter[i].psz_name );
3608 }
3609
3610 static int MP4_ReadBox_chpl( stream_t *p_stream, MP4_Box_t *p_box )
3611 {
3612     MP4_Box_data_chpl_t *p_chpl;
3613     uint32_t i_dummy;
3614     VLC_UNUSED(i_dummy);
3615     int i;
3616     MP4_READBOX_ENTER( MP4_Box_data_chpl_t, MP4_FreeBox_chpl );
3617
3618     p_chpl = p_box->data.p_chpl;
3619
3620     MP4_GETVERSIONFLAGS( p_chpl );
3621
3622     if ( i_read < 5 || p_chpl->i_version != 0x1 )
3623         MP4_READBOX_EXIT( 0 );
3624
3625     MP4_GET4BYTES( i_dummy );
3626
3627     MP4_GET1BYTE( p_chpl->i_chapter );
3628
3629     for( i = 0; i < p_chpl->i_chapter; i++ )
3630     {
3631         uint64_t i_start;
3632         uint8_t i_len;
3633         int i_copy;
3634         if ( i_read < 9 )
3635             break;
3636         MP4_GET8BYTES( i_start );
3637         MP4_GET1BYTE( i_len );
3638
3639         p_chpl->chapter[i].psz_name = malloc( i_len + 1 );
3640         if( !p_chpl->chapter[i].psz_name )
3641             MP4_READBOX_EXIT( 0 );
3642
3643         i_copy = __MIN( i_len, i_read );
3644         if( i_copy > 0 )
3645             memcpy( p_chpl->chapter[i].psz_name, p_peek, i_copy );
3646         p_chpl->chapter[i].psz_name[i_copy] = '\0';
3647         p_chpl->chapter[i].i_start = i_start;
3648
3649         p_peek += i_copy;
3650         i_read -= i_copy;
3651     }
3652
3653     if ( i != p_chpl->i_chapter )
3654         p_chpl->i_chapter = i;
3655
3656     /* Bubble sort by increasing start date */
3657     do
3658     {
3659         for( i = 0; i < p_chpl->i_chapter - 1; i++ )
3660         {
3661             if( p_chpl->chapter[i].i_start > p_chpl->chapter[i+1].i_start )
3662             {
3663                 char *psz = p_chpl->chapter[i+1].psz_name;
3664                 int64_t i64 = p_chpl->chapter[i+1].i_start;
3665
3666                 p_chpl->chapter[i+1].psz_name = p_chpl->chapter[i].psz_name;
3667                 p_chpl->chapter[i+1].i_start = p_chpl->chapter[i].i_start;
3668
3669                 p_chpl->chapter[i].psz_name = psz;
3670                 p_chpl->chapter[i].i_start = i64;
3671
3672                 i = -1;
3673                 break;
3674             }
3675         }
3676     } while( i == -1 );
3677
3678 #ifdef MP4_VERBOSE
3679     msg_Dbg( p_stream, "read box: \"chpl\" %d chapters",
3680                        p_chpl->i_chapter );
3681 #endif
3682     MP4_READBOX_EXIT( 1 );
3683 }
3684
3685 /* GoPro HiLight tags support */
3686 static void MP4_FreeBox_HMMT( MP4_Box_t *p_box )
3687 {
3688     free( p_box->data.p_hmmt->pi_chapter_start );
3689 }
3690
3691 static int MP4_ReadBox_HMMT( stream_t *p_stream, MP4_Box_t *p_box )
3692 {
3693 #define MAX_CHAPTER_COUNT 100
3694
3695     MP4_Box_data_HMMT_t *p_hmmt;
3696     MP4_READBOX_ENTER( MP4_Box_data_HMMT_t, MP4_FreeBox_HMMT );
3697
3698     if( i_read < 4 )
3699         MP4_READBOX_EXIT( 0 );
3700
3701     p_hmmt = p_box->data.p_hmmt;
3702
3703     MP4_GET4BYTES( p_hmmt->i_chapter_count );
3704
3705     if( p_hmmt->i_chapter_count <= 0 )
3706     {
3707         p_hmmt->pi_chapter_start = NULL;
3708         MP4_READBOX_EXIT( 1 );
3709     }
3710
3711     if( ( i_read / sizeof(uint32_t) ) < p_hmmt->i_chapter_count )
3712         MP4_READBOX_EXIT( 0 );
3713
3714     /* Cameras are allowing a maximum of 100 tags */
3715     if( p_hmmt->i_chapter_count > MAX_CHAPTER_COUNT )
3716         p_hmmt->i_chapter_count = MAX_CHAPTER_COUNT;
3717
3718     p_hmmt->pi_chapter_start = vlc_alloc( p_hmmt->i_chapter_count, sizeof(uint32_t) );
3719     if( p_hmmt->pi_chapter_start == NULL )
3720         MP4_READBOX_EXIT( 0 );
3721
3722     for( uint32_t i = 0; i < p_hmmt->i_chapter_count; i++ )
3723     {
3724         MP4_GET4BYTES( p_hmmt->pi_chapter_start[i] );
3725     }
3726
3727 #ifdef MP4_VERBOSE
3728     msg_Dbg( p_stream, "read box: \"HMMT\" %d HiLight tags", p_hmmt->i_chapter_count );
3729 #endif
3730
3731     MP4_READBOX_EXIT( 1 );
3732 }
3733
3734 static void MP4_FreeBox_tref_generic( MP4_Box_t *p_box )
3735 {
3736     free( p_box->data.p_tref_generic->i_track_ID );
3737 }
3738
3739 static int MP4_ReadBox_tref_generic( stream_t *p_stream, MP4_Box_t *p_box )
3740 {
3741     uint32_t count;
3742
3743     MP4_READBOX_ENTER( MP4_Box_data_tref_generic_t, MP4_FreeBox_tref_generic );
3744
3745     p_box->data.p_tref_generic->i_track_ID = NULL;
3746     count = i_read / sizeof(uint32_t);
3747     p_box->data.p_tref_generic->i_entry_count = count;
3748     p_box->data.p_tref_generic->i_track_ID = vlc_alloc( count,
3749                                                         sizeof(uint32_t) );
3750     if( p_box->data.p_tref_generic->i_track_ID == NULL )
3751         MP4_READBOX_EXIT( 0 );
3752
3753     for( unsigned i = 0; i < count; i++ )
3754     {
3755         MP4_GET4BYTES( p_box->data.p_tref_generic->i_track_ID[i] );
3756     }
3757 #ifdef MP4_VERBOSE
3758         msg_Dbg( p_stream, "read box: \"chap\" %d references",
3759                  p_box->data.p_tref_generic->i_entry_count );
3760 #endif
3761
3762     MP4_READBOX_EXIT( 1 );
3763 }
3764
3765 static void MP4_FreeBox_keys( MP4_Box_t *p_box )
3766 {
3767     for( uint32_t i=0; i<p_box->data.p_keys->i_entry_count; i++ )
3768         free( p_box->data.p_keys->p_entries[i].psz_value );
3769     free( p_box->data.p_keys->p_entries );
3770 }
3771
3772 static int MP4_ReadBox_keys( stream_t *p_stream, MP4_Box_t *p_box )
3773 {
3774     MP4_READBOX_ENTER( MP4_Box_data_keys_t, MP4_FreeBox_keys );
3775
3776     if ( i_read < 8 )
3777         MP4_READBOX_EXIT( 0 );
3778
3779     uint32_t i_count;
3780     MP4_GET4BYTES( i_count ); /* reserved + flags */
3781     if ( i_count != 0 )
3782         MP4_READBOX_EXIT( 0 );
3783