From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id F027146CED for ; Tue, 7 Nov 2023 14:13:26 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E96D768CB46; Tue, 7 Nov 2023 16:13:04 +0200 (EET) 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?B?clRBTmxxRVJ3VjlJSm9iT05OVS84RDBhVVI0cEhDL1laZnVhWnNuSzUrTHBn?= =?utf-8?B?RVd4TFdPdm1kRDRob0F2NnZUUjdDMXE4WGFDWkNZVDRYT1ZWR0ZwVXhqanhS?= =?utf-8?B?a3JTY2pnVjc5eXllUWtQMmpQamVPNHZkNVlEaUxkSkRGYmZFbDBHY0hsL0FM?= =?utf-8?B?WU5HVWNYeU0rV3VQT3FqZEN6Nk52NnhuRVNLZEZSVDBLK0lSUU5qYkNXWDg3?= =?utf-8?B?ZTBGS0g2L0ZxK3lIR05BQUJDK3Z0MDBLWENFNlhnb3RWMmtrZVpxOG9jb3FY?= =?utf-8?B?aCtVd0p5dlNDekxRbVpUMUQ5dGd5NEJyNjdIemdNdUV3c3Y2anBkaGtZRkdW?= =?utf-8?B?eC9WY2pvQ0ZqRGVLbFBtTXlYOHRaazVBZUZ5UkJtaGhlbjdmZzdQbmJyZzJr?= =?utf-8?B?bUNSWXdIMnUwa0pUTUZKZlNvNm9YZFFqcFBtc2FpOUx3NHZSSCtWUmFkMDJU?= =?utf-8?B?VkJ1Ukg2TVMzYnRpUEo0NWh2YjVrcDNCVmV0c0M2WVQ4b25EN3QwYlQrcHg3?= =?utf-8?B?eWVqOW9FTmJVcERkakk0amh5UmU5Tjg0WFdXZXd1OW1hL25KZUxRc3V1OXQ1?= =?utf-8?B?VTk0czNVZnJwdHd1RUVlaGZWVEp5ZUZYUVZWRE13Z0ZJaWk2SWs2UHBnVjQ1?= =?utf-8?B?clljRlZsVTlmb3IrNXVoVGI4emkwbDhvaUpiUm1OTEgxd1g5Wjg5QjE5Q1hU?= =?utf-8?B?S2R6OW1BMHBiamxTUHZrbFdxMzBZVmk3ZG1JNmI4ZU5QRnlJNkxqbCt0Z0t2?= =?utf-8?B?cGQ4NTFlbWwyRmY2dzY4M3gvRUpVL0VCVk1EZ2lDQVBsVTNUNU5rWVZwN0xI?= =?utf-8?B?VEhPNmhHbGF6QUFGcWFXSHZYQnhKRUQvY0lmK2I4WVpNKzF6Nis4YjYrUUhh?= =?utf-8?B?STcwa3gweVRxSmRCUXdxQ21wSGFyY1lRNENiNTJNVUsxUGZqZ0E3UFMyd3ds?= =?utf-8?B?Tk40VnJQZDFWQzJJS09ETHl3NFNVb2N0bjhyakFjSlhFTkE4RzJSTUp4V3E2?= =?utf-8?B?UFYrczRLSnAwWTAzZTRBcGpDV1R0SjJiNHhLRTdRQ20wWk9iNWNKOS94eTBV?= =?utf-8?B?STNmdFpCMC90RDVjbzNRSDRkZWRHaUZDZWlaMmw5bXZrRlNsRFJtMzdZL0Jy?= =?utf-8?B?Q3hkbGNmTkNhOTRJY2huU1ZXV0dDMEFEd3dsa1p0c0pwQW1pRjJXWVN5cU1M?= =?utf-8?B?TGVrLzEvVlhmc2dyK1pFVjRjRTNmWkpRNXRFNm9FcmFkNkZJakRsTjhsMzNW?= =?utf-8?B?dFpJdDhiQUNpRHJsa09uV2R3TStPQ3ZabVA0R2EwTnJ6cVUxVkpOcGEveWs5?= =?utf-8?B?VHpVUW5QNWFOKzBDUGVMQmUzNVROSFhpbHk1RUdjRmc1Tk5rbzgrQlBiSG1C?= =?utf-8?B?Q3pvTVY5ZVN0d3diTWR1SjFWQW1OOTdPRnpTYzg1eUtzNmxub29iZVN1WWov?= =?utf-8?B?cGdkSDFGRG1oWVpNTkFxcHg1dlNRS3M3dmJLRXdhN09HSXpoajBtZlpOWEZG?= =?utf-8?B?MFZsVDFXYk5CaEQ2cDRJS3R3dGRTQXU4WnVPYjJnNFI1NXRsV05Wamdwd1Yx?= =?utf-8?B?RlEvWU1Nc0QzWjUwUi82bXFXZ29zZG5VNWxzMXBtTkxMV2p3cGl4SzBDV0Fz?= =?utf-8?B?MVBUU0NEcHBnelBpUDlDUmZPc2RKS2dGeFhsTHp3UWFsaVdLMFJSYkVkblRn?= =?utf-8?B?SFNUSkpxUVpaODJnaU9NQXFPTWltWWtTci9GQTRnVzhXUXo0NFhFaVl5V0cz?= =?utf-8?B?Q2VNcE80QTUxUENMcDVucFF4TVBGVEU4SFE5c3NqWXRUQWNySTVkODhDZVoz?= =?utf-8?B?QmE0TUM5c2FJR2wrdi9vRDVPVG9FQVpqT3NwT2w3YnB4K2J6UVk5R1NDcHor?= =?utf-8?B?d0dXSjE1QlBGcHVVQ1BOaTZnTGppNFIrUFYwRDBUSEY3TTdiaDl4eXl5bnI4?= =?utf-8?B?dDQxZk5FblZ0cTZBQWxJMUpWSjdpQTZNenVQc3lXSnY4NGVaTW9ubjRuNVVJ?= =?utf-8?B?V0Z6RnFHOUVyVzlYSC9ZQzNDQlVCT0NQY1dUUUgveTBmeHFsSUNrcWRLVnBz?= =?utf-8?B?Z0UwZncrYXd4d0JNMi9PelJnLzRUM0xmZjAvZG9iTS9xNnNtR2ZBZXVwbzZE?= =?utf-8?B?N1ZBYVRJMzc4WFpCWTlRMitMUElLc1lySDV0VXFzcFJOUXNqZkRvbHQxSVRm?= =?utf-8?Q?V3eljiTbb9Pvzi8uSsiLFOg=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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: 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, +}; -- 2.39.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".