Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
1f8faf15
Commit
1f8faf15
authored
Sep 08, 2012
by
Denis Charmet
Committed by
Jean-Baptiste Kempf
Sep 08, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add MKV tag handling and use them to properly name editions
Signed-off-by:
Jean-Baptiste Kempf
<
jb@videolan.org
>
parent
b931c16e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
174 additions
and
26 deletions
+174
-26
modules/demux/mkv/demux.cpp
modules/demux/mkv/demux.cpp
+33
-5
modules/demux/mkv/matroska_segment.cpp
modules/demux/mkv/matroska_segment.cpp
+105
-20
modules/demux/mkv/matroska_segment.hpp
modules/demux/mkv/matroska_segment.hpp
+35
-1
modules/demux/mkv/mkv.cpp
modules/demux/mkv/mkv.cpp
+1
-0
No files found.
modules/demux/mkv/demux.cpp
View file @
1f8faf15
...
...
@@ -655,24 +655,52 @@ bool demux_sys_t::PreloadLinked()
{
for
(
j
=
0
;
j
<
p_seg
->
Editions
()
->
size
();
j
++
)
{
virtual_edition_c
*
p_ved
=
(
*
p_seg
->
Editions
())[
j
];
input_title_t
*
p_title
=
vlc_input_title_New
();
int
i_chapters
;
// TODO use a name for each edition, let the TITLE deal with a codec name
if
(
p_title
->
psz_name
==
NULL
)
{
const
char
*
psz_tmp
=
(
*
p_seg
->
Editions
())[
j
]
->
GetMainName
().
c_str
();
const
char
*
psz_tmp
=
p_ved
->
GetMainName
().
c_str
();
if
(
*
psz_tmp
!=
'\0'
)
p_title
->
psz_name
=
strdup
(
psz_tmp
);
else
if
(
asprintf
(
&
(
p_title
->
psz_name
),
"%s %d"
,
N_
(
"Segment"
),
(
int
)
i
)
==
-
1
)
p_title
->
psz_name
=
NULL
;
else
{
/* Check in tags if the edition has a name */
/* We use only the tags of the first segment as it contains the edition */
std
::
vector
<
Tag
*>
&
tags
=
opened_segments
[
0
]
->
tags
;
uint64_t
i_ed_uid
=
0
;
if
(
p_ved
->
p_edition
)
i_ed_uid
=
(
uint64_t
)
p_ved
->
p_edition
->
i_uid
;
for
(
size_t
k
=
0
;
k
<
tags
.
size
();
k
++
)
{
if
(
tags
[
k
]
->
i_tag_type
==
EDITION_UID
&&
tags
[
k
]
->
i_uid
==
i_ed_uid
)
for
(
size_t
l
=
0
;
l
<
tags
[
k
]
->
simple_tags
.
size
();
l
++
)
{
SimpleTag
*
p_st
=
tags
[
k
]
->
simple_tags
[
l
];
if
(
!
strcmp
(
p_st
->
psz_tag_name
,
"TITLE"
)
)
{
msg_Dbg
(
&
demuxer
,
"Using title
\"
%s
\"
from tag for edition %"
PRIu64
,
p_st
->
p_value
,
i_ed_uid
);
p_title
->
psz_name
=
strdup
(
p_st
->
p_value
);
break
;
}
}
}
if
(
!
p_title
->
psz_name
&&
asprintf
(
&
(
p_title
->
psz_name
),
"%s %d"
,
N_
(
"Segment"
),
(
int
)
i
)
==
-
1
)
p_title
->
psz_name
=
NULL
;
}
}
i_chapters
=
0
;
(
*
p_seg
->
Editions
()
)[
j
]
->
PublishChapters
(
*
p_title
,
i_chapters
,
0
);
p_ved
->
PublishChapters
(
*
p_title
,
i_chapters
,
0
);
// Input duration into i_length
p_title
->
i_length
=
(
*
p_seg
->
Editions
()
)[
j
]
->
i_duration
;
p_title
->
i_length
=
p_ved
->
i_duration
;
titles
.
push_back
(
p_title
);
}
...
...
modules/demux/mkv/matroska_segment.cpp
View file @
1f8faf15
...
...
@@ -242,11 +242,17 @@ static const struct {
{
vlc_meta_Title
,
NULL
,
0
},
};
void
matroska_segment_c
::
ParseSimpleTags
(
KaxTagSimple
*
tag
,
int
target_type
)
SimpleTag
*
matroska_segment_c
::
ParseSimpleTags
(
KaxTagSimple
*
tag
,
int
target_type
)
{
EbmlElement
*
el
;
EbmlParser
*
ep
=
new
EbmlParser
(
&
es
,
tag
,
&
sys
.
demuxer
);
char
*
k
=
NULL
,
*
v
=
NULL
;
SimpleTag
*
p_simple
=
new
SimpleTag
;
if
(
!
p_simple
)
{
msg_Err
(
&
sys
.
demuxer
,
"Couldn't allocate memory for Simple Tag... ignoring it"
);
return
NULL
;
}
if
(
!
sys
.
meta
)
sys
.
meta
=
vlc_meta_New
();
...
...
@@ -258,39 +264,58 @@ void matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag, int target_type )
{
KaxTagName
&
key
=
*
(
KaxTagName
*
)
el
;
key
.
ReadData
(
es
.
I_O
(),
SCOPE_ALL_DATA
);
k
=
strdup
(
UTFstring
(
key
).
GetUTF8
().
c_str
()
);
p_simple
->
psz_tag_name
=
strdup
(
UTFstring
(
key
).
GetUTF8
().
c_str
()
);
}
if
(
MKV_IS_ID
(
el
,
KaxTagString
)
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagString
)
)
{
KaxTagString
&
value
=
*
(
KaxTagString
*
)
el
;
value
.
ReadData
(
es
.
I_O
(),
SCOPE_ALL_DATA
);
v
=
strdup
(
UTFstring
(
value
).
GetUTF8
().
c_str
()
);
p_simple
->
p_value
=
strdup
(
UTFstring
(
value
).
GetUTF8
().
c_str
()
);
}
else
if
(
MKV_IS_ID
(
el
,
KaxTagLangue
)
)
{
KaxTagLangue
&
language
=
*
(
KaxTagLangue
*
)
el
;
language
.
ReadData
(
es
.
I_O
(),
SCOPE_ALL_DATA
);
p_simple
->
psz_lang
=
strdup
(
string
(
language
).
c_str
());
}
else
if
(
MKV_IS_ID
(
el
,
KaxTagDefault
)
)
{
KaxTagDefault
&
dft
=
*
(
KaxTagDefault
*
)
el
;
dft
.
ReadData
(
es
.
I_O
(),
SCOPE_ALL_DATA
);
p_simple
->
b_default
=
(
bool
)
uint8
(
dft
);
}
/*Tags can be nested*/
else
if
(
MKV_IS_ID
(
el
,
KaxTagSimple
)
)
{
SimpleTag
*
p_st
=
ParseSimpleTags
(
(
KaxTagSimple
*
)
el
,
target_type
);
if
(
p_st
)
p_simple
->
sub_tags
.
push_back
(
p_st
);
}
/*TODO Handle binary tags*/
}
delete
ep
;
if
(
!
k
||
!
v
)
if
(
!
p_simple
->
psz_tag_name
||
!
p_simple
->
p_value
)
{
msg_Warn
(
&
sys
.
demuxer
,
"Invalid MKV SimpleTag found."
);
return
;
delete
p_simple
;
return
NULL
;
}
for
(
int
i
=
0
;
metadata_map
[
i
].
key
;
i
++
)
{
if
(
!
strcmp
(
k
,
metadata_map
[
i
].
key
)
&&
if
(
!
strcmp
(
p_simple
->
psz_tag_name
,
metadata_map
[
i
].
key
)
&&
(
metadata_map
[
i
].
target_type
==
0
||
target_type
==
metadata_map
[
i
].
target_type
)
)
{
vlc_meta_Set
(
sys
.
meta
,
metadata_map
[
i
].
type
,
v
);
msg_Dbg
(
&
sys
.
demuxer
,
"| | + Meta %s: %s"
,
k
,
v
);
vlc_meta_Set
(
sys
.
meta
,
metadata_map
[
i
].
type
,
p_simple
->
p_value
);
msg_Dbg
(
&
sys
.
demuxer
,
"| | + Meta %s: %s"
,
p_simple
->
psz_tag_name
,
p_simple
->
p_value
);
goto
done
;
}
}
msg_Dbg
(
&
sys
.
demuxer
,
"| | + Meta %s: %s"
,
k
,
v
);
vlc_meta_AddExtra
(
sys
.
meta
,
k
,
v
);
msg_Dbg
(
&
sys
.
demuxer
,
"| | + Meta %s: %s"
,
p_simple
->
psz_tag_name
,
p_simple
->
p_value
);
vlc_meta_AddExtra
(
sys
.
meta
,
p_simple
->
psz_tag_name
,
p_simple
->
p_value
);
done:
free
(
k
);
free
(
v
);
return
;
return
p_simple
;
}
#define PARSE_TAG( type ) \
...
...
@@ -314,6 +339,12 @@ void matroska_segment_c::LoadTags( KaxTags *tags )
{
if
(
MKV_IS_ID
(
el
,
KaxTag
)
)
{
Tag
*
p_tag
=
new
Tag
;
if
(
!
p_tag
)
{
msg_Err
(
&
sys
.
demuxer
,
"Couldn't allocate memory for tag... ignoring it"
);
continue
;
}
msg_Dbg
(
&
sys
.
demuxer
,
"+ Tag"
);
ep
->
Down
();
int
target_type
=
50
;
...
...
@@ -333,11 +364,50 @@ void matroska_segment_c::LoadTags( KaxTags *tags )
msg_Dbg
(
&
sys
.
demuxer
,
"| | + TargetTypeValue: %u"
,
uint32
(
value
));
target_type
=
uint32
(
value
);
}
if
(
MKV_IS_ID
(
el
,
KaxTagTrackUID
)
)
{
p_tag
->
i_tag_type
=
TRACK_UID
;
KaxTagTrackUID
&
uid
=
*
(
KaxTagTrackUID
*
)
el
;
uid
.
ReadData
(
es
.
I_O
()
);
p_tag
->
i_uid
=
uint64
(
uid
);
msg_Dbg
(
&
sys
.
demuxer
,
"| | + TrackUID: %"
PRIu64
,
p_tag
->
i_uid
);
}
if
(
MKV_IS_ID
(
el
,
KaxTagEditionUID
)
)
{
p_tag
->
i_tag_type
=
EDITION_UID
;
KaxTagEditionUID
&
uid
=
*
(
KaxTagEditionUID
*
)
el
;
uid
.
ReadData
(
es
.
I_O
()
);
p_tag
->
i_uid
=
uint64
(
uid
);
msg_Dbg
(
&
sys
.
demuxer
,
"| | + EditionUID: %"
PRIu64
,
p_tag
->
i_uid
);
}
if
(
MKV_IS_ID
(
el
,
KaxTagChapterUID
)
)
{
p_tag
->
i_tag_type
=
CHAPTER_UID
;
KaxTagChapterUID
&
uid
=
*
(
KaxTagChapterUID
*
)
el
;
uid
.
ReadData
(
es
.
I_O
()
);
p_tag
->
i_uid
=
uint64
(
uid
);
msg_Dbg
(
&
sys
.
demuxer
,
"| | + ChapterUID: %"
PRIu64
,
p_tag
->
i_uid
);
}
if
(
MKV_IS_ID
(
el
,
KaxTagAttachmentUID
)
)
{
p_tag
->
i_tag_type
=
ATTACHMENT_UID
;
KaxTagAttachmentUID
&
uid
=
*
(
KaxTagAttachmentUID
*
)
el
;
uid
.
ReadData
(
es
.
I_O
()
);
p_tag
->
i_uid
=
uint64
(
uid
);
msg_Dbg
(
&
sys
.
demuxer
,
"| | + AttachmentUID: %"
PRIu64
,
p_tag
->
i_uid
);
}
}
ep
->
Up
();
}
else
if
(
MKV_IS_ID
(
el
,
KaxTagSimple
)
)
ParseSimpleTags
(
static_cast
<
KaxTagSimple
*>
(
el
),
target_type
);
{
SimpleTag
*
p_simple
=
ParseSimpleTags
(
static_cast
<
KaxTagSimple
*>
(
el
),
target_type
);
if
(
p_simple
)
p_tag
->
simple_tags
.
push_back
(
p_simple
);
}
#if 0 // not valid anymore
else if( MKV_IS_ID( el, KaxTagGeneral ) )
PARSE_TAG( "General" );
...
...
@@ -382,6 +452,7 @@ void matroska_segment_c::LoadTags( KaxTags *tags )
}
}
ep
->
Up
();
this
->
tags
.
push_back
(
p_tag
);
}
else
{
...
...
@@ -773,7 +844,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
sys
.
i_start_pts
=
0
;
sys
.
i_pts
=
0
;
sys
.
i_pcr
=
0
;
return
;
return
;
}
#endif
...
...
@@ -821,7 +892,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
{
spoint
*
tmp
=
sp
;
sp
=
sp
->
p_next
;
delete
tmp
;
delete
tmp
;
}
return
;
}
...
...
@@ -842,7 +913,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
}
/*Neither video nor audio track... no seek further*/
if
(
unlikely
(
!
p_first
)
)
return
;
return
;
for
(;;)
{
...
...
@@ -1611,7 +1682,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
ctc
.
ReadData
(
es
.
I_O
(),
SCOPE_ALL_DATA
);
cluster
->
InitTimecode
(
uint64
(
ctc
),
i_timescale
);
/* add it to the index */
if
(
i_index
==
0
||
(
i_index
>
0
&&
...
...
@@ -1685,3 +1756,17 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
}
}
SimpleTag
::~
SimpleTag
()
{
free
(
psz_tag_name
);
free
(
psz_lang
);
free
(
p_value
);
for
(
size_t
i
=
0
;
i
<
sub_tags
.
size
();
i
++
)
delete
sub_tags
[
i
];
}
Tag
::~
Tag
()
{
for
(
size_t
i
=
0
;
i
<
simple_tags
.
size
();
i
++
)
delete
simple_tags
[
i
];
}
modules/demux/mkv/matroska_segment.hpp
View file @
1f8faf15
...
...
@@ -36,6 +36,39 @@ class chapter_item_c;
struct
mkv_track_t
;
struct
mkv_index_t
;
typedef
enum
{
WHOLE_SEGMENT
,
TRACK_UID
,
EDITION_UID
,
CHAPTER_UID
,
ATTACHMENT_UID
}
tag_target_type
;
class
SimpleTag
{
public:
SimpleTag
()
:
psz_tag_name
(
NULL
),
psz_lang
(
NULL
),
b_default
(
true
),
p_value
(
NULL
){}
~
SimpleTag
();
char
*
psz_tag_name
;
char
*
psz_lang
;
/* NULL value means "undf" */
bool
b_default
;
char
*
p_value
;
std
::
vector
<
SimpleTag
*>
sub_tags
;
};
class
Tag
{
public:
Tag
()
:
i_tag_type
(
WHOLE_SEGMENT
),
i_target_type
(
50
),
i_uid
(
0
){}
~
Tag
();
tag_target_type
i_tag_type
;
uint64_t
i_target_type
;
uint64_t
i_uid
;
std
::
vector
<
SimpleTag
*>
simple_tags
;
};
class
matroska_segment_c
{
public:
...
...
@@ -93,6 +126,7 @@ public:
std
::
vector
<
chapter_translation_c
*>
translations
;
std
::
vector
<
KaxSegmentFamily
*>
families
;
std
::
vector
<
Tag
*>
tags
;
demux_sys_t
&
sys
;
EbmlParser
*
ep
;
...
...
@@ -125,7 +159,7 @@ private:
void
ParseChapterAtom
(
int
i_level
,
KaxChapterAtom
*
ca
,
chapter_item_c
&
chapters
);
void
ParseTrackEntry
(
KaxTrackEntry
*
m
);
void
ParseCluster
(
bool
b_update_start_time
=
true
);
void
ParseSimpleTags
(
KaxTagSimple
*
tag
,
int
level
=
50
);
SimpleTag
*
ParseSimpleTags
(
KaxTagSimple
*
tag
,
int
level
=
50
);
void
IndexAppendCluster
(
KaxCluster
*
cluster
);
};
...
...
modules/demux/mkv/mkv.cpp
View file @
1f8faf15
...
...
@@ -372,6 +372,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
Seek
(
p_demux
,
(
int64_t
)
p_sys
->
titles
[
i_idx
]
->
seekpoint
[
0
]
->
i_time_offset
,
-
1
,
NULL
);
p_demux
->
info
.
i_seekpoint
|=
INPUT_UPDATE_SEEKPOINT
;
p_demux
->
info
.
i_seekpoint
=
0
;
p_sys
->
f_duration
=
(
float
)
p_sys
->
titles
[
i_idx
]
->
i_length
/
1000.
f
;
return
VLC_SUCCESS
;
}
return
VLC_EGENERIC
;
...
...
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