bool b_ordered;
};
+class demux_sys_t;
+
class matroska_segment_t
{
public:
- matroska_segment_t()
+ matroska_segment_t( demux_sys_t *p_demuxer )
:segment(NULL)
,i_timescale(0)
,f_duration(0.0)
,psz_date_utc(NULL)
,i_current_edition(0)
,psz_current_chapter(NULL)
+ ,p_sys(p_demuxer)
+ ,ep(NULL)
{}
+ ~matroska_segment_t()
+ {
+ delete ep;
+ }
+
KaxSegment *segment;
/* time scale */
int64_t i_tags_position;
KaxCluster *cluster;
- KaxSegmentUID segment_uid;
+ KaxSegmentUID segment_uid, prev_segment_uid, next_segment_uid;
vlc_bool_t b_cues;
int i_index;
const chapter_item_t *psz_current_chapter;
std::vector<KaxSegmentFamily> families;
+
+ demux_sys_t *p_sys;
+ EbmlParser *ep;
- chapter_edition_t *Edition()
+ inline chapter_edition_t *Edition()
{
if ( i_current_edition != -1 && i_current_edition < editions.size() )
return &editions[i_current_edition];
class matroska_stream_t
{
public:
- matroska_stream_t()
+ matroska_stream_t( demux_sys_t *p_demuxer )
:in(NULL)
,es(NULL)
- ,ep(NULL)
,i_current_segment(-1)
+ ,p_sys(p_demuxer)
{}
~matroska_stream_t()
{
for ( int i=0; i<segments.size(); i++ )
delete segments[i];
- if ( in )
- delete in;
- if ( es )
- delete es;
- if ( ep )
- delete ep;
+ delete in;
+ delete es;
}
vlc_stream_io_callback *in;
EbmlStream *es;
- EbmlParser *ep;
std::vector<matroska_segment_t*> segments;
int i_current_segment;
- matroska_segment_t *Segment()
+ demux_sys_t *p_sys;
+
+ inline matroska_segment_t *Segment()
{
if ( i_current_segment != -1 && i_current_segment < segments.size() )
return segments[i_current_segment];
return NULL;
}
+
+ matroska_segment_t *FindSegment( KaxSegmentUID & i_uid ) const;
};
class demux_sys_t
std::vector<matroska_stream_t*> streams;
int i_current_stream;
- matroska_stream_t *Stream()
+ inline matroska_stream_t *Stream()
{
if ( i_current_stream != -1 && i_current_stream < streams.size() )
return streams[i_current_stream];
return NULL;
}
+
+ matroska_segment_t *FindSegment( KaxSegmentUID & i_uid ) const;
};
static int Demux ( demux_t * );
p_demux->pf_control = Control;
p_demux->p_sys = p_sys = new demux_sys_t;
- p_stream = new matroska_stream_t;
- p_segment = new matroska_segment_t;
+ p_stream = new matroska_stream_t( p_sys );
+ p_segment = new matroska_segment_t( p_sys );
p_sys->streams.push_back( p_stream );
p_sys->i_current_stream = 0;
p_segment->segment = (KaxSegment*)el;
p_segment->cluster = NULL;
- p_stream->ep = new EbmlParser( p_stream->es, el );
+ p_segment->ep = new EbmlParser( p_stream->es, el );
- while( ( el1 = p_stream->ep->Get() ) != NULL )
+ while( ( el1 = p_segment->ep->Get() ) != NULL )
{
if( MKV_IS_ID( el1, KaxInfo ) )
{
p_segment->cluster = (KaxCluster*)el1;
- p_stream->ep->Down();
+ p_segment->ep->Down();
/* stop parsing the stream */
break;
}
// test wether this file belongs to the our family
bool b_keep_file_opened = false;
StdIOCallback *p_file_io = new StdIOCallback(s_filename.c_str(), MODE_READ);
- EbmlStream *p_stream = new EbmlStream(*p_file_io);
+ EbmlStream *p_estream = new EbmlStream(*p_file_io);
EbmlElement *p_l0, *p_l1, *p_l2;
// verify the EBML Header
- p_l0 = p_stream->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
+ p_l0 = p_estream->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
if (p_l0 == NULL)
{
- delete p_stream;
+ delete p_estream;
delete p_file_io;
continue;
}
- p_l0->SkipData(*p_stream, EbmlHead_Context);
+ matroska_stream_t *p_stream1 = new matroska_stream_t( p_sys );
+ p_sys->streams.push_back( p_stream1 );
+
+ p_l0->SkipData(*p_estream, EbmlHead_Context);
delete p_l0;
// find all segments in this file
- p_l0 = p_stream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);
+ p_l0 = p_estream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);
if (p_l0 == NULL)
{
- delete p_stream;
+ delete p_estream;
delete p_file_io;
continue;
}
{
EbmlParser *ep;
KaxSegmentUID *p_uid = NULL;
+ matroska_segment_t *p_segment1 = new matroska_segment_t( p_sys );
+
+ p_stream1->segments.push_back( p_segment1 );
+
+ ep = new EbmlParser(p_estream, p_l0);
+ p_segment1->ep = ep;
- ep = new EbmlParser(p_stream, p_l0);
bool b_this_segment_matches = false;
while ((p_l1 = ep->Get()))
{
// find the families of this segment
KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);
- p_info->Read(*p_stream, KaxInfo::ClassInfos.Context, i_upper_lvl, p_l2, true);
+ p_info->Read(*p_estream, KaxInfo::ClassInfos.Context, i_upper_lvl, p_l2, true);
for( i = 0; i < p_info->ListSize() && !b_this_segment_matches; i++ )
{
EbmlElement *l = (*p_info)[i];
p_uid = static_cast<KaxSegmentUID*>(l);
if (p_segment->segment_uid == *p_uid)
break;
+ p_segment1->segment_uid = *p_uid;
}
else if( MKV_IS_ID( l, KaxSegmentFamily ) )
{
KaxSegmentFamily *p_fam = static_cast<KaxSegmentFamily*>(l);
std::vector<KaxSegmentFamily>::iterator iter;
- for( iter = p_segment->families.begin();
+ p_segment1->families.push_back( *p_fam );
+/* for( iter = p_segment->families.begin();
iter != p_segment->families.end();
iter++ )
{
if( *iter == *p_fam )
{
b_this_segment_matches = true;
+ p_segment1->families.push_back( *p_fam );
break;
}
- }
+ }*/
}
}
break;
}
}
- p_l0->SkipData(*p_stream, EbmlHead_Context);
+ p_l0->SkipData(*p_estream, EbmlHead_Context);
delete p_l0;
- p_l0 = p_stream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);
+ p_l0 = p_estream->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);
}
if (!b_keep_file_opened)
{
- delete p_stream;
+ delete p_estream;
delete p_file_io;
}
}
return VLC_EGENERIC;
}
- el = p_stream->ep->Get();
- i_level = p_stream->ep->GetLevel();
+ el = p_segment->ep->Get();
+ i_level = p_segment->ep->GetLevel();
if( el == NULL && *pp_block != NULL )
{
if( el == NULL )
{
- if( p_stream->ep->GetLevel() > 1 )
+ if( p_segment->ep->GetLevel() > 1 )
{
- p_stream->ep->Up();
+ p_segment->ep->Up();
continue;
}
msg_Warn( p_demux, "EOF" );
IndexAppendCluster( p_demux, p_segment->cluster );
}
- p_stream->ep->Down();
+ p_segment->ep->Down();
}
else if( MKV_IS_ID( el, KaxCues ) )
{
}
else if( MKV_IS_ID( el, KaxBlockGroup ) )
{
- p_stream->ep->Down();
+ p_segment->ep->Down();
}
}
else if( i_level == 3 )
(*pp_block)->ReadData( p_stream->es->I_O() );
(*pp_block)->SetParent( *p_segment->cluster );
- p_stream->ep->Keep();
+ p_segment->ep->Keep();
}
else if( MKV_IS_ID( el, KaxBlockDuration ) )
{
return;
}
- delete p_stream->ep;
- p_stream->ep = new EbmlParser( p_stream->es, p_segment->segment );
+ delete p_segment->ep;
+ p_segment->ep = new EbmlParser( p_stream->es, p_segment->segment );
p_segment->cluster = NULL;
/* seek without index or without date */