| 590 | } |
| 591 | |
| 592 | static int decklink_construct_vanc(AVFormatContext *avctx, struct decklink_ctx *ctx, |
| 593 | AVPacket *pkt, decklink_frame *frame, |
| 594 | AVStream *st) |
| 595 | { |
| 596 | struct klvanc_line_set_s vanc_lines = { 0 }; |
| 597 | int ret = 0, i; |
| 598 | |
| 599 | if (!ctx->supports_vanc) |
| 600 | return 0; |
| 601 | |
| 602 | parse_608subs(avctx, ctx, pkt); |
| 603 | construct_cc(avctx, ctx, pkt, &vanc_lines); |
| 604 | construct_afd(avctx, ctx, pkt, &vanc_lines, st); |
| 605 | |
| 606 | /* See if there any pending data packets to process */ |
| 607 | while (ff_decklink_packet_queue_size(&ctx->vanc_queue) > 0) { |
| 608 | AVStream *vanc_st; |
| 609 | AVPacket vanc_pkt; |
| 610 | int64_t pts; |
| 611 | |
| 612 | pts = ff_decklink_packet_queue_peekpts(&ctx->vanc_queue); |
| 613 | if (pts > ctx->last_pts) { |
| 614 | /* We haven't gotten to the video frame we are supposed to inject |
| 615 | the oldest VANC packet into yet, so leave it on the queue... */ |
| 616 | break; |
| 617 | } |
| 618 | |
| 619 | ret = ff_decklink_packet_queue_get(&ctx->vanc_queue, &vanc_pkt, 1); |
| 620 | if (vanc_pkt.pts + 1 < ctx->last_pts) { |
| 621 | av_log(avctx, AV_LOG_WARNING, "VANC packet too old, throwing away\n"); |
| 622 | av_packet_unref(&vanc_pkt); |
| 623 | continue; |
| 624 | } |
| 625 | |
| 626 | vanc_st = avctx->streams[vanc_pkt.stream_index]; |
| 627 | if (vanc_st->codecpar->codec_id == AV_CODEC_ID_SMPTE_2038) { |
| 628 | struct klvanc_smpte2038_anc_data_packet_s *pkt_2038 = NULL; |
| 629 | |
| 630 | klvanc_smpte2038_parse_pes_payload(vanc_pkt.data, vanc_pkt.size, &pkt_2038); |
| 631 | if (pkt_2038 == NULL) { |
| 632 | av_log(avctx, AV_LOG_ERROR, "failed to decode SMPTE 2038 PES packet"); |
| 633 | av_packet_unref(&vanc_pkt); |
| 634 | continue; |
| 635 | } |
| 636 | for (int i = 0; i < pkt_2038->lineCount; i++) { |
| 637 | struct klvanc_smpte2038_anc_data_line_s *l = &pkt_2038->lines[i]; |
| 638 | uint16_t *vancWords = NULL; |
| 639 | uint16_t vancWordCount; |
| 640 | |
| 641 | if (klvanc_smpte2038_convert_line_to_words(l, &vancWords, |
| 642 | &vancWordCount) < 0) |
| 643 | break; |
| 644 | |
| 645 | ret = klvanc_line_insert(ctx->vanc_ctx, &vanc_lines, vancWords, |
| 646 | vancWordCount, l->line_number, 0); |
| 647 | free(vancWords); |
| 648 | if (ret != 0) { |
| 649 | av_log(avctx, AV_LOG_ERROR, "VANC line insertion failed\n"); |
no test coverage detected