In preparation to make VANC decode modular, to support multiple other VANC data.
Showing the changes to libavdevice/decklink_dec.cpp (1 of 1 file). Show all
Unified · Split
| @@ -46,6 +46,63 @@ extern "C" { · 45 unmodified lines | ||
| 46 | 46 | #include "decklink_common.h" |
| 47 | 47 | #include "decklink_dec.h" |
| 48 | 48 | |
| 49 | +typedef struct VANCLineNumber { | |
| 50 | + BMDDisplayMode mode; | |
| 51 | + int vanc_start; | |
| 52 | + int field0_vanc_end; | |
| 53 | + int field1_vanc_start; | |
| 54 | + int vanc_end; | |
| 55 | +} VANCLineNumber; | |
| 56 | + | |
| 57 | +/* These VANC line numbers need not be very accurate. In any case | |
| 58 | + * GetBufferForVerticalBlankingLine() will return an error when invalid | |
| 59 | + * ancillary line number was requested. We just need to make sure that the | |
| 60 | + * entire VANC region is covered, while making sure we don't decode VANC of | |
| 61 | + * another source during switching*/ | |
| 62 | +static VANCLineNumber vanc_line_numbers[] = { | |
| 63 | + /* SD Modes */ | |
| 64 | + | |
| 65 | + {bmdModeNTSC, 11, 19, 274, 282}, | |
| 66 | + {bmdModeNTSC2398, 11, 19, 274, 282}, | |
| 67 | + {bmdModePAL, 7, 22, 320, 335}, | |
| 68 | + {bmdModeNTSCp, 11, -1, -1, 39}, | |
| 69 | + {bmdModePALp, 7, -1, -1, 45}, | |
| 70 | + | |
| 71 | + /* HD 1080 Modes */ | |
| 72 | + | |
| 73 | + {bmdModeHD1080p2398, 8, -1, -1, 42}, | |
| 74 | + {bmdModeHD1080p24, 8, -1, -1, 42}, | |
| 75 | + {bmdModeHD1080p25, 8, -1, -1, 42}, | |
| 76 | + {bmdModeHD1080p2997, 8, -1, -1, 42}, | |
| 77 | + {bmdModeHD1080p30, 8, -1, -1, 42}, | |
| 78 | + {bmdModeHD1080i50, 8, 20, 570, 585}, | |
| 79 | + {bmdModeHD1080i5994, 8, 20, 570, 585}, | |
| 80 | + {bmdModeHD1080i6000, 8, 20, 570, 585}, | |
| 81 | + {bmdModeHD1080p50, 8, -1, -1, 42}, | |
| 82 | + {bmdModeHD1080p5994, 8, -1, -1, 42}, | |
| 83 | + {bmdModeHD1080p6000, 8, -1, -1, 42}, | |
| 84 | + | |
| 85 | + /* HD 720 Modes */ | |
| 86 | + | |
| 87 | + {bmdModeHD720p50, 8, -1, -1, 26}, | |
| 88 | + {bmdModeHD720p5994, 8, -1, -1, 26}, | |
| 89 | + {bmdModeHD720p60, 8, -1, -1, 26}, | |
| 90 | + | |
| 91 | + /* For all other modes, for which we don't support VANC */ | |
| 92 | + {bmdModeUnknown, 0, -1, -1, -1} | |
| 93 | +}; | |
| 94 | + | |
| 95 | +static int get_vanc_line_idx(BMDDisplayMode mode) | |
| 96 | +{ | |
| 97 | + unsigned int i; | |
| 98 | + for (i = 0; i < FF_ARRAY_ELEMS(vanc_line_numbers); i++) { | |
| 99 | + if (mode == vanc_line_numbers[i].mode) | |
| 100 | + return i; | |
| 101 | + } | |
| 102 | + /* Return the VANC idx for Unknown mode */ | |
| 103 | + return i - 1; | |
| 104 | +} | |
| 105 | + | |
| 49 | 106 | static uint8_t calc_parity_and_line_offset(int line) |
| 50 | 107 | { |
| 51 | 108 | uint8_t ret = (line < 313) << 5; |
| @@ -502,18 +559,21 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( · 450 unmodified lines | ||
| 502 | 559 | } |
| 503 | 560 | } |
| 504 | 561 | #endif |
| 505 | − if (videoFrame->GetWidth() == 1920 && vanc_format == bmdFormat10BitYUV) { | |
| 506 | − int first_active_line = ctx->bmd_field_dominance == bmdProgressiveFrame ? 42 : 584; | |
| 507 | − for (i = 8; i < first_active_line; i++) { | |
| 562 | + if (vanc_format == bmdFormat10BitYUV) { | |
| 563 | + int idx = get_vanc_line_idx(ctx->bmd_mode); | |
| 564 | + for (i = vanc_line_numbers[idx].vanc_start; i <= vanc_line_numbers[idx].vanc_end; i++) { | |
| 508 | 565 | uint8_t *buf; |
| 509 | − if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) | |
| 510 | − txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines); | |
| 511 | − if (ctx->bmd_field_dominance != bmdProgressiveFrame && i == 20) // skip field1 active lines | |
| 512 | − i = 569; | |
| 513 | − if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer | |
| 514 | − av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); | |
| 515 | − break; | |
| 566 | + if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) { | |
| 567 | + if (videoFrame->GetWidth() == 1920) { | |
| 568 | + txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines); | |
| 569 | + if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer | |
| 570 | + av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); | |
| 571 | + break; | |
| 572 | + } | |
| 573 | + } | |
| 516 | 574 | } |
| 575 | + if (i == vanc_line_numbers[idx].field0_vanc_end) | |
| 576 | + i = vanc_line_numbers[idx].field1_vanc_start - 1; | |
| 517 | 577 | } |
| 518 | 578 | } |
| 519 | 579 | vanc->Release(); |