+/* Chapters */
+static void LoadChapterGpac( demux_t *p_demux, MP4_Box_t *p_chpl )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ int i;
+
+ p_sys->p_title = vlc_input_title_New();
+ for( i = 0; i < p_chpl->data.p_chpl->i_chapter; i++ )
+ {
+ seekpoint_t *s = vlc_seekpoint_New();
+
+ s->psz_name = strdup( p_chpl->data.p_chpl->chapter[i].psz_name );
+ EnsureUTF8( s->psz_name );
+ s->i_time_offset = p_chpl->data.p_chpl->chapter[i].i_start / 10;
+ TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
+ }
+}
+static void LoadChapterApple( demux_t *p_demux, mp4_track_t *tk )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+
+ for( tk->i_sample = 0; tk->i_sample < tk->i_sample_count; tk->i_sample++ )
+ {
+ const int64_t i_dts = MP4_TrackGetDTS( p_demux, tk );
+ const int64_t i_pts_delta = MP4_TrackGetPTSDelta( tk );
+ const unsigned int i_size = MP4_TrackSampleSize( tk );
+
+ if( i_size > 0 && !stream_Seek( p_demux->s, MP4_TrackGetPos( tk ) ) )
+ {
+ char p_buffer[256];
+ const int i_read = stream_Read( p_demux->s, p_buffer, __MIN( sizeof(p_buffer), i_size ) );
+ const int i_len = __MIN( GetWBE(p_buffer), i_read-2 );
+
+ if( i_len > 0 )
+ {
+ seekpoint_t *s = vlc_seekpoint_New();
+
+ s->psz_name = strndup( &p_buffer[2], i_len );
+ EnsureUTF8( s->psz_name );
+
+ s->i_time_offset = i_dts + __MAX( i_pts_delta, 0 );
+
+ if( !p_sys->p_title )
+ p_sys->p_title = vlc_input_title_New();
+ TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
+ }
+ }
+ if( tk->i_sample+1 >= tk->chunk[tk->i_chunk].i_sample_first +
+ tk->chunk[tk->i_chunk].i_sample_count )
+ tk->i_chunk++;
+ }
+}
+static void LoadChapter( demux_t *p_demux )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ MP4_Box_t *p_chpl;
+
+ if( ( p_chpl = MP4_BoxGet( p_sys->p_root, "/moov/udta/chpl" ) ) && p_chpl->data.p_chpl->i_chapter > 0 )
+ {
+ LoadChapterGpac( p_demux, p_chpl );
+ }
+ else if( p_sys->p_tref_chap )
+ {
+ MP4_Box_data_tref_generic_t *p_chap = p_sys->p_tref_chap->data.p_tref_generic;
+ unsigned int i, j;
+
+ /* Load the first subtitle track like quicktime */
+ for( i = 0; i < p_chap->i_entry_count; i++ )
+ {
+ for( j = 0; j < p_sys->i_tracks; j++ )
+ {
+ mp4_track_t *tk = &p_sys->track[j];
+ if( tk->b_ok && tk->i_track_ID == p_chap->i_track_ID[i] &&
+ tk->fmt.i_cat == SPU_ES && tk->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) )
+ break;
+ }
+ if( j < p_sys->i_tracks )
+ {
+ LoadChapterApple( p_demux, &p_sys->track[i] );
+ break;
+ }
+ }
+ }
+}