[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