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
fccffe2f
Commit
fccffe2f
authored
Sep 01, 2015
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
access: keep read offset in private data
parent
11138293
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
102 additions
and
69 deletions
+102
-69
modules/access/attachment.c
modules/access/attachment.c
+36
-15
modules/access/ftp.c
modules/access/ftp.c
+10
-6
modules/access/http.c
modules/access/http.c
+10
-9
modules/access/mms/mmsh.c
modules/access/mms/mmsh.c
+10
-9
modules/access/mms/mmsh.h
modules/access/mms/mmsh.h
+1
-0
modules/access/mms/mmstu.c
modules/access/mms/mmstu.c
+10
-10
modules/access/mms/mmstu.h
modules/access/mms/mmstu.h
+1
-0
modules/access/rar/access.c
modules/access/rar/access.c
+6
-5
modules/access/vcd/vcd.c
modules/access/vcd/vcd.c
+12
-10
modules/access/vdr.c
modules/access/vdr.c
+6
-5
No files found.
modules/access/attachment.c
View file @
fccffe2f
...
@@ -58,6 +58,12 @@ static ssize_t Read(access_t *, uint8_t *, size_t);
...
@@ -58,6 +58,12 @@ static ssize_t Read(access_t *, uint8_t *, size_t);
static
int
Seek
(
access_t
*
,
uint64_t
);
static
int
Seek
(
access_t
*
,
uint64_t
);
static
int
Control
(
access_t
*
,
int
,
va_list
);
static
int
Control
(
access_t
*
,
int
,
va_list
);
struct
access_sys_t
{
input_attachment_t
*
attachment
;
size_t
offset
;
};
/* */
/* */
static
int
Open
(
vlc_object_t
*
object
)
static
int
Open
(
vlc_object_t
*
object
)
{
{
...
@@ -67,23 +73,30 @@ static int Open(vlc_object_t *object)
...
@@ -67,23 +73,30 @@ static int Open(vlc_object_t *object)
if
(
!
input
)
if
(
!
input
)
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
input_attachment_t
*
a
;
access_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
if
(
input_Control
(
input
,
INPUT_GET_ATTACHMENT
,
&
a
,
access
->
psz_location
))
if
(
unlikely
(
sys
==
NULL
))
a
=
NULL
;
return
VLC_ENOMEM
;
if
(
input_Control
(
input
,
INPUT_GET_ATTACHMENT
,
&
sys
->
attachment
,
access
->
psz_location
))
sys
->
attachment
=
NULL
;
if
(
!
a
)
{
if
(
sys
->
attachment
==
NULL
)
{
msg_Err
(
access
,
"Failed to find the attachment '%s'"
,
msg_Err
(
access
,
"Failed to find the attachment '%s'"
,
access
->
psz_location
);
access
->
psz_location
);
free
(
sys
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
sys
->
offset
=
0
;
/* */
/* */
access_InitFields
(
access
);
access_InitFields
(
access
);
access
->
pf_read
=
Read
;
access
->
pf_read
=
Read
;
access
->
pf_block
=
NULL
;
access
->
pf_block
=
NULL
;
access
->
pf_control
=
Control
;
access
->
pf_control
=
Control
;
access
->
pf_seek
=
Seek
;
access
->
pf_seek
=
Seek
;
access
->
p_sys
=
(
void
*
)
a
;
access
->
p_sys
=
sys
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -91,30 +104,38 @@ static int Open(vlc_object_t *object)
...
@@ -91,30 +104,38 @@ static int Open(vlc_object_t *object)
static
void
Close
(
vlc_object_t
*
object
)
static
void
Close
(
vlc_object_t
*
object
)
{
{
access_t
*
access
=
(
access_t
*
)
object
;
access_t
*
access
=
(
access_t
*
)
object
;
input_attachment_t
*
a
=
(
void
*
)
access
->
p_sys
;
access_sys_t
*
sys
=
access
->
p_sys
;
vlc_input_attachment_Delete
(
a
);
vlc_input_attachment_Delete
(
sys
->
attachment
);
free
(
sys
);
}
}
/* */
/* */
static
ssize_t
Read
(
access_t
*
access
,
uint8_t
*
buffer
,
size_t
size
)
static
ssize_t
Read
(
access_t
*
access
,
uint8_t
*
buffer
,
size_t
size
)
{
{
input_attachment_t
*
a
=
(
void
*
)
access
->
p_sys
;
access_sys_t
*
sys
=
access
->
p_sys
;
input_attachment_t
*
a
=
sys
->
attachment
;
access
->
info
.
b_eof
=
access
->
info
.
i_pos
>=
(
uint64_t
)
a
->
i_data
;
access
->
info
.
b_eof
=
sys
->
offset
>=
(
uint64_t
)
a
->
i_data
;
if
(
access
->
info
.
b_eof
)
if
(
access
->
info
.
b_eof
)
return
0
;
return
0
;
const
size_t
copy
=
__MIN
(
size
,
a
->
i_data
-
access
->
info
.
i_pos
);
const
size_t
copy
=
__MIN
(
size
,
a
->
i_data
-
sys
->
offset
);
memcpy
(
buffer
,
(
uint8_t
*
)
a
->
p_data
+
access
->
info
.
i_pos
,
copy
);
memcpy
(
buffer
,
(
uint8_t
*
)
a
->
p_data
+
sys
->
offset
,
copy
);
access
->
info
.
i_pos
+=
copy
;
sys
->
offset
+=
copy
;
return
copy
;
return
copy
;
}
}
/* */
/* */
static
int
Seek
(
access_t
*
access
,
uint64_t
position
)
static
int
Seek
(
access_t
*
access
,
uint64_t
position
)
{
{
access
->
info
.
i_pos
=
position
;
access_sys_t
*
sys
=
access
->
p_sys
;
input_attachment_t
*
a
=
sys
->
attachment
;
if
(
position
>
a
->
i_data
)
position
=
a
->
i_data
;
sys
->
offset
=
position
;
access
->
info
.
b_eof
=
false
;
access
->
info
.
b_eof
=
false
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -122,7 +143,7 @@ static int Seek(access_t *access, uint64_t position)
...
@@ -122,7 +143,7 @@ static int Seek(access_t *access, uint64_t position)
/* */
/* */
static
int
Control
(
access_t
*
access
,
int
query
,
va_list
args
)
static
int
Control
(
access_t
*
access
,
int
query
,
va_list
args
)
{
{
input_attachment_t
*
a
=
(
void
*
)
access
->
p_sys
;
access_sys_t
*
sys
=
access
->
p_sys
;
switch
(
query
)
switch
(
query
)
{
{
...
@@ -133,7 +154,7 @@ static int Control(access_t *access, int query, va_list args)
...
@@ -133,7 +154,7 @@ static int Control(access_t *access, int query, va_list args)
*
va_arg
(
args
,
bool
*
)
=
true
;
*
va_arg
(
args
,
bool
*
)
=
true
;
break
;
break
;
case
ACCESS_GET_SIZE
:
case
ACCESS_GET_SIZE
:
*
va_arg
(
args
,
uint64_t
*
)
=
a
->
i_data
;
*
va_arg
(
args
,
uint64_t
*
)
=
sys
->
attachment
->
i_data
;
break
;
break
;
case
ACCESS_GET_PTS_DELAY
:
case
ACCESS_GET_PTS_DELAY
:
*
va_arg
(
args
,
int64_t
*
)
=
DEFAULT_PTS_DELAY
;
*
va_arg
(
args
,
int64_t
*
)
=
DEFAULT_PTS_DELAY
;
...
...
modules/access/ftp.c
View file @
fccffe2f
...
@@ -143,6 +143,7 @@ struct access_sys_t
...
@@ -143,6 +143,7 @@ struct access_sys_t
char
sz_epsv_ip
[
NI_MAXNUMERICHOST
];
char
sz_epsv_ip
[
NI_MAXNUMERICHOST
];
bool
out
;
bool
out
;
uint64_t
offset
;
uint64_t
size
;
uint64_t
size
;
};
};
#define GET_OUT_SYS( p_this ) \
#define GET_OUT_SYS( p_this ) \
...
@@ -632,6 +633,7 @@ static int InOpen( vlc_object_t *p_this )
...
@@ -632,6 +633,7 @@ static int InOpen( vlc_object_t *p_this )
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
p_sys
->
data
.
fd
=
-
1
;
p_sys
->
data
.
fd
=
-
1
;
p_sys
->
out
=
false
;
p_sys
->
out
=
false
;
p_sys
->
offset
=
0
;
p_sys
->
size
=
UINT64_MAX
;
p_sys
->
size
=
UINT64_MAX
;
readTLSMode
(
p_sys
,
p_access
->
psz_access
);
readTLSMode
(
p_sys
,
p_access
->
psz_access
);
...
@@ -797,12 +799,14 @@ static int _Seek( vlc_object_t *p_access, access_sys_t *p_sys, uint64_t i_pos )
...
@@ -797,12 +799,14 @@ static int _Seek( vlc_object_t *p_access, access_sys_t *p_sys, uint64_t i_pos )
static
int
Seek
(
access_t
*
p_access
,
uint64_t
i_pos
)
static
int
Seek
(
access_t
*
p_access
,
uint64_t
i_pos
)
{
{
int
val
=
_Seek
(
(
vlc_object_t
*
)
p_access
,
p_access
->
p_sys
,
i_pos
);
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
int
val
=
_Seek
(
(
vlc_object_t
*
)
p_access
,
p_sys
,
i_pos
);
if
(
val
)
if
(
val
)
return
val
;
return
val
;
p_access
->
info
.
b_eof
=
false
;
p_access
->
info
.
b_eof
=
false
;
p_
access
->
info
.
i_pos
=
i_pos
;
p_
sys
->
offset
=
i_pos
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -833,10 +837,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
...
@@ -833,10 +837,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
else
else
i_read
=
vlc_recv_i11e
(
p_sys
->
data
.
fd
,
p_buffer
,
i_len
,
0
);
i_read
=
vlc_recv_i11e
(
p_sys
->
data
.
fd
,
p_buffer
,
i_len
,
0
);
if
(
i_read
==
0
)
if
(
i_read
>
0
)
p_sys
->
offset
+=
i_read
;
else
if
(
i_read
==
0
)
p_access
->
info
.
b_eof
=
true
;
p_access
->
info
.
b_eof
=
true
;
else
if
(
i_read
>
0
)
p_access
->
info
.
i_pos
+=
i_read
;
else
if
(
errno
!=
EINTR
&&
errno
!=
EAGAIN
)
else
if
(
errno
!=
EINTR
&&
errno
!=
EAGAIN
)
{
{
msg_Err
(
p_access
,
"receive error: %s"
,
vlc_strerror_c
(
errno
)
);
msg_Err
(
p_access
,
"receive error: %s"
,
vlc_strerror_c
(
errno
)
);
...
@@ -954,7 +958,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
...
@@ -954,7 +958,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
case
ACCESS_SET_PAUSE_STATE
:
case
ACCESS_SET_PAUSE_STATE
:
pb_bool
=
(
bool
*
)
va_arg
(
args
,
bool
*
);
pb_bool
=
(
bool
*
)
va_arg
(
args
,
bool
*
);
if
(
!
pb_bool
)
if
(
!
pb_bool
)
return
Seek
(
p_access
,
p_access
->
info
.
i_pos
);
return
Seek
(
p_access
,
p_access
->
p_sys
->
offset
);
break
;
break
;
default:
default:
...
...
modules/access/http.c
View file @
fccffe2f
...
@@ -174,6 +174,7 @@ struct access_sys_t
...
@@ -174,6 +174,7 @@ struct access_sys_t
char
*
psz_icy_title
;
char
*
psz_icy_title
;
uint64_t
i_remaining
;
uint64_t
i_remaining
;
uint64_t
offset
;
uint64_t
size
;
uint64_t
size
;
/* cookie jar borrowed from playlist, do not free */
/* cookie jar borrowed from playlist, do not free */
...
@@ -270,8 +271,8 @@ static int OpenRedirected( vlc_object_t *p_this, const char *psz_access,
...
@@ -270,8 +271,8 @@ static int OpenRedirected( vlc_object_t *p_this, const char *psz_access,
p_sys
->
i_remaining
=
0
;
p_sys
->
i_remaining
=
0
;
p_sys
->
b_persist
=
false
;
p_sys
->
b_persist
=
false
;
p_sys
->
b_has_size
=
false
;
p_sys
->
b_has_size
=
false
;
p_sys
->
offset
=
0
;
p_sys
->
size
=
0
;
p_sys
->
size
=
0
;
p_access
->
info
.
i_pos
=
0
;
p_access
->
info
.
b_eof
=
false
;
p_access
->
info
.
b_eof
=
false
;
/* Only forward an store cookies if the corresponding option is activated */
/* Only forward an store cookies if the corresponding option is activated */
...
@@ -658,7 +659,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
...
@@ -658,7 +659,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if
(
p_sys
->
b_has_size
)
if
(
p_sys
->
b_has_size
)
{
{
/* Remaining bytes in the file */
/* Remaining bytes in the file */
uint64_t
remainder
=
p_sys
->
size
-
p_
access
->
info
.
i_pos
;
uint64_t
remainder
=
p_sys
->
size
-
p_
sys
->
offset
;
if
(
remainder
<
i_len
)
if
(
remainder
<
i_len
)
i_len
=
remainder
;
i_len
=
remainder
;
...
@@ -669,10 +670,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
...
@@ -669,10 +670,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if
(
i_len
==
0
)
if
(
i_len
==
0
)
goto
fatal
;
goto
fatal
;
if
(
p_sys
->
i_icy_meta
>
0
&&
p_
access
->
info
.
i_pos
-
p_sys
->
i_icy_offset
>
0
)
if
(
p_sys
->
i_icy_meta
>
0
&&
p_
sys
->
offset
-
p_sys
->
i_icy_offset
>
0
)
{
{
int64_t
i_next
=
p_sys
->
i_icy_meta
-
int64_t
i_next
=
p_sys
->
i_icy_meta
-
(
p_
access
->
info
.
i_pos
-
p_sys
->
i_icy_offset
)
%
p_sys
->
i_icy_meta
;
(
p_
sys
->
offset
-
p_sys
->
i_icy_offset
)
%
p_sys
->
i_icy_meta
;
if
(
i_next
==
p_sys
->
i_icy_meta
)
if
(
i_next
==
p_sys
->
i_icy_meta
)
{
{
...
@@ -705,7 +706,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
...
@@ -705,7 +706,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if
(
p_sys
->
b_reconnect
)
if
(
p_sys
->
b_reconnect
)
{
{
msg_Dbg
(
p_access
,
"got disconnected, trying to reconnect"
);
msg_Dbg
(
p_access
,
"got disconnected, trying to reconnect"
);
if
(
Connect
(
p_access
,
p_
access
->
info
.
i_pos
)
)
if
(
Connect
(
p_access
,
p_
sys
->
offset
)
)
{
{
msg_Dbg
(
p_access
,
"reconnection failed"
);
msg_Dbg
(
p_access
,
"reconnection failed"
);
}
}
...
@@ -728,10 +729,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
...
@@ -728,10 +729,10 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
}
}
assert
(
i_read
>=
0
);
assert
(
i_read
>=
0
);
p_
access
->
info
.
i_pos
+=
i_read
;
p_
sys
->
offset
+=
i_read
;
if
(
p_sys
->
b_has_size
)
if
(
p_sys
->
b_has_size
)
{
{
assert
(
p_
access
->
info
.
i_pos
<=
p_sys
->
size
);
assert
(
p_
sys
->
offset
<=
p_sys
->
size
);
assert
(
(
unsigned
)
i_read
<=
p_sys
->
i_remaining
);
assert
(
(
unsigned
)
i_read
<=
p_sys
->
i_remaining
);
p_sys
->
i_remaining
-=
i_read
;
p_sys
->
i_remaining
-=
i_read
;
}
}
...
@@ -1015,8 +1016,8 @@ static int Connect( access_t *p_access, uint64_t i_tell )
...
@@ -1015,8 +1016,8 @@ static int Connect( access_t *p_access, uint64_t i_tell )
p_sys
->
i_remaining
=
0
;
p_sys
->
i_remaining
=
0
;
p_sys
->
b_persist
=
false
;
p_sys
->
b_persist
=
false
;
p_sys
->
b_has_size
=
false
;
p_sys
->
b_has_size
=
false
;
p_sys
->
offset
=
i_tell
;
p_sys
->
size
=
0
;
p_sys
->
size
=
0
;
p_access
->
info
.
i_pos
=
i_tell
;
p_access
->
info
.
b_eof
=
false
;
p_access
->
info
.
b_eof
=
false
;
/* Open connection */
/* Open connection */
...
@@ -1296,7 +1297,7 @@ static int Request( access_t *p_access, uint64_t i_tell )
...
@@ -1296,7 +1297,7 @@ static int Request( access_t *p_access, uint64_t i_tell )
uint64_t
i_nsize
=
p_sys
->
size
;
uint64_t
i_nsize
=
p_sys
->
size
;
sscanf
(
p
,
"bytes %"
SCNu64
"-%"
SCNu64
"/%"
SCNu64
,
&
i_ntell
,
&
i_nend
,
&
i_nsize
);
sscanf
(
p
,
"bytes %"
SCNu64
"-%"
SCNu64
"/%"
SCNu64
,
&
i_ntell
,
&
i_nend
,
&
i_nsize
);
if
(
i_nend
>
i_ntell
)
{
if
(
i_nend
>
i_ntell
)
{
p_
access
->
info
.
i_pos
=
i_ntell
;
p_
sys
->
offset
=
i_ntell
;
p_sys
->
i_icy_offset
=
i_ntell
;
p_sys
->
i_icy_offset
=
i_ntell
;
p_sys
->
i_remaining
=
i_nend
+
1
-
i_ntell
;
p_sys
->
i_remaining
=
i_nend
+
1
-
i_ntell
;
uint64_t
i_size
=
(
i_nsize
>
i_nend
)
?
i_nsize
:
(
i_nend
+
1
);
uint64_t
i_size
=
(
i_nsize
>
i_nend
)
?
i_nsize
:
(
i_nend
+
1
);
...
...
modules/access/mms/mmsh.c
View file @
fccffe2f
...
@@ -84,6 +84,7 @@ int MMSHOpen( access_t *p_access )
...
@@ -84,6 +84,7 @@ int MMSHOpen( access_t *p_access )
p_sys
->
i_proto
=
MMS_PROTO_HTTP
;
p_sys
->
i_proto
=
MMS_PROTO_HTTP
;
p_sys
->
fd
=
-
1
;
p_sys
->
fd
=
-
1
;
p_sys
->
i_position
=
0
;
/* Handle proxy */
/* Handle proxy */
p_sys
->
b_proxy
=
false
;
p_sys
->
b_proxy
=
false
;
...
@@ -296,7 +297,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
...
@@ -296,7 +297,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
p_sys
->
asfh
.
stream
[
i_int
].
i_selected
=
true
;
p_sys
->
asfh
.
stream
[
i_int
].
i_selected
=
true
;
Stop
(
p_access
);
Stop
(
p_access
);
Seek
(
p_access
,
p_
access
->
info
.
i_pos
);
Seek
(
p_access
,
p_
sys
->
i_position
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -305,7 +306,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
...
@@ -305,7 +306,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
if
(
b_bool
)
if
(
b_bool
)
Stop
(
p_access
);
Stop
(
p_access
);
else
else
Seek
(
p_access
,
p_
access
->
info
.
i_pos
);
Seek
(
p_access
,
p_
sys
->
i_position
);
break
;
break
;
default:
default:
...
@@ -344,7 +345,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
...
@@ -344,7 +345,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
msg_Warn
(
p_access
,
"skipping header"
);
msg_Warn
(
p_access
,
"skipping header"
);
}
}
p_
access
->
info
.
i_pos
=
i_pos
;
p_
sys
->
i_position
=
i_pos
;
p_access
->
info
.
b_eof
=
false
;
p_access
->
info
.
b_eof
=
false
;
p_sys
->
i_packet_used
+=
i_offset
;
p_sys
->
i_packet_used
+=
i_offset
;
...
@@ -368,9 +369,9 @@ static block_t *Block( access_t *p_access )
...
@@ -368,9 +369,9 @@ static block_t *Block( access_t *p_access )
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
const
unsigned
i_packet_min
=
p_sys
->
asfh
.
i_min_data_packet_size
;
const
unsigned
i_packet_min
=
p_sys
->
asfh
.
i_min_data_packet_size
;
if
(
p_
access
->
info
.
i_pos
<
p_sys
->
i_start
+
p_sys
->
i_header
)
if
(
p_
sys
->
i_position
<
p_sys
->
i_start
+
p_sys
->
i_header
)
{
{
const
size_t
i_offset
=
p_
access
->
info
.
i_pos
-
p_sys
->
i_start
;
const
size_t
i_offset
=
p_
sys
->
i_position
-
p_sys
->
i_start
;
const
size_t
i_copy
=
p_sys
->
i_header
-
i_offset
;
const
size_t
i_copy
=
p_sys
->
i_header
-
i_offset
;
block_t
*
p_block
=
block_Alloc
(
i_copy
);
block_t
*
p_block
=
block_Alloc
(
i_copy
);
...
@@ -378,7 +379,7 @@ static block_t *Block( access_t *p_access )
...
@@ -378,7 +379,7 @@ static block_t *Block( access_t *p_access )
return
NULL
;
return
NULL
;
memcpy
(
p_block
->
p_buffer
,
&
p_sys
->
p_header
[
i_offset
],
i_copy
);
memcpy
(
p_block
->
p_buffer
,
&
p_sys
->
p_header
[
i_offset
],
i_copy
);
p_
access
->
info
.
i_pos
+=
i_copy
;
p_
sys
->
i_position
+=
i_copy
;
return
p_block
;
return
p_block
;
}
}
else
if
(
p_sys
->
i_packet_length
>
0
&&
else
if
(
p_sys
->
i_packet_length
>
0
&&
...
@@ -402,7 +403,7 @@ static block_t *Block( access_t *p_access )
...
@@ -402,7 +403,7 @@ static block_t *Block( access_t *p_access )
memset
(
&
p_block
->
p_buffer
[
i_copy
],
0
,
i_padding
);
memset
(
&
p_block
->
p_buffer
[
i_copy
],
0
,
i_padding
);
p_sys
->
i_packet_used
+=
i_copy
+
i_padding
;
p_sys
->
i_packet_used
+=
i_copy
+
i_padding
;
p_
access
->
info
.
i_pos
+=
i_copy
+
i_padding
;
p_
sys
->
i_position
+=
i_copy
+
i_padding
;
return
p_block
;
return
p_block
;
}
}
...
@@ -440,7 +441,7 @@ static int Restart( access_t *p_access )
...
@@ -440,7 +441,7 @@ static int Restart( access_t *p_access )
char
*
psz_location
=
NULL
;
char
*
psz_location
=
NULL
;
msg_Dbg
(
p_access
,
"Restart the stream"
);
msg_Dbg
(
p_access
,
"Restart the stream"
);
p_sys
->
i_start
=
p_
access
->
info
.
i_pos
;
p_sys
->
i_start
=
p_
sys
->
i_position
;
/* */
/* */
msg_Dbg
(
p_access
,
"stoping the stream"
);
msg_Dbg
(
p_access
,
"stoping the stream"
);
...
@@ -470,7 +471,7 @@ static int Reset( access_t *p_access )
...
@@ -470,7 +471,7 @@ static int Reset( access_t *p_access )
int
i
;
int
i
;
msg_Dbg
(
p_access
,
"Reset the stream"
);
msg_Dbg
(
p_access
,
"Reset the stream"
);
p_sys
->
i_start
=
p_
access
->
info
.
i_pos
;
p_sys
->
i_start
=
p_
sys
->
i_position
;
/* */
/* */
p_sys
->
i_packet_sequence
=
0
;
p_sys
->
i_packet_sequence
=
0
;
...
...
modules/access/mms/mmsh.h
View file @
fccffe2f
...
@@ -65,6 +65,7 @@ struct access_sys_t
...
@@ -65,6 +65,7 @@ struct access_sys_t
unsigned
int
i_packet_length
;
unsigned
int
i_packet_length
;
uint64_t
i_start
;
uint64_t
i_start
;
uint64_t
i_position
;
asf_header_t
asfh
;
asf_header_t
asfh
;
guid_t
guid
;
guid_t
guid
;
...
...
modules/access/mms/mmstu.c
View file @
fccffe2f
...
@@ -277,7 +277,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
...
@@ -277,7 +277,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
else
else
{
{
KeepAliveStop
(
p_access
);
KeepAliveStop
(
p_access
);
Seek
(
p_access
,
p_
access
->
info
.
i_pos
);
Seek
(
p_access
,
p_
sys
->
i_position
);
}
}
break
;
break
;
...
@@ -299,11 +299,11 @@ static int Seek( access_t * p_access, uint64_t i_pos )
...
@@ -299,11 +299,11 @@ static int Seek( access_t * p_access, uint64_t i_pos )
if
(
i_pos
<
p_sys
->
i_header
)
if
(
i_pos
<
p_sys
->
i_header
)
{
{
if
(
p_
access
->
info
.
i_pos
<
p_sys
->
i_header
)
if
(
p_
sys
->
i_position
<
p_sys
->
i_header
)
{
{
/* no need to restart stream, it was already one
/* no need to restart stream, it was already one
* or no stream was yet read */
* or no stream was yet read */
p_
access
->
info
.
i_pos
=
i_pos
;
p_
sys
->
i_position
=
i_pos
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
else
else
...
@@ -381,7 +381,7 @@ static int Seek( access_t * p_access, uint64_t i_pos )
...
@@ -381,7 +381,7 @@ static int Seek( access_t * p_access, uint64_t i_pos )
msg_Dbg
(
p_access
,
"Streaming restarted"
);
msg_Dbg
(
p_access
,
"Streaming restarted"
);
p_sys
->
i_media_used
+=
i_offset
;
p_sys
->
i_media_used
+=
i_offset
;
p_
access
->
info
.
i_pos
=
i_pos
;
p_
sys
->
i_position
=
i_pos
;
p_access
->
info
.
b_eof
=
false
;
p_access
->
info
.
b_eof
=
false
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
...
@@ -397,16 +397,16 @@ static block_t *Block( access_t *p_access )
...
@@ -397,16 +397,16 @@ static block_t *Block( access_t *p_access )
if
(
p_access
->
info
.
b_eof
)
if
(
p_access
->
info
.
b_eof
)
return
NULL
;
return
NULL
;
if
(
p_
access
->
info
.
i_pos
<
p_sys
->
i_header
)
if
(
p_
sys
->
i_position
<
p_sys
->
i_header
)
{
{
const
size_t
i_copy
=
p_sys
->
i_header
-
p_
access
->
info
.
i_pos
;
const
size_t
i_copy
=
p_sys
->
i_header
-
p_
sys
->
i_position
;
block_t
*
p_block
=
block_Alloc
(
i_copy
);
block_t
*
p_block
=
block_Alloc
(
i_copy
);
if
(
!
p_block
)
if
(
!
p_block
)
return
NULL
;
return
NULL
;
memcpy
(
p_block
->
p_buffer
,
&
p_sys
->
p_header
[
p_
access
->
info
.
i_pos
],
i_copy
);
memcpy
(
p_block
->
p_buffer
,
&
p_sys
->
p_header
[
p_
sys
->
i_position
],
i_copy
);
p_
access
->
info
.
i_pos
+=
i_copy
;
p_
sys
->
i_position
+=
i_copy
;
return
p_block
;
return
p_block
;
}
}
else
if
(
p_sys
->
p_media
&&
p_sys
->
i_media_used
<
__MAX
(
p_sys
->
i_media
,
p_sys
->
i_packet_length
)
)
else
if
(
p_sys
->
p_media
&&
p_sys
->
i_media_used
<
__MAX
(
p_sys
->
i_media
,
p_sys
->
i_packet_length
)
)
...
@@ -429,7 +429,7 @@ static block_t *Block( access_t *p_access )
...
@@ -429,7 +429,7 @@ static block_t *Block( access_t *p_access )
memset
(
&
p_block
->
p_buffer
[
i_copy
],
0
,
i_padding
);
memset
(
&
p_block
->
p_buffer
[
i_copy
],
0
,
i_padding
);
p_sys
->
i_media_used
+=
i_copy
+
i_padding
;
p_sys
->
i_media_used
+=
i_copy
+
i_padding
;
p_
access
->
info
.
i_pos
+=
i_copy
+
i_padding
;
p_
sys
->
i_position
+=
i_copy
+
i_padding
;
return
p_block
;
return
p_block
;
}
}
...
@@ -511,7 +511,7 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto )
...
@@ -511,7 +511,7 @@ static int MMSOpen( access_t *p_access, vlc_url_t *p_url, int i_proto )
p_sys
->
i_media
=
0
;
p_sys
->
i_media
=
0
;
p_sys
->
i_media_used
=
0
;
p_sys
->
i_media_used
=
0
;
p_
access
->
info
.
i_pos
=
0
;
p_
sys
->
i_position
=
0
;
p_sys
->
i_buffer_tcp
=
0
;
p_sys
->
i_buffer_tcp
=
0
;
p_sys
->
i_buffer_udp
=
0
;
p_sys
->
i_buffer_udp
=
0
;
p_sys
->
p_cmd
=
NULL
;
p_sys
->
p_cmd
=
NULL
;
...
...
modules/access/mms/mmstu.h
View file @
fccffe2f
...
@@ -43,6 +43,7 @@ struct access_sys_t
...
@@ -43,6 +43,7 @@ struct access_sys_t
char
sz_bind_addr
[
NI_MAXNUMERICHOST
];
/* used by udp */
char
sz_bind_addr
[
NI_MAXNUMERICHOST
];
/* used by udp */
vlc_url_t
url
;
vlc_url_t
url
;
uint64_t
i_position
;
uint64_t
i_size
;
uint64_t
i_size
;
asf_header_t
asfh
;
asf_header_t
asfh
;
...
...
modules/access/rar/access.c
View file @
fccffe2f
...
@@ -40,6 +40,7 @@ struct access_sys_t {
...
@@ -40,6 +40,7 @@ struct access_sys_t {
stream_t
*
s
;
stream_t
*
s
;
rar_file_t
*
file
;
rar_file_t
*
file
;
const
rar_file_chunk_t
*
chunk
;
const
rar_file_chunk_t
*
chunk
;
uint64_t
position
;
};
};
static
int
Seek
(
access_t
*
access
,
uint64_t
position
)
static
int
Seek
(
access_t
*
access
,
uint64_t
position
)
...
@@ -49,6 +50,7 @@ static int Seek(access_t *access, uint64_t position)
...
@@ -49,6 +50,7 @@ static int Seek(access_t *access, uint64_t position)
if
(
position
>
file
->
real_size
)
if
(
position
>
file
->
real_size
)
position
=
file
->
real_size
;
position
=
file
->
real_size
;
sys
->
position
=
position
;
/* Search the chunk */
/* Search the chunk */
const
rar_file_chunk_t
*
old_chunk
=
sys
->
chunk
;
const
rar_file_chunk_t
*
old_chunk
=
sys
->
chunk
;
...
@@ -57,7 +59,6 @@ static int Seek(access_t *access, uint64_t position)
...
@@ -57,7 +59,6 @@ static int Seek(access_t *access, uint64_t position)
if
(
position
<
sys
->
chunk
->
cummulated_size
+
sys
->
chunk
->
size
)
if
(
position
<
sys
->
chunk
->
cummulated_size
+
sys
->
chunk
->
size
)
break
;
break
;
}
}
access
->
info
.
i_pos
=
position
;
access
->
info
.
b_eof
=
false
;
access
->
info
.
b_eof
=
false
;
const
uint64_t
offset
=
sys
->
chunk
->
offset
+
const
uint64_t
offset
=
sys
->
chunk
->
offset
+
...
@@ -78,7 +79,7 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
...
@@ -78,7 +79,7 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
size_t
total
=
0
;
size_t
total
=
0
;
while
(
total
<
size
)
{
while
(
total
<
size
)
{
const
uint64_t
chunk_end
=
sys
->
chunk
->
cummulated_size
+
sys
->
chunk
->
size
;
const
uint64_t
chunk_end
=
sys
->
chunk
->
cummulated_size
+
sys
->
chunk
->
size
;
int
max
=
__MIN
(
__MIN
((
int64_t
)(
size
-
total
),
(
int64_t
)(
chunk_end
-
access
->
info
.
i_pos
)),
INT_MAX
);
int
max
=
__MIN
(
__MIN
((
int64_t
)(
size
-
total
),
(
int64_t
)(
chunk_end
-
sys
->
position
)),
INT_MAX
);
if
(
max
<=
0
)
if
(
max
<=
0
)
break
;
break
;
...
@@ -89,9 +90,9 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
...
@@ -89,9 +90,9 @@ static ssize_t Read(access_t *access, uint8_t *data, size_t size)
total
+=
r
;
total
+=
r
;
if
(
data
)
if
(
data
)
data
+=
r
;
data
+=
r
;
access
->
info
.
i_pos
+=
r
;
sys
->
position
+=
r
;
if
(
access
->
info
.
i_pos
>=
chunk_end
&&
if
(
sys
->
position
>=
chunk_end
&&
Seek
(
access
,
access
->
info
.
i_pos
))
Seek
(
access
,
sys
->
position
))
break
;
break
;
}
}
if
(
size
>
0
&&
total
<=
0
)
if
(
size
>
0
&&
total
<=
0
)
...
...
modules/access/vcd/vcd.c
View file @
fccffe2f
...
@@ -66,6 +66,7 @@ vlc_module_end ()
...
@@ -66,6 +66,7 @@ vlc_module_end ()
struct
access_sys_t
struct
access_sys_t
{
{
vcddev_t
*
vcddev
;
/* vcd device descriptor */
vcddev_t
*
vcddev
;
/* vcd device descriptor */
uint64_t
offset
;
/* Title infos */
/* Title infos */
int
i_titles
;
int
i_titles
;
...
@@ -141,6 +142,7 @@ static int Open( vlc_object_t *p_this )
...
@@ -141,6 +142,7 @@ static int Open( vlc_object_t *p_this )
if
(
unlikely
(
!
p_sys
))
if
(
unlikely
(
!
p_sys
))
goto
error
;
goto
error
;
p_sys
->
vcddev
=
vcddev
;
p_sys
->
vcddev
=
vcddev
;
p_sys
->
offset
=
0
;
/* We read the Table Of Content information */
/* We read the Table Of Content information */
p_sys
->
i_titles
=
ioctl_GetTracksMap
(
VLC_OBJECT
(
p_access
),
p_sys
->
i_titles
=
ioctl_GetTracksMap
(
VLC_OBJECT
(
p_access
),
...
@@ -200,8 +202,8 @@ static int Open( vlc_object_t *p_this )
...
@@ -200,8 +202,8 @@ static int Open( vlc_object_t *p_this )
p_sys
->
i_current_title
=
i_title
;
p_sys
->
i_current_title
=
i_title
;
p_sys
->
i_current_seekpoint
=
i_chapter
;
p_sys
->
i_current_seekpoint
=
i_chapter
;
p_
access
->
info
.
i_pos
=
(
uint64_t
)(
p_sys
->
i_sector
-
p_sys
->
p_sectors
[
1
+
i_title
]
)
*
p_
sys
->
offset
=
(
uint64_t
)(
p_sys
->
i_sector
-
p_sys
->
p_sectors
[
1
+
i_title
]
)
*
VCD_DATA_SIZE
;
VCD_DATA_SIZE
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
...
@@ -284,9 +286,9 @@ static int Control( access_t *p_access, int i_query, va_list args )
...
@@ -284,9 +286,9 @@ static int Control( access_t *p_access, int i_query, va_list args )
if
(
i
!=
p_sys
->
i_current_title
)
if
(
i
!=
p_sys
->
i_current_title
)
{
{
/* Update info */
/* Update info */
p_sys
->
offset
=
0
;
p_sys
->
i_current_title
=
i
;
p_sys
->
i_current_title
=
i
;
p_sys
->
i_current_seekpoint
=
0
;
p_sys
->
i_current_seekpoint
=
0
;
p_access
->
info
.
i_pos
=
0
;
/* Next sector to read */
/* Next sector to read */
p_sys
->
i_sector
=
p_sys
->
p_sectors
[
1
+
i
];
p_sys
->
i_sector
=
p_sys
->
p_sectors
[
1
+
i
];
...
@@ -307,8 +309,8 @@ static int Control( access_t *p_access, int i_query, va_list args )
...
@@ -307,8 +309,8 @@ static int Control( access_t *p_access, int i_query, va_list args )
p_sys
->
i_sector
=
p_sys
->
p_sectors
[
1
+
i_title
]
+
p_sys
->
i_sector
=
p_sys
->
p_sectors
[
1
+
i_title
]
+
t
->
seekpoint
[
i
]
->
i_byte_offset
/
VCD_DATA_SIZE
;
t
->
seekpoint
[
i
]
->
i_byte_offset
/
VCD_DATA_SIZE
;
p_
access
->
info
.
i_pos
=
(
uint64_t
)(
p_sys
->
i_sector
-
p_
sys
->
offset
=
(
uint64_t
)(
p_sys
->
i_sector
-
p_sys
->
p_sectors
[
1
+
i_title
])
*
VCD_DATA_SIZE
;
p_sys
->
p_sectors
[
1
+
i_title
])
*
VCD_DATA_SIZE
;
}
}
break
;
break
;
}
}
...
@@ -342,7 +344,7 @@ static block_t *Block( access_t *p_access )
...
@@ -342,7 +344,7 @@ static block_t *Block( access_t *p_access )
p_sys
->
i_current_title
++
;
p_sys
->
i_current_title
++
;
p_sys
->
i_current_seekpoint
=
0
;
p_sys
->
i_current_seekpoint
=
0
;
p_
access
->
info
.
i_pos
=
0
;
p_
sys
->
offset
=
0
;
}
}
/* Don't read after the end of a title */
/* Don't read after the end of a title */
...
@@ -367,8 +369,8 @@ static block_t *Block( access_t *p_access )
...
@@ -367,8 +369,8 @@ static block_t *Block( access_t *p_access )
block_Release
(
p_block
);
block_Release
(
p_block
);
/* Try to skip one sector (in case of bad sectors) */
/* Try to skip one sector (in case of bad sectors) */
p_sys
->
offset
+=
VCD_DATA_SIZE
;
p_sys
->
i_sector
++
;
p_sys
->
i_sector
++
;
p_access
->
info
.
i_pos
+=
VCD_DATA_SIZE
;
return
NULL
;
return
NULL
;
}
}
...
@@ -380,7 +382,7 @@ static block_t *Block( access_t *p_access )
...
@@ -380,7 +382,7 @@ static block_t *Block( access_t *p_access )
if
(
t
->
i_seekpoint
>
0
&&
if
(
t
->
i_seekpoint
>
0
&&
p_sys
->
i_current_seekpoint
+
1
<
t
->
i_seekpoint
&&
p_sys
->
i_current_seekpoint
+
1
<
t
->
i_seekpoint
&&
(
int64_t
)
/* Unlikely to go over 8192 PetaB */
(
int64_t
)
/* Unlikely to go over 8192 PetaB */
(
p_
access
->
info
.
i_pos
+
i_read
*
VCD_DATA_SIZE
)
>=
(
p_
sys
->
offset
+
i_read
*
VCD_DATA_SIZE
)
>=
t
->
seekpoint
[
p_sys
->
i_current_seekpoint
+
1
]
->
i_byte_offset
)
t
->
seekpoint
[
p_sys
->
i_current_seekpoint
+
1
]
->
i_byte_offset
)
{
{
msg_Dbg
(
p_access
,
"seekpoint change"
);
msg_Dbg
(
p_access
,
"seekpoint change"
);
...
@@ -389,8 +391,8 @@ static block_t *Block( access_t *p_access )
...
@@ -389,8 +391,8 @@ static block_t *Block( access_t *p_access )
}
}
/* Update a few values */
/* Update a few values */
p_sys
->
offset
+=
p_block
->
i_buffer
;
p_sys
->
i_sector
+=
i_blocks
;
p_sys
->
i_sector
+=
i_blocks
;
p_access
->
info
.
i_pos
+=
p_block
->
i_buffer
;
return
p_block
;
return
p_block
;
}
}
...
@@ -405,7 +407,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
...
@@ -405,7 +407,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
int
i_seekpoint
;
int
i_seekpoint
;
/* Next sector to read */
/* Next sector to read */
p_
access
->
info
.
i_pos
=
i_pos
;
p_
sys
->
offset
=
i_pos
;
p_sys
->
i_sector
=
i_pos
/
VCD_DATA_SIZE
+
p_sys
->
i_sector
=
i_pos
/
VCD_DATA_SIZE
+
p_sys
->
p_sectors
[
p_sys
->
i_current_title
+
1
];
p_sys
->
p_sectors
[
p_sys
->
i_current_title
+
1
];
...
...
modules/access/vdr.c
View file @
fccffe2f
...
@@ -110,6 +110,7 @@ struct access_sys_t
...
@@ -110,6 +110,7 @@ struct access_sys_t
{
{
/* file sizes of all parts */
/* file sizes of all parts */
size_array_t
file_sizes
;
size_array_t
file_sizes
;
uint64_t
offset
;
uint64_t
size
;
/* total size */
uint64_t
size
;
/* total size */
/* index and fd of current open file */
/* index and fd of current open file */
...
@@ -351,7 +352,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
...
@@ -351,7 +352,7 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
if
(
i_ret
>
0
)
if
(
i_ret
>
0
)
{
{
/* success */
/* success */
p_
access
->
info
.
i_pos
+=
i_ret
;
p_
sys
->
offset
+=
i_ret
;
UpdateFileSize
(
p_access
);
UpdateFileSize
(
p_access
);
FindSeekpoint
(
p_access
);
FindSeekpoint
(
p_access
);
return
i_ret
;
return
i_ret
;
...
@@ -392,7 +393,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
...
@@ -392,7 +393,7 @@ static int Seek( access_t *p_access, uint64_t i_pos )
/* might happen if called by ACCESS_SET_SEEKPOINT */
/* might happen if called by ACCESS_SET_SEEKPOINT */
i_pos
=
__MIN
(
i_pos
,
p_sys
->
size
);
i_pos
=
__MIN
(
i_pos
,
p_sys
->
size
);
p_
access
->
info
.
i_pos
=
i_pos
;
p_
sys
->
offset
=
i_pos
;
p_access
->
info
.
b_eof
=
false
;
p_access
->
info
.
b_eof
=
false
;
/* find correct chapter */
/* find correct chapter */
...
@@ -424,7 +425,7 @@ static void FindSeekpoint( access_t *p_access )
...
@@ -424,7 +425,7 @@ static void FindSeekpoint( access_t *p_access )
return
;
return
;
int
new_seekpoint
=
p_sys
->
cur_seekpoint
;
int
new_seekpoint
=
p_sys
->
cur_seekpoint
;
if
(
p_
access
->
info
.
i_pos
<
(
uint64_t
)
p_sys
->
p_marks
->
if
(
p_
sys
->
offset
<
(
uint64_t
)
p_sys
->
p_marks
->
seekpoint
[
p_sys
->
cur_seekpoint
]
->
i_byte_offset
)
seekpoint
[
p_sys
->
cur_seekpoint
]
->
i_byte_offset
)
{
{
/* i_pos moved backwards, start fresh */
/* i_pos moved backwards, start fresh */
...
@@ -433,7 +434,7 @@ static void FindSeekpoint( access_t *p_access )
...
@@ -433,7 +434,7 @@ static void FindSeekpoint( access_t *p_access )
/* only need to check the following seekpoints */
/* only need to check the following seekpoints */
while
(
new_seekpoint
+
1
<
p_sys
->
p_marks
->
i_seekpoint
&&
while
(
new_seekpoint
+
1
<
p_sys
->
p_marks
->
i_seekpoint
&&
p_
access
->
info
.
i_pos
>=
(
uint64_t
)
p_sys
->
p_marks
->
p_
sys
->
offset
>=
(
uint64_t
)
p_sys
->
p_marks
->
seekpoint
[
new_seekpoint
+
1
]
->
i_byte_offset
)
seekpoint
[
new_seekpoint
+
1
]
->
i_byte_offset
)
{
{
new_seekpoint
++
;
new_seekpoint
++
;
...
@@ -579,7 +580,7 @@ static void UpdateFileSize( access_t *p_access )
...
@@ -579,7 +580,7 @@ static void UpdateFileSize( access_t *p_access )
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
struct
stat
st
;
struct
stat
st
;
if
(
p_sys
->
size
>=
p_
access
->
info
.
i_pos
)
if
(
p_sys
->
size
>=
p_
sys
->
offset
)
return
;
return
;
/* TODO: not sure if this can happen or what to do in this case */
/* TODO: not sure if this can happen or what to do in this case */
...
...
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