On Thu, 31 Aug 2017, kjeya...@akamai.com wrote:

From: Karthick J <kjeya...@akamai.com>

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

Signed-off-by: Karthick J <kjeya...@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 */

That may well be true, but SMPTE 334M recommands to use lines "from the second line after the line specified for switching to the last line preceding active video, inclusive", so I'd skip at least the lines up to the switching line, in order not to decode stuff which in fact belongs to another source... And since we already keeping track of VANC line numbers for each mode, it's almost no extra code to do this properly.

+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,

you can use BMDFieldDominance type for the first argument.

+                           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;
+    }
+}

Instead of all the getter functions, I think it is simpler to create struct for a mode/field combination, and use an array to store the mode line settings. Then you can loop through the array and find your settings.

+
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();

Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to