Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
291c6479
Commit
291c6479
authored
Mar 07, 2005
by
Steve Lhomme
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mkv.cpp: prepare the code to handle seemless segment switching
parent
cb48de28
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
335 additions
and
244 deletions
+335
-244
modules/demux/mkv.cpp
modules/demux/mkv.cpp
+335
-244
No files found.
modules/demux/mkv.cpp
View file @
291c6479
...
...
@@ -362,13 +362,11 @@ public:
bool
b_ordered
;
};
class
demux_sys
_t
class
matroska_segment
_t
{
public:
demux_sys_t
()
:
in
(
NULL
)
,
es
(
NULL
)
,
ep
(
NULL
)
matroska_segment_t
()
:
segment
(
NULL
)
,
i_timescale
(
0
)
,
f_duration
(
0.0
)
,
i_track
(
0
)
...
...
@@ -376,11 +374,7 @@ public:
,
i_cues_position
(
0
)
,
i_chapters_position
(
0
)
,
i_tags_position
(
0
)
,
segment
(
NULL
)
,
cluster
(
NULL
)
,
i_pts
(
0
)
,
i_start_pts
(
0
)
,
i_chapter_time
(
0
)
,
b_cues
(
false
)
,
i_index
(
0
)
,
i_index_max
(
0
)
...
...
@@ -390,15 +384,11 @@ public:
,
psz_segment_filename
(
NULL
)
,
psz_title
(
NULL
)
,
psz_date_utc
(
NULL
)
,
meta
(
NULL
)
,
title
(
NULL
)
,
i_current_edition
(
0
)
,
psz_current_chapter
(
NULL
)
{}
vlc_stream_io_callback
*
in
;
EbmlStream
*
es
;
EbmlParser
*
ep
;
KaxSegment
*
segment
;
/* time scale */
uint64_t
i_timescale
;
...
...
@@ -415,15 +405,9 @@ public:
int64_t
i_chapters_position
;
int64_t
i_tags_position
;
/* current data */
KaxSegment
*
segment
;
KaxCluster
*
cluster
;
KaxSegmentUID
segment_uid
;
mtime_t
i_pts
;
mtime_t
i_start_pts
;
mtime_t
i_chapter_time
;
vlc_bool_t
b_cues
;
int
i_index
;
int
i_index_max
;
...
...
@@ -436,16 +420,93 @@ public:
char
*
psz_title
;
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
;
input_title_t
*
title
;
std
::
vector
<
KaxSegmentFamily
>
families
;
std
::
vector
<
KaxSegment
*>
family_members
;
std
::
vector
<
chapter_edition_t
>
editions
;
int
i_current_edition
;
const
chapter_item_t
*
psz_current_chapter
;
std
::
vector
<
matroska_stream_t
*>
streams
;
int
i_current_stream
;
matroska_stream_t
*
Stream
()
{
if
(
i_current_stream
!=
-
1
&&
i_current_stream
<
streams
.
size
()
)
return
streams
[
i_current_stream
];
return
NULL
;
}
};
static
int
Demux
(
demux_t
*
);
...
...
@@ -471,14 +532,16 @@ static void ParseChapters( demux_t *, EbmlElement *chapters );
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
uint8_t
*
p_peek
;
std
::
string
s_path
,
s_filename
;
int
i_upper_lvl
;
size_t
i
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
matroska_stream_t
*
p_stream
;
matroska_segment_t
*
p_segment
;
uint8_t
*
p_peek
;
std
::
string
s_path
,
s_filename
;
int
i_upper_lvl
;
size_t
i
;
int
i_track
;
int
i_track
;
EbmlElement
*
el
=
NULL
,
*
el1
=
NULL
;
...
...
@@ -494,40 +557,48 @@ static int Open( vlc_object_t * p_this )
p_demux
->
pf_control
=
Control
;
p_demux
->
p_sys
=
p_sys
=
new
demux_sys_t
;
p_sys
->
in
=
new
vlc_stream_io_callback
(
p_demux
->
s
);
p_sys
->
es
=
new
EbmlStream
(
*
p_sys
->
in
);
p_sys
->
f_duration
=
-
1
;
p_sys
->
i_timescale
=
MKVD_TIMECODESCALE
;
p_sys
->
i_track
=
0
;
p_sys
->
track
=
(
mkv_track_t
*
)
malloc
(
sizeof
(
mkv_track_t
)
);
p_stream
=
new
matroska_stream_t
;
p_segment
=
new
matroska_segment_t
;
p_sys
->
streams
.
push_back
(
p_stream
);
p_sys
->
i_current_stream
=
0
;
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_s
ys
->
i_cues_position
=
-
1
;
p_s
ys
->
i_chapters_position
=
-
1
;
p_s
ys
->
i_tags_position
=
-
1
;
p_s
ys
->
b_cues
=
VLC_FALSE
;
p_s
ys
->
i_index
=
0
;
p_s
ys
->
i_index_max
=
1024
;
p_s
ys
->
index
=
(
mkv_index_t
*
)
malloc
(
sizeof
(
mkv_index_t
)
*
p_s
ys
->
i_index_max
);
p_s
ys
->
psz_muxing_application
=
NULL
;
p_s
ys
->
psz_writing_application
=
NULL
;
p_s
ys
->
psz_segment_filename
=
NULL
;
p_s
ys
->
psz_title
=
NULL
;
p_s
ys
->
psz_date_utc
=
NULL
;;
p_s
egment
->
i_cues_position
=
-
1
;
p_s
egment
->
i_chapters_position
=
-
1
;
p_s
egment
->
i_tags_position
=
-
1
;
p_s
egment
->
b_cues
=
VLC_FALSE
;
p_s
egment
->
i_index
=
0
;
p_s
egment
->
i_index_max
=
1024
;
p_s
egment
->
index
=
(
mkv_index_t
*
)
malloc
(
sizeof
(
mkv_index_t
)
*
p_s
egment
->
i_index_max
);
p_s
egment
->
psz_muxing_application
=
NULL
;
p_s
egment
->
psz_writing_application
=
NULL
;
p_s
egment
->
psz_segment_filename
=
NULL
;
p_s
egment
->
psz_title
=
NULL
;
p_s
egment
->
psz_date_utc
=
NULL
;;
p_sys
->
meta
=
NULL
;
p_sys
->
title
=
NULL
;
if
(
p_s
ys
->
es
==
NULL
)
if
(
p_s
tream
->
es
==
NULL
)
{
msg_Err
(
p_demux
,
"failed to create EbmlStream"
);
delete
p_sys
->
in
;
delete
p_sys
;
return
VLC_EGENERIC
;
}
/* Find the EbmlHead element */
el
=
p_s
ys
->
es
->
FindNextID
(
EbmlHead
::
ClassInfos
,
0xFFFFFFFFL
);
el
=
p_s
tream
->
es
->
FindNextID
(
EbmlHead
::
ClassInfos
,
0xFFFFFFFFL
);
if
(
el
==
NULL
)
{
msg_Err
(
p_demux
,
"cannot find EbmlHead"
);
...
...
@@ -535,23 +606,23 @@ static int Open( vlc_object_t * p_this )
}
msg_Dbg
(
p_demux
,
"EbmlHead"
);
/* skip it */
el
->
SkipData
(
*
p_s
ys
->
es
,
el
->
Generic
().
Context
);
el
->
SkipData
(
*
p_s
tream
->
es
,
el
->
Generic
().
Context
);
delete
el
;
/* Find a segment */
el
=
p_s
ys
->
es
->
FindNextID
(
KaxSegment
::
ClassInfos
,
0xFFFFFFFFL
);
el
=
p_s
tream
->
es
->
FindNextID
(
KaxSegment
::
ClassInfos
,
0xFFFFFFFFL
);
if
(
el
==
NULL
)
{
msg_Err
(
p_demux
,
"cannot find KaxSegment"
);
goto
error
;
}
MkvTree
(
p_demux
,
0
,
"Segment"
);
p_s
ys
->
segment
=
(
KaxSegment
*
)
el
;
p_s
ys
->
cluster
=
NULL
;
p_s
egment
->
segment
=
(
KaxSegment
*
)
el
;
p_s
egment
->
cluster
=
NULL
;
p_s
ys
->
ep
=
new
EbmlParser
(
p_sys
->
es
,
el
);
p_s
tream
->
ep
=
new
EbmlParser
(
p_stream
->
es
,
el
);
while
(
(
el1
=
p_s
ys
->
ep
->
Get
()
)
!=
NULL
)
while
(
(
el1
=
p_s
tream
->
ep
->
Get
()
)
!=
NULL
)
{
if
(
MKV_IS_ID
(
el1
,
KaxInfo
)
)
{
...
...
@@ -573,9 +644,9 @@ static int Open( vlc_object_t * p_this )
{
msg_Dbg
(
p_demux
,
"| + Cluster"
);
p_s
ys
->
cluster
=
(
KaxCluster
*
)
el1
;
p_s
egment
->
cluster
=
(
KaxCluster
*
)
el1
;
p_s
ys
->
ep
->
Down
();
p_s
tream
->
ep
->
Down
();
/* stop parsing the stream */
break
;
}
...
...
@@ -692,15 +763,15 @@ static int Open( vlc_object_t * p_this )
if
(
MKV_IS_ID
(
l
,
KaxSegmentUID
)
)
{
p_uid
=
static_cast
<
KaxSegmentUID
*>
(
l
);
if
(
p_s
ys
->
segment_uid
==
*
p_uid
)
if
(
p_s
egment
->
segment_uid
==
*
p_uid
)
break
;
}
else
if
(
MKV_IS_ID
(
l
,
KaxSegmentFamily
)
)
{
KaxSegmentFamily
*
p_fam
=
static_cast
<
KaxSegmentFamily
*>
(
l
);
std
::
vector
<
KaxSegmentFamily
>::
iterator
iter
;
for
(
iter
=
p_s
ys
->
families
.
begin
();
iter
!=
p_s
ys
->
families
.
end
();
for
(
iter
=
p_s
egment
->
families
.
begin
();
iter
!=
p_s
egment
->
families
.
end
();
iter
++
)
{
if
(
*
iter
==
*
p_fam
)
...
...
@@ -739,14 +810,14 @@ static int Open( vlc_object_t * p_this )
}
if
(
p_s
ys
->
cluster
==
NULL
)
if
(
p_s
egment
->
cluster
==
NULL
)
{
msg_Err
(
p_demux
,
"cannot find any cluster, damaged file ?"
);
goto
error
;
}
/* *** Load the cue if found *** */
if
(
p_s
ys
->
i_cues_position
>=
0
)
if
(
p_s
egment
->
i_cues_position
>=
0
)
{
vlc_bool_t
b_seekable
;
...
...
@@ -757,20 +828,20 @@ static int Open( vlc_object_t * p_this )
}
}
if
(
!
p_s
ys
->
b_cues
||
p_sys
->
i_index
<=
0
)
if
(
!
p_s
egment
->
b_cues
||
p_segment
->
i_index
<=
0
)
{
msg_Warn
(
p_demux
,
"no cues/empty cues found->seek won't be precise"
);
IndexAppendCluster
(
p_demux
,
p_s
ys
->
cluster
);
IndexAppendCluster
(
p_demux
,
p_s
egment
->
cluster
);
p_s
ys
->
b_cues
=
VLC_FALSE
;
p_s
egment
->
b_cues
=
VLC_FALSE
;
}
/* add all es */
msg_Dbg
(
p_demux
,
"found %d es"
,
p_s
ys
->
i_track
);
for
(
i_track
=
0
;
i_track
<
p_s
ys
->
i_track
;
i_track
++
)
msg_Dbg
(
p_demux
,
"found %d es"
,
p_s
egment
->
i_track
);
for
(
i_track
=
0
;
i_track
<
p_s
egment
->
i_track
;
i_track
++
)
{
#define tk p_s
ys
->track[i_track]
#define tk p_s
egment
->track[i_track]
if
(
tk
.
fmt
.
i_cat
==
UNKNOWN_ES
)
{
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 )
return
VLC_SUCCESS
;
error:
delete
p_sys
->
es
;
delete
p_sys
->
in
;
delete
p_sys
;
return
VLC_EGENERIC
;
}
...
...
@@ -1073,11 +1142,13 @@ static void Close( vlc_object_t *p_this )
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
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
;
for
(
i_track
=
0
;
i_track
<
p_s
ys
->
i_track
;
i_track
++
)
for
(
i_track
=
0
;
i_track
<
p_s
egment
->
i_track
;
i_track
++
)
{
#define tk p_s
ys
->track[i_track]
#define tk p_s
egment
->track[i_track]
if
(
tk
.
fmt
.
psz_description
)
{
free
(
tk
.
fmt
.
psz_description
);
...
...
@@ -1092,22 +1163,19 @@ static void Close( vlc_object_t *p_this )
}
#undef tk
}
free
(
p_s
ys
->
track
);
free
(
p_s
egment
->
track
);
if
(
p_s
ys
->
psz_writing_application
)
if
(
p_s
egment
->
psz_writing_application
)
{
free
(
p_s
ys
->
psz_writing_application
);
free
(
p_s
egment
->
psz_writing_application
);
}
if
(
p_s
ys
->
psz_muxing_application
)
if
(
p_s
egment
->
psz_muxing_application
)
{
free
(
p_s
ys
->
psz_muxing_application
);
free
(
p_s
egment
->
psz_muxing_application
);
}
delete
p_s
ys
->
segment
;
delete
p_s
egment
->
segment
;
delete
p_sys
->
ep
;
delete
p_sys
->
es
;
delete
p_sys
->
in
;
delete
p_sys
;
}
...
...
@@ -1116,11 +1184,12 @@ static void Close( vlc_object_t *p_this )
*****************************************************************************/
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
;
double
*
pf
,
f
;
int
i_skp
;
mtime_t
*
i_sk_time
;
vlc_meta_t
**
pp_meta
;
...
...
@@ -1133,19 +1202,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case
DEMUX_GET_LENGTH
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
if
(
p_s
ys
->
f_duration
>
0.0
)
if
(
p_s
egment
->
f_duration
>
0.0
)
{
*
pi64
=
(
int64_t
)(
p_s
ys
->
f_duration
*
1000
);
*
pi64
=
(
int64_t
)(
p_s
egment
->
f_duration
*
1000
);
return
VLC_SUCCESS
;
}
return
VLC_EGENERIC
;
case
DEMUX_GET_POSITION
:
pf
=
(
double
*
)
va_arg
(
args
,
double
*
);
/* if (p_sys->i_pts < p_sys->i_start_pts)
*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
);
*
pf
=
(
double
)
p_sys
->
i_pts
/
(
1000.0
*
p_segment
->
f_duration
);
return
VLC_SUCCESS
;
case
DEMUX_SET_POSITION
:
...
...
@@ -1155,10 +1221,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case
DEMUX_GET_TIME
:
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
;
case
DEMUX_GET_TITLE_INFO
:
...
...
@@ -1206,7 +1269,9 @@ 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
)
{
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
;
*
pi_ref1
=
-
1
;
...
...
@@ -1222,14 +1287,14 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
return
VLC_EGENERIC
;
}
el
=
p_s
ys
->
ep
->
Get
();
i_level
=
p_s
ys
->
ep
->
GetLevel
();
el
=
p_s
tream
->
ep
->
Get
();
i_level
=
p_s
tream
->
ep
->
GetLevel
();
if
(
el
==
NULL
&&
*
pp_block
!=
NULL
)
{
/* update the index */
#define idx p_s
ys->index[p_sys
->i_index - 1]
if
(
p_s
ys
->
i_index
>
0
&&
idx
.
i_time
==
-
1
)
#define idx p_s
egment->index[p_segment
->i_index - 1]
if
(
p_s
egment
->
i_index
>
0
&&
idx
.
i_time
==
-
1
)
{
idx
.
i_time
=
(
*
pp_block
)
->
GlobalTimecode
()
/
(
mtime_t
)
1000
;
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
if
(
el
==
NULL
)
{
if
(
p_s
ys
->
ep
->
GetLevel
()
>
1
)
if
(
p_s
tream
->
ep
->
GetLevel
()
>
1
)
{
p_s
ys
->
ep
->
Up
();
p_s
tream
->
ep
->
Up
();
continue
;
}
msg_Warn
(
p_demux
,
"EOF"
);
...
...
@@ -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
)
)
{
p_s
ys
->
cluster
=
(
KaxCluster
*
)
el
;
p_s
egment
->
cluster
=
(
KaxCluster
*
)
el
;
/* add it to the index */
if
(
p_s
ys
->
i_index
==
0
||
(
p_s
ys
->
i_index
>
0
&&
p_sys
->
index
[
p_sys
->
i_index
-
1
].
i_position
<
(
int64_t
)
p_sys
->
cluster
->
GetElementPosition
()
)
)
if
(
p_s
egment
->
i_index
==
0
||
(
p_s
egment
->
i_index
>
0
&&
p_segment
->
index
[
p_segment
->
i_index
-
1
].
i_position
<
(
int64_t
)
p_segment
->
cluster
->
GetElementPosition
()
)
)
{
IndexAppendCluster
(
p_demux
,
p_s
ys
->
cluster
);
IndexAppendCluster
(
p_demux
,
p_s
egment
->
cluster
);
}
p_s
ys
->
ep
->
Down
();
p_s
tream
->
ep
->
Down
();
}
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
{
KaxClusterTimecode
&
ctc
=
*
(
KaxClusterTimecode
*
)
el
;
ctc
.
ReadData
(
p_s
ys
->
es
->
I_O
(),
SCOPE_ALL_DATA
);
p_s
ys
->
cluster
->
InitTimecode
(
uint64
(
ctc
),
p_sys
->
i_timescale
);
ctc
.
ReadData
(
p_s
tream
->
es
->
I_O
(),
SCOPE_ALL_DATA
);
p_s
egment
->
cluster
->
InitTimecode
(
uint64
(
ctc
),
p_segment
->
i_timescale
);
}
else
if
(
MKV_IS_ID
(
el
,
KaxBlockGroup
)
)
{
p_s
ys
->
ep
->
Down
();
p_s
tream
->
ep
->
Down
();
}
}
else
if
(
i_level
==
3
)
...
...
@@ -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
)
->
ReadData
(
p_s
ys
->
es
->
I_O
()
);
(
*
pp_block
)
->
SetParent
(
*
p_s
ys
->
cluster
);
(
*
pp_block
)
->
ReadData
(
p_s
tream
->
es
->
I_O
()
);
(
*
pp_block
)
->
SetParent
(
*
p_s
egment
->
cluster
);
p_s
ys
->
ep
->
Keep
();
p_s
tream
->
ep
->
Keep
();
}
else
if
(
MKV_IS_ID
(
el
,
KaxBlockDuration
)
)
{
KaxBlockDuration
&
dur
=
*
(
KaxBlockDuration
*
)
el
;
dur
.
ReadData
(
p_s
ys
->
es
->
I_O
()
);
dur
.
ReadData
(
p_s
tream
->
es
->
I_O
()
);
*
pi_duration
=
uint64
(
dur
);
}
else
if
(
MKV_IS_ID
(
el
,
KaxReferenceBlock
)
)
{
KaxReferenceBlock
&
ref
=
*
(
KaxReferenceBlock
*
)
el
;
ref
.
ReadData
(
p_s
ys
->
es
->
I_O
()
);
ref
.
ReadData
(
p_s
tream
->
es
->
I_O
()
);
if
(
*
pi_ref1
==
-
1
)
{
*
pi_ref1
=
int64
(
ref
);
...
...
@@ -1342,14 +1407,16 @@ static block_t *MemToBlock( demux_t *p_demux, uint8_t *p_mem, int i_mem)
static
void
BlockDecode
(
demux_t
*
p_demux
,
KaxBlock
*
block
,
mtime_t
i_pts
,
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
;
unsigned
int
i
;
vlc_bool_t
b
;
#define tk p_s
ys
->track[i_track]
for
(
i_track
=
0
;
i_track
<
p_s
ys
->
i_track
;
i_track
++
)
#define tk p_s
egment
->track[i_track]
for
(
i_track
=
0
;
i_track
<
p_s
egment
->
i_track
;
i_track
++
)
{
if
(
tk
.
i_number
==
block
->
TrackNum
()
)
{
...
...
@@ -1357,7 +1424,7 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
}
}
if
(
i_track
>=
p_s
ys
->
i_track
)
if
(
i_track
>=
p_s
egment
->
i_track
)
{
msg_Err
(
p_demux
,
"invalid track number=%d"
,
block
->
TrackNum
()
);
return
;
...
...
@@ -1437,43 +1504,47 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
static
void
UpdateCurrentToChapter
(
demux_t
&
demux
)
{
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
;
/* update current chapter/seekpoint */
if
(
sys
.
editions
.
size
())
if
(
p_segment
->
editions
.
size
())
{
/* 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 */
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_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) */
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
);
/* 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 */
}
//
sys.
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_user_time = psz_curr_chapter->i_user_start_time - psz_curr_chapter->i_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
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
mtime_t
i_time_offset
=
0
;
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
;
KaxBlock
*
block
;
int64_t
i_block_duration
;
...
...
@@ -1496,38 +1567,38 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
return
;
}
delete
p_s
ys
->
ep
;
p_s
ys
->
ep
=
new
EbmlParser
(
p_sys
->
es
,
p_sys
->
segment
);
p_s
ys
->
cluster
=
NULL
;
delete
p_s
tream
->
ep
;
p_s
tream
->
ep
=
new
EbmlParser
(
p_stream
->
es
,
p_segment
->
segment
);
p_s
egment
->
cluster
=
NULL
;
/* seek without index or without date */
if
(
f_percent
>=
0
&&
(
config_GetInt
(
p_demux
,
"mkv-seek-percent"
)
||
!
p_s
ys
->
b_cues
||
i_date
<
0
))
if
(
f_percent
>=
0
&&
(
config_GetInt
(
p_demux
,
"mkv-seek-percent"
)
||
!
p_s
egment
->
b_cues
||
i_date
<
0
))
{
if
(
p_s
ys
->
f_duration
>=
0
)
if
(
p_s
egment
->
f_duration
>=
0
)
{
i_date
=
int64_t
(
f_percent
*
p_s
ys
->
f_duration
*
1000.0
);
i_date
=
int64_t
(
f_percent
*
p_s
egment
->
f_duration
*
1000.0
);
}
else
{
int64_t
i_pos
=
int64_t
(
f_percent
*
stream_Size
(
p_demux
->
s
)
);
msg_Dbg
(
p_demux
,
"inacurate way of seeking"
);
for
(
i_index
=
0
;
i_index
<
p_s
ys
->
i_index
;
i_index
++
)
for
(
i_index
=
0
;
i_index
<
p_s
egment
->
i_index
;
i_index
++
)
{
if
(
p_s
ys
->
index
[
i_index
].
i_position
>=
i_pos
)
if
(
p_s
egment
->
index
[
i_index
].
i_position
>=
i_pos
)
{
break
;
}
}
if
(
i_index
==
p_s
ys
->
i_index
)
if
(
i_index
==
p_s
egment
->
i_index
)
{
i_index
--
;
}
i_date
=
p_s
ys
->
index
[
i_index
].
i_time
;
i_date
=
p_s
egment
->
index
[
i_index
].
i_time
;
#if 0
if( p_s
ys
->index[i_index].i_position < i_pos )
if( p_s
egment
->index[i_index].i_position < i_pos )
{
EbmlElement *el;
...
...
@@ -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
if
(
psz_chapter
==
NULL
)
{
if
(
p_s
ys
->
editions
.
size
()
&&
p_sys
->
editions
[
p_sys
->
i_current_edition
].
b_ordered
)
if
(
p_s
egment
->
editions
.
size
()
&&
p_segment
->
editions
[
p_segment
->
i_current_edition
].
b_ordered
)
{
/* 1st, we need to know in which chapter we are */
psz_chapter
=
p_s
ys
->
editions
[
p_sys
->
i_current_edition
].
FindTimecode
(
i_date
);
psz_chapter
=
p_s
egment
->
editions
[
p_segment
->
i_current_edition
].
FindTimecode
(
i_date
);
}
}
if
(
psz_chapter
!=
NULL
)
{
p_s
ys
->
psz_current_chapter
=
psz_chapter
;
p_s
egment
->
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_demux
->
info
.
i_update
|=
INPUT_UPDATE_SEEKPOINT
;
p_demux
->
info
.
i_seekpoint
=
psz_chapter
->
i_seekpoint_num
-
1
;
}
for
(
;
i_index
<
p_s
ys
->
i_index
;
i_index
++
)
for
(
;
i_index
<
p_s
egment
->
i_index
;
i_index
++
)
{
if
(
p_s
ys
->
index
[
i_index
].
i_time
+
i_time_offset
>
i_date
)
if
(
p_s
egment
->
index
[
i_index
].
i_time
+
i_time_offset
>
i_date
)
{
break
;
}
...
...
@@ -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%%)"
,
p_s
ys
->
index
[
i_index
].
i_time
,
(
int
)(
100
*
p_s
ys
->
index
[
i_index
].
i_position
/
p_s
egment
->
index
[
i_index
].
i_time
,
(
int
)(
100
*
p_s
egment
->
index
[
i_index
].
i_position
/
stream_Size
(
p_demux
->
s
)
)
);
p_s
ys
->
in
->
setFilePointer
(
p_sys
->
index
[
i_index
].
i_position
,
p_s
tream
->
in
->
setFilePointer
(
p_segment
->
index
[
i_index
].
i_position
,
seek_beginning
);
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
es_out_Control
(
p_demux
->
out
,
ES_OUT_RESET_PCR
);
/* now parse until key frame */
#define tk p_s
ys
->track[i_track]
#define tk p_s
egment
->track[i_track]
i_track_skipping
=
0
;
for
(
i_track
=
0
;
i_track
<
p_s
ys
->
i_track
;
i_track
++
)
for
(
i_track
=
0
;
i_track
<
p_s
egment
->
i_track
;
i_track
++
)
{
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
return
;
}
for
(
i_track
=
0
;
i_track
<
p_s
ys
->
i_track
;
i_track
++
)
for
(
i_track
=
0
;
i_track
<
p_s
egment
->
i_track
;
i_track
++
)
{
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
p_sys
->
i_pts
=
p_sys
->
i_chapter_time
+
block
->
GlobalTimecode
()
/
(
mtime_t
)
1000
;
if
(
i_track
<
p_s
ys
->
i_track
)
if
(
i_track
<
p_s
egment
->
i_track
)
{
if
(
tk
.
fmt
.
i_cat
==
VIDEO_ES
)
{
...
...
@@ -1660,8 +1731,10 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
*****************************************************************************/
static
int
Demux
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
int
i_block_count
=
0
;
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
;
KaxBlock
*
block
;
int64_t
i_block_duration
;
...
...
@@ -1673,7 +1746,7 @@ static int Demux( demux_t *p_demux)
if
(
p_sys
->
i_pts
>=
p_sys
->
i_start_pts
)
UpdateCurrentToChapter
(
*
p_demux
);
if
(
p_s
ys
->
editions
.
size
()
&&
p_sys
->
editions
[
p_sys
->
i_current_edition
].
b_ordered
&&
p_sys
->
psz_current_chapter
==
NULL
)
if
(
p_s
egment
->
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 */
return
0
;
...
...
@@ -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
(
p_s
ys
->
editions
.
size
()
&&
p_sys
->
editions
[
p_sys
->
i_current_edition
].
b_ordered
)
if
(
p_s
egment
->
editions
.
size
()
&&
p_segment
->
editions
[
p_segment
->
i_current_edition
].
b_ordered
)
{
// check if there are more chapters to read
if
(
p_s
ys
->
psz_current_chapter
!=
NULL
)
if
(
p_s
egment
->
psz_current_chapter
!=
NULL
)
{
p_sys
->
i_pts
=
p_s
ys
->
psz_current_chapter
->
i_user_end_time
;
p_sys
->
i_pts
=
p_s
egment
->
psz_current_chapter
->
i_user_end_time
;
return
1
;
}
...
...
@@ -1908,27 +1981,29 @@ EbmlElement *EbmlParser::Get( void )
static
void
LoadCues
(
demux_t
*
p_demux
)
{
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
;
EbmlElement
*
el
,
*
cues
;
msg_Dbg
(
p_demux
,
"loading cues"
);
p_s
ys
->
in
->
setFilePointer
(
p_sys
->
i_cues_position
,
seek_beginning
);
cues
=
p_s
ys
->
es
->
FindNextID
(
KaxCues
::
ClassInfos
,
0xFFFFFFFFL
);
p_s
tream
->
in
->
setFilePointer
(
p_segment
->
i_cues_position
,
seek_beginning
);
cues
=
p_s
tream
->
es
->
FindNextID
(
KaxCues
::
ClassInfos
,
0xFFFFFFFFL
);
if
(
cues
==
NULL
)
{
msg_Err
(
p_demux
,
"cannot load cues (broken seekhead or file)"
);
p_s
ys
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
p_s
tream
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
return
;
}
ep
=
new
EbmlParser
(
p_s
ys
->
es
,
cues
);
ep
=
new
EbmlParser
(
p_s
tream
->
es
,
cues
);
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
{
if
(
MKV_IS_ID
(
el
,
KaxCuePoint
)
)
{
#define idx p_s
ys->index[p_sys
->i_index]
#define idx p_s
egment->index[p_segment
->i_index]
idx
.
i_track
=
-
1
;
idx
.
i_block_number
=
-
1
;
...
...
@@ -1943,9 +2018,9 @@ static void LoadCues( demux_t *p_demux )
{
KaxCueTime
&
ctime
=
*
(
KaxCueTime
*
)
el
;
ctime
.
ReadData
(
p_s
ys
->
es
->
I_O
()
);
ctime
.
ReadData
(
p_s
tream
->
es
->
I_O
()
);
idx
.
i_time
=
uint64
(
ctime
)
*
p_s
ys
->
i_timescale
/
(
mtime_t
)
1000
;
idx
.
i_time
=
uint64
(
ctime
)
*
p_s
egment
->
i_timescale
/
(
mtime_t
)
1000
;
}
else
if
(
MKV_IS_ID
(
el
,
KaxCueTrackPositions
)
)
{
...
...
@@ -1956,21 +2031,21 @@ static void LoadCues( demux_t *p_demux )
{
KaxCueTrack
&
ctrack
=
*
(
KaxCueTrack
*
)
el
;
ctrack
.
ReadData
(
p_s
ys
->
es
->
I_O
()
);
ctrack
.
ReadData
(
p_s
tream
->
es
->
I_O
()
);
idx
.
i_track
=
uint16
(
ctrack
);
}
else
if
(
MKV_IS_ID
(
el
,
KaxCueClusterPosition
)
)
{
KaxCueClusterPosition
&
ccpos
=
*
(
KaxCueClusterPosition
*
)
el
;
ccpos
.
ReadData
(
p_s
ys
->
es
->
I_O
()
);
idx
.
i_position
=
p_s
ys
->
segment
->
GetGlobalPosition
(
uint64
(
ccpos
)
);
ccpos
.
ReadData
(
p_s
tream
->
es
->
I_O
()
);
idx
.
i_position
=
p_s
egment
->
segment
->
GetGlobalPosition
(
uint64
(
ccpos
)
);
}
else
if
(
MKV_IS_ID
(
el
,
KaxCueBlockNumber
)
)
{
KaxCueBlockNumber
&
cbnum
=
*
(
KaxCueBlockNumber
*
)
el
;
cbnum
.
ReadData
(
p_s
ys
->
es
->
I_O
()
);
cbnum
.
ReadData
(
p_s
tream
->
es
->
I_O
()
);
idx
.
i_block_number
=
uint32
(
cbnum
);
}
else
...
...
@@ -1993,11 +2068,11 @@ static void LoadCues( demux_t *p_demux )
idx.i_track, idx.i_block_number );
#endif
p_s
ys
->
i_index
++
;
if
(
p_s
ys
->
i_index
>=
p_sys
->
i_index_max
)
p_s
egment
->
i_index
++
;
if
(
p_s
egment
->
i_index
>=
p_segment
->
i_index_max
)
{
p_s
ys
->
i_index_max
+=
1024
;
p_s
ys
->
index
=
(
mkv_index_t
*
)
realloc
(
p_sys
->
index
,
sizeof
(
mkv_index_t
)
*
p_sys
->
i_index_max
);
p_s
egment
->
i_index_max
+=
1024
;
p_s
egment
->
index
=
(
mkv_index_t
*
)
realloc
(
p_segment
->
index
,
sizeof
(
mkv_index_t
)
*
p_segment
->
i_index_max
);
}
#undef idx
}
...
...
@@ -2009,32 +2084,34 @@ static void LoadCues( demux_t *p_demux )
delete
ep
;
delete
cues
;
p_s
ys
->
b_cues
=
VLC_TRUE
;
p_s
egment
->
b_cues
=
VLC_TRUE
;
msg_Dbg
(
p_demux
,
"loading cues done."
);
p_s
ys
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
p_s
tream
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
}
static
void
LoadTags
(
demux_t
*
p_demux
)
{
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
;
EbmlElement
*
el
,
*
tags
;
msg_Dbg
(
p_demux
,
"loading tags"
);
p_s
ys
->
in
->
setFilePointer
(
p_sys
->
i_tags_position
,
seek_beginning
);
tags
=
p_s
ys
->
es
->
FindNextID
(
KaxTags
::
ClassInfos
,
0xFFFFFFFFL
);
p_s
tream
->
in
->
setFilePointer
(
p_segment
->
i_tags_position
,
seek_beginning
);
tags
=
p_s
tream
->
es
->
FindNextID
(
KaxTags
::
ClassInfos
,
0xFFFFFFFFL
);
if
(
tags
==
NULL
)
{
msg_Err
(
p_demux
,
"cannot load tags (broken seekhead or file)"
);
p_s
ys
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
p_s
tream
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
return
;
}
msg_Dbg
(
p_demux
,
"Tags"
);
ep
=
new
EbmlParser
(
p_s
ys
->
es
,
tags
);
ep
=
new
EbmlParser
(
p_s
tream
->
es
,
tags
);
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
{
if
(
MKV_IS_ID
(
el
,
KaxTag
)
)
...
...
@@ -2137,7 +2214,7 @@ static void LoadTags( demux_t *p_demux )
delete
tags
;
msg_Dbg
(
p_demux
,
"loading tags done."
);
p_s
ys
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
p_s
tream
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
}
/*****************************************************************************
...
...
@@ -2146,6 +2223,8 @@ static void LoadTags( demux_t *p_demux )
static
void
ParseSeekHead
(
demux_t
*
p_demux
,
EbmlElement
*
seekhead
)
{
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
;
EbmlMaster
*
m
;
unsigned
int
i
;
...
...
@@ -2155,7 +2234,7 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
seekhead
);
m
->
Read
(
*
p_s
ys
->
es
,
seekhead
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
m
->
Read
(
*
p_s
tream
->
es
,
seekhead
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
...
...
@@ -2194,17 +2273,17 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
if
(
id
==
KaxCues
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = cues at "
I64Fd
,
i_pos
);
p_s
ys
->
i_cues_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
p_s
egment
->
i_cues_position
=
p_segment
->
segment
->
GetGlobalPosition
(
i_pos
);
}
else
if
(
id
==
KaxChapters
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = chapters at "
I64Fd
,
i_pos
);
p_s
ys
->
i_chapters_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
p_s
egment
->
i_chapters_position
=
p_segment
->
segment
->
GetGlobalPosition
(
i_pos
);
}
else
if
(
id
==
KaxTags
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = tags at "
I64Fd
,
i_pos
);
p_s
ys
->
i_tags_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
p_s
egment
->
i_tags_position
=
p_segment
->
segment
->
GetGlobalPosition
(
i_pos
);
}
}
}
...
...
@@ -2221,17 +2300,19 @@ static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
static
void
ParseTrackEntry
(
demux_t
*
p_demux
,
EbmlMaster
*
m
)
{
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
;
mkv_track_t
*
tk
;
msg_Dbg
(
p_demux
,
"| | + Track Entry"
);
p_s
ys
->
i_track
++
;
p_s
ys
->
track
=
(
mkv_track_t
*
)
realloc
(
p_sys
->
track
,
sizeof
(
mkv_track_t
)
*
(
p_sys
->
i_track
+
1
)
);
p_s
egment
->
i_track
++
;
p_s
egment
->
track
=
(
mkv_track_t
*
)
realloc
(
p_segment
->
track
,
sizeof
(
mkv_track_t
)
*
(
p_segment
->
i_track
+
1
)
);
/* Init the track */
tk
=
&
p_s
ys
->
track
[
p_sys
->
i_track
-
1
];
tk
=
&
p_s
egment
->
track
[
p_segment
->
i_track
-
1
];
memset
(
tk
,
0
,
sizeof
(
mkv_track_t
)
);
...
...
@@ -2241,7 +2322,7 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
tk
->
b_default
=
VLC_TRUE
;
tk
->
b_enabled
=
VLC_TRUE
;
tk
->
i_number
=
p_s
ys
->
i_track
-
1
;
tk
->
i_number
=
p_s
egment
->
i_track
-
1
;
tk
->
i_extra_data
=
0
;
tk
->
p_extra_data
=
NULL
;
tk
->
psz_codec
=
NULL
;
...
...
@@ -2625,6 +2706,8 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
static
void
ParseTracks
(
demux_t
*
p_demux
,
EbmlElement
*
tracks
)
{
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
;
EbmlMaster
*
m
;
unsigned
int
i
;
...
...
@@ -2634,7 +2717,7 @@ static void ParseTracks( demux_t *p_demux, EbmlElement *tracks )
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
tracks
);
m
->
Read
(
*
p_s
ys
->
es
,
tracks
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
m
->
Read
(
*
p_s
tream
->
es
,
tracks
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
...
...
@@ -2657,6 +2740,8 @@ static void ParseTracks( demux_t *p_demux, EbmlElement *tracks )
static
void
ParseInfo
(
demux_t
*
p_demux
,
EbmlElement
*
info
)
{
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
;
EbmlMaster
*
m
;
unsigned
int
i
;
...
...
@@ -2666,7 +2751,7 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
info
);
m
->
Read
(
*
p_s
ys
->
es
,
info
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
m
->
Read
(
*
p_s
tream
->
es
,
info
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
...
...
@@ -2674,68 +2759,68 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
if
(
MKV_IS_ID
(
l
,
KaxSegmentUID
)
)
{
p_s
ys
->
segment_uid
=
*
(
new
KaxSegmentUID
(
*
static_cast
<
KaxSegmentUID
*>
(
l
)));
p_s
egment
->
segment_uid
=
*
(
new
KaxSegmentUID
(
*
static_cast
<
KaxSegmentUID
*>
(
l
)));
msg_Dbg
(
p_demux
,
"| | + UID=%d"
,
*
(
uint32
*
)
p_s
ys
->
segment_uid
.
GetBuffer
()
);
msg_Dbg
(
p_demux
,
"| | + UID=%d"
,
*
(
uint32
*
)
p_s
egment
->
segment_uid
.
GetBuffer
()
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTimecodeScale
)
)
{
KaxTimecodeScale
&
tcs
=
*
(
KaxTimecodeScale
*
)
l
;
p_s
ys
->
i_timescale
=
uint64
(
tcs
);
p_s
egment
->
i_timescale
=
uint64
(
tcs
);
msg_Dbg
(
p_demux
,
"| | + TimecodeScale="
I64Fd
,
p_s
ys
->
i_timescale
);
p_s
egment
->
i_timescale
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxDuration
)
)
{
KaxDuration
&
dur
=
*
(
KaxDuration
*
)
l
;
p_s
ys
->
f_duration
=
float
(
dur
);
p_s
egment
->
f_duration
=
float
(
dur
);
msg_Dbg
(
p_demux
,
"| | + Duration=%f"
,
p_s
ys
->
f_duration
);
p_s
egment
->
f_duration
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxMuxingApp
)
)
{
KaxMuxingApp
&
mapp
=
*
(
KaxMuxingApp
*
)
l
;
p_s
ys
->
psz_muxing_application
=
UTF8ToStr
(
UTFstring
(
mapp
)
);
p_s
egment
->
psz_muxing_application
=
UTF8ToStr
(
UTFstring
(
mapp
)
);
msg_Dbg
(
p_demux
,
"| | + Muxing Application=%s"
,
p_s
ys
->
psz_muxing_application
);
p_s
egment
->
psz_muxing_application
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxWritingApp
)
)
{
KaxWritingApp
&
wapp
=
*
(
KaxWritingApp
*
)
l
;
p_s
ys
->
psz_writing_application
=
UTF8ToStr
(
UTFstring
(
wapp
)
);
p_s
egment
->
psz_writing_application
=
UTF8ToStr
(
UTFstring
(
wapp
)
);
msg_Dbg
(
p_demux
,
"| | + Writing Application=%s"
,
p_s
ys
->
psz_writing_application
);
p_s
egment
->
psz_writing_application
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxSegmentFilename
)
)
{
KaxSegmentFilename
&
sfn
=
*
(
KaxSegmentFilename
*
)
l
;
p_s
ys
->
psz_segment_filename
=
UTF8ToStr
(
UTFstring
(
sfn
)
);
p_s
egment
->
psz_segment_filename
=
UTF8ToStr
(
UTFstring
(
sfn
)
);
msg_Dbg
(
p_demux
,
"| | + Segment Filename=%s"
,
p_s
ys
->
psz_segment_filename
);
p_s
egment
->
psz_segment_filename
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTitle
)
)
{
KaxTitle
&
title
=
*
(
KaxTitle
*
)
l
;
p_s
ys
->
psz_title
=
UTF8ToStr
(
UTFstring
(
title
)
);
p_s
egment
->
psz_title
=
UTF8ToStr
(
UTFstring
(
title
)
);
msg_Dbg
(
p_demux
,
"| | + Title=%s"
,
p_s
ys
->
psz_title
);
msg_Dbg
(
p_demux
,
"| | + Title=%s"
,
p_s
egment
->
psz_title
);
}
if
(
MKV_IS_ID
(
l
,
KaxSegmentFamily
)
)
{
KaxSegmentFamily
*
uid
=
static_cast
<
KaxSegmentFamily
*>
(
l
);
p_s
ys
->
families
.
push_back
(
*
uid
);
p_s
egment
->
families
.
push_back
(
*
uid
);
msg_Dbg
(
p_demux
,
"| | + family=%d"
,
*
(
uint32
*
)
uid
->
GetBuffer
()
);
}
...
...
@@ -2753,8 +2838,8 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
asctime_r
(
&
tmres
,
buffer
)
)
{
buffer
[
strlen
(
buffer
)
-
1
]
=
'\0'
;
p_s
ys
->
psz_date_utc
=
strdup
(
buffer
);
msg_Dbg
(
p_demux
,
"| | + Date=%s"
,
p_s
ys
->
psz_date_utc
);
p_s
egment
->
psz_date_utc
=
strdup
(
buffer
);
msg_Dbg
(
p_demux
,
"| | + Date=%s"
,
p_s
egment
->
psz_date_utc
);
}
}
#endif
...
...
@@ -2764,7 +2849,7 @@ static void ParseInfo( demux_t *p_demux, EbmlElement *info )
}
}
p_s
ys
->
f_duration
*=
p_sys
->
i_timescale
/
1000000.0
;
p_s
egment
->
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
static
void
ParseChapters
(
demux_t
*
p_demux
,
EbmlElement
*
chapters
)
{
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
;
EbmlMaster
*
m
;
unsigned
int
i
;
...
...
@@ -2875,7 +2962,7 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
chapters
);
m
->
Read
(
*
p_s
ys
->
es
,
chapters
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
m
->
Read
(
*
p_s
tream
->
es
,
chapters
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
...
...
@@ -2909,14 +2996,14 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
else
if
(
MKV_IS_ID
(
l
,
KaxEditionFlagDefault
)
)
{
if
(
uint8
(
*
static_cast
<
KaxEditionFlagDefault
*>
(
l
))
!=
0
)
i_default_edition
=
p_s
ys
->
editions
.
size
();
i_default_edition
=
p_s
egment
->
editions
.
size
();
}
else
{
msg_Dbg
(
p_demux
,
"| | | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
p_s
ys
->
editions
.
push_back
(
edition
);
p_s
egment
->
editions
.
push_back
(
edition
);
}
else
{
...
...
@@ -2924,19 +3011,19 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
}
}
for
(
i
=
0
;
i
<
p_s
ys
->
editions
.
size
();
i
++
)
for
(
i
=
0
;
i
<
p_s
egment
->
editions
.
size
();
i
++
)
{
p_s
ys
->
editions
[
i
].
RefreshChapters
(
*
p_sys
->
title
);
p_s
egment
->
editions
[
i
].
RefreshChapters
(
*
p_sys
->
title
);
}
p_s
ys
->
i_current_edition
=
i_default_edition
;
p_s
egment
->
i_current_edition
=
i_default_edition
;
if
(
p_s
ys
->
editions
[
i_default_edition
].
b_ordered
)
if
(
p_s
egment
->
editions
[
i_default_edition
].
b_ordered
)
{
/* update the duration of the segment according to the sum of all sub chapters */
f_duration
=
p_s
ys
->
editions
[
i_default_edition
].
Duration
()
/
I64C
(
1000
);
f_duration
=
p_s
egment
->
editions
[
i_default_edition
].
Duration
()
/
I64C
(
1000
);
if
(
f_duration
>
0.0
)
p_s
ys
->
f_duration
=
f_duration
;
p_s
egment
->
f_duration
=
f_duration
;
}
}
...
...
@@ -2946,34 +3033,36 @@ static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
static
void
InformationCreate
(
demux_t
*
p_demux
)
{
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
;
p_sys
->
meta
=
vlc_meta_New
();
if
(
p_s
ys
->
psz_title
)
if
(
p_s
egment
->
psz_title
)
{
vlc_meta_Add
(
p_sys
->
meta
,
VLC_META_TITLE
,
p_s
ys
->
psz_title
);
vlc_meta_Add
(
p_sys
->
meta
,
VLC_META_TITLE
,
p_s
egment
->
psz_title
);
}
if
(
p_s
ys
->
psz_date_utc
)
if
(
p_s
egment
->
psz_date_utc
)
{
vlc_meta_Add
(
p_sys
->
meta
,
VLC_META_DATE
,
p_s
ys
->
psz_date_utc
);
vlc_meta_Add
(
p_sys
->
meta
,
VLC_META_DATE
,
p_s
egment
->
psz_date_utc
);
}
if
(
p_s
ys
->
psz_segment_filename
)
if
(
p_s
egment
->
psz_segment_filename
)
{
vlc_meta_Add
(
p_sys
->
meta
,
_
(
"Segment filename"
),
p_s
ys
->
psz_segment_filename
);
vlc_meta_Add
(
p_sys
->
meta
,
_
(
"Segment filename"
),
p_s
egment
->
psz_segment_filename
);
}
if
(
p_s
ys
->
psz_muxing_application
)
if
(
p_s
egment
->
psz_muxing_application
)
{
vlc_meta_Add
(
p_sys
->
meta
,
_
(
"Muxing application"
),
p_s
ys
->
psz_muxing_application
);
vlc_meta_Add
(
p_sys
->
meta
,
_
(
"Muxing application"
),
p_s
egment
->
psz_muxing_application
);
}
if
(
p_s
ys
->
psz_writing_application
)
if
(
p_s
egment
->
psz_writing_application
)
{
vlc_meta_Add
(
p_sys
->
meta
,
_
(
"Writing application"
),
p_s
ys
->
psz_writing_application
);
vlc_meta_Add
(
p_sys
->
meta
,
_
(
"Writing application"
),
p_s
egment
->
psz_writing_application
);
}
for
(
i_track
=
0
;
i_track
<
p_s
ys
->
i_track
;
i_track
++
)
for
(
i_track
=
0
;
i_track
<
p_s
egment
->
i_track
;
i_track
++
)
{
mkv_track_t
*
tk
=
&
p_s
ys
->
track
[
i_track
];
mkv_track_t
*
tk
=
&
p_s
egment
->
track
[
i_track
];
vlc_meta_t
*
mtk
=
vlc_meta_New
();
p_sys
->
meta
->
track
=
(
vlc_meta_t
**
)
realloc
(
p_sys
->
meta
->
track
,
...
...
@@ -3002,7 +3091,7 @@ static void InformationCreate( demux_t *p_demux )
}
}
if
(
p_s
ys
->
i_tags_position
>=
0
)
if
(
p_s
egment
->
i_tags_position
>=
0
)
{
vlc_bool_t
b_seekable
;
...
...
@@ -3022,19 +3111,21 @@ static void InformationCreate( demux_t *p_demux )
static
void
IndexAppendCluster
(
demux_t
*
p_demux
,
KaxCluster
*
cluster
)
{
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_s
ys->index[p_sys
->i_index]
#define idx p_s
egment->index[p_segment
->i_index]
idx
.
i_track
=
-
1
;
idx
.
i_block_number
=
-
1
;
idx
.
i_position
=
cluster
->
GetElementPosition
();
idx
.
i_time
=
-
1
;
idx
.
b_key
=
VLC_TRUE
;
p_s
ys
->
i_index
++
;
if
(
p_s
ys
->
i_index
>=
p_sys
->
i_index_max
)
p_s
egment
->
i_index
++
;
if
(
p_s
egment
->
i_index
>=
p_segment
->
i_index_max
)
{
p_s
ys
->
i_index_max
+=
1024
;
p_s
ys
->
index
=
(
mkv_index_t
*
)
realloc
(
p_sys
->
index
,
sizeof
(
mkv_index_t
)
*
p_sys
->
i_index_max
);
p_s
egment
->
i_index_max
+=
1024
;
p_s
egment
->
index
=
(
mkv_index_t
*
)
realloc
(
p_segment
->
index
,
sizeof
(
mkv_index_t
)
*
p_segment
->
i_index_max
);
}
#undef idx
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment