| @@ -345,6 +345,25 @@ static int decklink_setup_subtitle(AVFormatContext *avctx, AVStream *st) · 344 unmodified lines |
| 345 | return ret; | 345 | return ret; |
| 346 | } | 346 | } |
| 347 | | 347 | |
| | 348 | static int decklink_setup_data(AVFormatContext *avctx, AVStream *st) |
| | 349 | { |
| | 350 | int ret = -1; |
| | 351 | |
| | 352 | switch(st->codecpar->codec_id) { |
| | 353 | #if CONFIG_LIBKLVANC |
| | 354 | case AV_CODEC_ID_SMPTE_2038: |
| | 355 | /* No specific setup required */ |
| | 356 | ret = 0; |
| | 357 | break; |
| | 358 | #endif |
| | 359 | default: |
| | 360 | av_log(avctx, AV_LOG_ERROR, "Unsupported data codec specified\n"); |
| | 361 | break; |
| | 362 | } |
| | 363 | |
| | 364 | return ret; |
| | 365 | } |
| | 366 | |
| 348 | av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) | 367 | av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) |
| 349 | { | 368 | { |
| 350 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; | 369 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; |
| @@ -370,6 +389,7 @@ av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) · 19 unmodified lines |
| 370 | #if CONFIG_LIBKLVANC | 389 | #if CONFIG_LIBKLVANC |
| 371 | klvanc_context_destroy(ctx->vanc_ctx); | 390 | klvanc_context_destroy(ctx->vanc_ctx); |
| 372 | #endif | 391 | #endif |
| | 392 | ff_decklink_packet_queue_end(&ctx->vanc_queue); |
| 373 | | 393 | |
| 374 | ff_ccfifo_uninit(&ctx->cc_fifo); | 394 | ff_ccfifo_uninit(&ctx->cc_fifo); |
| 375 | av_freep(&cctx->ctx); | 395 | av_freep(&cctx->ctx); |
| @@ -552,6 +572,58 @@ static int decklink_construct_vanc(AVFormatContext *avctx, struct decklink_ctx * · 176 unmodified lines |
| 552 | construct_cc(avctx, ctx, pkt, &vanc_lines); | 572 | construct_cc(avctx, ctx, pkt, &vanc_lines); |
| 553 | construct_afd(avctx, ctx, pkt, &vanc_lines, st); | 573 | construct_afd(avctx, ctx, pkt, &vanc_lines, st); |
| 554 | | 574 | |
| | 575 | /* See if there any pending data packets to process */ |
| | 576 | while (ff_decklink_packet_queue_size(&ctx->vanc_queue) > 0) { |
| | 577 | AVStream *vanc_st; |
| | 578 | AVPacket vanc_pkt; |
| | 579 | int64_t pts; |
| | 580 | |
| | 581 | pts = ff_decklink_packet_queue_peekpts(&ctx->vanc_queue); |
| | 582 | if (pts > ctx->last_pts) { |
| | 583 | /* We haven't gotten to the video frame we are supposed to inject |
| | 584 | the oldest VANC packet into yet, so leave it on the queue... */ |
| | 585 | break; |
| | 586 | } |
| | 587 | |
| | 588 | ret = ff_decklink_packet_queue_get(&ctx->vanc_queue, &vanc_pkt, 1); |
| | 589 | if (vanc_pkt.pts + 1 < ctx->last_pts) { |
| | 590 | av_log(avctx, AV_LOG_WARNING, "VANC packet too old, throwing away\n"); |
| | 591 | av_packet_unref(&vanc_pkt); |
| | 592 | continue; |
| | 593 | } |
| | 594 | |
| | 595 | vanc_st = avctx->streams[vanc_pkt.stream_index]; |
| | 596 | if (vanc_st->codecpar->codec_id == AV_CODEC_ID_SMPTE_2038) { |
| | 597 | struct klvanc_smpte2038_anc_data_packet_s *pkt_2038 = NULL; |
| | 598 | |
| | 599 | klvanc_smpte2038_parse_pes_payload(vanc_pkt.data, vanc_pkt.size, &pkt_2038); |
| | 600 | if (pkt_2038 == NULL) { |
| | 601 | av_log(avctx, AV_LOG_ERROR, "failed to decode SMPTE 2038 PES packet"); |
| | 602 | av_packet_unref(&vanc_pkt); |
| | 603 | continue; |
| | 604 | } |
| | 605 | for (int i = 0; i < pkt_2038->lineCount; i++) { |
| | 606 | struct klvanc_smpte2038_anc_data_line_s *l = &pkt_2038->lines[i]; |
| | 607 | uint16_t *vancWords = NULL; |
| | 608 | uint16_t vancWordCount; |
| | 609 | |
| | 610 | if (klvanc_smpte2038_convert_line_to_words(l, &vancWords, |
| | 611 | &vancWordCount) < 0) |
| | 612 | break; |
| | 613 | |
| | 614 | ret = klvanc_line_insert(ctx->vanc_ctx, &vanc_lines, vancWords, |
| | 615 | vancWordCount, l->line_number, 0); |
| | 616 | free(vancWords); |
| | 617 | if (ret != 0) { |
| | 618 | av_log(avctx, AV_LOG_ERROR, "VANC line insertion failed\n"); |
| | 619 | break; |
| | 620 | } |
| | 621 | } |
| | 622 | klvanc_smpte2038_anc_data_packet_free(pkt_2038); |
| | 623 | } |
| | 624 | av_packet_unref(&vanc_pkt); |
| | 625 | } |
| | 626 | |
| 555 | IDeckLinkVideoFrameAncillary *vanc; | 627 | IDeckLinkVideoFrameAncillary *vanc; |
| 556 | int result = ctx->dlo->CreateAncillaryData(bmdFormat10BitYUV, &vanc); | 628 | int result = ctx->dlo->CreateAncillaryData(bmdFormat10BitYUV, &vanc); |
| 557 | if (result != S_OK) { | 629 | if (result != S_OK) { |
| @@ -750,6 +822,18 @@ static int decklink_write_subtitle_packet(AVFormatContext *avctx, AVPacket *pkt) · 192 unmodified lines |
| 750 | return 0; | 822 | return 0; |
| 751 | } | 823 | } |
| 752 | | 824 | |
| | 825 | static int decklink_write_data_packet(AVFormatContext *avctx, AVPacket *pkt) |
| | 826 | { |
| | 827 | struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; |
| | 828 | struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; |
| | 829 | |
| | 830 | if (ff_decklink_packet_queue_put(&ctx->vanc_queue, pkt) < 0) { |
| | 831 | av_log(avctx, AV_LOG_WARNING, "Failed to queue DATA packet\n"); |
| | 832 | } |
| | 833 | |
| | 834 | return 0; |
| | 835 | } |
| | 836 | |
| 753 | extern "C" { | 837 | extern "C" { |
| 754 | | 838 | |
| 755 | av_cold int ff_decklink_write_header(AVFormatContext *avctx) | 839 | av_cold int ff_decklink_write_header(AVFormatContext *avctx) |
| @@ -814,6 +898,9 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) · 58 unmodified lines |
| 814 | } else if (c->codec_type == AVMEDIA_TYPE_VIDEO) { | 898 | } else if (c->codec_type == AVMEDIA_TYPE_VIDEO) { |
| 815 | if (decklink_setup_video(avctx, st)) | 899 | if (decklink_setup_video(avctx, st)) |
| 816 | goto error; | 900 | goto error; |
| | 901 | } else if (c->codec_type == AVMEDIA_TYPE_DATA) { |
| | 902 | if (decklink_setup_data(avctx, st)) |
| | 903 | goto error; |
| 817 | } else if (c->codec_type == AVMEDIA_TYPE_SUBTITLE) { | 904 | } else if (c->codec_type == AVMEDIA_TYPE_SUBTITLE) { |
| 818 | if (decklink_setup_subtitle(avctx, st)) | 905 | if (decklink_setup_subtitle(avctx, st)) |
| 819 | goto error; | 906 | goto error; |
| @@ -823,13 +910,16 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) · 3 unmodified lines |
| 823 | } | 910 | } |
| 824 | } | 911 | } |
| 825 | | 912 | |
| | 913 | /* Reconfigure the data/subtitle stream clocks to match the video */ |
| 826 | for (n = 0; n < avctx->nb_streams; n++) { | 914 | for (n = 0; n < avctx->nb_streams; n++) { |
| 827 | AVStream *st = avctx->streams[n]; | 915 | AVStream *st = avctx->streams[n]; |
| 828 | AVCodecParameters *c = st->codecpar; | 916 | AVCodecParameters *c = st->codecpar; |
| 829 | | 917 | |
| 830 | if(c->codec_type == AVMEDIA_TYPE_SUBTITLE) | 918 | if(c->codec_type == AVMEDIA_TYPE_DATA || |
| | 919 | c->codec_type == AVMEDIA_TYPE_SUBTITLE) |
| 831 | avpriv_set_pts_info(st, 64, ctx->bmd_tb_num, ctx->bmd_tb_den); | 920 | avpriv_set_pts_info(st, 64, ctx->bmd_tb_num, ctx->bmd_tb_den); |
| 832 | } | 921 | } |
| | 922 | ff_decklink_packet_queue_init(avctx, &ctx->vanc_queue, cctx->vanc_queue_size); |
| 833 | | 923 | |
| 834 | ret = ff_ccfifo_init(&ctx->cc_fifo, av_make_q(ctx->bmd_tb_den, ctx->bmd_tb_num), avctx); | 924 | ret = ff_ccfifo_init(&ctx->cc_fifo, av_make_q(ctx->bmd_tb_den, ctx->bmd_tb_num), avctx); |
| 835 | if (ret < 0) { | 925 | if (ret < 0) { |
| @@ -852,6 +942,8 @@ int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt) · 16 unmodified lines |
| 852 | return decklink_write_video_packet(avctx, pkt); | 942 | return decklink_write_video_packet(avctx, pkt); |
| 853 | else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) | 943 | else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) |
| 854 | return decklink_write_audio_packet(avctx, pkt); | 944 | return decklink_write_audio_packet(avctx, pkt); |
| | 945 | else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) |
| | 946 | return decklink_write_data_packet(avctx, pkt); |
| 855 | else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) | 947 | else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) |
| 856 | return decklink_write_subtitle_packet(avctx, pkt); | 948 | return decklink_write_subtitle_packet(avctx, pkt); |
| 857 | | 949 | |