Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
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