From patchwork Fri Dec 29 18:12:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 7020 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.79.195 with SMTP id r64csp10785981jad; Fri, 29 Dec 2017 10:13:39 -0800 (PST) X-Google-Smtp-Source: ACJfBot2di0h/zj9LzHy2Jf6ZNN+5J6hlWAnRwKKF1UTfbUVXaTr+chdF7IxN6fDEA2FPBlLXH7o X-Received: by 10.223.175.239 with SMTP id y47mr31487544wrd.207.1514571219040; Fri, 29 Dec 2017 10:13:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1514571219; cv=none; d=google.com; s=arc-20160816; b=YWxDwy5tN0y9q/XKeiqcX8/4ZNWbHpPM00BpPlQybcnfI1n/NBvDV4GD+Y4rjDqpYb FI5ztXC6nPu6Ep6ewBf/UgI3UZYqjjwzsyAI0wWxi1LXagVlZz+8mgRbD8baKJv34k82 X6rb/LfXWY1aOuCDi9eGX7TzE4HeeWB5RtHcN0H3CtWicI4FCA3QHVpThlrNBxQP/yWT yedkl3SII7u88H+7olMdT6BUTnoVEJ606naBFLDtm/OfOo301o7szk8zS/VJIgRCbzcC a+0CgPracEfNlu8xoEKUlftFUVUwTN3h66dNBK0QjBJeSou8WxJxM8mN3qPEVYVIwiWt kHRA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:delivered-to:arc-authentication-results; bh=Dds5HadzgqpLtNDCX1EAp6f/1TOamwKONIKPMUnnq9g=; b=0SJ4AiQrIKLF2ROJ4MQzxdgr51wIoZmpq+9lWflVuS4LZs6SSHvkM1xaB9zigRSQ7J torDwMDEouFQd9n3mdYPbSRlSChaICAiG+pih8JNFen+eCVLSATr+CORyyhKPtnBFWLo reEfN2/m7rAkaqxBSO2HHlKmGoV2iFUSFlYeW/1fKv4Pc+A9AMMUVLpqVtRROHpzap9g 1U5yl+2byfIZocPCiQjEYlH45DakKxbK13V7wcLqaBN+9VkDYt6QBlgdCCzEIFE7nCs4 NxiXLnI6if27FbpjRg9NofBkLPXUex1w/7YpzB6ZU5uJf8W1ce7D97ykYNYVmkx6GVvG /9JA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o8si16562204wmi.239.2017.12.29.10.13.38; Fri, 29 Dec 2017 10:13:39 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 56300689C1B; Fri, 29 Dec 2017 20:12:46 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from was-smtp1.livetimenet.net (50-206-97-56-static.hfc.comcastbusiness.net [50.206.97.56]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C3B69689B83 for ; Fri, 29 Dec 2017 20:12:43 +0200 (EET) Received: by was-smtp1.livetimenet.net with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.84_2) (envelope-from ) id 1eUz9L-0002Cw-QV; Fri, 29 Dec 2017 13:12:57 -0500 From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Fri, 29 Dec 2017 13:12:29 -0500 Message-Id: <20171229181230.99473-8-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 2.13.2 In-Reply-To: <20171229181230.99473-1-dheitmueller@ltnglobal.com> References: <20171229181230.99473-1-dheitmueller@ltnglobal.com> X-Spam-Score: -1.9 (-) Subject: [FFmpeg-devel] [PATCH 7/8] decklink: Add support for SCTE-104 to decklink capture X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: jgreen@ltnglobal.com, Devin Heitmueller MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Make use of libklvanc to parse SCTE-104 packets and announce them as a new stream. Right now we just pass the payload straight through, but once this is hoooked into libklscte35 we'll be able to generate SCTE-35 messages in the MPEG TS stream. Note that this feature needs to be explicitly enabled by the user through the "-enable_scte_104" option, since we cannot autodetect the presence of SCTE-104 (because unlike with 708/AFD messages are not set except when trigger occurs, thus the stream wouldn't get created during the read_header phase). Updated to reflect feedback from Derek Buitenhuis Signed-off-by: Devin Heitmueller --- libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 6 ++++ libavdevice/decklink_common.h | 6 ++++ libavdevice/decklink_common_c.h | 1 + libavdevice/decklink_dec.cpp | 61 ++++++++++++++++++++++++++++++++++++++++- libavdevice/decklink_dec_c.c | 1 + libavdevice/version.h | 2 +- 7 files changed, 76 insertions(+), 2 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 4f7b6df09d..2b4a0bd669 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -668,6 +668,7 @@ enum AVCodecID { AV_CODEC_ID_TTF = 0x18000, AV_CODEC_ID_SCTE_35, ///< Contain timestamp estimated through PCR of program stream. + AV_CODEC_ID_SCTE_104, AV_CODEC_ID_BINTEXT = 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index c3688de1d6..e198985bb4 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -3103,6 +3103,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "scte_35", .long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), }, + { + .id = AV_CODEC_ID_SCTE_104, + .type = AVMEDIA_TYPE_DATA, + .name = "scte_104", + .long_name = NULL_IF_CONFIG_SMALL("SCTE 104 Digital Program Insertion"), + }, /* deprecated codec ids */ }; diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 06b241029e..4d2052ea79 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -41,6 +41,10 @@ Actual number for any particular model of card may be lower */ #define DECKLINK_MAX_AUDIO_CHANNELS 32 +/* This isn't actually tied to the Blackmagic hardware - it's an arbitrary + number used to size the array of streams */ +#define DECKLINK_MAX_DATA_STREAMS 16 + class decklink_output_callback; class decklink_input_callback; @@ -92,6 +96,8 @@ struct decklink_ctx { unsigned int dropped; AVStream *audio_st[DECKLINK_MAX_AUDIO_CHANNELS]; int num_audio_streams; + AVStream *data_st[DECKLINK_MAX_DATA_STREAMS]; + int num_data_streams; AVStream *video_st; AVStream *teletext_st; uint16_t cdp_sequence_num; diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index 02011ed53b..cb73ec990b 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -58,6 +58,7 @@ struct decklink_cctx { char *format_code; int raw_format; int64_t queue_size; + int enable_scte_104; }; #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 86db6d8fbd..f3f0d989bf 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -672,6 +672,30 @@ error: return ret; } +static int setup_data(AVFormatContext *avctx) +{ + struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; + struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; + AVStream *st; + + if (cctx->enable_scte_104) { + st = avformat_new_stream(avctx, NULL); + if (!st) { + av_log(avctx, AV_LOG_ERROR, "Cannot add data stream\n"); + return AVERROR(ENOMEM); + } + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; + st->time_base.den = ctx->bmd_tb_den; + st->time_base.num = ctx->bmd_tb_num; + st->codecpar->codec_id = AV_CODEC_ID_SCTE_104; + avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ + ctx->data_st[ctx->num_data_streams] = st; + ctx->num_data_streams++; + } + + return 0; +} + #if CONFIG_LIBKLVANC /* VANC Callbacks */ struct vanc_cb_ctx { @@ -731,12 +755,44 @@ static int cb_EIA_708B(void *callback_context, struct klvanc_context_s *ctx, return 0; } +static int cb_SCTE_104(void *callback_context, struct klvanc_context_s *ctx, + struct klvanc_packet_scte_104_s *pkt) +{ + struct vanc_cb_ctx *cb_ctx = (struct vanc_cb_ctx *)callback_context; + decklink_cctx *decklink_cctx = (struct decklink_cctx *)cb_ctx->avctx->priv_data; + struct decklink_ctx *decklink_ctx = (struct decklink_ctx *)decklink_cctx->ctx; + AVPacket avpkt; + av_init_packet(&avpkt); + + avpkt.stream_index = -1; + for (int i = 0; i < decklink_ctx->num_data_streams; i++) { + if (decklink_ctx->data_st[i]->codecpar->codec_id = AV_CODEC_ID_SCTE_104) { + avpkt.stream_index = decklink_ctx->data_st[i]->index; + break; + } + } + if (avpkt.stream_index == -1) { + /* SCTE-104 packet received but forwarding is disabled */ + return 0; + } + + avpkt.pts = cb_ctx->pkt->pts; + avpkt.dts = cb_ctx->pkt->dts; + avpkt.data = pkt->payload; + avpkt.size = pkt->payloadLengthBytes; + if (avpacket_queue_put(&decklink_ctx->queue, &avpkt) < 0) { + ++decklink_ctx->dropped; + } + + return 0; +} + static struct klvanc_callbacks_s callbacks = { cb_AFD, cb_EIA_708B, NULL, - NULL, + cb_SCTE_104, NULL, NULL, }; @@ -1285,6 +1341,9 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) ctx->teletext_st = st; } + /* Setup streams. */ + setup_data(avctx); + if (cctx->audio_mode == AUDIO_MODE_DISCRETE) { av_log(avctx, AV_LOG_VERBOSE, "Using %d input audio channels\n", ctx->audio_st[0]->codecpar->channels); result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index d3d8c848cf..122da08fa1 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -76,6 +76,7 @@ static const AVOption options[] = { { "draw_bars", "draw bars on signal loss" , OFFSET(draw_bars), AV_OPT_TYPE_BOOL, { .i64 = 1}, 0, 1, DEC }, { "queue_size", "input queue buffer size", OFFSET(queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC }, { "audio_depth", "audio bitdepth (16 or 32)", OFFSET(audio_depth), AV_OPT_TYPE_INT, { .i64 = 16}, 16, 32, DEC }, + { "enable_scte_104", "capture SCTE-104 VANC", OFFSET(enable_scte_104), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC, "enable_scte_104"}, { NULL }, }; diff --git a/libavdevice/version.h b/libavdevice/version.h index 364404d65e..0d4477f82e 100644 --- a/libavdevice/version.h +++ b/libavdevice/version.h @@ -29,7 +29,7 @@ #define LIBAVDEVICE_VERSION_MAJOR 58 #define LIBAVDEVICE_VERSION_MINOR 0 -#define LIBAVDEVICE_VERSION_MICRO 100 +#define LIBAVDEVICE_VERSION_MICRO 101 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \