+ /* Skip unread data */
+ const int64_t i_stream_current = stream_Tell( p_demux->s );
+ const int64_t i_stream_skip = (i_stream_position + i_size) - i_stream_current;
+
+ if( i_stream_skip > 0 )
+ {
+ if( stream_Read( p_demux->s, NULL, i_stream_skip ) != i_stream_skip )
+ return VLC_EGENERIC;
+ }
+ else if( i_stream_skip < 0 )
+ {
+ return VLC_EGENERIC;
+ }
+ }
+
+ /* read index if possible */
+ if( p_sys->i_index_offset > 0 )
+ {
+ const int64_t i_position = stream_Tell( p_demux->s );
+
+ HeaderINDX( p_demux );
+
+ if( stream_Seek( p_demux->s, i_position ) )
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+
+static void CodecMetaRead( demux_t *p_demux, const uint8_t **pp_data, int *pi_data )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+
+ /* Title */
+ p_sys->psz_title = MemoryReadString1( pp_data, pi_data );
+ if( p_sys->psz_title )
+ msg_Dbg( p_demux, " - title=`%s'", p_sys->psz_title );
+
+ /* Authors */
+ p_sys->psz_artist = MemoryReadString1( pp_data, pi_data );
+ if( p_sys->psz_artist )
+ msg_Dbg( p_demux, " - artist=`%s'", p_sys->psz_artist );
+
+ /* Copyright */
+ p_sys->psz_copyright = MemoryReadString1( pp_data, pi_data );
+ if( p_sys->psz_copyright )
+ msg_Dbg( p_demux, " - copyright=`%s'", p_sys->psz_copyright );
+
+ /* Comment */
+ p_sys->psz_description = MemoryReadString1( pp_data, pi_data );
+ if( p_sys->psz_description )
+ msg_Dbg( p_demux, " - Comment=`%s'", p_sys->psz_description );
+}
+
+static int CodecVideoParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data, int i_data )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+
+ if( i_data < 34 )
+ return VLC_EGENERIC;
+
+ /* */
+ es_format_t fmt;
+ es_format_Init( &fmt, VIDEO_ES,
+ VLC_FOURCC( p_data[8], p_data[9], p_data[10], p_data[11] ) );
+ fmt.video.i_width = GetWBE( &p_data[12] );
+ fmt.video.i_height= GetWBE( &p_data[14] );
+ fmt.video.i_frame_rate = (GetWBE( &p_data[22] ) << 16) | GetWBE( &p_data[24] );
+ fmt.video.i_frame_rate_base = 1 << 16;
+
+ fmt.i_extra = 8;
+ fmt.p_extra = malloc( 8 );
+ if( !fmt.p_extra )
+ return VLC_ENOMEM;
+
+ memcpy( fmt.p_extra, &p_data[26], 8 );
+
+ //msg_Dbg( p_demux, " - video 0x%08x 0x%08x", dw0, dw1 );
+
+ /* */
+ switch( GetDWBE( &p_data[30] ) )
+ {
+ case 0x10003000:
+ case 0x10003001:
+ fmt.i_codec = VLC_FOURCC( 'R','V','1','3' );
+ break;
+ case 0x20001000:
+ case 0x20100001:
+ case 0x20200002:
+ case 0x20201002:
+ fmt.i_codec = VLC_FOURCC( 'R','V','2','0' );
+ break;
+ case 0x30202002:
+ fmt.i_codec = VLC_FOURCC( 'R','V','3','0' );
+ break;
+ case 0x40000000:
+ fmt.i_codec = VLC_FOURCC( 'R','V','4','0' );
+ break;
+ }
+ msg_Dbg( p_demux, " - video %4.4s %dx%d - %8.8x",
+ (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height, GetDWBE( &p_data[30] ) );
+
+ real_track_t *tk = malloc( sizeof( *tk ) );
+ if( !tk )
+ {
+ es_format_Clean( &fmt );
+ return VLC_ENOMEM;
+ }
+ tk->i_out_subpacket = 0;
+ tk->i_subpacket = 0;
+ tk->i_subpackets = 0;
+ tk->p_subpackets = NULL;
+ tk->p_subpackets_timecode = NULL;
+ tk->i_id = i_tk_id;
+ tk->fmt = fmt;
+ tk->i_frame_num = -1;
+ tk->i_frame_size = 0;
+ tk->p_frame = NULL;
+ tk->i_last_dts = 0;
+ tk->p_es = es_out_Add( p_demux->out, &fmt );
+
+ TAB_APPEND( p_sys->i_track, p_sys->track, tk );
+ return VLC_SUCCESS;
+}
+static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data, int i_data )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ es_format_t fmt;
+
+ if( i_data < 6 )
+ return VLC_EGENERIC;
+
+ int i_flavor = 0;
+ int i_coded_frame_size = 0;
+ int i_subpacket_h = 0;
+ int i_frame_size = 0;
+ int i_subpacket_size = 0;
+ char p_genr[4];
+ int i_version = GetWBE( &p_data[4] );
+ int i_extra_codec = 0;
+
+ msg_Dbg( p_demux, " - audio version=%d", i_version );
+
+ es_format_Init( &fmt, AUDIO_ES, 0 );
+
+ RVoid( &p_data, &i_data, 6 ); /* 4 + version */
+ if( i_version == 3 ) /* RMF version 3 or .ra version 3 */
+ {
+ RVoid( &p_data, &i_data, 2 + 10 + 4 );
+
+ /* Meta Datas */
+ CodecMetaRead( p_demux, &p_data, &i_data );
+
+ RVoid( &p_data, &i_data, 1 + 1 );
+ if( i_data >= 4 )
+ memcpy( &fmt.i_codec, p_data, 4 );
+ RVoid( &p_data, &i_data, 4 );
+
+ fmt.audio.i_channels = 1; /* This is always the case in rm3 */
+ fmt.audio.i_rate = 8000;
+
+ msg_Dbg( p_demux, " - audio codec=%4.4s channels=%d rate=%dHz",
+ (char*)&fmt.i_codec, fmt.audio.i_channels, fmt.audio.i_rate );
+ }
+ else /* RMF version 4/5 or .ra version 4 */
+ {
+ RVoid( &p_data, &i_data, 2 + 4 + 4 + 2 + 4 );
+ i_flavor = R16( &p_data, &i_data );
+ i_coded_frame_size = R32( &p_data, &i_data );
+ RVoid( &p_data, &i_data, 4 + 4 + 4 );
+ i_subpacket_h = R16( &p_data, &i_data );
+ i_frame_size = R16( &p_data, &i_data );
+ i_subpacket_size = R16( &p_data, &i_data );
+ if( !i_frame_size || !i_coded_frame_size )
+ return VLC_EGENERIC;
+
+ RVoid( &p_data, &i_data, 2 + (i_version == 5 ? 6 : 0 ) );
+
+ fmt.audio.i_rate = R16( &p_data, &i_data );
+ RVoid( &p_data, &i_data, 2 );
+ fmt.audio.i_bitspersample = R16( &p_data, &i_data );
+ fmt.audio.i_channels = R16( &p_data, &i_data );
+ fmt.audio.i_blockalign = i_frame_size;
+
+ if( i_version == 5 )
+ {
+ if( i_data >= 8 )