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
29920e21
Commit
29920e21
authored
Nov 24, 2003
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* dshow: ported to es_out_* and stream_*. Not tested (sorry).
parent
df0c60d6
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
125 additions
and
170 deletions
+125
-170
modules/access/dshow/dshow.cpp
modules/access/dshow/dshow.cpp
+125
-170
No files found.
modules/access/dshow/dshow.cpp
View file @
29920e21
...
...
@@ -2,7 +2,7 @@
* dshow.cpp : DirectShow access module for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: dshow.cpp,v 1.1
4 2003/11/24 00:39:01
fenrir Exp $
* $Id: dshow.cpp,v 1.1
5 2003/11/24 19:30:54
fenrir Exp $
*
* Author: Gildas Bazin <gbazin@netcourrier.com>
*
...
...
@@ -34,34 +34,6 @@
#include "filter.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
AccessOpen
(
vlc_object_t
*
);
static
void
AccessClose
(
vlc_object_t
*
);
static
ssize_t
Read
(
input_thread_t
*
,
byte_t
*
,
size_t
);
static
ssize_t
ReadDV
(
input_thread_t
*
,
byte_t
*
,
size_t
);
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
,
vlc_bool_t
);
static
IBaseFilter
*
FindCaptureDevice
(
vlc_object_t
*
,
string
*
,
list
<
string
>
*
,
vlc_bool_t
);
static
AM_MEDIA_TYPE
EnumDeviceCaps
(
vlc_object_t
*
,
IBaseFilter
*
,
int
,
int
,
int
,
int
,
int
,
int
);
static
bool
ConnectFilters
(
IFilterGraph
*
,
IBaseFilter
*
,
IPin
*
);
static
int
FindDevicesCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
#if 0
/* Debug only, use this to find out GUIDs */
unsigned char p_st[];
UuidToString( (IID *)&IID_IAMBufferNegotiation, &p_st );
msg_Err( p_input, "BufferNegotiation: %s" , p_st );
#endif
/*****************************************************************************
* Module descriptor
*****************************************************************************/
...
...
@@ -94,6 +66,12 @@ static char *ppsz_adev_text[] = { N_("Default"), N_("None") };
"Force the DirectShow video input to use a specific chroma format " \
"(eg. I420 (default), RV24, etc...)")
static
int
AccessOpen
(
vlc_object_t
*
);
static
void
AccessClose
(
vlc_object_t
*
);
static
int
DemuxOpen
(
vlc_object_t
*
);
static
void
DemuxClose
(
vlc_object_t
*
);
vlc_module_begin
();
set_description
(
_
(
"DirectShow input"
)
);
add_category_hint
(
N_
(
"dshow"
),
NULL
,
VLC_TRUE
);
...
...
@@ -122,9 +100,28 @@ vlc_module_begin();
vlc_module_end
();
/****************************************************************************
* I. Access Part
****************************************************************************/
/*****************************************************************************
* Access: local prototypes
*****************************************************************************/
static
ssize_t
Read
(
input_thread_t
*
,
byte_t
*
,
size_t
);
static
ssize_t
ReadDV
(
input_thread_t
*
,
byte_t
*
,
size_t
);
static
int
OpenDevice
(
input_thread_t
*
,
string
,
vlc_bool_t
);
static
IBaseFilter
*
FindCaptureDevice
(
vlc_object_t
*
,
string
*
,
list
<
string
>
*
,
vlc_bool_t
);
static
AM_MEDIA_TYPE
EnumDeviceCaps
(
vlc_object_t
*
,
IBaseFilter
*
,
int
,
int
,
int
,
int
,
int
,
int
);
static
bool
ConnectFilters
(
IFilterGraph
*
,
IBaseFilter
*
,
IPin
*
);
static
int
FindDevicesCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
#if 0
/* Debug only, use this to find out GUIDs */
unsigned char p_st[];
UuidToString( (IID *)&IID_IAMBufferNegotiation, &p_st );
msg_Err( p_input, "BufferNegotiation: %s" , p_st );
#endif
/*
* header:
...
...
@@ -1134,223 +1131,181 @@ static ssize_t ReadDV( input_thread_t * p_input, byte_t * p_buffer,
return
0
;
/* never reached */
}
/*****************************************************************************
* Demux: local prototypes
*****************************************************************************/
struct
demux_sys_t
{
int
i_es
;
es_out_id_t
**
es
;
};
static
int
Demux
(
input_thread_t
*
);
/****************************************************************************
*
I. Demux Part
*
DemuxOpen:
****************************************************************************/
static
int
DemuxOpen
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
demux_sys_t
*
p_sys
;
uint8_t
*
p_peek
;
int
i_
stream
s
;
int
i_
e
s
;
int
i
;
data_packet_t
*
p_pk
;
/* a little test to see if it's a dshow stream */
if
(
input_Peek
(
p_input
,
&
p_peek
,
8
)
<
8
)
if
(
stream_Peek
(
p_input
->
s
,
&
p_peek
,
8
)
<
8
)
{
msg_Warn
(
p_input
,
"dshow plugin discarded (cannot peek)"
);
return
VLC_EGENERIC
;
}
if
(
str
cmp
(
(
const
char
*
)
p_peek
,
".dsh"
)
||
GetDWBE
(
&
p_peek
[
4
]
)
<=
0
)
if
(
str
ncmp
(
p_peek
,
".dsh"
,
4
)
||
(
i_es
=
GetDWBE
(
&
p_peek
[
4
]
)
)
<=
0
)
{
msg_Warn
(
p_input
,
"dshow plugin discarded (not a valid stream)"
);
return
VLC_EGENERIC
;
}
/* create one program */
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
if
(
input_InitStream
(
p_input
,
0
)
==
-
1
)
{
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
msg_Err
(
p_input
,
"cannot init stream"
);
return
VLC_EGENERIC
;
return
(
VLC_EGENERIC
)
;
}
if
(
input_AddProgram
(
p_input
,
0
,
0
)
==
NULL
)
{
p_input
->
stream
.
i_mux_rate
=
0
/
50
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
msg_Err
(
p_input
,
"cannot add program"
);
return
VLC_EGENERIC
;
}
p_input
->
stream
.
p_selected_program
=
p_input
->
stream
.
pp_programs
[
0
];
p_input
->
stream
.
i_mux_rate
=
0
;
p_input
->
pf_demux
=
Demux
;
p_input
->
pf_demux_control
=
demux_vaControlDefault
;
p_input
->
p_demux_data
=
p_sys
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_sys
->
i_es
=
0
;
p_sys
->
es
=
NULL
;
i_streams
=
GetDWBE
(
&
p_peek
[
4
]
);
if
(
input_Peek
(
p_input
,
&
p_peek
,
8
+
20
*
i_streams
)
<
8
+
20
*
i_streams
)
if
(
stream_Peek
(
p_input
->
s
,
&
p_peek
,
8
+
20
*
i_es
)
<
8
+
20
*
i_es
)
{
msg_Err
(
p_input
,
"dshow plugin discarded (cannot peek)"
);
return
VLC_EGENERIC
;
}
p_peek
+=
8
;
for
(
i
=
0
;
i
<
i_
stream
s
;
i
++
)
for
(
i
=
0
;
i
<
i_
e
s
;
i
++
)
{
es_
descriptor_t
*
p_es
;
es_
format_t
fmt
;
if
(
!
strncmp
(
(
const
char
*
)
p_peek
,
"auds"
,
4
)
)
if
(
!
strncmp
(
p_peek
,
"auds"
,
4
)
)
{
#define wf ((WAVEFORMATEX*)p_es->p_waveformatex)
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
pp_programs
[
0
],
i
+
1
,
AUDIO_ES
,
NULL
,
0
);
p_es
->
i_stream_id
=
i
+
1
;
p_es
->
i_fourcc
=
VLC_FOURCC
(
p_peek
[
4
],
p_peek
[
5
],
p_peek
[
6
],
p_peek
[
7
]
);
es_format_Init
(
&
fmt
,
AUDIO_ES
,
VLC_FOURCC
(
p_peek
[
4
],
p_peek
[
5
],
p_peek
[
6
],
p_peek
[
7
]
)
);
p_es
->
p_waveformatex
=
malloc
(
sizeof
(
WAVEFORMATEX
)
);
fmt
.
audio
.
i_channels
=
GetDWBE
(
&
p_peek
[
8
]
);
fmt
.
audio
.
i_rate
=
GetDWBE
(
&
p_peek
[
12
]
);
fmt
.
audio
.
i_bitspersample
=
GetDWBE
(
&
p_peek
[
16
]
);
fmt
.
audio
.
i_blockalign
=
fmt
.
audio
.
i_channels
*
fmt
.
audio
.
i_bitspersample
/
8
;
fmt
.
i_bitrate
=
fmt
.
audio
.
i_channels
*
fmt
.
audio
.
i_rate
*
fmt
.
audio
.
i_bitspersample
;
wf
->
wFormatTag
=
0
;
//WAVE_FORMAT_UNKNOWN;
wf
->
nChannels
=
GetDWBE
(
&
p_peek
[
8
]
);
wf
->
nSamplesPerSec
=
GetDWBE
(
&
p_peek
[
12
]
);
wf
->
wBitsPerSample
=
GetDWBE
(
&
p_peek
[
16
]
);
wf
->
nBlockAlign
=
wf
->
wBitsPerSample
*
wf
->
nChannels
/
8
;
wf
->
nAvgBytesPerSec
=
wf
->
nBlockAlign
*
wf
->
nSamplesPerSec
;
wf
->
cbSize
=
0
;
msg_Dbg
(
p_input
,
"new audio es %d channels %dHz"
,
fmt
.
audio
.
i_channels
,
fmt
.
audio
.
i_rate
);
msg_Dbg
(
p_input
,
"added new audio es %d channels %dHz"
,
wf
->
nChannels
,
wf
->
nSamplesPerSec
);
input_SelectES
(
p_input
,
p_es
);
#undef wf
TAB_APPEND
(
p_sys
->
i_es
,
p_sys
->
es
,
es_out_Add
(
p_input
->
p_es_out
,
&
fmt
)
);
}
else
if
(
!
strncmp
(
(
const
char
*
)
p_peek
,
"vids"
,
4
)
)
else
if
(
!
strncmp
(
p_peek
,
"vids"
,
4
)
)
{
#define bih ((BITMAPINFOHEADER*)p_es->p_bitmapinfoheader)
p_es
=
input_AddES
(
p_input
,
p_input
->
stream
.
pp_programs
[
0
],
i
+
1
,
VIDEO_ES
,
NULL
,
0
);
p_es
->
i_stream_id
=
i
+
1
;
p_es
->
i_fourcc
=
VLC_FOURCC
(
p_peek
[
4
],
p_peek
[
5
],
p_peek
[
6
],
p_peek
[
7
]
);
p_es
->
p_bitmapinfoheader
=
malloc
(
sizeof
(
BITMAPINFOHEADER
)
);
bih
->
biSize
=
sizeof
(
BITMAPINFOHEADER
);
bih
->
biWidth
=
GetDWBE
(
&
p_peek
[
8
]
);
bih
->
biHeight
=
GetDWBE
(
&
p_peek
[
12
]
);
bih
->
biPlanes
=
0
;
bih
->
biBitCount
=
0
;
bih
->
biCompression
=
0
;
bih
->
biSizeImage
=
0
;
bih
->
biXPelsPerMeter
=
0
;
bih
->
biYPelsPerMeter
=
0
;
bih
->
biClrUsed
=
0
;
bih
->
biClrImportant
=
0
;
es_format_Init
(
&
fmt
,
AUDIO_ES
,
VLC_FOURCC
(
p_peek
[
4
],
p_peek
[
5
],
p_peek
[
6
],
p_peek
[
7
]
)
);
fmt
.
video
.
i_width
=
GetDWBE
(
&
p_peek
[
8
]
);
fmt
.
video
.
i_height
=
GetDWBE
(
&
p_peek
[
12
]
);
msg_Dbg
(
p_input
,
"added new video es %4.4s %dx%d"
,
(
char
*
)
&
p_es
->
i_fourcc
,
bih
->
biWidth
,
bih
->
biHeight
);
input_SelectES
(
p_input
,
p_es
);
#undef bih
(
char
*
)
&
fmt
.
i_codec
,
fmt
.
video
.
i_width
,
fmt
.
video
.
i_height
);
TAB_APPEND
(
p_sys
->
i_es
,
p_sys
->
es
,
es_out_Add
(
p_input
->
p_es_out
,
&
fmt
)
);
}
p_peek
+=
20
;
}
p_input
->
stream
.
p_selected_program
->
b_is_ok
=
1
;
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
/* Skip header */
stream_Read
(
p_input
->
s
,
NULL
,
8
+
20
*
i_es
);
if
(
input_SplitBuffer
(
p_input
,
&
p_pk
,
8
+
i_streams
*
20
)
>
0
)
{
input_DeletePacket
(
p_input
->
p_method_data
,
p_pk
);
}
p_input
->
pf_demux
=
Demux
;
p_input
->
pf_demux_control
=
demux_vaControlDefault
;
return
VLC_SUCCESS
;
}
/****************************************************************************
* DemuxClose:
****************************************************************************/
static
void
DemuxClose
(
vlc_object_t
*
p_this
)
{
return
;
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_input
->
p_demux_data
;
if
(
p_sys
->
i_es
>
0
)
{
free
(
p_sys
->
es
);
}
free
(
p_sys
);
}
/****************************************************************************
* Demux:
****************************************************************************/
static
int
Demux
(
input_thread_t
*
p_input
)
{
es_descriptor_t
*
p_es
;
pes_packet_t
*
p_pes
;
demux_sys_t
*
p_sys
=
p_input
->
p_demux_data
;
block_t
*
p_block
;
int
i_
stream
;
int
i_
es
;
int
i_size
;
uint8_t
*
p_peek
;
mtime_t
i_p
cr
;
mtime_t
i_p
ts
;
if
(
input_Peek
(
p_input
,
&
p_peek
,
16
)
<
16
)
if
(
stream_Peek
(
p_input
->
s
,
&
p_peek
,
16
)
<
16
)
{
msg_Warn
(
p_input
,
"cannot peek (EOF ?)"
);
return
0
;
}
i_stream
=
GetDWBE
(
&
p_peek
[
0
]
);
i_size
=
GetDWBE
(
&
p_peek
[
4
]
);
i_pcr
=
GetQWBE
(
&
p_peek
[
8
]
);
p_es
=
p_input
->
stream
.
p_selected_program
->
pp_es
[
i_stream
];
if
(
!
p_es
)
i_es
=
GetDWBE
(
&
p_peek
[
0
]
);
if
(
i_es
<
0
||
i_es
>=
p_sys
->
i_es
)
{
msg_Err
(
p_input
,
"cannot find ES"
);
return
-
1
;
}
p_pes
=
input_NewPES
(
p_input
->
p_method_data
);
if
(
p_pes
==
NULL
)
{
msg_Warn
(
p_input
,
"cannot allocate PES"
);
msleep
(
1000
);
return
1
;
}
i_size
+=
16
;
while
(
i_size
>
0
)
{
data_packet_t
*
p_data
;
int
i_read
;
i_size
=
GetDWBE
(
&
p_peek
[
4
]
);
i_pts
=
GetQWBE
(
&
p_peek
[
8
]
);
if
(
(
i_read
=
input_SplitBuffer
(
p_input
,
&
p_data
,
i_size
)
)
<=
0
)
if
(
(
p_block
=
stream_Block
(
p_input
->
s
,
16
+
i_size
)
)
==
NULL
)
{
input_DeletePES
(
p_input
->
p_method_data
,
p_pes
);
msg_Warn
(
p_input
,
"cannot read data"
);
return
0
;
}
if
(
!
p_pes
->
p_first
)
{
p_pes
->
p_first
=
p_data
;
p_pes
->
i_nb_data
=
1
;
p_pes
->
i_pes_size
=
i_read
;
}
else
{
p_pes
->
p_last
->
p_next
=
p_data
;
p_pes
->
i_nb_data
++
;
p_pes
->
i_pes_size
+=
i_read
;
}
p_pes
->
p_last
=
p_data
;
i_size
-=
i_read
;
}
p_
pes
->
p_first
->
p_payload_start
+=
16
;
p_
pes
->
i_pes_size
-=
16
;
p_
block
->
p_buffer
+=
16
;
p_
block
->
i_buffer
-=
16
;
if
(
p_es
&&
p_es
->
p_dec
)
{
/* Call the pace control. */
input_ClockManageRef
(
p_input
,
p_input
->
stream
.
p_selected_program
,
i_pcr
);
i_pts
);
p_pes
->
i_pts
=
p_pes
->
i_dts
=
i_pcr
<=
0
?
0
:
input_ClockGetTS
(
p_input
,
p_input
->
stream
.
p_selected_program
,
i_pcr
);
p_block
->
i_dts
=
p_block
->
i_pts
=
i_pcr
<=
0
?
0
:
input_ClockGetTS
(
p_input
,
p_input
->
stream
.
p_selected_program
,
i_pts
);
input_DecodePES
(
p_es
->
p_dec
,
p_pes
);
}
else
{
input_DeletePES
(
p_input
->
p_method_data
,
p_pes
);
}
es_out_Send
(
p_input
->
p_es_out
,
p_sys
->
es
[
i_es
],
p_block
);
return
1
;
}
/*****************************************************************************
* config variable callback
*****************************************************************************/
...
...
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