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 | #include "decklink_common.h" | 46 | #include "decklink_common.h" |
| 47 | #include "decklink_dec.h" | 47 | #include "decklink_dec.h" |
| 48 | 48 | ||
| 49 | #define MAX_WIDTH_VANC 1920 | ||
| 50 | |||
| 49 | typedef struct VANCLineNumber { | 51 | typedef struct VANCLineNumber { |
| 50 | BMDDisplayMode mode; | 52 | BMDDisplayMode mode; |
| 51 | int vanc_start; | 53 | int vanc_start; |
| @@ -103,6 +105,18 @@ static int get_vanc_line_idx(BMDDisplayMode mode) · 51 unmodified lines | |||
| 103 | return i - 1; | 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 | static uint8_t calc_parity_and_line_offset(int line) | 120 | static uint8_t calc_parity_and_line_offset(int line) |
| 107 | { | 121 | { |
| 108 | uint8_t ret = (line < 313) << 5; | 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 | return tgt; | 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]; | 237 | uint16_t *pend = py + 1920; |
| 224 | uint16_t *py = y; | 238 | |
| 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; | ||
| 234 | while (py < pend - 6) { | 239 | while (py < pend - 6) { |
| 235 | if (py[0] == 0 && py[1] == 0x3ff && py[2] == 0x3ff) { // ancillary data flag | 240 | if (py[0] == 0 && py[1] == 0x3ff && py[2] == 0x3ff) { // ancillary data flag |
| 236 | py += 3; | 241 | py += 3; |
| @@ -559,13 +564,15 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( · 322 unmodified lines | |||
| 559 | } | 564 | } |
| 560 | } | 565 | } |
| 561 | #endif | 566 | #endif |
| 562 | if (vanc_format == bmdFormat10BitYUV) { | 567 | if (vanc_format == bmdFormat10BitYUV && videoFrame->GetWidth() <= MAX_WIDTH_VANC) { |
| 563 | int idx = get_vanc_line_idx(ctx->bmd_mode); | 568 | 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++) { | 569 | for (i = vanc_line_numbers[idx].vanc_start; i <= vanc_line_numbers[idx].vanc_end; i++) { |
| 565 | uint8_t *buf; | 570 | uint8_t *buf; |
| 566 | if (vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) { | 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 | if (videoFrame->GetWidth() == 1920) { | 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 | if (txt_buf - txt_buf0 > 1611) { // ensure we still have at least 1920 bytes free in the buffer | 576 | 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"); | 577 | av_log(avctx, AV_LOG_ERROR, "Too many OP47 teletext packets.\n"); |
| 571 | break; | 578 | break; |