Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
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-gpu
Commits
62ec0de3
Commit
62ec0de3
authored
Mar 28, 2005
by
Steve Lhomme
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mkv.cpp: seeking in linked files now works
parent
fa2eb0b5
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
149 additions
and
117 deletions
+149
-117
modules/demux/mkv.cpp
modules/demux/mkv.cpp
+149
-117
No files found.
modules/demux/mkv.cpp
View file @
62ec0de3
...
@@ -385,7 +385,7 @@ public:
...
@@ -385,7 +385,7 @@ public:
,
es
(
estream
)
,
es
(
estream
)
,
i_timescale
(
MKVD_TIMECODESCALE
)
,
i_timescale
(
MKVD_TIMECODESCALE
)
,
f_duration
(
-
1.0
)
,
f_duration
(
-
1.0
)
,
f_start_time
(
0.0
)
,
f_start_time
(
0.0
)
,
i_cues_position
(
-
1
)
,
i_cues_position
(
-
1
)
,
i_chapters_position
(
-
1
)
,
i_chapters_position
(
-
1
)
,
i_tags_position
(
-
1
)
,
i_tags_position
(
-
1
)
...
@@ -463,7 +463,7 @@ public:
...
@@ -463,7 +463,7 @@ public:
/* duration of the segment */
/* duration of the segment */
float
f_duration
;
float
f_duration
;
float
f_start_time
;
float
f_start_time
;
/* all tracks */
/* all tracks */
std
::
vector
<
mkv_track_t
*>
tracks
;
std
::
vector
<
mkv_track_t
*>
tracks
;
...
@@ -521,6 +521,7 @@ public:
...
@@ -521,6 +521,7 @@ public:
void
LoadCues
(
);
void
LoadCues
(
);
void
LoadTags
(
);
void
LoadTags
(
);
void
InformationCreate
(
);
void
InformationCreate
(
);
void
Seek
(
mtime_t
i_date
,
mtime_t
i_time_offset
);
int
BlockGet
(
KaxBlock
**
pp_block
,
int64_t
*
pi_ref1
,
int64_t
*
pi_ref2
,
int64_t
*
pi_duration
);
int
BlockGet
(
KaxBlock
**
pp_block
,
int64_t
*
pi_ref1
,
int64_t
*
pi_ref2
,
int64_t
*
pi_duration
);
bool
Select
(
mtime_t
i_start_time
);
bool
Select
(
mtime_t
i_start_time
);
void
UnSelect
(
);
void
UnSelect
(
);
...
@@ -546,6 +547,7 @@ public:
...
@@ -546,6 +547,7 @@ public:
void
PreloadLinked
(
);
void
PreloadLinked
(
);
float
Duration
(
)
const
;
float
Duration
(
)
const
;
void
LoadCues
(
);
void
LoadCues
(
);
void
Seek
(
mtime_t
i_date
,
mtime_t
i_time_offset
);
matroska_segment_t
*
Segment
()
const
matroska_segment_t
*
Segment
()
const
{
{
...
@@ -564,6 +566,8 @@ public:
...
@@ -564,6 +566,8 @@ public:
return
false
;
return
false
;
}
}
/* TODO handle/merge chapters here */
protected:
protected:
std
::
vector
<
matroska_segment_t
*>
linked_segments
;
std
::
vector
<
matroska_segment_t
*>
linked_segments
;
std
::
vector
<
const
KaxSegmentUID
>
linked_uids
;
std
::
vector
<
const
KaxSegmentUID
>
linked_uids
;
...
@@ -783,15 +787,6 @@ static int Open( vlc_object_t * p_this )
...
@@ -783,15 +787,6 @@ static int Open( vlc_object_t * p_this )
p_sys
->
PreloadLinked
(
p_segment
);
p_sys
->
PreloadLinked
(
p_segment
);
p_sys
->
PreparePlayback
(
);
p_sys
->
PreparePlayback
(
);
if
(
!
p_segment
->
b_cues
||
p_segment
->
i_index
<=
0
)
{
msg_Warn
(
p_demux
,
"no cues/empty cues found->seek won't be precise"
);
p_segment
->
IndexAppendCluster
(
p_segment
->
cluster
);
p_segment
->
b_cues
=
VLC_FALSE
;
}
/* add information */
/* add information */
p_segment
->
InformationCreate
(
);
p_segment
->
InformationCreate
(
);
...
@@ -1618,17 +1613,11 @@ static void UpdateCurrentToChapter( demux_t & demux )
...
@@ -1618,17 +1613,11 @@ static void UpdateCurrentToChapter( demux_t & demux )
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_segment_t
*
p_segment
=
p_sys
->
p_current_segment
->
Segment
();
virtual_segment_t
*
p_vsegment
=
p_sys
->
p_current_segment
;
matroska_segment_t
*
p_segment
=
p_vsegment
->
Segment
();
mtime_t
i_time_offset
=
0
;
mtime_t
i_time_offset
=
0
;
KaxBlock
*
block
;
int
i_index
;
int64_t
i_block_duration
;
int64_t
i_block_ref1
;
int64_t
i_block_ref2
;
int
i_index
=
0
;
int
i_track_skipping
;
size_t
i_track
;
msg_Dbg
(
p_demux
,
"seek request to "
I64Fd
" (%f%%)"
,
i_date
,
f_percent
);
msg_Dbg
(
p_demux
,
"seek request to "
I64Fd
" (%f%%)"
,
i_date
,
f_percent
);
if
(
i_date
<
0
&&
f_percent
<
0
)
if
(
i_date
<
0
&&
f_percent
<
0
)
...
@@ -1642,10 +1631,6 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
...
@@ -1642,10 +1631,6 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
return
;
return
;
}
}
delete
p_segment
->
ep
;
p_segment
->
ep
=
new
EbmlParser
(
&
p_segment
->
es
,
p_segment
->
segment
);
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_segment
->
b_cues
||
i_date
<
0
))
if
(
f_percent
>=
0
&&
(
config_GetInt
(
p_demux
,
"mkv-seek-percent"
)
||
!
p_segment
->
b_cues
||
i_date
<
0
))
{
{
...
@@ -1720,88 +1705,11 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
...
@@ -1720,88 +1705,11 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, const chap
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_segment
->
i_index
;
i_index
++
)
// p_sys->i_start_pts = i_date;
{
if
(
p_segment
->
index
[
i_index
].
i_time
+
i_time_offset
>
i_date
)
{
break
;
}
}
if
(
i_index
>
0
)
{
i_index
--
;
}
msg_Dbg
(
p_demux
,
"seek got "
I64Fd
" (%d%%)"
,
p_segment
->
index
[
i_index
].
i_time
,
(
int
)(
100
*
p_segment
->
index
[
i_index
].
i_position
/
stream_Size
(
p_demux
->
s
)
)
);
p_segment
->
es
.
I_O
().
setFilePointer
(
p_segment
->
index
[
i_index
].
i_position
,
seek_beginning
);
p_sys
->
i_start_pts
=
i_date
;
es_out_Control
(
p_demux
->
out
,
ES_OUT_RESET_PCR
);
/* now parse until key frame */
#define tk p_segment->tracks[i_track]
i_track_skipping
=
0
;
for
(
i_track
=
0
;
i_track
<
p_segment
->
tracks
.
size
();
i_track
++
)
{
if
(
tk
->
fmt
.
i_cat
==
VIDEO_ES
)
{
tk
->
b_search_keyframe
=
VLC_TRUE
;
i_track_skipping
++
;
}
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_NEXT_DISPLAY_TIME
,
tk
->
p_es
,
i_date
);
}
while
(
i_track_skipping
>
0
)
{
if
(
p_segment
->
BlockGet
(
&
block
,
&
i_block_ref1
,
&
i_block_ref2
,
&
i_block_duration
)
)
{
msg_Warn
(
p_demux
,
"cannot get block EOF?"
);
return
;
}
for
(
i_track
=
0
;
i_track
<
p_segment
->
tracks
.
size
();
i_track
++
)
{
if
(
tk
->
i_number
==
block
->
TrackNum
()
)
{
break
;
}
}
p_sys
->
i_pts
=
p_sys
->
i_chapter_time
+
block
->
GlobalTimecode
()
/
(
mtime_t
)
1000
;
// es_out_Control( p_demux->out, ES_OUT_RESET_PCR )
;
if
(
i_track
<
p_segment
->
tracks
.
size
()
)
p_vsegment
->
Seek
(
i_date
,
i_time_offset
);
{
if
(
p_sys
->
i_pts
>=
p_sys
->
i_start_pts
)
{
BlockDecode
(
p_demux
,
block
,
p_sys
->
i_pts
,
0
);
i_track_skipping
=
0
;
}
else
if
(
tk
->
fmt
.
i_cat
==
VIDEO_ES
)
{
if
(
i_block_ref1
==
-
1
&&
tk
->
b_search_keyframe
)
{
tk
->
b_search_keyframe
=
VLC_FALSE
;
i_track_skipping
--
;
}
if
(
!
tk
->
b_search_keyframe
)
{
BlockDecode
(
p_demux
,
block
,
p_sys
->
i_pts
,
0
);
}
}
}
delete
block
;
}
#undef tk
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -2110,7 +2018,11 @@ void matroska_segment_t::LoadCues( )
...
@@ -2110,7 +2018,11 @@ void matroska_segment_t::LoadCues( )
/* *** Load the cue if found *** */
/* *** Load the cue if found *** */
if
(
i_cues_position
<
0
)
if
(
i_cues_position
<
0
)
return
;
{
msg_Warn
(
&
sys
.
demuxer
,
"no cues/empty cues found->seek won't be precise"
);
// IndexAppendCluster( cluster );
}
vlc_bool_t
b_seekable
;
vlc_bool_t
b_seekable
;
...
@@ -3155,7 +3067,7 @@ void matroska_segment_t::ParseChapters( EbmlElement *chapters )
...
@@ -3155,7 +3067,7 @@ void matroska_segment_t::ParseChapters( EbmlElement *chapters )
void
matroska_segment_t
::
ParseCluster
(
)
void
matroska_segment_t
::
ParseCluster
(
)
{
{
EbmlElement
*
el
;
EbmlElement
*
el
;
EbmlMaster
*
m
;
EbmlMaster
*
m
;
unsigned
int
i
;
unsigned
int
i
;
int
i_upper_level
=
0
;
int
i_upper_level
=
0
;
...
@@ -3173,11 +3085,11 @@ void matroska_segment_t::ParseCluster( )
...
@@ -3173,11 +3085,11 @@ void matroska_segment_t::ParseCluster( )
KaxClusterTimecode
&
ctc
=
*
(
KaxClusterTimecode
*
)
l
;
KaxClusterTimecode
&
ctc
=
*
(
KaxClusterTimecode
*
)
l
;
cluster
->
InitTimecode
(
uint64
(
ctc
),
i_timescale
);
cluster
->
InitTimecode
(
uint64
(
ctc
),
i_timescale
);
break
;
break
;
}
}
}
}
f_start_time
=
cluster
->
GlobalTimecode
()
/
1000000.0
;
f_start_time
=
cluster
->
GlobalTimecode
()
/
1000000.0
;
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -3481,8 +3393,8 @@ void demux_sys_t::PreloadLinked( matroska_segment_t *p_segment )
...
@@ -3481,8 +3393,8 @@ void demux_sys_t::PreloadLinked( matroska_segment_t *p_segment )
void
demux_sys_t
::
PreparePlayback
(
)
void
demux_sys_t
::
PreparePlayback
(
)
{
{
f_duration
=
p_current_segment
->
Duration
();
p_current_segment
->
LoadCues
();
p_current_segment
->
LoadCues
();
f_duration
=
p_current_segment
->
Duration
();
}
}
bool
matroska_segment_t
::
CompareSegmentUIDs
(
const
matroska_segment_t
*
p_item_a
,
const
matroska_segment_t
*
p_item_b
)
bool
matroska_segment_t
::
CompareSegmentUIDs
(
const
matroska_segment_t
*
p_item_a
,
const
matroska_segment_t
*
p_item_b
)
...
@@ -3535,6 +3447,7 @@ bool matroska_segment_t::Preload( )
...
@@ -3535,6 +3447,7 @@ bool matroska_segment_t::Preload( )
cluster
=
(
KaxCluster
*
)
el
;
cluster
=
(
KaxCluster
*
)
el
;
i_start_pos
=
cluster
->
GetElementPosition
();
i_start_pos
=
cluster
->
GetElementPosition
();
ParseCluster
(
);
ep
->
Down
();
ep
->
Down
();
/* stop parsing the stream */
/* stop parsing the stream */
...
@@ -3625,14 +3538,14 @@ void virtual_segment_t::PreloadLinked( )
...
@@ -3625,14 +3538,14 @@ void virtual_segment_t::PreloadLinked( )
float
virtual_segment_t
::
Duration
()
const
float
virtual_segment_t
::
Duration
()
const
{
{
float
f_duration
;
float
f_duration
;
if
(
linked_segments
.
size
()
==
0
)
if
(
linked_segments
.
size
()
==
0
)
f_duration
=
0.0
;
f_duration
=
0.0
;
else
{
else
{
matroska_segment_t
*
p_last_segment
=
linked_segments
[
linked_segments
.
size
()
-
1
];
matroska_segment_t
*
p_last_segment
=
linked_segments
[
linked_segments
.
size
()
-
1
];
p_last_segment
->
ParseCluster
(
);
//
p_last_segment->ParseCluster( );
f_duration
=
p_last_segment
->
f_start_time
+
p_last_segment
->
f_duration
;
f_duration
=
p_last_segment
->
f_start_time
+
p_last_segment
->
f_duration
;
}
}
return
f_duration
;
return
f_duration
;
}
}
...
@@ -3656,3 +3569,122 @@ void virtual_segment_t::AppendUID( const EbmlBinary & UID )
...
@@ -3656,3 +3569,122 @@ void virtual_segment_t::AppendUID( const EbmlBinary & UID )
}
}
linked_uids
.
push_back
(
*
(
KaxSegmentUID
*
)(
&
UID
)
);
linked_uids
.
push_back
(
*
(
KaxSegmentUID
*
)(
&
UID
)
);
}
}
void
matroska_segment_t
::
Seek
(
mtime_t
i_date
,
mtime_t
i_time_offset
)
{
KaxBlock
*
block
;
int
i_track_skipping
;
int64_t
i_block_duration
;
int64_t
i_block_ref1
;
int64_t
i_block_ref2
;
size_t
i_track
;
int
i_idx
=
0
;
for
(
;
i_idx
<
i_index
;
i_idx
++
)
{
if
(
index
[
i_idx
].
i_time
+
i_time_offset
>
i_date
)
{
break
;
}
}
if
(
i_idx
>
0
)
{
i_idx
--
;
}
msg_Dbg
(
&
sys
.
demuxer
,
"seek got "
I64Fd
" (%d%%)"
,
index
[
i_idx
].
i_time
,
(
int
)(
100
*
index
[
i_idx
].
i_position
/
stream_Size
(
sys
.
demuxer
.
s
)
)
);
delete
ep
;
ep
=
new
EbmlParser
(
&
es
,
segment
);
cluster
=
NULL
;
es
.
I_O
().
setFilePointer
(
index
[
i_idx
].
i_position
,
seek_beginning
);
sys
.
i_start_pts
=
i_date
;
es_out_Control
(
sys
.
demuxer
.
out
,
ES_OUT_RESET_PCR
);
/* now parse until key frame */
#define tk tracks[i_track]
i_track_skipping
=
0
;
for
(
i_track
=
0
;
i_track
<
tracks
.
size
();
i_track
++
)
{
if
(
tk
->
fmt
.
i_cat
==
VIDEO_ES
)
{
tk
->
b_search_keyframe
=
VLC_TRUE
;
i_track_skipping
++
;
}
es_out_Control
(
sys
.
demuxer
.
out
,
ES_OUT_SET_NEXT_DISPLAY_TIME
,
tk
->
p_es
,
i_date
);
}
while
(
i_track_skipping
>
0
)
{
if
(
BlockGet
(
&
block
,
&
i_block_ref1
,
&
i_block_ref2
,
&
i_block_duration
)
)
{
msg_Warn
(
&
sys
.
demuxer
,
"cannot get block EOF?"
);
return
;
}
for
(
i_track
=
0
;
i_track
<
tracks
.
size
();
i_track
++
)
{
if
(
tk
->
i_number
==
block
->
TrackNum
()
)
{
break
;
}
}
sys
.
i_pts
=
sys
.
i_chapter_time
+
block
->
GlobalTimecode
()
/
(
mtime_t
)
1000
;
if
(
i_track
<
tracks
.
size
()
)
{
if
(
sys
.
i_pts
>=
sys
.
i_start_pts
)
{
BlockDecode
(
&
sys
.
demuxer
,
block
,
sys
.
i_pts
,
0
);
i_track_skipping
=
0
;
}
else
if
(
tk
->
fmt
.
i_cat
==
VIDEO_ES
)
{
if
(
i_block_ref1
==
-
1
&&
tk
->
b_search_keyframe
)
{
tk
->
b_search_keyframe
=
VLC_FALSE
;
i_track_skipping
--
;
}
if
(
!
tk
->
b_search_keyframe
)
{
BlockDecode
(
&
sys
.
demuxer
,
block
,
sys
.
i_pts
,
0
);
}
}
}
delete
block
;
}
#undef tk
}
void
virtual_segment_t
::
Seek
(
mtime_t
i_date
,
mtime_t
i_time_offset
)
{
// find the best matching segment
for
(
size_t
i
=
0
;
i
<
linked_segments
.
size
();
i
++
)
{
if
(
i_date
<
linked_segments
[
i
]
->
f_start_time
*
1000.0
)
break
;
}
if
(
i
>
0
)
i
--
;
if
(
i_current_segment
!=
i
)
{
linked_segments
[
i_current_segment
]
->
UnSelect
();
linked_segments
[
i
]
->
Select
(
i_date
);
i_current_segment
=
i
;
}
linked_segments
[
i
]
->
Seek
(
i_date
,
i_time_offset
);
}
\ No newline at end of file
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