Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
57882e0f
Commit
57882e0f
authored
Jan 31, 2010
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made normal es_out_t valid as long as input_thread_t.
parent
92410cb5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
55 additions
and
40 deletions
+55
-40
src/input/es_out.c
src/input/es_out.c
+44
-30
src/input/es_out.h
src/input/es_out.h
+2
-1
src/input/input.c
src/input/input.c
+9
-9
No files found.
src/input/es_out.c
View file @
57882e0f
...
@@ -173,6 +173,7 @@ static void EsOutDel ( es_out_t *, es_out_id_t * );
...
@@ -173,6 +173,7 @@ static void EsOutDel ( es_out_t *, es_out_id_t * );
static
int
EsOutControl
(
es_out_t
*
,
int
i_query
,
va_list
);
static
int
EsOutControl
(
es_out_t
*
,
int
i_query
,
va_list
);
static
void
EsOutDelete
(
es_out_t
*
);
static
void
EsOutDelete
(
es_out_t
*
);
static
void
EsOutTerminate
(
es_out_t
*
);
static
void
EsOutSelect
(
es_out_t
*
,
es_out_id_t
*
es
,
bool
b_force
);
static
void
EsOutSelect
(
es_out_t
*
,
es_out_id_t
*
es
,
bool
b_force
);
static
void
EsOutUpdateInfo
(
es_out_t
*
,
es_out_id_t
*
es
,
const
es_format_t
*
,
const
vlc_meta_t
*
);
static
void
EsOutUpdateInfo
(
es_out_t
*
,
es_out_id_t
*
es
,
const
es_format_t
*
,
const
vlc_meta_t
*
);
static
int
EsOutSetRecord
(
es_out_t
*
,
bool
b_record
);
static
int
EsOutSetRecord
(
es_out_t
*
,
bool
b_record
);
...
@@ -236,7 +237,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
...
@@ -236,7 +237,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
out
->
pf_control
=
EsOutControl
;
out
->
pf_control
=
EsOutControl
;
out
->
pf_destroy
=
EsOutDelete
;
out
->
pf_destroy
=
EsOutDelete
;
out
->
p_sys
=
p_sys
;
out
->
p_sys
=
p_sys
;
out
->
b_sout
=
p_input
->
p
->
p_sout
!=
NULL
;
out
->
b_sout
=
false
;
/* It has no meaning here, and p_input->p->p_sout is not yet valid */
vlc_mutex_init_recursive
(
&
p_sys
->
lock
);
vlc_mutex_init_recursive
(
&
p_sys
->
lock
);
...
@@ -329,12 +330,35 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
...
@@ -329,12 +330,35 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
static
void
EsOutDelete
(
es_out_t
*
out
)
static
void
EsOutDelete
(
es_out_t
*
out
)
{
{
es_out_sys_t
*
p_sys
=
out
->
p_sys
;
es_out_sys_t
*
p_sys
=
out
->
p_sys
;
int
i
;
assert
(
!
p_sys
->
i_es
&&
!
p_sys
->
i_pgrm
&&
!
p_sys
->
p_pgrm
);
if
(
p_sys
->
ppsz_audio_language
)
{
for
(
int
i
=
0
;
p_sys
->
ppsz_audio_language
[
i
];
i
++
)
free
(
p_sys
->
ppsz_audio_language
[
i
]
);
free
(
p_sys
->
ppsz_audio_language
);
}
if
(
p_sys
->
ppsz_sub_language
)
{
for
(
int
i
=
0
;
p_sys
->
ppsz_sub_language
[
i
];
i
++
)
free
(
p_sys
->
ppsz_sub_language
[
i
]
);
free
(
p_sys
->
ppsz_sub_language
);
}
vlc_mutex_destroy
(
&
p_sys
->
lock
);
free
(
p_sys
);
free
(
out
);
}
static
void
EsOutTerminate
(
es_out_t
*
out
)
{
es_out_sys_t
*
p_sys
=
out
->
p_sys
;
if
(
p_sys
->
p_sout_record
)
if
(
p_sys
->
p_sout_record
)
EsOutSetRecord
(
out
,
false
);
EsOutSetRecord
(
out
,
false
);
for
(
i
=
0
;
i
<
p_sys
->
i_es
;
i
++
)
for
(
i
nt
i
=
0
;
i
<
p_sys
->
i_es
;
i
++
)
{
{
if
(
p_sys
->
es
[
i
]
->
p_dec
)
if
(
p_sys
->
es
[
i
]
->
p_dec
)
input_DecoderDelete
(
p_sys
->
es
[
i
]
->
p_dec
);
input_DecoderDelete
(
p_sys
->
es
[
i
]
->
p_dec
);
...
@@ -345,22 +369,10 @@ static void EsOutDelete( es_out_t *out )
...
@@ -345,22 +369,10 @@ static void EsOutDelete( es_out_t *out )
free
(
p_sys
->
es
[
i
]
);
free
(
p_sys
->
es
[
i
]
);
}
}
if
(
p_sys
->
ppsz_audio_language
)
TAB_CLEAN
(
p_sys
->
i_es
,
p_sys
->
es
);
{
for
(
i
=
0
;
p_sys
->
ppsz_audio_language
[
i
];
i
++
)
free
(
p_sys
->
ppsz_audio_language
[
i
]
);
free
(
p_sys
->
ppsz_audio_language
);
}
if
(
p_sys
->
ppsz_sub_language
)
{
for
(
i
=
0
;
p_sys
->
ppsz_sub_language
[
i
];
i
++
)
free
(
p_sys
->
ppsz_sub_language
[
i
]
);
free
(
p_sys
->
ppsz_sub_language
);
}
free
(
p_sys
->
es
);
/* FIXME duplicate work EsOutProgramDel (but we cannot use it) add a EsOutProgramClean ? */
/* FIXME duplicate work EsOutProgramDel (but we cannot use it) add a EsOutProgramClean ? */
for
(
i
=
0
;
i
<
p_sys
->
i_pgrm
;
i
++
)
for
(
i
nt
i
=
0
;
i
<
p_sys
->
i_pgrm
;
i
++
)
{
{
es_out_pgrm_t
*
p_pgrm
=
p_sys
->
pgrm
[
i
];
es_out_pgrm_t
*
p_pgrm
=
p_sys
->
pgrm
[
i
];
input_clock_Delete
(
p_pgrm
->
p_clock
);
input_clock_Delete
(
p_pgrm
->
p_clock
);
...
@@ -372,13 +384,10 @@ static void EsOutDelete( es_out_t *out )
...
@@ -372,13 +384,10 @@ static void EsOutDelete( es_out_t *out )
}
}
TAB_CLEAN
(
p_sys
->
i_pgrm
,
p_sys
->
pgrm
);
TAB_CLEAN
(
p_sys
->
i_pgrm
,
p_sys
->
pgrm
);
p_sys
->
p_pgrm
=
NULL
;
input_item_SetEpgOffline
(
p_sys
->
p_input
->
p
->
p_item
);
input_item_SetEpgOffline
(
p_sys
->
p_input
->
p
->
p_item
);
input_SendEventMetaEpg
(
p_sys
->
p_input
);
input_SendEventMetaEpg
(
p_sys
->
p_input
);
vlc_mutex_destroy
(
&
p_sys
->
lock
);
free
(
p_sys
);
free
(
out
);
}
}
static
mtime_t
EsOutGetWakeup
(
es_out_t
*
out
)
static
mtime_t
EsOutGetWakeup
(
es_out_t
*
out
)
...
@@ -1370,7 +1379,7 @@ static void EsOutMeta( es_out_t *p_out, const vlc_meta_t *p_meta )
...
@@ -1370,7 +1379,7 @@ static void EsOutMeta( es_out_t *p_out, const vlc_meta_t *p_meta )
{
{
/* Don't look for art cover if sout
/* Don't look for art cover if sout
* XXX It can change when sout has meta data support */
* XXX It can change when sout has meta data support */
if
(
p_
out
->
b
_sout
&&
!
p_input
->
b_preparsing
)
if
(
p_
input
->
p
->
p
_sout
&&
!
p_input
->
b_preparsing
)
input_item_SetArtURL
(
p_item
,
""
);
input_item_SetArtURL
(
p_item
,
""
);
else
else
input_ExtractAttachmentAndCacheArt
(
p_input
);
input_ExtractAttachmentAndCacheArt
(
p_input
);
...
@@ -1602,9 +1611,10 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
...
@@ -1602,9 +1611,10 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
}
}
else
else
{
{
const
bool
b_sout
=
p_input
->
p
->
p_sout
!=
NULL
;
if
(
es
->
fmt
.
i_cat
==
VIDEO_ES
||
es
->
fmt
.
i_cat
==
SPU_ES
)
if
(
es
->
fmt
.
i_cat
==
VIDEO_ES
||
es
->
fmt
.
i_cat
==
SPU_ES
)
{
{
if
(
!
var_GetBool
(
p_input
,
out
->
b_sout
?
"sout-video"
:
"video"
)
)
if
(
!
var_GetBool
(
p_input
,
b_sout
?
"sout-video"
:
"video"
)
)
{
{
msg_Dbg
(
p_input
,
"video is disabled, not selecting ES 0x%x"
,
msg_Dbg
(
p_input
,
"video is disabled, not selecting ES 0x%x"
,
es
->
i_id
);
es
->
i_id
);
...
@@ -1613,7 +1623,7 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
...
@@ -1613,7 +1623,7 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
}
}
else
if
(
es
->
fmt
.
i_cat
==
AUDIO_ES
)
else
if
(
es
->
fmt
.
i_cat
==
AUDIO_ES
)
{
{
if
(
!
var_GetBool
(
p_input
,
out
->
b_sout
?
"sout-audio"
:
"audio"
)
)
if
(
!
var_GetBool
(
p_input
,
b_sout
?
"sout-audio"
:
"audio"
)
)
{
{
msg_Dbg
(
p_input
,
"audio is disabled, not selecting ES 0x%x"
,
msg_Dbg
(
p_input
,
"audio is disabled, not selecting ES 0x%x"
,
es
->
i_id
);
es
->
i_id
);
...
@@ -1622,7 +1632,7 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
...
@@ -1622,7 +1632,7 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
}
}
if
(
es
->
fmt
.
i_cat
==
SPU_ES
)
if
(
es
->
fmt
.
i_cat
==
SPU_ES
)
{
{
if
(
!
var_GetBool
(
p_input
,
out
->
b_sout
?
"sout-spu"
:
"spu"
)
)
if
(
!
var_GetBool
(
p_input
,
b_sout
?
"sout-spu"
:
"spu"
)
)
{
{
msg_Dbg
(
p_input
,
"spu is disabled, not selecting ES 0x%x"
,
msg_Dbg
(
p_input
,
"spu is disabled, not selecting ES 0x%x"
,
es
->
i_id
);
es
->
i_id
);
...
@@ -1922,7 +1932,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
...
@@ -1922,7 +1932,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
}
}
/* Check for sout mode */
/* Check for sout mode */
if
(
out
->
b
_sout
)
if
(
p_input
->
p
->
p
_sout
)
{
{
/* FIXME review this, proper lock may be missing */
/* FIXME review this, proper lock may be missing */
if
(
p_input
->
p
->
p_sout
->
i_out_pace_nocontrol
>
0
&&
if
(
p_input
->
p
->
p_sout
->
i_out_pace_nocontrol
>
0
&&
...
@@ -2115,7 +2125,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
...
@@ -2115,7 +2125,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
{
{
const
int
i_mode
=
va_arg
(
args
,
int
);
const
int
i_mode
=
va_arg
(
args
,
int
);
assert
(
i_mode
==
ES_OUT_MODE_NONE
||
i_mode
==
ES_OUT_MODE_ALL
||
assert
(
i_mode
==
ES_OUT_MODE_NONE
||
i_mode
==
ES_OUT_MODE_ALL
||
i_mode
==
ES_OUT_MODE_AUTO
||
i_mode
==
ES_OUT_MODE_PARTIAL
);
i_mode
==
ES_OUT_MODE_AUTO
||
i_mode
==
ES_OUT_MODE_PARTIAL
||
i_mode
==
ES_OUT_MODE_END
);
if
(
i_mode
!=
ES_OUT_MODE_NONE
&&
!
p_sys
->
b_active
&&
p_sys
->
i_es
>
0
)
if
(
i_mode
!=
ES_OUT_MODE_NONE
&&
!
p_sys
->
b_active
&&
p_sys
->
i_es
>
0
)
{
{
...
@@ -2143,6 +2154,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
...
@@ -2143,6 +2154,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
}
}
for
(
i
=
0
;
i
<
p_sys
->
i_es
;
i
++
)
for
(
i
=
0
;
i
<
p_sys
->
i_es
;
i
++
)
EsOutSelect
(
out
,
p_sys
->
es
[
i
],
false
);
EsOutSelect
(
out
,
p_sys
->
es
[
i
],
false
);
if
(
i_mode
==
ES_OUT_MODE_END
)
EsOutTerminate
(
out
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -2280,7 +2293,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
...
@@ -2280,7 +2293,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
/* Check buffering state on master clock update */
/* Check buffering state on master clock update */
EsOutDecodersStopBuffering
(
out
,
false
);
EsOutDecodersStopBuffering
(
out
,
false
);
}
}
else
if
(
b_late
&&
(
!
out
->
b
_sout
||
else
if
(
b_late
&&
(
!
p_sys
->
p_input
->
p
->
p
_sout
||
!
p_sys
->
p_input
->
p
->
b_out_pace_control
)
)
!
p_sys
->
p_input
->
p
->
b_out_pace_control
)
)
{
{
mtime_t
i_pts_delay
=
input_clock_GetJitter
(
p_pgrm
->
p_clock
);
mtime_t
i_pts_delay
=
input_clock_GetJitter
(
p_pgrm
->
p_clock
);
...
@@ -2547,7 +2560,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
...
@@ -2547,7 +2560,8 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
mtime_t
i_delay
;
mtime_t
i_delay
;
/* Fix for buffering delay */
/* Fix for buffering delay */
if
(
!
out
->
b_sout
||
!
p_sys
->
p_input
->
p
->
b_out_pace_control
)
if
(
!
p_sys
->
p_input
->
p
->
p_sout
||
!
p_sys
->
p_input
->
p
->
b_out_pace_control
)
i_delay
=
EsOutGetBuffering
(
out
);
i_delay
=
EsOutGetBuffering
(
out
);
else
else
i_delay
=
0
;
i_delay
=
0
;
...
...
src/input/es_out.h
View file @
57882e0f
...
@@ -36,7 +36,8 @@ enum es_out_mode_e
...
@@ -36,7 +36,8 @@ enum es_out_mode_e
ES_OUT_MODE_NONE
,
/* don't select anything */
ES_OUT_MODE_NONE
,
/* don't select anything */
ES_OUT_MODE_ALL
,
/* eg for stream output */
ES_OUT_MODE_ALL
,
/* eg for stream output */
ES_OUT_MODE_AUTO
,
/* best audio/video or for input follow audio-track, sub-track */
ES_OUT_MODE_AUTO
,
/* best audio/video or for input follow audio-track, sub-track */
ES_OUT_MODE_PARTIAL
/* select programs given after --programs */
ES_OUT_MODE_PARTIAL
,
/* select programs given after --programs */
ES_OUT_MODE_END
/* mark the es_out as dead */
};
};
enum
es_out_query_private_e
enum
es_out_query_private_e
...
...
src/input/input.c
View file @
57882e0f
...
@@ -356,8 +356,6 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
...
@@ -356,8 +356,6 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
memset
(
&
p_input
->
p
->
bookmark
,
0
,
sizeof
(
p_input
->
p
->
bookmark
)
);
memset
(
&
p_input
->
p
->
bookmark
,
0
,
sizeof
(
p_input
->
p
->
bookmark
)
);
TAB_INIT
(
p_input
->
p
->
i_bookmark
,
p_input
->
p
->
pp_bookmark
);
TAB_INIT
(
p_input
->
p
->
i_bookmark
,
p_input
->
p
->
pp_bookmark
);
TAB_INIT
(
p_input
->
p
->
i_attachment
,
p_input
->
p
->
attachment
);
TAB_INIT
(
p_input
->
p
->
i_attachment
,
p_input
->
p
->
attachment
);
p_input
->
p
->
p_es_out_display
=
NULL
;
p_input
->
p
->
p_es_out
=
NULL
;
p_input
->
p
->
p_sout
=
NULL
;
p_input
->
p
->
p_sout
=
NULL
;
p_input
->
p
->
b_out_pace_control
=
false
;
p_input
->
p
->
b_out_pace_control
=
false
;
...
@@ -477,6 +475,9 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
...
@@ -477,6 +475,9 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
memset
(
&
p_input
->
p
->
counters
,
0
,
sizeof
(
p_input
->
p
->
counters
)
);
memset
(
&
p_input
->
p
->
counters
,
0
,
sizeof
(
p_input
->
p
->
counters
)
);
vlc_mutex_init
(
&
p_input
->
p
->
counters
.
counters_lock
);
vlc_mutex_init
(
&
p_input
->
p
->
counters
.
counters_lock
);
p_input
->
p
->
p_es_out_display
=
input_EsOutNew
(
p_input
,
p_input
->
p
->
i_rate
);
p_input
->
p
->
p_es_out
=
NULL
;
/* Set the destructor when we are sure we are initialized */
/* Set the destructor when we are sure we are initialized */
vlc_object_set_destructor
(
p_input
,
(
vlc_destructor_t
)
Destructor
);
vlc_object_set_destructor
(
p_input
,
(
vlc_destructor_t
)
Destructor
);
...
@@ -497,6 +498,9 @@ static void Destructor( input_thread_t * p_input )
...
@@ -497,6 +498,9 @@ static void Destructor( input_thread_t * p_input )
stats_TimerDump
(
p_input
,
STATS_TIMER_INPUT_LAUNCHING
);
stats_TimerDump
(
p_input
,
STATS_TIMER_INPUT_LAUNCHING
);
stats_TimerClean
(
p_input
,
STATS_TIMER_INPUT_LAUNCHING
);
stats_TimerClean
(
p_input
,
STATS_TIMER_INPUT_LAUNCHING
);
if
(
p_input
->
p
->
p_es_out_display
)
es_out_Delete
(
p_input
->
p
->
p_es_out_display
);
if
(
p_input
->
p
->
p_resource
)
if
(
p_input
->
p
->
p_resource
)
input_resource_Delete
(
p_input
->
p
->
p_resource
);
input_resource_Delete
(
p_input
->
p
->
p_resource
);
...
@@ -1207,8 +1211,7 @@ static int Init( input_thread_t * p_input )
...
@@ -1207,8 +1211,7 @@ static int Init( input_thread_t * p_input )
#endif
#endif
/* Create es out */
/* Create es out */
p_input
->
p
->
p_es_out_display
=
input_EsOutNew
(
p_input
,
p_input
->
p
->
i_rate
);
p_input
->
p
->
p_es_out
=
input_EsOutTimeshiftNew
(
p_input
,
p_input
->
p
->
p_es_out_display
,
p_input
->
p
->
i_rate
);
p_input
->
p
->
p_es_out
=
input_EsOutTimeshiftNew
(
p_input
,
p_input
->
p
->
p_es_out_display
,
p_input
->
p
->
i_rate
);
/* */
/* */
input_ChangeState
(
p_input
,
OPENING_S
);
input_ChangeState
(
p_input
,
OPENING_S
);
...
@@ -1288,8 +1291,7 @@ error:
...
@@ -1288,8 +1291,7 @@ error:
if
(
p_input
->
p
->
p_es_out
)
if
(
p_input
->
p
->
p_es_out
)
es_out_Delete
(
p_input
->
p
->
p_es_out
);
es_out_Delete
(
p_input
->
p
->
p_es_out
);
if
(
p_input
->
p
->
p_es_out_display
)
es_out_SetMode
(
p_input
->
p
->
p_es_out_display
,
ES_OUT_MODE_END
);
es_out_Delete
(
p_input
->
p
->
p_es_out_display
);
if
(
p_input
->
p
->
p_resource
)
if
(
p_input
->
p
->
p_resource
)
{
{
if
(
p_input
->
p
->
p_sout
)
if
(
p_input
->
p
->
p_sout
)
...
@@ -1335,7 +1337,6 @@ error_stats:
...
@@ -1335,7 +1337,6 @@ error_stats:
p_input
->
p
->
input
.
p_stream
=
NULL
;
p_input
->
p
->
input
.
p_stream
=
NULL
;
p_input
->
p
->
input
.
p_access
=
NULL
;
p_input
->
p
->
input
.
p_access
=
NULL
;
p_input
->
p
->
p_es_out
=
NULL
;
p_input
->
p
->
p_es_out
=
NULL
;
p_input
->
p
->
p_es_out_display
=
NULL
;
p_input
->
p
->
p_sout
=
NULL
;
p_input
->
p
->
p_sout
=
NULL
;
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
...
@@ -1371,8 +1372,7 @@ static void End( input_thread_t * p_input )
...
@@ -1371,8 +1372,7 @@ static void End( input_thread_t * p_input )
/* Unload all modules */
/* Unload all modules */
if
(
p_input
->
p
->
p_es_out
)
if
(
p_input
->
p
->
p_es_out
)
es_out_Delete
(
p_input
->
p
->
p_es_out
);
es_out_Delete
(
p_input
->
p
->
p_es_out
);
if
(
p_input
->
p
->
p_es_out_display
)
es_out_SetMode
(
p_input
->
p
->
p_es_out_display
,
ES_OUT_MODE_END
);
es_out_Delete
(
p_input
->
p
->
p_es_out_display
);
if
(
!
p_input
->
b_preparsing
)
if
(
!
p_input
->
b_preparsing
)
{
{
...
...
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