Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
14863071
Commit
14863071
authored
Jan 31, 2010
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
LibVLC audio: take a player object for most functions, remove exceptions
parent
d3472830
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
112 additions
and
128 deletions
+112
-128
include/vlc/libvlc_media_player.h
include/vlc/libvlc_media_player.h
+34
-43
src/control/audio.c
src/control/audio.c
+69
-79
src/control/media_player.c
src/control/media_player.c
+5
-0
src/control/mediacontrol_audio_video.c
src/control/mediacontrol_audio_video.c
+4
-6
No files found.
include/vlc/libvlc_media_player.h
View file @
14863071
...
...
@@ -928,12 +928,12 @@ VLC_PUBLIC_API void libvlc_audio_output_list_release( libvlc_audio_output_t * );
* Set the audio output.
* Change will be applied after stop and play.
*
* \param
p_instance libvlc instance
* \param
mp media player
* \param psz_name name of audio output,
* use psz_name of \see libvlc_audio_output_t
* \return true if function succeded
*/
VLC_PUBLIC_API
int
libvlc_audio_output_set
(
libvlc_
instance
_t
*
,
VLC_PUBLIC_API
int
libvlc_audio_output_set
(
libvlc_
media_player
_t
*
,
const
char
*
);
/**
...
...
@@ -972,13 +972,13 @@ VLC_PUBLIC_API char * libvlc_audio_output_device_id( libvlc_instance_t *,
int
);
/**
* Set
device for using
* Set
audio output device. Changes are only effective after stop and play.
*
* \param
p_instance libvlc instance
* \param
mp media player
* \param psz_audio_output - name of audio output, \see libvlc_audio_output_t
* \param psz_device_id device
*/
VLC_PUBLIC_API
void
libvlc_audio_output_device_set
(
libvlc_
instance
_t
*
,
VLC_PUBLIC_API
void
libvlc_audio_output_device_set
(
libvlc_
media_player
_t
*
,
const
char
*
,
const
char
*
);
...
...
@@ -986,124 +986,115 @@ VLC_PUBLIC_API void libvlc_audio_output_device_set( libvlc_instance_t *,
* Get current audio device type. Device type describes something like
* character of output sound - stereo sound, 2.1, 5.1 etc
*
* \param p_instance vlc instance
* \param p_e an initialized exception pointer
* \param mp media player
* \return the audio devices type \see libvlc_audio_output_device_types_t
*/
VLC_PUBLIC_API
int
libvlc_audio_output_get_device_type
(
libvlc_
instance_t
*
,
libvlc_exception
_t
*
);
libvlc_
media_player
_t
*
);
/**
* Set current audio device type.
*
* \param
p_instance
vlc instance
* \param
mp
vlc instance
* \param device_type the audio device type,
according to \see libvlc_audio_output_device_types_t
* \param p_e an initialized exception pointer
*/
VLC_PUBLIC_API
void
libvlc_audio_output_set_device_type
(
libvlc_instance_t
*
,
int
,
libvlc_exception_t
*
);
VLC_PUBLIC_API
void
libvlc_audio_output_set_device_type
(
libvlc_media_player_t
*
,
int
);
/**
* Toggle mute status.
*
* \param
p_instance libvlc instance
* \param
mp media player
*/
VLC_PUBLIC_API
void
libvlc_audio_toggle_mute
(
libvlc_
instance
_t
*
);
VLC_PUBLIC_API
void
libvlc_audio_toggle_mute
(
libvlc_
media_player
_t
*
);
/**
* Get current mute status.
*
* \param
p_instance libvlc instance
* \param
mp media player
* \return the mute status (boolean)
*/
VLC_PUBLIC_API
int
libvlc_audio_get_mute
(
libvlc_
instance
_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_get_mute
(
libvlc_
media_player
_t
*
);
/**
* Set mute status.
*
* \param
p_instance libvlc instance
* \param
mp media player
* \param status If status is true then mute, otherwise unmute
*/
VLC_PUBLIC_API
void
libvlc_audio_set_mute
(
libvlc_
instance
_t
*
,
int
);
VLC_PUBLIC_API
void
libvlc_audio_set_mute
(
libvlc_
media_player
_t
*
,
int
);
/**
* Get current audio level.
*
* \param
p_instance libvlc instance
* \param
mp media player
* \param p_e an initialized exception pointer
* \return the audio level (int)
*/
VLC_PUBLIC_API
int
libvlc_audio_get_volume
(
libvlc_
instance
_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_get_volume
(
libvlc_
media_player
_t
*
);
/**
* Set current audio level.
*
* \param
p_instance libvlc instance
* \param
mp media player
* \param i_volume the volume (int)
* \
param p_e an initialized exception pointer
* \
return 0 if the volume was set, -1 if it was out of range
*/
VLC_PUBLIC_API
void
libvlc_audio_set_volume
(
libvlc_instance_t
*
,
int
,
libvlc_exception_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_set_volume
(
libvlc_media_player_t
*
,
int
);
/**
* Get number of available audio tracks.
*
* \param p_mi media player
* \param p_e an initialized exception
* \return the number of available audio tracks (int)
* \return the number of available audio tracks (int), or -1 if unavailable
*/
VLC_PUBLIC_API
int
libvlc_audio_get_track_count
(
libvlc_media_player_t
*
,
libvlc_exception_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_get_track_count
(
libvlc_media_player_t
*
);
/**
* Get the description of available audio tracks.
*
* \param p_mi media player
* \param p_e an initialized exception
* \return list with description of available audio tracks
* \return list with description of available audio tracks, or NULL
*/
VLC_PUBLIC_API
libvlc_track_description_t
*
libvlc_audio_get_track_description
(
libvlc_media_player_t
*
,
libvlc_exception_t
*
);
libvlc_audio_get_track_description
(
libvlc_media_player_t
*
);
/**
* Get current audio track.
*
* \param p_mi media player
* \param p_e an initialized exception pointer
* \return the audio track (int)
* \return the audio track (int), or -1 if none.
*/
VLC_PUBLIC_API
int
libvlc_audio_get_track
(
libvlc_media_player_t
*
,
libvlc_exception_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_get_track
(
libvlc_media_player_t
*
);
/**
* Set current audio track.
*
* \param p_mi media player
* \param i_track the track (int)
* \
param p_e an initialized exception pointe
r
* \
return 0 on success, -1 on erro
r
*/
VLC_PUBLIC_API
void
libvlc_audio_set_track
(
libvlc_media_player_t
*
,
int
,
libvlc_exception_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_set_track
(
libvlc_media_player_t
*
,
int
);
/**
* Get current audio channel.
*
* \param p_instance vlc instance
* \param p_e an initialized exception pointer
* \param mp media player
* \return the audio channel \see libvlc_audio_output_channel_t
*/
VLC_PUBLIC_API
int
libvlc_audio_get_channel
(
libvlc_instance_t
*
,
libvlc_exception_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_get_channel
(
libvlc_media_player_t
*
);
/**
* Set current audio channel.
*
* \param p_
instance vlc instance
* \param p_
mi media player
* \param channel the audio channel, \see libvlc_audio_output_channel_t
* \
param p_e an initialized exception pointe
r
* \
return 0 on success, -1 on erro
r
*/
VLC_PUBLIC_API
void
libvlc_audio_set_channel
(
libvlc_instance_t
*
,
int
,
libvlc_exception_t
*
);
VLC_PUBLIC_API
int
libvlc_audio_set_channel
(
libvlc_media_player_t
*
,
int
);
/** @} audio */
...
...
src/control/audio.c
View file @
14863071
...
...
@@ -26,6 +26,8 @@
# include "config.h"
#endif
#include <assert.h>
#include <vlc/libvlc.h>
#include <vlc/libvlc_media.h>
#include <vlc/libvlc_media_player.h>
...
...
@@ -41,22 +43,18 @@
* Remember to release the returned aout_instance_t since it is locked at
* the end of this function.
*/
static
aout_instance_t
*
GetAOut
(
libvlc_instance_t
*
p_instance
,
libvlc_exception_t
*
p_exception
)
static
aout_instance_t
*
GetAOut
(
libvlc_media_player_t
*
mp
)
{
if
(
!
p_instance
)
return
NULL
;
assert
(
mp
!=
NULL
);
aout_instance_t
*
p_aout
=
NULL
;
p_aout
=
vlc_object_find
(
p_instance
->
p_libvlc_int
,
VLC_OBJECT_AOUT
,
FIND_CHILD
);
if
(
!
p_aout
)
{
libvlc_exception_raise
(
p_exception
);
libvlc_printerr
(
"No active audio output"
);
input_thread_t
*
p_input
=
libvlc_get_input_thread
(
mp
);
if
(
p_input
==
NULL
)
return
NULL
;
}
aout_instance_t
*
p_aout
=
input_GetAout
(
p_input
);
vlc_object_release
(
p_input
);
if
(
p_aout
==
NULL
)
libvlc_printerr
(
"No active audio output"
);
return
p_aout
;
}
...
...
@@ -132,16 +130,12 @@ void libvlc_audio_output_list_release( libvlc_audio_output_t *p_list )
/***********************
* Set the audio output.
***********************/
int
libvlc_audio_output_set
(
libvlc_instance_t
*
p_instance
,
const
char
*
psz_name
)
int
libvlc_audio_output_set
(
libvlc_media_player_t
*
mp
,
const
char
*
psz_name
)
{
if
(
module_exists
(
psz_name
)
)
{
config_PutPsz
(
p_instance
->
p_libvlc_int
,
"aout"
,
psz_name
);
return
true
;
}
else
return
false
;
if
(
!
module_exists
(
psz_name
)
)
return
-
1
;
var_SetString
(
mp
,
"aout"
,
psz_name
);
return
0
;
}
/****************************
...
...
@@ -261,26 +255,28 @@ char * libvlc_audio_output_device_id( libvlc_instance_t *p_instance,
/*****************************
* Set device for using
*****************************/
void
libvlc_audio_output_device_set
(
libvlc_
instance_t
*
p_instance
,
const
char
*
psz_audio_output
,
const
char
*
psz_device_id
)
void
libvlc_audio_output_device_set
(
libvlc_
media_player_t
*
mp
,
const
char
*
psz_audio_output
,
const
char
*
psz_device_id
)
{
char
*
psz_config_name
=
NULL
;
char
*
psz_config_name
;
if
(
!
psz_audio_output
||
!
psz_device_id
)
return
;
if
(
asprintf
(
&
psz_config_name
,
"%s-audio-device"
,
psz_audio_output
)
==
-
1
)
return
;
config_PutPsz
(
p_instance
->
p_libvlc_int
,
psz_config_name
,
psz_device_id
);
if
(
!
var_Type
(
mp
,
psz_audio_output
)
)
/* Don't recreate the same variable over and over and over... */
var_Create
(
mp
,
psz_audio_output
,
VLC_VAR_STRING
);
var_SetString
(
mp
,
psz_config_name
,
psz_device_id
);
free
(
psz_config_name
);
}
/*****************************************************************************
* libvlc_audio_output_get_device_type : Get the current audio device type
*****************************************************************************/
int
libvlc_audio_output_get_device_type
(
libvlc_instance_t
*
p_instance
,
libvlc_exception_t
*
p_e
)
int
libvlc_audio_output_get_device_type
(
libvlc_media_player_t
*
mp
)
{
aout_instance_t
*
p_aout
=
GetAOut
(
p_instance
,
p_e
);
aout_instance_t
*
p_aout
=
GetAOut
(
mp
);
if
(
p_aout
)
{
int
i_device_type
=
var_GetInteger
(
p_aout
,
"audio-device"
);
...
...
@@ -293,50 +289,48 @@ int libvlc_audio_output_get_device_type( libvlc_instance_t *p_instance,
/*****************************************************************************
* libvlc_audio_output_set_device_type : Set the audio device type
*****************************************************************************/
void
libvlc_audio_output_set_device_type
(
libvlc_instance_t
*
p_instance
,
int
device_type
,
libvlc_exception_t
*
p_e
)
void
libvlc_audio_output_set_device_type
(
libvlc_media_player_t
*
mp
,
int
device_type
)
{
aout_instance_t
*
p_aout
=
GetAOut
(
p_instance
,
p_e
);
aout_instance_t
*
p_aout
=
GetAOut
(
mp
);
if
(
!
p_aout
)
return
;
if
(
var_SetInteger
(
p_aout
,
"audio-device"
,
device_type
)
<
0
)
{
libvlc_exception_raise
(
p_e
);
libvlc_printerr
(
"Error setting audio device"
);
}
vlc_object_release
(
p_aout
);
}
/*****************************************************************************
* libvlc_audio_get_mute : Get the volume state, true if muted
*****************************************************************************/
void
libvlc_audio_toggle_mute
(
libvlc_
instance_t
*
p_instance
)
void
libvlc_audio_toggle_mute
(
libvlc_
media_player_t
*
mp
)
{
aout_ToggleMute
(
p_instance
->
p_libvlc_int
,
NULL
);
#warning FIXME: no playlist
aout_ToggleMute
(
mp
,
NULL
);
}
int
libvlc_audio_get_mute
(
libvlc_
instance_t
*
p_instance
)
int
libvlc_audio_get_mute
(
libvlc_
media_player_t
*
mp
)
{
return
(
libvlc_audio_get_volume
(
p_instance
)
==
0
);
return
(
libvlc_audio_get_volume
(
mp
)
==
0
);
}
void
libvlc_audio_set_mute
(
libvlc_
instance_t
*
p_instance
,
int
mute
)
void
libvlc_audio_set_mute
(
libvlc_
media_player_t
*
mp
,
int
mute
)
{
if
(
!
mute
!=
!
libvlc_audio_get_mute
(
p_instance
)
)
{
aout_ToggleMute
(
p_instance
->
p_libvlc_int
,
NULL
);
}
#warning Not quite thread-safe
if
(
!
mute
!=
!
libvlc_audio_get_mute
(
mp
)
)
#warning FIXME: no playlist
aout_ToggleMute
(
mp
,
NULL
);
}
/*****************************************************************************
* libvlc_audio_get_volume : Get the current volume (range 0-200 %)
*****************************************************************************/
int
libvlc_audio_get_volume
(
libvlc_
instance_t
*
p_instance
)
int
libvlc_audio_get_volume
(
libvlc_
media_player_t
*
mp
)
{
audio_volume_t
i_volume
;
aout_VolumeGet
(
p_instance
->
p_libvlc_int
,
&
i_volume
);
#warning FIXME: no playlist
aout_VolumeGet
(
mp
,
&
i_volume
);
return
(
i_volume
*
200
+
AOUT_VOLUME_MAX
/
2
)
/
AOUT_VOLUME_MAX
;
}
...
...
@@ -345,27 +339,24 @@ int libvlc_audio_get_volume( libvlc_instance_t *p_instance )
/*****************************************************************************
* libvlc_audio_set_volume : Set the current volume
*****************************************************************************/
void
libvlc_audio_set_volume
(
libvlc_instance_t
*
p_instance
,
int
i_volume
,
libvlc_exception_t
*
p_e
)
int
libvlc_audio_set_volume
(
libvlc_media_player_t
*
mp
,
int
i_volume
)
{
if
(
i_volume
>=
0
&&
i_volume
<=
200
)
if
(
i_volume
<
0
||
i_volume
>
200
)
{
i_volume
=
(
i_volume
*
AOUT_VOLUME_MAX
+
100
)
/
200
;
aout_VolumeSet
(
p_instance
->
p_libvlc_int
,
i_volume
);
}
else
{
libvlc_exception_raise
(
p_e
);
libvlc_printerr
(
"Volume out of range"
);
return
-
1
;
}
i_volume
=
(
i_volume
*
AOUT_VOLUME_MAX
+
100
)
/
200
;
#warning FIXME: no playlist
aout_VolumeSet
(
mp
,
i_volume
);
return
0
;
}
/*****************************************************************************
* libvlc_audio_get_track_count : Get the number of available audio tracks
*****************************************************************************/
int
libvlc_audio_get_track_count
(
libvlc_media_player_t
*
p_mi
,
libvlc_exception_t
*
p_e
)
int
libvlc_audio_get_track_count
(
libvlc_media_player_t
*
p_mi
)
{
input_thread_t
*
p_input_thread
=
libvlc_get_input_thread
(
p_mi
);
int
i_track_count
;
...
...
@@ -383,8 +374,7 @@ int libvlc_audio_get_track_count( libvlc_media_player_t *p_mi,
* libvlc_audio_get_track_description : Get the description of available audio tracks
*****************************************************************************/
libvlc_track_description_t
*
libvlc_audio_get_track_description
(
libvlc_media_player_t
*
p_mi
,
libvlc_exception_t
*
p_e
)
libvlc_audio_get_track_description
(
libvlc_media_player_t
*
p_mi
)
{
return
libvlc_get_track_description
(
p_mi
,
"audio-es"
);
}
...
...
@@ -392,8 +382,7 @@ libvlc_track_description_t *
/*****************************************************************************
* libvlc_audio_get_track : Get the current audio track
*****************************************************************************/
int
libvlc_audio_get_track
(
libvlc_media_player_t
*
p_mi
,
libvlc_exception_t
*
p_e
)
int
libvlc_audio_get_track
(
libvlc_media_player_t
*
p_mi
)
{
input_thread_t
*
p_input_thread
=
libvlc_get_input_thread
(
p_mi
);
vlc_value_t
val_list
;
...
...
@@ -407,7 +396,6 @@ int libvlc_audio_get_track( libvlc_media_player_t *p_mi,
if
(
var_Get
(
p_input_thread
,
"audio-es"
,
&
val
)
<
0
)
{
vlc_object_release
(
p_input_thread
);
libvlc_exception_raise
(
p_e
);
libvlc_printerr
(
"Audio track information not found"
);
return
-
1
;
}
...
...
@@ -429,22 +417,21 @@ int libvlc_audio_get_track( libvlc_media_player_t *p_mi,
/*****************************************************************************
* libvlc_audio_set_track : Set the current audio track
*****************************************************************************/
void
libvlc_audio_set_track
(
libvlc_media_player_t
*
p_mi
,
int
i_track
,
libvlc_exception_t
*
p_e
)
int
libvlc_audio_set_track
(
libvlc_media_player_t
*
p_mi
,
int
i_track
)
{
input_thread_t
*
p_input_thread
=
libvlc_get_input_thread
(
p_mi
);
vlc_value_t
val_list
;
vlc_value_t
newval
;
int
i_ret
=
-
1
;
int
i_ret
;
if
(
!
p_input_thread
)
return
;
return
-
1
;
var_Change
(
p_input_thread
,
"audio-es"
,
VLC_VAR_GETCHOICES
,
&
val_list
,
NULL
);
if
(
(
i_track
<
0
)
||
(
i_track
>
val_list
.
p_list
->
i_count
)
)
{
libvlc_exception_raise
(
p_e
);
libvlc_printerr
(
"Audio track out of range"
);
i_ret
=
-
1
;
goto
end
;
}
...
...
@@ -452,22 +439,24 @@ void libvlc_audio_set_track( libvlc_media_player_t *p_mi, int i_track,
i_ret
=
var_Set
(
p_input_thread
,
"audio-es"
,
newval
);
if
(
i_ret
<
0
)
{
libvlc_exception_raise
(
p_e
);
libvlc_printerr
(
"Audio track out of range"
);
/* Race... */
i_ret
=
-
1
;
goto
end
;
}
i_ret
=
0
;
end:
var_FreeList
(
&
val_list
,
NULL
);
vlc_object_release
(
p_input_thread
);
return
i_ret
;
}
/*****************************************************************************
* libvlc_audio_get_channel : Get the current audio channel
*****************************************************************************/
int
libvlc_audio_get_channel
(
libvlc_instance_t
*
p_instance
,
libvlc_exception_t
*
p_e
)
int
libvlc_audio_get_channel
(
libvlc_media_player_t
*
mp
)
{
aout_instance_t
*
p_aout
=
GetAOut
(
p_instance
,
p_e
);
aout_instance_t
*
p_aout
=
GetAOut
(
mp
);
if
(
!
p_aout
)
return
0
;
...
...
@@ -479,18 +468,19 @@ int libvlc_audio_get_channel( libvlc_instance_t *p_instance,
/*****************************************************************************
* libvlc_audio_set_channel : Set the current audio channel
*****************************************************************************/
void
libvlc_audio_set_channel
(
libvlc_instance_t
*
p_instance
,
int
channel
,
libvlc_exception_t
*
p_e
)
int
libvlc_audio_set_channel
(
libvlc_media_player_t
*
mp
,
int
channel
)
{
aout_instance_t
*
p_aout
=
GetAOut
(
p_instance
,
p_e
);
aout_instance_t
*
p_aout
=
GetAOut
(
mp
);
int
ret
=
0
;
if
(
!
p_aout
)
return
;
return
-
1
;
if
(
var_SetInteger
(
p_aout
,
"audio-channels"
,
channel
)
<
0
)
{
libvlc_exception_raise
(
p_e
);
libvlc_printerr
(
"Audio channel out of range"
);
ret
=
-
1
;
}
vlc_object_release
(
p_aout
);
return
ret
;
}
src/control/media_player.c
View file @
14863071
...
...
@@ -132,6 +132,8 @@ input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi )
p_input_thread
=
p_mi
->
p_input_thread
;
if
(
p_input_thread
)
vlc_object_hold
(
p_input_thread
);
else
libvlc_printerr
(
"No active input"
);
unlock
(
p_mi
);
return
p_input_thread
;
...
...
@@ -354,6 +356,9 @@ libvlc_media_player_new( libvlc_instance_t *instance )
var_SetBool
(
mp
,
"keyboard-events"
,
true
);
var_Create
(
mp
,
"mouse-events"
,
VLC_VAR_BOOL
);
/* Audio */
var_Create
(
mp
,
"aout"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
);
mp
->
p_md
=
NULL
;
mp
->
state
=
libvlc_NothingSpecial
;
mp
->
p_libvlc_instance
=
instance
;
...
...
src/control/mediacontrol_audio_video.c
View file @
14863071
...
...
@@ -203,7 +203,8 @@ mediacontrol_sound_get_volume( mediacontrol_Instance *self,
mediacontrol_exception_init
(
exception
);
i_ret
=
libvlc_audio_get_volume
(
self
->
p_instance
);
//i_ret = libvlc_audio_get_volume( self->p_instance );
#warning FIXME: unimplented
/* FIXME: Normalize in [0..100] */
return
(
unsigned
short
)
i_ret
;
}
...
...
@@ -214,13 +215,10 @@ mediacontrol_sound_set_volume( mediacontrol_Instance *self,
mediacontrol_Exception
*
exception
)
{
/* FIXME: Normalize in [0..100] */
libvlc_exception_t
ex
;
mediacontrol_exception_init
(
exception
);
libvlc_exception_init
(
&
ex
);
libvlc_audio_set_volume
(
self
->
p_instance
,
volume
,
&
ex
);
HANDLE_LIBVLC_EXCEPTION_VOID
(
&
ex
);
//libvlc_audio_set_volume( self->p_instance, volume
);
#warning FIXME: unimplented
}
int
mediacontrol_set_visual
(
mediacontrol_Instance
*
self
,
...
...
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