From patchwork Fri Apr 21 21:12:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 41294 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:4645:b0:e3:3194:9d20 with SMTP id eb5csp1594018pzb; Fri, 21 Apr 2023 13:17:13 -0700 (PDT) X-Google-Smtp-Source: AKy350YEdzeK4Ri+d8z8saAsUCXMLc7+Vo/kWEkTgym+gCme3KaCw44BoYGv1EBqF9l6Sdz8qiN+ X-Received: by 2002:a05:6402:3ca:b0:506:8da7:fab7 with SMTP id t10-20020a05640203ca00b005068da7fab7mr5761308edw.10.1682108233426; Fri, 21 Apr 2023 13:17:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1682108233; cv=none; d=google.com; s=arc-20160816; b=T5XYDyaRB8idrNQ1XHVPpeosEsL2LsvZNl8WL+JGJemIU4aDfqKXh4iLgnHtD3Cm7/ lminVWItSkZRNXuFngBxdt+TNO6F9hnf6ZZFbc1J0+JXJgjo+Fpy7iIG5PJTTEWLXHE6 /oTEK/d77OjZxfIR5iYNiOP3J/2g9rEz4knr57yQUTa5VniJP/62qhv259gsjxdw8LIi Pg1SuJorrGo6Ff2dlFoz98sNm0EA5lu00H20tXDhaCFT4tvpGfSotCMz5JYL7J71Qtas 0n4sQpgrvKIVH0mg3y+5Oosl6d86IL43wJTRinuPbP6qQq6AbVVapbcAUCFXx952RtJ7 p6CA== 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=YIe0EFSnY1uRZvW7HK74JMYexapy+qFOASyJYouujpE=; b=h+8dW9SoU4nJ6GCtIaYN7C6LQKih6iGmMg7H70EBPmIY7e8wWjEWtlBT6EY4BvuEqh ClxRy8V4s0dZs5K73qP4rksDkEQPsb50pZPjU7Q9podwAO0TX8zH6hye3UT9gnvpMHnv CDbypX1OjIX7N3gb5bBrvUGmGglRURmnN1ebNzctfhxmfhZ9hccIAvKysAyIYfGfN/fq p55k9IlJTbR2/nUT2A84Jf+ms4U6RhpdHqzYda3DDt9YplL+uxSkQw/E8XLh+JIQ3Gng EszCHn+hwY946daVBsgEfKYt/Y9WAtkGIEY3xI2PmnJ2SNS0TOSLlwMFt7WtA+iF2H7I XHrg== 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=wkQ1wo6z; 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 r10-20020aa7d14a000000b0050463d6759esi4389276edo.533.2023.04.21.13.17.12; Fri, 21 Apr 2023 13:17:13 -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=wkQ1wo6z; 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 32EF868BEA2; Fri, 21 Apr 2023 23:17:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qv1-f44.google.com (mail-qv1-f44.google.com [209.85.219.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 328BB68BCCE for ; Fri, 21 Apr 2023 23:17:01 +0300 (EEST) Received: by mail-qv1-f44.google.com with SMTP id 6a1803df08f44-5f16a6fe2b1so11105096d6.1 for ; Fri, 21 Apr 2023 13:17:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ltnglobal-com.20221208.gappssmtp.com; s=20221208; t=1682108219; x=1684700219; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=prnz0eSxGADERKBujCu7+MRaFi+iiunWolEi6QOKboI=; b=wkQ1wo6zIbNUHkqM3coN+tlKNoN/vAnAfOppO5aE6osjRRiDpQm6nK7w7UuwUOYmXm 1mHeNlMGEOfSt+7VPb73XIuBiMhpveE1abhkYoeZNOmfV9zRvs59/ah5GZv0poLqEzgP xEi3yjE2xwiyHY/xIdIGzNIwZjMEuPKAjW52dSruVJ468oxlt4ibE3A1MLFnUqBz9cxE Mw4Y/cK5yq2v/n1xJ5DyREP55NGl2So/VRmcL2yy33jmSGjupKoHfYUdenaToDcLPbls IfFey8+KfnC8D8JqKGL/bY7mP0UWHQNidWcWSnpD779jZRaRE+C5g/JorwLELEdNnFHl Aj1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682108219; x=1684700219; 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=prnz0eSxGADERKBujCu7+MRaFi+iiunWolEi6QOKboI=; b=MONOzmq/spaXf77GA/iqnHAE79l4zs0KGekpx9jbFcD+uty4fIOwsc2T55kQ3x1/LJ gh1/CLpDFMP4O5JpSjwUgtRIBDTJQLQm6xsjhN3AbdZSpKR7Juo51xha/0lrR8/XmLEn 30pT8O4MtCp9PZvGNDLV/wZEFWUvGnv4An+zuiuf/tepl1VNVIuivoAjcjdpXr5r74p0 DvK9Ut0ZpxqDEULZisZG3AtO+lEElhdknCg+8Na1RJnlq7ok5BalyEbbK7Y1/7py6Gby 7hwmDu8QmbrBEVid79ovaW7raBC8A7Z+rIDNpHf7myRPGMOcNuuRXlVArn7uW/SanjhT BC6w== X-Gm-Message-State: AAQBX9d652skkbQDERIHZMg+4YWn/Ks4tNTuE0AzMQfFzqOrJmWQj/CI pZOMMe1c/0WeX8n0n3XCwikdqlX0CNnWsEYHXtQ= X-Received: by 2002:a05:6214:c29:b0:5af:9276:b59d with SMTP id a9-20020a0562140c2900b005af9276b59dmr6478327qvd.18.1682108219334; Fri, 21 Apr 2023 13:16:59 -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 o6-20020a05622a008600b003eeff94e2f8sm1590475qtw.0.2023.04.21.13.16.58 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Apr 2023 13:16:59 -0700 (PDT) From: Devin Heitmueller X-Google-Original-From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Fri, 21 Apr 2023 17:12:33 -0400 Message-Id: <1682111554-31597-2-git-send-email-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1682111554-31597-1-git-send-email-dheitmueller@ltnglobal.com> References: <1682111554-31597-1-git-send-email-dheitmueller@ltnglobal.com> Subject: [FFmpeg-devel] [PATCH 1/2] decklink: Move AVPacketQueue into decklink_common 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: 0vK+zcUJbheP Move the AVPacketQueue functionality that is currently only used for the decklink decode module into decklink_common, so it can be shared by the decklink encoder (i.e. for VANC insertion when we receive data packets separate from video). Signed-off-by: Devin Heitmueller --- libavdevice/decklink_common.cpp | 115 ++++++++++++++++++++++++++++++++++++++++ libavdevice/decklink_common.h | 7 +++ libavdevice/decklink_dec.cpp | 114 --------------------------------------- 3 files changed, 122 insertions(+), 114 deletions(-) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index acd1f77..31ab249 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -390,6 +390,121 @@ 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 avpacket_queue_init(AVFormatContext *avctx, AVPacketQueue *q) +{ + struct decklink_cctx *ctx = (struct decklink_cctx *)avctx->priv_data; + memset(q, 0, sizeof(AVPacketQueue)); + pthread_mutex_init(&q->mutex, NULL); + pthread_cond_init(&q->cond, NULL); + q->avctx = avctx; + q->max_q_size = ctx->queue_size; +} + +void avpacket_queue_flush(AVPacketQueue *q) +{ + PacketListEntry *pkt, *pkt1; + + pthread_mutex_lock(&q->mutex); + for (pkt = q->pkt_list.head; pkt != NULL; pkt = pkt1) { + pkt1 = pkt->next; + av_packet_unref(&pkt->pkt); + av_freep(&pkt); + } + q->pkt_list.head = NULL; + q->pkt_list.tail = NULL; + q->nb_packets = 0; + q->size = 0; + pthread_mutex_unlock(&q->mutex); +} + +void avpacket_queue_end(AVPacketQueue *q) +{ + avpacket_queue_flush(q); + pthread_mutex_destroy(&q->mutex); + pthread_cond_destroy(&q->cond); +} + +unsigned long long avpacket_queue_size(AVPacketQueue *q) +{ + unsigned long long size; + pthread_mutex_lock(&q->mutex); + size = q->size; + pthread_mutex_unlock(&q->mutex); + return size; +} + +int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) +{ + PacketListEntry *pkt1; + + // Drop Packet if queue size is > maximum queue size + if (avpacket_queue_size(q) > (uint64_t)q->max_q_size) { + av_packet_unref(pkt); + av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n"); + return -1; + } + /* ensure the packet is reference counted */ + if (av_packet_make_refcounted(pkt) < 0) { + av_packet_unref(pkt); + return -1; + } + + pkt1 = (PacketListEntry *)av_malloc(sizeof(*pkt1)); + if (!pkt1) { + av_packet_unref(pkt); + return -1; + } + av_packet_move_ref(&pkt1->pkt, pkt); + pkt1->next = NULL; + + pthread_mutex_lock(&q->mutex); + + if (!q->pkt_list.tail) { + q->pkt_list.head = pkt1; + } else { + q->pkt_list.tail->next = pkt1; + } + + q->pkt_list.tail = pkt1; + q->nb_packets++; + q->size += pkt1->pkt.size + sizeof(*pkt1); + + pthread_cond_signal(&q->cond); + + pthread_mutex_unlock(&q->mutex); + return 0; +} + +int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block) +{ + int ret; + + pthread_mutex_lock(&q->mutex); + + for (;; ) { + PacketListEntry *pkt1 = q->pkt_list.head; + if (pkt1) { + q->pkt_list.head = pkt1->next; + if (!q->pkt_list.head) { + q->pkt_list.tail = NULL; + } + q->nb_packets--; + q->size -= pkt1->pkt.size + sizeof(*pkt1); + *pkt = pkt1->pkt; + av_free(pkt1); + ret = 1; + break; + } else if (!block) { + ret = 0; + break; + } else { + pthread_cond_wait(&q->cond, &q->mutex); + } + } + pthread_mutex_unlock(&q->mutex); + return ret; +} + 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 088e165..d4330e5 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -232,4 +232,11 @@ 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 avpacket_queue_init(AVFormatContext *avctx, AVPacketQueue *q); +void avpacket_queue_flush(AVPacketQueue *q); +void avpacket_queue_end(AVPacketQueue *q); +unsigned long long avpacket_queue_size(AVPacketQueue *q); +int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt); +int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block); + #endif /* AVDEVICE_DECKLINK_COMMON_H */ diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 7bf5e37..b3ff2b0 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -471,120 +471,6 @@ skip_packet: return tgt; } -static void avpacket_queue_init(AVFormatContext *avctx, AVPacketQueue *q) -{ - struct decklink_cctx *ctx = (struct decklink_cctx *)avctx->priv_data; - memset(q, 0, sizeof(AVPacketQueue)); - pthread_mutex_init(&q->mutex, NULL); - pthread_cond_init(&q->cond, NULL); - q->avctx = avctx; - q->max_q_size = ctx->queue_size; -} - -static void avpacket_queue_flush(AVPacketQueue *q) -{ - PacketListEntry *pkt, *pkt1; - - pthread_mutex_lock(&q->mutex); - for (pkt = q->pkt_list.head; pkt != NULL; pkt = pkt1) { - pkt1 = pkt->next; - av_packet_unref(&pkt->pkt); - av_freep(&pkt); - } - q->pkt_list.head = NULL; - q->pkt_list.tail = NULL; - q->nb_packets = 0; - q->size = 0; - pthread_mutex_unlock(&q->mutex); -} - -static void avpacket_queue_end(AVPacketQueue *q) -{ - avpacket_queue_flush(q); - pthread_mutex_destroy(&q->mutex); - pthread_cond_destroy(&q->cond); -} - -static unsigned long long avpacket_queue_size(AVPacketQueue *q) -{ - unsigned long long size; - pthread_mutex_lock(&q->mutex); - size = q->size; - pthread_mutex_unlock(&q->mutex); - return size; -} - -static int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt) -{ - PacketListEntry *pkt1; - - // Drop Packet if queue size is > maximum queue size - if (avpacket_queue_size(q) > (uint64_t)q->max_q_size) { - av_packet_unref(pkt); - av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n"); - return -1; - } - /* ensure the packet is reference counted */ - if (av_packet_make_refcounted(pkt) < 0) { - av_packet_unref(pkt); - return -1; - } - - pkt1 = (PacketListEntry *)av_malloc(sizeof(*pkt1)); - if (!pkt1) { - av_packet_unref(pkt); - return -1; - } - av_packet_move_ref(&pkt1->pkt, pkt); - pkt1->next = NULL; - - pthread_mutex_lock(&q->mutex); - - if (!q->pkt_list.tail) { - q->pkt_list.head = pkt1; - } else { - q->pkt_list.tail->next = pkt1; - } - - q->pkt_list.tail = pkt1; - q->nb_packets++; - q->size += pkt1->pkt.size + sizeof(*pkt1); - - pthread_cond_signal(&q->cond); - - pthread_mutex_unlock(&q->mutex); - return 0; -} - -static int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block) -{ - int ret; - - pthread_mutex_lock(&q->mutex); - - for (;; ) { - PacketListEntry *pkt1 = q->pkt_list.head; - if (pkt1) { - q->pkt_list.head = pkt1->next; - if (!q->pkt_list.head) { - q->pkt_list.tail = NULL; - } - q->nb_packets--; - q->size -= pkt1->pkt.size + sizeof(*pkt1); - *pkt = pkt1->pkt; - av_free(pkt1); - ret = 1; - break; - } else if (!block) { - ret = 0; - break; - } else { - pthread_cond_wait(&q->cond, &q->mutex); - } - } - pthread_mutex_unlock(&q->mutex); - return ret; -} static void handle_klv(AVFormatContext *avctx, decklink_ctx *ctx, IDeckLinkVideoInputFrame *videoFrame, int64_t pts) { From patchwork Fri Apr 21 21:12:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 41295 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:4645:b0:e3:3194:9d20 with SMTP id eb5csp1594083pzb; Fri, 21 Apr 2023 13:17:23 -0700 (PDT) X-Google-Smtp-Source: AKy350adTAYURq4sCbg8mpLWNb07GAZRynqnCKMWa6XMI/kaHgCqklwPMDAINHMQjCVDExutJQWK X-Received: by 2002:a17:906:1409:b0:953:83a2:c813 with SMTP id p9-20020a170906140900b0095383a2c813mr3613188ejc.32.1682108243504; Fri, 21 Apr 2023 13:17:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1682108243; cv=none; d=google.com; s=arc-20160816; b=AFy6qysliiNn85NRy9cMGJCncb+hnIIZ/vZRxMP8Qmv3GFtm3cV6opnYCDktNavfrs OqqngsCYyZXVfV6auoWjt/DdjMF+N+1nig4a0ytlF3M9jhaTpKPxTpgaFhz5d/qVmjGl 5fH7PPoQe9SWYJPcQXhbi6X+omYQvTyCYo6vw2MttzObdiv+o2s1cJUCvEUHR0zTUngi us8FX4j979owFvWBvQw84C9pxOSQ90Sc0TJnLu1aHKXscuNVgu65bx9/TmDpQYW1Uwp2 i0kV1/jTijch6uFs09IYApb4Fs/5h7iFahAMvnr5XREsj1DY6AKH6mZaZh+rViqG8vjP mwLw== 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=E9Fk8p7+de2OBPkFeuU+/dicxUDVE9Qm+pGjXv37Jy8=; b=b9JbhDyAKkAtiyKq/dzrLZms+J3MG2Pbxtvs3x5l41SpdCZi/xCg2G6nmvrDqkxwQU Dh79/ILHvNaJTsRZT2/zpuP5HMsZ7SBF2IWfpT2OOrLHfHEya0OwAy0J4hEwxHRrevmG 0ch7EgbfWyW+bAJYY7zlzHkTsmkgikVPpFNPR81Jni5Iz3Jsn7jFF/DA0b2XJuYlvDvG /uf196BXVbFJyui+jXC2ScK+lDVSTSbR32zcI7zbm1P8VvTzG00bws5Fy9RMlRqPaO72 IYkTXro++/m+O3+HTqDstG81pbn7k/nNSLalaRLVANE76yUyM+otyknaGJg3qPhRhi/W 6q5w== 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="YWHeSJ/X"; 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 kv23-20020a17090778d700b0094f2d396328si4554176ejc.682.2023.04.21.13.17.23; Fri, 21 Apr 2023 13:17:23 -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="YWHeSJ/X"; 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 601A668BED3; Fri, 21 Apr 2023 23:17:09 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk1-f180.google.com (mail-qk1-f180.google.com [209.85.222.180]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2012D68BCCE for ; Fri, 21 Apr 2023 23:17:02 +0300 (EEST) Received: by mail-qk1-f180.google.com with SMTP id af79cd13be357-74ab718c344so713777985a.1 for ; Fri, 21 Apr 2023 13:17:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ltnglobal-com.20221208.gappssmtp.com; s=20221208; t=1682108220; x=1684700220; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=dqL+cLnEUjUxnh6ccSDUvRDQWGAUdG6o+Gs3D6p3sSE=; b=YWHeSJ/X/R3/H08ZKbaGEqBGvNQeowSKj8MfQQhOm8I1Hwgkz6+th9mnaXmF88by4G n6jtr7SpolJDL4wo4YzuDKmzD3NJ7SLybwpP/9Fs0yAhcPh/6FT81pG5ftVkbvF0nUkG BwOGEtF+CQFtSF48k9KIXUys8qniHzUIgVvQVvis6qHP+Bh/DTY1tMWn8Vz9gEZsnESh iPPfzSpLl/b06RYDykVdEAk1/A2zX5k07fpyzdcn/X/37RbWKj5z2qsU5uHkMQ7+aUfi cVsOHF962a9pAQqp0nkoTi/CgewZH+niJYHdP9ZWxwAQxXG6x132GsrdJc1MD8oMFAw/ ctaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682108220; x=1684700220; 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=dqL+cLnEUjUxnh6ccSDUvRDQWGAUdG6o+Gs3D6p3sSE=; b=FEyBxm9Li6CDCYn4r96n+9w0by5PuBRE4QoI3Ic+tB0EO0BGtVjRv1w3pko2lQBcXm K7YBn1Umo2nSS8502s0jAfXrisa02VRUgr8/4CCD1CYFix7BkFXLToPVvpQiNigLDrTI hz3vz5plMDqPSQn6Z2uulHY47yAULvoWoR64rfpsp7gpQ7mheRACL3/QONO5ke3/w84Z 1To55t+FMuMXlL1ql89LWKIkcRJdrN8A2NtpOxzP4BqB1v/JUW2XY6j3/axtCcoo305p J06NwROKr+elkCGb2qG4heyMaj5xPsNvcoIBoxvcvCOvhstueK1/awCYvJ+7dQyvXSoM 3XDg== X-Gm-Message-State: AAQBX9f+iBT5fxuomNyGAW4gxDMNBJmdsVEektY1kNQIxztznE3uUyhA vl5Kl8vsFT0BO+vVBtc3AG+ANMRMO/79CUMdJEM= X-Received: by 2002:ac8:7d0b:0:b0:3e9:65a2:61c6 with SMTP id g11-20020ac87d0b000000b003e965a261c6mr11333689qtb.21.1682108219814; Fri, 21 Apr 2023 13:16:59 -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 o6-20020a05622a008600b003eeff94e2f8sm1590475qtw.0.2023.04.21.13.16.59 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Apr 2023 13:16:59 -0700 (PDT) From: Devin Heitmueller X-Google-Original-From: Devin Heitmueller To: ffmpeg-devel@ffmpeg.org Date: Fri, 21 Apr 2023 17:12:34 -0400 Message-Id: <1682111554-31597-3-git-send-email-dheitmueller@ltnglobal.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1682111554-31597-1-git-send-email-dheitmueller@ltnglobal.com> References: <1682111554-31597-1-git-send-email-dheitmueller@ltnglobal.com> Subject: [FFmpeg-devel] [PATCH 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: fDCkL+UyJyXt 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. Signed-off-by: Devin Heitmueller --- libavdevice/decklink_common.cpp | 16 +++++++ libavdevice/decklink_common.h | 4 ++ libavdevice/decklink_enc.cpp | 104 ++++++++++++++++++++++++++++++++++++++++ libavdevice/decklink_enc_c.c | 1 + 4 files changed, 125 insertions(+) diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index 31ab249..8d2c6d0 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -505,6 +505,22 @@ int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block) return ret; } +int64_t avpacket_queue_peekpts(AVPacketQueue *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 d4330e5..99afcd4 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -112,6 +112,9 @@ struct decklink_ctx { /* Capture buffer queue */ AVPacketQueue queue; + /* Output VANC queue */ + AVPacketQueue vanc_queue; + /* Streams present */ int audio; int video; @@ -238,5 +241,6 @@ void avpacket_queue_end(AVPacketQueue *q); unsigned long long avpacket_queue_size(AVPacketQueue *q); int avpacket_queue_put(AVPacketQueue *q, AVPacket *pkt); int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block); +int64_t avpacket_queue_peekpts(AVPacketQueue *q); #endif /* AVDEVICE_DECKLINK_COMMON_H */ diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp index 92bfdb2..d7357a0 100644 --- a/libavdevice/decklink_enc.cpp +++ b/libavdevice/decklink_enc.cpp @@ -326,6 +326,25 @@ static int create_s337_payload(AVPacket *pkt, uint8_t **outbuf, int *outsize) return 0; } +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; @@ -351,6 +370,7 @@ av_cold int ff_decklink_write_trailer(AVFormatContext *avctx) #if CONFIG_LIBKLVANC klvanc_context_destroy(ctx->vanc_ctx); #endif + avpacket_queue_end(&ctx->vanc_queue); av_freep(&cctx->ctx); @@ -516,6 +536,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 (avpacket_queue_size(&ctx->vanc_queue) > 0) { + AVStream *vanc_st; + AVPacket vanc_pkt; + int64_t pts; + + pts = avpacket_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; + } + + avpacket_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) { @@ -704,6 +776,23 @@ static int decklink_write_audio_packet(AVFormatContext *avctx, AVPacket *pkt) return ret; } +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; + + AVPacket *avpacket = av_packet_clone(pkt); + if (!avpacket) { + av_log(avctx, AV_LOG_ERROR, "Could not clone data packet.\n"); + return AVERROR(EIO); + } + if (avpacket_queue_put(&ctx->vanc_queue, avpacket) < 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) @@ -768,12 +857,24 @@ 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 { av_log(avctx, AV_LOG_ERROR, "Unsupported stream type.\n"); goto error; } } + /* Reconfigure the data 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_DATA) + avpriv_set_pts_info(st, 64, ctx->bmd_tb_num, ctx->bmd_tb_den); + } + avpacket_queue_init (avctx, &ctx->vanc_queue); + return 0; error: @@ -789,6 +890,9 @@ 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); + } return AVERROR(EIO); } diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c index f7e3150..7aab660 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 }, + { "queue_size", "output queue buffer size", OFFSET(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