Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
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