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
6ee0c084
Commit
6ee0c084
authored
Aug 25, 2003
by
Gildas Bazin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/access/dshow/*: audio is now supported as well.
parent
7caa1250
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
262 additions
and
195 deletions
+262
-195
modules/access/dshow/dshow.cpp
modules/access/dshow/dshow.cpp
+255
-193
modules/access/dshow/filter.cpp
modules/access/dshow/filter.cpp
+7
-2
No files found.
modules/access/dshow/dshow.cpp
View file @
6ee0c084
...
...
@@ -2,7 +2,7 @@
* dshow.c : DirectShow access module for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: dshow.cpp,v 1.
1 2003/08/24 11:17:39
gbazin Exp $
* $Id: dshow.cpp,v 1.
2 2003/08/25 21:45:04
gbazin Exp $
*
* Author: Gildas Bazin <gbazin@netcourrier.com>
*
...
...
@@ -46,6 +46,7 @@
#endif
#include <dshow.h>
#include <vector>
#include "filter.h"
...
...
@@ -60,9 +61,9 @@ static int DemuxOpen ( vlc_object_t * );
static
void
DemuxClose
(
vlc_object_t
*
);
static
int
Demux
(
input_thread_t
*
);
static
int
OpenDevice
(
input_thread_t
*
,
string
);
static
int
OpenDevice
(
input_thread_t
*
,
string
,
vlc_bool_t
);
static
IBaseFilter
*
FindCaptureDevice
(
vlc_object_t
*
,
string
*
,
list
<
string
>
*
);
list
<
string
>
*
,
vlc_bool_t
);
static
bool
ConnectFilters
(
IFilterGraph
*
p_graph
,
IBaseFilter
*
p_filter
,
IPin
*
p_input_pin
);
...
...
@@ -80,7 +81,7 @@ vlc_module_begin();
add_integer
(
"dshow-caching"
,
DEFAULT_PTS_DELAY
/
1000
,
NULL
,
CACHING_TEXT
,
CACHING_LONGTEXT
,
VLC_TRUE
);
add_shortcut
(
"dshow"
);
set_capability
(
"access"
,
1
0
);
set_capability
(
"access"
,
0
);
set_callbacks
(
AccessOpen
,
AccessClose
);
add_submodule
();
...
...
@@ -130,38 +131,47 @@ static void SetQWBE( uint8_t *p, uint64_t qw )
SetDWBE
(
&
p
[
4
],
qw
&
0xffffffff
);
}
/****************************************************************************
* DirectShow elementary stream descriptor
****************************************************************************/
typedef
struct
dshow_stream_t
{
string
devicename
;
IBaseFilter
*
p_device_filter
;
CaptureFilter
*
p_capture_filter
;
AM_MEDIA_TYPE
mt
;
int
i_fourcc
;
union
{
VIDEOINFOHEADER
video
;
WAVEFORMATEX
audio
;
}
header
;
VLCMediaSample
sample
;
int
i_data_size
;
int
i_data_pos
;
uint8_t
*
p_data
;
}
dshow_stream_t
;
/****************************************************************************
* Access descriptor declaration
****************************************************************************/
struct
access_sys_t
{
IFilterGraph
*
p_graph
;
IBaseFilter
*
p_device_filter
;
CaptureFilter
*
p_capture_filter
;
IMediaControl
*
p_control
;
AM_MEDIA_TYPE
mt
;
/* video */
char
*
psz_video_device
;
int
i_fourcc
;
int
i_width
;
int
i_height
;
VIDEOINFOHEADER
vid_header
;
/* audio */
/* header */
int
i_header_size
;
int
i_header_pos
;
uint8_t
*
p_header
;
// at lest 8 bytes allocated
uint8_t
*
p_header
;
/* data */
int
i_data_size
;
int
i_data_pos
;
uint8_t
*
p_data
;
VLCMediaSample
sample
;
/* list of elementary streams */
vector
<
dshow_stream_t
>
streams
;
int
i_current_stream
;
};
/*****************************************************************************
...
...
@@ -208,21 +218,50 @@ static int AccessOpen( vlc_object_t *p_this )
(
access_sys_t
*
)
malloc
(
sizeof
(
access_sys_t
)
);
memset
(
p_sys
,
0
,
sizeof
(
access_sys_t
)
);
/* Initialize some data */
p_sys
->
psz_video_device
=
NULL
;
p_sys
->
sample
.
p_sample
=
NULL
;
p_sys
->
i_data_size
=
0
;
p_sys
->
i_data_pos
=
0
;
/* Create header */
p_sys
->
i_header_size
=
8
;
p_sys
->
p_header
=
(
uint8_t
*
)
malloc
(
p_sys
->
i_header_size
);
memcpy
(
&
p_sys
->
p_header
[
0
],
".dsh"
,
4
);
SetDWBE
(
&
p_sys
->
p_header
[
4
],
1
);
p_sys
->
i_header_pos
=
p_sys
->
i_header_size
;
/* Build directshow graph */
CoCreateInstance
(
CLSID_FilterGraph
,
0
,
CLSCTX_INPROC
,
(
REFIID
)
IID_IFilterGraph
,
(
void
**
)
&
p_sys
->
p_graph
);
p_sys
->
p_graph
->
QueryInterface
(
IID_IMediaControl
,
(
void
**
)
&
p_sys
->
p_control
);
if
(
OpenDevice
(
p_input
,
p_input
->
psz_name
,
0
)
!=
VLC_SUCCESS
)
{
msg_Err
(
p_input
,
"can't open video"
);
}
if
(
OpenDevice
(
p_input
,
p_input
->
psz_name
)
!=
VLC_SUCCESS
)
if
(
OpenDevice
(
p_input
,
p_input
->
psz_name
,
1
)
!=
VLC_SUCCESS
)
{
msg_Err
(
p_input
,
"can't open audio"
);
}
if
(
p_sys
->
streams
.
empty
()
)
{
/* Uninitialize OLE/COM */
CoUninitialize
();
/* Release directshow objects */
p_sys
->
p_control
->
Release
();
p_sys
->
p_graph
->
Release
();
free
(
p_sys
->
p_header
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
/* Initialize some data */
p_sys
->
i_current_stream
=
0
;
p_sys
->
i_header_pos
=
0
;
/* Everything is ready. Let's rock baby */
p_sys
->
p_control
->
Run
();
return
VLC_SUCCESS
;
}
...
...
@@ -278,19 +317,18 @@ static bool ConnectFilters( IFilterGraph *p_graph, IBaseFilter *p_filter,
return
false
;
}
static
int
OpenDevice
(
input_thread_t
*
p_input
,
string
devicename
)
static
int
OpenDevice
(
input_thread_t
*
p_input
,
string
devicename
,
vlc_bool_t
b_audio
)
{
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
list
<
string
>
list_devices
;
#if 1
// Enum devices and display their names
FindCaptureDevice
(
(
vlc_object_t
*
)
p_input
,
NULL
,
&
list_devices
);
/* Enumerate audio devices and display their names */
FindCaptureDevice
(
(
vlc_object_t
*
)
p_input
,
NULL
,
&
list_devices
,
b_audio
);
list
<
string
>::
iterator
iter
;
for
(
iter
=
list_devices
.
begin
();
iter
!=
list_devices
.
end
();
iter
++
)
msg_Err
(
p_input
,
"found device: %s"
,
iter
->
c_str
()
);
#endif
msg_Dbg
(
p_input
,
"found device: %s"
,
iter
->
c_str
()
);
/* If no device name was specified, pick the 1st one */
if
(
devicename
.
size
()
==
0
)
...
...
@@ -299,145 +337,159 @@ static int OpenDevice( input_thread_t *p_input, string devicename )
}
// Use the system device enumerator and class enumerator to find
// a video capture/preview device, such as a desktop USB video camera.
p_sys
->
p_device_filter
=
FindCaptureDevice
(
(
vlc_object_t
*
)
p_input
,
&
devicename
,
NULL
);
if
(
p_sys
->
p_device_filter
)
msg_Dbg
(
p_input
,
"found device: %s"
,
devicename
.
c_str
()
);
/* Build graph */
CoCreateInstance
(
CLSID_FilterGraph
,
0
,
CLSCTX_INPROC
,
(
REFIID
)
IID_IFilterGraph
,
(
void
**
)
&
p_sys
->
p_graph
);
p_sys
->
p_graph
->
QueryInterface
(
IID_IMediaControl
,
(
void
**
)
&
p_sys
->
p_control
);
// a capture/preview device, such as a desktop USB video camera.
IBaseFilter
*
p_device_filter
=
FindCaptureDevice
(
(
vlc_object_t
*
)
p_input
,
&
devicename
,
NULL
,
b_audio
);
if
(
p_device_filter
)
msg_Dbg
(
p_input
,
"using device: %s"
,
devicename
.
c_str
()
);
else
{
msg_Err
(
p_input
,
"can't use device: %s"
,
devicename
.
c_str
()
);
return
VLC_EGENERIC
;
}
/* Create and add our capture filter */
p_sys
->
p_capture_filter
=
new
CaptureFilter
(
p_input
);
p_sys
->
p_graph
->
AddFilter
(
p_
sys
->
p_
capture_filter
,
0
);
CaptureFilter
*
p_capture_filter
=
new
CaptureFilter
(
p_input
);
p_sys
->
p_graph
->
AddFilter
(
p_capture_filter
,
0
);
/* Add the device filter to the graph (seems necessary with VfW before
* accessing pin attributes). */
p_sys
->
p_graph
->
AddFilter
(
p_
sys
->
p_
device_filter
,
0
);
p_sys
->
p_graph
->
AddFilter
(
p_device_filter
,
0
);
/
/ Attempt to connect one of this device's capture output pins
/
* Attempt to connect one of this device's capture output pins */
msg_Dbg
(
p_input
,
"connecting filters"
);
if
(
ConnectFilters
(
p_sys
->
p_graph
,
p_
sys
->
p_
device_filter
,
p_
sys
->
p_
capture_filter
->
CustomGetPin
()
)
)
if
(
ConnectFilters
(
p_sys
->
p_graph
,
p_device_filter
,
p_capture_filter
->
CustomGetPin
()
)
)
{
/* Success */
int
i_fourcc
=
VLC_FOURCC
(
' '
,
' '
,
' '
,
' '
);
AM_MEDIA_TYPE
*
pmt
=
&
p_sys
->
mt
;
p_sys
->
mt
=
p_sys
->
p_capture_filter
->
CustomGetPin
()
->
CustomGetMediaType
();
dshow_stream_t
dshow_stream
;
dshow_stream
.
mt
=
p_capture_filter
->
CustomGetPin
()
->
CustomGetMediaType
();
if
(
pmt
->
majortype
==
MEDIATYPE_Video
)
if
(
dshow_stream
.
mt
.
majortype
==
MEDIATYPE_Video
)
{
if
(
pmt
->
subtype
==
MEDIASUBTYPE_RGB8
)
{
i_fourcc
=
VLC_FOURCC
(
'G'
,
'R'
,
'E'
,
'Y'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_RGB555
)
{
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'1'
,
'5'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_RGB565
)
{
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'1'
,
'6'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_RGB24
)
{
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'2'
,
'4'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_RGB32
)
{
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'3'
,
'2'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_ARGB32
)
{
i_fourcc
=
VLC_FOURCC
(
'R'
,
'G'
,
'B'
,
'A'
);
}
msg_Dbg
(
p_input
,
"MEDIATYPE_Video"
);
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_RGB8
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'G'
,
'R'
,
'E'
,
'Y'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_RGB555
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'1'
,
'5'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_RGB565
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'1'
,
'6'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_RGB24
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'2'
,
'4'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_RGB32
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'R'
,
'V'
,
'3'
,
'2'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_ARGB32
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'R'
,
'G'
,
'B'
,
'A'
);
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_YUYV
)
{
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'U'
,
'Y'
,
'V'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_Y411
)
{
i_fourcc
=
VLC_FOURCC
(
'I'
,
'4'
,
'1'
,
'N'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_Y41P
)
{
i_fourcc
=
VLC_FOURCC
(
'I'
,
'4'
,
'1'
,
'1'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_YUY2
)
{
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'U'
,
'Y'
,
'2'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_YVYU
)
{
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'V'
,
'Y'
,
'U'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_Y411
)
{
i_fourcc
=
VLC_FOURCC
(
'I'
,
'4'
,
'1'
,
'N'
);
}
else
if
(
pmt
->
subtype
==
MEDIASUBTYPE_YV12
)
{
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
);
}
p_sys
->
i_fourcc
=
i_fourcc
;
p_sys
->
vid_header
=
*
(
VIDEOINFOHEADER
*
)
pmt
->
pbFormat
;
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_YUYV
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'U'
,
'Y'
,
'V'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_Y411
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'I'
,
'4'
,
'1'
,
'N'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_Y41P
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'I'
,
'4'
,
'1'
,
'1'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_YUY2
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'U'
,
'Y'
,
'2'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_YVYU
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'V'
,
'Y'
,
'U'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_Y411
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'I'
,
'4'
,
'1'
,
'N'
);
else
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_YV12
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
);
else
goto
fail
;
dshow_stream
.
header
.
video
=
*
(
VIDEOINFOHEADER
*
)
dshow_stream
.
mt
.
pbFormat
;
/* Add video stream to header */
p_sys
->
i_header_size
+=
20
;
p_sys
->
p_header
=
(
uint8_t
*
)
realloc
(
p_sys
->
p_header
,
p_sys
->
i_header_size
);
memcpy
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
],
"vids"
,
4
);
memcpy
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
4
],
&
dshow_stream
.
i_fourcc
,
4
);
SetDWBE
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
8
],
dshow_stream
.
header
.
video
.
bmiHeader
.
biWidth
);
SetDWBE
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
12
],
dshow_stream
.
header
.
video
.
bmiHeader
.
biHeight
);
SetDWBE
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
16
],
0
);
p_sys
->
i_header_pos
=
p_sys
->
i_header_size
;
}
/* create header */
p_sys
->
i_header_size
=
8
+
20
;
p_sys
->
i_header_pos
=
0
;
p_sys
->
p_header
=
(
uint8_t
*
)
malloc
(
p_sys
->
i_header_size
);
else
if
(
dshow_stream
.
mt
.
majortype
==
MEDIATYPE_Audio
&&
dshow_stream
.
mt
.
formattype
==
FORMAT_WaveFormatEx
)
{
msg_Dbg
(
p_input
,
"MEDIATYPE_Audio"
);
memcpy
(
&
p_sys
->
p_header
[
0
],
".dsh"
,
4
);
SetDWBE
(
&
p_sys
->
p_header
[
4
],
1
);
memcpy
(
&
p_sys
->
p_header
[
8
],
"vids"
,
4
);
memcpy
(
&
p_sys
->
p_header
[
12
],
&
i_fourcc
,
4
);
SetDWBE
(
&
p_sys
->
p_header
[
16
],
p_sys
->
vid_header
.
bmiHeader
.
biWidth
);
SetDWBE
(
&
p_sys
->
p_header
[
20
],
p_sys
->
vid_header
.
bmiHeader
.
biHeight
);
SetDWBE
(
&
p_sys
->
p_header
[
24
],
0
);
if
(
dshow_stream
.
mt
.
subtype
==
MEDIASUBTYPE_PCM
)
dshow_stream
.
i_fourcc
=
VLC_FOURCC
(
'a'
,
'r'
,
'a'
,
'w'
);
#if 0
else if( dshow_stream.mt.subtype == MEDIASUBTYPE_IEEE_FLOAT )
dshow_stream.i_fourcc = VLC_FOURCC( 'f', 'l', '3', '2' );
#endif
else
goto
fail
;
dshow_stream
.
header
.
audio
=
*
(
WAVEFORMATEX
*
)
dshow_stream
.
mt
.
pbFormat
;
/* Add audio stream to header */
p_sys
->
i_header_size
+=
20
;
p_sys
->
p_header
=
(
uint8_t
*
)
realloc
(
p_sys
->
p_header
,
p_sys
->
i_header_size
);
memcpy
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
],
"auds"
,
4
);
memcpy
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
4
],
&
dshow_stream
.
i_fourcc
,
4
);
SetDWBE
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
8
],
dshow_stream
.
header
.
audio
.
nChannels
);
SetDWBE
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
12
],
dshow_stream
.
header
.
audio
.
nSamplesPerSec
);
SetDWBE
(
&
p_sys
->
p_header
[
p_sys
->
i_header_pos
+
16
],
dshow_stream
.
header
.
audio
.
wBitsPerSample
);
p_sys
->
i_header_pos
=
p_sys
->
i_header_size
;
}
else
goto
fail
;
p_sys
->
p_control
->
Run
();
/* Add directshow elementary stream to our list */
dshow_stream
.
sample
.
p_sample
=
NULL
;
dshow_stream
.
i_data_size
=
0
;
dshow_stream
.
i_data_pos
=
0
;
dshow_stream
.
p_device_filter
=
p_device_filter
;
dshow_stream
.
p_capture_filter
=
p_capture_filter
;
p_sys
->
streams
.
push_back
(
dshow_stream
);
SetDWBE
(
&
p_sys
->
p_header
[
4
],
(
uint32_t
)
p_sys
->
streams
.
size
()
);
// We're done
return
VLC_SUCCESS
;
}
fail:
/* Remove filters from graph */
p_sys
->
p_graph
->
RemoveFilter
(
p_
sys
->
p_
device_filter
);
p_sys
->
p_graph
->
RemoveFilter
(
p_
sys
->
p_
capture_filter
);
p_sys
->
p_graph
->
RemoveFilter
(
p_device_filter
);
p_sys
->
p_graph
->
RemoveFilter
(
p_capture_filter
);
/* Release objects */
p_sys
->
p_device_filter
->
Release
();
p_sys
->
p_capture_filter
->
Release
();
p_sys
->
p_control
->
Release
();
p_sys
->
p_graph
->
Release
();
p_device_filter
->
Release
();
p_capture_filter
->
Release
();
return
VLC_EGENERIC
;
}
static
IBaseFilter
*
FindCaptureDevice
(
vlc_object_t
*
p_this
,
string
*
p_devicename
,
list
<
string
>
*
p_listdevices
)
list
<
string
>
*
p_listdevices
,
vlc_bool_t
b_audio
)
{
IBaseFilter
*
p
BaseF
ilter
=
NULL
;
IMoniker
*
p
M
oniker
=
NULL
;
ULONG
lF
etched
;
IBaseFilter
*
p
_base_f
ilter
=
NULL
;
IMoniker
*
p
_m
oniker
=
NULL
;
ULONG
i_f
etched
;
HRESULT
hr
;
/* Create the system device enumerator */
ICreateDevEnum
*
p
DevE
num
=
NULL
;
ICreateDevEnum
*
p
_dev_e
num
=
NULL
;
hr
=
CoCreateInstance
(
CLSID_SystemDeviceEnum
,
NULL
,
CLSCTX_INPROC
,
IID_ICreateDevEnum
,
(
void
**
)
&
p
DevE
num
);
IID_ICreateDevEnum
,
(
void
**
)
&
p
_dev_e
num
);
if
(
FAILED
(
hr
)
)
{
msg_Err
(
p_this
,
"failed to create the device enumerator (0x%x)"
,
hr
);
...
...
@@ -445,9 +497,14 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
}
/* Create an enumerator for the video capture devices */
IEnumMoniker
*
pClassEnum
=
NULL
;
hr
=
pDevEnum
->
CreateClassEnumerator
(
CLSID_VideoInputDeviceCategory
,
&
pClassEnum
,
0
);
IEnumMoniker
*
p_class_enum
=
NULL
;
if
(
!
b_audio
)
hr
=
p_dev_enum
->
CreateClassEnumerator
(
CLSID_VideoInputDeviceCategory
,
&
p_class_enum
,
0
);
else
hr
=
p_dev_enum
->
CreateClassEnumerator
(
CLSID_AudioInputDeviceCategory
,
&
p_class_enum
,
0
);
p_dev_enum
->
Release
();
if
(
FAILED
(
hr
)
)
{
msg_Err
(
p_this
,
"failed to create the class enumerator (0x%x)"
,
hr
);
...
...
@@ -455,10 +512,10 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
}
/* If there are no enumerators for the requested type, then
* CreateClassEnumerator will succeed, but p
ClassE
num will be NULL */
if
(
p
ClassE
num
==
NULL
)
* CreateClassEnumerator will succeed, but p
_class_e
num will be NULL */
if
(
p
_class_e
num
==
NULL
)
{
msg_Err
(
p_this
,
"no
video
capture device was detected."
);
msg_Err
(
p_this
,
"no capture device was detected."
);
return
NULL
;
}
...
...
@@ -468,18 +525,18 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
* it will return S_FALSE (which is not a failure). Therefore, we check
* that the return code is S_OK instead of using SUCCEEDED() macro. */
while
(
p
ClassEnum
->
Next
(
1
,
&
pMoniker
,
&
lF
etched
)
==
S_OK
)
while
(
p
_class_enum
->
Next
(
1
,
&
p_moniker
,
&
i_f
etched
)
==
S_OK
)
{
/* Getting the property page to get the device name */
IPropertyBag
*
p
B
ag
;
hr
=
p
M
oniker
->
BindToStorage
(
0
,
0
,
IID_IPropertyBag
,
reinterpret_cast
<
PVOID
*>
(
&
pBag
)
);
IPropertyBag
*
p
_b
ag
;
hr
=
p
_m
oniker
->
BindToStorage
(
0
,
0
,
IID_IPropertyBag
,
(
void
**
)
&
p_bag
);
if
(
SUCCEEDED
(
hr
)
)
{
VARIANT
var
;
var
.
vt
=
VT_BSTR
;
hr
=
p
B
ag
->
Read
(
L"FriendlyName"
,
&
var
,
NULL
);
p
B
ag
->
Release
();
hr
=
p
_b
ag
->
Read
(
L"FriendlyName"
,
&
var
,
NULL
);
p
_b
ag
->
Release
();
if
(
SUCCEEDED
(
hr
)
)
{
int
i_convert
=
(
lstrlenW
(
var
.
bstrVal
)
+
1
)
*
2
;
...
...
@@ -493,20 +550,27 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
if
(
p_devicename
&&
*
p_devicename
==
string
(
p_buf
)
)
{
/* Bind Moniker to a filter object */
hr
=
p
M
oniker
->
BindToObject
(
0
,
0
,
IID_IBaseFilter
,
reinterpret_cast
<
LPVOID
*>
(
&
pBaseFilter
)
);
hr
=
p
_m
oniker
->
BindToObject
(
0
,
0
,
IID_IBaseFilter
,
(
void
**
)
&
p_base_filter
);
if
(
FAILED
(
hr
)
)
{
msg_Err
(
p_this
,
"couldn't bind moniker to filter "
"object (0x%x)"
,
hr
);
p_moniker
->
Release
();
p_class_enum
->
Release
();
return
NULL
;
}
return
pBaseFilter
;
p_moniker
->
Release
();
p_class_enum
->
Release
();
return
p_base_filter
;
}
}
}
p_moniker
->
Release
();
}
p_class_enum
->
Release
();
return
NULL
;
}
...
...
@@ -518,8 +582,9 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
*****************************************************************************/
static
int
Read
(
input_thread_t
*
p_input
,
byte_t
*
p_buffer
,
size_t
i_len
)
{
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
int
i_data
=
0
;
access_sys_t
*
p_sys
=
p_input
->
p_access_data
;
dshow_stream_t
*
p_stream
=
&
p_sys
->
streams
[
p_sys
->
i_current_stream
];
int
i_data
=
0
;
#if 0
msg_Info( p_input, "access read data_size %i, data_pos %i",
...
...
@@ -543,16 +608,15 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
i_data
+=
i_copy
;
}
/* Then copy
data
*/
if
(
i_len
>
0
&&
p_s
ys
->
i_data_pos
<
p_sys
->
i_data_size
)
/* Then copy
stream data if any
*/
if
(
i_len
>
0
&&
p_s
tream
->
i_data_pos
<
p_stream
->
i_data_size
)
{
int
i_copy
;
int
i_copy
=
__MIN
(
p_stream
->
i_data_size
-
p_stream
->
i_data_pos
,
(
int
)
i_len
);
i_copy
=
__MIN
(
p_sys
->
i_data_size
-
p_sys
->
i_data_pos
,
(
int
)
i_len
);
memcpy
(
p_buffer
,
&
p_sys
->
p_data
[
p_sys
->
i_data_pos
],
i_copy
);
p_sys
->
i_data_pos
+=
i_copy
;
memcpy
(
p_buffer
,
&
p_stream
->
p_data
[
p_stream
->
i_data_pos
],
i_copy
);
p_stream
->
i_data_pos
+=
i_copy
;
p_buffer
+=
i_copy
;
i_len
-=
i_copy
;
...
...
@@ -560,52 +624,50 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
}
/* The caller got what he wanted */
if
(
i_len
<=
0
)
{
return
i_data
;
}
if
(
i_len
<=
0
)
return
i_data
;
/* Read no more than one frame at a time, otherwise we kill latency */
if
(
p_s
ys
->
i_data_size
&&
i_data
&&
p_s
ys
->
i_data_pos
==
p_sys
->
i_data_size
)
if
(
p_s
tream
->
i_data_size
&&
i_data
&&
p_s
tream
->
i_data_pos
==
p_stream
->
i_data_size
)
{
p_s
ys
->
i_data_pos
=
0
;
p_sys
->
i_data_size
=
0
;
p_s
tream
->
i_data_pos
=
p_stream
->
i_data_size
=
0
;
return
i_data
;
}
/*
Start new audio/video frame
*/
if
(
p_sys
->
sample
.
p_sample
)
{
//p_sys->sample.p_sample->Releas
e();
}
if
(
p_sys
->
p_capture_filter
->
CustomGetPin
()
->
CustomGetSample
(
&
p_s
ys
->
sample
)
==
S_OK
)
/*
Get new sample/frame from next stream
*/
//if( p_sream->sample.p_sample ) p_stream->sample.p_sample->Release();
p_sys
->
i_current_stream
=
(
p_sys
->
i_current_stream
+
1
)
%
p_sys
->
streams
.
siz
e
();
p_stream
=
&
p_sys
->
streams
[
p_sys
->
i_current_stream
];
if
(
p_stream
->
p_capture_filter
&&
p_stream
->
p_capture_filter
->
CustomGetPin
()
->
CustomGetSample
(
&
p_s
tream
->
sample
)
==
S_OK
)
{
p_sys
->
i_data_pos
=
0
;
p_sys
->
i_data_size
=
p_sys
->
sample
.
p_sample
->
GetActualDataLength
();
p_sys
->
sample
.
p_sample
->
GetPointer
(
&
p_sys
->
p_data
);
p_stream
->
i_data_pos
=
0
;
p_stream
->
i_data_size
=
p_stream
->
sample
.
p_sample
->
GetActualDataLength
();
p_stream
->
sample
.
p_sample
->
GetPointer
(
&
p_stream
->
p_data
);
REFERENCE_TIME
i_pts
,
i_end_date
;
HRESULT
hr
=
p_sys
->
sample
.
p_sample
->
GetTime
(
&
i_pts
,
&
i_end_date
);
HRESULT
hr
=
p_stream
->
sample
.
p_sample
->
GetTime
(
&
i_pts
,
&
i_end_date
);
if
(
hr
!=
VFW_S_NO_STOP_TIME
&&
hr
!=
S_OK
)
i_pts
=
0
;
if
(
!
i_pts
)
{
/* Use our data timestamp */
i_pts
=
p_s
ys
->
sample
.
i_timestamp
;
i_pts
=
p_s
tream
->
sample
.
i_timestamp
;
}
#if 0
msg_Dbg( p_input, "Read() PTS: "I64Fd, i_pts );
#endif
/*
c
reate pseudo header */
/*
C
reate pseudo header */
p_sys
->
i_header_size
=
16
;
p_sys
->
i_header_pos
=
0
;
SetDWBE
(
&
p_sys
->
p_header
[
0
],
0
/*i_stream*/
);
SetDWBE
(
&
p_sys
->
p_header
[
4
],
p_s
ys
->
i_data_size
);
SetDWBE
(
&
p_sys
->
p_header
[
0
],
p_sys
->
i_current_stream
);
SetDWBE
(
&
p_sys
->
p_header
[
4
],
p_s
tream
->
i_data_size
);
SetQWBE
(
&
p_sys
->
p_header
[
8
],
i_pts
*
9
/
1000
);
}
else
msleep
(
10000
);
...
...
@@ -634,17 +696,17 @@ static int DemuxOpen( vlc_object_t *p_this )
p_input
->
i_bufsize
=
INPUT_DEFAULT_BUFSIZE
;
}
/* a little test to see if it's a
v4l
stream */
/* a little test to see if it's a
dshow
stream */
if
(
input_Peek
(
p_input
,
&
p_peek
,
8
)
<
8
)
{
msg_Warn
(
p_input
,
"
v4l
plugin discarded (cannot peek)"
);
msg_Warn
(
p_input
,
"
dshow
plugin discarded (cannot peek)"
);
return
(
VLC_EGENERIC
);
}
if
(
strcmp
(
(
const
char
*
)
p_peek
,
".dsh"
)
||
GetDWBE
(
&
p_peek
[
4
]
)
<=
0
)
{
msg_Warn
(
p_input
,
"
v4l
plugin discarded (not a valid stream)"
);
msg_Warn
(
p_input
,
"
dshow
plugin discarded (not a valid stream)"
);
return
VLC_EGENERIC
;
}
...
...
@@ -670,7 +732,7 @@ static int DemuxOpen( vlc_object_t *p_this )
if
(
input_Peek
(
p_input
,
&
p_peek
,
8
+
20
*
i_streams
)
<
8
+
20
*
i_streams
)
{
msg_Err
(
p_input
,
"
v4l
plugin discarded (cannot peek)"
);
msg_Err
(
p_input
,
"
dshow
plugin discarded (cannot peek)"
);
return
(
VLC_EGENERIC
);
}
p_peek
+=
8
;
...
...
modules/access/dshow/filter.cpp
View file @
6ee0c084
...
...
@@ -2,7 +2,7 @@
* filter.c : DirectShow access module for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: filter.cpp,v 1.
1 2003/08/24 11:17:39
gbazin Exp $
* $Id: filter.cpp,v 1.
2 2003/08/25 21:45:04
gbazin Exp $
*
* Author: Gildas Bazin <gbazin@netcourrier.com>
*
...
...
@@ -57,6 +57,7 @@
*****************************************************************************/
const
GUID
CLSID_SystemDeviceEnum
=
{
0x62be5d10
,
0x60eb
,
0x11d0
,
{
0xbd
,
0x3b
,
0x00
,
0xa0
,
0xc9
,
0x11
,
0xce
,
0x86
}};
const
GUID
CLSID_VideoInputDeviceCategory
=
{
0x860BB310
,
0x5D01
,
0x11d0
,{
0xBD
,
0x3B
,
0x00
,
0xA0
,
0xC9
,
0x11
,
0xCE
,
0x86
}};
const
GUID
CLSID_AudioInputDeviceCategory
=
{
0x33d9a762
,
0x90c8
,
0x11d0
,
{
0xbd
,
0x43
,
0x00
,
0xa0
,
0xc9
,
0x11
,
0xce
,
0x86
}};
const
GUID
IID_IPropertyBag
=
{
0x55272A00
,
0x42CB
,
0x11CE
,
{
0x81
,
0x35
,
0x00
,
0xAA
,
0x00
,
0x4B
,
0xB8
,
0x51
}};
const
GUID
IID_ICreateDevEnum
=
{
0x29840822
,
0x5b84
,
0x11d0
,
{
0xbd
,
0x3b
,
0x00
,
0xa0
,
0xc9
,
0x11
,
0xce
,
0x86
}};
const
GUID
IID_IFilterGraph
=
{
0x56a8689f
,
0x0ad4
,
0x11ce
,
{
0xb0
,
0x3a
,
0x00
,
0x20
,
0xaf
,
0x0b
,
0xa7
,
0x70
}};
...
...
@@ -94,6 +95,10 @@ const GUID MEDIASUBTYPE_UYVY = {0x59565955, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0
const
GUID
MEDIASUBTYPE_Y211
=
{
0x31313259
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
const
GUID
MEDIASUBTYPE_YV12
=
{
0x32315659
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
const
GUID
MEDIATYPE_Audio
=
{
0x73647561
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
const
GUID
FORMAT_WaveFormatEx
=
{
0x05589f81
,
0xc356
,
0x11ce
,
{
0xbf
,
0x01
,
0x00
,
0xaa
,
0x00
,
0x55
,
0x59
,
0x5a
}};
const
GUID
MEDIASUBTYPE_PCM
=
{
0x00000001
,
0x0000
,
0x0010
,
{
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
}};
void
WINAPI
FreeMediaType
(
AM_MEDIA_TYPE
&
mt
)
{
if
(
mt
.
cbFormat
!=
0
)
...
...
@@ -376,7 +381,7 @@ STDMETHODIMP CapturePin::GetAllocatorRequirements( ALLOCATOR_PROPERTIES *pProps
STDMETHODIMP
CapturePin
::
Receive
(
IMediaSample
*
pSample
)
{
#ifdef DEBUG_DSHOW
msg_Dbg
(
p_input
,
"CapturePin::Receive"
);
//
msg_Dbg( p_input, "CapturePin::Receive" );
#endif
//pSample->AddRef();
...
...
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