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
d82e9eb7
Commit
d82e9eb7
authored
Jun 22, 2004
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* all: rework of the input.
parent
3d331406
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1196 additions
and
1072 deletions
+1196
-1072
modules/demux/dvdnav.c
modules/demux/dvdnav.c
+314
-238
modules/demux/livedotcom.cpp
modules/demux/livedotcom.cpp
+101
-237
modules/demux/mkv.cpp
modules/demux/mkv.cpp
+780
-592
modules/demux/util/id3.c
modules/demux/util/id3.c
+1
-5
No files found.
modules/demux/dvdnav.c
View file @
d82e9eb7
...
@@ -44,27 +44,17 @@
...
@@ -44,27 +44,17 @@
"Allows you to modify the default caching value for DVDnav streams. This "\
"Allows you to modify the default caching value for DVDnav streams. This "\
"value should be set in millisecond units." )
"value should be set in millisecond units." )
static
int
AccessOpen
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
AccessClose
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
int
DemuxOpen
(
vlc_object_t
*
);
static
void
DemuxClose
(
vlc_object_t
*
);
vlc_module_begin
();
vlc_module_begin
();
set_description
(
_
(
"DVDnav Input"
)
);
set_description
(
_
(
"DVDnav Input"
)
);
add_integer
(
"dvdnav-caching"
,
DEFAULT_PTS_DELAY
/
1000
,
NULL
,
add_integer
(
"dvdnav-caching"
,
DEFAULT_PTS_DELAY
/
1000
,
NULL
,
CACHING_TEXT
,
CACHING_LONGTEXT
,
VLC_TRUE
);
CACHING_TEXT
,
CACHING_LONGTEXT
,
VLC_TRUE
);
set_capability
(
"access"
,
0
);
set_capability
(
"access
_demux
"
,
0
);
add_shortcut
(
"dvdnav"
);
add_shortcut
(
"dvdnav"
);
add_shortcut
(
"dvdnavsimple"
);
add_shortcut
(
"dvdnavsimple"
);
set_callbacks
(
AccessOpen
,
AccessClose
);
set_callbacks
(
Open
,
Close
);
add_submodule
();
set_description
(
_
(
"DVDnav Input (demux)"
)
);
set_capability
(
"demux2"
,
0
);
add_shortcut
(
"dvdnav"
);
add_shortcut
(
"dvdnavsimple"
);
set_callbacks
(
DemuxOpen
,
DemuxClose
);
vlc_module_end
();
vlc_module_end
();
/* TODO
/* TODO
...
@@ -80,7 +70,6 @@ vlc_module_end();
...
@@ -80,7 +70,6 @@ vlc_module_end();
/*****************************************************************************
/*****************************************************************************
* Local prototypes
* Local prototypes
*****************************************************************************/
*****************************************************************************/
static
ssize_t
AccessRead
(
input_thread_t
*
,
byte_t
*
,
size_t
);
/* dummy */
static
char
*
ParseCL
(
vlc_object_t
*
,
char
*
,
vlc_bool_t
,
int
*
,
int
*
,
int
*
);
static
char
*
ParseCL
(
vlc_object_t
*
,
char
*
,
vlc_bool_t
,
int
*
,
int
*
,
int
*
);
typedef
struct
typedef
struct
...
@@ -124,10 +113,13 @@ struct demux_sys_t
...
@@ -124,10 +113,13 @@ struct demux_sys_t
/* */
/* */
vlc_bool_t
b_es_out_ok
;
vlc_bool_t
b_es_out_ok
;
vlc_bool_t
b_simple
;
vlc_bool_t
b_simple
;
int
i_title
;
input_title_t
**
title
;
};
};
static
int
Demux
Control
(
demux_t
*
,
int
,
va_list
);
static
int
Control
(
demux_t
*
,
int
,
va_list
);
static
int
Demux
Demux
(
demux_t
*
);
static
int
Demux
(
demux_t
*
);
static
int
DemuxBlock
(
demux_t
*
,
uint8_t
*
pkt
,
int
i_pkt
);
static
int
DemuxBlock
(
demux_t
*
,
uint8_t
*
pkt
,
int
i_pkt
);
enum
enum
...
@@ -138,186 +130,26 @@ enum
...
@@ -138,186 +130,26 @@ enum
AR_221_1_PICTURE
=
4
,
/* 2.21:1 picture (movie) */
AR_221_1_PICTURE
=
4
,
/* 2.21:1 picture (movie) */
};
};
#if 0
static int MenusCallback( vlc_object_t *, char const *,
static int MenusCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
vlc_value_t, vlc_value_t, void * );
#endif
static
void
DemuxTitles
(
demux_t
*
p_demux
);
static
void
ESSubtitleUpdate
(
demux_t
*
);
static
void
ESSubtitleUpdate
(
demux_t
*
);
static
void
ButtonUpdate
(
demux_t
*
);
static
void
ButtonUpdate
(
demux_t
*
);
/*****************************************************************************
* Open: see if dvdnav can handle the input and if so force dvdnav demux
*****************************************************************************
* For now it has to be like that (ie open dvdnav twice) but will be fixed
* when a demux can work without an access module.
*****************************************************************************/
static
int
AccessOpen
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
dvdnav_t
*
dvdnav
;
int
i_title
,
i_chapter
,
i_angle
;
char
*
psz_name
;
vlc_value_t
val
;
vlc_bool_t
b_force
;
/* We try only if we are forced */
if
(
p_input
->
psz_demux
&&
*
p_input
->
psz_demux
&&
strncmp
(
p_input
->
psz_demux
,
"dvdnav"
,
6
)
)
{
msg_Warn
(
p_input
,
"dvdnav access discarded (demuxer forced)"
);
return
VLC_EGENERIC
;
}
b_force
=
p_input
->
psz_access
&&
!
strncmp
(
p_input
->
psz_access
,
"dvdnav"
,
6
);
psz_name
=
ParseCL
(
VLC_OBJECT
(
p_input
),
p_input
->
psz_name
,
b_force
,
&
i_title
,
&
i_chapter
,
&
i_angle
);
if
(
!
psz_name
)
{
return
VLC_EGENERIC
;
}
/* Test dvdnav */
if
(
dvdnav_open
(
&
dvdnav
,
psz_name
)
!=
DVDNAV_STATUS_OK
)
{
msg_Warn
(
p_input
,
"cannot open dvdnav"
);
free
(
psz_name
);
return
VLC_EGENERIC
;
}
dvdnav_close
(
dvdnav
);
free
(
psz_name
);
/* Fill p_input fields */
p_input
->
pf_read
=
AccessRead
;
p_input
->
pf_set_program
=
input_SetProgram
;
p_input
->
pf_set_area
=
NULL
;
p_input
->
pf_seek
=
NULL
;
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
b_pace_control
=
VLC_TRUE
;
p_input
->
stream
.
b_seekable
=
VLC_TRUE
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
/* Bogus for demux1 compatibility */
p_input
->
stream
.
p_selected_area
->
i_size
=
10000
;
p_input
->
stream
.
i_method
=
INPUT_METHOD_DVD
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
i_mtu
=
0
;
/* Force dvdnav demux */
if
(
p_input
->
psz_access
&&
!
strncmp
(
p_input
->
psz_access
,
"dvdnav"
,
6
)
)
p_input
->
psz_demux
=
strdup
(
p_input
->
psz_access
);
else
p_input
->
psz_demux
=
strdup
(
"dvdnav"
);
/* Update default_pts to a suitable value for udp access */
var_Create
(
p_input
,
"dvdnav-caching"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_input
,
"dvdnav-caching"
,
&
val
);
p_input
->
i_pts_delay
=
val
.
i_int
*
1000
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close: free unused data structures
*****************************************************************************/
static
void
AccessClose
(
vlc_object_t
*
p_this
)
{
}
/*****************************************************************************
* Read: Should not be called (ie not used by the dvdnav demuxer)
*****************************************************************************/
static
ssize_t
AccessRead
(
input_thread_t
*
p_input
,
byte_t
*
p_buffer
,
size_t
i_len
)
{
memset
(
p_buffer
,
0
,
i_len
);
return
i_len
;
}
/*****************************************************************************
* ParseCL: parse command line
*****************************************************************************/
static
char
*
ParseCL
(
vlc_object_t
*
p_this
,
char
*
psz_name
,
vlc_bool_t
b_force
,
int
*
i_title
,
int
*
i_chapter
,
int
*
i_angle
)
{
char
*
psz_parser
,
*
psz_source
,
*
psz_next
;
psz_source
=
strdup
(
psz_name
);
if
(
psz_source
==
NULL
)
return
NULL
;
*
i_title
=
0
;
*
i_chapter
=
1
;
*
i_angle
=
1
;
/* Start with the end, because you could have :
* dvdnav:/Volumes/my@toto/VIDEO_TS@1,1
* (yes, this is kludgy). */
for
(
psz_parser
=
psz_source
+
strlen
(
psz_source
)
-
1
;
psz_parser
>=
psz_source
&&
*
psz_parser
!=
'@'
;
psz_parser
--
);
if
(
psz_parser
>=
psz_source
&&
*
psz_parser
==
'@'
)
{
/* Found options */
*
psz_parser
=
'\0'
;
++
psz_parser
;
*
i_title
=
(
int
)
strtol
(
psz_parser
,
&
psz_next
,
10
);
if
(
*
psz_next
)
{
psz_parser
=
psz_next
+
1
;
*
i_chapter
=
(
int
)
strtol
(
psz_parser
,
&
psz_next
,
10
);
if
(
*
psz_next
)
{
*
i_angle
=
(
int
)
strtol
(
psz_next
+
1
,
NULL
,
10
);
}
}
}
*
i_title
=
*
i_title
>=
0
?
*
i_title
:
0
;
*
i_chapter
=
*
i_chapter
?
*
i_chapter
:
1
;
*
i_angle
=
*
i_angle
?
*
i_angle
:
1
;
if
(
!*
psz_source
)
{
free
(
psz_source
);
if
(
!
b_force
)
{
return
NULL
;
}
psz_source
=
config_GetPsz
(
p_this
,
"dvd"
);
if
(
!
psz_source
)
return
NULL
;
}
#ifdef WIN32
if
(
psz_source
[
0
]
&&
psz_source
[
1
]
==
':'
&&
psz_source
[
2
]
==
'\\'
&&
psz_source
[
3
]
==
'\0'
)
{
psz_source
[
2
]
=
'\0'
;
}
#endif
msg_Dbg
(
p_this
,
"dvdroot=%s title=%d chapter=%d angle=%d"
,
psz_source
,
*
i_title
,
*
i_chapter
,
*
i_angle
);
return
psz_source
;
}
/*****************************************************************************
/*****************************************************************************
* DemuxOpen:
* DemuxOpen:
*****************************************************************************/
*****************************************************************************/
static
int
Demux
Open
(
vlc_object_t
*
p_this
)
static
int
Open
(
vlc_object_t
*
p_this
)
{
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
demux_sys_t
*
p_sys
;
vlc_value_t
val
,
text
;
int
i_title
,
i_chapter
,
i_angle
;
int
i_title
,
i_titles
,
i_chapter
,
i_chapters
,
i_angle
,
i
;
char
*
psz_name
;
char
*
psz_name
;
if
(
strncmp
(
p_demux
->
psz_access
,
"dvdnav"
,
6
)
||
if
(
strncmp
(
p_demux
->
psz_access
,
"dvdnav"
,
6
)
)
strncmp
(
p_demux
->
psz_demux
,
"dvdnav"
,
6
)
)
{
{
msg_Warn
(
p_demux
,
"dvdnav module discarded"
);
msg_Warn
(
p_demux
,
"dvdnav module discarded"
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
...
@@ -330,7 +162,9 @@ static int DemuxOpen( vlc_object_t *p_this )
...
@@ -330,7 +162,9 @@ static int DemuxOpen( vlc_object_t *p_this )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
/* Init p_sys */
/* fill p_demux field */
p_demux
->
pf_demux
=
Demux
;
p_demux
->
pf_control
=
Control
;
p_demux
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_demux
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
memset
(
p_sys
,
0
,
sizeof
(
demux_sys_t
)
);
memset
(
p_sys
,
0
,
sizeof
(
demux_sys_t
)
);
...
@@ -376,29 +210,46 @@ static int DemuxOpen( vlc_object_t *p_this )
...
@@ -376,29 +210,46 @@ static int DemuxOpen( vlc_object_t *p_this )
dvdnav_err_to_string
(
p_sys
->
dvdnav
)
);
dvdnav_err_to_string
(
p_sys
->
dvdnav
)
);
}
}
#if 0 // FIXME: Doesn't work with libdvdnav CVS!
// FIXME: Doesn't work with libdvdnav CVS!
/* Find out number of titles/chapters */
// Bah don't use CVS ;) --fenrir (anyway it's needed now)
dvdnav_get_number_of_titles( p_sys->dvdnav, &i_titles );
DemuxTitles
(
p_demux
);
for( i = 1; i <= i_titles; i++ )
/* Set forced title/chapter */
if
(
i_title
!=
0
)
{
{
i_chapters = 0;
if
(
dvdnav_title_play
(
p_sys
->
dvdnav
,
i_title
)
!=
DVDNAV_STATUS_OK
)
dvdnav_get_number_of_parts( p_sys->dvdnav, i, &i_chapters );
{
msg_Warn
(
p_demux
,
"cannot set title"
);
i_title
=
0
;
}
else
{
p_demux
->
info
.
i_update
|=
INPUT_UPDATE_TITLE
;
p_demux
->
info
.
i_title
=
i_title
;
}
}
}
#endif
if
(
dvdnav_title_play
(
p_sys
->
dvdnav
,
i_title
)
!=
if
(
i_chapter
!=
0
&&
i_title
!=
0
)
DVDNAV_STATUS_OK
)
{
{
msg_Warn
(
p_demux
,
"cannot set title/chapter"
);
if
(
dvdnav_part_play
(
p_sys
->
dvdnav
,
i_title
,
i_chapter
)
!=
DVDNAV_STATUS_OK
)
{
msg_Warn
(
p_demux
,
"cannot set chapter"
);
i_chapter
=
0
;
}
else
{
p_demux
->
info
.
i_update
|=
INPUT_UPDATE_SEEKPOINT
;
p_demux
->
info
.
i_seekpoint
=
i_chapter
;
}
}
}
/* fill p_demux field */
/* Update default_pts to a suitable value for dvdnav access */
p_demux
->
pf_control
=
DemuxControl
;
var_Create
(
p_demux
,
"dvdnav-caching"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
p_demux
->
pf_demux
=
DemuxDemux
;
/* For simple mode (no menus), we're done */
/* For simple mode (no menus), we're done */
if
(
p_sys
->
b_simple
)
return
VLC_SUCCESS
;
if
(
p_sys
->
b_simple
)
return
VLC_SUCCESS
;
/* FIXME hack hack hack hachk FIXME */
/* Get p_input and create variable */
/* Get p_input and create variable */
p_sys
->
p_input
=
vlc_object_find
(
p_demux
,
VLC_OBJECT_INPUT
,
FIND_PARENT
);
p_sys
->
p_input
=
vlc_object_find
(
p_demux
,
VLC_OBJECT_INPUT
,
FIND_PARENT
);
var_Create
(
p_sys
->
p_input
,
"x-start"
,
VLC_VAR_INTEGER
);
var_Create
(
p_sys
->
p_input
,
"x-start"
,
VLC_VAR_INTEGER
);
...
@@ -410,27 +261,6 @@ static int DemuxOpen( vlc_object_t *p_this )
...
@@ -410,27 +261,6 @@ static int DemuxOpen( vlc_object_t *p_this )
var_Create
(
p_sys
->
p_input
,
"highlight"
,
VLC_VAR_BOOL
);
var_Create
(
p_sys
->
p_input
,
"highlight"
,
VLC_VAR_BOOL
);
var_Create
(
p_sys
->
p_input
,
"highlight-mutex"
,
VLC_VAR_MUTEX
);
var_Create
(
p_sys
->
p_input
,
"highlight-mutex"
,
VLC_VAR_MUTEX
);
/* Create a few object variables used for navigation in the interfaces */
var_Create
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_INTEGER
|
VLC_VAR_HASCHOICE
|
VLC_VAR_ISCOMMAND
);
text
.
psz_string
=
_
(
"DVD menus"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_SETTEXT
,
&
text
,
NULL
);
var_AddCallback
(
p_sys
->
p_input
,
"dvd_menus"
,
MenusCallback
,
p_demux
);
val
.
i_int
=
DVD_MENU_Escape
;
text
.
psz_string
=
_
(
"Resume"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
val
.
i_int
=
DVD_MENU_Root
;
text
.
psz_string
=
_
(
"Root"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
val
.
i_int
=
DVD_MENU_Title
;
text
.
psz_string
=
_
(
"Title"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
val
.
i_int
=
DVD_MENU_Part
;
text
.
psz_string
=
_
(
"Chapter"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
val
.
i_int
=
DVD_MENU_Subpicture
;
text
.
psz_string
=
_
(
"Subtitle"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
val
.
i_int
=
DVD_MENU_Audio
;
text
.
psz_string
=
_
(
"Audio"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
val
.
i_int
=
DVD_MENU_Angle
;
text
.
psz_string
=
_
(
"Angle"
);
var_Change
(
p_sys
->
p_input
,
"dvd_menus"
,
VLC_VAR_ADDCHOICE
,
&
val
,
&
text
);
/* Now create our event thread catcher */
/* Now create our event thread catcher */
p_sys
->
p_ev
=
vlc_object_create
(
p_demux
,
sizeof
(
event_thread_t
)
);
p_sys
->
p_ev
=
vlc_object_create
(
p_demux
,
sizeof
(
event_thread_t
)
);
p_sys
->
p_ev
->
p_demux
=
p_demux
;
p_sys
->
p_ev
->
p_demux
=
p_demux
;
...
@@ -441,9 +271,9 @@ static int DemuxOpen( vlc_object_t *p_this )
...
@@ -441,9 +271,9 @@ static int DemuxOpen( vlc_object_t *p_this )
}
}
/*****************************************************************************
/*****************************************************************************
*
Demux
Close:
* Close:
*****************************************************************************/
*****************************************************************************/
static
void
Demux
Close
(
vlc_object_t
*
p_this
)
static
void
Close
(
vlc_object_t
*
p_this
)
{
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
...
@@ -483,12 +313,17 @@ static void DemuxClose( vlc_object_t *p_this )
...
@@ -483,12 +313,17 @@ static void DemuxClose( vlc_object_t *p_this )
}
}
/*****************************************************************************
/*****************************************************************************
*
Demux
Control:
* Control:
*****************************************************************************/
*****************************************************************************/
static
int
Demux
Control
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
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
;
double
f
,
*
pf
;
double
f
,
*
pf
;
vlc_bool_t
*
pb
;
int64_t
*
pi64
;
input_title_t
***
ppp_title
;
int
*
pi_int
;
int
i
;
switch
(
i_query
)
switch
(
i_query
)
{
{
...
@@ -525,6 +360,92 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
...
@@ -525,6 +360,92 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
/* Special for access_demux */
case
DEMUX_CAN_PAUSE
:
case
DEMUX_CAN_CONTROL_PACE
:
/* TODO */
pb
=
(
vlc_bool_t
*
)
va_arg
(
args
,
vlc_bool_t
*
);
*
pb
=
VLC_TRUE
;
return
VLC_SUCCESS
;
case
DEMUX_SET_PAUSE_STATE
:
return
VLC_SUCCESS
;
case
DEMUX_GET_TITLE_INFO
:
ppp_title
=
(
input_title_t
***
)
va_arg
(
args
,
input_title_t
***
);
pi_int
=
(
int
*
)
va_arg
(
args
,
int
*
);
/* Duplicate title infos */
*
pi_int
=
p_sys
->
i_title
;
*
ppp_title
=
malloc
(
sizeof
(
input_title_t
**
)
*
p_sys
->
i_title
);
for
(
i
=
0
;
i
<
p_sys
->
i_title
;
i
++
)
{
(
*
ppp_title
)[
i
]
=
vlc_input_title_Duplicate
(
p_sys
->
title
[
i
]
);
}
return
VLC_SUCCESS
;
case
DEMUX_SET_TITLE
:
i
=
(
int
)
va_arg
(
args
,
int
);
if
(
(
i
==
0
&&
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Root
)
!=
DVDNAV_STATUS_OK
)
||
(
i
!=
0
&&
dvdnav_title_play
(
p_sys
->
dvdnav
,
i
)
!=
DVDNAV_STATUS_OK
)
)
{
msg_Warn
(
p_demux
,
"cannot set title/chapter"
);
return
VLC_EGENERIC
;
}
p_demux
->
info
.
i_update
|=
INPUT_UPDATE_TITLE
|
INPUT_UPDATE_SEEKPOINT
;
p_demux
->
info
.
i_title
=
i
;
p_demux
->
info
.
i_seekpoint
=
0
;
return
VLC_SUCCESS
;
case
DEMUX_SET_SEEKPOINT
:
i
=
(
int
)
va_arg
(
args
,
int
);
if
(
p_demux
->
info
.
i_title
==
0
)
{
int
i_ret
;
/* Special case */
switch
(
i
)
{
case
0
:
i_ret
=
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Escape
);
break
;
case
1
:
i_ret
=
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Root
);
break
;
case
2
:
i_ret
=
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Title
);
break
;
case
3
:
i_ret
=
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Part
);
break
;
case
4
:
i_ret
=
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Subpicture
);
break
;
case
5
:
i_ret
=
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Audio
);
break
;
case
6
:
i_ret
=
dvdnav_menu_call
(
p_sys
->
dvdnav
,
DVD_MENU_Angle
);
break
;
default:
return
VLC_EGENERIC
;
}
if
(
i_ret
!=
DVDNAV_STATUS_OK
)
return
VLC_EGENERIC
;
}
else
if
(
dvdnav_part_play
(
p_sys
->
dvdnav
,
p_demux
->
info
.
i_title
,
i
)
!=
DVDNAV_STATUS_OK
)
{
msg_Warn
(
p_demux
,
"cannot set title/chapter"
);
return
VLC_EGENERIC
;
}
p_demux
->
info
.
i_update
|=
INPUT_UPDATE_SEEKPOINT
;
p_demux
->
info
.
i_seekpoint
=
i
;
return
VLC_SUCCESS
;
case
DEMUX_GET_PTS_DELAY
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi64
=
(
int64_t
)
var_GetInteger
(
p_demux
,
"dvdnav-caching"
)
*
I64C
(
1000
);
return
VLC_SUCCESS
;
/* TODO implement others */
/* TODO implement others */
default:
default:
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
...
@@ -532,9 +453,9 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
...
@@ -532,9 +453,9 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
}
}
/*****************************************************************************
/*****************************************************************************
* Demux
Demux
:
* Demux:
*****************************************************************************/
*****************************************************************************/
static
int
Demux
Demux
(
demux_t
*
p_demux
)
static
int
Demux
(
demux_t
*
p_demux
)
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
...
@@ -558,11 +479,10 @@ static int DemuxDemux( demux_t *p_demux )
...
@@ -558,11 +479,10 @@ static int DemuxDemux( demux_t *p_demux )
}
}
#if DVD_READ_CACHE
#if DVD_READ_CACHE
if
(
dvdnav_get_next_cache_block
(
p_sys
->
dvdnav
,
&
packet
,
&
i_event
,
&
i_len
)
if
(
dvdnav_get_next_cache_block
(
p_sys
->
dvdnav
,
&
packet
,
&
i_event
,
&
i_len
)
==
DVDNAV_STATUS_ERR
)
#else
#else
if
(
dvdnav_get_next_block
(
p_sys
->
dvdnav
,
packet
,
&
i_event
,
&
i_len
)
if
(
dvdnav_get_next_block
(
p_sys
->
dvdnav
,
packet
,
&
i_event
,
&
i_len
)
==
DVDNAV_STATUS_ERR
)
#endif
#endif
==
DVDNAV_STATUS_ERR
)
{
{
msg_Warn
(
p_demux
,
"cannot get next block (%s)"
,
msg_Warn
(
p_demux
,
"cannot get next block (%s)"
,
dvdnav_err_to_string
(
p_sys
->
dvdnav
)
);
dvdnav_err_to_string
(
p_sys
->
dvdnav
)
);
...
@@ -638,7 +558,10 @@ static int DemuxDemux( demux_t *p_demux )
...
@@ -638,7 +558,10 @@ static int DemuxDemux( demux_t *p_demux )
}
}
case
DVDNAV_VTS_CHANGE
:
case
DVDNAV_VTS_CHANGE
:
{
{
int32_t
i_title
=
0
;
int32_t
i_part
=
0
;
int
i
;
int
i
;
dvdnav_vts_change_event_t
*
event
=
(
dvdnav_vts_change_event_t
*
)
packet
;
dvdnav_vts_change_event_t
*
event
=
(
dvdnav_vts_change_event_t
*
)
packet
;
msg_Dbg
(
p_demux
,
"DVDNAV_VTS_CHANGE"
);
msg_Dbg
(
p_demux
,
"DVDNAV_VTS_CHANGE"
);
msg_Dbg
(
p_demux
,
" - vtsN=%d"
,
event
->
new_vtsN
);
msg_Dbg
(
p_demux
,
" - vtsN=%d"
,
event
->
new_vtsN
);
...
@@ -662,25 +585,29 @@ static int DemuxDemux( demux_t *p_demux )
...
@@ -662,25 +585,29 @@ static int DemuxDemux( demux_t *p_demux )
tk
->
b_seen
=
VLC_FALSE
;
tk
->
b_seen
=
VLC_FALSE
;
}
}
if
(
p_sys
->
b_simple
)
if
(
dvdnav_current_title_info
(
p_sys
->
dvdnav
,
&
i_title
,
&
i_part
)
==
DVDNAV_STATUS_OK
)
{
{
int32_t
i_title
=
0
;
if
(
p_sys
->
b_simple
&&
i_title
==
0
)
int32_t
i_part
=
0
;
if
(
dvdnav_current_title_info
(
p_sys
->
dvdnav
,
&
i_title
,
&
i_part
)
==
DVDNAV_STATUS_OK
)
{
{
if
(
i_title
==
0
)
/* we have returned in menu, stop dvd */
{
/* FIXME is it the right way ? */
/* we have returned in menu, stop dvd */
return
0
;
/* FIXME is it the right way ? */
}
return
0
;
if
(
i_title
>=
0
&&
i_title
<
p_sys
->
i_title
&&
}
p_demux
->
info
.
i_title
!=
i_title
)
{
p_demux
->
info
.
i_update
|=
INPUT_UPDATE_TITLE
;
p_demux
->
info
.
i_title
=
i_title
;
}
}
}
}
break
;
break
;
}
}
case
DVDNAV_CELL_CHANGE
:
case
DVDNAV_CELL_CHANGE
:
{
{
int32_t
i_title
=
0
;
int32_t
i_part
=
0
;
dvdnav_cell_change_event_t
*
event
=
dvdnav_cell_change_event_t
*
event
=
(
dvdnav_cell_change_event_t
*
)
packet
;
(
dvdnav_cell_change_event_t
*
)
packet
;
msg_Dbg
(
p_demux
,
"DVDNAV_CELL_CHANGE"
);
msg_Dbg
(
p_demux
,
"DVDNAV_CELL_CHANGE"
);
...
@@ -691,8 +618,22 @@ static int DemuxDemux( demux_t *p_demux )
...
@@ -691,8 +618,22 @@ static int DemuxDemux( demux_t *p_demux )
msg_Dbg
(
p_demux
,
" - pgc_length=%lld"
,
event
->
pgc_length
);
msg_Dbg
(
p_demux
,
" - pgc_length=%lld"
,
event
->
pgc_length
);
msg_Dbg
(
p_demux
,
" - cell_start=%lld"
,
event
->
cell_start
);
msg_Dbg
(
p_demux
,
" - cell_start=%lld"
,
event
->
cell_start
);
msg_Dbg
(
p_demux
,
" - pg_start=%lld"
,
event
->
pg_start
);
msg_Dbg
(
p_demux
,
" - pg_start=%lld"
,
event
->
pg_start
);
/* FIXME is it correct or there is better way to know chapter change */
if
(
dvdnav_current_title_info
(
p_sys
->
dvdnav
,
&
i_title
,
&
i_part
)
==
DVDNAV_STATUS_OK
)
{
if
(
i_title
>=
0
&&
i_title
<
p_sys
->
i_title
&&
i_part
>=
0
&&
i_part
<
p_sys
->
title
[
i_title
]
->
i_seekpoint
&&
p_demux
->
info
.
i_seekpoint
!=
i_part
)
{
p_demux
->
info
.
i_update
|=
INPUT_UPDATE_SEEKPOINT
;
p_demux
->
info
.
i_seekpoint
=
i_part
;
}
}
break
;
break
;
}
}
case
DVDNAV_NAV_PACKET
:
case
DVDNAV_NAV_PACKET
:
{
{
#ifdef DVDNAV_DEBUG
#ifdef DVDNAV_DEBUG
...
@@ -751,6 +692,139 @@ static int DemuxDemux( demux_t *p_demux )
...
@@ -751,6 +692,139 @@ static int DemuxDemux( demux_t *p_demux )
return
1
;
return
1
;
}
}
/*****************************************************************************
* ParseCL: parse command line
*****************************************************************************/
static
char
*
ParseCL
(
vlc_object_t
*
p_this
,
char
*
psz_name
,
vlc_bool_t
b_force
,
int
*
i_title
,
int
*
i_chapter
,
int
*
i_angle
)
{
char
*
psz_parser
,
*
psz_source
,
*
psz_next
;
psz_source
=
strdup
(
psz_name
);
if
(
psz_source
==
NULL
)
return
NULL
;
*
i_title
=
0
;
*
i_chapter
=
0
;
*
i_angle
=
1
;
/* Start with the end, because you could have :
* dvdnav:/Volumes/my@toto/VIDEO_TS@1,1
* (yes, this is kludgy). */
for
(
psz_parser
=
psz_source
+
strlen
(
psz_source
)
-
1
;
psz_parser
>=
psz_source
&&
*
psz_parser
!=
'@'
;
psz_parser
--
);
if
(
psz_parser
>=
psz_source
&&
*
psz_parser
==
'@'
)
{
/* Found options */
*
psz_parser
=
'\0'
;
++
psz_parser
;
*
i_title
=
(
int
)
strtol
(
psz_parser
,
&
psz_next
,
10
);
if
(
*
psz_next
)
{
psz_parser
=
psz_next
+
1
;
*
i_chapter
=
(
int
)
strtol
(
psz_parser
,
&
psz_next
,
10
);
if
(
*
psz_next
)
{
*
i_angle
=
(
int
)
strtol
(
psz_next
+
1
,
NULL
,
10
);
}
}
}
*
i_title
=
*
i_title
>=
0
?
*
i_title
:
0
;
*
i_chapter
=
*
i_chapter
?
*
i_chapter
:
0
;
*
i_angle
=
*
i_angle
?
*
i_angle
:
1
;
if
(
!*
psz_source
)
{
free
(
psz_source
);
if
(
!
b_force
)
{
return
NULL
;
}
psz_source
=
config_GetPsz
(
p_this
,
"dvd"
);
if
(
!
psz_source
)
return
NULL
;
}
#ifdef WIN32
if
(
psz_source
[
0
]
&&
psz_source
[
1
]
==
':'
&&
psz_source
[
2
]
==
'\\'
&&
psz_source
[
3
]
==
'\0'
)
{
psz_source
[
2
]
=
'\0'
;
}
#endif
msg_Dbg
(
p_this
,
"dvdroot=%s title=%d chapter=%d angle=%d"
,
psz_source
,
*
i_title
,
*
i_chapter
,
*
i_angle
);
return
psz_source
;
}
static
void
DemuxTitles
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
input_title_t
*
t
;
seekpoint_t
*
s
;
int32_t
i_titles
;
int
i
;
/* Menu */
t
=
vlc_input_title_New
();
t
->
b_menu
=
VLC_TRUE
;
t
->
psz_name
=
strdup
(
"DVD Menu"
);
s
=
vlc_seekpoint_New
();
s
->
psz_name
=
strdup
(
"Resume"
);
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
s
=
vlc_seekpoint_New
();
s
->
psz_name
=
strdup
(
"Root"
);
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
s
=
vlc_seekpoint_New
();
s
->
psz_name
=
strdup
(
"Title"
);
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
s
=
vlc_seekpoint_New
();
s
->
psz_name
=
strdup
(
"Chapter"
);
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
s
=
vlc_seekpoint_New
();
s
->
psz_name
=
strdup
(
"Subtitle"
);
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
s
=
vlc_seekpoint_New
();
s
->
psz_name
=
strdup
(
"Audio"
);
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
s
=
vlc_seekpoint_New
();
s
->
psz_name
=
strdup
(
"Angle"
);
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
TAB_APPEND
(
p_sys
->
i_title
,
p_sys
->
title
,
t
);
/* Find out number of titles/chapters */
dvdnav_get_number_of_titles
(
p_sys
->
dvdnav
,
&
i_titles
);
for
(
i
=
1
;
i
<
i_titles
;
i
++
)
{
int32_t
i_chapters
=
0
;
int
j
;
dvdnav_get_number_of_parts
(
p_sys
->
dvdnav
,
i
,
&
i_chapters
);
t
=
vlc_input_title_New
();
for
(
j
=
0
;
j
<
__MAX
(
i_chapters
,
1
);
j
++
)
{
s
=
vlc_seekpoint_New
();
TAB_APPEND
(
t
->
i_seekpoint
,
t
->
seekpoint
,
s
);
}
TAB_APPEND
(
p_sys
->
i_title
,
p_sys
->
title
,
t
);
}
}
/*****************************************************************************
/*****************************************************************************
* Update functions:
* Update functions:
*****************************************************************************/
*****************************************************************************/
...
@@ -1220,6 +1294,7 @@ static int EventKey( vlc_object_t *p_this, char const *psz_var,
...
@@ -1220,6 +1294,7 @@ static int EventKey( vlc_object_t *p_this, char const *psz_var,
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
#if 0
static int MenusCallback( vlc_object_t *p_this, char const *psz_name,
static int MenusCallback( vlc_object_t *p_this, char const *psz_name,
vlc_value_t oldval, vlc_value_t newval, void *p_arg )
vlc_value_t oldval, vlc_value_t newval, void *p_arg )
{
{
...
@@ -1230,3 +1305,4 @@ static int MenusCallback( vlc_object_t *p_this, char const *psz_name,
...
@@ -1230,3 +1305,4 @@ static int MenusCallback( vlc_object_t *p_this, char const *psz_name,
return VLC_SUCCESS;
return VLC_SUCCESS;
}
}
#endif
modules/demux/livedotcom.cpp
View file @
d82e9eb7
...
@@ -44,11 +44,8 @@ using namespace std;
...
@@ -44,11 +44,8 @@ using namespace std;
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
*****************************************************************************/
*****************************************************************************/
static
int
DemuxOpen
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
DemuxClose
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
int
AccessOpen
(
vlc_object_t
*
);
static
void
AccessClose
(
vlc_object_t
*
);
#define CACHING_TEXT N_("Caching value (ms)")
#define CACHING_TEXT N_("Caching value (ms)")
#define CACHING_LONGTEXT N_( \
#define CACHING_LONGTEXT N_( \
...
@@ -58,15 +55,15 @@ static void AccessClose( vlc_object_t * );
...
@@ -58,15 +55,15 @@ static void AccessClose( vlc_object_t * );
vlc_module_begin
();
vlc_module_begin
();
set_description
(
_
(
"live.com (RTSP/RTP/SDP) demuxer"
)
);
set_description
(
_
(
"live.com (RTSP/RTP/SDP) demuxer"
)
);
set_capability
(
"demux2"
,
50
);
set_capability
(
"demux2"
,
50
);
set_callbacks
(
DemuxOpen
,
Demux
Close
);
set_callbacks
(
Open
,
Close
);
add_shortcut
(
"live"
);
add_shortcut
(
"live"
);
add_submodule
();
add_submodule
();
set_description
(
_
(
"RTSP/RTP
describe
"
)
);
set_description
(
_
(
"RTSP/RTP
access and demux
"
)
);
add_shortcut
(
"rtsp"
);
add_shortcut
(
"rtsp"
);
add_shortcut
(
"sdp"
);
add_shortcut
(
"sdp"
);
set_capability
(
"access"
,
0
);
set_capability
(
"access
_demux
"
,
0
);
set_callbacks
(
AccessOpen
,
Access
Close
);
set_callbacks
(
Open
,
Close
);
add_bool
(
"rtsp-tcp"
,
0
,
NULL
,
add_bool
(
"rtsp-tcp"
,
0
,
NULL
,
N_
(
"Use RTP over RTSP (TCP)"
),
N_
(
"Use RTP over RTSP (TCP)"
),
N_
(
"Use RTP over RTSP (TCP)"
),
VLC_TRUE
);
N_
(
"Use RTP over RTSP (TCP)"
),
VLC_TRUE
);
...
@@ -84,187 +81,7 @@ vlc_module_end();
...
@@ -84,187 +81,7 @@ vlc_module_end();
*/
*/
/*****************************************************************************
/*****************************************************************************
* Local prototypes for access
* Local prototypes
*****************************************************************************/
struct
access_sys_t
{
int
i_sdp
;
char
*
p_sdp
;
int
i_pos
;
};
static
ssize_t
Read
(
input_thread_t
*
,
byte_t
*
,
size_t
);
static
ssize_t
MRLRead
(
input_thread_t
*
,
byte_t
*
,
size_t
);
/*****************************************************************************
* AccessOpen:
*****************************************************************************/
static
int
AccessOpen
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
access_sys_t
*
p_sys
;
TaskScheduler
*
scheduler
=
NULL
;
UsageEnvironment
*
env
=
NULL
;
RTSPClient
*
rtsp
=
NULL
;
vlc_value_t
val
;
char
*
psz_url
;
if
(
p_input
->
psz_access
==
NULL
||
(
strcasecmp
(
p_input
->
psz_access
,
"rtsp"
)
&&
strcasecmp
(
p_input
->
psz_access
,
"sdp"
)
)
)
{
msg_Warn
(
p_input
,
"RTSP access discarded"
);
return
VLC_EGENERIC
;
}
if
(
!
strcasecmp
(
p_input
->
psz_access
,
"rtsp"
)
)
{
if
(
(
scheduler
=
BasicTaskScheduler
::
createNew
()
)
==
NULL
)
{
msg_Err
(
p_input
,
"BasicTaskScheduler::createNew failed"
);
return
VLC_EGENERIC
;
}
if
(
(
env
=
BasicUsageEnvironment
::
createNew
(
*
scheduler
)
)
==
NULL
)
{
delete
scheduler
;
msg_Err
(
p_input
,
"BasicUsageEnvironment::createNew failed"
);
return
VLC_EGENERIC
;
}
if
(
(
rtsp
=
RTSPClient
::
createNew
(
*
env
,
1
/*verbose*/
,
"VLC Media Player"
)
)
==
NULL
)
{
delete
env
;
delete
scheduler
;
msg_Err
(
p_input
,
"RTSPClient::createNew failed"
);
return
VLC_EGENERIC
;
}
psz_url
=
(
char
*
)
malloc
(
strlen
(
p_input
->
psz_name
)
+
8
);
sprintf
(
psz_url
,
"rtsp://%s"
,
p_input
->
psz_name
);
p_sys
=
(
access_sys_t
*
)
malloc
(
sizeof
(
access_sys_t
)
);
p_sys
->
p_sdp
=
rtsp
->
describeURL
(
psz_url
);
if
(
p_sys
->
p_sdp
==
NULL
)
{
msg_Err
(
p_input
,
"describeURL failed (%s)"
,
env
->
getResultMsg
()
);
free
(
psz_url
);
delete
env
;
delete
scheduler
;
free
(
p_sys
);
return
VLC_EGENERIC
;
}
free
(
psz_url
);
p_sys
->
i_sdp
=
strlen
(
p_sys
->
p_sdp
);
p_sys
->
i_pos
=
0
;
delete
env
;
delete
scheduler
;
var_Create
(
p_input
,
"rtsp-tcp"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_input
,
"rtsp-tcp"
,
&
val
);
p_input
->
p_access_data
=
p_sys
;
p_input
->
i_mtu
=
0
;
/* Set exported functions */
p_input
->
pf_read
=
Read
;
p_input
->
pf_seek
=
NULL
;
p_input
->
pf_set_program
=
input_SetProgram
;
p_input
->
pf_set_area
=
NULL
;
p_input
->
p_private
=
NULL
;
p_input
->
psz_demux
=
"live"
;
/* Finished to set some variable */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
/* FIXME that's not true but eg over tcp, server send data too fast */
p_input
->
stream
.
b_pace_control
=
val
.
b_bool
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
p_input
->
stream
.
b_seekable
=
1
;
/* Hack to display time */
p_input
->
stream
.
p_selected_area
->
i_size
=
p_sys
->
i_sdp
;
p_input
->
stream
.
i_method
=
INPUT_METHOD_NETWORK
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
/* Update default_pts to a suitable value for RTSP access */
var_Create
(
p_input
,
"rtsp-caching"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_input
,
"rtsp-caching"
,
&
val
);
p_input
->
i_pts_delay
=
val
.
i_int
*
1000
;
return
VLC_SUCCESS
;
}
else
{
p_input
->
p_access_data
=
(
access_sys_t
*
)
0
;
p_input
->
i_mtu
=
0
;
p_input
->
pf_read
=
MRLRead
;
p_input
->
pf_seek
=
NULL
;
p_input
->
pf_set_program
=
input_SetProgram
;
p_input
->
pf_set_area
=
NULL
;
p_input
->
p_private
=
NULL
;
p_input
->
psz_demux
=
"live"
;
/* Finished to set some variable */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
b_pace_control
=
VLC_TRUE
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
p_input
->
stream
.
b_seekable
=
VLC_FALSE
;
p_input
->
stream
.
p_selected_area
->
i_size
=
strlen
(
p_input
->
psz_name
);
p_input
->
stream
.
i_method
=
INPUT_METHOD_NETWORK
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
VLC_SUCCESS
;
}
}
/*****************************************************************************
* AccessClose:
*****************************************************************************/
static
void
AccessClose
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
if
(
!
strcasecmp
(
p_input
->
psz_access
,
"rtsp"
)
)
{
delete
[]
p_sys
->
p_sdp
;
free
(
p_sys
);
}
}
/*****************************************************************************
* Read:
*****************************************************************************/
static
ssize_t
Read
(
input_thread_t
*
p_input
,
byte_t
*
p_buffer
,
size_t
i_len
)
{
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
int
i_copy
=
__MIN
(
(
int
)
i_len
,
p_sys
->
i_sdp
-
p_sys
->
i_pos
);
if
(
i_copy
>
0
)
{
memcpy
(
p_buffer
,
&
p_sys
->
p_sdp
[
p_sys
->
i_pos
],
i_copy
);
p_sys
->
i_pos
+=
i_copy
;
}
return
i_copy
;
}
/*****************************************************************************
* MRLRead: read data from the mrl
*****************************************************************************/
static
ssize_t
MRLRead
(
input_thread_t
*
p_input
,
byte_t
*
p_buffer
,
size_t
i_len
)
{
int
i_done
=
(
int
)
p_input
->
p_access_data
;
int
i_copy
=
__MIN
(
(
int
)
i_len
,
(
int
)
strlen
(
p_input
->
psz_name
)
-
i_done
);
if
(
i_copy
>
0
)
{
memcpy
(
p_buffer
,
&
p_input
->
psz_name
[
i_done
],
i_copy
);
i_done
+=
i_copy
;
p_input
->
p_access_data
=
(
access_sys_t
*
)
i_done
;
}
return
i_copy
;
}
/*****************************************************************************
* Local prototypes for demux2
*****************************************************************************/
*****************************************************************************/
typedef
struct
typedef
struct
{
{
...
@@ -315,7 +132,7 @@ static int Control( demux_t *, int, va_list );
...
@@ -315,7 +132,7 @@ static int Control( demux_t *, int, va_list );
/*****************************************************************************
/*****************************************************************************
* DemuxOpen:
* DemuxOpen:
*****************************************************************************/
*****************************************************************************/
static
int
Demux
Open
(
vlc_object_t
*
p_this
)
static
int
Open
(
vlc_object_t
*
p_this
)
{
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
demux_sys_t
*
p_sys
;
...
@@ -323,26 +140,32 @@ static int DemuxOpen ( vlc_object_t *p_this )
...
@@ -323,26 +140,32 @@ static int DemuxOpen ( vlc_object_t *p_this )
MediaSubsessionIterator
*
iter
;
MediaSubsessionIterator
*
iter
;
MediaSubsession
*
sub
;
MediaSubsession
*
sub
;
vlc_value_t
val
;
vlc_bool_t
b_rtsp_tcp
;
uint8_t
*
p_peek
;
uint8_t
*
p_peek
;
int
i_sdp
;
int
i_sdp
;
int
i_sdp_max
;
int
i_sdp_max
;
uint8_t
*
p_sdp
;
uint8_t
*
p_sdp
;
/* See if it looks like a SDP
if
(
p_demux
->
s
)
v, o, s fields are mandatory and in this order */
if
(
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
7
)
<
7
)
{
{
msg_Err
(
p_demux
,
"cannot peek"
);
/* See if it looks like a SDP
return
VLC_EGENERIC
;
v, o, s fields are mandatory and in this order */
if
(
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
7
)
<
7
)
{
msg_Err
(
p_demux
,
"cannot peek"
);
return
VLC_EGENERIC
;
}
if
(
strncmp
(
(
char
*
)
p_peek
,
"v=0
\r\n
"
,
5
)
&&
strncmp
(
(
char
*
)
p_peek
,
"v=0
\n
"
,
4
)
&&
(
p_peek
[
0
]
<
'a'
||
p_peek
[
0
]
>
'z'
||
p_peek
[
1
]
!=
'='
)
)
{
msg_Warn
(
p_demux
,
"SDP module discarded"
);
return
VLC_EGENERIC
;
}
}
}
if
(
strncmp
(
(
char
*
)
p_peek
,
"v=0
\r\n
"
,
5
)
&&
strncmp
(
(
char
*
)
p_peek
,
"v=0
\n
"
,
4
)
&&
else
(
strcasecmp
(
p_demux
->
psz_access
,
"rtsp"
)
||
p_peek
[
0
]
<
'a'
||
p_peek
[
0
]
>
'z'
||
p_peek
[
1
]
!=
'='
)
)
{
{
msg_Warn
(
p_demux
,
"SDP module discarded"
);
var_Create
(
p_demux
,
"rtsp-caching"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
return
VLC_EGENERIC
;
}
}
p_demux
->
pf_demux
=
Demux
;
p_demux
->
pf_demux
=
Demux
;
...
@@ -360,35 +183,6 @@ static int DemuxOpen ( vlc_object_t *p_this )
...
@@ -360,35 +183,6 @@ static int DemuxOpen ( vlc_object_t *p_this )
p_sys
->
i_length
=
0
;
p_sys
->
i_length
=
0
;
p_sys
->
i_start
=
0
;
p_sys
->
i_start
=
0
;
/* Gather the complete sdp file */
i_sdp
=
0
;
i_sdp_max
=
1000
;
p_sdp
=
(
uint8_t
*
)
malloc
(
i_sdp_max
);
for
(
;;
)
{
int
i_read
=
stream_Read
(
p_demux
->
s
,
&
p_sdp
[
i_sdp
],
i_sdp_max
-
i_sdp
-
1
);
if
(
i_read
<
0
)
{
msg_Err
(
p_demux
,
"failed to read SDP"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
i_sdp
+=
i_read
;
if
(
i_read
<
i_sdp_max
-
i_sdp
-
1
)
{
p_sdp
[
i_sdp
]
=
'\0'
;
break
;
}
i_sdp_max
+=
1000
;
p_sdp
=
(
uint8_t
*
)
realloc
(
p_sdp
,
i_sdp_max
);
}
p_sys
->
p_sdp
=
(
char
*
)
p_sdp
;
fprintf
(
stderr
,
"sdp=%s
\n
"
,
p_sys
->
p_sdp
);
if
(
(
p_sys
->
scheduler
=
BasicTaskScheduler
::
createNew
()
)
==
NULL
)
if
(
(
p_sys
->
scheduler
=
BasicTaskScheduler
::
createNew
()
)
==
NULL
)
{
{
...
@@ -400,7 +194,8 @@ static int DemuxOpen ( vlc_object_t *p_this )
...
@@ -400,7 +194,8 @@ static int DemuxOpen ( vlc_object_t *p_this )
msg_Err
(
p_demux
,
"BasicUsageEnvironment::createNew failed"
);
msg_Err
(
p_demux
,
"BasicUsageEnvironment::createNew failed"
);
goto
error
;
goto
error
;
}
}
if
(
!
strcasecmp
(
p_demux
->
psz_access
,
"rtsp"
)
)
if
(
p_demux
->
s
==
NULL
&&
!
strcasecmp
(
p_demux
->
psz_access
,
"rtsp"
)
)
{
{
char
*
psz_url
;
char
*
psz_url
;
char
*
psz_options
;
char
*
psz_options
;
...
@@ -417,7 +212,56 @@ static int DemuxOpen ( vlc_object_t *p_this )
...
@@ -417,7 +212,56 @@ static int DemuxOpen ( vlc_object_t *p_this )
if
(
psz_options
)
if
(
psz_options
)
delete
[]
psz_options
;
delete
[]
psz_options
;
p_sdp
=
(
uint8_t
*
)
p_sys
->
rtsp
->
describeURL
(
psz_url
);
if
(
p_sdp
==
NULL
)
{
msg_Err
(
p_demux
,
"describeURL failed (%s)"
,
p_sys
->
env
->
getResultMsg
()
);
free
(
psz_url
);
goto
error
;
}
free
(
psz_url
);
free
(
psz_url
);
/* malloc-ated copy */
p_sys
->
p_sdp
=
strdup
(
(
char
*
)
p_sdp
);
delete
[]
p_sdp
;
fprintf
(
stderr
,
"sdp=%s
\n
"
,
p_sys
->
p_sdp
);
}
else
if
(
p_demux
->
s
==
NULL
&&
!
strcasecmp
(
p_demux
->
psz_access
,
"sdp"
)
)
{
p_sys
->
p_sdp
=
strdup
(
p_demux
->
psz_path
);
}
else
{
/* Gather the complete sdp file */
i_sdp
=
0
;
i_sdp_max
=
1000
;
p_sdp
=
(
uint8_t
*
)
malloc
(
i_sdp_max
);
for
(
;;
)
{
int
i_read
=
stream_Read
(
p_demux
->
s
,
&
p_sdp
[
i_sdp
],
i_sdp_max
-
i_sdp
-
1
);
if
(
i_read
<
0
)
{
msg_Err
(
p_demux
,
"failed to read SDP"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
i_sdp
+=
i_read
;
if
(
i_read
<
i_sdp_max
-
i_sdp
-
1
)
{
p_sdp
[
i_sdp
]
=
'\0'
;
break
;
}
i_sdp_max
+=
1000
;
p_sdp
=
(
uint8_t
*
)
realloc
(
p_sdp
,
i_sdp_max
);
}
p_sys
->
p_sdp
=
(
char
*
)
p_sdp
;
fprintf
(
stderr
,
"sdp=%s
\n
"
,
p_sys
->
p_sdp
);
}
}
if
(
(
p_sys
->
ms
=
MediaSession
::
createNew
(
*
p_sys
->
env
,
p_sys
->
p_sdp
)
)
==
NULL
)
if
(
(
p_sys
->
ms
=
MediaSession
::
createNew
(
*
p_sys
->
env
,
p_sys
->
p_sdp
)
)
==
NULL
)
{
{
...
@@ -425,8 +269,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
...
@@ -425,8 +269,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
goto
error
;
goto
error
;
}
}
var_Create
(
p_demux
,
"rtsp-tcp"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
b_rtsp_tcp
=
var_CreateGetBool
(
p_demux
,
"rtsp-tcp"
);
var_Get
(
p_demux
,
"rtsp-tcp"
,
&
val
);
/* Initialise each media subsession */
/* Initialise each media subsession */
iter
=
new
MediaSubsessionIterator
(
*
p_sys
->
ms
);
iter
=
new
MediaSubsessionIterator
(
*
p_sys
->
ms
);
...
@@ -466,7 +309,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
...
@@ -466,7 +309,7 @@ static int DemuxOpen ( vlc_object_t *p_this )
/* Issue the SETUP */
/* Issue the SETUP */
if
(
p_sys
->
rtsp
)
if
(
p_sys
->
rtsp
)
{
{
p_sys
->
rtsp
->
setupMediaSubsession
(
*
sub
,
False
,
val
.
b_bool
?
True
:
False
);
p_sys
->
rtsp
->
setupMediaSubsession
(
*
sub
,
False
,
b_rtsp_tcp
?
True
:
False
);
}
}
}
}
}
}
...
@@ -693,7 +536,7 @@ error:
...
@@ -693,7 +536,7 @@ error:
/*****************************************************************************
/*****************************************************************************
* DemuxClose:
* DemuxClose:
*****************************************************************************/
*****************************************************************************/
static
void
Demux
Close
(
vlc_object_t
*
p_this
)
static
void
Close
(
vlc_object_t
*
p_this
)
{
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
...
@@ -775,7 +618,8 @@ static int Demux( demux_t *p_demux )
...
@@ -775,7 +618,8 @@ static int Demux( demux_t *p_demux )
p_sys
->
i_pcr
=
i_pcr
;
p_sys
->
i_pcr
=
i_pcr
;
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
i_pcr
);
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
i_pcr
);
if
(
p_sys
->
i_pcr_start
<=
0
||
p_sys
->
i_pcr_start
>
i_pcr
)
if
(
p_sys
->
i_pcr_start
<=
0
||
p_sys
->
i_pcr_start
>
i_pcr
||
(
p_sys
->
i_length
>
0
&&
i_pcr
-
p_sys
->
i_pcr_start
>
p_sys
->
i_length
)
)
{
{
p_sys
->
i_pcr_start
=
i_pcr
;
p_sys
->
i_pcr_start
=
i_pcr
;
}
}
...
@@ -835,6 +679,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
...
@@ -835,6 +679,7 @@ 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
;
int64_t
*
pi64
;
int64_t
*
pi64
;
double
*
pf
,
f
;
double
*
pf
,
f
;
vlc_bool_t
*
pb
;
switch
(
i_query
)
switch
(
i_query
)
{
{
...
@@ -891,6 +736,25 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
...
@@ -891,6 +736,25 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
/* Special for access_demux */
case
DEMUX_CAN_PAUSE
:
case
DEMUX_CAN_CONTROL_PACE
:
/* TODO */
pb
=
(
vlc_bool_t
*
)
va_arg
(
args
,
vlc_bool_t
*
);
*
pb
=
VLC_FALSE
;
return
VLC_SUCCESS
;
case
DEMUX_SET_PAUSE_STATE
:
case
DEMUX_GET_TITLE_INFO
:
case
DEMUX_SET_TITLE
:
case
DEMUX_SET_SEEKPOINT
:
return
VLC_EGENERIC
;
case
DEMUX_GET_PTS_DELAY
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi64
=
(
int64_t
)
var_GetInteger
(
p_demux
,
"rtsp-caching"
)
*
I64C
(
1000
);
return
VLC_SUCCESS
;
default:
default:
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
...
...
modules/demux/mkv.cpp
View file @
d82e9eb7
...
@@ -51,11 +51,7 @@
...
@@ -51,11 +51,7 @@
#include "ebml/EbmlVoid.h"
#include "ebml/EbmlVoid.h"
#include "matroska/FileKax.h"
#include "matroska/FileKax.h"
#ifdef HAVE_MATROSKA_KAXATTACHMENTS_H
#include "matroska/KaxAttachments.h"
#include "matroska/KaxAttachments.h"
#else
#include "matroska/KaxAttachements.h"
#endif
#include "matroska/KaxBlock.h"
#include "matroska/KaxBlock.h"
#include "matroska/KaxBlockData.h"
#include "matroska/KaxBlockData.h"
#include "matroska/KaxChapters.h"
#include "matroska/KaxChapters.h"
...
@@ -146,7 +142,7 @@ class EbmlParser
...
@@ -146,7 +142,7 @@ class EbmlParser
private:
private:
EbmlStream
*
m_es
;
EbmlStream
*
m_es
;
int
mi_level
;
int
mi_level
;
EbmlElement
*
m_el
[
6
];
EbmlElement
*
m_el
[
10
];
EbmlElement
*
m_got
;
EbmlElement
*
m_got
;
...
@@ -253,15 +249,24 @@ struct demux_sys_t
...
@@ -253,15 +249,24 @@ struct demux_sys_t
char
*
psz_date_utc
;
char
*
psz_date_utc
;
vlc_meta_t
*
meta
;
vlc_meta_t
*
meta
;
input_title_t
*
title
;
};
};
#define MKVD_TIMECODESCALE 1000000
#define MKVD_TIMECODESCALE 1000000
#define MKV_IS_ID( el, C ) ( EbmlId( (*el) ) == C::ClassInfos.GlobalId )
static
void
IndexAppendCluster
(
demux_t
*
p_demux
,
KaxCluster
*
cluster
);
static
void
IndexAppendCluster
(
demux_t
*
p_demux
,
KaxCluster
*
cluster
);
static
char
*
UTF8ToStr
(
const
UTFstring
&
u
);
static
char
*
UTF8ToStr
(
const
UTFstring
&
u
);
static
void
LoadCues
(
demux_t
*
);
static
void
LoadCues
(
demux_t
*
);
static
void
InformationsCreate
(
demux_t
*
);
static
void
InformationsCreate
(
demux_t
*
);
static
void
ParseInfo
(
demux_t
*
,
EbmlElement
*
info
);
static
void
ParseTracks
(
demux_t
*
,
EbmlElement
*
tracks
);
static
void
ParseSeekHead
(
demux_t
*
,
EbmlElement
*
seekhead
);
static
void
ParseChapters
(
demux_t
*
,
EbmlElement
*
chapters
);
/*****************************************************************************
/*****************************************************************************
* Open: initializes matroska demux structures
* Open: initializes matroska demux structures
*****************************************************************************/
*****************************************************************************/
...
@@ -273,7 +278,7 @@ static int Open( vlc_object_t * p_this )
...
@@ -273,7 +278,7 @@ static int Open( vlc_object_t * p_this )
int
i_track
;
int
i_track
;
EbmlElement
*
el
=
NULL
,
*
el1
=
NULL
,
*
el2
=
NULL
,
*
el3
=
NULL
,
*
el4
=
NULL
;
EbmlElement
*
el
=
NULL
,
*
el1
=
NULL
;
/* peek the begining */
/* peek the begining */
if
(
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
4
)
<
4
)
if
(
stream_Peek
(
p_demux
->
s
,
&
p_peek
,
4
)
<
4
)
...
@@ -321,6 +326,7 @@ static int Open( vlc_object_t * p_this )
...
@@ -321,6 +326,7 @@ static int Open( vlc_object_t * p_this )
p_sys
->
psz_title
=
NULL
;
p_sys
->
psz_title
=
NULL
;
p_sys
->
psz_date_utc
=
NULL
;;
p_sys
->
psz_date_utc
=
NULL
;;
p_sys
->
meta
=
NULL
;
p_sys
->
meta
=
NULL
;
p_sys
->
title
=
NULL
;
if
(
p_sys
->
es
==
NULL
)
if
(
p_sys
->
es
==
NULL
)
{
{
...
@@ -356,560 +362,23 @@ static int Open( vlc_object_t * p_this )
...
@@ -356,560 +362,23 @@ static int Open( vlc_object_t * p_this )
while
(
(
el1
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
while
(
(
el1
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
{
if
(
EbmlId
(
*
el1
)
==
KaxInfo
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el1
,
KaxInfo
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Informations"
);
ParseInfo
(
p_demux
,
el1
);
p_sys
->
ep
->
Down
();
while
(
(
el2
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
if
(
EbmlId
(
*
el2
)
==
KaxTimecodeScale
::
ClassInfos
.
GlobalId
)
{
KaxTimecodeScale
&
tcs
=
*
(
KaxTimecodeScale
*
)
el2
;
tcs
.
ReadData
(
p_sys
->
es
->
I_O
()
);
p_sys
->
i_timescale
=
uint64
(
tcs
);
msg_Dbg
(
p_demux
,
"| | + TimecodeScale="
I64Fd
,
p_sys
->
i_timescale
);
}
else
if
(
EbmlId
(
*
el2
)
==
KaxDuration
::
ClassInfos
.
GlobalId
)
{
KaxDuration
&
dur
=
*
(
KaxDuration
*
)
el2
;
dur
.
ReadData
(
p_sys
->
es
->
I_O
()
);
p_sys
->
f_duration
=
float
(
dur
);
msg_Dbg
(
p_demux
,
"| | + Duration=%f"
,
p_sys
->
f_duration
);
}
else
if
(
EbmlId
(
*
el2
)
==
KaxMuxingApp
::
ClassInfos
.
GlobalId
)
{
KaxMuxingApp
&
mapp
=
*
(
KaxMuxingApp
*
)
el2
;
mapp
.
ReadData
(
p_sys
->
es
->
I_O
()
);
p_sys
->
psz_muxing_application
=
UTF8ToStr
(
UTFstring
(
mapp
)
);
msg_Dbg
(
p_demux
,
"| | + Muxing Application=%s"
,
p_sys
->
psz_muxing_application
);
}
else
if
(
EbmlId
(
*
el2
)
==
KaxWritingApp
::
ClassInfos
.
GlobalId
)
{
KaxWritingApp
&
wapp
=
*
(
KaxWritingApp
*
)
el2
;
wapp
.
ReadData
(
p_sys
->
es
->
I_O
()
);
p_sys
->
psz_writing_application
=
UTF8ToStr
(
UTFstring
(
wapp
)
);
msg_Dbg
(
p_demux
,
"| | + Writing Application=%s"
,
p_sys
->
psz_writing_application
);
}
else
if
(
EbmlId
(
*
el2
)
==
KaxSegmentFilename
::
ClassInfos
.
GlobalId
)
{
KaxSegmentFilename
&
sfn
=
*
(
KaxSegmentFilename
*
)
el2
;
sfn
.
ReadData
(
p_sys
->
es
->
I_O
()
);
p_sys
->
psz_segment_filename
=
UTF8ToStr
(
UTFstring
(
sfn
)
);
msg_Dbg
(
p_demux
,
"| | + Segment Filename=%s"
,
p_sys
->
psz_segment_filename
);
}
else
if
(
EbmlId
(
*
el2
)
==
KaxTitle
::
ClassInfos
.
GlobalId
)
{
KaxTitle
&
title
=
*
(
KaxTitle
*
)
el2
;
title
.
ReadData
(
p_sys
->
es
->
I_O
()
);
p_sys
->
psz_title
=
UTF8ToStr
(
UTFstring
(
title
)
);
msg_Dbg
(
p_demux
,
"| | + Title=%s"
,
p_sys
->
psz_title
);
}
#if defined( HAVE_GMTIME_R ) && !defined( SYS_DARWIN )
else
if
(
EbmlId
(
*
el2
)
==
KaxDateUTC
::
ClassInfos
.
GlobalId
)
{
KaxDateUTC
&
date
=
*
(
KaxDateUTC
*
)
el2
;
time_t
i_date
;
struct
tm
tmres
;
char
buffer
[
256
];
date
.
ReadData
(
p_sys
->
es
->
I_O
()
);
i_date
=
date
.
GetEpochDate
();
memset
(
buffer
,
0
,
256
);
if
(
gmtime_r
(
&
i_date
,
&
tmres
)
&&
asctime_r
(
&
tmres
,
buffer
)
)
{
buffer
[
strlen
(
buffer
)
-
1
]
=
'\0'
;
p_sys
->
psz_date_utc
=
strdup
(
buffer
);
msg_Dbg
(
p_demux
,
"| | + Date=%s"
,
p_sys
->
psz_date_utc
);
}
}
#endif
else
{
msg_Dbg
(
p_demux
,
"| | + Unknown (%s)"
,
typeid
(
*
el2
).
name
()
);
}
}
p_sys
->
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el1
)
==
KaxTracks
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el1
,
KaxTracks
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Tracks"
);
ParseTracks
(
p_demux
,
el1
);
p_sys
->
ep
->
Down
();
while
(
(
el2
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
if
(
EbmlId
(
*
el2
)
==
KaxTrackEntry
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | + Track Entry"
);
p_sys
->
i_track
++
;
p_sys
->
track
=
(
mkv_track_t
*
)
realloc
(
p_sys
->
track
,
sizeof
(
mkv_track_t
)
*
(
p_sys
->
i_track
+
1
)
);
#define tk p_sys->track[p_sys->i_track - 1]
memset
(
&
tk
,
0
,
sizeof
(
mkv_track_t
)
);
es_format_Init
(
&
tk
.
fmt
,
UNKNOWN_ES
,
0
);
tk
.
fmt
.
psz_language
=
strdup
(
"English"
);
tk
.
fmt
.
psz_description
=
NULL
;
tk
.
b_default
=
VLC_TRUE
;
tk
.
b_enabled
=
VLC_TRUE
;
tk
.
i_number
=
p_sys
->
i_track
-
1
;
tk
.
i_extra_data
=
0
;
tk
.
p_extra_data
=
NULL
;
tk
.
psz_codec
=
NULL
;
tk
.
i_default_duration
=
0
;
tk
.
f_timecodescale
=
1.0
;
tk
.
b_inited
=
VLC_FALSE
;
tk
.
i_data_init
=
0
;
tk
.
p_data_init
=
NULL
;
tk
.
psz_codec_name
=
NULL
;
tk
.
psz_codec_settings
=
NULL
;
tk
.
psz_codec_info_url
=
NULL
;
tk
.
psz_codec_download_url
=
NULL
;
p_sys
->
ep
->
Down
();
while
(
(
el3
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
if
(
EbmlId
(
*
el3
)
==
KaxTrackNumber
::
ClassInfos
.
GlobalId
)
{
KaxTrackNumber
&
tnum
=
*
(
KaxTrackNumber
*
)
el3
;
tnum
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
i_number
=
uint32
(
tnum
);
msg_Dbg
(
p_demux
,
"| | | + Track Number=%u"
,
uint32
(
tnum
)
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackUID
::
ClassInfos
.
GlobalId
)
{
KaxTrackUID
&
tuid
=
*
(
KaxTrackUID
*
)
el3
;
tuid
.
ReadData
(
p_sys
->
es
->
I_O
()
);
msg_Dbg
(
p_demux
,
"| | | + Track UID=%u"
,
uint32
(
tuid
)
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackType
::
ClassInfos
.
GlobalId
)
{
char
*
psz_type
;
KaxTrackType
&
ttype
=
*
(
KaxTrackType
*
)
el3
;
ttype
.
ReadData
(
p_sys
->
es
->
I_O
()
);
switch
(
uint8
(
ttype
)
)
{
case
track_audio
:
psz_type
=
"audio"
;
tk
.
fmt
.
i_cat
=
AUDIO_ES
;
break
;
case
track_video
:
psz_type
=
"video"
;
tk
.
fmt
.
i_cat
=
VIDEO_ES
;
break
;
case
track_subtitle
:
psz_type
=
"subtitle"
;
tk
.
fmt
.
i_cat
=
SPU_ES
;
break
;
default:
psz_type
=
"unknown"
;
tk
.
fmt
.
i_cat
=
UNKNOWN_ES
;
break
;
}
msg_Dbg
(
p_demux
,
"| | | + Track Type=%s"
,
psz_type
);
}
// else if( EbmlId( *el3 ) == KaxTrackFlagEnabled::ClassInfos.GlobalId )
// {
// KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)el3;
// fenb.ReadData( p_sys->es->I_O() );
// tk.b_enabled = uint32( fenb );
// msg_Dbg( p_demux, "| | | + Track Enabled=%u",
// uint32( fenb ) );
// }
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackFlagDefault
::
ClassInfos
.
GlobalId
)
{
KaxTrackFlagDefault
&
fdef
=
*
(
KaxTrackFlagDefault
*
)
el3
;
fdef
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
b_default
=
uint32
(
fdef
);
msg_Dbg
(
p_demux
,
"| | | + Track Default=%u"
,
uint32
(
fdef
)
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackFlagLacing
::
ClassInfos
.
GlobalId
)
{
KaxTrackFlagLacing
&
lac
=
*
(
KaxTrackFlagLacing
*
)
el3
;
lac
.
ReadData
(
p_sys
->
es
->
I_O
()
);
msg_Dbg
(
p_demux
,
"| | | + Track Lacing=%d"
,
uint32
(
lac
)
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackMinCache
::
ClassInfos
.
GlobalId
)
{
KaxTrackMinCache
&
cmin
=
*
(
KaxTrackMinCache
*
)
el3
;
cmin
.
ReadData
(
p_sys
->
es
->
I_O
()
);
msg_Dbg
(
p_demux
,
"| | | + Track MinCache=%d"
,
uint32
(
cmin
)
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackMaxCache
::
ClassInfos
.
GlobalId
)
{
KaxTrackMaxCache
&
cmax
=
*
(
KaxTrackMaxCache
*
)
el3
;
cmax
.
ReadData
(
p_sys
->
es
->
I_O
()
);
msg_Dbg
(
p_demux
,
"| | | + Track MaxCache=%d"
,
uint32
(
cmax
)
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackDefaultDuration
::
ClassInfos
.
GlobalId
)
{
KaxTrackDefaultDuration
&
defd
=
*
(
KaxTrackDefaultDuration
*
)
el3
;
defd
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
i_default_duration
=
uint64
(
defd
);
msg_Dbg
(
p_demux
,
"| | | + Track Default Duration="
I64Fd
,
uint64
(
defd
)
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackTimecodeScale
::
ClassInfos
.
GlobalId
)
{
KaxTrackTimecodeScale
&
ttcs
=
*
(
KaxTrackTimecodeScale
*
)
el3
;
ttcs
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
f_timecodescale
=
float
(
ttcs
);
msg_Dbg
(
p_demux
,
"| | | + Track TimeCodeScale=%f"
,
tk
.
f_timecodescale
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackName
::
ClassInfos
.
GlobalId
)
{
KaxTrackName
&
tname
=
*
(
KaxTrackName
*
)
el3
;
tname
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
psz_description
=
UTF8ToStr
(
UTFstring
(
tname
)
);
msg_Dbg
(
p_demux
,
"| | | + Track Name=%s"
,
tk
.
fmt
.
psz_description
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackLanguage
::
ClassInfos
.
GlobalId
)
{
KaxTrackLanguage
&
lang
=
*
(
KaxTrackLanguage
*
)
el3
;
lang
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
psz_language
=
strdup
(
string
(
lang
).
c_str
()
);
msg_Dbg
(
p_demux
,
"| | | + Track Language=`%s'"
,
tk
.
fmt
.
psz_language
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxCodecID
::
ClassInfos
.
GlobalId
)
{
KaxCodecID
&
codecid
=
*
(
KaxCodecID
*
)
el3
;
codecid
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
psz_codec
=
strdup
(
string
(
codecid
).
c_str
()
);
msg_Dbg
(
p_demux
,
"| | | + Track CodecId=%s"
,
string
(
codecid
).
c_str
()
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxCodecPrivate
::
ClassInfos
.
GlobalId
)
{
KaxCodecPrivate
&
cpriv
=
*
(
KaxCodecPrivate
*
)
el3
;
cpriv
.
ReadData
(
p_sys
->
es
->
I_O
(),
SCOPE_ALL_DATA
);
tk
.
i_extra_data
=
cpriv
.
GetSize
();
if
(
tk
.
i_extra_data
>
0
)
{
tk
.
p_extra_data
=
(
uint8_t
*
)
malloc
(
tk
.
i_extra_data
);
memcpy
(
tk
.
p_extra_data
,
cpriv
.
GetBuffer
(),
tk
.
i_extra_data
);
}
msg_Dbg
(
p_demux
,
"| | | + Track CodecPrivate size="
I64Fd
,
cpriv
.
GetSize
()
);
}
else
if
(
EbmlId
(
*
el3
)
==
KaxCodecName
::
ClassInfos
.
GlobalId
)
{
KaxCodecName
&
cname
=
*
(
KaxCodecName
*
)
el3
;
cname
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
psz_codec_name
=
UTF8ToStr
(
UTFstring
(
cname
)
);
msg_Dbg
(
p_demux
,
"| | | + Track Codec Name=%s"
,
tk
.
psz_codec_name
);
}
// else if( EbmlId( *el3 ) == KaxCodecSettings::ClassInfos.GlobalId )
// {
// KaxCodecSettings &cset = *(KaxCodecSettings*)el3;
// cset.ReadData( p_sys->es->I_O() );
// tk.psz_codec_settings = UTF8ToStr( UTFstring( cset ) );
// msg_Dbg( p_demux, "| | | + Track Codec Settings=%s", tk.psz_codec_settings );
// }
// else if( EbmlId( *el3 ) == KaxCodecInfoURL::ClassInfos.GlobalId )
// {
// KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)el3;
// ciurl.ReadData( p_sys->es->I_O() );
// tk.psz_codec_info_url = strdup( string( ciurl ).c_str() );
// msg_Dbg( p_demux, "| | | + Track Codec Info URL=%s", tk.psz_codec_info_url );
// }
// else if( EbmlId( *el3 ) == KaxCodecDownloadURL::ClassInfos.GlobalId )
// {
// KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)el3;
// cdurl.ReadData( p_sys->es->I_O() );
// tk.psz_codec_download_url = strdup( string( cdurl ).c_str() );
// msg_Dbg( p_demux, "| | | + Track Codec Info URL=%s", tk.psz_codec_download_url );
// }
// else if( EbmlId( *el3 ) == KaxCodecDecodeAll::ClassInfos.GlobalId )
// {
// KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)el3;
// cdall.ReadData( p_sys->es->I_O() );
// msg_Dbg( p_demux, "| | | + Track Codec Decode All=%u <== UNUSED", uint8( cdall ) );
// }
// else if( EbmlId( *el3 ) == KaxTrackOverlay::ClassInfos.GlobalId )
// {
// KaxTrackOverlay &tovr = *(KaxTrackOverlay*)el3;
// tovr.ReadData( p_sys->es->I_O() );
// msg_Dbg( p_demux, "| | | + Track Overlay=%u <== UNUSED", uint32( tovr ) );
// }
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackVideo
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | + Track Video"
);
tk
.
f_fps
=
0.0
;
p_sys
->
ep
->
Down
();
while
(
(
el4
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
// if( EbmlId( *el4 ) == KaxVideoFlagInterlaced::ClassInfos.GlobalId )
// {
// KaxVideoFlagInterlaced &fint = *(KaxVideoFlagInterlaced*)el4;
// fint.ReadData( p_sys->es->I_O() );
// msg_Dbg( p_demux, "| | | | + Track Video Interlaced=%u", uint8( fint ) );
// }
// else if( EbmlId( *el4 ) == KaxVideoStereoMode::ClassInfos.GlobalId )
// {
// KaxVideoStereoMode &stereo = *(KaxVideoStereoMode*)el4;
// stereo.ReadData( p_sys->es->I_O() );
// msg_Dbg( p_demux, "| | | | + Track Video Stereo Mode=%u", uint8( stereo ) );
// }
// else
if
(
EbmlId
(
*
el4
)
==
KaxVideoPixelWidth
::
ClassInfos
.
GlobalId
)
{
KaxVideoPixelWidth
&
vwidth
=
*
(
KaxVideoPixelWidth
*
)
el4
;
vwidth
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
video
.
i_width
=
uint16
(
vwidth
);
msg_Dbg
(
p_demux
,
"| | | | + width=%d"
,
uint16
(
vwidth
)
);
}
else
if
(
EbmlId
(
*
el4
)
==
KaxVideoPixelHeight
::
ClassInfos
.
GlobalId
)
{
KaxVideoPixelWidth
&
vheight
=
*
(
KaxVideoPixelWidth
*
)
el4
;
vheight
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
video
.
i_height
=
uint16
(
vheight
);
msg_Dbg
(
p_demux
,
"| | | | + height=%d"
,
uint16
(
vheight
)
);
}
else
if
(
EbmlId
(
*
el4
)
==
KaxVideoDisplayWidth
::
ClassInfos
.
GlobalId
)
{
KaxVideoDisplayWidth
&
vwidth
=
*
(
KaxVideoDisplayWidth
*
)
el4
;
vwidth
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
video
.
i_visible_width
=
uint16
(
vwidth
);
msg_Dbg
(
p_demux
,
"| | | | + display width=%d"
,
uint16
(
vwidth
)
);
}
else
if
(
EbmlId
(
*
el4
)
==
KaxVideoDisplayHeight
::
ClassInfos
.
GlobalId
)
{
KaxVideoDisplayWidth
&
vheight
=
*
(
KaxVideoDisplayWidth
*
)
el4
;
vheight
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
video
.
i_visible_height
=
uint16
(
vheight
);
msg_Dbg
(
p_demux
,
"| | | | + display height=%d"
,
uint16
(
vheight
)
);
}
else
if
(
EbmlId
(
*
el4
)
==
KaxVideoFrameRate
::
ClassInfos
.
GlobalId
)
{
KaxVideoFrameRate
&
vfps
=
*
(
KaxVideoFrameRate
*
)
el4
;
vfps
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
f_fps
=
float
(
vfps
);
msg_Dbg
(
p_demux
,
" | | | + fps=%f"
,
float
(
vfps
)
);
}
// else if( EbmlId( *el4 ) == KaxVideoDisplayUnit::ClassInfos.GlobalId )
// {
// KaxVideoDisplayUnit &vdmode = *(KaxVideoDisplayUnit*)el4;
// vdmode.ReadData( p_sys->es->I_O() );
// msg_Dbg( p_demux, "| | | | + Track Video Display Unit=%s",
// uint8( vdmode ) == 0 ? "pixels" : ( uint8( vdmode ) == 1 ? "centimeters": "inches" ) );
// }
// else if( EbmlId( *el4 ) == KaxVideoAspectRatio::ClassInfos.GlobalId )
// {
// KaxVideoAspectRatio &ratio = *(KaxVideoAspectRatio*)el4;
// ratio.ReadData( p_sys->es->I_O() );
// msg_Dbg( p_demux, " | | | + Track Video Aspect Ratio Type=%u", uint8( ratio ) );
// }
// else if( EbmlId( *el4 ) == KaxVideoGamma::ClassInfos.GlobalId )
// {
// KaxVideoGamma &gamma = *(KaxVideoGamma*)el4;
// gamma.ReadData( p_sys->es->I_O() );
// msg_Dbg( p_demux, " | | | + fps=%f", float( gamma ) );
// }
else
{
msg_Dbg
(
p_demux
,
"| | | | + Unknown (%s)"
,
typeid
(
*
el4
).
name
()
);
}
}
p_sys
->
ep
->
Up
();
}
else
if
(
EbmlId
(
*
el3
)
==
KaxTrackAudio
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | + Track Audio"
);
p_sys
->
ep
->
Down
();
while
(
(
el4
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
if
(
EbmlId
(
*
el4
)
==
KaxAudioSamplingFreq
::
ClassInfos
.
GlobalId
)
{
KaxAudioSamplingFreq
&
afreq
=
*
(
KaxAudioSamplingFreq
*
)
el4
;
afreq
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
audio
.
i_rate
=
(
int
)
float
(
afreq
);
msg_Dbg
(
p_demux
,
"| | | | + afreq=%d"
,
tk
.
fmt
.
audio
.
i_rate
);
}
else
if
(
EbmlId
(
*
el4
)
==
KaxAudioChannels
::
ClassInfos
.
GlobalId
)
{
KaxAudioChannels
&
achan
=
*
(
KaxAudioChannels
*
)
el4
;
achan
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
audio
.
i_channels
=
uint8
(
achan
);
msg_Dbg
(
p_demux
,
"| | | | + achan=%u"
,
uint8
(
achan
)
);
}
else
if
(
EbmlId
(
*
el4
)
==
KaxAudioBitDepth
::
ClassInfos
.
GlobalId
)
{
KaxAudioBitDepth
&
abits
=
*
(
KaxAudioBitDepth
*
)
el4
;
abits
.
ReadData
(
p_sys
->
es
->
I_O
()
);
tk
.
fmt
.
audio
.
i_bitspersample
=
uint8
(
abits
);
msg_Dbg
(
p_demux
,
"| | | | + abits=%u"
,
uint8
(
abits
)
);
}
else
{
msg_Dbg
(
p_demux
,
"| | | | + Unknown (%s)"
,
typeid
(
*
el4
).
name
()
);
}
}
p_sys
->
ep
->
Up
();
}
else
{
msg_Dbg
(
p_demux
,
"| | | + Unknown (%s)"
,
typeid
(
*
el3
).
name
()
);
}
}
p_sys
->
ep
->
Up
();
}
else
{
msg_Dbg
(
p_demux
,
"| | + Unknown (%s)"
,
typeid
(
*
el2
).
name
()
);
}
#undef tk
}
p_sys
->
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el1
)
==
KaxSeekHead
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el1
,
KaxSeekHead
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Seek head"
);
ParseSeekHead
(
p_demux
,
el1
);
p_sys
->
ep
->
Down
();
while
(
(
el
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
if
(
EbmlId
(
*
el
)
==
KaxSeek
::
ClassInfos
.
GlobalId
)
{
EbmlId
id
=
EbmlVoid
::
ClassInfos
.
GlobalId
;
int64_t
i_pos
=
-
1
;
//msg_Dbg( p_demux, "| | + Seek" );
p_sys
->
ep
->
Down
();
while
(
(
el
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
if
(
EbmlId
(
*
el
)
==
KaxSeekID
::
ClassInfos
.
GlobalId
)
{
KaxSeekID
&
sid
=
*
(
KaxSeekID
*
)
el
;
sid
.
ReadData
(
p_sys
->
es
->
I_O
(),
SCOPE_ALL_DATA
);
id
=
EbmlId
(
sid
.
GetBuffer
(),
sid
.
GetSize
()
);
}
else
if
(
EbmlId
(
*
el
)
==
KaxSeekPosition
::
ClassInfos
.
GlobalId
)
{
KaxSeekPosition
&
spos
=
*
(
KaxSeekPosition
*
)
el
;
spos
.
ReadData
(
p_sys
->
es
->
I_O
(),
SCOPE_ALL_DATA
);
i_pos
=
uint64
(
spos
);
}
else
{
msg_Dbg
(
p_demux
,
"| | | + Unknown (%s)"
,
typeid
(
*
el
).
name
()
);
}
}
p_sys
->
ep
->
Up
();
if
(
i_pos
>=
0
)
{
if
(
id
==
KaxCues
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = cues at "
I64Fd
,
i_pos
);
p_sys
->
i_cues_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
}
else
if
(
id
==
KaxChapters
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = chapters at "
I64Fd
,
i_pos
);
p_sys
->
i_chapters_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
}
else
if
(
id
==
KaxTags
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = tags at "
I64Fd
,
i_pos
);
p_sys
->
i_tags_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
}
}
}
else
{
msg_Dbg
(
p_demux
,
"| | + Unknown (%s)"
,
typeid
(
*
el
).
name
()
);
}
}
p_sys
->
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el1
)
==
KaxCues
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el1
,
KaxCues
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Cues"
);
msg_Dbg
(
p_demux
,
"| + Cues"
);
}
}
else
if
(
EbmlId
(
*
el1
)
==
KaxCluster
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el1
,
KaxCluster
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Cluster"
);
msg_Dbg
(
p_demux
,
"| + Cluster"
);
...
@@ -919,19 +388,16 @@ static int Open( vlc_object_t * p_this )
...
@@ -919,19 +388,16 @@ static int Open( vlc_object_t * p_this )
/* stop parsing the stream */
/* stop parsing the stream */
break
;
break
;
}
}
#ifdef HAVE_MATROSKA_KAXATTACHMENTS_H
else
if
(
MKV_IS_ID
(
el1
,
KaxAttachments
)
)
else
if
(
EbmlId
(
*
el1
)
==
KaxAttachments
::
ClassInfos
.
GlobalId
)
#else
else
if
(
EbmlId
(
*
el1
)
==
KaxAttachements
::
ClassInfos
.
GlobalId
)
#endif
{
{
msg_Dbg
(
p_demux
,
"| + Attachments FIXME TODO (but probably never supported)"
);
msg_Dbg
(
p_demux
,
"| + Attachments FIXME TODO (but probably never supported)"
);
}
}
else
if
(
EbmlId
(
*
el1
)
==
KaxChapters
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el1
,
KaxChapters
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Chapters FIXME TODO"
);
msg_Dbg
(
p_demux
,
"| + Chapters"
);
ParseChapters
(
p_demux
,
el1
);
}
}
else
if
(
EbmlId
(
*
el1
)
==
KaxTag
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el1
,
KaxTag
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Tags FIXME TODO"
);
msg_Dbg
(
p_demux
,
"| + Tags FIXME TODO"
);
}
}
...
@@ -947,11 +413,6 @@ static int Open( vlc_object_t * p_this )
...
@@ -947,11 +413,6 @@ static int Open( vlc_object_t * p_this )
goto
error
;
goto
error
;
}
}
if
(
p_sys
->
i_chapters_position
>=
0
)
{
msg_Warn
(
p_demux
,
"chapters unsupported"
);
}
/* *** Load the cue if found *** */
/* *** Load the cue if found *** */
if
(
p_sys
->
i_cues_position
>=
0
)
if
(
p_sys
->
i_cues_position
>=
0
)
{
{
...
@@ -1256,7 +717,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
...
@@ -1256,7 +717,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
case
DEMUX_SET_POSITION
:
case
DEMUX_SET_POSITION
:
f
=
(
double
)
va_arg
(
args
,
double
);
f
=
(
double
)
va_arg
(
args
,
double
);
Seek
(
p_demux
,
-
1
,
(
int
)(
100.0
*
f
)
);
Seek
(
p_demux
,
-
1
,
(
int
)(
100.0
*
f
)
);
return
VLC_
EGENERIC
;
return
VLC_
SUCCESS
;
case
DEMUX_GET_TIME
:
case
DEMUX_GET_TIME
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
...
@@ -1273,6 +734,45 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
...
@@ -1273,6 +734,45 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
}
}
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
case
DEMUX_GET_TITLE_INFO
:
if
(
p_sys
->
title
&&
p_sys
->
title
->
i_seekpoint
>
0
)
{
input_title_t
***
ppp_title
=
(
input_title_t
***
)
va_arg
(
args
,
input_title_t
***
);
int
*
pi_int
=
(
int
*
)
va_arg
(
args
,
int
*
);
*
pi_int
=
1
;
*
ppp_title
=
(
input_title_t
**
)
malloc
(
sizeof
(
input_title_t
**
)
);
(
*
ppp_title
)[
0
]
=
vlc_input_title_Duplicate
(
p_sys
->
title
);
return
VLC_SUCCESS
;
}
return
VLC_EGENERIC
;
case
DEMUX_SET_TITLE
:
if
(
p_sys
->
title
&&
p_sys
->
title
->
i_seekpoint
>
0
)
{
return
VLC_SUCCESS
;
}
return
VLC_EGENERIC
;
case
DEMUX_SET_SEEKPOINT
:
/* FIXME do a better implementation */
if
(
p_sys
->
title
&&
p_sys
->
title
->
i_seekpoint
>
0
)
{
int
i_skp
=
(
int
)
va_arg
(
args
,
int
);
int64_t
i_start
=
(
int64_t
)
p_sys
->
title
->
seekpoint
[
i_skp
]
->
i_time_offset
;
if
(
p_sys
->
f_duration
>
0.0
)
{
double
f_pos
=
(
double
)
i_start
/
(
double
)(
1000.0
*
p_sys
->
f_duration
);
Seek
(
p_demux
,
-
1
,
(
int
)(
100
*
f_pos
+
0.5
));
return
VLC_SUCCESS
;
}
}
return
VLC_EGENERIC
;
case
DEMUX_SET_TIME
:
case
DEMUX_SET_TIME
:
case
DEMUX_GET_FPS
:
case
DEMUX_GET_FPS
:
default:
default:
...
@@ -1328,7 +828,7 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
...
@@ -1328,7 +828,7 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
/* do parsing */
/* do parsing */
if
(
i_level
==
1
)
if
(
i_level
==
1
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxCluster
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxCluster
)
)
{
{
p_sys
->
cluster
=
(
KaxCluster
*
)
el
;
p_sys
->
cluster
=
(
KaxCluster
*
)
el
;
...
@@ -1341,7 +841,7 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
...
@@ -1341,7 +841,7 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
p_sys
->
ep
->
Down
();
p_sys
->
ep
->
Down
();
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxCues
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxCues
)
)
{
{
msg_Warn
(
p_demux
,
"find KaxCues FIXME"
);
msg_Warn
(
p_demux
,
"find KaxCues FIXME"
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
...
@@ -1353,21 +853,21 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
...
@@ -1353,21 +853,21 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
}
}
else
if
(
i_level
==
2
)
else
if
(
i_level
==
2
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxClusterTimecode
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxClusterTimecode
)
)
{
{
KaxClusterTimecode
&
ctc
=
*
(
KaxClusterTimecode
*
)
el
;
KaxClusterTimecode
&
ctc
=
*
(
KaxClusterTimecode
*
)
el
;
ctc
.
ReadData
(
p_sys
->
es
->
I_O
(),
SCOPE_ALL_DATA
);
ctc
.
ReadData
(
p_sys
->
es
->
I_O
(),
SCOPE_ALL_DATA
);
p_sys
->
cluster
->
InitTimecode
(
uint64
(
ctc
),
p_sys
->
i_timescale
);
p_sys
->
cluster
->
InitTimecode
(
uint64
(
ctc
),
p_sys
->
i_timescale
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxBlockGroup
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxBlockGroup
)
)
{
{
p_sys
->
ep
->
Down
();
p_sys
->
ep
->
Down
();
}
}
}
}
else
if
(
i_level
==
3
)
else
if
(
i_level
==
3
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxBlock
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxBlock
)
)
{
{
*
pp_block
=
(
KaxBlock
*
)
el
;
*
pp_block
=
(
KaxBlock
*
)
el
;
...
@@ -1376,14 +876,14 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
...
@@ -1376,14 +876,14 @@ static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, in
p_sys
->
ep
->
Keep
();
p_sys
->
ep
->
Keep
();
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxBlockDuration
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxBlockDuration
)
)
{
{
KaxBlockDuration
&
dur
=
*
(
KaxBlockDuration
*
)
el
;
KaxBlockDuration
&
dur
=
*
(
KaxBlockDuration
*
)
el
;
dur
.
ReadData
(
p_sys
->
es
->
I_O
()
);
dur
.
ReadData
(
p_sys
->
es
->
I_O
()
);
*
pi_duration
=
uint64
(
dur
);
*
pi_duration
=
uint64
(
dur
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxReferenceBlock
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxReferenceBlock
)
)
{
{
KaxReferenceBlock
&
ref
=
*
(
KaxReferenceBlock
*
)
el
;
KaxReferenceBlock
&
ref
=
*
(
KaxReferenceBlock
*
)
el
;
...
@@ -1558,6 +1058,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, int i_percent)
...
@@ -1558,6 +1058,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, int i_percent)
{
{
return
;
return
;
}
}
if
(
i_percent
>
100
)
i_percent
=
100
;
delete
p_sys
->
ep
;
delete
p_sys
->
ep
;
p_sys
->
ep
=
new
EbmlParser
(
p_sys
->
es
,
p_sys
->
segment
);
p_sys
->
ep
=
new
EbmlParser
(
p_sys
->
es
,
p_sys
->
segment
);
...
@@ -1593,7 +1094,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, int i_percent)
...
@@ -1593,7 +1094,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, int i_percent)
/* search a cluster */
/* search a cluster */
while
(
(
el
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
while
(
(
el
=
p_sys
->
ep
->
Get
()
)
!=
NULL
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxCluster
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxCluster
)
)
{
{
KaxCluster
*
cluster
=
(
KaxCluster
*
)
el
;
KaxCluster
*
cluster
=
(
KaxCluster
*
)
el
;
...
@@ -1942,7 +1443,7 @@ static void LoadCues( demux_t *p_demux )
...
@@ -1942,7 +1443,7 @@ static void LoadCues( demux_t *p_demux )
ep
=
new
EbmlParser
(
p_sys
->
es
,
cues
);
ep
=
new
EbmlParser
(
p_sys
->
es
,
cues
);
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxCuePoint
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxCuePoint
)
)
{
{
#define idx p_sys->index[p_sys->i_index]
#define idx p_sys->index[p_sys->i_index]
...
@@ -1955,7 +1456,7 @@ static void LoadCues( demux_t *p_demux )
...
@@ -1955,7 +1456,7 @@ static void LoadCues( demux_t *p_demux )
ep
->
Down
();
ep
->
Down
();
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxCueTime
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxCueTime
)
)
{
{
KaxCueTime
&
ctime
=
*
(
KaxCueTime
*
)
el
;
KaxCueTime
&
ctime
=
*
(
KaxCueTime
*
)
el
;
...
@@ -1963,26 +1464,26 @@ static void LoadCues( demux_t *p_demux )
...
@@ -1963,26 +1464,26 @@ static void LoadCues( demux_t *p_demux )
idx
.
i_time
=
uint64
(
ctime
)
*
(
mtime_t
)
1000000000
/
p_sys
->
i_timescale
;
idx
.
i_time
=
uint64
(
ctime
)
*
(
mtime_t
)
1000000000
/
p_sys
->
i_timescale
;
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxCueTrackPositions
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxCueTrackPositions
)
)
{
{
ep
->
Down
();
ep
->
Down
();
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxCueTrack
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxCueTrack
)
)
{
{
KaxCueTrack
&
ctrack
=
*
(
KaxCueTrack
*
)
el
;
KaxCueTrack
&
ctrack
=
*
(
KaxCueTrack
*
)
el
;
ctrack
.
ReadData
(
p_sys
->
es
->
I_O
()
);
ctrack
.
ReadData
(
p_sys
->
es
->
I_O
()
);
idx
.
i_track
=
uint16
(
ctrack
);
idx
.
i_track
=
uint16
(
ctrack
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxCueClusterPosition
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxCueClusterPosition
)
)
{
{
KaxCueClusterPosition
&
ccpos
=
*
(
KaxCueClusterPosition
*
)
el
;
KaxCueClusterPosition
&
ccpos
=
*
(
KaxCueClusterPosition
*
)
el
;
ccpos
.
ReadData
(
p_sys
->
es
->
I_O
()
);
ccpos
.
ReadData
(
p_sys
->
es
->
I_O
()
);
idx
.
i_position
=
p_sys
->
segment
->
GetGlobalPosition
(
uint64
(
ccpos
)
);
idx
.
i_position
=
p_sys
->
segment
->
GetGlobalPosition
(
uint64
(
ccpos
)
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxCueBlockNumber
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxCueBlockNumber
)
)
{
{
KaxCueBlockNumber
&
cbnum
=
*
(
KaxCueBlockNumber
*
)
el
;
KaxCueBlockNumber
&
cbnum
=
*
(
KaxCueBlockNumber
*
)
el
;
...
@@ -2053,13 +1554,13 @@ static void LoadTags( demux_t *p_demux )
...
@@ -2053,13 +1554,13 @@ static void LoadTags( demux_t *p_demux )
ep
=
new
EbmlParser
(
p_sys
->
es
,
tags
);
ep
=
new
EbmlParser
(
p_sys
->
es
,
tags
);
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxTag
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxTag
)
)
{
{
msg_Dbg
(
p_demux
,
"+ Tag"
);
msg_Dbg
(
p_demux
,
"+ Tag"
);
ep
->
Down
();
ep
->
Down
();
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
while
(
(
el
=
ep
->
Get
()
)
!=
NULL
)
{
{
if
(
EbmlId
(
*
el
)
==
KaxTagTargets
::
ClassInfos
.
GlobalId
)
if
(
MKV_IS_ID
(
el
,
KaxTagTargets
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Targets"
);
msg_Dbg
(
p_demux
,
"| + Targets"
);
ep
->
Down
();
ep
->
Down
();
...
@@ -2069,7 +1570,7 @@ static void LoadTags( demux_t *p_demux )
...
@@ -2069,7 +1570,7 @@ static void LoadTags( demux_t *p_demux )
}
}
ep
->
Up
();
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagGeneral
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagGeneral
)
)
{
{
msg_Dbg
(
p_demux
,
"| + General"
);
msg_Dbg
(
p_demux
,
"| + General"
);
ep
->
Down
();
ep
->
Down
();
...
@@ -2079,7 +1580,7 @@ static void LoadTags( demux_t *p_demux )
...
@@ -2079,7 +1580,7 @@ static void LoadTags( demux_t *p_demux )
}
}
ep
->
Up
();
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagGenres
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagGenres
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Genres"
);
msg_Dbg
(
p_demux
,
"| + Genres"
);
ep
->
Down
();
ep
->
Down
();
...
@@ -2089,7 +1590,7 @@ static void LoadTags( demux_t *p_demux )
...
@@ -2089,7 +1590,7 @@ static void LoadTags( demux_t *p_demux )
}
}
ep
->
Up
();
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagAudioSpecific
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagAudioSpecific
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Audio Specific"
);
msg_Dbg
(
p_demux
,
"| + Audio Specific"
);
ep
->
Down
();
ep
->
Down
();
...
@@ -2099,7 +1600,7 @@ static void LoadTags( demux_t *p_demux )
...
@@ -2099,7 +1600,7 @@ static void LoadTags( demux_t *p_demux )
}
}
ep
->
Up
();
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagImageSpecific
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagImageSpecific
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Images Specific"
);
msg_Dbg
(
p_demux
,
"| + Images Specific"
);
ep
->
Down
();
ep
->
Down
();
...
@@ -2109,31 +1610,31 @@ static void LoadTags( demux_t *p_demux )
...
@@ -2109,31 +1610,31 @@ static void LoadTags( demux_t *p_demux )
}
}
ep
->
Up
();
ep
->
Up
();
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagMultiComment
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagMultiComment
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Multi Comment"
);
msg_Dbg
(
p_demux
,
"| + Multi Comment"
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagMultiCommercial
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagMultiCommercial
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Multi Commercial"
);
msg_Dbg
(
p_demux
,
"| + Multi Commercial"
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagMultiDate
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagMultiDate
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Multi Date"
);
msg_Dbg
(
p_demux
,
"| + Multi Date"
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagMultiEntity
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagMultiEntity
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Multi Entity"
);
msg_Dbg
(
p_demux
,
"| + Multi Entity"
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagMultiIdentifier
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagMultiIdentifier
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Multi Identifier"
);
msg_Dbg
(
p_demux
,
"| + Multi Identifier"
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagMultiLegal
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagMultiLegal
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Multi Legal"
);
msg_Dbg
(
p_demux
,
"| + Multi Legal"
);
}
}
else
if
(
EbmlId
(
*
el
)
==
KaxTagMultiTitle
::
ClassInfos
.
GlobalId
)
else
if
(
MKV_IS_ID
(
el
,
KaxTagMultiTitle
)
)
{
{
msg_Dbg
(
p_demux
,
"| + Multi Title"
);
msg_Dbg
(
p_demux
,
"| + Multi Title"
);
}
}
...
@@ -2156,6 +1657,693 @@ static void LoadTags( demux_t *p_demux )
...
@@ -2156,6 +1657,693 @@ static void LoadTags( demux_t *p_demux )
p_sys
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
p_sys
->
in
->
setFilePointer
(
i_sav_position
,
seek_beginning
);
}
}
/*****************************************************************************
* ParseInfo:
*****************************************************************************/
static
void
ParseSeekHead
(
demux_t
*
p_demux
,
EbmlElement
*
seekhead
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
EbmlElement
*
el
;
EbmlMaster
*
m
;
unsigned
int
i
;
int
i_upper_level
=
0
;
msg_Dbg
(
p_demux
,
"| + Seek head"
);
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
seekhead
);
m
->
Read
(
*
p_sys
->
es
,
seekhead
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
EbmlElement
*
l
=
(
*
m
)[
i
];
if
(
MKV_IS_ID
(
l
,
KaxSeek
)
)
{
EbmlMaster
*
sk
=
static_cast
<
EbmlMaster
*>
(
l
);
EbmlId
id
=
EbmlVoid
::
ClassInfos
.
GlobalId
;
int64_t
i_pos
=
-
1
;
unsigned
int
j
;
for
(
j
=
0
;
j
<
sk
->
ListSize
();
j
++
)
{
EbmlElement
*
l
=
(
*
sk
)[
j
];
if
(
MKV_IS_ID
(
l
,
KaxSeekID
)
)
{
KaxSeekID
&
sid
=
*
(
KaxSeekID
*
)
l
;
id
=
EbmlId
(
sid
.
GetBuffer
(),
sid
.
GetSize
()
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxSeekPosition
)
)
{
KaxSeekPosition
&
spos
=
*
(
KaxSeekPosition
*
)
l
;
i_pos
=
uint64
(
spos
);
}
else
{
msg_Dbg
(
p_demux
,
"| | | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
if
(
i_pos
>=
0
)
{
if
(
id
==
KaxCues
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = cues at "
I64Fd
,
i_pos
);
p_sys
->
i_cues_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
}
else
if
(
id
==
KaxChapters
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = chapters at "
I64Fd
,
i_pos
);
p_sys
->
i_chapters_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
}
else
if
(
id
==
KaxTags
::
ClassInfos
.
GlobalId
)
{
msg_Dbg
(
p_demux
,
"| | | = tags at "
I64Fd
,
i_pos
);
p_sys
->
i_tags_position
=
p_sys
->
segment
->
GetGlobalPosition
(
i_pos
);
}
}
}
else
{
msg_Dbg
(
p_demux
,
"| | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
/*****************************************************************************
* ParseTracks:
*****************************************************************************/
static
void
ParseTrackEntry
(
demux_t
*
p_demux
,
EbmlMaster
*
m
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
unsigned
int
i
;
mkv_track_t
*
tk
;
msg_Dbg
(
p_demux
,
"| | + Track Entry"
);
p_sys
->
i_track
++
;
p_sys
->
track
=
(
mkv_track_t
*
)
realloc
(
p_sys
->
track
,
sizeof
(
mkv_track_t
)
*
(
p_sys
->
i_track
+
1
)
);
/* Init the track */
tk
=
&
p_sys
->
track
[
p_sys
->
i_track
-
1
];
memset
(
tk
,
0
,
sizeof
(
mkv_track_t
)
);
es_format_Init
(
&
tk
->
fmt
,
UNKNOWN_ES
,
0
);
tk
->
fmt
.
psz_language
=
strdup
(
"English"
);
tk
->
fmt
.
psz_description
=
NULL
;
tk
->
b_default
=
VLC_TRUE
;
tk
->
b_enabled
=
VLC_TRUE
;
tk
->
i_number
=
p_sys
->
i_track
-
1
;
tk
->
i_extra_data
=
0
;
tk
->
p_extra_data
=
NULL
;
tk
->
psz_codec
=
NULL
;
tk
->
i_default_duration
=
0
;
tk
->
f_timecodescale
=
1.0
;
tk
->
b_inited
=
VLC_FALSE
;
tk
->
i_data_init
=
0
;
tk
->
p_data_init
=
NULL
;
tk
->
psz_codec_name
=
NULL
;
tk
->
psz_codec_settings
=
NULL
;
tk
->
psz_codec_info_url
=
NULL
;
tk
->
psz_codec_download_url
=
NULL
;
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
EbmlElement
*
l
=
(
*
m
)[
i
];
if
(
MKV_IS_ID
(
l
,
KaxTrackNumber
)
)
{
KaxTrackNumber
&
tnum
=
*
(
KaxTrackNumber
*
)
l
;
tk
->
i_number
=
uint32
(
tnum
);
msg_Dbg
(
p_demux
,
"| | | + Track Number=%u"
,
uint32
(
tnum
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackUID
)
)
{
KaxTrackUID
&
tuid
=
*
(
KaxTrackUID
*
)
l
;
msg_Dbg
(
p_demux
,
"| | | + Track UID=%u"
,
uint32
(
tuid
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackType
)
)
{
char
*
psz_type
;
KaxTrackType
&
ttype
=
*
(
KaxTrackType
*
)
l
;
switch
(
uint8
(
ttype
)
)
{
case
track_audio
:
psz_type
=
"audio"
;
tk
->
fmt
.
i_cat
=
AUDIO_ES
;
break
;
case
track_video
:
psz_type
=
"video"
;
tk
->
fmt
.
i_cat
=
VIDEO_ES
;
break
;
case
track_subtitle
:
psz_type
=
"subtitle"
;
tk
->
fmt
.
i_cat
=
SPU_ES
;
break
;
default:
psz_type
=
"unknown"
;
tk
->
fmt
.
i_cat
=
UNKNOWN_ES
;
break
;
}
msg_Dbg
(
p_demux
,
"| | | + Track Type=%s"
,
psz_type
);
}
// else if( EbmlId( *l ) == KaxTrackFlagEnabled::ClassInfos.GlobalId )
// {
// KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)l;
// tk->b_enabled = uint32( fenb );
// msg_Dbg( p_demux, "| | | + Track Enabled=%u",
// uint32( fenb ) );
// }
else
if
(
MKV_IS_ID
(
l
,
KaxTrackFlagDefault
)
)
{
KaxTrackFlagDefault
&
fdef
=
*
(
KaxTrackFlagDefault
*
)
l
;
tk
->
b_default
=
uint32
(
fdef
);
msg_Dbg
(
p_demux
,
"| | | + Track Default=%u"
,
uint32
(
fdef
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackFlagLacing
)
)
{
KaxTrackFlagLacing
&
lac
=
*
(
KaxTrackFlagLacing
*
)
l
;
msg_Dbg
(
p_demux
,
"| | | + Track Lacing=%d"
,
uint32
(
lac
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackMinCache
)
)
{
KaxTrackMinCache
&
cmin
=
*
(
KaxTrackMinCache
*
)
l
;
msg_Dbg
(
p_demux
,
"| | | + Track MinCache=%d"
,
uint32
(
cmin
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackMaxCache
)
)
{
KaxTrackMaxCache
&
cmax
=
*
(
KaxTrackMaxCache
*
)
l
;
msg_Dbg
(
p_demux
,
"| | | + Track MaxCache=%d"
,
uint32
(
cmax
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackDefaultDuration
)
)
{
KaxTrackDefaultDuration
&
defd
=
*
(
KaxTrackDefaultDuration
*
)
l
;
tk
->
i_default_duration
=
uint64
(
defd
);
msg_Dbg
(
p_demux
,
"| | | + Track Default Duration="
I64Fd
,
uint64
(
defd
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackTimecodeScale
)
)
{
KaxTrackTimecodeScale
&
ttcs
=
*
(
KaxTrackTimecodeScale
*
)
l
;
tk
->
f_timecodescale
=
float
(
ttcs
);
msg_Dbg
(
p_demux
,
"| | | + Track TimeCodeScale=%f"
,
tk
->
f_timecodescale
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackName
)
)
{
KaxTrackName
&
tname
=
*
(
KaxTrackName
*
)
l
;
tk
->
fmt
.
psz_description
=
UTF8ToStr
(
UTFstring
(
tname
)
);
msg_Dbg
(
p_demux
,
"| | | + Track Name=%s"
,
tk
->
fmt
.
psz_description
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackLanguage
)
)
{
KaxTrackLanguage
&
lang
=
*
(
KaxTrackLanguage
*
)
l
;
tk
->
fmt
.
psz_language
=
strdup
(
string
(
lang
).
c_str
()
);
msg_Dbg
(
p_demux
,
"| | | + Track Language=`%s'"
,
tk
->
fmt
.
psz_language
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxCodecID
)
)
{
KaxCodecID
&
codecid
=
*
(
KaxCodecID
*
)
l
;
tk
->
psz_codec
=
strdup
(
string
(
codecid
).
c_str
()
);
msg_Dbg
(
p_demux
,
"| | | + Track CodecId=%s"
,
string
(
codecid
).
c_str
()
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxCodecPrivate
)
)
{
KaxCodecPrivate
&
cpriv
=
*
(
KaxCodecPrivate
*
)
l
;
tk
->
i_extra_data
=
cpriv
.
GetSize
();
if
(
tk
->
i_extra_data
>
0
)
{
tk
->
p_extra_data
=
(
uint8_t
*
)
malloc
(
tk
->
i_extra_data
);
memcpy
(
tk
->
p_extra_data
,
cpriv
.
GetBuffer
(),
tk
->
i_extra_data
);
}
msg_Dbg
(
p_demux
,
"| | | + Track CodecPrivate size="
I64Fd
,
cpriv
.
GetSize
()
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxCodecName
)
)
{
KaxCodecName
&
cname
=
*
(
KaxCodecName
*
)
l
;
tk
->
psz_codec_name
=
UTF8ToStr
(
UTFstring
(
cname
)
);
msg_Dbg
(
p_demux
,
"| | | + Track Codec Name=%s"
,
tk
->
psz_codec_name
);
}
// else if( EbmlId( *l ) == KaxCodecSettings::ClassInfos.GlobalId )
// {
// KaxCodecSettings &cset = *(KaxCodecSettings*)l;
// tk->psz_codec_settings = UTF8ToStr( UTFstring( cset ) );
// msg_Dbg( p_demux, "| | | + Track Codec Settings=%s", tk->psz_codec_settings );
// }
// else if( EbmlId( *l ) == KaxCodecInfoURL::ClassInfos.GlobalId )
// {
// KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)l;
// tk->psz_codec_info_url = strdup( string( ciurl ).c_str() );
// msg_Dbg( p_demux, "| | | + Track Codec Info URL=%s", tk->psz_codec_info_url );
// }
// else if( EbmlId( *l ) == KaxCodecDownloadURL::ClassInfos.GlobalId )
// {
// KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)l;
// tk->psz_codec_download_url = strdup( string( cdurl ).c_str() );
// msg_Dbg( p_demux, "| | | + Track Codec Info URL=%s", tk->psz_codec_download_url );
// }
// else if( EbmlId( *l ) == KaxCodecDecodeAll::ClassInfos.GlobalId )
// {
// KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)l;
// msg_Dbg( p_demux, "| | | + Track Codec Decode All=%u <== UNUSED", uint8( cdall ) );
// }
// else if( EbmlId( *l ) == KaxTrackOverlay::ClassInfos.GlobalId )
// {
// KaxTrackOverlay &tovr = *(KaxTrackOverlay*)l;
// msg_Dbg( p_demux, "| | | + Track Overlay=%u <== UNUSED", uint32( tovr ) );
// }
else
if
(
MKV_IS_ID
(
l
,
KaxTrackVideo
)
)
{
EbmlMaster
*
tkv
=
static_cast
<
EbmlMaster
*>
(
l
);
unsigned
int
j
;
msg_Dbg
(
p_demux
,
"| | | + Track Video"
);
tk
->
f_fps
=
0.0
;
for
(
j
=
0
;
j
<
tkv
->
ListSize
();
j
++
)
{
EbmlElement
*
l
=
(
*
tkv
)[
j
];
// if( EbmlId( *el4 ) == KaxVideoFlagInterlaced::ClassInfos.GlobalId )
// {
// KaxVideoFlagInterlaced &fint = *(KaxVideoFlagInterlaced*)el4;
// msg_Dbg( p_demux, "| | | | + Track Video Interlaced=%u", uint8( fint ) );
// }
// else if( EbmlId( *el4 ) == KaxVideoStereoMode::ClassInfos.GlobalId )
// {
// KaxVideoStereoMode &stereo = *(KaxVideoStereoMode*)el4;
// msg_Dbg( p_demux, "| | | | + Track Video Stereo Mode=%u", uint8( stereo ) );
// }
// else
if
(
MKV_IS_ID
(
l
,
KaxVideoPixelWidth
)
)
{
KaxVideoPixelWidth
&
vwidth
=
*
(
KaxVideoPixelWidth
*
)
l
;
tk
->
fmt
.
video
.
i_width
=
uint16
(
vwidth
);
msg_Dbg
(
p_demux
,
"| | | | + width=%d"
,
uint16
(
vwidth
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxVideoPixelHeight
)
)
{
KaxVideoPixelWidth
&
vheight
=
*
(
KaxVideoPixelWidth
*
)
l
;
tk
->
fmt
.
video
.
i_height
=
uint16
(
vheight
);
msg_Dbg
(
p_demux
,
"| | | | + height=%d"
,
uint16
(
vheight
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxVideoDisplayWidth
)
)
{
KaxVideoDisplayWidth
&
vwidth
=
*
(
KaxVideoDisplayWidth
*
)
l
;
tk
->
fmt
.
video
.
i_visible_width
=
uint16
(
vwidth
);
msg_Dbg
(
p_demux
,
"| | | | + display width=%d"
,
uint16
(
vwidth
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxVideoDisplayHeight
)
)
{
KaxVideoDisplayWidth
&
vheight
=
*
(
KaxVideoDisplayWidth
*
)
l
;
tk
->
fmt
.
video
.
i_visible_height
=
uint16
(
vheight
);
msg_Dbg
(
p_demux
,
"| | | | + display height=%d"
,
uint16
(
vheight
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxVideoFrameRate
)
)
{
KaxVideoFrameRate
&
vfps
=
*
(
KaxVideoFrameRate
*
)
l
;
tk
->
f_fps
=
float
(
vfps
);
msg_Dbg
(
p_demux
,
" | | | + fps=%f"
,
float
(
vfps
)
);
}
// else if( EbmlId( *l ) == KaxVideoDisplayUnit::ClassInfos.GlobalId )
// {
// KaxVideoDisplayUnit &vdmode = *(KaxVideoDisplayUnit*)l;
// msg_Dbg( p_demux, "| | | | + Track Video Display Unit=%s",
// uint8( vdmode ) == 0 ? "pixels" : ( uint8( vdmode ) == 1 ? "centimeters": "inches" ) );
// }
// else if( EbmlId( *l ) == KaxVideoAspectRatio::ClassInfos.GlobalId )
// {
// KaxVideoAspectRatio &ratio = *(KaxVideoAspectRatio*)l;
// msg_Dbg( p_demux, " | | | + Track Video Aspect Ratio Type=%u", uint8( ratio ) );
// }
// else if( EbmlId( *l ) == KaxVideoGamma::ClassInfos.GlobalId )
// {
// KaxVideoGamma &gamma = *(KaxVideoGamma*)l;
// msg_Dbg( p_demux, " | | | + fps=%f", float( gamma ) );
// }
else
{
msg_Dbg
(
p_demux
,
"| | | | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
else
if
(
MKV_IS_ID
(
l
,
KaxTrackAudio
)
)
{
EbmlMaster
*
tka
=
static_cast
<
EbmlMaster
*>
(
l
);
unsigned
int
j
;
msg_Dbg
(
p_demux
,
"| | | + Track Audio"
);
for
(
j
=
0
;
j
<
tka
->
ListSize
();
j
++
)
{
EbmlElement
*
l
=
(
*
tka
)[
j
];
if
(
MKV_IS_ID
(
l
,
KaxAudioSamplingFreq
)
)
{
KaxAudioSamplingFreq
&
afreq
=
*
(
KaxAudioSamplingFreq
*
)
l
;
tk
->
fmt
.
audio
.
i_rate
=
(
int
)
float
(
afreq
);
msg_Dbg
(
p_demux
,
"| | | | + afreq=%d"
,
tk
->
fmt
.
audio
.
i_rate
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxAudioChannels
)
)
{
KaxAudioChannels
&
achan
=
*
(
KaxAudioChannels
*
)
l
;
tk
->
fmt
.
audio
.
i_channels
=
uint8
(
achan
);
msg_Dbg
(
p_demux
,
"| | | | + achan=%u"
,
uint8
(
achan
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxAudioBitDepth
)
)
{
KaxAudioBitDepth
&
abits
=
*
(
KaxAudioBitDepth
*
)
l
;
tk
->
fmt
.
audio
.
i_bitspersample
=
uint8
(
abits
);
msg_Dbg
(
p_demux
,
"| | | | + abits=%u"
,
uint8
(
abits
)
);
}
else
{
msg_Dbg
(
p_demux
,
"| | | | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
else
{
msg_Dbg
(
p_demux
,
"| | | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
static
void
ParseTracks
(
demux_t
*
p_demux
,
EbmlElement
*
tracks
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
EbmlElement
*
el
;
EbmlMaster
*
m
;
unsigned
int
i
;
int
i_upper_level
=
0
;
msg_Dbg
(
p_demux
,
"| + Tracks"
);
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
tracks
);
m
->
Read
(
*
p_sys
->
es
,
tracks
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
EbmlElement
*
l
=
(
*
m
)[
i
];
if
(
MKV_IS_ID
(
l
,
KaxTrackEntry
)
)
{
ParseTrackEntry
(
p_demux
,
static_cast
<
EbmlMaster
*>
(
l
)
);
}
else
{
msg_Dbg
(
p_demux
,
"| | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
/*****************************************************************************
* ParseInfo:
*****************************************************************************/
static
void
ParseInfo
(
demux_t
*
p_demux
,
EbmlElement
*
info
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
EbmlElement
*
el
;
EbmlMaster
*
m
;
unsigned
int
i
;
int
i_upper_level
=
0
;
msg_Dbg
(
p_demux
,
"| + Informations"
);
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
info
);
m
->
Read
(
*
p_sys
->
es
,
info
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
EbmlElement
*
l
=
(
*
m
)[
i
];
if
(
MKV_IS_ID
(
l
,
KaxSegmentUID
)
)
{
KaxSegmentUID
&
uid
=
*
(
KaxSegmentUID
*
)
l
;
msg_Dbg
(
p_demux
,
"| | + UID=%d"
,
uint32
(
uid
)
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTimecodeScale
)
)
{
KaxTimecodeScale
&
tcs
=
*
(
KaxTimecodeScale
*
)
l
;
p_sys
->
i_timescale
=
uint64
(
tcs
);
msg_Dbg
(
p_demux
,
"| | + TimecodeScale="
I64Fd
,
p_sys
->
i_timescale
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxDuration
)
)
{
KaxDuration
&
dur
=
*
(
KaxDuration
*
)
l
;
p_sys
->
f_duration
=
float
(
dur
);
msg_Dbg
(
p_demux
,
"| | + Duration=%f"
,
p_sys
->
f_duration
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxMuxingApp
)
)
{
KaxMuxingApp
&
mapp
=
*
(
KaxMuxingApp
*
)
l
;
p_sys
->
psz_muxing_application
=
UTF8ToStr
(
UTFstring
(
mapp
)
);
msg_Dbg
(
p_demux
,
"| | + Muxing Application=%s"
,
p_sys
->
psz_muxing_application
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxWritingApp
)
)
{
KaxWritingApp
&
wapp
=
*
(
KaxWritingApp
*
)
l
;
p_sys
->
psz_writing_application
=
UTF8ToStr
(
UTFstring
(
wapp
)
);
msg_Dbg
(
p_demux
,
"| | + Writing Application=%s"
,
p_sys
->
psz_writing_application
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxSegmentFilename
)
)
{
KaxSegmentFilename
&
sfn
=
*
(
KaxSegmentFilename
*
)
l
;
p_sys
->
psz_segment_filename
=
UTF8ToStr
(
UTFstring
(
sfn
)
);
msg_Dbg
(
p_demux
,
"| | + Segment Filename=%s"
,
p_sys
->
psz_segment_filename
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxTitle
)
)
{
KaxTitle
&
title
=
*
(
KaxTitle
*
)
l
;
p_sys
->
psz_title
=
UTF8ToStr
(
UTFstring
(
title
)
);
msg_Dbg
(
p_demux
,
"| | + Title=%s"
,
p_sys
->
psz_title
);
}
#if defined( HAVE_GMTIME_R ) && !defined( SYS_DARWIN )
else
if
(
MKV_IS_ID
(
l
,
KaxDateUTC
)
)
{
KaxDateUTC
&
date
=
*
(
KaxDateUTC
*
)
l
;
time_t
i_date
;
struct
tm
tmres
;
char
buffer
[
256
];
i_date
=
date
.
GetEpochDate
();
memset
(
buffer
,
0
,
256
);
if
(
gmtime_r
(
&
i_date
,
&
tmres
)
&&
asctime_r
(
&
tmres
,
buffer
)
)
{
buffer
[
strlen
(
buffer
)
-
1
]
=
'\0'
;
p_sys
->
psz_date_utc
=
strdup
(
buffer
);
msg_Dbg
(
p_demux
,
"| | + Date=%s"
,
p_sys
->
psz_date_utc
);
}
}
#endif
else
{
msg_Dbg
(
p_demux
,
"| | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
/*****************************************************************************
* ParseChapterAtom
*****************************************************************************/
static
void
ParseChapterAtom
(
demux_t
*
p_demux
,
int
i_level
,
EbmlMaster
*
ca
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
unsigned
int
i
;
seekpoint_t
*
sk
;
if
(
p_sys
->
title
==
NULL
)
{
p_sys
->
title
=
vlc_input_title_New
();
}
sk
=
vlc_seekpoint_New
();
msg_Dbg
(
p_demux
,
"| | | + ChapterAtom (level=%d)"
,
i_level
);
for
(
i
=
0
;
i
<
ca
->
ListSize
();
i
++
)
{
EbmlElement
*
l
=
(
*
ca
)[
i
];
if
(
MKV_IS_ID
(
l
,
KaxChapterUID
)
)
{
KaxChapterUID
&
uid
=
*
(
KaxChapterUID
*
)
l
;
uint32_t
i_uid
=
uint32
(
uid
);
msg_Dbg
(
p_demux
,
"| | | | + ChapterUID: 0x%x"
,
i_uid
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxChapterTimeStart
)
)
{
KaxChapterTimeStart
&
start
=*
(
KaxChapterTimeStart
*
)
l
;
sk
->
i_time_offset
=
uint64
(
start
)
/
I64C
(
1000
);
msg_Dbg
(
p_demux
,
"| | | | + ChapterTimeStart: %lld"
,
sk
->
i_time_offset
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxChapterTimeEnd
)
)
{
KaxChapterTimeEnd
&
end
=*
(
KaxChapterTimeEnd
*
)
l
;
int64_t
i_end
=
uint64
(
end
);
msg_Dbg
(
p_demux
,
"| | | | + ChapterTimeEnd: %lld"
,
i_end
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxChapterDisplay
)
)
{
EbmlMaster
*
cd
=
static_cast
<
EbmlMaster
*>
(
l
);
unsigned
int
j
;
msg_Dbg
(
p_demux
,
"| | | | + ChapterDisplay"
);
for
(
j
=
0
;
j
<
cd
->
ListSize
();
j
++
)
{
EbmlElement
*
l
=
(
*
cd
)[
j
];
if
(
MKV_IS_ID
(
l
,
KaxChapterString
)
)
{
KaxChapterString
&
name
=*
(
KaxChapterString
*
)
l
;
char
*
psz
=
UTF8ToStr
(
UTFstring
(
name
)
);
sk
->
psz_name
=
strdup
(
psz
);
msg_Dbg
(
p_demux
,
"| | | | | + ChapterString '%s'"
,
psz
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxChapterLanguage
)
)
{
KaxChapterLanguage
&
lang
=*
(
KaxChapterLanguage
*
)
l
;
const
char
*
psz
=
string
(
lang
).
c_str
();
msg_Dbg
(
p_demux
,
"| | | | | + ChapterLanguage '%s'"
,
psz
);
}
else
if
(
MKV_IS_ID
(
l
,
KaxChapterCountry
)
)
{
KaxChapterCountry
&
ct
=*
(
KaxChapterCountry
*
)
l
;
const
char
*
psz
=
string
(
ct
).
c_str
();
msg_Dbg
(
p_demux
,
"| | | | | + ChapterCountry '%s'"
,
psz
);
}
}
}
else
if
(
MKV_IS_ID
(
l
,
KaxChapterAtom
)
)
{
ParseChapterAtom
(
p_demux
,
i_level
+
1
,
static_cast
<
EbmlMaster
*>
(
l
)
);
}
}
if
(
sk
->
i_time_offset
>
0
)
{
p_sys
->
title
->
i_seekpoint
++
;
p_sys
->
title
->
seekpoint
=
(
seekpoint_t
**
)
realloc
(
p_sys
->
title
->
seekpoint
,
p_sys
->
title
->
i_seekpoint
*
sizeof
(
seekpoint_t
*
)
);
p_sys
->
title
->
seekpoint
[
p_sys
->
title
->
i_seekpoint
-
1
]
=
sk
;
}
else
{
vlc_seekpoint_Delete
(
sk
);
}
}
/*****************************************************************************
* ParseChapters:
*****************************************************************************/
static
void
ParseChapters
(
demux_t
*
p_demux
,
EbmlElement
*
chapters
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
EbmlElement
*
el
;
EbmlMaster
*
m
;
unsigned
int
i
;
int
i_upper_level
=
0
;
/* Master elements */
m
=
static_cast
<
EbmlMaster
*>
(
chapters
);
m
->
Read
(
*
p_sys
->
es
,
chapters
->
Generic
().
Context
,
i_upper_level
,
el
,
true
);
for
(
i
=
0
;
i
<
m
->
ListSize
();
i
++
)
{
EbmlElement
*
l
=
(
*
m
)[
i
];
if
(
MKV_IS_ID
(
l
,
KaxEditionEntry
)
)
{
EbmlMaster
*
E
=
static_cast
<
EbmlMaster
*>
(
l
);
unsigned
int
j
;
msg_Dbg
(
p_demux
,
"| | + EditionEntry"
);
for
(
j
=
0
;
j
<
E
->
ListSize
();
j
++
)
{
EbmlElement
*
l
=
(
*
E
)[
j
];
if
(
MKV_IS_ID
(
l
,
KaxChapterAtom
)
)
{
ParseChapterAtom
(
p_demux
,
0
,
static_cast
<
EbmlMaster
*>
(
l
)
);
}
else
{
msg_Dbg
(
p_demux
,
"| | | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
else
{
msg_Dbg
(
p_demux
,
"| | + Unknown (%s)"
,
typeid
(
*
l
).
name
()
);
}
}
}
/*****************************************************************************
* InformationsCreate:
*****************************************************************************/
static
void
InformationsCreate
(
demux_t
*
p_demux
)
static
void
InformationsCreate
(
demux_t
*
p_demux
)
{
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
...
...
modules/demux/util/id3.c
View file @
d82e9eb7
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* id3.c: simple id3 tag skipper
* id3.c: simple id3 tag skipper
*****************************************************************************
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* Copyright (C) 2001 VideoLAN
* $Id
: id3.c,v 1.8 2004/03/03 11:38:14 fenrir Exp
$
* $Id$
*
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
*
...
@@ -30,10 +30,6 @@
...
@@ -30,10 +30,6 @@
#include <vlc/vlc.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc/input.h>
#include "ninput.h"
#include <sys/types.h>
/*****************************************************************************
/*****************************************************************************
* Local prototypes
* Local prototypes
*****************************************************************************/
*****************************************************************************/
...
...
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