| 491 | |
| 492 | |
| 493 | static void handle_klv(AVFormatContext *avctx, decklink_ctx *ctx, IDeckLinkVideoInputFrame_v14_2_1 *videoFrame, int64_t pts) |
| 494 | { |
| 495 | const uint8_t KLV_DID = 0x44; |
| 496 | const uint8_t KLV_IN_VANC_SDID = 0x04; |
| 497 | |
| 498 | struct KLVPacket |
| 499 | { |
| 500 | uint16_t sequence_counter; |
| 501 | std::vector<uint8_t> data; |
| 502 | }; |
| 503 | |
| 504 | size_t total_size = 0; |
| 505 | std::vector<std::vector<KLVPacket>> klv_packets(256); |
| 506 | |
| 507 | IDeckLinkVideoFrameAncillaryPackets *packets = nullptr; |
| 508 | if (videoFrame->QueryInterface(IID_IDeckLinkVideoFrameAncillaryPackets, (void**)&packets) != S_OK) |
| 509 | return; |
| 510 | |
| 511 | IDeckLinkAncillaryPacketIterator *it = nullptr; |
| 512 | if (packets->GetPacketIterator(&it) != S_OK) { |
| 513 | packets->Release(); |
| 514 | return; |
| 515 | } |
| 516 | |
| 517 | IDeckLinkAncillaryPacket *packet = nullptr; |
| 518 | while (it->Next(&packet) == S_OK) { |
| 519 | uint8_t *data = nullptr; |
| 520 | uint32_t size = 0; |
| 521 | |
| 522 | if (packet->GetDID() == KLV_DID && packet->GetSDID() == KLV_IN_VANC_SDID) { |
| 523 | av_log(avctx, AV_LOG_DEBUG, "Found KLV VANC packet on line: %d\n", packet->GetLineNumber()); |
| 524 | |
| 525 | if (packet->GetBytes(bmdAncillaryPacketFormatUInt8, (const void**) &data, &size) == S_OK) { |
| 526 | // MID and PSC |
| 527 | if (size > 3) { |
| 528 | uint8_t mid = data[0]; |
| 529 | uint16_t psc = data[1] << 8 | data[2]; |
| 530 | |
| 531 | av_log(avctx, AV_LOG_DEBUG, "KLV with MID: %d and PSC: %d\n", mid, psc); |
| 532 | |
| 533 | auto& list = klv_packets[mid]; |
| 534 | uint16_t expected_psc = list.size() + 1; |
| 535 | |
| 536 | if (psc == expected_psc) { |
| 537 | uint32_t data_len = size - 3; |
| 538 | total_size += data_len; |
| 539 | |
| 540 | KLVPacket packet{ psc }; |
| 541 | packet.data.resize(data_len); |
| 542 | memcpy(packet.data.data(), data + 3, data_len); |
| 543 | |
| 544 | list.push_back(std::move(packet)); |
| 545 | } else { |
| 546 | av_log(avctx, AV_LOG_WARNING, "Out of order PSC: %d for MID: %d\n", psc, mid); |
| 547 | |
| 548 | if (!list.empty()) { |
| 549 | for (auto& klv : list) |
| 550 | total_size -= klv.data.size(); |
no test coverage detected