From patchwork Tue Nov 7 14:12:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Riedl X-Patchwork-Id: 44549 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7aa7:b0:181:818d:5e7f with SMTP id u39csp337787pzh; Tue, 7 Nov 2023 06:13:04 -0800 (PST) X-Google-Smtp-Source: AGHT+IEBHf1yBTfYPTHMZy/lCb2cbxkS+gxhKF/VSZ0Lj2ravTS8dSecdsBGsMSNViCKDB/g9qdG X-Received: by 2002:a17:907:c9aa:b0:9da:de23:738e with SMTP id uj42-20020a170907c9aa00b009dade23738emr1950595ejc.37.1699366384549; Tue, 07 Nov 2023 06:13:04 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id ga39-20020a1709070c2700b0099bcfa1f75dsi1059767ejc.206.2023.11.07.06.12.59; Tue, 07 Nov 2023 06:13:04 -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; dkim=neutral (body hash did not verify) header.i=@nativewaves.onmicrosoft.com header.s=selector2-nativewaves-onmicrosoft-com header.b=Br5AWdRt; arc=fail (body hash mismatch); 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 23B9A68CAF4; Tue, 7 Nov 2023 16:12:52 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on2071.outbound.protection.outlook.com [40.107.14.71]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1C72D68C78E for ; Tue, 7 Nov 2023 16:12:45 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=aYvRGTwM3lFEE2jtvG4nA1NNIE8hfby/IvsSbgcODdKk27+pV2OZxYBT94G7Ty5vdHFCU2WQ7bvazDPhWK/mzaM6ZM7lIbIMLH1808lNhOagGoHmWSUya+zvSDx7nOrQ4un8odzdXy+9vHUu7IIAtSGEsdVzPVI6Xlo2ipbbXSUKBsA6yMj1AgophYEwxhbXc3d9I/y7BxNje9tiCZZXqQgkIU7DK/nf7TZvvMCphTg/pb3gAJ8do9Xdz3TxFiBWoLz8eiUOXiQiLEzAtMIkqnvP8PGt17WUEeM9dp0mfBhiWLWctop+jsRIqAe//u9l6zczA8XktOmQY4KBjOQ99w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Ivoml0XBKy8NcsT2rbYFVkyPyYhTlG1dh3/HwN9dh/s=; b=eHNtTDZzAzmm6ypmrbC80X36kX0pxTNj6pD3g1CwTV8nj8cLAoVZlAHnFP8D5ADL4WFC2L8rDAllceL+bfPGMDEhvStVuZu0ZbdritpfaoUxsk5CPrC1styjvwQx/z27/Y1SpMujeBHO/JHoi9cm0VKT/emfACUr3NEDQIwMoZJoNmtdsk8jRRMZDn4tVD5l/56TuYYKZ35753W3J3v7NHjmhtRDjtN2A4zXytKCZs5vi2m4gMt2eLYDlVNW/7Tg6+7RKu5uBiPvof69aF+Z9D2pQI1koFvtCXNLABOK01t+S3p582PHm4S1YpuZrkCmrNnRtFIhmnDb0SjLrPuLyw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nativewaves.com; dmarc=pass action=none header.from=nativewaves.com; dkim=pass header.d=nativewaves.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nativewaves.onmicrosoft.com; s=selector2-nativewaves-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Ivoml0XBKy8NcsT2rbYFVkyPyYhTlG1dh3/HwN9dh/s=; b=Br5AWdRtAFIdFitXBUCH4rOwAgw/DuYLrk0IPScfnPUL02gkzIIcpobTrsWgY7IGm3GKM8RjpowxlKqaIs/OmnSl7x3FHI9qWRto+LpUd6WH2tQapGP0ZicI+BcK+0/HkYlL6pZluFdjAnzG/vesPXFMx2vmVHDPfC+KhQcwozQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nativewaves.com; Received: from VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) by GV1PR03MB8333.eurprd03.prod.outlook.com (2603:10a6:150:61::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.29; Tue, 7 Nov 2023 14:12:39 +0000 Received: from VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6]) by VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6%6]) with mapi id 15.20.6954.028; Tue, 7 Nov 2023 14:12:39 +0000 Message-ID: <74b2eb04-6ec8-4e20-930a-026793793186@nativewaves.com> Date: Tue, 7 Nov 2023 15:12:39 +0100 User-Agent: Mozilla Thunderbird From: Michael Riedl To: ffmpeg-devel@ffmpeg.org Content-Language: en-US X-ClientProxiedBy: ZR0P278CA0220.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:6a::22) To VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR03MB4239:EE_|GV1PR03MB8333:EE_ X-MS-Office365-Filtering-Correlation-Id: 8f0d7367-7c3b-49ff-a882-08dbdf9b99d2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: TGupOL1lpER8euoP/mhVBDa70ttqFq/2DhNDZUjEXqqGKxdlRz1hzuopTL7gkfclJNPsADWmC39LG088KD5KaFhm5tmsyQN5/d0C+jpM45MqigdwDdJACuzF62qzgYWGQwUQ4fGlwDsvKBOLEIA+iyPmUGFnZZIkYs1YavEo1VPGmLaKjDb4Kr5tKsuyerGsd/DFmWZd/7EVGOoQ81+IWAk3ZnXED/C7RTlePxeF9ODNMwORFX+RGqB5+Wyb2rDSHsCXpyBIiiioIkE4Z4SdS3SyicpPc0qJjPRMqW3oQ3t99Hn3IB9SaKzpcR/Nlzg1DG5bgPxfcQ/OLy5s+kEE2W+ohfM+02f2p4nExkX838de8yDwwMHiyXOlKNIMMH0kQhqNigFscQXaA68Nw4seDtIXOhjD0CZoZ1w6n+1/pHNGl828ysBeV1At8C1T7EEOz0vlYNmzwLV6Cs8Sxs2dDAL4QqQme/xKiBZ821BdhCSPUBhUsNZVQWHoVqtX27TNb/l0ZfVXwMbkss9STPtuL/ytdWowMZzvpuIGOKvJ1jw3RM5O7DrveXpN2OE2A8c/0zYMGcs7d5705w8WnvaHnu3sv0xGjNUKxrATjmpBFbStI6Ts2fqLj7xc1kN/H4Ya+rj2T65ISDWLxUFiC1jxJg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR03MB4239.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(39830400003)(346002)(366004)(376002)(136003)(396003)(230922051799003)(186009)(1800799009)(64100799003)(451199024)(6486002)(478600001)(66946007)(2616005)(66476007)(26005)(66556008)(6512007)(41300700001)(2906002)(6506007)(8936002)(6916009)(316002)(5660300002)(8676002)(44832011)(36756003)(31696002)(86362001)(83380400001)(38100700002)(31686004)(45980500001)(43740500002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?mUu9jRlBrwBTKwLN5kcj+ZBmP4xb?= =?utf-8?q?XcxFLqFCTPqsUbEtE8cF1WkWWrucOMRkkfKG+yQg3ueCqAqHIfiky9QO8Zsw72Pi9?= =?utf-8?q?cSIBv/bqmofNmtrrhUeOmWAhQdZUyS82QjEdnuy8KvezOcpcjdXDC9PRsFxTV0Y6H?= =?utf-8?q?5R3ixEov4gJSXKuWACN/yBgh9H85xmacJ5odjIXyt6765RtDTHbRkrXQF0X8UaXei?= =?utf-8?q?xwgmXIaa+JoZqJZ4IJ5zbpO3EOIAHUM9loikpQlOySOsMkvBD3ayWy0zx4E4h+DUn?= =?utf-8?q?70cpsZk4ijfGlDtMVwvIgehQmK3LPy7omBo+6egie1DsKsdM53SqMiJtX08Ft472d?= =?utf-8?q?Z/yqBMZgOXcGSFLithu3/2vm6vuKyJVo3Cx5snzrVkLpnsRnPvPoAhXxCbTdV2PV9?= =?utf-8?q?C3Llx0DxP7k1/RDEJfVm5IvsPZmxATM54hKrl2Fj0jesKamcdJOXhic+IwA8oYSaH?= =?utf-8?q?eld2BNSP89MJINosKTEnWtN2qw9SJbXBHZtJn2On9nydxPOlJoqPy7ZAs67bCP37D?= =?utf-8?q?TTIWhPUNOKweRVsOcKP/xnsQm7/3somaaQqOJX+cWOJKfdy35Op6aDTB0h1jJgPd6?= =?utf-8?q?3K0MqTug43xxGNN121HWBm577s4MpTuhRuR5slaMJxQWSa9P3EbE8CeM5kuFutMva?= =?utf-8?q?AeptADFFZiwkwei5qioEz0DFjS+h/XEc3IlDcLoRSFDs8/UtQPiDf5zbo7D5OzG5R?= =?utf-8?q?/EHxluuZpkb05WpIY58YFsWos0tk7M6DmZyd3XxHcn0xlv9NfrAi/EvO5guazFPCO?= =?utf-8?q?28fWTYteOTusHGo2TRONztb+njrDiayFAWw5aAmZItDjGVL/SsEt82uzfUsJ1fytu?= =?utf-8?q?aThxGZrgPT/fmi0ojhGN4m7gqrutxesfFZdhkvxlxkNTHmDIvVThM4izrbs6Xa/7a?= =?utf-8?q?vpdLVB93JWZgHNYC98LVcKe5kHRjWH6Gu/pM7z1vDHy+n2ysDRkj5SXb7Fe/7HR3P?= =?utf-8?q?iDdjeihyOqI9Cab3u90L9vTSg4rsbYkTf8HNVxGezyW7R/xS//d3VJlxl9866h3rE?= =?utf-8?q?Csci4cTx72nKr5odaqK8S7UkQZ6DGemyvkB6nv5cDesAuoTRl65cfJ40nL1G112ji?= =?utf-8?q?xtL5U/Ckgyb4hRNQ0IHonuQzVsZ86WZ6Oeo+gY/ioWQE73qy0AGH3CQ/1Ho3ikHQk?= =?utf-8?q?YEn/R1Zc7Gu4cD8pfQo9auSu87YdXlizqzRvkdJP5cZPJasGkhpWk5LGF5VsX6eCa?= =?utf-8?q?IRm04wdy5Vw7nLITX4knIZukGWdut9TCzjGEQSbZCf+bfYi0FF5yDHJJUdslvOZJP?= =?utf-8?q?9ksyISmu2MYAQbjMjCd/dLdnkz7lm53vwrnFz61nv5+sieaTTFGFS1Ksy1PHm2eYe?= =?utf-8?q?22085BVhYFz5EN5GnMtXWP/CsxJBlSgNIbR8lu6vlwlMKm2bm3vNNC1wzfRs+aHBg?= =?utf-8?q?uHO+Gi97IVQuOn7PsgjbCX3hwqcxb2pC6wEjNRir6KVvgTp85GzFifWbKBVn6Y/qc?= =?utf-8?q?O9sh58/qJ5fI1cC5mfa6YTxhsNFdD1aaPrOuKptlQsg/2+yy/pk8E/VtV6u6VTU/e?= =?utf-8?q?s+svO1plINkP6Mnzdrzy7ORxnKGazgyctydRlZE8ENbjiPXSjATKzm4=3D?= X-OriginatorOrg: nativewaves.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8f0d7367-7c3b-49ff-a882-08dbdf9b99d2 X-MS-Exchange-CrossTenant-AuthSource: VI1PR03MB4239.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Nov 2023 14:12:39.8017 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e4239718-b000-4513-8314-02ef46bd0276 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: +r+HhR5qS30gF9BeDHhfWP/7G4/HD7LToT/QNHxkdbj1TCzdFScQa66zqruudbK9OJO/pufEg1UFp9d0nvRB1zqQRRHyHt2XzcYRmMO1ePQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR03MB8333 Subject: [FFmpeg-devel] [PATCH v2 1/6] libavformat/http: expose actual Location header value 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: /FONcqMigPXc This is needed for (de)muxers which need to access the Location header as transmitted when no redirection happend. Signed-off-by: Michael Riedl --- libavformat/http.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/http.c b/libavformat/http.c index c0fe7c36d91..27f9c8e3000 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -166,6 +166,7 @@ static const AVOption options[] = { { "basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_BASIC }, 0, 0, D | E, "auth_type"}, { "send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, E }, { "location", "The actual location of the data received", OFFSET(location), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D | E }, + { "new_location", "The location header value of the data received", OFFSET(new_location), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D }, { "offset", "initial byte offset", OFFSET(off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, { "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, { "method", "Override the HTTP method or set the expected HTTP method from a client", OFFSET(method), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D | E }, From patchwork Tue Nov 7 14:12:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Riedl X-Patchwork-Id: 44550 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7aa7:b0:181:818d:5e7f with SMTP id u39csp337887pzh; Tue, 7 Nov 2023 06:13:12 -0800 (PST) X-Google-Smtp-Source: AGHT+IHNHebu8nH/cLJrJZIrtdTIMGhZfBAArBZEO4ctSIvZzRFz0zwjeILQs53QricWJ7ZrcQw+ X-Received: by 2002:a17:907:86a1:b0:9d5:96e7:5ae1 with SMTP id qa33-20020a17090786a100b009d596e75ae1mr2305568ejc.12.1699366392664; Tue, 07 Nov 2023 06:13:12 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id dl17-20020a170907945100b009b95622c296si939563ejc.704.2023.11.07.06.13.08; Tue, 07 Nov 2023 06:13:12 -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; dkim=neutral (body hash did not verify) header.i=@nativewaves.onmicrosoft.com header.s=selector2-nativewaves-onmicrosoft-com header.b=eqzZcOsQ; arc=fail (body hash mismatch); 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 1078D68C851; Tue, 7 Nov 2023 16:12:57 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on2071.outbound.protection.outlook.com [40.107.14.71]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3848268CB18 for ; Tue, 7 Nov 2023 16:12:50 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=jy5mrMPsBO5lA3lV0szy7eWv+maAil5N9IOJ0zQ0I824Q/7rvSJLmWa32impsVZnd2yHjAhS/o9j1gHJSaqqY3aJIngnDen2SoQAeRC9tS08/aqED70ZX3BLx5t2ouv91nQFPcj4U9aPIhxQd7ZNAM5HjQdFXoJrLuJRmbsU9S+T+Iyxa2+iKHWIx0vqGLhJ9fgN6wbHOFdhFybwO3uz8vQ5c0KcnjWIjEy4ZmdJszRX7N+4ZvW2Lc2a79PR+QQ+r2LYq5gSUB+ec5x5z49kimMZKmAPdC9S4WFP+jitILC5IboreR6x33ag9+tX7xoSlSeYr0jt/sA7GGVgCdz8BA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Bm9tGQhod7PEvVgD7v6BVyCM0ni+0LgRSJkhv1VeSNI=; b=juZvUHqz6yP0JQzfIbco+i/Jvw0Fd9dx6BTh5z1eAEiG3aCMeUkGKsWMBaGBw7ZcnaoSHlc3HcsyLy6p7+kRD2UGyfrA8PkGh1aDOLTa4YGbm13ZQXlIrsEaJ5rmuipzO5YTDf4EzOa4J66W1bsI0QU0ruRGozs6MNUcC300R67Wr7JV3OdQDkPM/F71OGgtwczw72RBzsCcgUJpf4/4Q2tpdgIvynpBPRUnDaGuMd0cYgzK06Vu0rQGaNl4qPMB2CkEnWezss4vD6DmS9rAkEeEAWaX0/+uJmkDy2c1kaa03keTjVt1y3oShCmWek1ddrQHkqXsyvdmKTp7e3Pfqg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nativewaves.com; dmarc=pass action=none header.from=nativewaves.com; dkim=pass header.d=nativewaves.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nativewaves.onmicrosoft.com; s=selector2-nativewaves-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Bm9tGQhod7PEvVgD7v6BVyCM0ni+0LgRSJkhv1VeSNI=; b=eqzZcOsQ8qBXfHO7nXCpkdTAWZwo9ZxXzLWXeWZy0CydS4D8YvjTAqq/RGyA4ePHb/LPX2kHVxniQaU6limSnyx6MCqRcKOf49EWubp660e19BNJ+Xmlg4MeX4jmsLcLiZjYclqNC0VpjmtxjfJ1Q1k71yzFTkIUG5wkfZDL62w= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nativewaves.com; Received: from VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) by GV1PR03MB8333.eurprd03.prod.outlook.com (2603:10a6:150:61::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.29; Tue, 7 Nov 2023 14:12:43 +0000 Received: from VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6]) by VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6%6]) with mapi id 15.20.6954.028; Tue, 7 Nov 2023 14:12:43 +0000 Message-ID: Date: Tue, 7 Nov 2023 15:12:42 +0100 User-Agent: Mozilla Thunderbird From: Michael Riedl To: ffmpeg-devel@ffmpeg.org Content-Language: en-US X-ClientProxiedBy: ZR0P278CA0220.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:6a::22) To VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR03MB4239:EE_|GV1PR03MB8333:EE_ X-MS-Office365-Filtering-Correlation-Id: ca94e3c1-1883-4cf3-caa4-08dbdf9b9bdc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ggnaNnVvbYBPBr4aUK+fkbSleEq27tCQPsicm41v4e2RXTpYg1gUhf25zMdxVQgnQdmMNnEAu4EVwzh8jxFDN+Lod/1Y1jrZx1c+kh1cwP8woyi+F39dlOMJpvJTgLP2CuT8GCzXLlSlCwwNFF5zCkcPGz0+tDDHj9QL3/IanEP6YmUT6En4zFcU8q3HJT1YtpQa5PurVfZ7VQEuDOxniQ2qgQOXuCxRCr+I3cPsx4dKUhmCph1Hi09oLerVmR0bHwpOVlTaOXDxAhu6631FwZlEQs63+dsEWIL5lJNseQDfKcHgcqgQcynS1wuD1k4jTiQ2f3Tvk/dnwDmKtBs1kvjFKqMJ1N1j6kkJfC4Hun9LJzhXInevWwjW2OcxYGzlWLibcJZI1m0t1EBILyOt266BRIV9w01IwP1/Irw3Pgdf25MBj3x0OtT3Op8dhlNvAkeQyeJ9d0Occm5rZFi172a3tvneb9mm6m/BF1uWZWuFabxwl2f90kDQSAmSPZa/7ksjWyhYmI1OJocJUf+9KHm+WBNgk9maKcjcyaSW9IC3ibAFgyGIVcOIma67noiWPSMFUNb++1nVdDdTZA+WmGAXQ2ZQ31t75cj/wLLp05lScwCC1FGKrHdFIBrOIXoIXi0ttbZk1B/p8KZN/P59vA== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR03MB4239.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(39830400003)(346002)(366004)(376002)(136003)(396003)(230922051799003)(186009)(1800799009)(64100799003)(451199024)(6486002)(478600001)(66946007)(2616005)(66476007)(26005)(66556008)(6512007)(41300700001)(4744005)(2906002)(6506007)(8936002)(6916009)(316002)(5660300002)(8676002)(44832011)(36756003)(31696002)(86362001)(83380400001)(38100700002)(31686004)(45980500001)(43740500002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?hVtsG7G6tm6SNoEIueJyXleVx67n?= =?utf-8?q?QGDIzttqTTS3JR5bDrcW2J9VqLynPZ+tZPj3Y2sw+lEvesW5wVlTZpvMaEGcvGjqH?= =?utf-8?q?QsZ8Nxs3VenzMKHi5CXiY3Ax+dyRGodkXIUzcbsWLy10+ZkHxK6oNKxUa1Upo8cyl?= =?utf-8?q?77XTIj0yBS8kYbGkyAfjBpvzw5u53rMerFMRSEAPC+bJXy9r0W4m9rGNPBz4um80U?= =?utf-8?q?rcHvZQ3Zy8yODmTnALHxLH5gmMniTV0Jxp9XBvrFPDpCgQHS0S5EmBKJvWgskANRw?= =?utf-8?q?yC4/lr+vBwfl6EYeAzJEded+PmyI1kFkcXE4+rnZm78gwnTGUawi+9Gs64T9oEiUb?= =?utf-8?q?3c8QOLfaIJPMp60dXIWPK+C+2sDb0YIe1wLiMGZB01lqnlwIp5zuDZK2+0pKf+Wlv?= =?utf-8?q?VwhoYsZ/4ooNn03kIMNQv8kNS0yU1Vjqoo0rNu59+ai+d9D3Pq2Y/1Jwce6mFpYGb?= =?utf-8?q?NlPkzBwCz/yKIg0wZv7/70MOJ0FcXcUzTNHHVoSduknW3dtVhXeQ9CSk0V/t4qXz1?= =?utf-8?q?+H/LQlkvnN5eKo3/JLG1yE8ZEFbD84VWcB7+JFcB5akda5OTaOiZaG1x2Y+MScGDu?= =?utf-8?q?k+YNNKnDarqUYSLFeLcUSeFfZGQnAW0mJfP+pLGFjix+oYbePKt+GXfmsW3+38CFH?= =?utf-8?q?vMILHgoTnYkV34r6CV+WiNkcwnbOY7ryAazdXpwDi8Cgf0NOQYgA2kR2TWutQrc+7?= =?utf-8?q?jrvrX67d6oO+6IsCs60Vd6IOPEXU5ebkfclV6kg6ItkMOei+ACfrizE/ma2+qYiHA?= =?utf-8?q?ujLRNu8t9yEnOVjqeIfNXzIOn+YjR/JnVvHmWhMqO7YAumzFBfRDYj3fwSKzDKEfT?= =?utf-8?q?CgePGAcIno4ViotqY8vqx54rF+XtxFUv2cavRotwmLWwvEK/0e3xONsQUjOrX84/2?= =?utf-8?q?ts5bTdNPjdED28k4zP6xxvtWGr/UTTz7KDgll8opUTgLm6SIh1n7umoNhQhnCoDIJ?= =?utf-8?q?B43phMS0crWwX8K6qsen6c3FVR7hYs6r0w8W07XddFHRc8yfb4cbopmR+29I5oIcC?= =?utf-8?q?ejz8DAWtYILOj9+5E96Vy84QDpOydWNf+FFH/IzOnCoXSjV93uY1ehdTK2gKdZ09E?= =?utf-8?q?7xzLZKKkJ107EY5Kaln406SV3Nd9LvBqDujEM+8lVfkqVP4UY6xWUaHyaz8nPBb0g?= =?utf-8?q?aeF3xzfH1Y1wgyGpNULKd8WeyDL2q3RO7dhIX2ZltZi5deUJN1ddKElyWSXru/O8y?= =?utf-8?q?/nTN/wCHPbUjwJW0NylouDbqEDN6GwUJq9ao580CxicRUxasb3hFEoma3sB0Q0iHf?= =?utf-8?q?zNUOELTviDrMc6buIops0Flt17I20B1+Up2M5b4qw68NZhkfDOPKJ7Ih7rnwOjRLS?= =?utf-8?q?WjNPnD8lzyYSPPdRC3fBTPODHGjxP717L0U8U35oSkixEGaGNCmecdN0bAMhXu74x?= =?utf-8?q?vpZ73I78wWDBUfosnwpQyOpncDCgZZ1hxubQhnBQBBJB3zi6M31PBX+USdIOr8Iz6?= =?utf-8?q?ruHNUm/sOEuwlybcRuuh82kb7xWpD4mzR+Th8c6uxQSyRvLqoYGZEIKidgWbS/ASE?= =?utf-8?q?ZVYS+8niia2Uo4osuEeMG2rZHPdqJ8TDT56LBID06vM+Zwcuirn6BkI=3D?= X-OriginatorOrg: nativewaves.com X-MS-Exchange-CrossTenant-Network-Message-Id: ca94e3c1-1883-4cf3-caa4-08dbdf9b9bdc X-MS-Exchange-CrossTenant-AuthSource: VI1PR03MB4239.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Nov 2023 14:12:43.2493 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e4239718-b000-4513-8314-02ef46bd0276 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: o04c3GcXYAGycgCR5aKT4/DwgCMtshQSD4TN5s/f+pAnolUA5Jqwwy6hX+3mYKIstiBRITcs2E0SG4erQv6UFmnQPGugDH4J1o61JaaOwOI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR03MB8333 Subject: [FFmpeg-devel] [PATCH v2 2/6] libavformat/sdp: remove whitespaces in fmtp 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: DZTQOf6UTtQb Whitespaces after semicolon breaks some servers Signed-off-by: Michael Riedl --- libavformat/sdp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 68889362906..5ab017b1ba5 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -159,8 +159,8 @@ static int extradata2psets(AVFormatContext *s, const AVCodecParameters *par, { char *psets, *p; const uint8_t *r; - static const char pset_string[] = "; sprop-parameter-sets="; - static const char profile_string[] = "; profile-level-id="; + static const char pset_string[] = ";sprop-parameter-sets="; + static const char profile_string[] = ";profile-level-id="; uint8_t *extradata = par->extradata; int extradata_size = par->extradata_size; uint8_t *tmpbuf = NULL; From patchwork Tue Nov 7 14:12:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Riedl X-Patchwork-Id: 44551 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7aa7:b0:181:818d:5e7f with SMTP id u39csp338061pzh; Tue, 7 Nov 2023 06:13:25 -0800 (PST) X-Google-Smtp-Source: AGHT+IEOugAKyD0Fs3r/yXHI0VxBPm30L0JHrmAdbEU6FYCZqvYpHqXI//FbARS6XlyLYkEV8/Yc X-Received: by 2002:a17:907:3fa2:b0:9a6:426f:7dfd with SMTP id hr34-20020a1709073fa200b009a6426f7dfdmr16293589ejc.66.1699366405441; Tue, 07 Nov 2023 06:13:25 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id sa41-20020a1709076d2900b009ddbafdff6asi956639ejc.900.2023.11.07.06.13.18; Tue, 07 Nov 2023 06:13:25 -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; dkim=neutral (body hash did not verify) header.i=@nativewaves.onmicrosoft.com header.s=selector2-nativewaves-onmicrosoft-com header.b=QHariRim; arc=fail (body hash mismatch); 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 1C96468CB55; Tue, 7 Nov 2023 16:13:02 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on2071.outbound.protection.outlook.com [40.107.14.71]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 53F0C68CB2C for ; Tue, 7 Nov 2023 16:12:55 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EJuKQWFyyG4PtZ2Oa0TL6FDCIHYLEzRBzZ0EY6HfexJE5PODu+NNEoi/YdNvU37yatCV5JIM2CiSsqq27B1GNpJ2c20Cmn2TBEsgMwNSrcTXFLwfDw2S9Cy0+a2x8TQVo+yPHSRx1FXIeqBR0fVpz7IE/+q5ViOWE6iRV73dSO7FxV9yr3D90Wn+HD3cBNaBQouuneXcwRj0Lq9grH9lXgmW0B5yXS6QLMAxGQKrRAnBF6MnVGPzpRsNlMZuSUORkxzTZHqtWUk0ZCpcoHzt3mTQXwORSFMXWioUSh10KCWUDfKFNj2jLW/8jhVrUKVD3BdoOva/3XdBqHLqJF+aeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=K2/+6XZX5i/RhWGViD8/JhzqzUkY7d3moYqMuwJDdYY=; b=B2K6Q/fZP0rZCgSQPMCMeh8CALkqdKu1wbUfxjPDkWcl0W4L409W/yvdD8U0r7tKI/cXzQgdt4I5NMHUJqcOBBSRNkfthVsWdC7z/t/qoV4/qgbsrLsAsqCn+zArYUyPgz9mj1/wjoABNbj3pjToeZTMcnNTpdSEB5gZwbgmws2kl6JvphInKfmG9XiwxcorEAZy0jAelkcBpPSiV4znmWSNU47lI1MQpFdnwwVNxRrJ6DHFgSyCOx0Q7JDLqm4pZ7FQL6elZvCEGQsnx7gYqxdQMPvtHXctdNI9ZhJ6EmmddIaR821GVDZKanx8PW/fKoG4sNJ6kDNM4rOHaPu5GQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nativewaves.com; dmarc=pass action=none header.from=nativewaves.com; dkim=pass header.d=nativewaves.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nativewaves.onmicrosoft.com; s=selector2-nativewaves-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=K2/+6XZX5i/RhWGViD8/JhzqzUkY7d3moYqMuwJDdYY=; b=QHariRim42QuQthB+lqEhcKlxTGlNfwECVMBH8MEPEGfKLuJ0bTSzCPqf5lDIQ/UZJ9e4e9zekMdlam69qxMx10Hclax1Uaku9pXKMKNULqN282gJiVXSTyNXAKKt5e81r+Y2aRkbsUtPiihlkFcfSjz40xT5IXrxAAQ7m6jbGE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nativewaves.com; Received: from VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) by GV1PR03MB8333.eurprd03.prod.outlook.com (2603:10a6:150:61::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.29; Tue, 7 Nov 2023 14:12:48 +0000 Received: from VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6]) by VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6%6]) with mapi id 15.20.6954.028; Tue, 7 Nov 2023 14:12:48 +0000 Message-ID: <8fdd0a0c-7c55-438b-83b1-22215cf9d047@nativewaves.com> Date: Tue, 7 Nov 2023 15:12:47 +0100 User-Agent: Mozilla Thunderbird From: Michael Riedl To: ffmpeg-devel@ffmpeg.org Content-Language: en-US X-ClientProxiedBy: ZR0P278CA0220.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:6a::22) To VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR03MB4239:EE_|GV1PR03MB8333:EE_ X-MS-Office365-Filtering-Correlation-Id: 8bedf54c-3f70-4165-8fa3-08dbdf9b9f0e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: YCregJhVJwVSnq9t9RK/xNgv7U/QhIAhIGEevnuiFPJJCPU07tmrk0VQhKasQz/Hj/MUn99V52w4lpXVZX6M0voNH+mdrOWnKFWkIZR0/HBEPXmMQwcuarwfxSuABf6gHPlZDlmJ2FB+VN/3biSBUYhOGARx1fCFIgFtK5tGAi6YlkpKZprJVmFWuuUbd6af7nUhzPc9MuL+W9W6Ir7GLeUxEk5bQWouBnGmN5Dq9ftr/22kOL9sDrsPzTlMiWfOc8mFOFOTuk+KtqsAYDvbLlRVOddK3hcJM/5JQfDkb6MfP0wrqwbJEA5QM+cgfsvejlYuZBUmQVhRZ90wt0BwwscFUiWXpcbryC8iJnVf+5Ce2MiITSwi7El5LuNNTLJoxpZ5pxE0RkH6/TDF4y4Ng17hNIdv6JH7vge547K3/mz5gQd8Zzzrk5L1BLLDhfZnEELHmX4/VZedFX0FhCcVDAdjP9EB2rxguSD+b3OwQmNuO/q5x+Ub7YDtDpgSGdyxqvrH/j5Im7YuGO8KUpF55UP2fqt0qx1XFrRrSNp8xwrrqBjWuRkRCyI5OE5rEGaO/c/gfCG9dEceBs4wDcIdVMVCeyi0kRtBKwDgDSYdDHKm9pjyRVbimDpLKiZa527Dxvbeg3B+jydhEie8nje7rsvK5FdCaS8aj9TivwK3H/sgK4Krox17Lln0bS6Qf/LSoM8wljQ0cED0bmW508aB290Eq10kR05XOTCADgpMRKo= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR03MB4239.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(39830400003)(346002)(366004)(376002)(136003)(396003)(230273577357003)(230922051799003)(230173577357003)(186009)(1800799009)(64100799003)(451199024)(6486002)(478600001)(66946007)(2616005)(66476007)(26005)(66556008)(6512007)(41300700001)(2906002)(6506007)(8936002)(6916009)(316002)(5660300002)(8676002)(44832011)(36756003)(31696002)(86362001)(38100700002)(31686004)(45980500001)(43740500002)(357404004); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?RwIu55hqmVzBDqdxYZEvxd4YlFPo?= =?utf-8?q?SCXEMCRNWqOCBdlCNogEZ/NdpB6AXiNSKQe6bmdpnhDh+VRPiwsry1WhRbqPgE8ow?= =?utf-8?q?r0vgyQ5U3s3X8rIwKk5iMUzgQXRslRrGP4D1KlG9zaBqOVGAt2jBHh0QaEwklfDGl?= =?utf-8?q?8GNzSLHGDuuOAUB5Po8i6X/6NeKWDz+VN5Na0a+LDh7T5RsENvbxz6pAX4ggK2htl?= =?utf-8?q?DG+UhunMxMQkV3Angf7J12V8UvyuTHDZvImzFxRn3O55a5pedjlBP/vuxsuk2phDx?= =?utf-8?q?6YrOWUwuTRqQQ/wMM3lwf58HuahGnMSHHrmvyFxkr6UFyyrup3VhRQ6EEwhs81C7d?= =?utf-8?q?A706vnAI0XNrQ8umzl5Utq6+r23ZUBRjeyW8noJxbnRpcQKuEk7xXeCmKNY7U19de?= =?utf-8?q?g/Inevd6HeXDXlx5IfRUCt1juOs2vYeWthNTJ8eWLFY7I67SnL5vMorD0O+WPYoTC?= =?utf-8?q?Hy2ZPNaINc77UcBsLOh04ibWTI7b6bnHV1MCC6zldlahGqbLE9sEdF3ZDTTcBE1Ta?= =?utf-8?q?1kPHX862Ur+WhuFu7krLJvVOogYjBTEgl77iLuhgi6ARrbymRfmyT2L/0/ir5VCvd?= =?utf-8?q?v9TenmyQFiriHd7wIIA8TOARTbMefWUdJ01hlrBEiXl+PdGFBsD7fejgYKyMmJ5V9?= =?utf-8?q?nRbwefTiJxE8vDyE5a6NVcQQXboPwjs0e1SKWjJiKJ0Ex3Fz9H+gQuTgQiEKTThr8?= =?utf-8?q?Op41C6O6boI6sSoHcYtYRrquAVgBhecHL5V8bPXkCU45dFrNRnTlzxdCbmlLPxvLc?= =?utf-8?q?YQbNWl1bQv7XsdsjZvQY8jsbj6aYPUB/U8Bd9bk630y9qyyfeLGFL4/3VJhfJk/4T?= =?utf-8?q?8nVNb41ZOA2wMLQc7UUjdUcF0jH3DUtzRJVSz+j/8lGAo/8HEzUzR/4pbdDhUg/7C?= =?utf-8?q?dH6ZDGOV+kWBM7d+GYZZzcy8tXRyA45lSm+OphdC+omd8bHINdKEcpsigxMKHpKCL?= =?utf-8?q?SnoX7t/0G7Tb1oMlNPuFAFvQne3/600uqqmez9+e6UBwqa9rrGC+eTuOW+v7Fjp1F?= =?utf-8?q?DFThjSC5K1V7uHVb7ogUz+yXC7geDsg7WfY4BNdka9taJnr+RXmpoWyAQtlZsqofv?= =?utf-8?q?S5Kdbuz4a8orf1w79G1yP8kanngERcM26jKwCmo+YhKAfUl9zsUllc19+jubCMcfG?= =?utf-8?q?s0zMLDpOHaQTcl3/HI40zmqxSnHY0H0IE5g8WEI7erqAARfpVErhLoBOkM+0Zcj9t?= =?utf-8?q?IQXnpx5DF/KoPOvY6HUxODx9vt4vvAYYwuWxsOOlJGRy/NDWfiIRiXkxOsDy4cGH5?= =?utf-8?q?jruoRog8L2iL5eqktMGLLa45coyoXOJ1TF/dSpjCuLTVo+b0FMm5xA8lsZyZlAGVi?= =?utf-8?q?WGPugBL3HIsZ/qxUxxc2/hvb0zB/ayHAfGMUWC+2oiL95rqoiwWtJ2T4gQGEnKbm4?= =?utf-8?q?MhIhkbtO05lCe8++DqxRiIsp1WNJN7p/J7D7YIIxLhaDVA3vipg2AHk7s2ESjJAER?= =?utf-8?q?7vXIxTNLOeoBM+6sHetBGpMHPP6dHhFuuRzMGX7i55w0h883Qsc/WEKBoLPPhQkDb?= =?utf-8?q?gpcGvUT/ZeRCdrW6d2yOJ0b3uE0sYBLAaOM5AW0R8WreLWYy57J3HPs=3D?= X-OriginatorOrg: nativewaves.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8bedf54c-3f70-4165-8fa3-08dbdf9b9f0e X-MS-Exchange-CrossTenant-AuthSource: VI1PR03MB4239.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Nov 2023 14:12:48.5553 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e4239718-b000-4513-8314-02ef46bd0276 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: WqDABONPnlQlHMa+ZJ5jXniAHtIFGMrkzijxOpQqYWRrcotV1+fUHw3ME2/LKx3HXQgJtg60AgxDfRyIEYpqx7BjQTUqpXG3Sm6ZCq6mC3c= X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR03MB8333 Subject: [FFmpeg-devel] [PATCH v2 3/6] configure: add libdatachannel as external library 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: qnkTHsnDbc8D Signed-off-by: Michael Riedl --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index 8ab658f7303..187f16b425d 100755 --- a/configure +++ b/configure @@ -223,6 +223,7 @@ External library support: --enable-libcelt enable CELT decoding via libcelt [no] --enable-libcdio enable audio CD grabbing with libcdio [no] --enable-libcodec2 enable codec2 en/decoding using libcodec2 [no] + --enable-libdatachannel enable WHIP muxing via libdatachannel [no] --enable-libdav1d enable AV1 decoding via libdav1d [no] --enable-libdavs2 enable AVS2 decoding via libdavs2 [no] --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394 @@ -1849,6 +1850,7 @@ EXTERNAL_LIBRARY_LIST=" libcaca libcelt libcodec2 + libdatachannel libdav1d libdc1394 libdrm @@ -6708,6 +6710,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2 enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.5.0" "dav1d/dav1d.h" dav1d_version +enabled libdatachannel && require libdatachannel rtc/rtc.h rtcPreload -ldatachannel enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdrm && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion From patchwork Tue Nov 7 14:12:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Riedl X-Patchwork-Id: 44553 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7aa7:b0:181:818d:5e7f with SMTP id u39csp338329pzh; Tue, 7 Nov 2023 06:13:45 -0800 (PST) X-Google-Smtp-Source: AGHT+IH8dYGiFEXf5yfhlNC7E1TM7+PGXvoxLG21h5uY1bZw6zTRGF1Q6v3M5Ar8RdnDKGGzDcYe X-Received: by 2002:a17:907:6e88:b0:9dd:add6:4c12 with SMTP id sh8-20020a1709076e8800b009ddadd64c12mr11676594ejc.77.1699366424673; Tue, 07 Nov 2023 06:13:44 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id dn13-20020a17090794cd00b009bedd8e630csi1095413ejc.931.2023.11.07.06.13.38; Tue, 07 Nov 2023 06:13:44 -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; dkim=neutral (body hash did not verify) header.i=@nativewaves.onmicrosoft.com header.s=selector2-nativewaves-onmicrosoft-com header.b=oEDDE9+z; arc=fail (body hash mismatch); 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 3160268CB38; Tue, 7 Nov 2023 16:13:07 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-ve1eur01on2071.outbound.protection.outlook.com [40.107.14.71]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 710DC68CB6C for ; Tue, 7 Nov 2023 16:13:00 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LBrGdcl9kOaneJKjXAUiLiNa0YLriZWZRBNYuIeJbf61mDJtLMvbx9DPbTmfQ3duNcL2qdtYM+xTGPm9Ei0Y4LmCbMl9bYL70lGDoyI3v5jNmDNBN0fvrOVQoEOw99FEnFPJ9N8iWGTsW4et+52NQVcN4Np3jQaLPMZSv9e0tnQruRRM3k1fojAsTLPXxhNo+8FBLKyAzXxykaE9U8xqczSBjll3R0IzDWZLpUXxExoNJBg9SGwwzn9FniXNDUFfJSRJT38b2m2duULv51eNjU9/fZwHG4FMKm14dMmEsGjIvczDtAI1llYxcZD9xQBZxZaruM376txlhT+6W9xYNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=XVcmbofZ13j2GNaMxlXV7kKhoMzqAARTJNm1wucR19c=; b=ZUzvjWow4M+x9Jf2t80oroqrNcP9l479Zmy7yQ8IQs7PW0KBf4GQH+eCcy0my34ZOSd+jqqSOx59St67EZoOzXCxwFxD1MHzGwjFZ2NkA4ylR2MYkfrdfPCDaUKTAlqkge4oRl49xMR1tvIdbYdF05gMog9seU9mC2X1XO/aGfrj+PTSlk0jZq915sXUGrf2mjOzEaJf3irkpV5YzmA1OAEBBdqlLWrIjT1dr2PmOsC3roBy0cjTcg2zWLIjPGcCLK9NQx3qmgA8cBHb63OyXVbP2SL5xd75bqD5Lq/UfQ3L2s7J2HjrLhtRH4H0jMAPdhPT+8EMe+6TTJqJvm5lLg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nativewaves.com; dmarc=pass action=none header.from=nativewaves.com; dkim=pass header.d=nativewaves.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nativewaves.onmicrosoft.com; s=selector2-nativewaves-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XVcmbofZ13j2GNaMxlXV7kKhoMzqAARTJNm1wucR19c=; b=oEDDE9+zL8ncw40N3QzqTVGaVcwAN3QJz37C6VAAQ/K0lLYuf572ZLg5fNf+xl+6kJGd9LB8PiSFPcNnde6bz9IJJFZpcs3OpMG0tnyu87cmOgR6ibsVrE/9RvRuE43MfDorTqaPRlw1sl4IPjU5G+k0ftbDRu2aNPnXiaE1rbg= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nativewaves.com; Received: from VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) by GV1PR03MB8333.eurprd03.prod.outlook.com (2603:10a6:150:61::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.29; Tue, 7 Nov 2023 14:12:53 +0000 Received: from VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6]) by VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6%6]) with mapi id 15.20.6954.028; Tue, 7 Nov 2023 14:12:53 +0000 Message-ID: Date: Tue, 7 Nov 2023 15:12:52 +0100 User-Agent: Mozilla Thunderbird From: Michael Riedl To: ffmpeg-devel@ffmpeg.org Content-Language: en-US X-ClientProxiedBy: ZR0P278CA0220.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:6a::22) To VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR03MB4239:EE_|GV1PR03MB8333:EE_ X-MS-Office365-Filtering-Correlation-Id: 59b65c95-740f-4ee5-07f8-08dbdf9ba213 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: /tuINJUe0xXv2rvMOF08wHAJOq+rJVbGgTkWtxeKntp4AngJFLWFvvNNmlExykJVeahAAWPPKcG5cjeZkU+5Bn+ST6euwU++fxJNuI6vsEiT+CWHf8ykBKZOL0fJyLanEoVdR6L6yfnsaeKJF4w1a7el3TXYF7xxUYDpA7/yoW7917KsTyDmJVkEkXaiiuZQibZbI+84s7Zp/2kMmYeCujKMoyAZySICMeLltplbDlqy57LuuJ18xUQDiUZxljrEykA3lDLj3HOkuneVeYMcRHPsgt8i8gq8Hw3JUTpBwI4NUVCz3bhxMgt0fQV9SfbPChEncwKAhKeFhFwzy7luk0HR/Ab6l2DB8AfH+M7emAE6YwLK+2chYzcvsKV+NMrIqkeDDg2cOSzx7KR9Ng+1tzSU7GCwz4QAeUIvdpIBnEoW1RXJvLVJn0waM39uYorFdSPXEcIVfUhH428gRclnJ7aTy/75AEBBf/3iCzlIfQta74sTC9ls5uUTlfaoZckNY+uNML39JxQnCIlJ+V0DRWWgeuXNjDHJS2L6lmDjmE52GUZo8cvN0bW09YNlJmoyBpcRAKO1aaBqA6BR6v4dR35QkmbE+fdHnOwedfcRBZnTXRdBlXGxTvI6fZFo9+BRyHnzLL/Im8DSmGpOzuWnqo7Ov10sbwkZyMc4YGywIesx1CRog+opxPE+QRNvgp4zvJz489lPFISFnCMAYALXZA== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR03MB4239.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(39830400003)(346002)(366004)(376002)(136003)(396003)(230273577357003)(230922051799003)(230173577357003)(186009)(1800799009)(64100799003)(451199024)(6486002)(478600001)(66946007)(2616005)(66476007)(26005)(66556008)(6512007)(41300700001)(2906002)(6506007)(8936002)(6916009)(316002)(5660300002)(30864003)(8676002)(44832011)(36756003)(31696002)(86362001)(83380400001)(38100700002)(66899024)(31686004)(2004002)(45980500001)(43740500002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?xWCWlzsVqYv08rYTxjrtDMRFIW65?= =?utf-8?q?7KIO44kasRBVYY5/M94nZ6xvUDR9WEEIQGbT9hDoLzks4XZWRraBsBS/ylYaYwIkY?= =?utf-8?q?vbFR/KkI5eIsq1TR/KsP5oC6aMVoUL4zYK1M5oXVe8Qaqp5hQxAFGhVz76WfuSSPE?= =?utf-8?q?WfWbUopDEVWlBFrQt2Hn8TN73r7Hc1SJEqaw2hu4LnHtTEgU7rVQ0jUCM+QkaPDD5?= =?utf-8?q?KhSGQwHpZ3BV1NsmsuQGj2soCqYdVJ0VsHGZfDSFwnpAKqvpz1KvEulspGpWzEdtk?= =?utf-8?q?5La7BPQmILi4DNfQsrmsZn0T1k842XQ4aDov0WBYtmTLBhtXAvP8qsu16oJbMrAwF?= =?utf-8?q?c83of2uV7dSEMZAI4V+CA+dSqV3nysaSnMiQKQnegpCpndkLj5Dm0w8scL2kUnh+I?= =?utf-8?q?/G6cqZBqdl/nRoSDTt1ioy2oli/iQmLD9NmDetcGGlpPYVnoqnhxA6ULZ00zzCHL0?= =?utf-8?q?NWr2MT/qJf8fEdUfCOvMLbJR7s2gYao6MA7WBQWD5Cuz6VNm4kbPGkiDxqKCv+3JG?= =?utf-8?q?ehkywcwq0P+cOZcYhEtaXtv1tf9MtK6I9PrR4UqBNYK6COkpc2zUVO+vx4LZfdMPn?= =?utf-8?q?eHA3Y7sOjkq+o72BCKYRWggJX1g5FDGBEn66BzaNwtJxRtpunaz+FPaqMWdAOkgfa?= =?utf-8?q?DDv7HHWN2v7yKSifYOllC4nJN2yN+5gG9sqKmkqfRI3lKd/ClGV5P0fzaesGN8pyg?= =?utf-8?q?T5kXNSl+a+qEBMs/BtFoAfGLK3AD0oyOVEknE9WYHBnlnNTQGo4kXi1AuOHDdqQNa?= =?utf-8?q?lTMphWnoEEMbwOnsAvvXrNzDbriqCLl4JC2kvTP95hA7IL69iQtlu0AbKFMtaWXl5?= =?utf-8?q?jOpFfEPyPwf38EX0I4tHll6+9gRw4IckqlTF2x3aPTn4jdYjkb1WMP+eBwdGLFA1D?= =?utf-8?q?7nW5Wu90vOYLi6It2XbzWxr66drUy9cAQNLkkYm/PcQKHJ1G3OkUChEG2k9POkCH/?= =?utf-8?q?i8+s+YeuRpeNsG/ruFxuFwehJ60cE1deOkFeI0DrQMs8IPJqkk+5CNeSdtYV95otC?= =?utf-8?q?i21FK4erUXmDB+VZ9dAq+KaZnSqeMuuBQDtyf7UunSO1nKVxLUwYHic6UnHgMjOLN?= =?utf-8?q?G6wAu1MppaHc/Tp1meLeReNfb6qv1J/gstFAgVrY/i1Zj7beU6an60KKofXxldo9G?= =?utf-8?q?5TNlUh22gZsa19n7MGFHDkQxd1AC0VLI/O8WDtx5yGK/xmir4gdq/OiY3fGT6U3FZ?= =?utf-8?q?JKtk0lA1dAnY+b0qmg33/FosZAq6ToUvtjkyJhUqCam32VqKsUjLmAuKsXkwwGgc9?= =?utf-8?q?XKnO7/pkJ18f54N5sfWuWuVqyic0o57ZagtcVP4HLjbk1wlRBxHuJfMO+KvdMQHL0?= =?utf-8?q?0gUL1M+EABkDbx9omkyd1fERW4QAVxuAFIm2k9O0KHaP5YsJWTFZ9r6b5CZdShpI5?= =?utf-8?q?HhRQALWAU0mE3oTXpPLdpZFO5hn2gBF7f0VX/7Z7kMIfmcsIRngV3K2PNZdLzWYhv?= =?utf-8?q?iUG4mi1Bwo1n++9L9OmqSOPyeGZCsodE3ZW7pBiNyCJQTx2NSsbRDav9+YERl6ZHM?= =?utf-8?q?3PcbE4xvRPAzInfk93bIOKK5ENVhU4EfEbAcBMiyTQkVZA3epLRQpYo=3D?= X-OriginatorOrg: nativewaves.com X-MS-Exchange-CrossTenant-Network-Message-Id: 59b65c95-740f-4ee5-07f8-08dbdf9ba213 X-MS-Exchange-CrossTenant-AuthSource: VI1PR03MB4239.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Nov 2023 14:12:53.6168 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e4239718-b000-4513-8314-02ef46bd0276 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: JBjyv8WAu2Fb4AMNRFu1hbx+9fuv9wip5TpvmNhi+MRufXmrqyZLNU6y/ZS6h1a970/UQAjQgBAkaUcACSb62Ri8zNHwTzLrzjBhY/WHlBI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR03MB8333 Subject: [FFmpeg-devel] [PATCH v2 4/6] libavformat/webrtc: add common code for WebRTC streaming 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: dS11OeBd1mij Signed-off-by: Michael Riedl --- MAINTAINERS | 1 + libavformat/webrtc.c (new) | 410 +++++++++++++++++++++++++++++++++++++ libavformat/webrtc.h (new) | 70 +++++++ 3 files changed, 481 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b66c3d09a68..840290c4514 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -505,6 +505,7 @@ Muxers/Demuxers: wav.c Michael Niedermayer wc3movie.c Mike Melanson webm dash (matroskaenc.c) Vignesh Venkatasubramanian + webrtc* Michael Riedl webvtt* Matthew J Heaney westwood.c Mike Melanson wtv.c Peter Ross diff --git a/libavformat/webrtc.c b/libavformat/webrtc.c new file mode 100644 index 00000000000..c5a0ce8f5de --- /dev/null +++ b/libavformat/webrtc.c @@ -0,0 +1,410 @@ +/* + * WebRTC-HTTP ingestion/egress protocol (WHIP/WHEP) common code + * + * Copyright (C) 2023 NativeWaves GmbH + * This work is supported by FFG project 47168763. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/avstring.h" +#include "libavutil/opt.h" +#include "libavutil/uuid.h" +#include "libavutil/random_seed.h" +#include "rtpenc_chain.h" +#include "rtsp.h" +#include "webrtc.h" + +static const char* webrtc_get_state_name(const rtcState state) +{ + switch (state) + { + case RTC_NEW: + return "RTC_NEW"; + case RTC_CONNECTING: + return "RTC_CONNECTING"; + case RTC_CONNECTED: + return "RTC_CONNECTED"; + case RTC_DISCONNECTED: + return "RTC_DISCONNECTED"; + case RTC_FAILED: + return "RTC_FAILED"; + case RTC_CLOSED: + return "RTC_CLOSED"; + default: + return "UNKNOWN"; + } +} + +static void webrtc_log(const rtcLogLevel rtcLevel, const char *const message) +{ + int level = AV_LOG_VERBOSE; + switch (rtcLevel) + { + case RTC_LOG_NONE: + level = AV_LOG_QUIET; + break; + case RTC_LOG_DEBUG: + case RTC_LOG_VERBOSE: + level = AV_LOG_DEBUG; + break; + case RTC_LOG_INFO: + level = AV_LOG_VERBOSE; + break; + case RTC_LOG_WARNING: + level = AV_LOG_WARNING; + break; + case RTC_LOG_ERROR: + level = AV_LOG_ERROR; + break; + case RTC_LOG_FATAL: + level = AV_LOG_FATAL; + break; + } + + av_log(NULL, level, "[libdatachannel] %s\n", message); +} + +void ff_webrtc_init_logger(void) +{ + rtcLogLevel level = RTC_LOG_VERBOSE; + switch (av_log_get_level()) + { + case AV_LOG_QUIET: + level = RTC_LOG_NONE; + break; + case AV_LOG_DEBUG: + level = RTC_LOG_DEBUG; + break; + case AV_LOG_VERBOSE: + level = RTC_LOG_VERBOSE; + break; + case AV_LOG_WARNING: + level = RTC_LOG_WARNING; + break; + case AV_LOG_ERROR: + level = RTC_LOG_ERROR; + break; + case AV_LOG_FATAL: + level = RTC_LOG_FATAL; + break; + } + + rtcInitLogger(level, webrtc_log); +} + +int ff_webrtc_generate_media_stream_id(char media_stream_id[37]) +{ + int ret; + AVUUID uuid; + + ret = av_random_bytes(uuid, sizeof(uuid)); + if (ret < 0) { + goto fail; + } + av_uuid_unparse(uuid, media_stream_id); + return 0; + +fail: + return ret; +} + +int ff_webrtc_create_resource(WebRTCContext*const ctx) +{ + int ret; + URLContext* h = NULL; + char* headers = NULL; + char offer_sdp[SDP_MAX_SIZE] = { 0 }; + char response_sdp[SDP_MAX_SIZE] = { 0 }; + + /* set local description */ + if (rtcSetLocalDescription(ctx->peer_connection, "offer") != RTC_ERR_SUCCESS) { + av_log(ctx->avctx, AV_LOG_ERROR, "Failed to set local description\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + + /* create offer */ + ret = rtcGetLocalDescription(ctx->peer_connection, offer_sdp, sizeof(offer_sdp)); + if (ret < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "Failed to get local description\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + av_log(ctx->avctx, AV_LOG_VERBOSE, "offer_sdp: %s\n", offer_sdp); + + /* alloc the http context */ + if ((ret = ffurl_alloc(&h, ctx->avctx->url, AVIO_FLAG_READ_WRITE, NULL)) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "ffurl_alloc failed\n"); + goto fail; + } + + /* set options */ + headers = av_asprintf("Content-type: application/sdp\r\n"); + if (headers && ctx->bearer_token) { + headers = av_asprintf("%sAuthorization: Bearer %s\r\n", headers, ctx->bearer_token); + } + if (!headers) { + ret = AVERROR(ENOMEM); + goto fail; + } + av_log(ctx->avctx, AV_LOG_VERBOSE, "headers: %s\n", headers); + av_opt_set(h->priv_data, "headers", headers, 0); + av_opt_set(h->priv_data, "method", "POST", 0); + av_opt_set_bin(h->priv_data, "post_data", (uint8_t*)offer_sdp, strlen(offer_sdp), 0); + + /* open the http context */ + if ((ret = ffurl_connect(h, NULL)) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "ffurl_connect failed\n"); + goto fail; + } + + /* read the server reply */ + ret = ffurl_read_complete(h, (unsigned char*)response_sdp, sizeof(response_sdp)); + if (ret < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "ffurl_read_complete failed\n"); + goto fail; + } + + av_log(ctx->avctx, AV_LOG_VERBOSE, "response: %s\n", response_sdp); + + /* set remote description */ + ret = rtcSetRemoteDescription(ctx->peer_connection, response_sdp, "answer"); + if (ret < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "Failed to set remote description\n"); + goto fail; + } + + /* save resource location for later use */ + av_opt_get(h->priv_data, "new_location", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&ctx->resource_location); + av_log(ctx->avctx, AV_LOG_VERBOSE, "resource_location: %s\n", ctx->resource_location); + + /* close the http context */ + if ((ret = ffurl_closep(&h)) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "ffurl_closep failed\n"); + goto fail; + } + + av_freep(&headers); + return 0; + +fail: + if (h) { + ffurl_closep(&h); + } + av_freep(&headers); + return ret; +} + +int ff_webrtc_close_resource(WebRTCContext*const ctx) +{ + int ret; + URLContext* h = NULL; + char* headers = NULL; + + if (!ctx->resource_location) { + return 0; + } + + /* alloc the http context */ + if ((ret = ffurl_alloc(&h, ctx->resource_location, AVIO_FLAG_READ_WRITE, NULL)) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "ffurl_alloc failed\n"); + goto fail; + } + + /* set options */ + if (ctx->bearer_token) { + headers = av_asprintf("Authorization: Bearer %s\r\n", ctx->bearer_token); + if (!headers) { + ret = AVERROR(ENOMEM); + goto fail; + } + av_log(ctx->avctx, AV_LOG_VERBOSE, "headers: %s\n", headers); + av_opt_set(h->priv_data, "headers", headers, 0); + } + av_opt_set(h->priv_data, "method", "DELETE", 0); + + /* open the http context */ + if ((ret = ffurl_connect(h, NULL)) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "ffurl_connect failed\n"); + goto fail; + } + + /* close the http context */ + if ((ret = ffurl_closep(&h)) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "ffurl_close failed\n"); + goto fail; + } + +fail: + if (h) { + ffurl_closep(&h); + } + av_freep(&ctx->resource_location); + av_freep(&headers); + return ret; +} + +/* callback for receiving data */ +static int webrtc_read(URLContext *h, unsigned char *buf, int size) +{ + const WebRTCTrack*const ctx = (const WebRTCTrack*const)h->priv_data; + int ret; + + ret = rtcReceiveMessage(ctx->track_id, (char*)buf, &size); + if (ret == RTC_ERR_NOT_AVAIL) { + return AVERROR(EAGAIN); + } + else if (ret == RTC_ERR_TOO_SMALL) { + return AVERROR_BUFFER_TOO_SMALL; + } + else if (ret != RTC_ERR_SUCCESS) { + av_log(ctx->avctx, AV_LOG_ERROR, "rtcReceiveMessage failed: %d\n", ret); + return AVERROR_EOF; + } + return size; +} + +/* callback for sending data */ +static int webrtc_write(URLContext *h, const unsigned char *buf, int size) +{ + const WebRTCTrack*const ctx = (const WebRTCTrack*const)h->priv_data; + int ret; + + ret = rtcSendMessage(ctx->track_id, (const char*)buf, size); + if (ret != RTC_ERR_SUCCESS) { + av_log(ctx->avctx, AV_LOG_ERROR, "rtcSendMessage failed: %d\n", ret); + return AVERROR_EXTERNAL; + } + return size; +} + +static const URLProtocol ff_webrtc_protocol = { + .name = "webrtc", + .url_read = webrtc_read, + .url_write = webrtc_write, +}; + +int ff_webrtc_init_urlcontext(WebRTCContext*const ctx, int track_idx) +{ + WebRTCTrack*const track = &ctx->tracks[track_idx]; + + track->rtp_url_context = av_mallocz(sizeof(URLContext)); + if (!track->rtp_url_context) { + return AVERROR(ENOMEM); + } + + track->rtp_url_context->prot = &ff_webrtc_protocol; + track->rtp_url_context->priv_data = track; + track->rtp_url_context->max_packet_size = RTP_MAX_PACKET_SIZE; + track->rtp_url_context->flags = AVIO_FLAG_READ_WRITE; + track->rtp_url_context->rw_timeout = ctx->rw_timeout; + return 0; +} + +static void webrtc_on_state_change(int pc, rtcState state, void* ptr) +{ + WebRTCContext*const ctx = (WebRTCContext*const)ptr; + + av_log(ctx->avctx, AV_LOG_VERBOSE, "Connection state changed from %s to %s\n", webrtc_get_state_name(ctx->state), webrtc_get_state_name(state)); + ctx->state = state; +} + +int ff_webrtc_init_connection(WebRTCContext *const ctx) +{ + int ret; + rtcConfiguration config = { 0 }; + + if (!(ctx->peer_connection = rtcCreatePeerConnection(&config))) { + av_log(ctx->avctx, AV_LOG_ERROR, "Failed to create PeerConnection\n"); + return AVERROR_EXTERNAL; + } + + rtcSetUserPointer(ctx->peer_connection, ctx); + + if (rtcSetStateChangeCallback(ctx->peer_connection, webrtc_on_state_change)) { + av_log(ctx->avctx, AV_LOG_ERROR, "Failed to set state change callback\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + + return 0; + +fail: + rtcDeletePeerConnection(ctx->peer_connection); + return ret; +} + +int ff_webrtc_convert_codec(enum AVCodecID codec_id, rtcCodec* rtc_codec) +{ + switch (codec_id) + { + case AV_CODEC_ID_H264: + *rtc_codec = RTC_CODEC_H264; + break; + case AV_CODEC_ID_HEVC: + *rtc_codec = RTC_CODEC_H265; + break; + case AV_CODEC_ID_AV1: + *rtc_codec = RTC_CODEC_AV1; + break; + case AV_CODEC_ID_VP8: + *rtc_codec = RTC_CODEC_VP8; + break; + case AV_CODEC_ID_VP9: + *rtc_codec = RTC_CODEC_VP9; + break; + case AV_CODEC_ID_OPUS: + *rtc_codec = RTC_CODEC_OPUS; + break; + case AV_CODEC_ID_AAC: + *rtc_codec = RTC_CODEC_AAC; + break; + case AV_CODEC_ID_PCM_ALAW: + *rtc_codec = RTC_CODEC_PCMA; + break; + case AV_CODEC_ID_PCM_MULAW: + *rtc_codec = RTC_CODEC_PCMU; + break; + default: + *rtc_codec = -1; + return AVERROR(EINVAL); + } + + return 0; +} + +void ff_webrtc_deinit(WebRTCContext*const ctx) +{ + if (ctx->tracks) { + for (int i = 0; i < ctx->nb_tracks; ++i) { + if (ctx->tracks[i].rtp_ctx) + avformat_free_context(ctx->tracks[i].rtp_ctx); + if (ctx->tracks[i].rtp_url_context) + av_freep(&ctx->tracks[i].rtp_url_context); + if (ctx->tracks[i].track_id) + rtcDeleteTrack(ctx->tracks[i].track_id); + } + av_freep(&ctx->tracks); + } + if (ctx->peer_connection) { + rtcDeletePeerConnection(ctx->peer_connection); + ctx->peer_connection = 0; + } + if (ctx->resource_location) + av_freep(&ctx->resource_location); +} \ No newline at end of file diff --git a/libavformat/webrtc.h b/libavformat/webrtc.h new file mode 100644 index 00000000000..786242de377 --- /dev/null +++ b/libavformat/webrtc.h @@ -0,0 +1,70 @@ +/* + * WebRTC-HTTP ingestion/egress protocol (WHIP/WHEP) common code + * + * Copyright (C) 2023 NativeWaves GmbH + * This work is supported by FFG project 47168763. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_WEBRTC_H +#define AVFORMAT_WEBRTC_H + +#include "avformat.h" +#include "avio_internal.h" +#include "libavcodec/codec_id.h" +#include "url.h" +#include "rtc/rtc.h" + +#define RTP_MAX_PACKET_SIZE 1450 + +typedef struct WebRTCTrack { + AVFormatContext *avctx; + int track_id; + AVFormatContext *rtp_ctx; + URLContext *rtp_url_context; +} WebRTCTrack; + +typedef struct WebRTCContext { + AVFormatContext *avctx; + int peer_connection; + rtcState state; + WebRTCTrack *tracks; + int nb_tracks; + const char *resource_location; + + /* options */ + char* bearer_token; + int64_t connection_timeout; + int64_t rw_timeout; +} WebRTCContext; + +#define FF_WEBRTC_COMMON_OPTIONS \ + { "bearer_token", "optional bearer token for authentication and authorization", OFFSET(webrtc_ctx.bearer_token), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, \ + { "connection_timeout", "timeout for establishing a connection", OFFSET(webrtc_ctx.connection_timeout), AV_OPT_TYPE_DURATION, { .i64 = 10000000 }, 1, INT_MAX, FLAGS }, \ + { "rw_timeout", "timeout for receiving/writing data", OFFSET(webrtc_ctx.rw_timeout), AV_OPT_TYPE_DURATION, { .i64 = 1000000 }, 1, INT_MAX, FLAGS } + +int ff_webrtc_close_resource(WebRTCContext*const ctx); +int ff_webrtc_convert_codec(enum AVCodecID codec_id, rtcCodec* rtc_codec); +int ff_webrtc_create_resource(WebRTCContext*const ctx); +void ff_webrtc_deinit(WebRTCContext*const ctx); +int ff_webrtc_generate_media_stream_id(char media_stream_id[37]); +int ff_webrtc_init_connection(WebRTCContext*const ctx); +void ff_webrtc_init_logger(void); +int ff_webrtc_init_urlcontext(WebRTCContext*const ctx, int track_idx); + +#endif /* AVFORMAT_WEBRTC_H */ From patchwork Tue Nov 7 14:12:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Riedl X-Patchwork-Id: 44552 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7aa7:b0:181:818d:5e7f with SMTP id u39csp338207pzh; Tue, 7 Nov 2023 06:13:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IEdSeqj1i+c1FKWStWL9Ljdg3lhRqdUqdHfvvy9iPlp8jptKjphXtTFBGvXlekQyDDjuFtm X-Received: by 2002:a17:906:5346:b0:9dd:b919:79bf with SMTP id j6-20020a170906534600b009ddb91979bfmr2357876ejo.36.1699366415615; Tue, 07 Nov 2023 06:13:35 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id hs20-20020a1709073e9400b009bf7879101dsi1091952ejc.485.2023.11.07.06.13.28; Tue, 07 Nov 2023 06:13:35 -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; dkim=neutral (body hash did not verify) header.i=@nativewaves.onmicrosoft.com header.s=selector2-nativewaves-onmicrosoft-com header.b="HFY/YMAK"; arc=fail (body hash mismatch); 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 2EE1C68CB5E; Tue, 7 Nov 2023 16:13:05 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR03-AM7-obe.outbound.protection.outlook.com (mail-am7eur03on2041.outbound.protection.outlook.com [40.107.105.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7A32F68C562 for ; Tue, 7 Nov 2023 16:13:03 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fv8fcgmXIBCnky43pMG96WFt8VN+jiFBR0/ku+SZ96MQ1LIhJ6S+6Ny/oy2q7UYjPO9ou3RIuYtlPixcCj8rDOiC4UT5h2HSJmTMA9UP2dakEMJ/sFXU4vUS73Lms96iwWys1iAjGIi3fVhnXLSWMPq/6jOotYiPTkdfO7lOawnYiBCwAe2VF9AtV5teKD9DZkJNLJNnKwomOv8ZQLuZSsYWOiCgDsSYRPdG3FHi+gcnmgbcU+KBrVvxz7BeZtnJG6kJbDeiKqBHWIRfR/eZkV+Z8ECIbe0zTWOYtq9IgmvJuvzfvIM4Hib1mg2DOzj7MFaVqvCDEKMjHqrvTWzG9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=C81LoAvXNr2E4SfZm/Il30VEjaCBLHBYWNTu2nDfOGc=; b=Hojh8ukv8I1hf0d/pYeuYeAdr7XpevMpmIhFMHkHtIiaZUO0y5/OLDgtDevgv4e4+16pwA3q4vF0xXmmeK04ZGP9omx8sdwqQKJXfCUmbnLh7kb74P5/htM0aUAoGqBcagCVS4FgKkeHyOfTEMCMENhmmpUxmNpV0IdWfWhOyzW/gtFUAk+scIMY/Vcma1dQefL4ETd9Ng3MnzqY5IXshH8Zwjk1hTSOBIrQYHmAVzkqSbk8OeD0VPwvgR3qVOfolXlWql9lkBlXCJSEhY+p3bojG988bjqCZuppaTX4eXuHcCtwXTZOwcrPIVJraYw+I4bhQAat8fJuMQpULJc2ew== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nativewaves.com; dmarc=pass action=none header.from=nativewaves.com; dkim=pass header.d=nativewaves.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nativewaves.onmicrosoft.com; s=selector2-nativewaves-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=C81LoAvXNr2E4SfZm/Il30VEjaCBLHBYWNTu2nDfOGc=; b=HFY/YMAKsGXQOTfSytf7dzzBxgHGjb6ZRsZSYvBCoNGW/2uCIxOetXhapktV9whwq4Z0Fc0kjKK/Q+NRM7rPYq0lOG90pts9bEZnenIauRwTIIowUX+SJjgh5GGTL/aKswYtEk9jagPzGsa4Jsm77vbijX0WkW9zd+qZgy29sNw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nativewaves.com; Received: from VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) by GV1PR03MB8685.eurprd03.prod.outlook.com (2603:10a6:150:93::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.28; Tue, 7 Nov 2023 14:12:58 +0000 Received: from VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6]) by VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6%6]) with mapi id 15.20.6954.028; Tue, 7 Nov 2023 14:12:58 +0000 Message-ID: Date: Tue, 7 Nov 2023 15:12:58 +0100 User-Agent: Mozilla Thunderbird From: Michael Riedl To: ffmpeg-devel@ffmpeg.org Content-Language: en-US X-ClientProxiedBy: ZR0P278CA0220.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:6a::22) To VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR03MB4239:EE_|GV1PR03MB8685:EE_ X-MS-Office365-Filtering-Correlation-Id: f6805e49-8c15-4b3b-1e18-08dbdf9ba515 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: US+MgT2gOu1uUfdzvpg+u9X0eQnDPKJCn3LKWSw45+86AkT2yPIAu2FHv68SYXHakIg5fgLZiHLcCefiKJ/ioR5HFmx4ZcRd6wC61t2fD2BIOhvcHejknYAlBRqJesYydlBQC1OKOdXW0awHFjoVco572tlsCMh+D8Pjy9Wv8XB1118WoOWAOZfNczUSeWpfJOwhEGUH9DY1YyShZ/7drMrJGhuO9+hoO3Y6tsy3CI8brrsLOYmSlxpdf0nN/urgqAn8A+WESz+s957+OyPJMJDyIlT5v1vWdyhCSRQdN+7zc+pOw2/uzwhjxRqgYNSwA9RHf69htnE1pVd3TB6eC1xYyZAAGJF4y3BMajaZOgcPzt07dhByU3ORcUq3279+wBQ5zD8xkvgUqHScYxH0hs5pqWhy3L8qvJe+TJIljLS6e2Gthodz5Sdc7Rwcx1Ka3GcSZinR912ELzefjOxlkc2onoLuaIsdP7AdJTYTaM2OiNcspNUdkOT4PvD2NRyVYbkzFJoK1Q+tgQwBfmxnTtC7FuVeg1WndBUsL7CwdWvCQHysMk8L/8G98BLvr/5K/BAnVsiUqUtoz+KvcLKhwVoWSFX/PSuYRugvdYKYolRXj4O78AvEbvOcxZVTbItTaFm3za2uW/m2KHBMm/9mHUWUgHeRbREXBoS4oMQBqSY3jipyP7pUCLuHpU+BNNu3 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR03MB4239.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366004)(396003)(376002)(346002)(136003)(39830400003)(230173577357003)(230273577357003)(230922051799003)(64100799003)(451199024)(1800799009)(186009)(6486002)(2906002)(38100700002)(31686004)(30864003)(8676002)(5660300002)(41300700001)(83380400001)(86362001)(8936002)(31696002)(44832011)(6512007)(2616005)(316002)(66476007)(66946007)(66556008)(6916009)(6506007)(26005)(36756003)(478600001)(2004002)(43740500002)(45980500001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?rTANlqERwV9IJobONNU/8D0aUR4p?= =?utf-8?q?HC/YZfuaZsnK5+LpgEWxLWOvmdD4hoAv6vTR7C1q8XaCZCYT4XOVVGFpUxjjxRkrS?= =?utf-8?q?cjgV79yyeQkP2jPjeO4vd5YDiLdJDFbfEl0GcHl/ALYNGUcXyM+WuPOqjdCz6Nv6x?= =?utf-8?q?nESKdFRT0K+IRQNjbCWX87e0FKH6/Fq+yHGNAABC+vt00KXCE6XgotV2kkeZq8oco?= =?utf-8?q?qXh+UwJyvSCzLQmZT1D9tgy4Br67HzgMuEwsv6jpdhkYFGVx/VcjoCFjDeKlPmMyX?= =?utf-8?q?8tZk5AeFyRBmhhen7fg7Pnbrg2kmCRYwH2u0kJTMFJfSo6oXdQjpPmsai9Lw4vRH+?= =?utf-8?q?VRad02TVBuRH6MS3btiPJ45hvb5kp3BVetsC6YT8onD7t0bT+px7yej9oENbUpDdj?= =?utf-8?q?I4jhyRe9N84XWWewu9ma/nJeLQsuu9t5U94s3UfrptwuEEehfVTJyeFXQVVDMwgFI?= =?utf-8?q?ii6Ik6PpgV45rYcFVlU9for+5uhTb8zi0l8oiJbRmNLH1wX9Z89B19CXTKdz9mA0p?= =?utf-8?q?bjlSPvklWq30YVi7dmI6b8eNPFyI6Ljl+tgKvpd851eml2Ff6w683x/EJU/EBVMDg?= =?utf-8?q?iCAPlU3T5NkYVp7LHTHO6hGlazAAFqaWHvXBxJED/cIf+b8YZM+1z6+8b6+QHaI70?= =?utf-8?q?kx0yTqJdBQwqCmpHarcYQ4Cb52MUK1PfjgA7PS2wwlNN4VrPd1VC2IKODLyw4SUoc?= =?utf-8?q?tn8rjAcJXENA8G2RMJxWq6PV+s4KJp0Y03e4ApjCWTtJ2b4xKE7QCm0ZOb5cJ9/xy?= =?utf-8?q?0UI3ftZB0/tD5co3QH4dedGiFCeiZ2l9mvkFSlDRm37Y/BrCxdlcfNCa94IchnSVW?= =?utf-8?q?WGC0ADwwlkZtsJpAmiF2WYSyqMLLek/1/VXfsgr+ZEV4cE3fZJQ5tE6oErad6FIjD?= =?utf-8?q?lN8l33VtZIt8bACiDrlkOnWdwM+OCvZmP4Ga0NrzqU1VJNpa/yk9TzUQnP5aN+0CP?= =?utf-8?q?eLBe35TNHXily5EGcFg5NNko8+BPbHmBCzoMV9eStwwbMduJ1VAmN97OFzSc85yKs?= =?utf-8?q?6lnoobeSuYj/pgdH1FDmhYZMNAqpx5vSQKs7vbKEwa7OGIzhj0mfZNXFF0VlT1WbN?= =?utf-8?q?BhD6p4IKtwtdSAu8ZuOb2g4R55tlWNVjgpwV1FQ/YMMsD3Z50R/6mqWgosdnU5ls1?= =?utf-8?q?pmNLLWjwpixK0CWAs1PTSCDppgzPiP9CRfOsdJKgFxXlLzwQaliWK0RRbEdnTgHST?= =?utf-8?q?JJqQZZ82giOMAqOMimYkSr/FA4gW8WQz44XEiYyWG3CeMpO4A51PCLp5npQxMPFTE?= =?utf-8?q?8HQ9ssjYtTAcrI5d88CeZ3Ba4MC9saIGl+v/oD5OToEAZjOspOl7bpx+bzQY9GSCp?= =?utf-8?q?z+wGWJ15BPFpuUCPNi6gLji4R+PV0D0THF7M7bh9xyyynr8t41fNEnVtq6AAlI1JV?= =?utf-8?q?J7iA6MzuPsyWJv84eZMonn4n5UIWFzFqG9ErW9XH/YC3CBUBOCPcWTQH/y0fxqlIC?= =?utf-8?q?kqdKVpsgE0fw+awxwBM2/OzRg/4T3Lff0/dobM/q6smGfAeupo6D7VAaTI378XZBY?= =?utf-8?q?9Q2+LPIKsYrH5tUqspRNQsjfDolt1ITfV3eljiTbb9Pvzi8uSsiLFOg=3D?= X-OriginatorOrg: nativewaves.com X-MS-Exchange-CrossTenant-Network-Message-Id: f6805e49-8c15-4b3b-1e18-08dbdf9ba515 X-MS-Exchange-CrossTenant-AuthSource: VI1PR03MB4239.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Nov 2023 14:12:58.6738 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e4239718-b000-4513-8314-02ef46bd0276 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ijAZIz+iusxqjkNLkHDlrISXCG2f2hHNFAkHS1Xeo3apzWgcBSuQyiGFrMBYLco5mdm1Atq8guw0gqycc6UuxUuxUmWXBkupW8I1sRRcOes= X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR03MB8685 Subject: [FFmpeg-devel] [PATCH v2 5/6] libavformat/webrtc_demux: add WebRTC-HTTP egress protocol (WHEP) demuxer 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: R9lMRY7eZjXr Signed-off-by: Michael Riedl --- Changelog | 4 + configure | 2 + doc/demuxers.texi | 22 +++ libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/webrtc_demux.c (new) | 246 +++++++++++++++++++++++++++++++ 6 files changed, 276 insertions(+) diff --git a/Changelog b/Changelog index 8f0606fc267..45c6c752a06 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,10 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. +version : +- WHEP demuxer + + version 6.1: - libaribcaption decoder - Playdate video decoder and demuxer diff --git a/configure b/configure index 187f16b425d..02c6f7f2c5d 100755 --- a/configure +++ b/configure @@ -3557,6 +3557,8 @@ wav_demuxer_select="riffdec" wav_muxer_select="riffenc" webm_chunk_muxer_select="webm_muxer" webm_dash_manifest_demuxer_select="matroska_demuxer" +whep_demuxer_deps="libdatachannel sdp_demuxer" +whep_demuxer_select="http_protocol" wtv_demuxer_select="mpegts_demuxer riffdec" wtv_muxer_select="mpegts_muxer riffenc" xmv_demuxer_select="riffdec" diff --git a/doc/demuxers.texi b/doc/demuxers.texi index ca1563abb03..81940b8ece7 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -943,4 +943,26 @@ which in turn, acts as a ceiling for the size of scripts that can be read. Default is 1 MiB. @end table +@section whep + +WebRTC-HTTP egress protocol (WHEP) demuxer. + +This demuxers allows reading media from a remote media server using the +WebRTC-HTTP egress protocol (WHEP) as defined in +@url{https://datatracker.ietf.org/doc/draft-murillo-whep/02}. Currently, only a +single video (H.264) and a single audio stream (OPUS) are supported. + +This demuxer accepts the following options: +@table @option +@item bearer_token +Optional bearer token for authentication and authorization to the HTTP server. +Default is @code{NULL}. +@item connection_timeout +Timeout for establishing a connection to the media server. +Default is 10 seconds. +@item rw_timeout +Timeout for receiving/writing data from/to the media server. +Default is 1 second. +@end table + @c man end DEMUXERS diff --git a/libavformat/Makefile b/libavformat/Makefile index 329055ccfd9..f790fa8cae4 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -621,6 +621,7 @@ OBJS-$(CONFIG_WEBM_CHUNK_MUXER) += webm_chunk.o OBJS-$(CONFIG_WEBP_MUXER) += webpenc.o OBJS-$(CONFIG_WEBVTT_DEMUXER) += webvttdec.o subtitles.o OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o +OBJS-$(CONFIG_WHEP_DEMUXER) += webrtc.o webrtc_demux.o OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o OBJS-$(CONFIG_WSAUD_MUXER) += westwood_audenc.o OBJS-$(CONFIG_WSD_DEMUXER) += wsddec.o rawdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index d4b505a5a32..7acb05634c8 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -504,6 +504,7 @@ extern const FFOutputFormat ff_webm_chunk_muxer; extern const FFOutputFormat ff_webp_muxer; extern const AVInputFormat ff_webvtt_demuxer; extern const FFOutputFormat ff_webvtt_muxer; +extern const AVInputFormat ff_whep_demuxer; extern const AVInputFormat ff_wsaud_demuxer; extern const FFOutputFormat ff_wsaud_muxer; extern const AVInputFormat ff_wsd_demuxer; diff --git a/libavformat/webrtc_demux.c b/libavformat/webrtc_demux.c new file mode 100644 index 00000000000..391eea6d654 --- /dev/null +++ b/libavformat/webrtc_demux.c @@ -0,0 +1,246 @@ +/* + * WebRTC-HTTP egress protocol (WHEP) demuxer using libdatachannel + * + * Copyright (C) 2023 NativeWaves GmbH + * This work is supported by FFG project 47168763. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "internal.h" +#include "libavutil/avstring.h" +#include "libavutil/time.h" +#include "libavutil/random_seed.h" +#include "version.h" +#include "rtsp.h" +#include "webrtc.h" + +typedef struct WHEPContext { + const AVClass *av_class; + WebRTCContext webrtc_ctx; +} WHEPContext; + +static int whep_read_header(AVFormatContext* avctx) +{ + WHEPContext*const ctx = (WHEPContext*const)avctx->priv_data; + int ret, i; + char media_stream_id[37] = { 0 }; + rtcTrackInit track_init; + AVDictionary* options = NULL; + const AVInputFormat* infmt; + AVStream* stream; + FFIOContext sdp_pb; + int64_t timeout; + + ff_webrtc_init_logger(); + ret = ff_webrtc_init_connection(&ctx->webrtc_ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize connection\n"); + goto fail; + } + + /* configure audio and video track */ + ret = ff_webrtc_generate_media_stream_id(media_stream_id); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to generate media stream id\n"); + goto fail; + } + ctx->webrtc_ctx.tracks = av_mallocz(2 * sizeof(WebRTCTrack)); + ctx->webrtc_ctx.nb_tracks = 2; + ctx->webrtc_ctx.avctx = avctx; + if (!ctx->webrtc_ctx.tracks) { + ret = AVERROR(ENOMEM); + goto fail; + } + for (i=0; i < ctx->webrtc_ctx.nb_tracks; i++) { + ctx->webrtc_ctx.tracks[i].avctx = avctx; + } + + /* configure video track */ + memset(&track_init, 0, sizeof(rtcTrackInit)); + track_init.direction = RTC_DIRECTION_RECVONLY; + track_init.codec = RTC_CODEC_H264; // TODO: support more codecs once libdatachannel C api supports them + track_init.payloadType = 96; + track_init.ssrc = av_get_random_seed(); + track_init.mid = "0"; + track_init.name = LIBAVFORMAT_IDENT; + track_init.msid = media_stream_id; + track_init.trackId = av_asprintf("%s-video", media_stream_id); + track_init.profile = "profile-level-id=42e01f;packetization-mode=1;level-asymmetry-allowed=1"; + + ctx->webrtc_ctx.tracks[0].track_id = rtcAddTrackEx(ctx->webrtc_ctx.peer_connection, &track_init); + if (!ctx->webrtc_ctx.tracks[0].track_id) { + av_log(avctx, AV_LOG_ERROR, "Failed to add track\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + + /* configure audio track */ + memset(&track_init, 0, sizeof(rtcTrackInit)); + track_init.direction = RTC_DIRECTION_RECVONLY; + track_init.codec = RTC_CODEC_OPUS; // TODO: support more codecs once libdatachannel C api supports them + track_init.payloadType = 97; + track_init.ssrc = av_get_random_seed(); + track_init.mid = "1"; + track_init.name = LIBAVFORMAT_IDENT; + track_init.msid = media_stream_id; + track_init.trackId = av_asprintf("%s-audio", media_stream_id); + track_init.profile = "minptime=10;maxaveragebitrate=96000;stereo=1;sprop-stereo=1;useinbandfec=1"; + + ctx->webrtc_ctx.tracks[1].track_id = rtcAddTrackEx(ctx->webrtc_ctx.peer_connection, &track_init); + if (!ctx->webrtc_ctx.tracks[1].track_id) { + av_log(avctx, AV_LOG_ERROR, "Failed to add track\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + + /* create resource */ + ret = ff_webrtc_create_resource(&ctx->webrtc_ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "webrtc_create_resource failed\n"); + goto fail; + } + + /* wait for connection to be established */ + timeout = av_gettime_relative() + ctx->webrtc_ctx.connection_timeout; + while (ctx->webrtc_ctx.state != RTC_CONNECTED) { + if (ctx->webrtc_ctx.state == RTC_FAILED || ctx->webrtc_ctx.state == RTC_CLOSED || av_gettime_relative() > timeout) { + av_log(avctx, AV_LOG_ERROR, "Failed to open connection\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + + av_log(avctx, AV_LOG_VERBOSE, "Waiting for PeerConnection to open\n"); + av_usleep(1000); + } + + /* initialize SDP muxer per track */ + for (int i = 0; i < ctx->webrtc_ctx.nb_tracks; i++) { + char sdp_track[SDP_MAX_SIZE] = { 0 }; + ret = rtcGetTrackDescription(ctx->webrtc_ctx.tracks[i].track_id, sdp_track, sizeof(sdp_track)); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "rtcGetTrackDescription failed\n"); + goto fail; + } + + ffio_init_read_context(&sdp_pb, (uint8_t*)sdp_track, strlen(sdp_track)); + + infmt = av_find_input_format("sdp"); + if (!infmt) + goto fail; + ctx->webrtc_ctx.tracks[i].rtp_ctx = avformat_alloc_context(); + if (!ctx->webrtc_ctx.tracks[i].rtp_ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + ctx->webrtc_ctx.tracks[i].rtp_ctx->max_delay = avctx->max_delay; + ctx->webrtc_ctx.tracks[i].rtp_ctx->pb = &sdp_pb.pub; + ctx->webrtc_ctx.tracks[i].rtp_ctx->interrupt_callback = avctx->interrupt_callback; + + if ((ret = ff_copy_whiteblacklists(ctx->webrtc_ctx.tracks[i].rtp_ctx, avctx)) < 0) + goto fail; + + av_dict_set(&options, "sdp_flags", "custom_io", 0); + + ret = avformat_open_input(&ctx->webrtc_ctx.tracks[i].rtp_ctx, "temp.sdp", infmt, &options); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "avformat_open_input failed\n"); + goto fail; + } + + ret = ff_webrtc_init_urlcontext(&ctx->webrtc_ctx, i); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "webrtc_init_urlcontext failed\n"); + goto fail; + } + ret = ffio_fdopen(&ctx->webrtc_ctx.tracks[i].rtp_ctx->pb, ctx->webrtc_ctx.tracks[i].rtp_url_context); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "ffio_fdopen failed\n"); + goto fail; + } + + /* copy codec parameters */ + stream = avformat_new_stream(avctx, NULL); + if (!stream) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = avcodec_parameters_copy(stream->codecpar, ctx->webrtc_ctx.tracks[i].rtp_ctx->streams[0]->codecpar); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "avcodec_parameters_copy failed\n"); + goto fail; + } + stream->time_base = ctx->webrtc_ctx.tracks[i].rtp_ctx->streams[0]->time_base; + } + + return 0; + +fail: + ff_webrtc_deinit(&ctx->webrtc_ctx); + return ret; +} + +static int whep_read_close(AVFormatContext* avctx) +{ + WHEPContext*const ctx = (WHEPContext*const)avctx->priv_data; + int ret = 0; + + /* close resource */ + ret = ff_webrtc_close_resource(&ctx->webrtc_ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "webrtc_close_resource failed\n"); + } + + ff_webrtc_deinit(&ctx->webrtc_ctx); + + return ret; +} + +static int whep_read_packet(AVFormatContext* avctx, AVPacket* pkt) +{ + const WHEPContext*const s = (const WHEPContext*const)avctx->priv_data; + const WebRTCTrack*const track = &s->webrtc_ctx.tracks[pkt->stream_index]; + pkt->stream_index = 0; + return av_read_frame(track->rtp_ctx, pkt); +} + + +#define OFFSET(x) offsetof(WHEPContext, x) +#define FLAGS AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + FF_WEBRTC_COMMON_OPTIONS, + { NULL }, +}; + +static const AVClass whep_demuxer_class = { + .class_name = "WHEP demuxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVInputFormat ff_whep_demuxer = { + .name = "whep", + .long_name = NULL_IF_CONFIG_SMALL("WebRTC-HTTP egress protocol (WHEP) demuxer"), + .flags = AVFMT_NOFILE | AVFMT_EXPERIMENTAL, + .priv_class = &whep_demuxer_class, + .priv_data_size = sizeof(WHEPContext), + .read_header = whep_read_header, + .read_packet = whep_read_packet, + .read_close = whep_read_close, +}; From patchwork Tue Nov 7 14:13:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Riedl X-Patchwork-Id: 44554 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7aa7:b0:181:818d:5e7f with SMTP id u39csp338457pzh; Tue, 7 Nov 2023 06:13:53 -0800 (PST) X-Google-Smtp-Source: AGHT+IG3v4IfTtb1+TxIfRW2JKDHMR4Uc1rTFNMn+GkTn4vo/U4JMQzjKkkYA5oM4Nl88bryPKIc X-Received: by 2002:aa7:d392:0:b0:53e:6013:7fe8 with SMTP id x18-20020aa7d392000000b0053e60137fe8mr26775204edq.22.1699366432902; Tue, 07 Nov 2023 06:13:52 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id s26-20020aa7d79a000000b005435b4f879bsi5439335edq.691.2023.11.07.06.13.48; Tue, 07 Nov 2023 06:13:52 -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; dkim=neutral (body hash did not verify) header.i=@nativewaves.onmicrosoft.com header.s=selector2-nativewaves-onmicrosoft-com header.b=GpEqACae; arc=fail (body hash mismatch); 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 2D22F68CB8A; Tue, 7 Nov 2023 16:13:09 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on2086.outbound.protection.outlook.com [40.107.21.86]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CB83F68CB83 for ; Tue, 7 Nov 2023 16:13:06 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LPX+QujBlOR1vs5X3BrvzrCzXfkNA/mIRerVUQW/dyQad0gQmXaMqKs13Ojf9uuqJFJ7mMzg5kwFc/UWzrq3+T/TGLOg4TBX+DJM6xOL0FsorifjX5pOB+Uacwc8p4W6o1xqfyv7aJu8DTSOKLgvAzq333yq+xJfEMe7JafqVTKs5+r7zKioAw+G7Mmif+SyUz+EHfpRyWLY7EfOz6ZJFniSN1ze23uUDVo8zZPAMmk78+3xoUbDWRk+SA0n+tJm/i5Jno3kV9sJuCfFsCcwgBHFZKvBZt3bjgRlCgFOpCqEcUFehN7VtrGiwOmdyt47N2lN3jBoZJ9l0FCFq6BcrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=nkPRbJQrjwCrzHzvR4muOVKo9fb/oxWKHa/tty7P5KM=; b=mF/eV9BeR/MksTiE3g44JqxI9hnFTXsqxQjHKnq46x3QsYtd/npSHmMGgs7zBfhRCh+wUDqOzlq0O6Dfa1KQZ9loTs1jF8nWtaeKSbD0XhFN7nNGF92mhvg9h9I9nkjWm3JfnAvV4bXFswPOyewKdVMOGrgIRVw2bb67jWFgIOghHtRBbub1ysfC8q+59lQxp5F9cr4xM4vyqUGEB/RMYNE9+wJh1yMC/LlhKFppkdIfMLfGJ7oqkMHkb1uEf2a4x3hdO5zXNrp2izngA2IFJwA9fVzNX70CmUez7Wl1qdOIfUlvMx9VSyGUE1iM7wcCyd1dW/szLEwL/490jhwgOw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nativewaves.com; dmarc=pass action=none header.from=nativewaves.com; dkim=pass header.d=nativewaves.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nativewaves.onmicrosoft.com; s=selector2-nativewaves-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nkPRbJQrjwCrzHzvR4muOVKo9fb/oxWKHa/tty7P5KM=; b=GpEqACaeGsi7uy01C2Jc1KSXg9tI7HtEdDhUxxTVqZiq39mrOCkb1zekoltmwsedNPTKwh0WMiHUW9Wb1BTdKi+WE1RyDwFDtXNRaabV5rkbfRVVb6Kr0TS2zik6C/wmWQpLFI5DN3iZSL4bCq3RmRze1LkkCecpBl45y/zw6vk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nativewaves.com; Received: from VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) by GV1PR03MB8685.eurprd03.prod.outlook.com (2603:10a6:150:93::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.28; Tue, 7 Nov 2023 14:13:04 +0000 Received: from VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6]) by VI1PR03MB4239.eurprd03.prod.outlook.com ([fe80::150d:b41:699f:42b6%6]) with mapi id 15.20.6954.028; Tue, 7 Nov 2023 14:13:04 +0000 Message-ID: <3ba38498-a74a-4a56-955f-c1aa16153404@nativewaves.com> Date: Tue, 7 Nov 2023 15:13:03 +0100 User-Agent: Mozilla Thunderbird From: Michael Riedl To: ffmpeg-devel@ffmpeg.org Content-Language: en-US X-ClientProxiedBy: ZR0P278CA0220.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:6a::22) To VI1PR03MB4239.eurprd03.prod.outlook.com (2603:10a6:803:5f::26) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1PR03MB4239:EE_|GV1PR03MB8685:EE_ X-MS-Office365-Filtering-Correlation-Id: 6041096a-3e61-47b5-de8c-08dbdf9ba8a3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: RR9uBTxroHbmYx0+grwfK0Ek+UE3hfrZolSbOfwz9UlZgxh1WoZ0ToN53CavubqPfEaB67gMYL+bgwxJim+sR3igD/0ceIQtmUX9gCIE9b3JTam5HSTF7zoitV6SvrrkL/nGBWJouo0zBFizf8FkSy8/40yjnLxCtl2I5a+A2aOf67RHAXIkSf9C/PBB8/tqbYoCdDq+khbUnPPB1OdnV1ldc2IBGQmdD0eo2ofWmazrhFPY+OvHwRWUQD+IgL0tgOjxI988a+zDu4cYPZf4A1Yn0Z83msRmwPd04gg+dYlnQoyhbUHahcg899XupYfX3UK9G3QhnZIma5T/zR0Rtl2QI+PjTXPZ214qyUCbS9/QaRfO+zLAbAppom8Etv4f64D7aJ4y2wsNztXwHnaRZbYAA2IvbDVPWHqs/DVxPNUNnJ1xvQ8pkm3RX1WF5/FcgbDZtfpXO97MFrF6tA4DI1b0vho7/IUb4k1uGww/pj4eQFw2DQHbqKPK/ItiLT+z9qgnfW8mbu07RgASymVZBYzas3S5ZbX6n5gNrawZvx5KR3X994dUCRjzut0xrIg5MnWOuwJvWcZ/u6N7eKJuBY5nuL/zaWJG1W1iqbD/vJCrTAxhJS5h4IbpjfJNBpSmS31grnit/ZLKJaI9tzqEIlgGBkQU5tukSruzfxOrDY6Rlqc1xd2yId84Y/Ju7UOM5fN0XpSp1kxcLp4bNAw0ZQ== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:VI1PR03MB4239.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366004)(396003)(376002)(346002)(136003)(39830400003)(230173577357003)(230273577357003)(230922051799003)(64100799003)(451199024)(1800799009)(186009)(6486002)(2906002)(38100700002)(31686004)(30864003)(8676002)(5660300002)(41300700001)(83380400001)(86362001)(8936002)(31696002)(44832011)(6512007)(2616005)(316002)(66476007)(66946007)(66556008)(6916009)(6506007)(26005)(36756003)(478600001)(2004002)(43740500002)(45980500001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?GdijB5VFHDz6wTnojWhcLA48uLYi?= =?utf-8?q?Q0zpc90RG9m9pftmOXnzt2ZkAQ2W2HGXCvmG7tlocfTELoZkzSJjeAvozXQDWBGp3?= =?utf-8?q?UDwuREe6cnbEbYpMQX8+hyDSY3KghalQDTFMBh1KHdtyT+dt22tmL8iGypa0W1FQv?= =?utf-8?q?DzIHe9JDkfP8qDgrddpQEtKuXiDy+I4w/9Yr4FtREQ7eIquxzrRk4UTjWSDOYwnh4?= =?utf-8?q?1mhfPFes2qZIwlSe1E8yGoDjrJfXxoJ5RCZ3ULrt4DFj3xmkmTySuN6BF79wWgv22?= =?utf-8?q?fokSQSquQQQWEEgbjvp+mluYGQyFkZJknTheNbQzGH4OiCxMW5Vq60efz9WzybNtg?= =?utf-8?q?XGlG4MtKj3y0u6efodCVUBDj4Fe656E2oq93sF6hTR+Hd5XQI90hp1BQYoMUAwP06?= =?utf-8?q?3gm4U9qlh1eekPgKez+uPbY31H8hRQdiQrp7nz8Tk731kWAzIc40vIQd3EtwFcUzD?= =?utf-8?q?OXszh3PQBrnt6z33bgQEGl1Nivpjq6MKzrVdLYAEADiHNyVFX9Wwvk69TsPr/RCPw?= =?utf-8?q?N4OQDS3hvt/lpJDV+PtEAcvIUDl9zE71TJ3v9P32M5DJCXw/LZVsffFuXzk4fL9L1?= =?utf-8?q?gPvTfiCTGO4QbOfHDv8T+L36YDMg5yZlFw4RH4ScawRSAn0VeTvzBQj3kOdRXBN19?= =?utf-8?q?9lh66RBSmBKIig6YMHKNMDlVqk0s/7sssg9lpuOIWJ+0M7cGe9s51JJZR5gvdkVWe?= =?utf-8?q?M7XnWatp7bV12w+6bsXuUkUF5B5MSfjC3MFPqL50l5rWmElrwQjJmpR8la7sxXrlq?= =?utf-8?q?kOWwqEBN1PLDg0CGo890qA416l8yQ9KTQiWugFiO5zJu/zn/RZ1iqIKESG8BhdDZU?= =?utf-8?q?klO7Df41sRUYil95B773eSRj9PCEAj6PNHX7uDqLYAd9PxamaGEcKXU8OT3JoGW8H?= =?utf-8?q?1K9XYvUrDTUOqDdHRpubszWXMcHYHCMsZsUBJt0pFGl3Ph1WNz7ITNL1fUZ3kokZO?= =?utf-8?q?CV1IFzE0U/Lpjd77JKV0yMaVMLmHvar45jSLmeitTIjQ4xMXgXXj8nBzSqBXTZd5r?= =?utf-8?q?CMTWWeRxz0TJ2gu0kMWYc84jkWeUXMfwNrameBeDW7lAkTPn6HErdd4XLXuwn5DUd?= =?utf-8?q?NuXO4GspC1JrRMRVknlMjJv4H1KKUjo7TaTyMZMB/Q2rC13JoKNG/7xYImyBH7fwc?= =?utf-8?q?5mnKYdVek0QQiXK42OA4cdwJBvxYjKICurZue7EMLI/+8rfkIFTzSeQQPFdTipRBk?= =?utf-8?q?vkAV8DfE39FK3Wvq/THaGINLKApa8JpL9ugMK6/BTfvTl5UREqU00dmLDALvtjohe?= =?utf-8?q?y6cmE/mZ0WEUrNpuHGjt8YgP1XvDYQxrC0fPSz3cA5WVBgLxtqXuzoCtKz6y3oE2Y?= =?utf-8?q?oGOJO4+UEzio0CYF72d0PhBYRSCMUKnV0Y5GSvhzJAzxevOGNccSDo5oW4Xi+eykm?= =?utf-8?q?3WG9lomIPSnvqVupTwpTb6kdmYqthPcD/K24rINdm4ON+8UQGV+b8RBjsNPIgOLvn?= =?utf-8?q?NcL1U+RgLMjQoCpgXrbxFihQRO/0SWNwx4UvzJ+AnMRfEdisG5hVhsqX4sxA33qWR?= =?utf-8?q?4jDPOe38x1MSAKIig1fxmfJkiPEqcJdSvolgaIYNGQM7FEO7h8pEZ0Q=3D?= X-OriginatorOrg: nativewaves.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6041096a-3e61-47b5-de8c-08dbdf9ba8a3 X-MS-Exchange-CrossTenant-AuthSource: VI1PR03MB4239.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Nov 2023 14:13:04.6541 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: e4239718-b000-4513-8314-02ef46bd0276 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: T5oo7yaTCmYGQQEAlYmElYO9EW9o3dO4VhWkVx8MIFRqeqAvA/8UiTSGKTc9XrveCwybGc6GgKmMHRN4JZP/lJC4x+ZwnjpKfeF9prqga1o= X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR03MB8685 Subject: [FFmpeg-devel] [PATCH v2 6/6] libavformat/webrtc_mux: add WebRTC-HTTP ingestion protocol (WHIP) muxer 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: gc4Ojo4Gep+F Signed-off-by: Michael Riedl --- Changelog | 1 + configure | 2 + doc/muxers.texi | 21 +++ libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/webrtc_mux.c (new) | 273 +++++++++++++++++++++++++++++++++ 6 files changed, 299 insertions(+) diff --git a/Changelog b/Changelog index 45c6c752a06..2604a2925bb 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,7 @@ releases are sorted from youngest to oldest. version : - WHEP demuxer +- WHIP muxer version 6.1: diff --git a/configure b/configure index 02c6f7f2c5d..05cfbbb2376 100755 --- a/configure +++ b/configure @@ -3557,6 +3557,8 @@ wav_demuxer_select="riffdec" wav_muxer_select="riffenc" webm_chunk_muxer_select="webm_muxer" webm_dash_manifest_demuxer_select="matroska_demuxer" +whip_muxer_deps="libdatachannel rtp_muxer" +whip_muxer_select="http_protocol rtpenc_chain" whep_demuxer_deps="libdatachannel sdp_demuxer" whep_demuxer_select="http_protocol" wtv_demuxer_select="mpegts_demuxer riffdec" diff --git a/doc/muxers.texi b/doc/muxers.texi index f6071484ff6..144b0638571 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -2846,4 +2846,25 @@ ffmpeg -f webm_dash_manifest -i video1.webm \ manifest.xml @end example +@section whip + +WebRTC-HTTP ingestion protocol (WHIP) muxer. + +This muxer allows sending audio and video streams to a remote media server +using the WebRTC-HTTP ingestion protocol (WHIP) as defined in +@url{https://datatracker.ietf.org/doc/draft-ietf-wish-whip/}. + +This muxer supports the following options: +@table @option +@item bearer_token +Optional bearer token for authentication and authorization to the HTTP server. +Default is @code{NULL}. +@item connection_timeout +Timeout for establishing a connection to the media server. +Default is 10 seconds. +@item rw_timeout +Timeout for receiving/writing data from/to the media server. +Default is 1 second. +@end table + @c man end MUXERS diff --git a/libavformat/Makefile b/libavformat/Makefile index f790fa8cae4..000fd308be2 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -621,6 +621,7 @@ OBJS-$(CONFIG_WEBM_CHUNK_MUXER) += webm_chunk.o OBJS-$(CONFIG_WEBP_MUXER) += webpenc.o OBJS-$(CONFIG_WEBVTT_DEMUXER) += webvttdec.o subtitles.o OBJS-$(CONFIG_WEBVTT_MUXER) += webvttenc.o +OBJS-$(CONFIG_WHIP_MUXER) += webrtc.o webrtc_mux.o OBJS-$(CONFIG_WHEP_DEMUXER) += webrtc.o webrtc_demux.o OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o OBJS-$(CONFIG_WSAUD_MUXER) += westwood_audenc.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 7acb05634c8..2ad2a6dcba2 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -504,6 +504,7 @@ extern const FFOutputFormat ff_webm_chunk_muxer; extern const FFOutputFormat ff_webp_muxer; extern const AVInputFormat ff_webvtt_demuxer; extern const FFOutputFormat ff_webvtt_muxer; +extern const FFOutputFormat ff_whip_muxer; extern const AVInputFormat ff_whep_demuxer; extern const AVInputFormat ff_wsaud_demuxer; extern const FFOutputFormat ff_wsaud_muxer; diff --git a/libavformat/webrtc_mux.c b/libavformat/webrtc_mux.c new file mode 100644 index 00000000000..2a659ffa41b --- /dev/null +++ b/libavformat/webrtc_mux.c @@ -0,0 +1,273 @@ +/* + * WebRTC-HTTP ingestion protocol (WHIP) muxer using libdatachannel + * + * Copyright (C) 2023 NativeWaves GmbH + * This work is supported by FFG project 47168763. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "internal.h" +#include "libavutil/avstring.h" +#include "libavutil/time.h" +#include "mux.h" +#include "rtpenc.h" +#include "rtpenc_chain.h" +#include "rtsp.h" +#include "webrtc.h" +#include "version.h" + +typedef struct WHIPContext { + AVClass *av_class; + WebRTCContext webrtc_ctx; +} WHIPContext; + + +static void whip_deinit(AVFormatContext* avctx); +static int whip_init(AVFormatContext* avctx) +{ + WHIPContext*const ctx = (WHIPContext*const)avctx->priv_data; + AVStream* stream; + const AVCodecParameters* codecpar; + int i, ret; + char media_stream_id[37] = { 0 }; + rtcTrackInit track_init; + const AVChannelLayout supported_layout = AV_CHANNEL_LAYOUT_STEREO; + const RTPMuxContext* rtp_mux_ctx; + WebRTCTrack* track; + char sdp_stream[SDP_MAX_SIZE] = { 0 }; + char* fmtp; + + ctx->webrtc_ctx.avctx = avctx; + ff_webrtc_init_logger(); + ret = ff_webrtc_init_connection(&ctx->webrtc_ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to initialize connection\n"); + goto fail; + } + + if (!(ctx->webrtc_ctx.tracks = av_mallocz(sizeof(WebRTCTrack) * avctx->nb_streams))) { + av_log(avctx, AV_LOG_ERROR, "Failed to allocate tracks\n"); + ret = AVERROR(ENOMEM); + goto fail; + } + + /* configure tracks */ + ret = ff_webrtc_generate_media_stream_id(media_stream_id); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to generate media stream id\n"); + goto fail; + } + + for (i = 0; i < avctx->nb_streams; ++i) { + stream = avctx->streams[i]; + codecpar = stream->codecpar; + track = &ctx->webrtc_ctx.tracks[i]; + + switch (codecpar->codec_type) + { + case AVMEDIA_TYPE_VIDEO: + /* based on rtpenc */ + avpriv_set_pts_info(stream, 32, 1, 90000); + break; + case AVMEDIA_TYPE_AUDIO: + if (codecpar->sample_rate != 48000) { + av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate. Only 48kHz is supported\n"); + ret = AVERROR(EINVAL); + goto fail; + } + if (av_channel_layout_compare(&codecpar->ch_layout, &supported_layout) != 0) { + av_log(avctx, AV_LOG_ERROR, "Unsupported channel layout. Only stereo is supported\n"); + ret = AVERROR(EINVAL); + goto fail; + } + /* based on rtpenc */ + avpriv_set_pts_info(stream, 32, 1, codecpar->sample_rate); + break; + default: + continue; + } + + ret = ff_webrtc_init_urlcontext(&ctx->webrtc_ctx, i); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "webrtc_init_urlcontext failed\n"); + goto fail; + } + + ret = ff_rtp_chain_mux_open(&track->rtp_ctx, avctx, stream, track->rtp_url_context, RTP_MAX_PACKET_SIZE, i); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "ff_rtp_chain_mux_open failed\n"); + goto fail; + } + rtp_mux_ctx = (const RTPMuxContext*)ctx->webrtc_ctx.tracks[i].rtp_ctx->priv_data; + + memset(&track_init, 0, sizeof(rtcTrackInit)); + track_init.direction = RTC_DIRECTION_SENDONLY; + track_init.payloadType = rtp_mux_ctx->payload_type; + track_init.ssrc = rtp_mux_ctx->ssrc; + track_init.mid = av_asprintf("%d", i); + track_init.name = LIBAVFORMAT_IDENT; + track_init.msid = media_stream_id; + track_init.trackId = av_asprintf("%s-video-%d", media_stream_id, i); + + ret = ff_webrtc_convert_codec(codecpar->codec_id, &track_init.codec); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to convert codec\n"); + goto fail; + } + + /* parse fmtp from global header */ + ret = ff_sdp_write_media(sdp_stream, sizeof(sdp_stream), stream, i, NULL, NULL, 0, 0, NULL); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to write sdp\n"); + goto fail; + } + fmtp = strstr(sdp_stream, "a=fmtp:"); + if (fmtp) { + track_init.profile = av_strndup(fmtp + 10, strchr(fmtp, '\r') - fmtp - 10); + track_init.profile = av_asprintf("%s;level-asymmetry-allowed=1", track_init.profile); + memset(sdp_stream, 0, sizeof(sdp_stream)); + } + + track->track_id = rtcAddTrackEx(ctx->webrtc_ctx.peer_connection, &track_init); + if (track->track_id < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to add track\n"); + ret = AVERROR(EINVAL); + goto fail; + } + } + + return 0; + +fail: + return ret; +} + +static int whip_write_header(AVFormatContext* avctx) +{ + WHIPContext*const ctx = (WHIPContext*const)avctx->priv_data; + int ret; + int64_t timeout; + + ret = ff_webrtc_create_resource(&ctx->webrtc_ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to create resource\n"); + goto fail; + } + + /* wait for connection to be established */ + timeout = av_gettime_relative() + ctx->webrtc_ctx.connection_timeout; + while (ctx->webrtc_ctx.state != RTC_CONNECTED) { + if (ctx->webrtc_ctx.state == RTC_FAILED || ctx->webrtc_ctx.state == RTC_CLOSED || av_gettime_relative() > timeout) { + av_log(avctx, AV_LOG_ERROR, "Failed to open connection\n"); + ret = AVERROR_EXTERNAL; + goto fail; + } + + av_log(avctx, AV_LOG_VERBOSE, "Waiting for PeerConnection to open\n"); + av_usleep(1000); + } + + return 0; + +fail: + return ret; +} + +static int whip_write_packet(AVFormatContext* avctx, AVPacket* pkt) +{ + WHIPContext*const ctx = (WHIPContext*const)avctx->priv_data; + AVFormatContext* rtpctx = ctx->webrtc_ctx.tracks[pkt->stream_index].rtp_ctx; + pkt->stream_index = 0; + + if (ctx->webrtc_ctx.state != RTC_CONNECTED) { + av_log(avctx, AV_LOG_ERROR, "Connection is not open\n"); + return AVERROR(EINVAL); + } + + return av_write_frame(rtpctx, pkt); +} + +static int whip_write_trailer(AVFormatContext* avctx) +{ + WHIPContext*const ctx = (WHIPContext*const)avctx->priv_data; + return ff_webrtc_close_resource(&ctx->webrtc_ctx); +} + +static void whip_deinit(AVFormatContext* avctx) +{ + WHIPContext*const ctx = (WHIPContext*const)avctx->priv_data; + ff_webrtc_deinit(&ctx->webrtc_ctx); +} + +static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt) +{ + /* insert SPS/PPS into every keyframe otherwise browsers won't play the stream */ + if (st->codecpar->extradata_size && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) + return ff_stream_add_bitstream_filter(st, "dump_extra", "freq=keyframe"); + return 1; +} + +static int whip_query_codec(enum AVCodecID codec_id, int std_compliance) +{ + switch (codec_id) + { + case AV_CODEC_ID_OPUS: + case AV_CODEC_ID_AAC: + case AV_CODEC_ID_PCM_MULAW: + case AV_CODEC_ID_PCM_ALAW: + case AV_CODEC_ID_H264: + case AV_CODEC_ID_HEVC: + case AV_CODEC_ID_AV1: + case AV_CODEC_ID_VP9: + return 1; + default: + return 0; + } +} + +#define OFFSET(x) offsetof(WHIPContext, x) +#define FLAGS AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + FF_WEBRTC_COMMON_OPTIONS, + { NULL }, +}; + +static const AVClass whip_muxer_class = { + .class_name = "WHIP muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const FFOutputFormat ff_whip_muxer = { + .p.name = "whip", + .p.long_name = NULL_IF_CONFIG_SMALL("WebRTC-HTTP ingestion protocol (WHIP) muxer"), + .p.audio_codec = AV_CODEC_ID_OPUS, // supported by major browsers + .p.video_codec = AV_CODEC_ID_H264, + .p.flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER | AVFMT_EXPERIMENTAL, + .p.priv_class = &whip_muxer_class, + .priv_data_size = sizeof(WHIPContext), + .write_packet = whip_write_packet, + .write_header = whip_write_header, + .write_trailer = whip_write_trailer, + .init = whip_init, + .deinit = whip_deinit, + .query_codec = whip_query_codec, + .check_bitstream = whip_check_bitstream, +};