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
dd6a1ec3
Commit
dd6a1ec3
authored
Dec 11, 2012
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
decklink access: cosmetics
parent
637db5ea
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
277 additions
and
279 deletions
+277
-279
modules/access/decklink.cpp
modules/access/decklink.cpp
+277
-279
No files found.
modules/access/decklink.cpp
View file @
dd6a1ec3
...
...
@@ -36,42 +36,42 @@
#include <DeckLinkAPI.h>
#include <DeckLinkAPIDispatch.cpp>
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
#define CARD_INDEX_TEXT N_("Input card to use")
#define CARD_INDEX_LONGTEXT N_( \
"DeckLink capture card to use, if multiple exist. " \
"The cards are numbered from 0."
)
"The cards are numbered from 0.")
#define MODE_TEXT N_("Desired input video mode")
#define MODE_LONGTEXT N_( \
"Desired input video mode for DeckLink captures. " \
"This value should be a FOURCC code in textual " \
"form, e.g. \"ntsc\"."
)
"form, e.g. \"ntsc\".")
#define AUDIO_CONNECTION_TEXT N_("Audio connection")
#define AUDIO_CONNECTION_LONGTEXT N_( \
"Audio connection to use for DeckLink captures. " \
"Valid choices: embedded, aesebu, analog. " \
"Leave blank for card default."
)
"Leave blank for card default.")
#define RATE_TEXT N_("Audio sampling rate in Hz")
#define RATE_LONGTEXT N_( \
"Audio sampling rate (in hertz) for DeckLink captures. " \
"0 disables audio input."
)
"0 disables audio input.")
#define CHANNELS_TEXT N_("Number of audio channels")
#define CHANNELS_LONGTEXT N_( \
"Number of input audio channels for DeckLink captures. " \
"Must be 2, 8 or 16. 0 disables audio input."
)
"Must be 2, 8 or 16. 0 disables audio input.")
#define VIDEO_CONNECTION_TEXT N_("Video connection")
#define VIDEO_CONNECTION_LONGTEXT N_( \
"Video connection to use for DeckLink captures. " \
"Valid choices: sdi, hdmi, opticalsdi, component, " \
"composite, svideo. " \
"Leave blank for card default."
)
"Leave blank for card default.")
static
const
char
*
const
ppsz_videoconns
[]
=
{
"sdi"
,
"hdmi"
,
"opticalsdi"
,
"component"
,
"composite"
,
"svideo"
...
...
@@ -88,87 +88,87 @@ static const char *const ppsz_audioconns_text[] = {
};
#define ASPECT_RATIO_TEXT N_("Aspect ratio")
#define ASPECT_RATIO_LONGTEXT N_(
\
"Aspect ratio (4:3, 16:9). Default assumes square pixels."
)
#define ASPECT_RATIO_LONGTEXT N_(\
"Aspect ratio (4:3, 16:9). Default assumes square pixels.")
vlc_module_begin
()
set_shortname
(
N_
(
"DeckLink"
)
)
set_description
(
N_
(
"Blackmagic DeckLink SDI input"
)
)
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_ACCESS
)
add_integer
(
"decklink-card-index"
,
0
,
CARD_INDEX_TEXT
,
CARD_INDEX_LONGTEXT
,
true
)
add_string
(
"decklink-mode"
,
"pal "
,
MODE_TEXT
,
MODE_LONGTEXT
,
true
)
add_string
(
"decklink-audio-connection"
,
0
,
AUDIO_CONNECTION_TEXT
,
AUDIO_CONNECTION_LONGTEXT
,
true
)
change_string_list
(
ppsz_audioconns
,
ppsz_audioconns_text
)
add_integer
(
"decklink-audio-rate"
,
48000
,
RATE_TEXT
,
RATE_LONGTEXT
,
true
)
add_integer
(
"decklink-audio-channels"
,
2
,
CHANNELS_TEXT
,
CHANNELS_LONGTEXT
,
true
)
add_string
(
"decklink-video-connection"
,
0
,
VIDEO_CONNECTION_TEXT
,
VIDEO_CONNECTION_LONGTEXT
,
true
)
change_string_list
(
ppsz_videoconns
,
ppsz_videoconns_text
)
add_string
(
"decklink-aspect-ratio"
,
NULL
,
ASPECT_RATIO_TEXT
,
ASPECT_RATIO_LONGTEXT
,
true
)
add_shortcut
(
"decklink"
)
set_capability
(
"access_demux"
,
10
)
set_callbacks
(
Open
,
Close
)
set_shortname
(
N_
(
"DeckLink"
)
)
set_description
(
N_
(
"Blackmagic DeckLink SDI input"
)
)
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_ACCESS
)
add_integer
(
"decklink-card-index"
,
0
,
CARD_INDEX_TEXT
,
CARD_INDEX_LONGTEXT
,
true
)
add_string
(
"decklink-mode"
,
"pal "
,
MODE_TEXT
,
MODE_LONGTEXT
,
true
)
add_string
(
"decklink-audio-connection"
,
0
,
AUDIO_CONNECTION_TEXT
,
AUDIO_CONNECTION_LONGTEXT
,
true
)
change_string_list
(
ppsz_audioconns
,
ppsz_audioconns_text
)
add_integer
(
"decklink-audio-rate"
,
48000
,
RATE_TEXT
,
RATE_LONGTEXT
,
true
)
add_integer
(
"decklink-audio-channels"
,
2
,
CHANNELS_TEXT
,
CHANNELS_LONGTEXT
,
true
)
add_string
(
"decklink-video-connection"
,
0
,
VIDEO_CONNECTION_TEXT
,
VIDEO_CONNECTION_LONGTEXT
,
true
)
change_string_list
(
ppsz_videoconns
,
ppsz_videoconns_text
)
add_string
(
"decklink-aspect-ratio"
,
NULL
,
ASPECT_RATIO_TEXT
,
ASPECT_RATIO_LONGTEXT
,
true
)
add_shortcut
(
"decklink"
)
set_capability
(
"access_demux"
,
10
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
static
int
Control
(
demux_t
*
,
int
,
va_list
);
static
int
Control
(
demux_t
*
,
int
,
va_list
);
class
DeckLinkCaptureDelegate
;
struct
demux_sys_t
{
IDeckLink
*
p_
card
;
IDeckLinkInput
*
p_
input
;
DeckLinkCaptureDelegate
*
p_
delegate
;
IDeckLink
*
card
;
IDeckLinkInput
*
input
;
DeckLinkCaptureDelegate
*
delegate
;
/* We need to hold onto the IDeckLinkConfiguration object, or our settings will not apply.
See section 2.4.15 of the Blackmagic Decklink SDK documentation. */
IDeckLinkConfiguration
*
p_
config
;
IDeckLinkConfiguration
*
config
;
es_out_id_t
*
p_
video_es
;
es_out_id_t
*
p_
audio_es
;
es_out_id_t
*
video_es
;
es_out_id_t
*
audio_es
;
vlc_mutex_t
pts_lock
;
int
i_
last_pts
;
/* protected by <pts_lock> */
int
last_pts
;
/* protected by <pts_lock> */
uint32_t
i_
dominance_flags
;
int
i_
channels
;
uint32_t
dominance_flags
;
int
channels
;
};
class
DeckLinkCaptureDelegate
:
public
IDeckLinkInputCallback
{
public:
DeckLinkCaptureDelegate
(
demux_t
*
p_demux
)
:
p_demux_
(
p_
demux
)
DeckLinkCaptureDelegate
(
demux_t
*
demux
)
:
demux_
(
demux
)
{
vlc_atomic_set
(
&
m_ref_
,
1
);
vlc_atomic_set
(
&
m_ref_
,
1
);
}
virtual
HRESULT
STDMETHODCALLTYPE
QueryInterface
(
REFIID
iid
,
LPVOID
*
ppv
)
{
return
E_NOINTERFACE
;
}
virtual
ULONG
STDMETHODCALLTYPE
AddRef
(
void
)
{
return
vlc_atomic_inc
(
&
m_ref_
);
return
vlc_atomic_inc
(
&
m_ref_
);
}
virtual
ULONG
STDMETHODCALLTYPE
Release
(
void
)
{
uintptr_t
new_ref
=
vlc_atomic_dec
(
&
m_ref_
);
if
(
new_ref
==
0
)
uintptr_t
new_ref
=
vlc_atomic_dec
(
&
m_ref_
);
if
(
new_ref
==
0
)
delete
this
;
return
new_ref
;
}
virtual
HRESULT
STDMETHODCALLTYPE
VideoInputFormatChanged
(
BMDVideoInputFormatChangedEvents
,
IDeckLinkDisplayMode
*
,
BMDDetectedVideoInputFormatFlags
)
{
msg_Dbg
(
p_demux_
,
"Video input format changed"
);
msg_Dbg
(
demux_
,
"Video input format changed"
);
return
S_OK
;
}
...
...
@@ -176,249 +176,248 @@ public:
private:
vlc_atomic_t
m_ref_
;
demux_t
*
p_
demux_
;
demux_t
*
demux_
;
};
HRESULT
DeckLinkCaptureDelegate
::
VideoInputFrameArrived
(
IDeckLinkVideoInputFrame
*
videoFrame
,
IDeckLinkAudioInputPacket
*
audioFrame
)
{
demux_sys_t
*
p_sys
=
p_
demux_
->
p_sys
;
block_t
*
p_
video_frame
=
NULL
;
block_t
*
p_
audio_frame
=
NULL
;
demux_sys_t
*
sys
=
demux_
->
p_sys
;
block_t
*
video_frame
=
NULL
;
block_t
*
audio_frame
=
NULL
;
if
(
videoFrame
)
if
(
videoFrame
)
{
if
(
videoFrame
->
GetFlags
()
&
bmdFrameHasNoInputSource
)
if
(
videoFrame
->
GetFlags
()
&
bmdFrameHasNoInputSource
)
{
msg_Warn
(
p_demux_
,
"No input signal detected"
);
msg_Warn
(
demux_
,
"No input signal detected"
);
return
S_OK
;
}
const
int
i_
width
=
videoFrame
->
GetWidth
();
const
int
i_
height
=
videoFrame
->
GetHeight
();
const
int
i_
stride
=
videoFrame
->
GetRowBytes
();
const
int
i_
bpp
=
2
;
const
int
width
=
videoFrame
->
GetWidth
();
const
int
height
=
videoFrame
->
GetHeight
();
const
int
stride
=
videoFrame
->
GetRowBytes
();
const
int
bpp
=
2
;
p_video_frame
=
block_New
(
p_demux_
,
i_width
*
i_height
*
i_bpp
);
if
(
!
p_video_frame
)
video_frame
=
block_New
(
demux_
,
width
*
height
*
bpp
);
if
(
!
video_frame
)
{
msg_Err
(
p_demux_
,
"Could not allocate memory for video frame"
);
return
S_OK
;
msg_Err
(
demux_
,
"Could not allocate memory for video frame"
);
}
void
*
frame_bytes
;
videoFrame
->
GetBytes
(
&
frame_bytes
);
for
(
int
y
=
0
;
y
<
i_height
;
++
y
)
videoFrame
->
GetBytes
(
&
frame_bytes
);
for
(
int
y
=
0
;
y
<
height
;
++
y
)
{
const
uint8_t
*
src
=
(
const
uint8_t
*
)
frame_bytes
+
i_
stride
*
y
;
uint8_t
*
dst
=
p_video_frame
->
p_buffer
+
i_width
*
i_
bpp
*
y
;
memcpy
(
dst
,
src
,
i_width
*
i_bpp
);
const
uint8_t
*
src
=
(
const
uint8_t
*
)
frame_bytes
+
stride
*
y
;
uint8_t
*
dst
=
video_frame
->
p_buffer
+
width
*
bpp
*
y
;
memcpy
(
dst
,
src
,
width
*
bpp
);
}
BMDTimeValue
stream_time
,
frame_duration
;
videoFrame
->
GetStreamTime
(
&
stream_time
,
&
frame_duration
,
CLOCK_FREQ
);
p_video_frame
->
i_flags
=
BLOCK_FLAG_TYPE_I
|
p_sys
->
i_
dominance_flags
;
p_video_frame
->
i_pts
=
p_
video_frame
->
i_dts
=
VLC_TS_0
+
stream_time
;
videoFrame
->
GetStreamTime
(
&
stream_time
,
&
frame_duration
,
CLOCK_FREQ
);
video_frame
->
i_flags
=
BLOCK_FLAG_TYPE_I
|
sys
->
dominance_flags
;
video_frame
->
i_pts
=
video_frame
->
i_dts
=
VLC_TS_0
+
stream_time
;
vlc_mutex_lock
(
&
p_sys
->
pts_lock
);
if
(
p_video_frame
->
i_pts
>
p_sys
->
i_last_pts
)
p_sys
->
i_last_pts
=
p_
video_frame
->
i_pts
;
vlc_mutex_unlock
(
&
p_sys
->
pts_lock
);
vlc_mutex_lock
(
&
sys
->
pts_lock
);
if
(
video_frame
->
i_pts
>
sys
->
last_pts
)
sys
->
last_pts
=
video_frame
->
i_pts
;
vlc_mutex_unlock
(
&
sys
->
pts_lock
);
es_out_Control
(
p_demux_
->
out
,
ES_OUT_SET_PCR
,
p_video_frame
->
i_pts
);
es_out_Send
(
p_demux_
->
out
,
p_sys
->
p_video_es
,
p_video_frame
);
es_out_Control
(
demux_
->
out
,
ES_OUT_SET_PCR
,
video_frame
->
i_pts
);
es_out_Send
(
demux_
->
out
,
sys
->
video_es
,
video_frame
);
}
if
(
audioFrame
)
if
(
audioFrame
)
{
const
int
i_bytes
=
audioFrame
->
GetSampleFrameCount
()
*
sizeof
(
int16_t
)
*
p_sys
->
i_
channels
;
const
int
bytes
=
audioFrame
->
GetSampleFrameCount
()
*
sizeof
(
int16_t
)
*
sys
->
channels
;
p_audio_frame
=
block_New
(
p_demux_
,
i_bytes
);
if
(
!
p_audio_frame
)
audio_frame
=
block_New
(
demux_
,
bytes
);
if
(
!
audio_frame
)
{
msg_Err
(
p_demux_
,
"Could not allocate memory for audio frame"
);
if
(
p_video_frame
)
block_Release
(
p_video_frame
);
msg_Err
(
demux_
,
"Could not allocate memory for audio frame"
);
if
(
video_frame
)
block_Release
(
video_frame
);
return
S_OK
;
}
void
*
frame_bytes
;
audioFrame
->
GetBytes
(
&
frame_bytes
);
memcpy
(
p_audio_frame
->
p_buffer
,
frame_bytes
,
i_bytes
);
audioFrame
->
GetBytes
(
&
frame_bytes
);
memcpy
(
audio_frame
->
p_buffer
,
frame_bytes
,
bytes
);
BMDTimeValue
packet_time
;
audioFrame
->
GetPacketTime
(
&
packet_time
,
CLOCK_FREQ
);
p_audio_frame
->
i_pts
=
p_
audio_frame
->
i_dts
=
VLC_TS_0
+
packet_time
;
audioFrame
->
GetPacketTime
(
&
packet_time
,
CLOCK_FREQ
);
audio_frame
->
i_pts
=
audio_frame
->
i_dts
=
VLC_TS_0
+
packet_time
;
vlc_mutex_lock
(
&
p_sys
->
pts_lock
);
if
(
p_audio_frame
->
i_pts
>
p_sys
->
i_last_pts
)
p_sys
->
i_last_pts
=
p_
audio_frame
->
i_pts
;
vlc_mutex_unlock
(
&
p_sys
->
pts_lock
);
if
(
p_audio_frame
->
i_pts
>
p_sys
->
i_last_pts
)
vlc_mutex_lock
(
&
sys
->
pts_lock
);
if
(
audio_frame
->
i_pts
>
sys
->
last_pts
)
sys
->
last_pts
=
audio_frame
->
i_pts
;
vlc_mutex_unlock
(
&
sys
->
pts_lock
);
if
(
audio_frame
->
i_pts
>
sys
->
last_pts
)
es_out_Control
(
p_demux_
->
out
,
ES_OUT_SET_PCR
,
p_audio_frame
->
i_pts
);
es_out_Send
(
p_demux_
->
out
,
p_sys
->
p_audio_es
,
p_audio_frame
);
es_out_Control
(
demux_
->
out
,
ES_OUT_SET_PCR
,
audio_frame
->
i_pts
);
es_out_Send
(
demux_
->
out
,
sys
->
audio_es
,
audio_frame
);
}
return
S_OK
;
}
static
int
Open
(
vlc_object_t
*
p_this
)
static
int
Open
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_
demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_
sys
;
demux_t
*
demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
sys
;
int
ret
=
VLC_EGENERIC
;
char
*
psz_
aspect
;
char
*
psz_
display_mode
=
NULL
;
char
*
psz_
video_connection
=
NULL
;
char
*
psz_
audio_connection
=
NULL
;
char
*
aspect
;
char
*
display_mode
=
NULL
;
char
*
video_connection
=
NULL
;
char
*
audio_connection
=
NULL
;
bool
b_found_mode
;
int
i_
card_index
;
int
i_width
,
i_height
,
i_fps_num
,
i_
fps_den
;
int
i_
rate
;
unsigned
u_aspect_num
,
u_
aspect_den
;
int
card_index
;
int
width
,
height
,
fps_num
,
fps_den
;
int
rate
;
unsigned
aspect_num
,
aspect_den
;
/* Only when selected */
if
(
*
p_demux
->
psz_access
==
'\0'
)
if
(
*
demux
->
psz_access
==
'\0'
)
return
VLC_EGENERIC
;
/* Set up
p_
demux */
p_
demux
->
pf_demux
=
NULL
;
p_
demux
->
pf_control
=
Control
;
p_
demux
->
info
.
i_update
=
0
;
p_
demux
->
info
.
i_title
=
0
;
p_
demux
->
info
.
i_seekpoint
=
0
;
p_demux
->
p_sys
=
p_sys
=
(
demux_sys_t
*
)
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
if
(
!
p_sys
)
/* Set up demux */
demux
->
pf_demux
=
NULL
;
demux
->
pf_control
=
Control
;
demux
->
info
.
i_update
=
0
;
demux
->
info
.
i_title
=
0
;
demux
->
info
.
i_seekpoint
=
0
;
demux
->
p_sys
=
sys
=
(
demux_sys_t
*
)
calloc
(
1
,
sizeof
(
demux_sys_t
)
);
if
(
!
sys
)
return
VLC_ENOMEM
;
vlc_mutex_init
(
&
p_sys
->
pts_lock
);
vlc_mutex_init
(
&
sys
->
pts_lock
);
IDeckLinkDisplayModeIterator
*
p_
display_iterator
=
NULL
;
IDeckLinkDisplayModeIterator
*
display_iterator
=
NULL
;
IDeckLinkIterator
*
decklink_iterator
=
CreateDeckLinkIteratorInstance
();
if
(
!
decklink_iterator
)
if
(
!
decklink_iterator
)
{
msg_Err
(
p_demux
,
"DeckLink drivers not found."
);
msg_Err
(
demux
,
"DeckLink drivers not found."
);
goto
finish
;
}
HRESULT
result
;
i_card_index
=
var_InheritInteger
(
p_demux
,
"decklink-card-index"
);
if
(
i_card_index
<
0
)
card_index
=
var_InheritInteger
(
demux
,
"decklink-card-index"
);
if
(
card_index
<
0
)
{
msg_Err
(
p_demux
,
"Invalid card index %d"
,
i_card_index
);
msg_Err
(
demux
,
"Invalid card index %d"
,
card_index
);
goto
finish
;
}
for
(
int
i
=
0
;
i
<=
i_card_index
;
++
i
)
for
(
int
i
=
0
;
i
<=
card_index
;
++
i
)
{
if
(
p_sys
->
p_card
)
p_sys
->
p_
card
->
Release
();
result
=
decklink_iterator
->
Next
(
&
p_sys
->
p_card
);
if
(
result
!=
S_OK
)
if
(
sys
->
card
)
sys
->
card
->
Release
();
result
=
decklink_iterator
->
Next
(
&
sys
->
card
);
if
(
result
!=
S_OK
)
break
;
}
if
(
result
!=
S_OK
)
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"DeckLink PCI card %d not found"
,
i_card_index
);
msg_Err
(
demux
,
"DeckLink PCI card %d not found"
,
card_index
);
goto
finish
;
}
const
char
*
psz_
model_name
;
result
=
p_sys
->
p_card
->
GetModelName
(
&
psz_model_name
);
const
char
*
model_name
;
result
=
sys
->
card
->
GetModelName
(
&
model_name
);
if
(
result
!=
S_OK
)
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Could not get model name"
);
msg_Err
(
demux
,
"Could not get model name"
);
goto
finish
;
}
msg_Dbg
(
p_demux
,
"Opened DeckLink PCI card %d (%s)"
,
i_card_index
,
psz_model_name
);
msg_Dbg
(
demux
,
"Opened DeckLink PCI card %d (%s)"
,
card_index
,
model_name
);
if
(
p_sys
->
p_card
->
QueryInterface
(
IID_IDeckLinkInput
,
(
void
**
)
&
p_sys
->
p_input
)
!=
S_OK
)
if
(
sys
->
card
->
QueryInterface
(
IID_IDeckLinkInput
,
(
void
**
)
&
sys
->
input
)
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Card has no inputs"
);
msg_Err
(
demux
,
"Card has no inputs"
);
goto
finish
;
}
/* Set up the video and audio sources. */
if
(
p_sys
->
p_card
->
QueryInterface
(
IID_IDeckLinkConfiguration
,
(
void
**
)
&
p_sys
->
p_config
)
!=
S_OK
)
if
(
sys
->
card
->
QueryInterface
(
IID_IDeckLinkConfiguration
,
(
void
**
)
&
sys
->
config
)
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to get configuration interface"
);
msg_Err
(
demux
,
"Failed to get configuration interface"
);
goto
finish
;
}
psz_video_connection
=
var_InheritString
(
p_demux
,
"decklink-video-connection"
);
if
(
psz_video_connection
)
video_connection
=
var_InheritString
(
demux
,
"decklink-video-connection"
);
if
(
video_connection
)
{
BMDVideoConnection
conn
;
if
(
!
strcmp
(
psz_video_connection
,
"sdi"
)
)
if
(
!
strcmp
(
video_connection
,
"sdi"
)
)
conn
=
bmdVideoConnectionSDI
;
else
if
(
!
strcmp
(
psz_video_connection
,
"hdmi"
)
)
else
if
(
!
strcmp
(
video_connection
,
"hdmi"
)
)
conn
=
bmdVideoConnectionHDMI
;
else
if
(
!
strcmp
(
psz_video_connection
,
"opticalsdi"
)
)
else
if
(
!
strcmp
(
video_connection
,
"opticalsdi"
)
)
conn
=
bmdVideoConnectionOpticalSDI
;
else
if
(
!
strcmp
(
psz_video_connection
,
"component"
)
)
else
if
(
!
strcmp
(
video_connection
,
"component"
)
)
conn
=
bmdVideoConnectionComponent
;
else
if
(
!
strcmp
(
psz_video_connection
,
"composite"
)
)
else
if
(
!
strcmp
(
video_connection
,
"composite"
)
)
conn
=
bmdVideoConnectionComposite
;
else
if
(
!
strcmp
(
psz_video_connection
,
"svideo"
)
)
else
if
(
!
strcmp
(
video_connection
,
"svideo"
)
)
conn
=
bmdVideoConnectionSVideo
;
else
{
msg_Err
(
p_
demux
,
"Invalid --decklink-video-connection specified; choose one of "
\
"sdi, hdmi, opticalsdi, component, composite, or svideo."
);
msg_Err
(
demux
,
"Invalid --decklink-video-connection specified; choose one of "
\
"sdi, hdmi, opticalsdi, component, composite, or svideo."
);
goto
finish
;
}
msg_Dbg
(
p_
demux
,
"Setting video input connection to 0x%x"
,
conn
);
result
=
p_sys
->
p_config
->
SetInt
(
bmdDeckLinkConfigVideoInputConnection
,
conn
);
if
(
result
!=
S_OK
)
msg_Dbg
(
demux
,
"Setting video input connection to 0x%x"
,
conn
);
result
=
sys
->
config
->
SetInt
(
bmdDeckLinkConfigVideoInputConnection
,
conn
);
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to set video input connection"
);
msg_Err
(
demux
,
"Failed to set video input connection"
);
goto
finish
;
}
}
psz_audio_connection
=
var_CreateGetNonEmptyString
(
p_demux
,
"decklink-audio-connection"
);
if
(
psz_audio_connection
)
audio_connection
=
var_CreateGetNonEmptyString
(
demux
,
"decklink-audio-connection"
);
if
(
audio_connection
)
{
BMDAudioConnection
conn
;
if
(
!
strcmp
(
psz_audio_connection
,
"embedded"
)
)
if
(
!
strcmp
(
audio_connection
,
"embedded"
)
)
conn
=
bmdAudioConnectionEmbedded
;
else
if
(
!
strcmp
(
psz_audio_connection
,
"aesebu"
)
)
else
if
(
!
strcmp
(
audio_connection
,
"aesebu"
)
)
conn
=
bmdAudioConnectionAESEBU
;
else
if
(
!
strcmp
(
psz_audio_connection
,
"analog"
)
)
else
if
(
!
strcmp
(
audio_connection
,
"analog"
)
)
conn
=
bmdAudioConnectionAnalog
;
else
{
msg_Err
(
p_
demux
,
"Invalid --decklink-audio-connection specified; choose one of "
\
"embedded, aesebu, or analog."
);
msg_Err
(
demux
,
"Invalid --decklink-audio-connection specified; choose one of "
\
"embedded, aesebu, or analog."
);
goto
finish
;
}
msg_Dbg
(
p_
demux
,
"Setting audio input format to 0x%x"
,
conn
);
result
=
p_sys
->
p_config
->
SetInt
(
bmdDeckLinkConfigAudioInputConnection
,
conn
);
if
(
result
!=
S_OK
)
msg_Dbg
(
demux
,
"Setting audio input format to 0x%x"
,
conn
);
result
=
sys
->
config
->
SetInt
(
bmdDeckLinkConfigAudioInputConnection
,
conn
);
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to set audio input connection"
);
msg_Err
(
demux
,
"Failed to set audio input connection"
);
goto
finish
;
}
}
/* Get the list of display modes. */
result
=
p_sys
->
p_input
->
GetDisplayModeIterator
(
&
p_display_iterator
);
if
(
result
!=
S_OK
)
result
=
sys
->
input
->
GetDisplayModeIterator
(
&
display_iterator
);
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to enumerate display modes"
);
msg_Err
(
demux
,
"Failed to enumerate display modes"
);
goto
finish
;
}
psz_display_mode
=
var_CreateGetNonEmptyString
(
p_demux
,
"decklink-mode"
);
if
(
!
psz_display_mode
||
strlen
(
psz_display_mode
)
>
4
)
{
msg_Err
(
p_demux
,
"Missing or invalid --decklink-mode string"
);
display_mode
=
var_CreateGetNonEmptyString
(
demux
,
"decklink-mode"
);
if
(
!
display_mode
||
strlen
(
display_mode
)
>
4
)
{
msg_Err
(
demux
,
"Missing or invalid --decklink-mode string"
);
goto
finish
;
}
...
...
@@ -428,226 +427,225 @@ static int Open( vlc_object_t *p_this )
*/
char
sz_display_mode_padded
[
5
];
strcpy
(
sz_display_mode_padded
,
" "
);
for
(
int
i
=
0
;
i
<
strlen
(
psz_display_mode
);
++
i
)
sz_display_mode_padded
[
i
]
=
psz_
display_mode
[
i
];
for
(
int
i
=
0
;
i
<
strlen
(
display_mode
);
++
i
)
sz_display_mode_padded
[
i
]
=
display_mode
[
i
];
BMDDisplayMode
wanted_mode_id
;
memcpy
(
&
wanted_mode_id
,
&
sz_display_mode_padded
,
sizeof
(
wanted_mode_id
)
);
memcpy
(
&
wanted_mode_id
,
&
sz_display_mode_padded
,
sizeof
(
wanted_mode_id
)
);
b_found_mode
=
false
;
for
(;;)
{
IDeckLinkDisplayMode
*
p_
display_mode
;
result
=
p_display_iterator
->
Next
(
&
p_display_mode
);
if
(
result
!=
S_OK
||
!
p_display_mode
)
IDeckLinkDisplayMode
*
display_mode
;
result
=
display_iterator
->
Next
(
&
display_mode
);
if
(
result
!=
S_OK
||
!
display_mode
)
break
;
char
sz_mode_id_text
[
5
]
=
{
0
};
BMDDisplayMode
mode_id
=
ntohl
(
p_display_mode
->
GetDisplayMode
()
);
memcpy
(
sz_mode_id_text
,
&
mode_id
,
sizeof
(
mode_id
)
);
BMDDisplayMode
mode_id
=
ntohl
(
display_mode
->
GetDisplayMode
()
);
memcpy
(
sz_mode_id_text
,
&
mode_id
,
sizeof
(
mode_id
)
);
const
char
*
psz_
mode_name
;
result
=
p_display_mode
->
GetName
(
&
psz_mode_name
);
if
(
result
!=
S_OK
)
const
char
*
mode_name
;
result
=
display_mode
->
GetName
(
&
mode_name
);
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to get display mode name"
);
p_
display_mode
->
Release
();
msg_Err
(
demux
,
"Failed to get display mode name"
);
display_mode
->
Release
();
goto
finish
;
}
BMDTimeValue
frame_duration
,
time_scale
;
result
=
p_display_mode
->
GetFrameRate
(
&
frame_duration
,
&
time_scale
);
if
(
result
!=
S_OK
)
result
=
display_mode
->
GetFrameRate
(
&
frame_duration
,
&
time_scale
);
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to get frame rate"
);
p_
display_mode
->
Release
();
msg_Err
(
demux
,
"Failed to get frame rate"
);
display_mode
->
Release
();
goto
finish
;
}
const
char
*
psz_
field_dominance
;
uint32_t
i_
dominance_flags
=
0
;
switch
(
p_display_mode
->
GetFieldDominance
()
)
const
char
*
field_dominance
;
uint32_t
dominance_flags
=
0
;
switch
(
display_mode
->
GetFieldDominance
()
)
{
case
bmdProgressiveFrame
:
psz_
field_dominance
=
""
;
field_dominance
=
""
;
break
;
case
bmdProgressiveSegmentedFrame
:
psz_
field_dominance
=
", segmented"
;
field_dominance
=
", segmented"
;
break
;
case
bmdLowerFieldFirst
:
psz_
field_dominance
=
", interlaced [BFF]"
;
i_
dominance_flags
=
BLOCK_FLAG_BOTTOM_FIELD_FIRST
;
field_dominance
=
", interlaced [BFF]"
;
dominance_flags
=
BLOCK_FLAG_BOTTOM_FIELD_FIRST
;
break
;
case
bmdUpperFieldFirst
:
psz_
field_dominance
=
", interlaced [TFF]"
;
i_
dominance_flags
=
BLOCK_FLAG_TOP_FIELD_FIRST
;
field_dominance
=
", interlaced [TFF]"
;
dominance_flags
=
BLOCK_FLAG_TOP_FIELD_FIRST
;
break
;
case
bmdUnknownFieldDominance
:
default:
psz_
field_dominance
=
", unknown field dominance"
;
field_dominance
=
", unknown field dominance"
;
break
;
}
msg_Dbg
(
p_
demux
,
"Found mode '%s': %s (%dx%d, %.3f fps%s)"
,
sz_mode_id_text
,
psz_
mode_name
,
p_display_mode
->
GetWidth
(),
p_
display_mode
->
GetHeight
(),
double
(
time_scale
)
/
frame_duration
,
psz_field_dominance
);
msg_Dbg
(
demux
,
"Found mode '%s': %s (%dx%d, %.3f fps%s)"
,
sz_mode_id_text
,
mode_name
,
display_mode
->
GetWidth
(),
display_mode
->
GetHeight
(),
double
(
time_scale
)
/
frame_duration
,
field_dominance
);
if
(
wanted_mode_id
==
mode_id
)
if
(
wanted_mode_id
==
mode_id
)
{
b_found_mode
=
true
;
i_width
=
p_
display_mode
->
GetWidth
();
i_height
=
p_
display_mode
->
GetHeight
();
i_
fps_num
=
time_scale
;
i_
fps_den
=
frame_duration
;
p_sys
->
i_dominance_flags
=
i_
dominance_flags
;
width
=
display_mode
->
GetWidth
();
height
=
display_mode
->
GetHeight
();
fps_num
=
time_scale
;
fps_den
=
frame_duration
;
sys
->
dominance_flags
=
dominance_flags
;
}
p_
display_mode
->
Release
();
display_mode
->
Release
();
}
if
(
!
b_found_mode
)
if
(
!
b_found_mode
)
{
msg_Err
(
p_
demux
,
"Unknown video mode specified. "
"Run VLC with -vv to get a list of supported modes."
);
msg_Err
(
demux
,
"Unknown video mode specified. "
"Run VLC with -vv to get a list of supported modes."
);
goto
finish
;
}
result
=
p_sys
->
p_input
->
EnableVideoInput
(
htonl
(
wanted_mode_id
),
bmdFormat8BitYUV
,
0
);
if
(
result
!=
S_OK
)
result
=
sys
->
input
->
EnableVideoInput
(
htonl
(
wanted_mode_id
),
bmdFormat8BitYUV
,
0
);
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to enable video input"
);
msg_Err
(
demux
,
"Failed to enable video input"
);
goto
finish
;
}
/* Set up audio. */
p_sys
->
i_channels
=
var_InheritInteger
(
p_demux
,
"decklink-audio-channels"
);
i_rate
=
var_InheritInteger
(
p_demux
,
"decklink-audio-rate"
);
if
(
i_rate
>
0
&&
p_sys
->
i_channels
>
0
)
sys
->
channels
=
var_InheritInteger
(
demux
,
"decklink-audio-channels"
);
rate
=
var_InheritInteger
(
demux
,
"decklink-audio-rate"
);
if
(
rate
>
0
&&
sys
->
channels
>
0
)
{
result
=
p_sys
->
p_input
->
EnableAudioInput
(
i_rate
,
bmdAudioSampleType16bitInteger
,
p_sys
->
i_channels
);
if
(
result
!=
S_OK
)
result
=
sys
->
input
->
EnableAudioInput
(
rate
,
bmdAudioSampleType16bitInteger
,
sys
->
channels
);
if
(
result
!=
S_OK
)
{
msg_Err
(
p_demux
,
"Failed to enable audio input"
);
msg_Err
(
demux
,
"Failed to enable audio input"
);
goto
finish
;
}
}
p_sys
->
p_delegate
=
new
DeckLinkCaptureDelegate
(
p_demux
);
p_sys
->
p_input
->
SetCallback
(
p_sys
->
p_delegate
);
sys
->
delegate
=
new
DeckLinkCaptureDelegate
(
demux
);
sys
->
input
->
SetCallback
(
sys
->
delegate
);
result
=
p_sys
->
p_
input
->
StartStreams
();
if
(
result
!=
S_OK
)
result
=
sys
->
input
->
StartStreams
();
if
(
result
!=
S_OK
)
{
msg_Err
(
p_
demux
,
"Could not start streaming from SDI card. This could be caused "
"by invalid video mode or flags, access denied, or card already in use."
);
msg_Err
(
demux
,
"Could not start streaming from SDI card. This could be caused "
"by invalid video mode or flags, access denied, or card already in use."
);
goto
finish
;
}
/* Declare elementary streams */
es_format_t
video_fmt
;
es_format_Init
(
&
video_fmt
,
VIDEO_ES
,
VLC_CODEC_UYVY
);
video_fmt
.
video
.
i_width
=
i_
width
;
video_fmt
.
video
.
i_height
=
i_
height
;
es_format_Init
(
&
video_fmt
,
VIDEO_ES
,
VLC_CODEC_UYVY
);
video_fmt
.
video
.
i_width
=
width
;
video_fmt
.
video
.
i_height
=
height
;
video_fmt
.
video
.
i_sar_num
=
1
;
video_fmt
.
video
.
i_sar_den
=
1
;
video_fmt
.
video
.
i_frame_rate
=
i_
fps_num
;
video_fmt
.
video
.
i_frame_rate_base
=
i_
fps_den
;
video_fmt
.
video
.
i_frame_rate
=
fps_num
;
video_fmt
.
video
.
i_frame_rate_base
=
fps_den
;
video_fmt
.
i_bitrate
=
video_fmt
.
video
.
i_width
*
video_fmt
.
video
.
i_height
*
video_fmt
.
video
.
i_frame_rate
*
2
*
8
;
if
(
!
var_InheritURational
(
p_demux
,
&
u_aspect_num
,
&
u_aspect_den
,
"decklink-aspect-ratio"
)
&&
u_aspect_num
>
0
&&
u_aspect_den
>
0
)
{
video_fmt
.
video
.
i_sar_num
=
u_
aspect_num
*
video_fmt
.
video
.
i_height
;
video_fmt
.
video
.
i_sar_den
=
u_
aspect_den
*
video_fmt
.
video
.
i_width
;
if
(
!
var_InheritURational
(
demux
,
&
aspect_num
,
&
aspect_den
,
"decklink-aspect-ratio"
)
&&
aspect_num
>
0
&&
aspect_den
>
0
)
{
video_fmt
.
video
.
i_sar_num
=
aspect_num
*
video_fmt
.
video
.
i_height
;
video_fmt
.
video
.
i_sar_den
=
aspect_den
*
video_fmt
.
video
.
i_width
;
}
msg_Dbg
(
p_
demux
,
"added new video es %4.4s %dx%d"
,
(
char
*
)
&
video_fmt
.
i_codec
,
video_fmt
.
video
.
i_width
,
video_fmt
.
video
.
i_height
);
p_sys
->
p_video_es
=
es_out_Add
(
p_demux
->
out
,
&
video_fmt
);
msg_Dbg
(
demux
,
"added new video es %4.4s %dx%d"
,
(
char
*
)
&
video_fmt
.
i_codec
,
video_fmt
.
video
.
i_width
,
video_fmt
.
video
.
i_height
);
sys
->
video_es
=
es_out_Add
(
demux
->
out
,
&
video_fmt
);
es_format_t
audio_fmt
;
es_format_Init
(
&
audio_fmt
,
AUDIO_ES
,
VLC_CODEC_S16N
);
audio_fmt
.
audio
.
i_channels
=
p_sys
->
i_
channels
;
audio_fmt
.
audio
.
i_rate
=
i_
rate
;
es_format_Init
(
&
audio_fmt
,
AUDIO_ES
,
VLC_CODEC_S16N
);
audio_fmt
.
audio
.
i_channels
=
sys
->
channels
;
audio_fmt
.
audio
.
i_rate
=
rate
;
audio_fmt
.
audio
.
i_bitspersample
=
16
;
audio_fmt
.
audio
.
i_blockalign
=
audio_fmt
.
audio
.
i_channels
*
audio_fmt
.
audio
.
i_bitspersample
/
8
;
audio_fmt
.
i_bitrate
=
audio_fmt
.
audio
.
i_channels
*
audio_fmt
.
audio
.
i_rate
*
audio_fmt
.
audio
.
i_bitspersample
;
msg_Dbg
(
p_
demux
,
"added new audio es %4.4s %dHz %dbpp %dch"
,
msg_Dbg
(
demux
,
"added new audio es %4.4s %dHz %dbpp %dch"
,
(
char
*
)
&
audio_fmt
.
i_codec
,
audio_fmt
.
audio
.
i_rate
,
audio_fmt
.
audio
.
i_bitspersample
,
audio_fmt
.
audio
.
i_channels
);
p_sys
->
p_audio_es
=
es_out_Add
(
p_demux
->
out
,
&
audio_fmt
);
sys
->
audio_es
=
es_out_Add
(
demux
->
out
,
&
audio_fmt
);
ret
=
VLC_SUCCESS
;
finish:
if
(
decklink_iterator
)
if
(
decklink_iterator
)
decklink_iterator
->
Release
();
free
(
psz_video_connection
);
free
(
psz_audio_connection
);
free
(
psz_display_mode
);
free
(
video_connection
);
free
(
audio_connection
);
free
(
display_mode
);
if
(
p_display_iterator
)
p_
display_iterator
->
Release
();
if
(
display_iterator
)
display_iterator
->
Release
();
if
(
ret
!=
VLC_SUCCESS
)
Close
(
p_this
);
if
(
ret
!=
VLC_SUCCESS
)
Close
(
p_this
);
return
ret
;
}
static
void
Close
(
vlc_object_t
*
p_this
)
static
void
Close
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_
demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
p_sys
=
p_
demux
->
p_sys
;
demux_t
*
demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
sys
=
demux
->
p_sys
;
if
(
p_sys
->
p_config
)
p_sys
->
p_
config
->
Release
();
if
(
sys
->
config
)
sys
->
config
->
Release
();
if
(
p_sys
->
p_input
)
if
(
sys
->
input
)
{
p_sys
->
p_
input
->
StopStreams
();
p_sys
->
p_
input
->
Release
();
sys
->
input
->
StopStreams
();
sys
->
input
->
Release
();
}
if
(
p_sys
->
p_card
)
p_sys
->
p_
card
->
Release
();
if
(
sys
->
card
)
sys
->
card
->
Release
();
if
(
p_sys
->
p_delegate
)
p_sys
->
p_
delegate
->
Release
();
if
(
sys
->
delegate
)
sys
->
delegate
->
Release
();
vlc_mutex_destroy
(
&
p_sys
->
pts_lock
);
free
(
p_sys
);
vlc_mutex_destroy
(
&
sys
->
pts_lock
);
free
(
sys
);
}
static
int
Control
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
static
int
Control
(
demux_t
*
demux
,
int
query
,
va_list
args
)
{
demux_sys_t
*
p_sys
=
p_
demux
->
p_sys
;
demux_sys_t
*
sys
=
demux
->
p_sys
;
bool
*
pb
;
int64_t
*
pi64
;
int64_t
*
pi64
;
switch
(
i_query
)
switch
(
query
)
{
/* Special for access_demux */
case
DEMUX_CAN_PAUSE
:
case
DEMUX_CAN_SEEK
:
case
DEMUX_CAN_CONTROL_PACE
:
pb
=
(
bool
*
)
va_arg
(
args
,
bool
*
);
pb
=
(
bool
*
)
va_arg
(
args
,
bool
*
);
*
pb
=
false
;
return
VLC_SUCCESS
;
case
DEMUX_GET_PTS_DELAY
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi64
=
INT64_C
(
1000
)
*
var_InheritInteger
(
p_demux
,
"live-caching"
);
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
*
pi64
=
INT64_C
(
1000
)
*
var_InheritInteger
(
demux
,
"live-caching"
);
return
VLC_SUCCESS
;
case
DEMUX_GET_TIME
:
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
vlc_mutex_lock
(
&
p_sys
->
pts_lock
);
*
pi64
=
p_sys
->
i_
last_pts
;
vlc_mutex_unlock
(
&
p_sys
->
pts_lock
);
pi64
=
(
int64_t
*
)
va_arg
(
args
,
int64_t
*
);
vlc_mutex_lock
(
&
sys
->
pts_lock
);
*
pi64
=
sys
->
last_pts
;
vlc_mutex_unlock
(
&
sys
->
pts_lock
);
return
VLC_SUCCESS
;
default:
...
...
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