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
a7620012
Commit
a7620012
authored
Jun 09, 2004
by
Gildas Bazin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/access/dshow: converted to access2/demux2. Let's hope I didn't break anything ;)
parent
cd3d0c21
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
460 additions
and
417 deletions
+460
-417
modules/access/access2.c
modules/access/access2.c
+1
-0
modules/access/dshow/dshow.cpp
modules/access/dshow/dshow.cpp
+382
-341
modules/access/dshow/filter.cpp
modules/access/dshow/filter.cpp
+65
-66
modules/access/dshow/filter.h
modules/access/dshow/filter.h
+8
-8
modules/demux/demux2.c
modules/demux/demux2.c
+4
-2
No files found.
modules/access/access2.c
View file @
a7620012
...
@@ -69,6 +69,7 @@ vlc_module_begin();
...
@@ -69,6 +69,7 @@ vlc_module_begin();
add_shortcut
(
"svcd"
);
add_shortcut
(
"svcd"
);
add_shortcut
(
"v4l"
);
add_shortcut
(
"v4l"
);
add_shortcut
(
"dshow"
);
vlc_module_end
();
vlc_module_end
();
/*****************************************************************************
/*****************************************************************************
...
...
modules/access/dshow/dshow.cpp
View file @
a7620012
This diff is collapsed.
Click to expand it.
modules/access/dshow/filter.cpp
View file @
a7620012
...
@@ -299,7 +299,7 @@ int GetFourCCFromMediaType(const AM_MEDIA_TYPE &media_type)
...
@@ -299,7 +299,7 @@ int GetFourCCFromMediaType(const AM_MEDIA_TYPE &media_type)
* Implementation of our dummy directshow filter pin class
* Implementation of our dummy directshow filter pin class
****************************************************************************/
****************************************************************************/
CapturePin
::
CapturePin
(
input_thread
_t
*
_p_input
,
CaptureFilter
*
_p_filter
,
CapturePin
::
CapturePin
(
access
_t
*
_p_input
,
CaptureFilter
*
_p_filter
,
AM_MEDIA_TYPE
*
mt
,
size_t
mt_count
)
AM_MEDIA_TYPE
*
mt
,
size_t
mt_count
)
:
p_input
(
_p_input
),
p_filter
(
_p_filter
),
p_connected_pin
(
NULL
),
:
p_input
(
_p_input
),
p_filter
(
_p_filter
),
p_connected_pin
(
NULL
),
media_types
(
mt
),
media_type_count
(
mt_count
),
i_ref
(
1
)
media_types
(
mt
),
media_type_count
(
mt_count
),
i_ref
(
1
)
...
@@ -317,7 +317,7 @@ CapturePin::~CapturePin()
...
@@ -317,7 +317,7 @@ CapturePin::~CapturePin()
#endif
#endif
for
(
size_t
c
=
0
;
c
<
media_type_count
;
c
++
)
for
(
size_t
c
=
0
;
c
<
media_type_count
;
c
++
)
{
{
FreeMediaType
(
media_types
[
c
]);
FreeMediaType
(
media_types
[
c
]);
}
}
FreeMediaType
(
cx_media_type
);
FreeMediaType
(
cx_media_type
);
}
}
...
@@ -328,7 +328,7 @@ HRESULT CapturePin::CustomGetSample( VLCMediaSample *vlc_sample )
...
@@ -328,7 +328,7 @@ HRESULT CapturePin::CustomGetSample( VLCMediaSample *vlc_sample )
msg_Dbg( p_input, "CapturePin::CustomGetSample" );
msg_Dbg( p_input, "CapturePin::CustomGetSample" );
#endif
#endif
access_sys_t
*
p_sys
=
p_input
->
p_
access_data
;
access_sys_t
*
p_sys
=
p_input
->
p_
sys
;
vlc_mutex_lock
(
&
p_sys
->
lock
);
vlc_mutex_lock
(
&
p_sys
->
lock
);
if
(
samples_queue
.
size
()
)
if
(
samples_queue
.
size
()
)
{
{
...
@@ -410,31 +410,31 @@ STDMETHODIMP CapturePin::Connect( IPin * pReceivePin,
...
@@ -410,31 +410,31 @@ STDMETHODIMP CapturePin::Connect( IPin * pReceivePin,
#endif
#endif
if
(
State_Stopped
==
p_filter
->
state
)
if
(
State_Stopped
==
p_filter
->
state
)
{
{
if
(
!
p_connected_pin
)
if
(
!
p_connected_pin
)
{
{
if
(
!
pmt
)
if
(
!
pmt
)
return
S_OK
;
return
S_OK
;
if
(
(
GUID_NULL
!=
pmt
->
majortype
)
&&
(
media_types
[
0
].
majortype
!=
pmt
->
majortype
)
)
if
(
(
GUID_NULL
!=
pmt
->
majortype
)
&&
(
media_types
[
0
].
majortype
!=
pmt
->
majortype
)
)
return
S_FALSE
;
return
S_FALSE
;
if
(
(
GUID_NULL
!=
pmt
->
subtype
)
&&
(
!
GetFourCCFromMediaType
(
*
pmt
))
)
if
(
(
GUID_NULL
!=
pmt
->
subtype
)
&&
(
!
GetFourCCFromMediaType
(
*
pmt
))
)
return
S_FALSE
;
return
S_FALSE
;
if
(
pmt
->
pbFormat
)
if
(
pmt
->
pbFormat
)
{
{
if
(
pmt
->
majortype
==
MEDIATYPE_Video
)
if
(
pmt
->
majortype
==
MEDIATYPE_Video
)
{
{
if
(
(((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biHeight
==
0
)
)
if
(
(((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biHeight
==
0
)
)
return
S_FALSE
;
return
S_FALSE
;
if
(
(((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biWidth
==
0
)
)
if
(
(((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biWidth
==
0
)
)
return
S_FALSE
;
return
S_FALSE
;
}
}
}
}
return
S_OK
;
return
S_OK
;
}
}
return
VFW_E_ALREADY_CONNECTED
;
return
VFW_E_ALREADY_CONNECTED
;
}
}
return
VFW_E_NOT_STOPPED
;
return
VFW_E_NOT_STOPPED
;
}
}
...
@@ -446,16 +446,16 @@ STDMETHODIMP CapturePin::ReceiveConnection( IPin * pConnector,
...
@@ -446,16 +446,16 @@ STDMETHODIMP CapturePin::ReceiveConnection( IPin * pConnector,
#endif
#endif
if
(
State_Stopped
!=
p_filter
->
state
)
if
(
State_Stopped
!=
p_filter
->
state
)
return
VFW_E_NOT_STOPPED
;
return
VFW_E_NOT_STOPPED
;
if
(
!
pmt
)
if
(
!
pmt
)
return
E_POINTER
;
return
E_POINTER
;
if
(
p_connected_pin
)
if
(
p_connected_pin
)
return
VFW_E_ALREADY_CONNECTED
;
return
VFW_E_ALREADY_CONNECTED
;
if
(
S_OK
!=
QueryAccept
(
pmt
)
)
if
(
S_OK
!=
QueryAccept
(
pmt
)
)
return
VFW_E_TYPE_NOT_ACCEPTED
;
return
VFW_E_TYPE_NOT_ACCEPTED
;
p_connected_pin
=
pConnector
;
p_connected_pin
=
pConnector
;
p_connected_pin
->
AddRef
();
p_connected_pin
->
AddRef
();
...
@@ -473,7 +473,7 @@ STDMETHODIMP CapturePin::Disconnect()
...
@@ -473,7 +473,7 @@ STDMETHODIMP CapturePin::Disconnect()
#if 0 // FIXME: This does seem to create crashes sometimes
#if 0 // FIXME: This does seem to create crashes sometimes
VLCMediaSample vlc_sample;
VLCMediaSample vlc_sample;
access_sys_t *p_sys = p_input->p_
access_data
;
access_sys_t *p_sys = p_input->p_
sys
;
vlc_mutex_lock( &p_sys->lock );
vlc_mutex_lock( &p_sys->lock );
while( samples_queue.size() )
while( samples_queue.size() )
...
@@ -554,23 +554,23 @@ STDMETHODIMP CapturePin::QueryAccept( const AM_MEDIA_TYPE *pmt )
...
@@ -554,23 +554,23 @@ STDMETHODIMP CapturePin::QueryAccept( const AM_MEDIA_TYPE *pmt )
#endif
#endif
if
(
State_Stopped
==
p_filter
->
state
)
if
(
State_Stopped
==
p_filter
->
state
)
{
{
if
(
media_types
[
0
].
majortype
==
pmt
->
majortype
)
if
(
media_types
[
0
].
majortype
==
pmt
->
majortype
)
{
{
if
(
GetFourCCFromMediaType
(
*
pmt
)
)
if
(
GetFourCCFromMediaType
(
*
pmt
)
)
{
{
if
(
pmt
->
majortype
==
MEDIATYPE_Video
)
if
(
pmt
->
majortype
==
MEDIATYPE_Video
)
if
(
pmt
->
pbFormat
&&
if
(
pmt
->
pbFormat
&&
((((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biHeight
==
0
)
||
((((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biHeight
==
0
)
||
(((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biWidth
==
0
))
)
(((
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
)
->
bmiHeader
.
biWidth
==
0
))
)
return
S_FALSE
;
return
S_FALSE
;
if
(
!
p_connected_pin
)
if
(
!
p_connected_pin
)
return
S_OK
;
return
S_OK
;
FreeMediaType
(
cx_media_type
);
FreeMediaType
(
cx_media_type
);
return
CopyMediaType
(
&
cx_media_type
,
pmt
);
return
CopyMediaType
(
&
cx_media_type
,
pmt
);
}
}
}
}
}
}
return
S_FALSE
;
return
S_FALSE
;
}
}
...
@@ -660,7 +660,7 @@ STDMETHODIMP CapturePin::Receive( IMediaSample *pSample )
...
@@ -660,7 +660,7 @@ STDMETHODIMP CapturePin::Receive( IMediaSample *pSample )
mtime_t
i_timestamp
=
mdate
()
*
10
;
mtime_t
i_timestamp
=
mdate
()
*
10
;
VLCMediaSample
vlc_sample
=
{
pSample
,
i_timestamp
};
VLCMediaSample
vlc_sample
=
{
pSample
,
i_timestamp
};
access_sys_t
*
p_sys
=
p_input
->
p_
access_data
;
access_sys_t
*
p_sys
=
p_input
->
p_
sys
;
vlc_mutex_lock
(
&
p_sys
->
lock
);
vlc_mutex_lock
(
&
p_sys
->
lock
);
samples_queue
.
push_front
(
vlc_sample
);
samples_queue
.
push_front
(
vlc_sample
);
...
@@ -705,9 +705,10 @@ STDMETHODIMP CapturePin::ReceiveCanBlock( void )
...
@@ -705,9 +705,10 @@ STDMETHODIMP CapturePin::ReceiveCanBlock( void )
/****************************************************************************
/****************************************************************************
* Implementation of our dummy directshow filter class
* Implementation of our dummy directshow filter class
****************************************************************************/
****************************************************************************/
CaptureFilter
::
CaptureFilter
(
access_t
*
_p_input
,
AM_MEDIA_TYPE
*
mt
,
CaptureFilter
::
CaptureFilter
(
input_thread_t
*
_p_input
,
AM_MEDIA_TYPE
*
mt
,
size_t
mt_count
)
size_t
mt_count
)
:
p_input
(
_p_input
),
p_pin
(
new
CapturePin
(
_p_input
,
this
,
mt
,
mt_count
)
),
:
p_input
(
_p_input
),
p_pin
(
new
CapturePin
(
_p_input
,
this
,
mt
,
mt_count
)
),
state
(
State_Stopped
),
i_ref
(
1
)
state
(
State_Stopped
),
i_ref
(
1
)
{
{
}
}
...
@@ -909,7 +910,7 @@ CapturePin *CaptureFilter::CustomGetPin()
...
@@ -909,7 +910,7 @@ CapturePin *CaptureFilter::CustomGetPin()
* Implementation of our dummy directshow enumpins class
* Implementation of our dummy directshow enumpins class
****************************************************************************/
****************************************************************************/
CaptureEnumPins
::
CaptureEnumPins
(
input_thread
_t
*
_p_input
,
CaptureEnumPins
::
CaptureEnumPins
(
access
_t
*
_p_input
,
CaptureFilter
*
_p_filter
,
CaptureFilter
*
_p_filter
,
CaptureEnumPins
*
pEnumPins
)
CaptureEnumPins
*
pEnumPins
)
:
p_input
(
_p_input
),
p_filter
(
_p_filter
),
i_ref
(
1
)
:
p_input
(
_p_input
),
p_filter
(
_p_filter
),
i_ref
(
1
)
...
@@ -1038,10 +1039,8 @@ STDMETHODIMP CaptureEnumPins::Clone( IEnumPins **ppEnum )
...
@@ -1038,10 +1039,8 @@ STDMETHODIMP CaptureEnumPins::Clone( IEnumPins **ppEnum )
/****************************************************************************
/****************************************************************************
* Implementation of our dummy directshow enummediatypes class
* Implementation of our dummy directshow enummediatypes class
****************************************************************************/
****************************************************************************/
CaptureEnumMediaTypes
::
CaptureEnumMediaTypes
(
access_t
*
_p_input
,
CaptureEnumMediaTypes
::
CaptureEnumMediaTypes
(
input_thread_t
*
_p_input
,
CapturePin
*
_p_pin
,
CaptureEnumMediaTypes
*
pEnumMediaTypes
)
CapturePin
*
_p_pin
,
CaptureEnumMediaTypes
*
pEnumMediaTypes
)
:
p_input
(
_p_input
),
p_pin
(
_p_pin
),
i_ref
(
1
)
:
p_input
(
_p_input
),
p_pin
(
_p_pin
),
i_ref
(
1
)
{
{
/* Hold a reference count on our filter */
/* Hold a reference count on our filter */
...
@@ -1116,7 +1115,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Next( ULONG cMediaTypes,
...
@@ -1116,7 +1115,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Next( ULONG cMediaTypes,
ULONG
count
;
ULONG
count
;
if
(
!
ppMediaTypes
)
if
(
!
ppMediaTypes
)
return
E_POINTER
;
return
E_POINTER
;
if
(
(
!
pcFetched
)
&&
(
cMediaTypes
>
1
)
)
if
(
(
!
pcFetched
)
&&
(
cMediaTypes
>
1
)
)
return
E_POINTER
;
return
E_POINTER
;
...
@@ -1125,17 +1124,17 @@ STDMETHODIMP CaptureEnumMediaTypes::Next( ULONG cMediaTypes,
...
@@ -1125,17 +1124,17 @@ STDMETHODIMP CaptureEnumMediaTypes::Next( ULONG cMediaTypes,
while
(
(
count
<
cMediaTypes
)
&&
(
i_position
<
p_pin
->
media_type_count
)
)
while
(
(
count
<
cMediaTypes
)
&&
(
i_position
<
p_pin
->
media_type_count
)
)
{
{
ppMediaTypes
[
count
]
=
(
AM_MEDIA_TYPE
*
)
CoTaskMemAlloc
(
sizeof
(
AM_MEDIA_TYPE
));
ppMediaTypes
[
count
]
=
(
AM_MEDIA_TYPE
*
)
CoTaskMemAlloc
(
sizeof
(
AM_MEDIA_TYPE
));
if
(
CopyMediaType
(
ppMediaTypes
[
count
],
&
p_pin
->
media_types
[
i_position
])
!=
S_OK
)
if
(
CopyMediaType
(
ppMediaTypes
[
count
],
&
p_pin
->
media_types
[
i_position
])
!=
S_OK
)
return
E_OUTOFMEMORY
;
return
E_OUTOFMEMORY
;
count
++
;
count
++
;
i_position
++
;
i_position
++
;
}
}
if
(
pcFetched
)
if
(
pcFetched
)
{
{
*
pcFetched
=
count
;
*
pcFetched
=
count
;
}
}
return
(
count
==
cMediaTypes
)
?
S_OK
:
S_FALSE
;
return
(
count
==
cMediaTypes
)
?
S_OK
:
S_FALSE
;
...
...
modules/access/dshow/filter.h
View file @
a7620012
...
@@ -69,7 +69,7 @@ class CapturePin: public IPin, public IMemInputPin
...
@@ -69,7 +69,7 @@ class CapturePin: public IPin, public IMemInputPin
{
{
friend
class
CaptureEnumMediaTypes
;
friend
class
CaptureEnumMediaTypes
;
input_thread
_t
*
p_input
;
access
_t
*
p_input
;
CaptureFilter
*
p_filter
;
CaptureFilter
*
p_filter
;
IPin
*
p_connected_pin
;
IPin
*
p_connected_pin
;
...
@@ -84,7 +84,7 @@ class CapturePin: public IPin, public IMemInputPin
...
@@ -84,7 +84,7 @@ class CapturePin: public IPin, public IMemInputPin
long
i_ref
;
long
i_ref
;
public:
public:
CapturePin
(
input_thread
_t
*
_p_input
,
CaptureFilter
*
_p_filter
,
CapturePin
(
access
_t
*
_p_input
,
CaptureFilter
*
_p_filter
,
AM_MEDIA_TYPE
*
mt
,
size_t
mt_count
);
AM_MEDIA_TYPE
*
mt
,
size_t
mt_count
);
virtual
~
CapturePin
();
virtual
~
CapturePin
();
...
@@ -134,7 +134,7 @@ class CaptureFilter : public IBaseFilter
...
@@ -134,7 +134,7 @@ class CaptureFilter : public IBaseFilter
{
{
friend
class
CapturePin
;
friend
class
CapturePin
;
input_thread
_t
*
p_input
;
access
_t
*
p_input
;
CapturePin
*
p_pin
;
CapturePin
*
p_pin
;
IFilterGraph
*
p_graph
;
IFilterGraph
*
p_graph
;
//AM_MEDIA_TYPE media_type;
//AM_MEDIA_TYPE media_type;
...
@@ -143,7 +143,7 @@ class CaptureFilter : public IBaseFilter
...
@@ -143,7 +143,7 @@ class CaptureFilter : public IBaseFilter
long
i_ref
;
long
i_ref
;
public:
public:
CaptureFilter
(
input_thread
_t
*
_p_input
,
AM_MEDIA_TYPE
*
mt
,
size_t
mt_count
);
CaptureFilter
(
access
_t
*
_p_input
,
AM_MEDIA_TYPE
*
mt
,
size_t
mt_count
);
virtual
~
CaptureFilter
();
virtual
~
CaptureFilter
();
/* IUnknown methods */
/* IUnknown methods */
...
@@ -178,14 +178,14 @@ class CaptureFilter : public IBaseFilter
...
@@ -178,14 +178,14 @@ class CaptureFilter : public IBaseFilter
****************************************************************************/
****************************************************************************/
class
CaptureEnumPins
:
public
IEnumPins
class
CaptureEnumPins
:
public
IEnumPins
{
{
input_thread
_t
*
p_input
;
access
_t
*
p_input
;
CaptureFilter
*
p_filter
;
CaptureFilter
*
p_filter
;
int
i_position
;
int
i_position
;
long
i_ref
;
long
i_ref
;
public:
public:
CaptureEnumPins
(
input_thread
_t
*
_p_input
,
CaptureFilter
*
_p_filter
,
CaptureEnumPins
(
access
_t
*
_p_input
,
CaptureFilter
*
_p_filter
,
CaptureEnumPins
*
pEnumPins
);
CaptureEnumPins
*
pEnumPins
);
virtual
~
CaptureEnumPins
();
virtual
~
CaptureEnumPins
();
...
@@ -206,14 +206,14 @@ public:
...
@@ -206,14 +206,14 @@ public:
****************************************************************************/
****************************************************************************/
class
CaptureEnumMediaTypes
:
public
IEnumMediaTypes
class
CaptureEnumMediaTypes
:
public
IEnumMediaTypes
{
{
input_thread
_t
*
p_input
;
access
_t
*
p_input
;
CapturePin
*
p_pin
;
CapturePin
*
p_pin
;
int
i_position
;
int
i_position
;
long
i_ref
;
long
i_ref
;
public:
public:
CaptureEnumMediaTypes
(
input_thread
_t
*
_p_input
,
CapturePin
*
_p_pin
,
CaptureEnumMediaTypes
(
access
_t
*
_p_input
,
CapturePin
*
_p_pin
,
CaptureEnumMediaTypes
*
pEnumMediaTypes
);
CaptureEnumMediaTypes
*
pEnumMediaTypes
);
virtual
~
CaptureEnumMediaTypes
();
virtual
~
CaptureEnumMediaTypes
();
...
...
modules/demux/demux2.c
View file @
a7620012
...
@@ -71,6 +71,7 @@ vlc_module_begin();
...
@@ -71,6 +71,7 @@ vlc_module_begin();
add_shortcut
(
"directory"
);
add_shortcut
(
"directory"
);
add_shortcut
(
"wav"
);
add_shortcut
(
"wav"
);
add_shortcut
(
"v4l"
);
add_shortcut
(
"v4l"
);
add_shortcut
(
"dshow"
);
vlc_module_end
();
vlc_module_end
();
/*****************************************************************************
/*****************************************************************************
...
@@ -141,8 +142,9 @@ static int Demux2Open( vlc_object_t * p_this )
...
@@ -141,8 +142,9 @@ static int Demux2Open( vlc_object_t * p_this )
*****************************************************************************/
*****************************************************************************/
static
int
Demux2Demux
(
input_thread_t
*
p_input
)
static
int
Demux2Demux
(
input_thread_t
*
p_input
)
{
{
demux2_sys_t
*
p_sys
=
(
demux2_sys_t
*
)
p_input
->
p_demux_data
;
demux2_sys_t
*
p_sys
=
(
demux2_sys_t
*
)
p_input
->
p_demux_data
;
p_sys
->
p_demux
->
b_die
=
p_input
->
b_die
;
return
demux2_Demux
(
p_sys
->
p_demux
);
return
demux2_Demux
(
p_sys
->
p_demux
);
}
}
...
@@ -151,7 +153,7 @@ static int Demux2Demux( input_thread_t * p_input )
...
@@ -151,7 +153,7 @@ static int Demux2Demux( input_thread_t * p_input )
*****************************************************************************/
*****************************************************************************/
static
int
Demux2Control
(
input_thread_t
*
p_input
,
int
i_query
,
va_list
args
)
static
int
Demux2Control
(
input_thread_t
*
p_input
,
int
i_query
,
va_list
args
)
{
{
demux2_sys_t
*
p_sys
=
(
demux2_sys_t
*
)
p_input
->
p_demux_data
;
demux2_sys_t
*
p_sys
=
(
demux2_sys_t
*
)
p_input
->
p_demux_data
;
return
demux2_vaControl
(
p_sys
->
p_demux
,
i_query
,
args
);
return
demux2_vaControl
(
p_sys
->
p_demux
,
i_query
,
args
);
}
}
...
...
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