Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
3e666faf
Commit
3e666faf
authored
Jun 06, 2004
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* vcd/vcd.c: ported to access2.
* access2: added chapter support.
parent
d279ea85
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
459 additions
and
143 deletions
+459
-143
modules/access/access2.c
modules/access/access2.c
+80
-41
modules/access/vcd/vcd.c
modules/access/vcd/vcd.c
+379
-102
No files found.
modules/access/access2.c
View file @
3e666faf
...
...
@@ -64,6 +64,9 @@ vlc_module_begin();
add_shortcut
(
"mmsh"
);
add_shortcut
(
"mmst"
);
add_shortcut
(
"mmsu"
);
add_shortcut
(
"vcd"
);
add_shortcut
(
"svcd"
);
vlc_module_end
();
/*****************************************************************************
...
...
@@ -86,6 +89,8 @@ typedef struct
}
access2_sys_t
;
static
void
UpdateInfo
(
input_thread_t
*
p_input
,
vlc_bool_t
b_force_chapter
);
/*****************************************************************************
* Access2Open: initializes structures
*****************************************************************************/
...
...
@@ -299,38 +304,10 @@ update:
}
p_sys
->
b_first_read
=
VLC_FALSE
;
}
/* Title change */
if
(
p_access
->
info
.
i_update
&
INPUT_UPDATE_TITLE
)
{
vlc_value_t
val
;
msg_Dbg
(
p_input
,
"INPUT_UPDATE_TITLE"
);
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
p_selected_area
=
p_input
->
stream
.
pp_areas
[
p_access
->
info
.
i_title
+
1
];
p_input
->
stream
.
b_changed
=
VLC_TRUE
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
val
.
i_int
=
p_access
->
info
.
i_title
+
1
;
var_Change
(
p_input
,
"title"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
p_access
->
info
.
i_update
&=
~
INPUT_UPDATE_TITLE
;
}
/* Size change */
if
(
p_access
->
info
.
i_update
&
INPUT_UPDATE_SIZE
)
{
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
p_selected_area
->
i_size
=
p_access
->
info
.
i_size
;
p_input
->
stream
.
b_changed
=
VLC_TRUE
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
p_access
->
info
.
i_update
&=
~
INPUT_UPDATE_SIZE
;
}
if
(
p_access
->
info
.
i_update
&
INPUT_UPDATE_SEEKPOINT
)
{
/* TODO */
msg_Err
(
p_input
,
"INPUT_UPDATE_SEEKPOINT to do"
);
}
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
UpdateInfo
(
p_input
,
VLC_FALSE
);
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
return
i_total
;
}
...
...
@@ -343,7 +320,7 @@ static int Access2SetArea( input_thread_t * p_input, input_area_t * p_area )
{
access2_sys_t
*
p_sys
=
(
access2_sys_t
*
)
p_input
->
p_access_data
;
access_t
*
p_access
=
p_sys
->
p_access
;
vlc_value_t
val
;
int
i_seekpoint
=
p_area
->
i_part
-
1
;
/* we can't use the interface slider until initilization is complete */
p_input
->
stream
.
b_seekable
=
0
;
...
...
@@ -354,18 +331,21 @@ static int Access2SetArea( input_thread_t * p_input, input_area_t * p_area )
if
(
access2_Control
(
p_access
,
ACCESS_SET_TITLE
,
(
int
)(
p_area
->
i_id
-
1
)
)
)
return
VLC_EGENERIC
;
/* Change the default area */
p_input
->
stream
.
p_selected_area
=
p_input
->
stream
.
pp_areas
[
p_access
->
info
.
i_title
+
1
];
p_input
->
stream
.
p_selected_area
->
i_tell
=
p_access
->
info
.
i_pos
;
/* Update the navigation variables without triggering a callback */
val
.
i_int
=
p_access
->
info
.
i_title
+
1
;;
var_Change
(
p_input
,
"title"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
p_input
->
stream
.
p_selected_area
=
p_area
;
}
fprintf
(
stderr
,
"Access2SetArea: part=%d seekpart=%d nbseekpoint=%d
\n
"
,
p_area
->
i_part
,
i_seekpoint
,
p_sys
->
title
[
p_access
->
info
.
i_title
]
->
i_seekpoint
);
/* Clear the flag */
p_access
->
info
.
i_update
&=
~
INPUT_UPDATE_TITLE
;
if
(
i_seekpoint
!=
p_access
->
info
.
i_seekpoint
&&
i_seekpoint
>=
0
&&
i_seekpoint
<
p_sys
->
title
[
p_access
->
info
.
i_title
]
->
i_seekpoint
)
{
msg_Dbg
(
p_input
,
"setting seekpoint"
);
access2_Control
(
p_access
,
ACCESS_SET_SEEKPOINT
,
(
int
)
i_seekpoint
);
}
UpdateInfo
(
p_input
,
VLC_TRUE
);
/* warn interface that something has changed */
p_input
->
stream
.
b_seekable
=
VLC_TRUE
;
p_input
->
stream
.
b_changed
=
VLC_TRUE
;
...
...
@@ -412,3 +392,62 @@ static int Access2Control( input_thread_t *p_input, int i_query, va_list args )
return
access2_vaControl
(
p_access
,
i_query
,
args
);
}
/*****************************************************************************
* UpdateInfo:
*****************************************************************************/
static
void
UpdateInfo
(
input_thread_t
*
p_input
,
vlc_bool_t
b_force_chapter
)
{
access2_sys_t
*
p_sys
=
(
access2_sys_t
*
)
p_input
->
p_access_data
;
access_t
*
p_access
=
p_sys
->
p_access
;
/* Title change */
if
(
p_access
->
info
.
i_update
&
INPUT_UPDATE_TITLE
)
{
int
i_seekpoint
;
int
i
;
vlc_value_t
val
;
msg_Dbg
(
p_input
,
"INPUT_UPDATE_TITLE"
);
p_input
->
stream
.
p_selected_area
=
p_input
->
stream
.
pp_areas
[
p_access
->
info
.
i_title
+
1
];
p_input
->
stream
.
p_selected_area
->
i_part
=
1
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
p_access
->
info
.
i_pos
;
p_input
->
stream
.
b_changed
=
VLC_TRUE
;
val
.
i_int
=
p_access
->
info
.
i_title
+
1
;
var_Change
(
p_input
,
"title"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
var_Change
(
p_input
,
"chapter"
,
VLC_VAR_CLEARCHOICES
,
NULL
,
NULL
);
i_seekpoint
=
p_sys
->
title
[
p_access
->
info
.
i_title
]
->
i_seekpoint
;
for
(
i
=
0
;
i
<
i_seekpoint
?
i_seekpoint
:
0
;
i
++
)
{
val
.
i_int
=
i
+
1
;
var_Change
(
p_input
,
"chapter"
,
VLC_VAR_ADDCHOICE
,
&
val
,
NULL
);
}
p_access
->
info
.
i_update
&=
~
INPUT_UPDATE_TITLE
;
}
/* b_force_chapter: don't force a chapter change when a there is
* pending user one (as it reset i_part */
if
(
p_access
->
info
.
i_update
&
INPUT_UPDATE_SEEKPOINT
&&
(
b_force_chapter
||
!
p_input
->
stream
.
p_new_area
)
)
{
vlc_value_t
val
;
/* TODO is it complete ? */
p_input
->
stream
.
p_selected_area
->
i_part
=
p_access
->
info
.
i_seekpoint
+
1
;
val
.
i_int
=
p_input
->
stream
.
p_selected_area
->
i_part
;
var_Change
(
p_input
,
"chapter"
,
VLC_VAR_SETVALUE
,
&
val
,
NULL
);
p_access
->
info
.
i_update
&=
~
INPUT_UPDATE_SEEKPOINT
;
}
/* Size change */
if
(
p_access
->
info
.
i_update
&
INPUT_UPDATE_SIZE
)
{
p_input
->
stream
.
p_selected_area
->
i_size
=
p_access
->
info
.
i_size
;
p_input
->
stream
.
b_changed
=
VLC_TRUE
;
p_access
->
info
.
i_update
&=
~
INPUT_UPDATE_SIZE
;
}
}
modules/access/vcd/vcd.c
View file @
3e666faf
...
...
@@ -37,12 +37,20 @@
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
#define CACHING_TEXT N_("Caching value in ms")
#define CACHING_LONGTEXT N_( \
"Allows you to modify the default caching value for cdda streams. This " \
"value should be set in milliseconds units." )
vlc_module_begin
();
set_description
(
_
(
"VCD input"
)
);
set_capability
(
"access
"
,
8
0
);
set_capability
(
"access
2"
,
1
0
);
set_callbacks
(
Open
,
Close
);
add_usage_hint
(
N_
(
"[vcd:][device][@[title][,[chapter]]]"
)
);
add_integer
(
"vcd-caching"
,
DEFAULT_PTS_DELAY
/
1000
,
NULL
,
CACHING_TEXT
,
CACHING_LONGTEXT
,
VLC_TRUE
);
add_shortcut
(
"vcd"
);
add_shortcut
(
"svcd"
);
vlc_module_end
();
...
...
@@ -57,37 +65,35 @@ vlc_module_end();
struct
access_sys_t
{
vcddev_t
*
vcddev
;
/* vcd device descriptor */
int
i_nb_tracks
;
/* Nb of tracks (titles) */
int
i_track
;
/* Current track */
/* Title infos */
int
i_titles
;
input_title_t
*
title
[
99
];
/* No more that 99 track in a vcd ? */
int
i_sector
;
/* Current Sector */
int
*
p_sectors
;
/* Track sectors */
int
i_entries_nb
;
/* Number of entry points */
int
*
p_entries
;
/* Entry points */
vlc_bool_t
b_valid_ep
;
/* Valid entry points flag */
vlc_bool_t
b_end_of_track
;
/* If the end of track was reached */
int
*
p_sectors
;
/* Track sectors */
};
static
int
VCDRead
(
input_thread_t
*
,
byte_t
*
,
size_t
);
static
void
VCDSeek
(
input_thread_t
*
,
off
_t
);
static
int
VCDSetArea
(
input_thread_t
*
,
input_area_t
*
);
static
int
VCDSetProgram
(
input_thread_t
*
,
pgrm_descriptor_t
*
);
static
int
VCDEntryPoints
(
input_thread
_t
*
);
static
block_t
*
Block
(
access_t
*
);
static
int
Seek
(
access_t
*
,
int64
_t
);
static
int
Control
(
access_t
*
,
int
,
va_list
);
static
int
EntryPoints
(
access
_t
*
);
/*****************************************************************************
* VCDOpen: open vcd
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread
_t
*
)
p_this
;
access_sys_t
*
p_sys
;
char
*
psz_dup
=
strdup
(
p_
input
->
psz_name
);
access_t
*
p_access
=
(
access
_t
*
)
p_this
;
access_sys_t
*
p_sys
;
char
*
psz_dup
=
strdup
(
p_
access
->
psz_path
);
char
*
psz
;
int
i
;
input_area_t
*
p_area
;
int
i_title
=
0
;
int
i_chapter
=
0
;
vcddev_t
*
vcddev
;
int
i_title
=
0
;
int
i_chapter
=
0
;
int
i
;
vcddev_t
*
vcddev
;
/* Command line: vcd://[dev_path][@title[,chapter]] */
if
(
(
psz
=
strchr
(
psz_dup
,
'@'
)
)
)
...
...
@@ -96,9 +102,7 @@ static int Open( vlc_object_t *p_this )
i_title
=
strtol
(
psz
,
&
psz
,
0
);
if
(
*
psz
)
{
i_chapter
=
strtol
(
psz
,
&
psz
,
0
);
}
i_chapter
=
strtol
(
psz
+
1
,
&
psz
,
0
);
}
if
(
*
psz_dup
==
'\0'
)
...
...
@@ -106,10 +110,10 @@ static int Open( vlc_object_t *p_this )
free
(
psz_dup
);
/* Only when selected */
if
(
*
p_
input
->
psz_access
==
'\0'
)
if
(
*
p_
access
->
psz_access
==
'\0'
)
return
VLC_EGENERIC
;
psz_dup
=
var_CreateGetString
(
p_
input
,
"vcd"
);
psz_dup
=
var_CreateGetString
(
p_
access
,
"vcd"
);
if
(
*
psz_dup
==
'\0'
)
{
free
(
psz_dup
);
...
...
@@ -120,125 +124,397 @@ static int Open( vlc_object_t *p_this )
/* Open VCD */
if
(
!
(
vcddev
=
ioctl_Open
(
p_this
,
psz_dup
))
)
{
msg_Warn
(
p_
input
,
"could not open %s"
,
psz_dup
);
msg_Warn
(
p_
access
,
"could not open %s"
,
psz_dup
);
free
(
psz_dup
);
return
VLC_EGENERIC
;
}
free
(
psz_dup
);
p_sys
=
malloc
(
sizeof
(
access_sys_t
)
);
if
(
p_sys
==
NULL
)
/* Set up p_access */
p_access
->
pf_read
=
NULL
;
p_access
->
pf_block
=
Block
;
p_access
->
pf_control
=
Control
;
p_access
->
pf_seek
=
Seek
;
p_access
->
info
.
i_update
=
0
;
p_access
->
info
.
i_size
=
0
;
p_access
->
info
.
i_pos
=
0
;
p_access
->
info
.
b_eof
=
VLC_FALSE
;
p_access
->
info
.
i_title
=
0
;
p_access
->
info
.
i_seekpoint
=
0
;
p_access
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
access_sys_t
)
);
memset
(
p_sys
,
0
,
sizeof
(
access_sys_t
)
);
p_sys
->
vcddev
=
vcddev
;
/* We read the Table Of Content information */
p_sys
->
i_titles
=
ioctl_GetTracksMap
(
VLC_OBJECT
(
p_access
),
p_sys
->
vcddev
,
&
p_sys
->
p_sectors
);
if
(
p_sys
->
i_titles
<
0
)
{
msg_Err
(
p_input
,
"out of memory"
);
free
(
psz_dup
);
return
VLC_EGENERIC
;
msg_Err
(
p_access
,
"unable to count tracks"
);
goto
error
;
}
free
(
psz_dup
);
else
if
(
p_sys
->
i_titles
<=
1
)
{
msg_Err
(
p_access
,
"no movie tracks found"
);
goto
error
;
}
/* The first title isn't usable */
p_sys
->
i_titles
--
;
p_sys
->
vcddev
=
vcddev
;
p_input
->
p_access_data
=
(
void
*
)
p_sys
;
/* Build title table */
for
(
i
=
0
;
i
<
p_sys
->
i_titles
;
i
++
)
{
input_title_t
*
t
=
p_sys
->
title
[
i
]
=
vlc_input_title_New
();
p_input
->
i_mtu
=
VCD_DATA_ONCE
;
fprintf
(
stderr
,
"title[%d] start=%d
\n
"
,
i
,
p_sys
->
p_sectors
[
1
+
i
]
);
fprintf
(
stderr
,
"title[%d] end=%d
\n
"
,
i
,
p_sys
->
p_sectors
[
i
+
2
]
);
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
b_pace_control
=
1
;
p_input
->
stream
.
b_seekable
=
1
;
p_input
->
stream
.
p_selected_area
->
i_size
=
0
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
0
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
t
->
i_size
=
(
p_sys
->
p_sectors
[
i
+
2
]
-
p_sys
->
p_sectors
[
i
+
1
]
)
*
(
int64_t
)
VCD_DATA_SIZE
;
}
/* We read the Table Of Content information */
p_sys
->
i_nb_tracks
=
ioctl_GetTracksMap
(
VLC_OBJECT
(
p_input
),
p_sys
->
vcddev
,
&
p_sys
->
p_sectors
);
if
(
p_sys
->
i_nb_tracks
<
0
)
msg_Err
(
p_input
,
"unable to count tracks"
);
else
if
(
p_sys
->
i_nb_tracks
<=
1
)
msg_Err
(
p_input
,
"no movie tracks found"
);
if
(
p_sys
->
i_nb_tracks
<=
1
)
{
ioctl_Close
(
p_this
,
p_sys
->
vcddev
);
free
(
p_sys
);
return
-
1
;
/* Map entry points into chapters */
if
(
EntryPoints
(
p_access
)
)
{
msg_Warn
(
p_access
,
"could not read entry points, will not use them"
);
}
/* Allocate the entry points table */
p_sys
->
p_entries
=
malloc
(
p_sys
->
i_nb_tracks
*
sizeof
(
int
)
);
/* Starting title/chapter and sector */
if
(
i_title
>=
p_sys
->
i_titles
)
i_title
=
0
;
if
(
i_chapter
>=
p_sys
->
title
[
i_title
]
->
i_seekpoint
)
i_chapter
=
0
;
if
(
p_sys
->
p_entries
==
NULL
)
p_sys
->
i_sector
=
p_sys
->
p_sectors
[
1
+
i_title
];
if
(
i_chapter
>
0
)
{
msg_Err
(
p_input
,
"not enough memory"
);
ioctl_Close
(
p_this
,
p_sys
->
vcddev
);
free
(
p_sys
);
int64_t
i_off
=
p_sys
->
title
[
i_title
]
->
seekpoint
[
i_chapter
]
->
i_byte_offset
;
p_sys
->
i_sector
+=
i_off
/
VCD_DATA_SIZE
;
}
p_access
->
info
.
i_title
=
i_title
;
p_access
->
info
.
i_seekpoint
=
i_chapter
;
p_access
->
info
.
i_size
=
p_sys
->
title
[
i_title
]
->
i_size
;
p_access
->
info
.
i_pos
=
(
p_sys
->
i_sector
-
p_sys
->
p_sectors
[
1
+
i_title
]
)
*
VCD_DATA_SIZE
;
/* Set stream and area data */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_access
->
psz_demux
=
strdup
(
"ps2"
);
/* Initialize ES structures */
input_InitStream
(
p_input
,
0
);
return
VLC_SUCCESS
;
/* disc input method */
p_input
->
stream
.
i_method
=
INPUT_METHOD_VCD
;
error:
ioctl_Close
(
VLC_OBJECT
(
p_access
),
p_sys
->
vcddev
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
p_input
->
stream
.
i_area_nb
=
1
;
/*****************************************************************************
* Close: closes vcd
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
{
access_t
*
p_access
=
(
access_t
*
)
p_this
;
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
ioctl_Close
(
p_this
,
p_sys
->
vcddev
);
free
(
p_sys
);
}
#define area p_input->stream.pp_areas
for
(
i
=
1
;
i
<
p_sys
->
i_nb_tracks
;
i
++
)
/*****************************************************************************
* Control:
*****************************************************************************/
static
int
Control
(
access_t
*
p_access
,
int
i_query
,
va_list
args
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
vlc_bool_t
*
pb_bool
;
int
*
pi_int
;
int64_t
*
pi_64
;
input_title_t
***
ppp_title
;
int
i
;
switch
(
i_query
)
{
/* Titles are Program Chains */
input_AddArea
(
p_input
,
i
,
1
);
/* */
case
ACCESS_CAN_SEEK
:
case
ACCESS_CAN_FASTSEEK
:
case
ACCESS_CAN_PAUSE
:
case
ACCESS_CAN_CONTROL_PACE
:
pb_bool
=
(
vlc_bool_t
*
)
va_arg
(
args
,
vlc_bool_t
*
);
*
pb_bool
=
VLC_TRUE
;
break
;
/* */
case
ACCESS_GET_MTU
:
pi_int
=
(
int
*
)
va_arg
(
args
,
int
*
);
*
pi_int
=
VCD_DATA_ONCE
;
break
;
case
ACCESS_GET_PTS_DELAY
:
pi_64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi_64
=
(
int64_t
)
var_GetInteger
(
p_access
,
"vcd-caching"
)
*
I64C
(
1000
);
break
;
/* */
case
ACCESS_SET_PAUSE_STATE
:
break
;
case
ACCESS_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_titles
;
*
ppp_title
=
malloc
(
sizeof
(
input_title_t
**
)
*
p_sys
->
i_titles
);
for
(
i
=
0
;
i
<
p_sys
->
i_titles
;
i
++
)
{
(
*
ppp_title
)[
i
]
=
vlc_input_title_Duplicate
(
p_sys
->
title
[
i
]
);
}
break
;
/* Absolute start offset and size */
area
[
i
]
->
i_start
=
(
off_t
)
p_sys
->
p_sectors
[
i
]
*
(
off_t
)
VCD_DATA_SIZE
;
area
[
i
]
->
i_size
=
(
off_t
)(
p_sys
->
p_sectors
[
i
+
1
]
-
p_sys
->
p_sectors
[
i
])
*
(
off_t
)
VCD_DATA_SIZE
;
case
ACCESS_SET_TITLE
:
i
=
(
int
)
va_arg
(
args
,
int
);
if
(
i
!=
p_access
->
info
.
i_title
)
{
/* Update info */
p_access
->
info
.
i_update
|=
INPUT_UPDATE_TITLE
|
INPUT_UPDATE_SEEKPOINT
|
INPUT_UPDATE_SIZE
;
p_access
->
info
.
i_title
=
i
;
p_access
->
info
.
i_seekpoint
=
0
;
p_access
->
info
.
i_size
=
p_sys
->
title
[
i
]
->
i_size
;
p_access
->
info
.
i_pos
=
0
;
/* Next sector to read */
p_sys
->
i_sector
=
p_sys
->
p_sectors
[
1
+
i
];
}
break
;
/* Default Chapter */
area
[
i
]
->
i_part
=
1
;
case
ACCESS_SET_SEEKPOINT
:
{
input_title_t
*
t
=
p_sys
->
title
[
p_access
->
info
.
i_title
];
i
=
(
int
)
va_arg
(
args
,
int
);
if
(
t
->
i_seekpoint
>
0
)
{
p_access
->
info
.
i_update
|=
INPUT_UPDATE_SEEKPOINT
;
p_access
->
info
.
i_seekpoint
=
i
;
p_sys
->
i_sector
=
p_sys
->
p_sectors
[
1
+
p_access
->
info
.
i_title
]
+
t
->
seekpoint
[
i
]
->
i_byte_offset
/
VCD_DATA_SIZE
;
p_access
->
info
.
i_pos
=
(
int64_t
)(
p_sys
->
i_sector
-
p_sys
->
p_sectors
[
1
+
p_access
->
info
.
i_title
]
)
*
(
int64_t
)
VCD_DATA_SIZE
;
}
return
VLC_SUCCESS
;
}
default:
msg_Err
(
p_access
,
"unimplemented query in control"
);
return
VLC_EGENERIC
;
/* i_plugin_data is used to store which entry point is the first
* of the track (area) */
area
[
i
]
->
i_plugin_data
=
0
;
}
#undef area
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Block:
*****************************************************************************/
static
block_t
*
Block
(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
i_skip
=
p_access
->
info
.
i_pos
%
VCD_DATA_SIZE
;
block_t
*
p_block
;
int
i_blocks
;
int
i_read
;
int
i
;
if
(
p_access
->
info
.
b_eof
)
return
NULL
;
p_area
=
p_input
->
stream
.
pp_areas
[
__MIN
(
i_title
,
p_sys
->
i_nb_tracks
-
1
)];
/* Read raw data */
i_blocks
=
VCD_BLOCKS_ONCE
;
p_sys
->
b_valid_ep
=
1
;
if
(
VCDEntryPoints
(
p_input
)
<
0
)
/* Don't read after a title */
if
(
p_sys
->
i_sector
+
i_blocks
>=
p_sys
->
p_sectors
[
p_access
->
info
.
i_title
+
2
]
)
{
msg_Warn
(
p_input
,
"could not read entry points, will not use them"
)
;
p_sys
->
b_valid_ep
=
0
;
i_blocks
=
p_sys
->
p_sectors
[
p_access
->
info
.
i_title
+
2
]
-
p_sys
->
i_sector
;
if
(
i_blocks
<=
0
)
i_blocks
=
1
;
/* Should never occur */
}
VCDSetArea
(
p_input
,
p_area
);
p_block
=
block_New
(
p_access
,
i_blocks
*
VCD_DATA_SIZE
);
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
if
(
ioctl_ReadSectors
(
VLC_OBJECT
(
p_access
),
p_sys
->
vcddev
,
p_sys
->
i_sector
,
p_block
->
p_buffer
,
i_blocks
,
VCD_TYPE
)
<
0
)
{
msg_Err
(
p_access
,
"cannot read a sector"
);
block_Release
(
p_block
);
if
(
!
p_input
->
psz_demux
||
!*
p_input
->
psz_demux
)
p_block
=
NULL
;
i_blocks
=
1
;
/* Next sector */
}
i_read
=
0
;
for
(
i
=
0
;
i
<
i_blocks
;
i
++
)
{
p_input
->
psz_demux
=
"ps"
;
input_title_t
*
t
=
p_sys
->
title
[
p_access
->
info
.
i_title
];
/* A good sector read */
i_read
++
;
p_sys
->
i_sector
++
;
/* Check end of title */
if
(
p_sys
->
i_sector
>=
p_sys
->
p_sectors
[
p_access
->
info
.
i_title
+
2
]
)
{
if
(
p_access
->
info
.
i_title
+
2
>=
p_sys
->
i_titles
)
{
p_access
->
info
.
b_eof
=
VLC_TRUE
;
break
;
}
p_access
->
info
.
i_update
|=
INPUT_UPDATE_TITLE
|
INPUT_UPDATE_SEEKPOINT
|
INPUT_UPDATE_SIZE
;
p_access
->
info
.
i_title
++
;
p_access
->
info
.
i_seekpoint
=
0
;
p_access
->
info
.
i_size
=
p_sys
->
title
[
p_access
->
info
.
i_title
]
->
i_size
;
p_access
->
info
.
i_pos
=
0
;
}
else
if
(
t
->
i_seekpoint
>
0
&&
p_access
->
info
.
i_seekpoint
+
1
<
t
->
i_seekpoint
&&
p_access
->
info
.
i_pos
-
i_skip
+
i_read
*
VCD_DATA_SIZE
>=
t
->
seekpoint
[
p_access
->
info
.
i_seekpoint
+
1
]
->
i_byte_offset
)
{
fprintf
(
stderr
,
"seekpoint change
\n
"
);
p_access
->
info
.
i_update
|=
INPUT_UPDATE_SEEKPOINT
;
p_access
->
info
.
i_seekpoint
++
;
}
/* TODO */
}
p_input
->
pf_read
=
VCDRead
;
p_input
->
pf_seek
=
VCDSeek
;
p_input
->
pf_set_area
=
VCDSetArea
;
p_input
->
pf_set_program
=
VCDSetProgram
;
if
(
i_read
<=
0
)
{
block_Release
(
p_block
);
return
NULL
;
}
return
0
;
if
(
p_block
)
{
/* Really read data */
p_block
->
i_buffer
=
i_read
*
VCD_DATA_SIZE
;
/* */
p_block
->
i_buffer
-=
i_skip
;
p_block
->
p_buffer
+=
i_skip
;
p_access
->
info
.
i_pos
+=
p_block
->
i_buffer
;
}
return
p_block
;
}
/*****************************************************************************
*
VCDClose: closes vcd
*
Seek:
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_thi
s
)
static
int
Seek
(
access_t
*
p_access
,
int64_t
i_po
s
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
return
VLC_EGENERIC
;
}
ioctl_Close
(
p_this
,
p_sys
->
vcddev
);
free
(
p_sys
);
/*****************************************************************************
* EntryPoints:
*****************************************************************************/
static
int
EntryPoints
(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
uint8_t
sector
[
VCD_DATA_SIZE
];
entries_sect_t
entries
;
int
i_nb
;
int
i
;
/* Read the entry point sector */
if
(
ioctl_ReadSectors
(
VLC_OBJECT
(
p_access
),
p_sys
->
vcddev
,
VCD_ENTRIES_SECTOR
,
sector
,
1
,
VCD_TYPE
)
<
0
)
{
msg_Err
(
p_access
,
"could not read entry points sector"
);
return
VLC_EGENERIC
;
}
memcpy
(
&
entries
,
sector
,
CD_SECTOR_SIZE
);
i_nb
=
GetWBE
(
&
entries
.
i_entries_nb
);
if
(
i_nb
>
500
)
{
msg_Err
(
p_access
,
"invalid entry points number"
);
return
VLC_EGENERIC
;
}
if
(
strncmp
(
entries
.
psz_id
,
"ENTRYVCD"
,
sizeof
(
entries
.
psz_id
)
)
&&
strncmp
(
entries
.
psz_id
,
"ENTRYSVD"
,
sizeof
(
entries
.
psz_id
)
)
)
{
msg_Err
(
p_access
,
"unrecognized entry points format"
);
return
VLC_EGENERIC
;
}
for
(
i
=
0
;
i
<
i_nb
;
i
++
)
{
const
int
i_title
=
BCD_TO_BIN
(
entries
.
entry
[
i
].
i_track
)
-
2
;
const
int
i_sector
=
(
MSF_TO_LBA2
(
BCD_TO_BIN
(
entries
.
entry
[
i
].
msf
.
minute
),
BCD_TO_BIN
(
entries
.
entry
[
i
].
msf
.
second
),
BCD_TO_BIN
(
entries
.
entry
[
i
].
msf
.
frame
)
));
seekpoint_t
*
s
;
if
(
i_title
<
0
)
continue
;
/* Should not occur */
if
(
i_title
>=
p_sys
->
i_titles
)
continue
;
fprintf
(
stderr
,
"Entry[%d] title=%d sector=%d
\n
"
,
i
,
i_title
,
i_sector
);
s
=
vlc_seekpoint_New
();
s
->
i_byte_offset
=
(
i_sector
-
p_sys
->
p_sectors
[
i_title
+
1
])
*
VCD_DATA_SIZE
;
TAB_APPEND
(
p_sys
->
title
[
i_title
]
->
i_seekpoint
,
p_sys
->
title
[
i_title
]
->
seekpoint
,
s
);
}
#if 0
#define i_track BCD_TO_BIN(entries.entry[i].i_track)
/* Reset the i_part_nb for each track */
for( i = 0 ; i < i_nb ; i++ )
{
if( i_track <= p_input->stream.i_area_nb )
{
p_input->stream.pp_areas[i_track-1]->i_part_nb = 0;
}
}
for( i = 0 ; i < i_nb ; i++ )
{
if( i_track <= p_input->stream.i_area_nb )
{
p_sys->p_entries[i_entry_index] =
(MSF_TO_LBA2( BCD_TO_BIN( entries.entry[i].msf.minute ),
BCD_TO_BIN( entries.entry[i].msf.second ),
BCD_TO_BIN( entries.entry[i].msf.frame ) ));
p_input->stream.pp_areas[i_track-1]->i_part_nb ++;
/* if this entry belongs to a new track */
if( i_track != i_previous_track )
{
/* i_plugin_data is used to store the first entry of the area*/
p_input->stream.pp_areas[i_track-1]->i_plugin_data =
i_entry_index;
i_previous_track = i_track;
}
msg_Dbg( p_input, "entry point %i begins at LBA: %i",
i_entry_index, p_sys->p_entries[i_entry_index] );
i_entry_index ++;
p_sys->i_entries_nb ++;
}
else
msg_Warn( p_input, "wrong track number found in entry points" );
}
#undef i_track
return 0;
#endif
return
VLC_EGENERIC
;
}
#if 0
/*****************************************************************************
* VCDRead: reads from the VCD into PES packets.
*****************************************************************************
...
...
@@ -546,3 +822,4 @@ static int VCDEntryPoints( input_thread_t * p_input )
#undef i_track
return 0;
}
#endif
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