From patchwork Fri Jun 30 21:14:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 42348 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3b1e:b0:12b:9ae3:586d with SMTP id c30csp2779792pzh; Fri, 30 Jun 2023 13:17:04 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ54jVDP60yVOnejmLrskf2Qp3r6hhEjcp6HaumlrxCnehPcKi1UGsbJ8JkPEcnn+G8pxf0O X-Received: by 2002:a05:6402:3481:b0:51d:a5c6:37c1 with SMTP id v1-20020a056402348100b0051da5c637c1mr10699011edc.1.1688156224511; Fri, 30 Jun 2023 13:17:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688156224; cv=none; d=google.com; s=arc-20160816; b=keK3Wj1wIVNt0SDRZpHblcbc9RTC39UTDxocsaNjstSkVzXIW2HMLjWvLywKzQxaiA W43oIXLbvjMHAr4jCdBoMPGTBemZTMaUigZ+AvyptGYvrgM3H6yOsDZqMNDqG4JQMXDx A8Zfwm4DN1ea+yjWcgGurRXt/g/iPgqM7L3BDAfauQHSl/m743kxXLbYbbdJjyAiWGHd E1nN95KoroTt8cKYYJ8hrKDaSU/kPhtWvEsjjpAj5D6DTkc728iUMtHn6p0q5X2ShKLt mFYMw/abwUl5gI14MaR+MoOkN5njb5BGMBDe26oE68mRZ+SzDY5iReZ9Qj+k2HeRRb/j Bl/g== 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:message-id:date:to:from:dkim-signature :delivered-to; bh=5utsh7oSqGcIzVfnqR/lSCr7m8pBxrTKYZzl3VaQt/0=; fh=pXLAZvRiz3/uELcsWNfKAkJPgyV9/rr3Mrznj9KeXEo=; b=UojSqMsWKSqdXFmx1NLKM+m2QvdpLuC61IoReFRL2n1s+dQ9G1AgQqIcRvfabdhHvj RIzYwTMPKSTYUD5U6NjqDHnm4bg6T8hJVy9tfX271HNjW8BakbNYUJbcX2wxX1sPqU19 YDy/b7zEJWUR/bsQnirC2r8CB8WakthNafFkk+wAYsFK1B6351skDcBQNLdIKEYr9MOW lD3Yk7ONdQfT3kEPsif66u17/GZ70vEd41KJvfHHdjTv2hWYI3gR1ynWZCbToO7vFdUH 0oqWyiPGGR8mBN7mVkfAmT804NmShxPEG1Hr5kGz+krcVSEXgOcCsg9xNcik6ghz2F7E vIhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@ltnglobal-com.20221208.gappssmtp.com header.s=20221208 header.b=QY8dwg06; 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 u15-20020a056402064f00b0051df7f18d3esi640808edx.673.2023.06.30.13.17.03; Fri, 30 Jun 2023 13:17:04 -0700 (PDT) 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; dkim=neutral (body hash did not verify) header.i=@ltnglobal-com.20221208.gappssmtp.com header.s=20221208 header.b=QY8dwg06; 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 2035868C390; Fri, 30 Jun 2023 23:16:59 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oo1-f45.google.com (mail-oo1-f45.google.com [209.85.161.45]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A77C668C390 for ; Fri, 30 Jun 2023 23:16:52 +0300 (EEST) Received: by mail-oo1-f45.google.com with SMTP id 006d021491bc7-55b85b94bb0so1376606eaf.0 for ; Fri, 30 Jun 2023 13:16:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ltnglobal-com.20221208.gappssmtp.com; s=20221208; t=1688156210; x=1690748210; h=message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/qIOhQlM5ixR8HTa0eSLOhGGRVUByvfCDKOXGT6H9N4=; b=QY8dwg06VC2GW5LrQIDV1I13w3j2YVJQHIbkUPvc1m2plO3YZ1ryHPzwNUWRQRoQzQ x2WengS2rtjDbmLD4QbLkmCeArbTZU3/o29qfSdb3yckcdKz10uCrL4aJcBDwoLwoG1L +WGfonqltZMv4oqcbdXgev+2/IyxlLruOAIjWLaCSwgMLrJBQJWOZluee1ay34MuwQKB hO+6Z/XVULueYUCUqHFG8RJjVy1kpkIOH+tv8YqPRGWzoxE79A3Z45LvbrH6ATmTe5/H Qs+qzlADTNFFbfDQlAUKbF7FL6QlAicSU8kgFnvnMnDOUnyx4PyEDnJS9QBPZmCVhZTC rIHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688156210; x=1690748210; h=message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/qIOhQlM5ixR8HTa0eSLOhGGRVUByvfCDKOXGT6H9N4=; b=kohhTgqWYPdblUIgiW3UT57AehS/Xf0JsA3+xEpuXvtZ74CE7gARzSy3cin7J1PJvt H4/l3TLI7ZGyunuwf4Qhj0/c2dMbPMWB0pEDhl2XBuvtqrA1lokS0cO5xyy/DSvKh9U7 ftQ9g3ZitffEbUL96njOZmFwucz+XqGk7lmpFkmK6NDl7tiRP7FNFRYc39eNgpwGIyd/ iXPsSicm+hPHTGHruxy3xjK6WxFqHV/j/VBssj8PTWh6UjP15Cc7jUrJERpDAv7wYkGF pMVVqN3Nslvf6JcYk19okxUBB0OYA2GSUvI/bNS+4qjc6iaF6PVlac7IsFBntibY7nYx 5sbA== X-Gm-Message-State: ABy/qLY+mzwCoQe7wYpiI541GlU0FVW34yx1POaSEpGCnUu0pzRfyRVS zRsu4Yr5DdP1gY/rqLf/DUO2Pxk5jLUygGMVYd8= X-Received: by 2002:a05:6358:1a91:b0:134:d030:e5da with SMTP id gm17-20020a0563581a9100b00134d030e5damr1581710rwb.21.1688156210175; Fri, 30 Jun 2023 13:16:50 -0700 (PDT) Received: from ltnt-nyc-580testdevin.livetimenet.com (pool-71-105-132-214.nycmny.fios.verizon.net. [71.105.132.214]) by smtp.gmail.com with ESMTPSA id h12-20020ac8776c000000b003f9efa2ddb4sm2294999qtu.66.2023.06.30.13.16.49 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jun 2023 13:16:49 -0700 (PDT) From: Devin Heitmueller X-Google-Original-From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Fri, 30 Jun 2023 17:14:38 -0400 Message-Id: <1688159679-3623-1-git-send-email-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 1.8.3.1 Subject: [FFmpeg-devel] [PATCH v3 1/2] decklink: move queue_size to an argument for ff_decklink_packet_queue_init X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Devin Heitmueller MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 3d0uQaYuuLhT The existing queue initialization function would always sets it's maximum queue size to ctx->queue_size. But because we are introducing more queues we may want the sizes to differ between them. Move the specification of the queue size into an argument, which can be passed from the caller. This patch makes no functional change to the behavior. It is being made to accommodate Marton Balin's request to split out the queue size for the new VANC queue being introduced in a later patch. Signed-off-by: Devin Heitmueller --- libavdevice/decklink_common.cpp | 4 ++-- libavdevice/decklink_common.h | 2 +- libavdevice/decklink_dec.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index b6cc8d7..5e8d612 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -390,14 +390,14 @@ int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t directio return ff_decklink_set_format(avctx, 0, 0, 0, 0, AV_FIELD_UNKNOWN, direction); } -void ff_decklink_packet_queue_init(AVFormatContext *avctx, DecklinkPacketQueue *q) +void ff_decklink_packet_queue_init(AVFormatContext *avctx, DecklinkPacketQueue *q, int64_t queue_size) { struct decklink_cctx *ctx = (struct decklink_cctx *)avctx->priv_data; memset(q, 0, sizeof(DecklinkPacketQueue)); pthread_mutex_init(&q->mutex, NULL); pthread_cond_init(&q->cond, NULL); q->avctx = avctx; - q->max_q_size = ctx->queue_size; + q->max_q_size = queue_size; } void ff_decklink_packet_queue_flush(DecklinkPacketQueue *q) diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index ebb5b94..53e9983 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -235,7 +235,7 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct void ff_decklink_cleanup(AVFormatContext *avctx); int ff_decklink_init_device(AVFormatContext *avctx, const char* name); -void ff_decklink_packet_queue_init(AVFormatContext *avctx, DecklinkPacketQueue *q); +void ff_decklink_packet_queue_init(AVFormatContext *avctx, DecklinkPacketQueue *q, int64_t queue_size); void ff_decklink_packet_queue_flush(DecklinkPacketQueue *q); void ff_decklink_packet_queue_end(DecklinkPacketQueue *q); unsigned long long ff_decklink_packet_queue_size(DecklinkPacketQueue *q); diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 66abee1..11640f7 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -1297,7 +1297,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) goto error; } - ff_decklink_packet_queue_init(avctx, &ctx->queue); + ff_decklink_packet_queue_init(avctx, &ctx->queue, cctx->queue_size); if (ctx->dli->StartStreams() != S_OK) { av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n"); From patchwork Fri Jun 30 21:14:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 42349 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3b1e:b0:12b:9ae3:586d with SMTP id c30csp2779907pzh; Fri, 30 Jun 2023 13:17:14 -0700 (PDT) X-Google-Smtp-Source: APBJJlG/okMIKF2aBvFvK3Zn+FlFLuvA1kjbzczQl2bQ8Jgh2fpdtvVRcf34BCyxaDj6BdZzsu4I X-Received: by 2002:aa7:c3d2:0:b0:50b:c085:1991 with SMTP id l18-20020aa7c3d2000000b0050bc0851991mr2598761edr.19.1688156234296; Fri, 30 Jun 2023 13:17:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688156234; cv=none; d=google.com; s=arc-20160816; b=dux85drOIHfTxDuQ9ee36AsAtHyvWNVbKAQLet9KzjKSYeiIxIPvhiDgFf00GFW9+7 EV4zhGwnSyUHScJbZI6rpgVA/F+yTBCmq4/990OOfVnDo6A1HtG0syj8bomlqw7TTgM9 uF4SR/aAaWgSqDP17fmz+jb1dAxlFLctH3poRY509pmux8GixXn6Z25GcAK2BwH7wD2V 5Wvkoyz9J2IgyCVTgZ4PiRDNbS5+UY95qOw0S+J4NCRL3rHoUKblj2LF3EJ6lU0x6X41 znpoSr5T9Jtx16XYv6PAaBNUY1khpr+eCGr8iFyhT7XR0QlDZzyjtcKW8VZwr1OplSeH //OA== 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:dkim-signature:delivered-to; bh=bfv6gOR/D4bzr/Ih3zbKTf/a068J9qkQVKmX7mFAQXc=; fh=pXLAZvRiz3/uELcsWNfKAkJPgyV9/rr3Mrznj9KeXEo=; b=UQAYIHopCsCvNzYlyAjCNOkAqu6/cEMPGMK2t03mpkDIkm5kKl9KTTY9+2aP8x7d+Y KqAW4beNw/uej0g2qlkHlnBOrYd34KVPU61ZYI1KdTx7IcTqJO+Mi7nZArdHqc3cQ0QA piZc/dPWWCMidQz9na4rVVhl2mGqGkXefZbn7i7IV+K+kPQwlxmKeikCQ87xGNHK5avL WBn0uINEeRGu+nq7WdUXDEems1B++Ovxo4SJjPICrYLzGQEefpBO1+lRu/FQVKuNx16k d6ql0Mqv2/i9JLplDqQoRUydwGZNEAwlxiBTim8UYbn2q+NAHu8LbIv60gaokS6fBybC 0YAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@ltnglobal-com.20221208.gappssmtp.com header.s=20221208 header.b=mc7pvE58; 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 p14-20020a056402074e00b0051dd54bdc58si3032227edy.315.2023.06.30.13.17.13; Fri, 30 Jun 2023 13:17:14 -0700 (PDT) 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; dkim=neutral (body hash did not verify) header.i=@ltnglobal-com.20221208.gappssmtp.com header.s=20221208 header.b=mc7pvE58; 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 558CC68C419; Fri, 30 Jun 2023 23:17:00 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ot1-f47.google.com (mail-ot1-f47.google.com [209.85.210.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A8D7968C3BD for ; Fri, 30 Jun 2023 23:16:52 +0300 (EEST) Received: by mail-ot1-f47.google.com with SMTP id 46e09a7af769-6b5cf23b9fcso1987719a34.0 for ; Fri, 30 Jun 2023 13:16:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ltnglobal-com.20221208.gappssmtp.com; s=20221208; t=1688156211; x=1690748211; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=L3IWzN2UxflYLjJFNL0X2TFiWNXyjZRhVliG42iU7ok=; b=mc7pvE58g1MQWTTLz0YMM7OyyJBkh6mTUTksqRQis6FA3Me7QnvOmn6kVAXICol7SH XbxP3bjCZxhpt0CtBQ83yrXiKemJMwqgsvnK/JX34rk+DA9NAGiN3t+C+/bTHaWBA/cC Li83hLxtLCuK9SC7PM12w75vC3soG9HCLeQxqvIcLE4+lKpLUtUMnDhFGJjgyswEaczu qyuPE9HW+3b3G+nkrlvGt5fWwgFnk9tIqOvxcAPjWjvajjmiyM392RQ4oQgOtyjQ4zDS 64r4F+jxXm36HJEMDO/CEx4pe1zIt0S3dk2qY0NzG/Kif0AFkw56vEEmwqLCrc2P8OUy Yanw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688156211; x=1690748211; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=L3IWzN2UxflYLjJFNL0X2TFiWNXyjZRhVliG42iU7ok=; b=EomN6/D9sj6bnRX+P5iLWVPn1cLN89FxmziJuaKfEiJeOVeZ71+6KHeV4M8VZ6Ot1G cQb5Zy3R/v+78UdZ96yype0mdKT3JwxPjtqmeUNgI0pzLIKQ/sfRCCTOnvaaFGpY77DA Zy1rL5+imZb4rdfSwtTx9JmWmEV0qLnnYAXnIMS8EC1zGWHF2AvKpVHsNcC+o9DgN8Jw erbkeq3WTE/X29ZdqZ/HpxCVHP1Fa2PQ2JBfb7vPC7BJdbCt9uqk6voPCaAJf6UXIdgs 5qnvne7eOkCkUewjpmjU2H7gQApXLrIhrpAG541p1C1VmziWyehtXE+BF5qFV+J/QDX9 UDQQ== X-Gm-Message-State: AC+VfDzQUjtJE0ZRKVuKDU2r5ltWUKWhmAlEpst01WwNu7llph3oQZxt QG9wXsYPNy6d3i5FZESXn3Pn1hjUIAgkYLoFIKM= X-Received: by 2002:a05:6830:118:b0:6b7:155b:1df8 with SMTP id i24-20020a056830011800b006b7155b1df8mr4088428otp.16.1688156210726; Fri, 30 Jun 2023 13:16:50 -0700 (PDT) Received: from ltnt-nyc-580testdevin.livetimenet.com (pool-71-105-132-214.nycmny.fios.verizon.net. [71.105.132.214]) by smtp.gmail.com with ESMTPSA id h12-20020ac8776c000000b003f9efa2ddb4sm2294999qtu.66.2023.06.30.13.16.50 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jun 2023 13:16:50 -0700 (PDT) From: Devin Heitmueller X-Google-Original-From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Fri, 30 Jun 2023 17:14:39 -0400 Message-Id: <1688159679-3623-2-git-send-email-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1688159679-3623-1-git-send-email-dheitmueller@ltnglobal.com> References: <1688159679-3623-1-git-send-email-dheitmueller@ltnglobal.com> Subject: [FFmpeg-devel] [PATCH v3 2/2] decklink_enc: add support for SMPTE 2038 VANC packet output X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Devin Heitmueller MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: WMwFhU7k0Wwz Support decoding and embedding VANC packets delivered via SMPTE 2038 into the SDI output. We leverage an intermediate queue because data packets are announced separately from video but we need to embed the data into the video frame when it is output. Note that this patch has some additional abstraction for data streams in general as opposed to just SMPTE 2038 packets. This is because subsequent patches will introduce support for other data codecs. Thanks to Marton Balint for review/feedback. Signed-off-by: Devin Heitmueller --- doc/outdevs.texi | 5 +++ libavdevice/decklink_common.cpp | 16 +++++++ libavdevice/decklink_common.h | 4 ++ libavdevice/decklink_common_c.h | 1 + libavdevice/decklink_enc.cpp | 94 ++++++++++++++++++++++++++++++++++++++++- libavdevice/decklink_enc_c.c | 1 + 6 files changed, 120 insertions(+), 1 deletion(-) diff --git a/doc/outdevs.texi b/doc/outdevs.texi index 93391db..f0484bb 100644 --- a/doc/outdevs.texi +++ b/doc/outdevs.texi @@ -235,6 +235,11 @@ Enable SMPTE Level A mode on the used output. Must be @samp{unset}, @samp{true} or @samp{false}. Defaults to @option{unset}. +@item vanc_queue_size +Sets maximum output buffer size in bytes for VANC data. If the buffering reaches this value, +outgoing VANC data will be dropped. +Defaults to @samp{1048576}. + @end table @subsection Examples diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index 5e8d612..6eefb6f1 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -485,6 +485,22 @@ int ff_decklink_packet_queue_get(DecklinkPacketQueue *q, AVPacket *pkt, int bloc return ret; } +int64_t ff_decklink_packet_queue_peekpts(DecklinkPacketQueue *q) +{ + PacketListEntry *pkt1; + int64_t pts = -1; + + pthread_mutex_lock(&q->mutex); + pkt1 = q->pkt_list.head; + if (pkt1) { + pts = pkt1->pkt.pts; + } + pthread_mutex_unlock(&q->mutex); + + return pts; +} + + int ff_decklink_list_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list, int show_inputs, int show_outputs) diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index 53e9983..34ab1b9 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -115,6 +115,9 @@ struct decklink_ctx { CCFifo cc_fifo; ///< closed captions + /* Output VANC queue */ + DecklinkPacketQueue vanc_queue; + /* Streams present */ int audio; int video; @@ -241,5 +244,6 @@ void ff_decklink_packet_queue_end(DecklinkPacketQueue *q); unsigned long long ff_decklink_packet_queue_size(DecklinkPacketQueue *q); int ff_decklink_packet_queue_put(DecklinkPacketQueue *q, AVPacket *pkt); int ff_decklink_packet_queue_get(DecklinkPacketQueue *q, AVPacket *pkt, int block); +int64_t ff_decklink_packet_queue_peekpts(DecklinkPacketQueue *q); #endif /* AVDEVICE_DECKLINK_COMMON_H */ diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index 75896ad..9c55d89 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -63,6 +63,7 @@ struct decklink_cctx { char *format_code; int raw_format; int64_t queue_size; + int64_t vanc_queue_size; int copyts; int64_t timestamp_align; int timing_offset; diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 6906cb0..11e67c4 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -345,6 +345,25 @@ static int decklink_setup_subtitle(AVFormatContext *avctx, AVStream *st) return ret; } +static int decklink_setup_data(AVFormatContext *avctx, AVStream *st) +{ + int ret = -1; + + switch(st->codecpar->codec_id) { +#if CONFIG_LIBKLVANC + case AV_CODEC_ID_SMPTE_2038: + /* No specific setup required */ + ret = 0; + break; +#endif + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported data codec specified\n"); + break; + } + + return ret; +} + av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) { struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; @@ -370,6 +389,7 @@ av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) #if CONFIG_LIBKLVANC klvanc_context_destroy(ctx->vanc_ctx); #endif + ff_decklink_packet_queue_end(&ctx->vanc_queue); ff_ccfifo_uninit(&ctx->cc_fifo); av_freep(&cctx->ctx); @@ -552,6 +572,58 @@ static int decklink_construct_vanc(AVFormatContext *avctx, struct decklink_ctx * construct_cc(avctx, ctx, pkt, &vanc_lines); construct_afd(avctx, ctx, pkt, &vanc_lines, st); + /* See if there any pending data packets to process */ + while (ff_decklink_packet_queue_size(&ctx->vanc_queue) > 0) { + AVStream *vanc_st; + AVPacket vanc_pkt; + int64_t pts; + + pts = ff_decklink_packet_queue_peekpts(&ctx->vanc_queue); + if (pts > ctx->last_pts) { + /* We haven't gotten to the video frame we are supposed to inject + the oldest VANC packet into yet, so leave it on the queue... */ + break; + } + + ret = ff_decklink_packet_queue_get(&ctx->vanc_queue, &vanc_pkt, 1); + if (vanc_pkt.pts + 1 < ctx->last_pts) { + av_log(avctx, AV_LOG_WARNING, "VANC packet too old, throwing away\n"); + av_packet_unref(&vanc_pkt); + continue; + } + + vanc_st = avctx->streams[vanc_pkt.stream_index]; + if (vanc_st->codecpar->codec_id == AV_CODEC_ID_SMPTE_2038) { + struct klvanc_smpte2038_anc_data_packet_s *pkt_2038 = 0; + + klvanc_smpte2038_parse_pes_payload(vanc_pkt.data, vanc_pkt.size, &pkt_2038); + if (pkt_2038 == NULL) { + av_log(avctx, AV_LOG_ERROR, "failed to decode SMPTE 2038 PES packet"); + av_packet_unref(&vanc_pkt); + continue; + } + for (int i = 0; i < pkt_2038->lineCount; i++) { + struct klvanc_smpte2038_anc_data_line_s *l = &pkt_2038->lines[i]; + uint16_t *vancWords = NULL; + uint16_t vancWordCount; + + if (klvanc_smpte2038_convert_line_to_words(l, &vancWords, + &vancWordCount) < 0) + break; + + ret = klvanc_line_insert(ctx->vanc_ctx, &vanc_lines, vancWords, + vancWordCount, l->line_number, 0); + free(vancWords); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "VANC line insertion failed\n"); + break; + } + } + klvanc_smpte2038_anc_data_packet_free(pkt_2038); + } + av_packet_unref(&vanc_pkt); + } + IDeckLinkVideoFrameAncillary *vanc; int result = ctx->dlo->CreateAncillaryData(bmdFormat10BitYUV, &vanc); if (result != S_OK) { @@ -750,6 +822,18 @@ static int decklink_write_subtitle_packet(AVFormatContext *avctx, AVPacket *pkt) return 0; } +static int decklink_write_data_packet(AVFormatContext *avctx, AVPacket *pkt) +{ + struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; + struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; + + if (ff_decklink_packet_queue_put(&ctx->vanc_queue, pkt) < 0) { + av_log(avctx, AV_LOG_WARNING, "Failed to queue DATA packet\n"); + } + + return 0; +} + extern "C" { av_cold int ff_decklink_write_header(AVFormatContext *avctx) @@ -814,6 +898,9 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) } else if (c->codec_type == AVMEDIA_TYPE_VIDEO) { if (decklink_setup_video(avctx, st)) goto error; + } else if (c->codec_type == AVMEDIA_TYPE_DATA) { + if (decklink_setup_data(avctx, st)) + goto error; } else if (c->codec_type == AVMEDIA_TYPE_SUBTITLE) { if (decklink_setup_subtitle(avctx, st)) goto error; @@ -823,13 +910,16 @@ av_cold int ff_decklink_write_header(AVFormatContext *avctx) } } + /* Reconfigure the data/subtitle stream clocks to match the video */ for (n = 0; n < avctx->nb_streams; n++) { AVStream *st = avctx->streams[n]; AVCodecParameters *c = st->codecpar; - if(c->codec_type == AVMEDIA_TYPE_SUBTITLE) + if(c->codec_type == AVMEDIA_TYPE_DATA || + c->codec_type == AVMEDIA_TYPE_SUBTITLE) avpriv_set_pts_info(st, 64, ctx->bmd_tb_num, ctx->bmd_tb_den); } + ff_decklink_packet_queue_init(avctx, &ctx->vanc_queue, cctx->vanc_queue_size); ret = ff_ccfifo_init(&ctx->cc_fifo, av_make_q(ctx->bmd_tb_den, ctx->bmd_tb_num), avctx); if (ret < 0) { @@ -852,6 +942,8 @@ int ff_decklink_write_packet(AVFormatContext *avctx, AVPacket *pkt) return decklink_write_video_packet(avctx, pkt); else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) return decklink_write_audio_packet(avctx, pkt); + else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) + return decklink_write_data_packet(avctx, pkt); else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) return decklink_write_subtitle_packet(avctx, pkt); diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c index 0a3984b..25ffe77 100644 --- a/libavdevice/decklink_enc_c.c +++ b/libavdevice/decklink_enc_c.c @@ -32,6 +32,7 @@ static const AVOption options[] = { { "list_devices", "use ffmpeg -sinks decklink instead", OFFSET(list_devices), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC | AV_OPT_FLAG_DEPRECATED}, { "list_formats", "list supported formats" , OFFSET(list_formats), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 1, ENC }, { "preroll" , "video preroll in seconds", OFFSET(preroll ), AV_OPT_TYPE_DOUBLE, { .dbl = 0.5 }, 0, 5, ENC }, + { "vanc_queue_size", "VANC queue buffer size", OFFSET(vanc_queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024)}, 0, INT64_MAX, ENC }, #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 { "duplex_mode" , "duplex mode" , OFFSET(duplex_mode ), AV_OPT_TYPE_INT , { .i64 = 0 }, 0, 5, ENC, "duplex_mode"}, #else