[FFmpeg-devel] [PATCH] avdevice/decklink_dec: Extract 1080i and NTSC VANC

Ray Tiley raytiley at gmail.com
Sat Jan 20 19:33:29 EET 2018


This changes the vertical blanking lines extracted for NTSC and 1080i
resolutions that in personal testing were required to extract closed
caption data from the decklink video frames.

Additionally NTSC resolutions have the vanc data interleved between the uyvy
and not just the luma as in high definition resolutions.

In my testing this allows a decklink card encoding valid NTSC and 1080i
closed captions to pass the caption data to the x264 encoder.

Signed-off-by: Ray Tiley <raytiley at gmail.com>
---
 libavdevice/decklink_dec.cpp | 37 ++++++++++++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 94dae26..bceced5 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -67,8 +67,7 @@ typedef struct VANCLineNumber {
  * another source during switching*/
 static VANCLineNumber vanc_line_numbers[] = {
     /* SD Modes */
-
-    {bmdModeNTSC, 11, 19, 274, 282},
+    {bmdModeNTSC, 4, 21, 24, 284},
     {bmdModeNTSC2398, 11, 19, 274, 282},
     {bmdModePAL, 7, 22, 320, 335},
     {bmdModeNTSCp, 11, -1, -1, 39},
@@ -82,7 +81,7 @@ static VANCLineNumber vanc_line_numbers[] = {
     {bmdModeHD1080p2997, 8, -1, -1, 42},
     {bmdModeHD1080p30, 8, -1, -1, 42},
     {bmdModeHD1080i50, 8, 20, 570, 585},
-    {bmdModeHD1080i5994, 8, 20, 570, 585},
+    {bmdModeHD1080i5994, 6, 30, 568, 595},
     {bmdModeHD1080i6000, 8, 20, 570, 585},
     {bmdModeHD1080p50, 8, -1, -1, 42},
     {bmdModeHD1080p5994, 8, -1, -1, 42},
@@ -92,7 +91,7 @@ static VANCLineNumber vanc_line_numbers[] = {
 
     {bmdModeHD720p50, 8, -1, -1, 26},
     {bmdModeHD720p5994, 8, -1, -1, 26},
-    {bmdModeHD720p60, 8, -1, -1, 26},
+    {bmdModeHD720p60, 7, -1, -1, 26},
 
     /* For all other modes, for which we don't support VANC */
     {bmdModeUnknown, 0, -1, -1, -1}
@@ -149,6 +148,30 @@ 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 / 6; i++) {
+        *dst++ =  src[0]       + ((src[1] & 3)  << 8);
+        *dst++ = (src[1] >> 2) + ((src[2] & 15) << 6);
+        *dst++ = (src[2] >> 4) + ((src[3] & 63) << 4);
+
+        *dst++ =  src[4]       + ((src[5] & 3)  << 8);
+        *dst++ = (src[5] >> 2) + ((src[6] & 15) << 6);
+        *dst++ = (src[6] >> 4) + ((src[7] & 63) << 4);
+
+        *dst++ =  src[8]       + ((src[9] & 3)  << 8);
+        *dst++ = (src[9] >> 2) + ((src[10] & 15) << 6);
+        *dst++ = (src[10] >> 4) + ((src[11] & 63) << 4);
+
+        *dst++ =  src[12]       + ((src[13] & 3)  << 8);
+        *dst++ = (src[13] >> 2) + ((src[14] & 15) << 6);
+        *dst++ = (src[14] >> 4) + ((src[15] & 63) << 4);
+
+        src += 16;
+    }
+}
+
 static uint8_t calc_parity_and_line_offset(int line)
 {
     uint8_t ret = (line < 313) << 5;
@@ -741,7 +764,11 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
                         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());
+                            if (ctx->bmd_mode == bmdModeNTSC) {
+                              unpack_v210(luma_vanc, buf, videoFrame->GetWidth());
+                            } else {
+                              extract_luma_from_v210(luma_vanc, buf, videoFrame->GetWidth());
+                            }
                             txt_buf = get_metadata(avctx, luma_vanc, videoFrame->GetWidth(),
                                                    txt_buf, sizeof(txt_buf0) - (txt_buf - txt_buf0), &pkt);
                         }
-- 
2.7.4



More information about the ffmpeg-devel mailing list