In preparation to support multiple VANC data decode
Showing the changes to libavdevice/decklink_dec.cpp (1 of 1 file). Show all
Unified · Split
| @@ -46,6 +46,8 @@ extern "C" { · 45 unmodified lines | ||
| 46 | 46 | #include "decklink_common.h" |
| 47 | 47 | #include "decklink_dec.h" |
| 48 | 48 | |
| 49 | +#define MAX_WIDTH_VANC 1920 | |
| 50 | + | |
| 49 | 51 | typedef struct VANCLineNumber { |
| 50 | 52 | BMDDisplayMode mode; |
| 51 | 53 | int vanc_start; |
| @@ -103,6 +105,18 @@ static int get_vanc_line_idx(BMDDisplayMode mode) · 51 unmodified lines | ||
| 103 | 105 | return i - 1; |
| 104 | 106 | } |
| 105 | 107 | |
| 108 | +/* The 10-bit VANC data is packed in V210, we only need the luma component. */ | |
| 109 | +static void extract_luma_from_v210(uint16_t *dst, const uint8_t *src, int width) | |
| 110 | +{ | |
| 111 | + int i; | |
| 112 | + for (i = 0; i < width / 3; i += 3) { | |
| 113 | + *dst++ = (src[1] >> 2) + ((src[2] & 15) << 6); | |
| 114 | + *dst++ = src[4] + ((src[5] & 3) << 8); | |
| 115 | + *dst++ = (src[6] >> 4) + ((src[7] & 63) << 4); | |
| 116 | + src += 8; | |
| 117 | + } | |
| 118 | +} | |
| 119 | + | |
| 106 | 120 | static uint8_t calc_parity_and_line_offset(int line) |
| 107 | 121 | { |
| 108 | 122 | uint8_t ret = (line < 313) << 5; |
| @@ -218,19 +232,10 @@ static uint8_t* teletext_data_unit_from_ancillary_packet(uint16_t *py, uint16_t · 109 unmodified lines | ||
| 218 | 232 | return tgt; |
| 219 | 233 | } |
| 220 | 234 | |
| 221 | −static uint8_t* teletext_data_unit_from_vanc_data(uint8_t *src, uint8_t *tgt, int64_t wanted_lines) | |
| 235 | +static uint8_t* teletext_data_unit_from_vanc_data(uint16_t *py, uint8_t *tgt, int64_t wanted_lines) | |
| 222 | 236 | { |
| 223 | − uint16_t y[1920]; | |
| 224 | − uint16_t *py = y; | |
| 225 | − uint16_t *pend = y + 1920; | |
| 226 | − /* The 10-bit VANC data is packed in V210, we only need the luma component. */ | |
| 227 | − while (py < pend) { | |
| 228 | − *py++ = (src[1] >> 2) + ((src[2] & 15) << 6); | |
| 229 | − *py++ = src[4] + ((src[5] & 3) << 8); | |
| 230 | − *py++ = (src[6] >> 4) + ((src[7] & 63) << 4); | |
| 231 | − src += 8; | |
| 232 | − } | |
| 233 | − py = y; | |
| 237 | + uint16_t *pend = py + 1920; | |
| 238 | + | |
| 234 | 239 | while (py < pend - 6) { |
| 235 | 240 | if (py[0] == 0 && py[1] == 0x3ff && py[2] == 0x3ff) { // ancillary data flag |
| 236 | 241 | py += 3; |
| @@ -559,13 +564,15 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( · 322 unmodified lines | ||
| 559 | 564 | } |
| 560 | 565 | } |
| 561 | 566 | #endif |
| 562 | − if (vanc_format == bmdFormat10BitYUV) { | |
| 567 | + if (vanc_format == bmdFormat10BitYUV && videoFrame->GetWidth() <= MAX_WIDTH_VANC) { | |
| 563 | 568 | int idx = get_vanc_line_idx(ctx->bmd_mode); |
| 564 | 569 | for (i = vanc_line_numbers[idx].vanc_start; i <= vanc_line_numbers[idx].vanc_end; i++) { |
| 565 | 570 | uint8_t *buf; |
| 566 | 571 | if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) { |
| 572 | + uint16_t luma_vanc[MAX_WIDTH_VANC]; | |
| 573 | + extract_luma_from_v210(luma_vanc, buf, videoFrame->GetWidth()); | |
| 567 | 574 | if (videoFrame->GetWidth() == 1920) { |
| 568 | − txt_buf = teletext_data_unit_from_vanc_data(buf, txt_buf, ctx->teletext_lines); | |
| 575 | + txt_buf = teletext_data_unit_from_vanc_data(luma_vanc, txt_buf, ctx->teletext_lines); | |
| 569 | 576 | if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer |
| 570 | 577 | av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); |
| 571 | 578 | break; |