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
5743d45f
Commit
5743d45f
authored
Apr 20, 2005
by
Steve Lhomme
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mkv.cpp: finding the segment matching the Title for JumpTT works
parent
4d1b2d7f
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
12 deletions
+124
-12
modules/demux/mkv.cpp
modules/demux/mkv.cpp
+124
-12
No files found.
modules/demux/mkv.cpp
View file @
5743d45f
...
@@ -330,9 +330,15 @@ typedef struct
...
@@ -330,9 +330,15 @@ typedef struct
vlc_bool_t
b_key
;
vlc_bool_t
b_key
;
}
mkv_index_t
;
}
mkv_index_t
;
class
demux_sys_t
;
class
chapter_codec_cmds_c
class
chapter_codec_cmds_c
{
{
public:
public:
chapter_codec_cmds_c
(
int
codec_id
=
-
1
)
:
i_codec_id
(
codec_id
)
{}
virtual
~
chapter_codec_cmds_c
()
{}
virtual
~
chapter_codec_cmds_c
()
{}
void
SetPrivate
(
const
KaxChapterProcessPrivate
&
private_data
)
void
SetPrivate
(
const
KaxChapterProcessPrivate
&
private_data
)
...
@@ -345,18 +351,21 @@ public:
...
@@ -345,18 +351,21 @@ public:
virtual
bool
Enter
()
{
return
true
;
}
virtual
bool
Enter
()
{
return
true
;
}
virtual
bool
Leave
()
{
return
true
;
}
virtual
bool
Leave
()
{
return
true
;
}
protected:
KaxChapterProcessPrivate
m_private_data
;
KaxChapterProcessPrivate
m_private_data
;
protected:
std
::
vector
<
KaxChapterProcessData
>
enter_cmds
;
std
::
vector
<
KaxChapterProcessData
>
enter_cmds
;
std
::
vector
<
KaxChapterProcessData
>
during_cmds
;
std
::
vector
<
KaxChapterProcessData
>
during_cmds
;
std
::
vector
<
KaxChapterProcessData
>
leave_cmds
;
std
::
vector
<
KaxChapterProcessData
>
leave_cmds
;
int
i_codec_id
;
};
};
class
dvd_command_interpretor_c
class
dvd_command_interpretor_c
{
{
public:
public:
dvd_command_interpretor_c
()
dvd_command_interpretor_c
(
demux_sys_t
&
demuxer
)
:
sys
(
demuxer
)
{
{
memset
(
p_GPRM
,
0
,
sizeof
(
p_GPRM
)
);
memset
(
p_GPRM
,
0
,
sizeof
(
p_GPRM
)
);
memset
(
p_SPRM
,
0
,
sizeof
(
p_SPRM
)
);
memset
(
p_SPRM
,
0
,
sizeof
(
p_SPRM
)
);
...
@@ -410,13 +419,23 @@ protected:
...
@@ -410,13 +419,23 @@ protected:
uint16
p_GPRM
[
16
];
uint16
p_GPRM
[
16
];
uint16
p_SPRM
[
24
];
uint16
p_SPRM
[
24
];
demux_sys_t
&
sys
;
// DVD command IDs
static
const
uint16
CMD_JUMP_TT
=
0x3002
;
static
const
uint16
CMD_JUMP_TT
=
0x3002
;
// callbacks when browsing inside CodecPrivate
static
bool
MatchTitleNumber
(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
);
};
};
class
dvd_chapter_codec_c
:
public
chapter_codec_cmds_c
class
dvd_chapter_codec_c
:
public
chapter_codec_cmds_c
{
{
public:
public:
dvd_chapter_codec_c
(
demux_sys_t
&
sys
)
:
chapter_codec_cmds_c
(
1
)
,
interpretor
(
sys
)
{}
bool
Enter
();
bool
Enter
();
bool
Leave
();
bool
Leave
();
...
@@ -470,6 +489,10 @@ public:
...
@@ -470,6 +489,10 @@ public:
chapter_item_c
*
FindTimecode
(
mtime_t
i_timecode
);
chapter_item_c
*
FindTimecode
(
mtime_t
i_timecode
);
void
Append
(
const
chapter_item_c
&
edition
);
void
Append
(
const
chapter_item_c
&
edition
);
chapter_item_c
*
FindChapter
(
const
chapter_item_c
&
chapter
);
chapter_item_c
*
FindChapter
(
const
chapter_item_c
&
chapter
);
chapter_item_c
*
BrowseCodecPrivate
(
unsigned
int
codec_id
,
bool
(
*
match
)(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
),
const
void
*
p_cookie
,
size_t
i_cookie_size
);
int64_t
i_start_time
,
i_end_time
;
int64_t
i_start_time
,
i_end_time
;
int64_t
i_user_start_time
,
i_user_end_time
;
/* the time in the stream when an edition is ordered */
int64_t
i_user_start_time
,
i_user_end_time
;
/* the time in the stream when an edition is ordered */
...
@@ -505,8 +528,6 @@ public:
...
@@ -505,8 +528,6 @@ public:
bool
b_ordered
;
bool
b_ordered
;
};
};
class
demux_sys_t
;
class
matroska_segment_c
class
matroska_segment_c
{
{
public:
public:
...
@@ -654,6 +675,11 @@ public:
...
@@ -654,6 +675,11 @@ public:
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
(
);
chapter_item_c
*
BrowseCodecPrivate
(
unsigned
int
codec_id
,
bool
(
*
match
)(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
),
const
void
*
p_cookie
,
size_t
i_cookie_size
);
static
bool
CompareSegmentUIDs
(
const
matroska_segment_c
*
item_a
,
const
matroska_segment_c
*
item_b
);
static
bool
CompareSegmentUIDs
(
const
matroska_segment_c
*
item_a
,
const
matroska_segment_c
*
item_b
);
};
};
...
@@ -714,7 +740,6 @@ public:
...
@@ -714,7 +740,6 @@ public:
return
false
;
return
false
;
}
}
/* TODO handle/merge chapters here */
void
UpdateCurrentToChapter
(
demux_t
&
demux
);
void
UpdateCurrentToChapter
(
demux_t
&
demux
);
bool
Select
(
input_title_t
&
title
);
bool
Select
(
input_title_t
&
title
);
...
@@ -794,6 +819,12 @@ public:
...
@@ -794,6 +819,12 @@ public:
float
f_duration
;
float
f_duration
;
matroska_segment_c
*
FindSegment
(
const
EbmlBinary
&
uid
)
const
;
matroska_segment_c
*
FindSegment
(
const
EbmlBinary
&
uid
)
const
;
chapter_item_c
*
BrowseCodecPrivate
(
unsigned
int
codec_id
,
bool
(
*
match
)(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
),
const
void
*
p_cookie
,
size_t
i_cookie_size
,
matroska_segment_c
*
&
p_segment_found
);
void
PreloadFamily
(
const
matroska_segment_c
&
of_segment
);
void
PreloadFamily
(
const
matroska_segment_c
&
of_segment
);
void
PreloadLinked
(
matroska_segment_c
*
p_segment
);
void
PreloadLinked
(
matroska_segment_c
*
p_segment
);
bool
PreparePlayback
(
);
bool
PreparePlayback
(
);
...
@@ -1028,7 +1059,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
...
@@ -1028,7 +1059,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
case
DEMUX_SET_SEEKPOINT
:
case
DEMUX_SET_SEEKPOINT
:
/* FIXME do a better implementation */
i_skp
=
(
int
)
va_arg
(
args
,
int
);
i_skp
=
(
int
)
va_arg
(
args
,
int
);
if
(
p_sys
->
title
&&
i_skp
<
p_sys
->
title
->
i_seekpoint
)
if
(
p_sys
->
title
&&
i_skp
<
p_sys
->
title
->
i_seekpoint
)
...
@@ -1821,6 +1851,50 @@ void virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
...
@@ -1821,6 +1851,50 @@ void virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
}
}
}
}
chapter_item_c
*
matroska_segment_c
::
BrowseCodecPrivate
(
unsigned
int
codec_id
,
bool
(
*
match
)(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
),
const
void
*
p_cookie
,
size_t
i_cookie_size
)
{
// FIXME don't assume it is the first edition
std
::
vector
<
chapter_edition_c
*>::
iterator
index
=
stored_editions
.
begin
();
if
(
index
!=
stored_editions
.
end
()
)
{
chapter_item_c
*
p_result
=
(
*
index
)
->
BrowseCodecPrivate
(
codec_id
,
match
,
p_cookie
,
i_cookie_size
);
if
(
p_result
!=
NULL
)
return
p_result
;
}
return
NULL
;
}
chapter_item_c
*
chapter_item_c
::
BrowseCodecPrivate
(
unsigned
int
codec_id
,
bool
(
*
match
)(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
),
const
void
*
p_cookie
,
size_t
i_cookie_size
)
{
// this chapter
std
::
vector
<
chapter_codec_cmds_c
*>::
const_iterator
index
=
codecs
.
begin
();
while
(
index
!=
codecs
.
end
()
)
{
if
(
match
(
**
index
,
p_cookie
,
i_cookie_size
)
)
return
this
;
index
++
;
}
// sub-chapters
chapter_item_c
*
p_result
=
NULL
;
std
::
vector
<
chapter_item_c
*>::
const_iterator
index2
=
sub_chapters
.
begin
();
while
(
index2
!=
sub_chapters
.
end
()
)
{
p_result
=
(
*
index2
)
->
BrowseCodecPrivate
(
codec_id
,
match
,
p_cookie
,
i_cookie_size
);
if
(
p_result
!=
NULL
)
return
p_result
;
index2
++
;
}
return
p_result
;
}
void
chapter_item_c
::
Append
(
const
chapter_item_c
&
chapter
)
void
chapter_item_c
::
Append
(
const
chapter_item_c
&
chapter
)
{
{
// we are appending content for the same chapter UID
// we are appending content for the same chapter UID
...
@@ -3254,7 +3328,7 @@ void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chap
...
@@ -3254,7 +3328,7 @@ void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chap
if
(
uint32
(
*
p_codec_id
)
==
0
)
if
(
uint32
(
*
p_codec_id
)
==
0
)
p_ccodec
=
new
matroska_script_codec_c
();
p_ccodec
=
new
matroska_script_codec_c
();
else
if
(
uint32
(
*
p_codec_id
)
==
1
)
else
if
(
uint32
(
*
p_codec_id
)
==
1
)
p_ccodec
=
new
dvd_chapter_codec_c
();
p_ccodec
=
new
dvd_chapter_codec_c
(
sys
);
break
;
break
;
}
}
}
}
...
@@ -3719,7 +3793,7 @@ bool matroska_segment_c::Preload( )
...
@@ -3719,7 +3793,7 @@ bool matroska_segment_c::Preload( )
}
}
else
if
(
MKV_IS_ID
(
el
,
KaxAttachments
)
)
else
if
(
MKV_IS_ID
(
el
,
KaxAttachments
)
)
{
{
msg_Dbg
(
&
sys
.
demuxer
,
"| + Attachments FIXME
TODO
(but probably never supported)"
);
msg_Dbg
(
&
sys
.
demuxer
,
"| + Attachments FIXME (but probably never supported)"
);
}
}
else
if
(
MKV_IS_ID
(
el
,
KaxChapters
)
)
else
if
(
MKV_IS_ID
(
el
,
KaxChapters
)
)
{
{
...
@@ -3751,6 +3825,25 @@ matroska_segment_c *demux_sys_t::FindSegment( const EbmlBinary & uid ) const
...
@@ -3751,6 +3825,25 @@ matroska_segment_c *demux_sys_t::FindSegment( const EbmlBinary & uid ) const
return
NULL
;
return
NULL
;
}
}
chapter_item_c
*
demux_sys_t
::
BrowseCodecPrivate
(
unsigned
int
codec_id
,
bool
(
*
match
)(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
),
const
void
*
p_cookie
,
size_t
i_cookie_size
,
matroska_segment_c
*
&
p_segment_found
)
{
chapter_item_c
*
p_result
=
NULL
;
for
(
size_t
i
=
0
;
i
<
opened_segments
.
size
();
i
++
)
{
p_result
=
opened_segments
[
i
]
->
BrowseCodecPrivate
(
codec_id
,
match
,
p_cookie
,
i_cookie_size
);
if
(
p_result
!=
NULL
)
{
p_segment_found
=
opened_segments
[
i
];
break
;
}
}
return
p_result
;
}
void
virtual_segment_c
::
Sort
()
void
virtual_segment_c
::
Sort
()
{
{
// keep the current segment index
// keep the current segment index
...
@@ -4099,10 +4192,29 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si
...
@@ -4099,10 +4192,29 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si
case
CMD_JUMP_TT
:
case
CMD_JUMP_TT
:
{
{
uint8
i_title
=
p_command
[
5
];
uint8
i_title
=
p_command
[
5
];
// TODO find in the ChapProcessPrivate matching this Title level
// find in the ChapProcessPrivate matching this Title level
matroska_segment_c
*
p_segment
;
chapter_item_c
*
p_chapter
;
p_chapter
=
sys
.
BrowseCodecPrivate
(
1
,
MatchTitleNumber
,
&
i_title
,
sizeof
(
i_title
),
p_segment
);
// TODO if the segment is not part of the current segment, select the new one
// TODO jump to the location in the found segment
break
;
break
;
}
}
}
}
return
true
;
return
true
;
}
}
bool
dvd_command_interpretor_c
::
MatchTitleNumber
(
const
chapter_codec_cmds_c
&
data
,
const
void
*
p_cookie
,
size_t
i_cookie_size
)
{
if
(
i_cookie_size
!=
1
||
data
.
m_private_data
.
GetSize
()
<
4
)
return
false
;
if
(
data
.
m_private_data
.
GetBuffer
()[
0
]
!=
0x28
)
return
false
;
uint16
i_gtitle
=
(
data
.
m_private_data
.
GetBuffer
()[
1
]
<<
8
)
+
data
.
m_private_data
.
GetBuffer
()[
2
];
uint8
i_title
=
*
(
uint8
*
)
p_cookie
;
return
(
i_gtitle
==
i_title
);
}
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