+ msg_Dbg( p_demux, " - file version=0x%x num headers=%d",
+ GetDWBE( &p_buffer[0] ), GetDWBE( &p_buffer[4] ) );
+ return VLC_SUCCESS;
+}
+/**
+ * This function parses the PROP properties chunk.
+ */
+static int HeaderPROP( demux_t *p_demux )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+
+ uint8_t p_buffer[40];
+ int i_flags;
+
+ if( stream_Read( p_demux->s, p_buffer, 40 ) < 40 )
+ return VLC_EGENERIC;
+
+ msg_Dbg( p_demux, " - max bitrate=%d avg bitrate=%d",
+ GetDWBE(&p_buffer[0]), GetDWBE(&p_buffer[4]) );
+ msg_Dbg( p_demux, " - max packet size=%d avg bitrate=%d",
+ GetDWBE(&p_buffer[8]), GetDWBE(&p_buffer[12]) );
+ msg_Dbg( p_demux, " - packets count=%d", GetDWBE(&p_buffer[16]) );
+ msg_Dbg( p_demux, " - duration=%d ms", GetDWBE(&p_buffer[20]) );
+ msg_Dbg( p_demux, " - preroll=%d ms", GetDWBE(&p_buffer[24]) );
+ msg_Dbg( p_demux, " - index offset=%d", GetDWBE(&p_buffer[28]) );
+ msg_Dbg( p_demux, " - data offset=%d", GetDWBE(&p_buffer[32]) );
+ msg_Dbg( p_demux, " - num streams=%d", GetWBE(&p_buffer[36]) );
+
+ /* set the duration for export in control */
+ p_sys->i_our_duration = GetDWBE(&p_buffer[20]);
+
+ p_sys->i_index_offset = GetDWBE(&p_buffer[28]);
+
+ i_flags = GetWBE(&p_buffer[38]);
+ msg_Dbg( p_demux, " - flags=0x%x %s%s%s",
+ i_flags,
+ i_flags&0x0001 ? "PN_SAVE_ENABLED " : "",
+ i_flags&0x0002 ? "PN_PERFECT_PLAY_ENABLED " : "",
+ i_flags&0x0004 ? "PN_LIVE_BROADCAST" : "" );
+
+ return VLC_SUCCESS;
+}
+/**
+ * This functions parses the CONT commentairs chunk.
+ */
+static int HeaderCONT( demux_t *p_demux )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+
+ /* */
+ p_sys->psz_title = StreamReadString2( p_demux->s );
+ if( p_sys->psz_title )
+ msg_Dbg( p_demux, " - title=`%s'", p_sys->psz_title );
+
+ /* */
+ p_sys->psz_artist = StreamReadString2( p_demux->s );
+ if( p_sys->psz_artist )
+ msg_Dbg( p_demux, " - artist=`%s'", p_sys->psz_artist );
+
+ /* */
+ p_sys->psz_copyright = StreamReadString2( p_demux->s );
+ if( p_sys->psz_copyright )
+ msg_Dbg( p_demux, " - copyright=`%s'", p_sys->psz_copyright );
+
+ /* */
+ p_sys->psz_description = StreamReadString2( p_demux->s );
+ if( p_sys->psz_description )
+ msg_Dbg( p_demux, " - comment=`%s'", p_sys->psz_description );
+
+ return VLC_SUCCESS;
+}
+/**
+ * This function parses the MDPR (Media properties) chunk.
+ */
+static int HeaderMDPR( demux_t *p_demux )
+{
+ uint8_t p_buffer[30];
+
+ if( stream_Read( p_demux->s, p_buffer, 30 ) < 30 )
+ return VLC_EGENERIC;
+
+ const int i_num = GetWBE( &p_buffer[0] );
+ msg_Dbg( p_demux, " - id=0x%x", i_num );
+ msg_Dbg( p_demux, " - max bitrate=%d avg bitrate=%d",
+ GetDWBE(&p_buffer[2]), GetDWBE(&p_buffer[6]) );
+ msg_Dbg( p_demux, " - max packet size=%d avg packet size=%d",
+ GetDWBE(&p_buffer[10]), GetDWBE(&p_buffer[14]) );
+ msg_Dbg( p_demux, " - start time=%d", GetDWBE(&p_buffer[18]) );
+ msg_Dbg( p_demux, " - preroll=%d", GetDWBE(&p_buffer[22]) );
+ msg_Dbg( p_demux, " - duration=%d", GetDWBE(&p_buffer[26]) );
+
+ /* */
+ const uint8_t *p_peek;
+ int i_peek_org = stream_Peek( p_demux->s, &p_peek, 2 * 256 );
+ int i_peek = i_peek_org;
+ if( i_peek <= 0 )
+ return VLC_EGENERIC;
+
+ char *psz_name = MemoryReadString1( &p_peek, &i_peek );
+ if( psz_name )
+ {
+ msg_Dbg( p_demux, " - name=`%s'", psz_name );
+ free( psz_name );
+ }
+ char *psz_mime = MemoryReadString1( &p_peek, &i_peek );
+ if( psz_mime )
+ {
+ msg_Dbg( p_demux, " - mime=`%s'", psz_mime );
+ free( psz_mime );
+ }
+ const int i_skip = i_peek_org - i_peek;
+ if( i_skip > 0 && stream_Read( p_demux->s, NULL, i_skip ) < i_skip )
+ return VLC_EGENERIC;
+
+ /* */
+ if( stream_Read( p_demux->s, p_buffer, 4 ) < 4 )
+ return VLC_EGENERIC;
+
+ const uint32_t i_size = GetDWBE( p_buffer );
+ if( i_size > 0 )
+ {
+ CodecParse( p_demux, i_size, i_num );
+ unsigned size = stream_Read( p_demux->s, NULL, i_size );
+ if( size < i_size )
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+/**
+ * This function parses DATA chunk (it contains the actual movie data).
+ */
+static int HeaderDATA( demux_t *p_demux, uint32_t i_size )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ uint8_t p_buffer[8];
+
+ if( stream_Read( p_demux->s, p_buffer, 8 ) < 8 )
+ return VLC_EGENERIC;
+
+ p_sys->i_data_offset = stream_Tell( p_demux->s ) - 10;
+ p_sys->i_data_size = i_size;
+ p_sys->i_data_packets_count = GetDWBE( p_buffer );
+ p_sys->i_data_packets = 0;
+ p_sys->i_data_offset_next = GetDWBE( &p_buffer[4] );
+
+ msg_Dbg( p_demux, " - packets count=%d next=%u",
+ p_sys->i_data_packets_count,
+ (unsigned int)p_sys->i_data_offset_next );
+ return VLC_SUCCESS;
+}
+/**
+ * This function parses the INDX (movie index chunk).
+ * It is optional but seeking without it is ... hard.
+ */
+static void HeaderINDX( demux_t *p_demux )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ uint8_t buffer[20];
+
+ uint32_t i_index_count;
+
+ if( p_sys->i_index_offset == 0 )
+ return;
+
+ stream_Seek( p_demux->s, p_sys->i_index_offset );
+
+ if( stream_Read( p_demux->s, buffer, 20 ) < 20 )
+ return ;
+
+ const uint32_t i_id = VLC_FOURCC( buffer[0], buffer[1], buffer[2], buffer[3] );
+ const uint32_t i_size = GetDWBE( &buffer[4] );
+ int i_version = GetWBE( &buffer[8] );
+
+ msg_Dbg( p_demux, "Real index %4.4s size=%d version=%d",
+ (char*)&i_id, i_size, i_version );
+
+ if( (i_size < 20) && (i_id != VLC_FOURCC('I','N','D','X')) )
+ return;
+
+ i_index_count = GetDWBE( &buffer[10] );
+
+ msg_Dbg( p_demux, "Real Index : num : %d ", i_index_count );
+
+ if( i_index_count >= ( 0xffffffff / sizeof(*p_sys->p_index) ) )
+ return;
+
+ if( GetDWBE( &buffer[16] ) > 0 )
+ msg_Dbg( p_demux, "Real Index: Does next index exist? %d ",
+ GetDWBE( &buffer[16] ) );
+
+ /* One extra entry is allocated (that MUST be set to 0) to identify the
+ * end of the index.
+ * TODO add a clean entry count (easier to build index on the fly) */
+ p_sys->p_index = calloc( i_index_count + 1, sizeof(*p_sys->p_index) );
+ if( !p_sys->p_index )
+ return;
+
+ for( unsigned int i = 0; i < i_index_count; i++ )
+ {
+ uint8_t p_entry[14];
+
+ if( stream_Read( p_demux->s, p_entry, 14 ) < 14 )
+ return ;
+
+ if( GetWBE( &p_entry[0] ) != 0 )
+ {
+ msg_Dbg( p_demux, "Real Index: invaild version of index entry %d ",
+ GetWBE( &p_entry[0] ) );
+ return;