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
55702dbd
Commit
55702dbd
authored
Mar 07, 2014
by
Rafaël Carré
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decklink input: factor out some SDI code
parent
9df9c4cf
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
262 additions
and
157 deletions
+262
-157
modules/access/Makefile.am
modules/access/Makefile.am
+1
-1
modules/access/decklink.cpp
modules/access/decklink.cpp
+22
-156
modules/access/sdi.c
modules/access/sdi.c
+202
-0
modules/access/sdi.h
modules/access/sdi.h
+37
-0
No files found.
modules/access/Makefile.am
View file @
55702dbd
...
...
@@ -132,7 +132,7 @@ liblinsys_sdi_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)'
access_LTLIBRARIES
+=
$(LTLIBlinsys_hdsdi)
$(LTLIBlinsys_sdi)
EXTRA_LTLIBRARIES
+=
liblinsys_hdsdi_plugin.la liblinsys_sdi_plugin.la
libdecklink_plugin_la_SOURCES
=
access/decklink.cpp
libdecklink_plugin_la_SOURCES
=
access/decklink.cpp
access/sdi.c access/sdi.h
libdecklink_plugin_la_CXXFLAGS
=
$(AM_CFLAGS)
$(CPPFLAGS_decklink)
libdecklink_plugin_la_LIBADD
=
$(LIBS_decklink)
-ldl
if
HAVE_DECKLINK
...
...
modules/access/decklink.cpp
View file @
55702dbd
...
...
@@ -2,10 +2,10 @@
* decklink.cpp: BlackMagic DeckLink SDI input module
*****************************************************************************
* Copyright (C) 2010 Steinar H. Gunderson
* Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
* Copyright (C) 2012-2014 Rafaël Carré
*
* Authors: Steinar H. Gunderson <steinar+vlc@gunderson.no>
Rafaël Carré <funman@videolanorg>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
...
...
@@ -38,6 +38,8 @@
#include <DeckLinkAPI.h>
#include <DeckLinkAPIDispatch.cpp>
#include "sdi.h"
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
...
...
@@ -268,60 +270,6 @@ private:
demux_t
*
demux_
;
};
static
inline
uint32_t
av_le2ne32
(
uint32_t
val
)
{
union
{
uint32_t
v
;
uint8_t
b
[
4
];
}
u
;
u
.
v
=
val
;
return
(
u
.
b
[
0
]
<<
0
)
|
(
u
.
b
[
1
]
<<
8
)
|
(
u
.
b
[
2
]
<<
16
)
|
(
u
.
b
[
3
]
<<
24
);
}
static
void
v210_convert
(
uint16_t
*
dst
,
const
uint32_t
*
bytes
,
const
int
width
,
const
int
height
)
{
const
int
stride
=
((
width
+
47
)
/
48
)
*
48
*
8
/
3
/
4
;
uint16_t
*
y
=
&
dst
[
0
];
uint16_t
*
u
=
&
dst
[
width
*
height
*
2
/
2
];
uint16_t
*
v
=
&
dst
[
width
*
height
*
3
/
2
];
#define READ_PIXELS(a, b, c) \
do { \
val = av_le2ne32(*src++); \
*a++ = val & 0x3FF; \
*b++ = (val >> 10) & 0x3FF; \
*c++ = (val >> 20) & 0x3FF; \
} while (0)
for
(
int
h
=
0
;
h
<
height
;
h
++
)
{
const
uint32_t
*
src
=
bytes
;
uint32_t
val
=
0
;
int
w
;
for
(
w
=
0
;
w
<
width
-
5
;
w
+=
6
)
{
READ_PIXELS
(
u
,
y
,
v
);
READ_PIXELS
(
y
,
u
,
y
);
READ_PIXELS
(
v
,
y
,
u
);
READ_PIXELS
(
y
,
v
,
y
);
}
if
(
w
<
width
-
1
)
{
READ_PIXELS
(
u
,
y
,
v
);
val
=
av_le2ne32
(
*
src
++
);
*
y
++
=
val
&
0x3FF
;
}
if
(
w
<
width
-
3
)
{
*
u
++
=
(
val
>>
10
)
&
0x3FF
;
*
y
++
=
(
val
>>
20
)
&
0x3FF
;
val
=
av_le2ne32
(
*
src
++
);
*
v
++
=
val
&
0x3FF
;
*
y
++
=
(
val
>>
10
)
&
0x3FF
;
}
bytes
+=
stride
;
}
}
HRESULT
DeckLinkCaptureDelegate
::
VideoInputFrameArrived
(
IDeckLinkVideoInputFrame
*
videoFrame
,
IDeckLinkAudioInputPacket
*
audioFrame
)
{
demux_sys_t
*
sys
=
demux_
->
p_sys
;
...
...
@@ -359,97 +307,16 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
break
;
uint16_t
dec
[
width
*
2
];
v210_convert
(
&
dec
[
0
],
buf
,
width
,
1
);
static
const
uint16_t
vanc_header
[
3
]
=
{
0
,
0x3ff
,
0x3ff
};
if
(
!
memcmp
(
vanc_header
,
dec
,
sizeof
(
vanc_header
)))
{
int
len
=
(
dec
[
5
]
&
0xff
)
+
6
+
1
;
uint16_t
vanc_sum
=
0
;
bool
parity_ok
=
true
;
for
(
int
i
=
3
;
i
<
len
-
1
;
i
++
)
{
uint16_t
v
=
dec
[
i
];
int
np
=
v
>>
8
;
int
p
=
parity
(
v
&
0xff
);
if
((
!!
p
^
!!
(
v
&
0x100
))
||
(
np
!=
1
&&
np
!=
2
))
{
parity_ok
=
false
;
break
;
}
vanc_sum
+=
v
;
vanc_sum
&=
0x1ff
;
dec
[
i
]
&=
0xff
;
}
if
(
!
parity_ok
)
continue
;
vanc_sum
|=
((
~
vanc_sum
&
0x100
)
<<
1
);
if
(
dec
[
len
-
1
]
!=
vanc_sum
)
continue
;
if
(
dec
[
3
]
!=
0x61
/* DID */
||
dec
[
4
]
!=
0x01
/* SDID = CEA-708 */
)
continue
;
/* CDP follows */
uint16_t
*
cdp
=
&
dec
[
6
];
if
(
cdp
[
0
]
!=
0x96
||
cdp
[
1
]
!=
0x69
)
continue
;
len
-=
7
;
// remove VANC header and checksum
if
(
cdp
[
2
]
!=
len
)
block_t
*
cc
=
vanc_to_cc
(
demux_
,
dec
,
width
*
2
);
if
(
!
cc
)
continue
;
uint8_t
cdp_sum
=
0
;
for
(
int
i
=
0
;
i
<
len
-
1
;
i
++
)
cdp_sum
+=
cdp
[
i
];
cdp_sum
=
cdp_sum
?
256
-
cdp_sum
:
0
;
if
(
cdp
[
len
-
1
]
!=
cdp_sum
)
continue
;
uint8_t
rate
=
cdp
[
3
];
if
(
!
(
rate
&
0x0f
))
continue
;
rate
>>=
4
;
if
(
rate
>
8
)
continue
;
if
(
!
(
cdp
[
4
]
&
0x43
))
/* ccdata_present | caption_service_active | reserved */
continue
;
uint16_t
hdr
=
(
cdp
[
5
]
<<
8
)
|
cdp
[
6
];
if
(
cdp
[
7
]
!=
0x72
)
/* ccdata_id */
continue
;
int
cc_count
=
cdp
[
8
];
if
(
!
(
cc_count
&
0xe0
))
continue
;
cc_count
&=
0x1f
;
/* FIXME: parse additional data (CC language?) */
if
((
len
-
13
)
<
cc_count
*
3
)
continue
;
if
(
cdp
[
len
-
4
]
!=
0x74
)
/* footer id */
continue
;
uint16_t
ftr
=
(
cdp
[
len
-
3
]
<<
8
)
|
cdp
[
len
-
2
];
if
(
ftr
!=
hdr
)
continue
;
block_t
*
cc
=
block_Alloc
(
cc_count
*
3
);
for
(
int
i
=
0
;
i
<
cc_count
;
i
++
)
{
cc
->
p_buffer
[
3
*
i
+
0
]
=
cdp
[
9
+
3
*
i
+
0
]
&
3
;
cc
->
p_buffer
[
3
*
i
+
1
]
=
cdp
[
9
+
3
*
i
+
1
];
cc
->
p_buffer
[
3
*
i
+
2
]
=
cdp
[
9
+
3
*
i
+
2
];
}
cc
->
i_pts
=
cc
->
i_dts
=
VLC_TS_0
+
stream_time
;
if
(
!
sys
->
cc_es
)
{
es_format_t
fmt
;
es_format_Init
(
&
fmt
,
SPU_ES
,
VLC_FOURCC
(
'c'
,
'c'
,
'1'
,
' '
)
);
fmt
.
psz_description
=
strdup
(
"Closed captions 1"
);
fmt
.
psz_description
=
strdup
(
N_
(
"Closed captions 1"
)
);
if
(
fmt
.
psz_description
)
{
sys
->
cc_es
=
es_out_Add
(
demux_
->
out
,
&
fmt
);
msg_Dbg
(
demux_
,
"Adding Closed captions stream"
);
...
...
@@ -461,7 +328,6 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
block_Release
(
cc
);
break
;
// we found the line with Closed Caption data
}
}
vanc
->
Release
();
}
}
else
{
...
...
modules/access/sdi.c
0 → 100644
View file @
55702dbd
/*****************************************************************************
* sdi.c: SDI helpers
*****************************************************************************
* Copyright (C) 2014 Rafaël Carré
* Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "sdi.h"
static
inline
uint32_t
av_le2ne32
(
uint32_t
val
)
{
union
{
uint32_t
v
;
uint8_t
b
[
4
];
}
u
;
u
.
v
=
val
;
return
(
u
.
b
[
0
]
<<
0
)
|
(
u
.
b
[
1
]
<<
8
)
|
(
u
.
b
[
2
]
<<
16
)
|
(
u
.
b
[
3
]
<<
24
);
}
void
v210_convert
(
uint16_t
*
dst
,
const
uint32_t
*
bytes
,
const
int
width
,
const
int
height
)
{
const
int
stride
=
((
width
+
47
)
/
48
)
*
48
*
8
/
3
/
4
;
uint16_t
*
y
=
&
dst
[
0
];
uint16_t
*
u
=
&
dst
[
width
*
height
*
2
/
2
];
uint16_t
*
v
=
&
dst
[
width
*
height
*
3
/
2
];
#define READ_PIXELS(a, b, c) \
do { \
val = av_le2ne32(*src++); \
*a++ = val & 0x3FF; \
*b++ = (val >> 10) & 0x3FF; \
*c++ = (val >> 20) & 0x3FF; \
} while (0)
for
(
int
h
=
0
;
h
<
height
;
h
++
)
{
const
uint32_t
*
src
=
bytes
;
uint32_t
val
=
0
;
int
w
;
for
(
w
=
0
;
w
<
width
-
5
;
w
+=
6
)
{
READ_PIXELS
(
u
,
y
,
v
);
READ_PIXELS
(
y
,
u
,
y
);
READ_PIXELS
(
v
,
y
,
u
);
READ_PIXELS
(
y
,
v
,
y
);
}
if
(
w
<
width
-
1
)
{
READ_PIXELS
(
u
,
y
,
v
);
val
=
av_le2ne32
(
*
src
++
);
*
y
++
=
val
&
0x3FF
;
}
if
(
w
<
width
-
3
)
{
*
u
++
=
(
val
>>
10
)
&
0x3FF
;
*
y
++
=
(
val
>>
20
)
&
0x3FF
;
val
=
av_le2ne32
(
*
src
++
);
*
v
++
=
val
&
0x3FF
;
*
y
++
=
(
val
>>
10
)
&
0x3FF
;
}
bytes
+=
stride
;
}
}
#undef vanc_to_cc
block_t
*
vanc_to_cc
(
vlc_object_t
*
obj
,
uint16_t
*
buf
,
size_t
words
)
{
if
(
words
<
3
)
{
msg_Err
(
obj
,
"VANC line too small (%zu words)"
,
words
);
return
NULL
;
}
static
const
uint8_t
vanc_header
[
6
]
=
{
0x00
,
0x00
,
0xff
,
0x03
,
0xff
,
0x03
};
if
(
memcmp
(
vanc_header
,
buf
,
3
*
2
))
{
/* Does not start with the VANC header */
return
NULL
;
}
size_t
len
=
(
buf
[
5
]
&
0xff
)
+
6
+
1
;
if
(
len
>
words
)
{
msg_Err
(
obj
,
"Data Count (%zu) > line length (%zu)"
,
len
,
words
);
return
NULL
;
}
uint16_t
vanc_sum
=
0
;
for
(
size_t
i
=
3
;
i
<
len
-
1
;
i
++
)
{
uint16_t
v
=
buf
[
i
];
int
np
=
v
>>
8
;
int
p
=
parity
(
v
&
0xff
);
if
((
!!
p
^
!!
(
v
&
0x100
))
||
(
np
!=
1
&&
np
!=
2
))
{
msg_Err
(
obj
,
"Parity incorrect for word %zu"
,
i
);
return
NULL
;
}
vanc_sum
+=
v
;
vanc_sum
&=
0x1ff
;
buf
[
i
]
&=
0xff
;
}
vanc_sum
|=
((
~
vanc_sum
&
0x100
)
<<
1
);
if
(
buf
[
len
-
1
]
!=
vanc_sum
)
{
msg_Err
(
obj
,
"VANC checksum incorrect: 0x%.4x != 0x%.4x"
,
vanc_sum
,
buf
[
len
-
1
]);
return
NULL
;
}
if
(
buf
[
3
]
!=
0x61
/* DID */
||
buf
[
4
]
!=
0x01
/* SDID = CEA-708 */
)
{
//msg_Err(obj, "Not a CEA-708 packet: DID = 0x%.2x SDID = 0x%.2x", buf[3], buf[4]);
// XXX : what is Not a CEA-708 packet: DID = 0x61 SDID = 0x02 ?
return
NULL
;
}
/* CDP follows */
uint16_t
*
cdp
=
&
buf
[
6
];
if
(
cdp
[
0
]
!=
0x96
||
cdp
[
1
]
!=
0x69
)
{
msg_Err
(
obj
,
"Invalid CDP header 0x%.2x 0x%.2x"
,
cdp
[
0
],
cdp
[
1
]);
return
NULL
;
}
len
-=
7
;
// remove VANC header and checksum
if
(
cdp
[
2
]
!=
len
)
{
msg_Err
(
obj
,
"CDP len %d != %zu"
,
cdp
[
2
],
len
);
return
NULL
;
}
uint8_t
cdp_sum
=
0
;
for
(
size_t
i
=
0
;
i
<
len
-
1
;
i
++
)
cdp_sum
+=
cdp
[
i
];
cdp_sum
=
cdp_sum
?
256
-
cdp_sum
:
0
;
if
(
cdp
[
len
-
1
]
!=
cdp_sum
)
{
msg_Err
(
obj
,
"CDP checksum invalid 0x%.4x != 0x%.4x"
,
cdp_sum
,
cdp
[
len
-
1
]);
return
NULL
;
}
uint8_t
rate
=
cdp
[
3
];
if
(
!
(
rate
&
0x0f
))
{
msg_Err
(
obj
,
"CDP frame rate invalid (0x%.2x)"
,
rate
);
return
NULL
;
}
rate
>>=
4
;
if
(
rate
>
8
)
{
msg_Err
(
obj
,
"CDP frame rate invalid (0x%.2x)"
,
rate
);
return
NULL
;
}
if
(
!
(
cdp
[
4
]
&
0x43
))
/* ccdata_present | caption_service_active | reserved */
{
msg_Err
(
obj
,
"CDP flags invalid (0x%.2x)"
,
cdp
[
4
]);
return
NULL
;
}
uint16_t
hdr
=
(
cdp
[
5
]
<<
8
)
|
cdp
[
6
];
if
(
cdp
[
7
]
!=
0x72
)
/* ccdata_id */
{
msg_Err
(
obj
,
"Invalid ccdata_id 0x%.2x"
,
cdp
[
7
]);
return
NULL
;
}
unsigned
cc_count
=
cdp
[
8
];
if
(
!
(
cc_count
&
0xe0
))
{
msg_Err
(
obj
,
"Invalid cc_count 0x%.2x"
,
cc_count
);
return
NULL
;
}
cc_count
&=
0x1f
;
if
((
len
-
13
)
<
cc_count
*
3
)
{
msg_Err
(
obj
,
"Invalid cc_count %d (> %zu)"
,
cc_count
*
3
,
len
-
13
);
return
NULL
;
}
if
(
cdp
[
len
-
4
]
!=
0x74
)
/* footer id */
{
msg_Err
(
obj
,
"Invalid footer id 0x%.2x"
,
cdp
[
len
-
4
]);
return
NULL
;
}
uint16_t
ftr
=
(
cdp
[
len
-
3
]
<<
8
)
|
cdp
[
len
-
2
];
if
(
ftr
!=
hdr
)
{
msg_Err
(
obj
,
"Header 0x%.4x != Footer 0x%.4x"
,
hdr
,
ftr
);
return
NULL
;
}
block_t
*
cc
=
block_Alloc
(
cc_count
*
3
);
for
(
size_t
i
=
0
;
i
<
cc_count
;
i
++
)
{
cc
->
p_buffer
[
3
*
i
+
0
]
=
cdp
[
9
+
3
*
i
+
0
]
/* & 3 */
;
cc
->
p_buffer
[
3
*
i
+
1
]
=
cdp
[
9
+
3
*
i
+
1
];
cc
->
p_buffer
[
3
*
i
+
2
]
=
cdp
[
9
+
3
*
i
+
2
];
}
return
cc
;
}
modules/access/sdi.h
0 → 100644
View file @
55702dbd
/*****************************************************************************
* sdi.c: SDI helpers
*****************************************************************************
* Copyright (C) 2014 Rafaël Carré
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef __cplusplus
extern
"C"
{
#endif
#include <vlc_common.h>
#include <vlc_block.h>
#include <inttypes.h>
void
v210_convert
(
uint16_t
*
dst
,
const
uint32_t
*
bytes
,
const
int
width
,
const
int
height
);
block_t
*
vanc_to_cc
(
vlc_object_t
*
,
uint16_t
*
,
size_t
);
#define vanc_to_cc(obj, buf, words) vanc_to_cc(VLC_OBJECT(obj), buf, words)
#ifdef __cplusplus
}
#endif
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