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
9df9c4cf
Commit
9df9c4cf
authored
Mar 07, 2014
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decklink: autodetect input format
parent
5ec4f242
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
135 additions
and
63 deletions
+135
-63
modules/access/decklink.cpp
modules/access/decklink.cpp
+135
-63
No files found.
modules/access/decklink.cpp
View file @
9df9c4cf
...
@@ -46,7 +46,7 @@ static void Close(vlc_object_t *);
...
@@ -46,7 +46,7 @@ static void Close(vlc_object_t *);
"DeckLink capture card to use, if multiple exist. " \
"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_TEXT N_("Desired input video mode
. Leave empty for autodetection.
")
#define MODE_LONGTEXT N_( \
#define MODE_LONGTEXT N_( \
"Desired input video mode for DeckLink captures. " \
"Desired input video mode for DeckLink captures. " \
"This value should be a FOURCC code in textual " \
"This value should be a FOURCC code in textual " \
...
@@ -101,7 +101,7 @@ vlc_module_begin ()
...
@@ -101,7 +101,7 @@ vlc_module_begin ()
add_integer
(
"decklink-card-index"
,
0
,
add_integer
(
"decklink-card-index"
,
0
,
CARD_INDEX_TEXT
,
CARD_INDEX_LONGTEXT
,
true
)
CARD_INDEX_TEXT
,
CARD_INDEX_LONGTEXT
,
true
)
add_string
(
"decklink-mode"
,
"pal "
,
add_string
(
"decklink-mode"
,
NULL
,
MODE_TEXT
,
MODE_LONGTEXT
,
true
)
MODE_TEXT
,
MODE_LONGTEXT
,
true
)
add_string
(
"decklink-audio-connection"
,
0
,
add_string
(
"decklink-audio-connection"
,
0
,
AUDIO_CONNECTION_TEXT
,
AUDIO_CONNECTION_LONGTEXT
,
true
)
AUDIO_CONNECTION_TEXT
,
AUDIO_CONNECTION_LONGTEXT
,
true
)
...
@@ -135,6 +135,9 @@ struct demux_sys_t
...
@@ -135,6 +135,9 @@ struct demux_sys_t
/* We need to hold onto the IDeckLinkConfiguration object, or our settings will not apply.
/* 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. */
See section 2.4.15 of the Blackmagic Decklink SDK documentation. */
IDeckLinkConfiguration
*
config
;
IDeckLinkConfiguration
*
config
;
IDeckLinkAttributes
*
attributes
;
bool
autodetect
;
es_out_id_t
*
video_es
;
es_out_id_t
*
video_es
;
es_out_id_t
*
audio_es
;
es_out_id_t
*
audio_es
;
...
@@ -149,6 +152,62 @@ struct demux_sys_t
...
@@ -149,6 +152,62 @@ struct demux_sys_t
bool
tenbits
;
bool
tenbits
;
};
};
static
const
char
*
GetFieldDominance
(
BMDFieldDominance
dom
,
uint32_t
*
flags
)
{
switch
(
dom
)
{
case
bmdProgressiveFrame
:
return
""
;
case
bmdProgressiveSegmentedFrame
:
return
", segmented"
;
case
bmdLowerFieldFirst
:
*
flags
=
BLOCK_FLAG_BOTTOM_FIELD_FIRST
;
return
", interlaced [BFF]"
;
case
bmdUpperFieldFirst
:
*
flags
=
BLOCK_FLAG_TOP_FIELD_FIRST
;
return
", interlaced [TFF]"
;
case
bmdUnknownFieldDominance
:
default:
return
", unknown field dominance"
;
}
}
static
es_format_t
GetModeSettings
(
demux_t
*
demux
,
IDeckLinkDisplayMode
*
m
)
{
demux_sys_t
*
sys
=
demux
->
p_sys
;
uint32_t
flags
=
0
;
(
void
)
GetFieldDominance
(
m
->
GetFieldDominance
(),
&
flags
);
BMDTimeValue
frame_duration
,
time_scale
;
if
(
m
->
GetFrameRate
(
&
frame_duration
,
&
time_scale
)
!=
S_OK
)
{
time_scale
=
0
;
frame_duration
=
1
;
}
es_format_t
video_fmt
;
vlc_fourcc_t
chroma
;
chroma
=
sys
->
tenbits
?
VLC_CODEC_I422_10L
:
VLC_CODEC_UYVY
;
es_format_Init
(
&
video_fmt
,
VIDEO_ES
,
chroma
);
video_fmt
.
video
.
i_width
=
m
->
GetWidth
();
video_fmt
.
video
.
i_height
=
m
->
GetHeight
();
video_fmt
.
video
.
i_sar_num
=
1
;
video_fmt
.
video
.
i_sar_den
=
1
;
video_fmt
.
video
.
i_frame_rate
=
time_scale
;
video_fmt
.
video
.
i_frame_rate_base
=
frame_duration
;
video_fmt
.
i_bitrate
=
video_fmt
.
video
.
i_width
*
video_fmt
.
video
.
i_height
*
video_fmt
.
video
.
i_frame_rate
*
2
*
8
;
unsigned
aspect_num
,
aspect_den
;
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
;
}
sys
->
dominance_flags
=
flags
;
return
video_fmt
;
}
class
DeckLinkCaptureDelegate
:
public
IDeckLinkInputCallback
class
DeckLinkCaptureDelegate
:
public
IDeckLinkInputCallback
{
{
public:
public:
...
@@ -172,9 +231,33 @@ public:
...
@@ -172,9 +231,33 @@ public:
return
new_ref
;
return
new_ref
;
}
}
virtual
HRESULT
STDMETHODCALLTYPE
VideoInputFormatChanged
(
BMDVideoInputFormatChangedEvents
,
IDeckLinkDisplayMode
*
,
BMDDetectedVideoInputFormatFlags
)
virtual
HRESULT
STDMETHODCALLTYPE
VideoInputFormatChanged
(
BMDVideoInputFormatChangedEvents
events
,
IDeckLinkDisplayMode
*
mode
,
BMDDetectedVideoInputFormatFlags
)
{
{
msg_Dbg
(
demux_
,
"Video input format changed"
);
demux_sys_t
*
sys
=
demux_
->
p_sys
;
if
(
!
(
events
&
bmdVideoInputDisplayModeChanged
))
return
S_OK
;
const
char
*
mode_name
;
if
(
mode
->
GetName
(
&
mode_name
)
!=
S_OK
)
mode_name
=
"unknown"
;
msg_Dbg
(
demux_
,
"Video input format changed to %s"
,
mode_name
);
if
(
!
sys
->
autodetect
)
{
msg_Err
(
demux_
,
"Video format detection disabled"
);
return
S_OK
;
}
es_out_Del
(
demux_
->
out
,
sys
->
video_es
);
es_format_t
video_fmt
=
GetModeSettings
(
demux_
,
mode
);
sys
->
video_es
=
es_out_Add
(
demux_
->
out
,
&
video_fmt
);
BMDPixelFormat
fmt
=
sys
->
tenbits
?
bmdFormat10BitYUV
:
bmdFormat8BitYUV
;
sys
->
input
->
PauseStreams
();
sys
->
input
->
EnableVideoInput
(
mode
->
GetDisplayMode
(),
fmt
,
bmdVideoInputEnableFormatDetection
);
sys
->
input
->
FlushStreams
();
sys
->
input
->
StartStreams
();
return
S_OK
;
return
S_OK
;
}
}
...
@@ -491,36 +574,15 @@ static int GetVideoConn(demux_t *demux)
...
@@ -491,36 +574,15 @@ static int GetVideoConn(demux_t *demux)
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
const
char
*
GetFieldDominance
(
BMDFieldDominance
dom
,
uint32_t
*
flags
)
{
switch
(
dom
)
{
case
bmdProgressiveFrame
:
return
""
;
case
bmdProgressiveSegmentedFrame
:
return
", segmented"
;
case
bmdLowerFieldFirst
:
*
flags
=
BLOCK_FLAG_BOTTOM_FIELD_FIRST
;
return
", interlaced [BFF]"
;
case
bmdUpperFieldFirst
:
*
flags
=
BLOCK_FLAG_TOP_FIELD_FIRST
;
return
", interlaced [TFF]"
;
case
bmdUnknownFieldDominance
:
default:
return
", unknown field dominance"
;
}
}
static
int
Open
(
vlc_object_t
*
p_this
)
static
int
Open
(
vlc_object_t
*
p_this
)
{
{
demux_t
*
demux
=
(
demux_t
*
)
p_this
;
demux_t
*
demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
sys
;
demux_sys_t
*
sys
;
int
ret
=
VLC_EGENERIC
;
int
ret
=
VLC_EGENERIC
;
int
card_index
;
int
card_index
;
int
width
=
0
,
height
,
fps_num
,
fps_den
;
int
physical_channels
=
0
;
int
physical_channels
=
0
;
int
rate
;
int
rate
;
unsigned
aspect_num
,
aspect_den
;
BMDVideoInputFlags
flags
=
bmdVideoInputFlagDefault
;
/* Only when selected */
/* Only when selected */
if
(
*
demux
->
psz_access
==
'\0'
)
if
(
*
demux
->
psz_access
==
'\0'
)
...
@@ -578,13 +640,18 @@ static int Open(vlc_object_t *p_this)
...
@@ -578,13 +640,18 @@ static int Open(vlc_object_t *p_this)
goto
finish
;
goto
finish
;
}
}
if
(
sys
->
card
->
QueryInterface
(
IID_IDeckLinkAttributes
,
(
void
**
)
&
sys
->
attributes
)
!=
S_OK
)
{
msg_Err
(
demux
,
"Failed to get attributes interface"
);
goto
finish
;
}
if
(
GetVideoConn
(
demux
)
||
GetAudioConn
(
demux
))
if
(
GetVideoConn
(
demux
)
||
GetAudioConn
(
demux
))
goto
finish
;
goto
finish
;
char
*
mode
;
BMDPixelFormat
fmt
;
mode
=
var_CreateGetNonEmptyString
(
demux
,
"decklink-mode"
)
;
fmt
=
sys
->
tenbits
?
bmdFormat10BitYUV
:
bmdFormat8BitYUV
;
if
(
!
mode
||
strlen
(
mode
)
<
3
||
strlen
(
mode
)
>
4
)
{
if
(
sys
->
attributes
->
GetFlag
(
BMDDeckLinkSupportsInputFormatDetection
,
&
sys
->
autodetect
)
!=
S_OK
)
{
msg_Err
(
demux
,
"
Invalid mode: `%s
\'
"
,
mode
?
mode
:
"
"
);
msg_Err
(
demux
,
"
Failed to query card attribute
"
);
goto
finish
;
goto
finish
;
}
}
...
@@ -592,7 +659,6 @@ static int Open(vlc_object_t *p_this)
...
@@ -592,7 +659,6 @@ static int Open(vlc_object_t *p_this)
IDeckLinkDisplayModeIterator
*
mode_it
;
IDeckLinkDisplayModeIterator
*
mode_it
;
if
(
sys
->
input
->
GetDisplayModeIterator
(
&
mode_it
)
!=
S_OK
)
{
if
(
sys
->
input
->
GetDisplayModeIterator
(
&
mode_it
)
!=
S_OK
)
{
msg_Err
(
demux
,
"Failed to enumerate display modes"
);
msg_Err
(
demux
,
"Failed to enumerate display modes"
);
free
(
mode
);
goto
finish
;
goto
finish
;
}
}
...
@@ -600,10 +666,35 @@ static int Open(vlc_object_t *p_this)
...
@@ -600,10 +666,35 @@ static int Open(vlc_object_t *p_this)
BMDDisplayMode
id
;
BMDDisplayMode
id
;
char
str
[
4
];
char
str
[
4
];
}
u
;
}
u
;
u
.
id
=
0
;
char
*
mode
;
mode
=
var_CreateGetNonEmptyString
(
demux
,
"decklink-mode"
);
if
(
mode
)
sys
->
autodetect
=
false
;
// disable autodetection if mode was set
if
(
sys
->
autodetect
)
{
msg_Dbg
(
demux
,
"Card supports input format detection"
);
flags
|=
bmdVideoInputEnableFormatDetection
;
/* Enable a random format, we will reconfigure on format detection */
u
.
id
=
htonl
(
bmdModeHD1080p2997
);
}
else
{
if
(
!
mode
||
strlen
(
mode
)
<
3
||
strlen
(
mode
)
>
4
)
{
msg_Err
(
demux
,
"Invalid mode:
\'
%s
\'
"
,
mode
?
mode
:
""
);
free
(
mode
);
goto
finish
;
}
msg_Dbg
(
demux
,
"Looking for mode
\'
%s
\'
"
,
mode
);
memcpy
(
u
.
str
,
mode
,
4
);
memcpy
(
u
.
str
,
mode
,
4
);
if
(
u
.
str
[
3
]
==
'\0'
)
if
(
u
.
str
[
3
]
==
'\0'
)
u
.
str
[
3
]
=
' '
;
/* 'pal'\0 -> 'pal ' */
u
.
str
[
3
]
=
' '
;
/* 'pal'\0 -> 'pal ' */
free
(
mode
);
free
(
mode
);
}
es_format_t
video_fmt
;
video_fmt
.
video
.
i_width
=
0
;
for
(
IDeckLinkDisplayMode
*
m
;;
m
->
Release
())
{
for
(
IDeckLinkDisplayMode
*
m
;;
m
->
Release
())
{
if
((
mode_it
->
Next
(
&
m
)
!=
S_OK
)
||
!
m
)
if
((
mode_it
->
Next
(
&
m
)
!=
S_OK
)
||
!
m
)
...
@@ -611,8 +702,8 @@ static int Open(vlc_object_t *p_this)
...
@@ -611,8 +702,8 @@ static int Open(vlc_object_t *p_this)
const
char
*
mode_name
;
const
char
*
mode_name
;
BMDTimeValue
frame_duration
,
time_scale
;
BMDTimeValue
frame_duration
,
time_scale
;
uint32_t
f
lags
=
0
;
uint32_t
f
ield_flags
;
const
char
*
field
=
GetFieldDominance
(
m
->
GetFieldDominance
(),
&
flags
);
const
char
*
field
=
GetFieldDominance
(
m
->
GetFieldDominance
(),
&
f
ield_f
lags
);
BMDDisplayMode
id
=
ntohl
(
m
->
GetDisplayMode
());
BMDDisplayMode
id
=
ntohl
(
m
->
GetDisplayMode
());
if
(
m
->
GetName
(
&
mode_name
)
!=
S_OK
)
if
(
m
->
GetName
(
&
mode_name
)
!=
S_OK
)
...
@@ -628,23 +719,19 @@ static int Open(vlc_object_t *p_this)
...
@@ -628,23 +719,19 @@ static int Open(vlc_object_t *p_this)
double
(
time_scale
)
/
frame_duration
,
field
);
double
(
time_scale
)
/
frame_duration
,
field
);
if
(
u
.
id
==
id
)
{
if
(
u
.
id
==
id
)
{
width
=
m
->
GetWidth
();
video_fmt
=
GetModeSettings
(
demux
,
m
);
height
=
m
->
GetHeight
();
msg_Dbg
(
demux
,
"Using that mode"
);
fps_num
=
time_scale
;
fps_den
=
frame_duration
;
sys
->
dominance_flags
=
flags
;
}
}
}
}
mode_it
->
Release
();
mode_it
->
Release
();
if
(
width
==
0
)
{
if
(
video_fmt
.
video
.
i_
width
==
0
)
{
msg_Err
(
demux
,
"Unknown video mode `%4.4s
\'
specified."
,
(
char
*
)
&
u
.
id
);
msg_Err
(
demux
,
"Unknown video mode `%4.4s
\'
specified."
,
(
char
*
)
&
u
.
id
);
goto
finish
;
goto
finish
;
}
}
BMDPixelFormat
fmt
;
fmt
=
sys
->
tenbits
?
bmdFormat10BitYUV
:
bmdFormat8BitYUV
;
if
(
sys
->
input
->
EnableVideoInput
(
htonl
(
u
.
id
),
fmt
,
flags
)
!=
S_OK
)
{
if
(
sys
->
input
->
EnableVideoInput
(
htonl
(
u
.
id
),
fmt
,
0
)
!=
S_OK
)
{
msg_Err
(
demux
,
"Failed to enable video input"
);
msg_Err
(
demux
,
"Failed to enable video input"
);
goto
finish
;
goto
finish
;
}
}
...
@@ -682,24 +769,6 @@ static int Open(vlc_object_t *p_this)
...
@@ -682,24 +769,6 @@ static int Open(vlc_object_t *p_this)
goto
finish
;
goto
finish
;
}
}
/* Declare elementary streams */
es_format_t
video_fmt
;
vlc_fourcc_t
chroma
;
chroma
=
sys
->
tenbits
?
VLC_CODEC_I422_10L
:
VLC_CODEC_UYVY
;
es_format_Init
(
&
video_fmt
,
VIDEO_ES
,
chroma
);
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
=
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
(
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
(
demux
,
"added new video es %4.4s %dx%d"
,
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
);
(
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
);
sys
->
video_es
=
es_out_Add
(
demux
->
out
,
&
video_fmt
);
...
@@ -734,6 +803,9 @@ static void Close(vlc_object_t *p_this)
...
@@ -734,6 +803,9 @@ static void Close(vlc_object_t *p_this)
demux_t
*
demux
=
(
demux_t
*
)
p_this
;
demux_t
*
demux
=
(
demux_t
*
)
p_this
;
demux_sys_t
*
sys
=
demux
->
p_sys
;
demux_sys_t
*
sys
=
demux
->
p_sys
;
if
(
sys
->
attributes
)
sys
->
attributes
->
Release
();
if
(
sys
->
config
)
if
(
sys
->
config
)
sys
->
config
->
Release
();
sys
->
config
->
Release
();
...
...
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