Commit 291c6479 authored by Steve Lhomme's avatar Steve Lhomme

mkv.cpp: prepare the code to handle seemless segment switching

parent cb48de28
...@@ -362,13 +362,11 @@ public: ...@@ -362,13 +362,11 @@ public:
bool b_ordered; bool b_ordered;
}; };
class demux_sys_t class matroska_segment_t
{ {
public: public:
demux_sys_t() matroska_segment_t()
:in(NULL) :segment(NULL)
,es(NULL)
,ep(NULL)
,i_timescale(0) ,i_timescale(0)
,f_duration(0.0) ,f_duration(0.0)
,i_track(0) ,i_track(0)
...@@ -376,11 +374,7 @@ public: ...@@ -376,11 +374,7 @@ public:
,i_cues_position(0) ,i_cues_position(0)
,i_chapters_position(0) ,i_chapters_position(0)
,i_tags_position(0) ,i_tags_position(0)
,segment(NULL)
,cluster(NULL) ,cluster(NULL)
,i_pts(0)
,i_start_pts(0)
,i_chapter_time(0)
,b_cues(false) ,b_cues(false)
,i_index(0) ,i_index(0)
,i_index_max(0) ,i_index_max(0)
...@@ -390,15 +384,11 @@ public: ...@@ -390,15 +384,11 @@ public:
,psz_segment_filename(NULL) ,psz_segment_filename(NULL)
,psz_title(NULL) ,psz_title(NULL)
,psz_date_utc(NULL) ,psz_date_utc(NULL)
,meta(NULL)
,title(NULL)
,i_current_edition(0) ,i_current_edition(0)
,psz_current_chapter(NULL) ,psz_current_chapter(NULL)
{} {}
vlc_stream_io_callback *in; KaxSegment *segment;
EbmlStream *es;
EbmlParser *ep;
/* time scale */ /* time scale */
uint64_t i_timescale; uint64_t i_timescale;
...@@ -415,15 +405,9 @@ public: ...@@ -415,15 +405,9 @@ public:
int64_t i_chapters_position; int64_t i_chapters_position;
int64_t i_tags_position; int64_t i_tags_position;
/* current data */
KaxSegment *segment;
KaxCluster *cluster; KaxCluster *cluster;
KaxSegmentUID segment_uid; KaxSegmentUID segment_uid;
mtime_t i_pts;
mtime_t i_start_pts;
mtime_t i_chapter_time;
vlc_bool_t b_cues; vlc_bool_t b_cues;
int i_index; int i_index;
int i_index_max; int i_index_max;
...@@ -436,16 +420,93 @@ public: ...@@ -436,16 +420,93 @@ public:
char *psz_title; char *psz_title;
char *psz_date_utc; char *psz_date_utc;
std::vector<chapter_edition_t> editions;
int i_current_edition;
const chapter_item_t *psz_current_chapter;
std::vector<KaxSegmentFamily> families;
chapter_edition_t *Edition()
{
if ( i_current_edition != -1 && i_current_edition < editions.size() )
return &editions[i_current_edition];
return NULL;
}
};
class matroska_stream_t
{
public:
matroska_stream_t()
:in(NULL)
,es(NULL)
,ep(NULL)
,i_current_segment(-1)
{}
~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;
}
vlc_stream_io_callback *in;
EbmlStream *es;
EbmlParser *ep;
std::vector<matroska_segment_t*> segments;
int i_current_segment;
matroska_segment_t *Segment()
{
if ( i_current_segment != -1 && i_current_segment < segments.size() )
return segments[i_current_segment];
return NULL;
}
};
class demux_sys_t
{
public:
demux_sys_t()
:i_pts(0)
,i_start_pts(0)
,i_chapter_time(0)
,meta(NULL)
,title(NULL)
,i_current_stream(-1)
{}
~demux_sys_t()
{
for (int i=0; i<streams.size(); i++)
delete streams[i];
}
/* current data */
mtime_t i_pts;
mtime_t i_start_pts;
mtime_t i_chapter_time;
vlc_meta_t *meta; vlc_meta_t *meta;
input_title_t *title; input_title_t *title;
std::vector<KaxSegmentFamily> families; std::vector<matroska_stream_t*> streams;
std::vector<KaxSegment*> family_members; int i_current_stream;
std::vector<chapter_edition_t> editions; matroska_stream_t *Stream()
int i_current_edition; {
const chapter_item_t *psz_current_chapter; if ( i_current_stream != -1 && i_current_stream < streams.size() )
return streams[i_current_stream];
return NULL;
}
}; };
static int Demux ( demux_t * ); static int Demux ( demux_t * );
...@@ -473,6 +534,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -473,6 +534,8 @@ static int Open( vlc_object_t * p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys; demux_sys_t *p_sys;
matroska_stream_t *p_stream;
matroska_segment_t *p_segment;
uint8_t *p_peek; uint8_t *p_peek;
std::string s_path, s_filename; std::string s_path, s_filename;
int i_upper_lvl; int i_upper_lvl;
...@@ -494,40 +557,48 @@ static int Open( vlc_object_t * p_this ) ...@@ -494,40 +557,48 @@ static int Open( vlc_object_t * p_this )
p_demux->pf_control = Control; p_demux->pf_control = Control;
p_demux->p_sys = p_sys = new demux_sys_t; p_demux->p_sys = p_sys = new demux_sys_t;
p_sys->in = new vlc_stream_io_callback( p_demux->s ); p_stream = new matroska_stream_t;
p_sys->es = new EbmlStream( *p_sys->in ); p_segment = new matroska_segment_t;
p_sys->f_duration = -1;
p_sys->i_timescale = MKVD_TIMECODESCALE; p_sys->streams.push_back( p_stream );
p_sys->i_track = 0; p_sys->i_current_stream = 0;
p_sys->track = (mkv_track_t*)malloc( sizeof( mkv_track_t ) );
p_stream->segments.push_back( p_segment );
p_stream->i_current_segment = 0;
p_stream->in = new vlc_stream_io_callback( p_demux->s );
p_stream->es = new EbmlStream( *p_stream->in );
p_segment->f_duration = -1;
p_segment->i_timescale = MKVD_TIMECODESCALE;
p_segment->i_track = 0;
p_segment->track = (mkv_track_t*)malloc( sizeof( mkv_track_t ) );
p_sys->i_pts = 0; p_sys->i_pts = 0;
p_sys->i_cues_position = -1; p_segment->i_cues_position = -1;
p_sys->i_chapters_position = -1; p_segment->i_chapters_position = -1;
p_sys->i_tags_position = -1; p_segment->i_tags_position = -1;
p_sys->b_cues = VLC_FALSE; p_segment->b_cues = VLC_FALSE;
p_sys->i_index = 0; p_segment->i_index = 0;
p_sys->i_index_max = 1024; p_segment->i_index_max = 1024;
p_sys->index = (mkv_index_t*)malloc( sizeof( mkv_index_t ) * p_segment->index = (mkv_index_t*)malloc( sizeof( mkv_index_t ) *
p_sys->i_index_max ); p_segment->i_index_max );
p_sys->psz_muxing_application = NULL; p_segment->psz_muxing_application = NULL;
p_sys->psz_writing_application = NULL; p_segment->psz_writing_application = NULL;
p_sys->psz_segment_filename = NULL; p_segment->psz_segment_filename = NULL;
p_sys->psz_title = NULL; p_segment->psz_title = NULL;
p_sys->psz_date_utc = NULL;; p_segment->psz_date_utc = NULL;;
p_sys->meta = NULL; p_sys->meta = NULL;
p_sys->title = NULL; p_sys->title = NULL;
if( p_sys->es == NULL ) if( p_stream->es == NULL )
{ {
msg_Err( p_demux, "failed to create EbmlStream" ); msg_Err( p_demux, "failed to create EbmlStream" );
delete p_sys->in;
delete p_sys; delete p_sys;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* Find the EbmlHead element */ /* Find the EbmlHead element */
el = p_sys->es->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL); el = p_stream->es->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
if( el == NULL ) if( el == NULL )
{ {
msg_Err( p_demux, "cannot find EbmlHead" ); msg_Err( p_demux, "cannot find EbmlHead" );
...@@ -535,23 +606,23 @@ static int Open( vlc_object_t * p_this ) ...@@ -535,23 +606,23 @@ static int Open( vlc_object_t * p_this )
} }
msg_Dbg( p_demux, "EbmlHead" ); msg_Dbg( p_demux, "EbmlHead" );
/* skip it */ /* skip it */
el->SkipData( *p_sys->es, el->Generic().Context ); el->SkipData( *p_stream->es, el->Generic().Context );
delete el; delete el;
/* Find a segment */ /* Find a segment */
el = p_sys->es->FindNextID( KaxSegment::ClassInfos, 0xFFFFFFFFL); el = p_stream->es->FindNextID( KaxSegment::ClassInfos, 0xFFFFFFFFL);
if( el == NULL ) if( el == NULL )
{ {
msg_Err( p_demux, "cannot find KaxSegment" ); msg_Err( p_demux, "cannot find KaxSegment" );
goto error; goto error;
} }
MkvTree( p_demux, 0, "Segment" ); MkvTree( p_demux, 0, "Segment" );
p_sys->segment = (KaxSegment*)el; p_segment->segment = (KaxSegment*)el;
p_sys->cluster = NULL; p_segment->cluster = NULL;
p_sys->ep = new EbmlParser( p_sys->es, el ); p_stream->ep = new EbmlParser( p_stream->es, el );
while( ( el1 = p_sys->ep->Get() ) != NULL ) while( ( el1 = p_stream->ep->Get() ) != NULL )
{ {
if( MKV_IS_ID( el1, KaxInfo ) ) if( MKV_IS_ID( el1, KaxInfo ) )
{ {
...@@ -573,9 +644,9 @@ static int Open( vlc_object_t * p_this ) ...@@ -573,9 +644,9 @@ static int Open( vlc_object_t * p_this )
{ {
msg_Dbg( p_demux, "| + Cluster" ); msg_Dbg( p_demux, "| + Cluster" );
p_sys->cluster = (KaxCluster*)el1; p_segment->cluster = (KaxCluster*)el1;
p_sys->ep->Down(); p_stream->ep->Down();
/* stop parsing the stream */ /* stop parsing the stream */
break; break;
} }
...@@ -692,15 +763,15 @@ static int Open( vlc_object_t * p_this ) ...@@ -692,15 +763,15 @@ static int Open( vlc_object_t * p_this )
if( MKV_IS_ID( l, KaxSegmentUID ) ) if( MKV_IS_ID( l, KaxSegmentUID ) )
{ {
p_uid = static_cast<KaxSegmentUID*>(l); p_uid = static_cast<KaxSegmentUID*>(l);
if (p_sys->segment_uid == *p_uid) if (p_segment->segment_uid == *p_uid)
break; break;
} }
else if( MKV_IS_ID( l, KaxSegmentFamily ) ) else if( MKV_IS_ID( l, KaxSegmentFamily ) )
{ {
KaxSegmentFamily *p_fam = static_cast<KaxSegmentFamily*>(l); KaxSegmentFamily *p_fam = static_cast<KaxSegmentFamily*>(l);
std::vector<KaxSegmentFamily>::iterator iter; std::vector<KaxSegmentFamily>::iterator iter;
for( iter = p_sys->families.begin(); for( iter = p_segment->families.begin();
iter != p_sys->families.end(); iter != p_segment->families.end();
iter++ ) iter++ )
{ {
if( *iter == *p_fam ) if( *iter == *p_fam )
...@@ -739,14 +810,14 @@ static int Open( vlc_object_t * p_this ) ...@@ -739,14 +810,14 @@ static int Open( vlc_object_t * p_this )
} }
if( p_sys->cluster == NULL ) if( p_segment->cluster == NULL )
{ {
msg_Err( p_demux, "cannot find any cluster, damaged file ?" ); msg_Err( p_demux, "cannot find any cluster, damaged file ?" );
goto error; goto error;
} }
/* *** Load the cue if found *** */ /* *** Load the cue if found *** */
if( p_sys->i_cues_position >= 0 ) if( p_segment->i_cues_position >= 0 )
{ {
vlc_bool_t b_seekable; vlc_bool_t b_seekable;
...@@ -757,20 +828,20 @@ static int Open( vlc_object_t * p_this ) ...@@ -757,20 +828,20 @@ static int Open( vlc_object_t * p_this )
} }
} }
if( !p_sys->b_cues || p_sys->i_index <= 0 ) if( !p_segment->b_cues || p_segment->i_index <= 0 )
{ {
msg_Warn( p_demux, "no cues/empty cues found->seek won't be precise" ); msg_Warn( p_demux, "no cues/empty cues found->seek won't be precise" );
IndexAppendCluster( p_demux, p_sys->cluster ); IndexAppendCluster( p_demux, p_segment->cluster );
p_sys->b_cues = VLC_FALSE; p_segment->b_cues = VLC_FALSE;
} }
/* add all es */ /* add all es */
msg_Dbg( p_demux, "found %d es", p_sys->i_track ); msg_Dbg( p_demux, "found %d es", p_segment->i_track );
for( i_track = 0; i_track < p_sys->i_track; i_track++ ) for( i_track = 0; i_track < p_segment->i_track; i_track++ )
{ {
#define tk p_sys->track[i_track] #define tk p_segment->track[i_track]
if( tk.fmt.i_cat == UNKNOWN_ES ) if( tk.fmt.i_cat == UNKNOWN_ES )
{ {
msg_Warn( p_demux, "invalid track[%d, n=%d]", i_track, tk.i_number ); msg_Warn( p_demux, "invalid track[%d, n=%d]", i_track, tk.i_number );
...@@ -1060,8 +1131,6 @@ static int Open( vlc_object_t * p_this ) ...@@ -1060,8 +1131,6 @@ static int Open( vlc_object_t * p_this )
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
delete p_sys->es;
delete p_sys->in;
delete p_sys; delete p_sys;
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -1073,11 +1142,13 @@ static void Close( vlc_object_t *p_this ) ...@@ -1073,11 +1142,13 @@ static void Close( vlc_object_t *p_this )
{ {
demux_t *p_demux = (demux_t*)p_this; demux_t *p_demux = (demux_t*)p_this;
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
int i_track; int i_track;
for( i_track = 0; i_track < p_sys->i_track; i_track++ ) for( i_track = 0; i_track < p_segment->i_track; i_track++ )
{ {
#define tk p_sys->track[i_track] #define tk p_segment->track[i_track]
if( tk.fmt.psz_description ) if( tk.fmt.psz_description )
{ {
free( tk.fmt.psz_description ); free( tk.fmt.psz_description );
...@@ -1092,22 +1163,19 @@ static void Close( vlc_object_t *p_this ) ...@@ -1092,22 +1163,19 @@ static void Close( vlc_object_t *p_this )
} }
#undef tk #undef tk
} }
free( p_sys->track ); free( p_segment->track );
if( p_sys->psz_writing_application ) if( p_segment->psz_writing_application )
{ {
free( p_sys->psz_writing_application ); free( p_segment->psz_writing_application );
} }
if( p_sys->psz_muxing_application ) if( p_segment->psz_muxing_application )
{ {
free( p_sys->psz_muxing_application ); free( p_segment->psz_muxing_application );
} }
delete p_sys->segment; delete p_segment->segment;
delete p_sys->ep;
delete p_sys->es;
delete p_sys->in;
delete p_sys; delete p_sys;
} }
...@@ -1117,10 +1185,11 @@ static void Close( vlc_object_t *p_this ) ...@@ -1117,10 +1185,11 @@ static void Close( vlc_object_t *p_this )
static int Control( demux_t *p_demux, int i_query, va_list args ) static int Control( demux_t *p_demux, int i_query, va_list args )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
int64_t *pi64; int64_t *pi64;
double *pf, f; double *pf, f;
int i_skp; int i_skp;
mtime_t *i_sk_time;
vlc_meta_t **pp_meta; vlc_meta_t **pp_meta;
...@@ -1133,19 +1202,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1133,19 +1202,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_GET_LENGTH: case DEMUX_GET_LENGTH:
pi64 = (int64_t*)va_arg( args, int64_t * ); pi64 = (int64_t*)va_arg( args, int64_t * );
if( p_sys->f_duration > 0.0 ) if( p_segment->f_duration > 0.0 )
{ {
*pi64 = (int64_t)(p_sys->f_duration * 1000); *pi64 = (int64_t)(p_segment->f_duration * 1000);
return VLC_SUCCESS; return VLC_SUCCESS;
} }
return VLC_EGENERIC; return VLC_EGENERIC;
case DEMUX_GET_POSITION: case DEMUX_GET_POSITION:
pf = (double*)va_arg( args, double * ); pf = (double*)va_arg( args, double * );
/* if (p_sys->i_pts < p_sys->i_start_pts) *pf = (double)p_sys->i_pts / (1000.0 * p_segment->f_duration);
*pf = (double)p_sys->i_start_pts / (1000.0 * p_sys->f_duration);
else*/
*pf = (double)p_sys->i_pts / (1000.0 * p_sys->f_duration);
return VLC_SUCCESS; return VLC_SUCCESS;
case DEMUX_SET_POSITION: case DEMUX_SET_POSITION:
...@@ -1155,9 +1221,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1155,9 +1221,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case DEMUX_GET_TIME: case DEMUX_GET_TIME:
pi64 = (int64_t*)va_arg( args, int64_t * ); pi64 = (int64_t*)va_arg( args, int64_t * );
/* if (p_sys->i_pts < p_sys->i_start_pts)
*pi64 = p_sys->i_start_pts;
else*/
*pi64 = p_sys->i_pts; *pi64 = p_sys->i_pts;
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -1207,6 +1270,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -1207,6 +1270,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration ) static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
*pp_block = NULL; *pp_block = NULL;
*pi_ref1 = -1; *pi_ref1 = -1;
...@@ -1222,14 +1287,14 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in ...@@ -1222,14 +1287,14 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
return VLC_EGENERIC; return VLC_EGENERIC;
} }
el = p_sys->ep->Get(); el = p_stream->ep->Get();
i_level = p_sys->ep->GetLevel(); i_level = p_stream->ep->GetLevel();
if( el == NULL && *pp_block != NULL ) if( el == NULL && *pp_block != NULL )
{ {
/* update the index */ /* update the index */
#define idx p_sys->index[p_sys->i_index - 1] #define idx p_segment->index[p_segment->i_index - 1]
if( p_sys->i_index > 0 && idx.i_time == -1 ) if( p_segment->i_index > 0 && idx.i_time == -1 )
{ {
idx.i_time = (*pp_block)->GlobalTimecode() / (mtime_t)1000; idx.i_time = (*pp_block)->GlobalTimecode() / (mtime_t)1000;
idx.b_key = *pi_ref1 == -1 ? VLC_TRUE : VLC_FALSE; idx.b_key = *pi_ref1 == -1 ? VLC_TRUE : VLC_FALSE;
...@@ -1240,9 +1305,9 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in ...@@ -1240,9 +1305,9 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
if( el == NULL ) if( el == NULL )
{ {
if( p_sys->ep->GetLevel() > 1 ) if( p_stream->ep->GetLevel() > 1 )
{ {
p_sys->ep->Up(); p_stream->ep->Up();
continue; continue;
} }
msg_Warn( p_demux, "EOF" ); msg_Warn( p_demux, "EOF" );
...@@ -1254,16 +1319,16 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in ...@@ -1254,16 +1319,16 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
{ {
if( MKV_IS_ID( el, KaxCluster ) ) if( MKV_IS_ID( el, KaxCluster ) )
{ {
p_sys->cluster = (KaxCluster*)el; p_segment->cluster = (KaxCluster*)el;
/* add it to the index */ /* add it to the index */
if( p_sys->i_index == 0 || if( p_segment->i_index == 0 ||
( p_sys->i_index > 0 && p_sys->index[p_sys->i_index - 1].i_position < (int64_t)p_sys->cluster->GetElementPosition() ) ) ( p_segment->i_index > 0 && p_segment->index[p_segment->i_index - 1].i_position < (int64_t)p_segment->cluster->GetElementPosition() ) )
{ {
IndexAppendCluster( p_demux, p_sys->cluster ); IndexAppendCluster( p_demux, p_segment->cluster );
} }
p_sys->ep->Down(); p_stream->ep->Down();
} }
else if( MKV_IS_ID( el, KaxCues ) ) else if( MKV_IS_ID( el, KaxCues ) )
{ {
...@@ -1281,12 +1346,12 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in ...@@ -1281,12 +1346,12 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
{ {
KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el; KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
ctc.ReadData( p_sys->es->I_O(), SCOPE_ALL_DATA ); ctc.ReadData( p_stream->es->I_O(), SCOPE_ALL_DATA );
p_sys->cluster->InitTimecode( uint64( ctc ), p_sys->i_timescale ); p_segment->cluster->InitTimecode( uint64( ctc ), p_segment->i_timescale );
} }
else if( MKV_IS_ID( el, KaxBlockGroup ) ) else if( MKV_IS_ID( el, KaxBlockGroup ) )
{ {
p_sys->ep->Down(); p_stream->ep->Down();
} }
} }
else if( i_level == 3 ) else if( i_level == 3 )
...@@ -1295,23 +1360,23 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in ...@@ -1295,23 +1360,23 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
{ {
*pp_block = (KaxBlock*)el; *pp_block = (KaxBlock*)el;
(*pp_block)->ReadData( p_sys->es->I_O() ); (*pp_block)->ReadData( p_stream->es->I_O() );
(*pp_block)->SetParent( *p_sys->cluster ); (*pp_block)->SetParent( *p_segment->cluster );
p_sys->ep->Keep(); p_stream->ep->Keep();
} }
else if( MKV_IS_ID( el, KaxBlockDuration ) ) else if( MKV_IS_ID( el, KaxBlockDuration ) )
{ {
KaxBlockDuration &dur = *(KaxBlockDuration*)el; KaxBlockDuration &dur = *(KaxBlockDuration*)el;
dur.ReadData( p_sys->es->I_O() ); dur.ReadData( p_stream->es->I_O() );
*pi_duration = uint64( dur ); *pi_duration = uint64( dur );
} }
else if( MKV_IS_ID( el, KaxReferenceBlock ) ) else if( MKV_IS_ID( el, KaxReferenceBlock ) )
{ {
KaxReferenceBlock &ref = *(KaxReferenceBlock*)el; KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
ref.ReadData( p_sys->es->I_O() ); ref.ReadData( p_stream->es->I_O() );
if( *pi_ref1 == -1 ) if( *pi_ref1 == -1 )
{ {
*pi_ref1 = int64( ref ); *pi_ref1 = int64( ref );
...@@ -1343,13 +1408,15 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts, ...@@ -1343,13 +1408,15 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
mtime_t i_duration ) mtime_t i_duration )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
int i_track; int i_track;
unsigned int i; unsigned int i;
vlc_bool_t b; vlc_bool_t b;
#define tk p_sys->track[i_track] #define tk p_segment->track[i_track]
for( i_track = 0; i_track < p_sys->i_track; i_track++ ) for( i_track = 0; i_track < p_segment->i_track; i_track++ )
{ {
if( tk.i_number == block->TrackNum() ) if( tk.i_number == block->TrackNum() )
{ {
...@@ -1357,7 +1424,7 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts, ...@@ -1357,7 +1424,7 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
} }
} }
if( i_track >= p_sys->i_track ) if( i_track >= p_segment->i_track )
{ {
msg_Err( p_demux, "invalid track number=%d", block->TrackNum() ); msg_Err( p_demux, "invalid track number=%d", block->TrackNum() );
return; return;
...@@ -1437,42 +1504,46 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts, ...@@ -1437,42 +1504,46 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
static void UpdateCurrentToChapter( demux_t & demux ) static void UpdateCurrentToChapter( demux_t & demux )
{ {
demux_sys_t & sys = *demux.p_sys; demux_sys_t & sys = *demux.p_sys;
matroska_stream_t *p_stream = sys.Stream();
matroska_segment_t *p_segment = p_stream->Segment();
const chapter_item_t *psz_curr_chapter; const chapter_item_t *psz_curr_chapter;
/* update current chapter/seekpoint */ /* update current chapter/seekpoint */
if ( sys.editions.size()) if ( p_segment->editions.size())
{ {
/* 1st, we need to know in which chapter we are */ /* 1st, we need to know in which chapter we are */
psz_curr_chapter = sys.editions[sys.i_current_edition].FindTimecode( sys.i_pts ); psz_curr_chapter = p_segment->editions[p_segment->i_current_edition].FindTimecode( sys.i_pts );
/* we have moved to a new chapter */ /* we have moved to a new chapter */
if (sys.psz_current_chapter != NULL && psz_curr_chapter != NULL && sys.psz_current_chapter != psz_curr_chapter) if (p_segment->psz_current_chapter != NULL && psz_curr_chapter != NULL && p_segment->psz_current_chapter != psz_curr_chapter)
{ {
if (sys.psz_current_chapter->i_seekpoint_num != psz_curr_chapter->i_seekpoint_num && psz_curr_chapter->i_seekpoint_num > 0) if (p_segment->psz_current_chapter->i_seekpoint_num != psz_curr_chapter->i_seekpoint_num && psz_curr_chapter->i_seekpoint_num > 0)
{ {
demux.info.i_update |= INPUT_UPDATE_SEEKPOINT; demux.info.i_update |= INPUT_UPDATE_SEEKPOINT;
demux.info.i_seekpoint = psz_curr_chapter->i_seekpoint_num - 1; demux.info.i_seekpoint = psz_curr_chapter->i_seekpoint_num - 1;
} }
if (sys.editions[sys.i_current_edition].b_ordered ) if (p_segment->editions[p_segment->i_current_edition].b_ordered )
{ {
/* TODO check if we need to silently seek to a new location in the stream (switch to another chapter) */ /* TODO check if we need to silently seek to a new location in the stream (switch to another chapter) */
if (sys.psz_current_chapter->i_end_time != psz_curr_chapter->i_start_time) if (p_segment->psz_current_chapter->i_end_time != psz_curr_chapter->i_start_time)
Seek(&demux, sys.i_pts, -1, psz_curr_chapter); Seek(&demux, sys.i_pts, -1, psz_curr_chapter);
/* count the last duration time found for each track in a table (-1 not found, -2 silent) */ /* count the last duration time found for each track in a table (-1 not found, -2 silent) */
/* only seek after each duration >= end timecode of the current chapter */ /* only seek after each duration >= end timecode of the current chapter */
} }
// sys.i_user_time = psz_curr_chapter->i_user_start_time - psz_curr_chapter->i_start_time; // p_segment->i_user_time = psz_curr_chapter->i_user_start_time - psz_curr_chapter->i_start_time;
// sys.i_start_pts = psz_curr_chapter->i_user_start_time; // p_segment->i_start_pts = psz_curr_chapter->i_user_start_time;
} }
sys.psz_current_chapter = psz_curr_chapter; p_segment->psz_current_chapter = psz_curr_chapter;
} }
} }
static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chapter_item_t *psz_chapter) static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chapter_item_t *psz_chapter)
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
mtime_t i_time_offset = 0; mtime_t i_time_offset = 0;
KaxBlock *block; KaxBlock *block;
...@@ -1496,38 +1567,38 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap ...@@ -1496,38 +1567,38 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
return; return;
} }
delete p_sys->ep; delete p_stream->ep;
p_sys->ep = new EbmlParser( p_sys->es, p_sys->segment ); p_stream->ep = new EbmlParser( p_stream->es, p_segment->segment );
p_sys->cluster = NULL; p_segment->cluster = NULL;
/* seek without index or without date */ /* seek without index or without date */
if( f_percent >= 0 && (config_GetInt( p_demux, "mkv-seek-percent" ) || !p_sys->b_cues || i_date < 0 )) if( f_percent >= 0 && (config_GetInt( p_demux, "mkv-seek-percent" ) || !p_segment->b_cues || i_date < 0 ))
{ {
if (p_sys->f_duration >= 0) if (p_segment->f_duration >= 0)
{ {
i_date = int64_t( f_percent * p_sys->f_duration * 1000.0 ); i_date = int64_t( f_percent * p_segment->f_duration * 1000.0 );
} }
else else
{ {
int64_t i_pos = int64_t( f_percent * stream_Size( p_demux->s ) ); int64_t i_pos = int64_t( f_percent * stream_Size( p_demux->s ) );
msg_Dbg( p_demux, "inacurate way of seeking" ); msg_Dbg( p_demux, "inacurate way of seeking" );
for( i_index = 0; i_index < p_sys->i_index; i_index++ ) for( i_index = 0; i_index < p_segment->i_index; i_index++ )
{ {
if( p_sys->index[i_index].i_position >= i_pos) if( p_segment->index[i_index].i_position >= i_pos)
{ {
break; break;
} }
} }
if( i_index == p_sys->i_index ) if( i_index == p_segment->i_index )
{ {
i_index--; i_index--;
} }
i_date = p_sys->index[i_index].i_time; i_date = p_segment->index[i_index].i_time;
#if 0 #if 0
if( p_sys->index[i_index].i_position < i_pos ) if( p_segment->index[i_index].i_position < i_pos )
{ {
EbmlElement *el; EbmlElement *el;
...@@ -1559,24 +1630,24 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap ...@@ -1559,24 +1630,24 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
// find the actual time for an ordered edition // find the actual time for an ordered edition
if ( psz_chapter == NULL ) if ( psz_chapter == NULL )
{ {
if ( p_sys->editions.size() && p_sys->editions[p_sys->i_current_edition].b_ordered ) if ( p_segment->editions.size() && p_segment->editions[p_segment->i_current_edition].b_ordered )
{ {
/* 1st, we need to know in which chapter we are */ /* 1st, we need to know in which chapter we are */
psz_chapter = p_sys->editions[p_sys->i_current_edition].FindTimecode( i_date ); psz_chapter = p_segment->editions[p_segment->i_current_edition].FindTimecode( i_date );
} }
} }
if ( psz_chapter != NULL ) if ( psz_chapter != NULL )
{ {
p_sys->psz_current_chapter = psz_chapter; p_segment->psz_current_chapter = psz_chapter;
p_sys->i_chapter_time = i_time_offset = psz_chapter->i_user_start_time - psz_chapter->i_start_time; p_sys->i_chapter_time = i_time_offset = psz_chapter->i_user_start_time - psz_chapter->i_start_time;
p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT; p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_seekpoint = psz_chapter->i_seekpoint_num - 1; p_demux->info.i_seekpoint = psz_chapter->i_seekpoint_num - 1;
} }
for( ; i_index < p_sys->i_index; i_index++ ) for( ; i_index < p_segment->i_index; i_index++ )
{ {
if( p_sys->index[i_index].i_time + i_time_offset > i_date ) if( p_segment->index[i_index].i_time + i_time_offset > i_date )
{ {
break; break;
} }
...@@ -1588,11 +1659,11 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap ...@@ -1588,11 +1659,11 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
} }
msg_Dbg( p_demux, "seek got "I64Fd" (%d%%)", msg_Dbg( p_demux, "seek got "I64Fd" (%d%%)",
p_sys->index[i_index].i_time, p_segment->index[i_index].i_time,
(int)( 100 * p_sys->index[i_index].i_position / (int)( 100 * p_segment->index[i_index].i_position /
stream_Size( p_demux->s ) ) ); stream_Size( p_demux->s ) ) );
p_sys->in->setFilePointer( p_sys->index[i_index].i_position, p_stream->in->setFilePointer( p_segment->index[i_index].i_position,
seek_beginning ); seek_beginning );
p_sys->i_start_pts = i_date; p_sys->i_start_pts = i_date;
...@@ -1600,9 +1671,9 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap ...@@ -1600,9 +1671,9 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
/* now parse until key frame */ /* now parse until key frame */
#define tk p_sys->track[i_track] #define tk p_segment->track[i_track]
i_track_skipping = 0; i_track_skipping = 0;
for( i_track = 0; i_track < p_sys->i_track; i_track++ ) for( i_track = 0; i_track < p_segment->i_track; i_track++ )
{ {
if( tk.fmt.i_cat == VIDEO_ES ) if( tk.fmt.i_cat == VIDEO_ES )
{ {
...@@ -1622,7 +1693,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap ...@@ -1622,7 +1693,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
return; return;
} }
for( i_track = 0; i_track < p_sys->i_track; i_track++ ) for( i_track = 0; i_track < p_segment->i_track; i_track++ )
{ {
if( tk.i_number == block->TrackNum() ) if( tk.i_number == block->TrackNum() )
{ {
...@@ -1632,7 +1703,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap ...@@ -1632,7 +1703,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
p_sys->i_pts = p_sys->i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000; p_sys->i_pts = p_sys->i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000;
if( i_track < p_sys->i_track ) if( i_track < p_segment->i_track )
{ {
if( tk.fmt.i_cat == VIDEO_ES ) if( tk.fmt.i_cat == VIDEO_ES )
{ {
...@@ -1661,6 +1732,8 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap ...@@ -1661,6 +1732,8 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
static int Demux( demux_t *p_demux) static int Demux( demux_t *p_demux)
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
int i_block_count = 0; int i_block_count = 0;
KaxBlock *block; KaxBlock *block;
...@@ -1673,7 +1746,7 @@ static int Demux( demux_t *p_demux) ...@@ -1673,7 +1746,7 @@ static int Demux( demux_t *p_demux)
if( p_sys->i_pts >= p_sys->i_start_pts ) if( p_sys->i_pts >= p_sys->i_start_pts )
UpdateCurrentToChapter( *p_demux ); UpdateCurrentToChapter( *p_demux );
if ( p_sys->editions.size() && p_sys->editions[p_sys->i_current_edition].b_ordered && p_sys->psz_current_chapter == NULL ) if ( p_segment->editions.size() && p_segment->editions[p_segment->i_current_edition].b_ordered && p_segment->psz_current_chapter == NULL )
{ {
/* nothing left to read in this ordered edition */ /* nothing left to read in this ordered edition */
return 0; return 0;
...@@ -1681,12 +1754,12 @@ static int Demux( demux_t *p_demux) ...@@ -1681,12 +1754,12 @@ static int Demux( demux_t *p_demux)
if( BlockGet( p_demux, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) ) if( BlockGet( p_demux, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
{ {
if ( p_sys->editions.size() && p_sys->editions[p_sys->i_current_edition].b_ordered ) if ( p_segment->editions.size() && p_segment->editions[p_segment->i_current_edition].b_ordered )
{ {
// check if there are more chapters to read // check if there are more chapters to read
if ( p_sys->psz_current_chapter != NULL ) if ( p_segment->psz_current_chapter != NULL )
{ {
p_sys->i_pts = p_sys->psz_current_chapter->i_user_end_time; p_sys->i_pts = p_segment->psz_current_chapter->i_user_end_time;
return 1; return 1;
} }
...@@ -1908,27 +1981,29 @@ EbmlElement *EbmlParser::Get( void ) ...@@ -1908,27 +1981,29 @@ EbmlElement *EbmlParser::Get( void )
static void LoadCues( demux_t *p_demux ) static void LoadCues( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
int64_t i_sav_position = p_sys->in->getFilePointer(); matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
int64_t i_sav_position = p_stream->in->getFilePointer();
EbmlParser *ep; EbmlParser *ep;
EbmlElement *el, *cues; EbmlElement *el, *cues;
msg_Dbg( p_demux, "loading cues" ); msg_Dbg( p_demux, "loading cues" );
p_sys->in->setFilePointer( p_sys->i_cues_position, seek_beginning ); p_stream->in->setFilePointer( p_segment->i_cues_position, seek_beginning );
cues = p_sys->es->FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL); cues = p_stream->es->FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL);
if( cues == NULL ) if( cues == NULL )
{ {
msg_Err( p_demux, "cannot load cues (broken seekhead or file)" ); msg_Err( p_demux, "cannot load cues (broken seekhead or file)" );
p_sys->in->setFilePointer( i_sav_position, seek_beginning ); p_stream->in->setFilePointer( i_sav_position, seek_beginning );
return; return;
} }
ep = new EbmlParser( p_sys->es, cues ); ep = new EbmlParser( p_stream->es, cues );
while( ( el = ep->Get() ) != NULL ) while( ( el = ep->Get() ) != NULL )
{ {
if( MKV_IS_ID( el, KaxCuePoint ) ) if( MKV_IS_ID( el, KaxCuePoint ) )
{ {
#define idx p_sys->index[p_sys->i_index] #define idx p_segment->index[p_segment->i_index]
idx.i_track = -1; idx.i_track = -1;
idx.i_block_number= -1; idx.i_block_number= -1;
...@@ -1943,9 +2018,9 @@ static void LoadCues( demux_t *p_demux ) ...@@ -1943,9 +2018,9 @@ static void LoadCues( demux_t *p_demux )
{ {
KaxCueTime &ctime = *(KaxCueTime*)el; KaxCueTime &ctime = *(KaxCueTime*)el;
ctime.ReadData( p_sys->es->I_O() ); ctime.ReadData( p_stream->es->I_O() );
idx.i_time = uint64( ctime ) * p_sys->i_timescale / (mtime_t)1000; idx.i_time = uint64( ctime ) * p_segment->i_timescale / (mtime_t)1000;
} }
else if( MKV_IS_ID( el, KaxCueTrackPositions ) ) else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
{ {
...@@ -1956,21 +2031,21 @@ static void LoadCues( demux_t *p_demux ) ...@@ -1956,21 +2031,21 @@ static void LoadCues( demux_t *p_demux )
{ {
KaxCueTrack &ctrack = *(KaxCueTrack*)el; KaxCueTrack &ctrack = *(KaxCueTrack*)el;
ctrack.ReadData( p_sys->es->I_O() ); ctrack.ReadData( p_stream->es->I_O() );
idx.i_track = uint16( ctrack ); idx.i_track = uint16( ctrack );
} }
else if( MKV_IS_ID( el, KaxCueClusterPosition ) ) else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
{ {
KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el; KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
ccpos.ReadData( p_sys->es->I_O() ); ccpos.ReadData( p_stream->es->I_O() );
idx.i_position = p_sys->segment->GetGlobalPosition( uint64( ccpos ) ); idx.i_position = p_segment->segment->GetGlobalPosition( uint64( ccpos ) );
} }
else if( MKV_IS_ID( el, KaxCueBlockNumber ) ) else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
{ {
KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el; KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
cbnum.ReadData( p_sys->es->I_O() ); cbnum.ReadData( p_stream->es->I_O() );
idx.i_block_number = uint32( cbnum ); idx.i_block_number = uint32( cbnum );
} }
else else
...@@ -1993,11 +2068,11 @@ static void LoadCues( demux_t *p_demux ) ...@@ -1993,11 +2068,11 @@ static void LoadCues( demux_t *p_demux )
idx.i_track, idx.i_block_number ); idx.i_track, idx.i_block_number );
#endif #endif
p_sys->i_index++; p_segment->i_index++;
if( p_sys->i_index >= p_sys->i_index_max ) if( p_segment->i_index >= p_segment->i_index_max )
{ {
p_sys->i_index_max += 1024; p_segment->i_index_max += 1024;
p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max ); p_segment->index = (mkv_index_t*)realloc( p_segment->index, sizeof( mkv_index_t ) * p_segment->i_index_max );
} }
#undef idx #undef idx
} }
...@@ -2009,32 +2084,34 @@ static void LoadCues( demux_t *p_demux ) ...@@ -2009,32 +2084,34 @@ static void LoadCues( demux_t *p_demux )
delete ep; delete ep;
delete cues; delete cues;
p_sys->b_cues = VLC_TRUE; p_segment->b_cues = VLC_TRUE;
msg_Dbg( p_demux, "loading cues done." ); msg_Dbg( p_demux, "loading cues done." );
p_sys->in->setFilePointer( i_sav_position, seek_beginning ); p_stream->in->setFilePointer( i_sav_position, seek_beginning );
} }
static void LoadTags( demux_t *p_demux ) static void LoadTags( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
int64_t i_sav_position = p_sys->in->getFilePointer(); matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
int64_t i_sav_position = p_stream->in->getFilePointer();
EbmlParser *ep; EbmlParser *ep;
EbmlElement *el, *tags; EbmlElement *el, *tags;
msg_Dbg( p_demux, "loading tags" ); msg_Dbg( p_demux, "loading tags" );
p_sys->in->setFilePointer( p_sys->i_tags_position, seek_beginning ); p_stream->in->setFilePointer( p_segment->i_tags_position, seek_beginning );
tags = p_sys->es->FindNextID( KaxTags::ClassInfos, 0xFFFFFFFFL); tags = p_stream->es->FindNextID( KaxTags::ClassInfos, 0xFFFFFFFFL);
if( tags == NULL ) if( tags == NULL )
{ {
msg_Err( p_demux, "cannot load tags (broken seekhead or file)" ); msg_Err( p_demux, "cannot load tags (broken seekhead or file)" );
p_sys->in->setFilePointer( i_sav_position, seek_beginning ); p_stream->in->setFilePointer( i_sav_position, seek_beginning );
return; return;
} }
msg_Dbg( p_demux, "Tags" ); msg_Dbg( p_demux, "Tags" );
ep = new EbmlParser( p_sys->es, tags ); ep = new EbmlParser( p_stream->es, tags );
while( ( el = ep->Get() ) != NULL ) while( ( el = ep->Get() ) != NULL )
{ {
if( MKV_IS_ID( el, KaxTag ) ) if( MKV_IS_ID( el, KaxTag ) )
...@@ -2137,7 +2214,7 @@ static void LoadTags( demux_t *p_demux ) ...@@ -2137,7 +2214,7 @@ static void LoadTags( demux_t *p_demux )
delete tags; delete tags;
msg_Dbg( p_demux, "loading tags done." ); msg_Dbg( p_demux, "loading tags done." );
p_sys->in->setFilePointer( i_sav_position, seek_beginning ); p_stream->in->setFilePointer( i_sav_position, seek_beginning );
} }
/***************************************************************************** /*****************************************************************************
...@@ -2146,6 +2223,8 @@ static void LoadTags( demux_t *p_demux ) ...@@ -2146,6 +2223,8 @@ static void LoadTags( demux_t *p_demux )
static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead ) static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
EbmlElement *el; EbmlElement *el;
EbmlMaster *m; EbmlMaster *m;
unsigned int i; unsigned int i;
...@@ -2155,7 +2234,7 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead ) ...@@ -2155,7 +2234,7 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>(seekhead); m = static_cast<EbmlMaster *>(seekhead);
m->Read( *p_sys->es, seekhead->Generic().Context, i_upper_level, el, true ); m->Read( *p_stream->es, seekhead->Generic().Context, i_upper_level, el, true );
for( i = 0; i < m->ListSize(); i++ ) for( i = 0; i < m->ListSize(); i++ )
{ {
...@@ -2194,17 +2273,17 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead ) ...@@ -2194,17 +2273,17 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
if( id == KaxCues::ClassInfos.GlobalId ) if( id == KaxCues::ClassInfos.GlobalId )
{ {
msg_Dbg( p_demux, "| | | = cues at "I64Fd, i_pos ); msg_Dbg( p_demux, "| | | = cues at "I64Fd, i_pos );
p_sys->i_cues_position = p_sys->segment->GetGlobalPosition( i_pos ); p_segment->i_cues_position = p_segment->segment->GetGlobalPosition( i_pos );
} }
else if( id == KaxChapters::ClassInfos.GlobalId ) else if( id == KaxChapters::ClassInfos.GlobalId )
{ {
msg_Dbg( p_demux, "| | | = chapters at "I64Fd, i_pos ); msg_Dbg( p_demux, "| | | = chapters at "I64Fd, i_pos );
p_sys->i_chapters_position = p_sys->segment->GetGlobalPosition( i_pos ); p_segment->i_chapters_position = p_segment->segment->GetGlobalPosition( i_pos );
} }
else if( id == KaxTags::ClassInfos.GlobalId ) else if( id == KaxTags::ClassInfos.GlobalId )
{ {
msg_Dbg( p_demux, "| | | = tags at "I64Fd, i_pos ); msg_Dbg( p_demux, "| | | = tags at "I64Fd, i_pos );
p_sys->i_tags_position = p_sys->segment->GetGlobalPosition( i_pos ); p_segment->i_tags_position = p_segment->segment->GetGlobalPosition( i_pos );
} }
} }
} }
...@@ -2221,17 +2300,19 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead ) ...@@ -2221,17 +2300,19 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m ) static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
unsigned int i; unsigned int i;
mkv_track_t *tk; mkv_track_t *tk;
msg_Dbg( p_demux, "| | + Track Entry" ); msg_Dbg( p_demux, "| | + Track Entry" );
p_sys->i_track++; p_segment->i_track++;
p_sys->track = (mkv_track_t*)realloc( p_sys->track, sizeof( mkv_track_t ) * (p_sys->i_track + 1 ) ); p_segment->track = (mkv_track_t*)realloc( p_segment->track, sizeof( mkv_track_t ) * (p_segment->i_track + 1 ) );
/* Init the track */ /* Init the track */
tk = &p_sys->track[p_sys->i_track - 1]; tk = &p_segment->track[p_segment->i_track - 1];
memset( tk, 0, sizeof( mkv_track_t ) ); memset( tk, 0, sizeof( mkv_track_t ) );
...@@ -2241,7 +2322,7 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m ) ...@@ -2241,7 +2322,7 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
tk->b_default = VLC_TRUE; tk->b_default = VLC_TRUE;
tk->b_enabled = VLC_TRUE; tk->b_enabled = VLC_TRUE;
tk->i_number = p_sys->i_track - 1; tk->i_number = p_segment->i_track - 1;
tk->i_extra_data = 0; tk->i_extra_data = 0;
tk->p_extra_data = NULL; tk->p_extra_data = NULL;
tk->psz_codec = NULL; tk->psz_codec = NULL;
...@@ -2625,6 +2706,8 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m ) ...@@ -2625,6 +2706,8 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
static void ParseTracks( demux_t *p_demux, EbmlElement *tracks ) static void ParseTracks( demux_t *p_demux, EbmlElement *tracks )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
EbmlElement *el; EbmlElement *el;
EbmlMaster *m; EbmlMaster *m;
unsigned int i; unsigned int i;
...@@ -2634,7 +2717,7 @@ static void ParseTracks( demux_t *p_demux, EbmlElement *tracks ) ...@@ -2634,7 +2717,7 @@ static void ParseTracks( demux_t *p_demux, EbmlElement *tracks )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>(tracks); m = static_cast<EbmlMaster *>(tracks);
m->Read( *p_sys->es, tracks->Generic().Context, i_upper_level, el, true ); m->Read( *p_stream->es, tracks->Generic().Context, i_upper_level, el, true );
for( i = 0; i < m->ListSize(); i++ ) for( i = 0; i < m->ListSize(); i++ )
{ {
...@@ -2657,6 +2740,8 @@ static void ParseTracks( demux_t *p_demux, EbmlElement *tracks ) ...@@ -2657,6 +2740,8 @@ static void ParseTracks( demux_t *p_demux, EbmlElement *tracks )
static void ParseInfo( demux_t *p_demux, EbmlElement *info ) static void ParseInfo( demux_t *p_demux, EbmlElement *info )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
EbmlElement *el; EbmlElement *el;
EbmlMaster *m; EbmlMaster *m;
unsigned int i; unsigned int i;
...@@ -2666,7 +2751,7 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info ) ...@@ -2666,7 +2751,7 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>(info); m = static_cast<EbmlMaster *>(info);
m->Read( *p_sys->es, info->Generic().Context, i_upper_level, el, true ); m->Read( *p_stream->es, info->Generic().Context, i_upper_level, el, true );
for( i = 0; i < m->ListSize(); i++ ) for( i = 0; i < m->ListSize(); i++ )
{ {
...@@ -2674,68 +2759,68 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info ) ...@@ -2674,68 +2759,68 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
if( MKV_IS_ID( l, KaxSegmentUID ) ) if( MKV_IS_ID( l, KaxSegmentUID ) )
{ {
p_sys->segment_uid = *(new KaxSegmentUID(*static_cast<KaxSegmentUID*>(l))); p_segment->segment_uid = *(new KaxSegmentUID(*static_cast<KaxSegmentUID*>(l)));
msg_Dbg( p_demux, "| | + UID=%d", *(uint32*)p_sys->segment_uid.GetBuffer() ); msg_Dbg( p_demux, "| | + UID=%d", *(uint32*)p_segment->segment_uid.GetBuffer() );
} }
else if( MKV_IS_ID( l, KaxTimecodeScale ) ) else if( MKV_IS_ID( l, KaxTimecodeScale ) )
{ {
KaxTimecodeScale &tcs = *(KaxTimecodeScale*)l; KaxTimecodeScale &tcs = *(KaxTimecodeScale*)l;
p_sys->i_timescale = uint64(tcs); p_segment->i_timescale = uint64(tcs);
msg_Dbg( p_demux, "| | + TimecodeScale="I64Fd, msg_Dbg( p_demux, "| | + TimecodeScale="I64Fd,
p_sys->i_timescale ); p_segment->i_timescale );
} }
else if( MKV_IS_ID( l, KaxDuration ) ) else if( MKV_IS_ID( l, KaxDuration ) )
{ {
KaxDuration &dur = *(KaxDuration*)l; KaxDuration &dur = *(KaxDuration*)l;
p_sys->f_duration = float(dur); p_segment->f_duration = float(dur);
msg_Dbg( p_demux, "| | + Duration=%f", msg_Dbg( p_demux, "| | + Duration=%f",
p_sys->f_duration ); p_segment->f_duration );
} }
else if( MKV_IS_ID( l, KaxMuxingApp ) ) else if( MKV_IS_ID( l, KaxMuxingApp ) )
{ {
KaxMuxingApp &mapp = *(KaxMuxingApp*)l; KaxMuxingApp &mapp = *(KaxMuxingApp*)l;
p_sys->psz_muxing_application = UTF8ToStr( UTFstring( mapp ) ); p_segment->psz_muxing_application = UTF8ToStr( UTFstring( mapp ) );
msg_Dbg( p_demux, "| | + Muxing Application=%s", msg_Dbg( p_demux, "| | + Muxing Application=%s",
p_sys->psz_muxing_application ); p_segment->psz_muxing_application );
} }
else if( MKV_IS_ID( l, KaxWritingApp ) ) else if( MKV_IS_ID( l, KaxWritingApp ) )
{ {
KaxWritingApp &wapp = *(KaxWritingApp*)l; KaxWritingApp &wapp = *(KaxWritingApp*)l;
p_sys->psz_writing_application = UTF8ToStr( UTFstring( wapp ) ); p_segment->psz_writing_application = UTF8ToStr( UTFstring( wapp ) );
msg_Dbg( p_demux, "| | + Writing Application=%s", msg_Dbg( p_demux, "| | + Writing Application=%s",
p_sys->psz_writing_application ); p_segment->psz_writing_application );
} }
else if( MKV_IS_ID( l, KaxSegmentFilename ) ) else if( MKV_IS_ID( l, KaxSegmentFilename ) )
{ {
KaxSegmentFilename &sfn = *(KaxSegmentFilename*)l; KaxSegmentFilename &sfn = *(KaxSegmentFilename*)l;
p_sys->psz_segment_filename = UTF8ToStr( UTFstring( sfn ) ); p_segment->psz_segment_filename = UTF8ToStr( UTFstring( sfn ) );
msg_Dbg( p_demux, "| | + Segment Filename=%s", msg_Dbg( p_demux, "| | + Segment Filename=%s",
p_sys->psz_segment_filename ); p_segment->psz_segment_filename );
} }
else if( MKV_IS_ID( l, KaxTitle ) ) else if( MKV_IS_ID( l, KaxTitle ) )
{ {
KaxTitle &title = *(KaxTitle*)l; KaxTitle &title = *(KaxTitle*)l;
p_sys->psz_title = UTF8ToStr( UTFstring( title ) ); p_segment->psz_title = UTF8ToStr( UTFstring( title ) );
msg_Dbg( p_demux, "| | + Title=%s", p_sys->psz_title ); msg_Dbg( p_demux, "| | + Title=%s", p_segment->psz_title );
} }
if( MKV_IS_ID( l, KaxSegmentFamily ) ) if( MKV_IS_ID( l, KaxSegmentFamily ) )
{ {
KaxSegmentFamily *uid = static_cast<KaxSegmentFamily*>(l); KaxSegmentFamily *uid = static_cast<KaxSegmentFamily*>(l);
p_sys->families.push_back(*uid); p_segment->families.push_back(*uid);
msg_Dbg( p_demux, "| | + family=%d", *(uint32*)uid->GetBuffer() ); msg_Dbg( p_demux, "| | + family=%d", *(uint32*)uid->GetBuffer() );
} }
...@@ -2753,8 +2838,8 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info ) ...@@ -2753,8 +2838,8 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
asctime_r( &tmres, buffer ) ) asctime_r( &tmres, buffer ) )
{ {
buffer[strlen( buffer)-1]= '\0'; buffer[strlen( buffer)-1]= '\0';
p_sys->psz_date_utc = strdup( buffer ); p_segment->psz_date_utc = strdup( buffer );
msg_Dbg( p_demux, "| | + Date=%s", p_sys->psz_date_utc ); msg_Dbg( p_demux, "| | + Date=%s", p_segment->psz_date_utc );
} }
} }
#endif #endif
...@@ -2764,7 +2849,7 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info ) ...@@ -2764,7 +2849,7 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
} }
} }
p_sys->f_duration *= p_sys->i_timescale / 1000000.0; p_segment->f_duration *= p_segment->i_timescale / 1000000.0;
} }
...@@ -2866,6 +2951,8 @@ static void ParseChapterAtom( demux_t *p_demux, int i_level, EbmlMaster *ca, cha ...@@ -2866,6 +2951,8 @@ static void ParseChapterAtom( demux_t *p_demux, int i_level, EbmlMaster *ca, cha
static void ParseChapters( demux_t *p_demux, EbmlElement *chapters ) static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
EbmlElement *el; EbmlElement *el;
EbmlMaster *m; EbmlMaster *m;
unsigned int i; unsigned int i;
...@@ -2875,7 +2962,7 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters ) ...@@ -2875,7 +2962,7 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>(chapters); m = static_cast<EbmlMaster *>(chapters);
m->Read( *p_sys->es, chapters->Generic().Context, i_upper_level, el, true ); m->Read( *p_stream->es, chapters->Generic().Context, i_upper_level, el, true );
for( i = 0; i < m->ListSize(); i++ ) for( i = 0; i < m->ListSize(); i++ )
{ {
...@@ -2909,14 +2996,14 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters ) ...@@ -2909,14 +2996,14 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
else if( MKV_IS_ID( l, KaxEditionFlagDefault ) ) else if( MKV_IS_ID( l, KaxEditionFlagDefault ) )
{ {
if (uint8(*static_cast<KaxEditionFlagDefault *>( l )) != 0) if (uint8(*static_cast<KaxEditionFlagDefault *>( l )) != 0)
i_default_edition = p_sys->editions.size(); i_default_edition = p_segment->editions.size();
} }
else else
{ {
msg_Dbg( p_demux, "| | | + Unknown (%s)", typeid(*l).name() ); msg_Dbg( p_demux, "| | | + Unknown (%s)", typeid(*l).name() );
} }
} }
p_sys->editions.push_back( edition ); p_segment->editions.push_back( edition );
} }
else else
{ {
...@@ -2924,19 +3011,19 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters ) ...@@ -2924,19 +3011,19 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
} }
} }
for( i = 0; i < p_sys->editions.size(); i++ ) for( i = 0; i < p_segment->editions.size(); i++ )
{ {
p_sys->editions[i].RefreshChapters( *p_sys->title ); p_segment->editions[i].RefreshChapters( *p_sys->title );
} }
p_sys->i_current_edition = i_default_edition; p_segment->i_current_edition = i_default_edition;
if ( p_sys->editions[i_default_edition].b_ordered ) if ( p_segment->editions[i_default_edition].b_ordered )
{ {
/* update the duration of the segment according to the sum of all sub chapters */ /* update the duration of the segment according to the sum of all sub chapters */
f_duration = p_sys->editions[i_default_edition].Duration() / I64C(1000); f_duration = p_segment->editions[i_default_edition].Duration() / I64C(1000);
if (f_duration > 0.0) if (f_duration > 0.0)
p_sys->f_duration = f_duration; p_segment->f_duration = f_duration;
} }
} }
...@@ -2946,34 +3033,36 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters ) ...@@ -2946,34 +3033,36 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
static void InformationCreate( demux_t *p_demux ) static void InformationCreate( demux_t *p_demux )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
int i_track; int i_track;
p_sys->meta = vlc_meta_New(); p_sys->meta = vlc_meta_New();
if( p_sys->psz_title ) if( p_segment->psz_title )
{ {
vlc_meta_Add( p_sys->meta, VLC_META_TITLE, p_sys->psz_title ); vlc_meta_Add( p_sys->meta, VLC_META_TITLE, p_segment->psz_title );
} }
if( p_sys->psz_date_utc ) if( p_segment->psz_date_utc )
{ {
vlc_meta_Add( p_sys->meta, VLC_META_DATE, p_sys->psz_date_utc ); vlc_meta_Add( p_sys->meta, VLC_META_DATE, p_segment->psz_date_utc );
} }
if( p_sys->psz_segment_filename ) if( p_segment->psz_segment_filename )
{ {
vlc_meta_Add( p_sys->meta, _("Segment filename"), p_sys->psz_segment_filename ); vlc_meta_Add( p_sys->meta, _("Segment filename"), p_segment->psz_segment_filename );
} }
if( p_sys->psz_muxing_application ) if( p_segment->psz_muxing_application )
{ {
vlc_meta_Add( p_sys->meta, _("Muxing application"), p_sys->psz_muxing_application ); vlc_meta_Add( p_sys->meta, _("Muxing application"), p_segment->psz_muxing_application );
} }
if( p_sys->psz_writing_application ) if( p_segment->psz_writing_application )
{ {
vlc_meta_Add( p_sys->meta, _("Writing application"), p_sys->psz_writing_application ); vlc_meta_Add( p_sys->meta, _("Writing application"), p_segment->psz_writing_application );
} }
for( i_track = 0; i_track < p_sys->i_track; i_track++ ) for( i_track = 0; i_track < p_segment->i_track; i_track++ )
{ {
mkv_track_t *tk = &p_sys->track[i_track]; mkv_track_t *tk = &p_segment->track[i_track];
vlc_meta_t *mtk = vlc_meta_New(); vlc_meta_t *mtk = vlc_meta_New();
p_sys->meta->track = (vlc_meta_t**)realloc( p_sys->meta->track, p_sys->meta->track = (vlc_meta_t**)realloc( p_sys->meta->track,
...@@ -3002,7 +3091,7 @@ static void InformationCreate( demux_t *p_demux ) ...@@ -3002,7 +3091,7 @@ static void InformationCreate( demux_t *p_demux )
} }
} }
if( p_sys->i_tags_position >= 0 ) if( p_segment->i_tags_position >= 0 )
{ {
vlc_bool_t b_seekable; vlc_bool_t b_seekable;
...@@ -3022,19 +3111,21 @@ static void InformationCreate( demux_t *p_demux ) ...@@ -3022,19 +3111,21 @@ static void InformationCreate( demux_t *p_demux )
static void IndexAppendCluster( demux_t *p_demux, KaxCluster *cluster ) static void IndexAppendCluster( demux_t *p_demux, KaxCluster *cluster )
{ {
demux_sys_t *p_sys = p_demux->p_sys; demux_sys_t *p_sys = p_demux->p_sys;
matroska_stream_t *p_stream = p_sys->Stream();
matroska_segment_t *p_segment = p_stream->Segment();
#define idx p_sys->index[p_sys->i_index] #define idx p_segment->index[p_segment->i_index]
idx.i_track = -1; idx.i_track = -1;
idx.i_block_number= -1; idx.i_block_number= -1;
idx.i_position = cluster->GetElementPosition(); idx.i_position = cluster->GetElementPosition();
idx.i_time = -1; idx.i_time = -1;
idx.b_key = VLC_TRUE; idx.b_key = VLC_TRUE;
p_sys->i_index++; p_segment->i_index++;
if( p_sys->i_index >= p_sys->i_index_max ) if( p_segment->i_index >= p_segment->i_index_max )
{ {
p_sys->i_index_max += 1024; p_segment->i_index_max += 1024;
p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max ); p_segment->index = (mkv_index_t*)realloc( p_segment->index, sizeof( mkv_index_t ) * p_segment->i_index_max );
} }
#undef idx #undef idx
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment