aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRay Tiley <raytiley@gmail.com>2018-02-11 16:16:45 -0800
committerMarton Balint <cus@passwd.hu>2018-02-13 00:13:21 +0100
commitc837cd3d4d11b7d304ff83a448831c81a53c8c25 (patch)
treee2e281913e9701c8f5aa39c69b0f69a9329de2bd
parentce6ce595cf10778f77ae586b606203ecb2914ed8 (diff)
downloadffmpeg-c837cd3d4d11b7d304ff83a448831c81a53c8c25.tar.gz
avdevice/decklink_dec: extract NTSC VANC
This changes how NTSC VANC is extracted from the buffer. In NTSC the vanc data is interleaved between luma and chroma, and not just the luma as in high definition resolutions. In my testing this allows a decklink card encoding valid NTSC closed captions to pass the caption data to the x264 encoder. Updated with reviews from Devin Heitmueller and Marton Balint. Signed-off-by: Ray Tiley <raytiley@gmail.com> Signed-off-by: Marton Balint <cus@passwd.hu>
-rw-r--r--libavdevice/decklink_dec.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 5c116f2d13..c3bb46e18f 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -149,6 +149,17 @@ static void extract_luma_from_v210(uint16_t *dst, const uint8_t *src, int width)
}
}
+static void unpack_v210(uint16_t *dst, const uint8_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width * 2 / 3; i++) {
+ *dst++ = src[0] + ((src[1] & 3) << 8);
+ *dst++ = (src[1] >> 2) + ((src[2] & 15) << 6);
+ *dst++ = (src[2] >> 4) + ((src[3] & 63) << 4);
+ src += 4;
+ }
+}
+
static uint8_t calc_parity_and_line_offset(int line)
{
uint8_t ret = (line < 313) << 5;
@@ -752,9 +763,15 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
for (i = vanc_line_numbers[idx].vanc_start; i <= vanc_line_numbers[idx].vanc_end; i++) {
uint8_t *buf;
if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) {
- uint16_t luma_vanc[MAX_WIDTH_VANC];
- extract_luma_from_v210(luma_vanc, buf, videoFrame->GetWidth());
- txt_buf = get_metadata(avctx, luma_vanc, videoFrame->GetWidth(),
+ uint16_t vanc[MAX_WIDTH_VANC];
+ size_t vanc_size = videoFrame->GetWidth();
+ if (ctx->bmd_mode == bmdModeNTSC && videoFrame->GetWidth() * 2 <= MAX_WIDTH_VANC) {
+ vanc_size = vanc_size * 2;
+ unpack_v210(vanc, buf, videoFrame->GetWidth());
+ } else {
+ extract_luma_from_v210(vanc, buf, videoFrame->GetWidth());
+ }
+ txt_buf = get_metadata(avctx, vanc, vanc_size,
txt_buf, sizeof(txt_buf0) - (txt_buf - txt_buf0), &pkt);
}
if (i == vanc_line_numbers[idx].field0_vanc_end)