Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
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-1.1
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