[FFmpeg-devel] [PATCH 1/4] avdevice/decklink_dec: Added VANC search for all resolutions

kjeyapal at akamai.com kjeyapal at akamai.com
Thu Aug 31 11:36:47 EEST 2017


From: Karthick J <kjeyapal at akamai.com>

In preparation to make VANC decode modular, to support multiple other VANC data.

Signed-off-by: Karthick J <kjeyapal at akamai.com>
---
 libavdevice/decklink_dec.cpp | 86 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 76 insertions(+), 10 deletions(-)

diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index c271ff3..40ef655 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -46,6 +46,66 @@ extern "C" {
 #include "decklink_common.h"
 #include "decklink_dec.h"
 
+/* These VANC line numbers need not be very accurate. In any case
+ * GetBufferForVerticalBlankingLine() will return an error when invalid
+ * ancillary line number was requested. We just need to make sure that the
+ * entire VANC region is covered */
+static int get_vanc_lines_progressive (int height)
+{
+    switch (height) {
+    case 486:
+        return 39;
+    case 576:
+        return 45;
+    case 720:
+        return 30;
+    case 1080:
+        return 45;
+    default:
+        return 0;
+    }
+}
+
+static void get_vanc_lines_interlaced (int height, int *field0_vanc_end,
+                                       int *field1_vanc_start, int *field1_vanc_end)
+{
+    switch (height) {
+    // NTSC
+    case 486:
+        *field0_vanc_end = 19;
+        *field1_vanc_start = *field0_vanc_end + 243;
+        *field1_vanc_end = *field1_vanc_start + 20;
+        break;
+    // PAL
+    case 576:
+        *field0_vanc_end = 22;
+        *field1_vanc_start = *field0_vanc_end + 288 + 2;
+        *field1_vanc_end = *field1_vanc_start + 23;
+        break;
+    // 1080i
+    case 1080:
+        *field0_vanc_end = 20;
+        *field1_vanc_start = *field0_vanc_end + 540 + 2;
+        *field1_vanc_end = *field1_vanc_start + 21;
+        break;
+    default:
+        *field0_vanc_end = *field1_vanc_start = *field1_vanc_end = 0;
+    }
+}
+
+static void get_vanc_lines(int bmd_field_dominance, int height, int *field0_vanc_end,
+                           int *field1_vanc_start, int *vanc_end)
+{
+    if (bmd_field_dominance == bmdLowerFieldFirst || bmd_field_dominance == bmdUpperFieldFirst) {
+        get_vanc_lines_interlaced (height, field0_vanc_end, field1_vanc_start, vanc_end);
+    } else if (bmd_field_dominance == bmdProgressiveFrame) {
+        *vanc_end = get_vanc_lines_progressive(height);
+        *field0_vanc_end = *field1_vanc_start = -1;
+    } else {
+        *field0_vanc_end = *field1_vanc_start = *vanc_end = 0;
+    }
+}
+
 static uint8_t calc_parity_and_line_offset(int line)
 {
     uint8_t ret = (line < 313) << 5;
@@ -502,18 +562,24 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
                     }
                 }
 #endif
-                if (videoFrame->GetWidth() == 1920 && vanc_format == bmdFormat10BitYUV) {
-                    int first_active_line = ctx->bmd_field_dominance == bmdProgressiveFrame ? 42 : 584;
-                    for (i = 8; i < first_active_line; i++) {
+                if (vanc_format == bmdFormat10BitYUV) {
+                    int bmd_field_dominance, height;
+                    int field0_vanc_end, field1_vanc_start, vanc_end;
+                    get_vanc_lines(ctx->bmd_field_dominance, videoFrame->GetHeight(),
+                                   &field0_vanc_end, &field1_vanc_start, &vanc_end);
+                    for (i = 0; i <= vanc_end; i++) {
                         uint8_t *buf;
-                        if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK)
-                            txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines);
-                        if (ctx->bmd_field_dominance != bmdProgressiveFrame && i == 20)     // skip field1 active lines
-                            i = 569;
-                        if (txt_buf - txt_buf0 > 1611) {   // ensure we still have at least 1920 bytes free in the buffer
-                            av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n");
-                            break;
+                        if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) {
+                            if (videoFrame->GetWidth() == 1920) {
+                                txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines);
+                                if (txt_buf - txt_buf0 > 1611) {   // ensure we still have at least 1920 bytes free in the buffer
+                                    av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n");
+                                    break;
+                                }
+                            }
                         }
+                        if (i == field0_vanc_end)
+                            i = field1_vanc_start;
                     }
                 }
                 vanc->Release();
-- 
1.9.1



More information about the ffmpeg-devel mailing list