From patchwork Tue Jul 9 10:02:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernardo Pilarz X-Patchwork-Id: 50435 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:fad:b0:482:c625:d099 with SMTP id kf13csp257337vqb; Tue, 9 Jul 2024 03:02:49 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVCfwIcz2iMXXusznD20mH0oTiMSproxIvp59Bh5Z2v+QyZwGoi0Cu5GZSt4shnpWGe09+eUozfI4E/Rf4cZ5Jbrg3Gs5MZIlj2rg== X-Google-Smtp-Source: AGHT+IHEq5Vs4RYh1oZkg21co/vl7uNHfaJ6Fkw4rhKhOMg4kb87tWn5iMeJ/t0foEyidD4oDnsC X-Received: by 2002:a2e:9589:0:b0:2ee:8905:769c with SMTP id 38308e7fff4ca-2eeb30fefc2mr14634871fa.28.1720519368745; Tue, 09 Jul 2024 03:02:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1720519368; cv=none; d=google.com; s=arc-20160816; b=QdYrPggIs2o9/08OxFS89aiBAGhijNGWvBVyhBzBnr1EdlVPOXbEFAP/OPkAn474Hb rbyxfD2uj4FDSJ911p82IMuBWNr1iEcIqvyB6zdTmqia6sHuoD2fRvzX9iPq+z+KESCA d1OZOQXVr0T8X5Hql9ua4pED6O7VgMa2tFvGqLv/jXLuUJscZtY+3aOFEQqDNWePS2rh I6R8zFRL3ZPxcWcdtj2HoqnmfAPpLrzuQ8lO8RSfNrogVSPt9lI+utbV9qiqXqYw2Qvg 27jHfnbd55oNSctVDuS4iMtE/hXhNMJyW0AEcWNJqtr7VO0D6+H8n7RX9Q4+0SiTU/So FENQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to:from :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:content-language:to:mime-version:date :message-id:dkim-filter:delivered-to; bh=ynxhvCThjJvV2W13llWs3lEAA5eIvcjJc8d2x/+ebHo=; fh=BLn51q7SjHgGIj+gC34mWa6upHCOzzwSChD7Q8MutZ0=; b=Sw4h9bIm7stWWFpgmeEbC4XIVGYFSS4VhWn6FUczY4ijrfxhNiV27s1pPv2KSZvMYG EqMJp6A1fBSZdBk3Xqm0HeEiiNOH/T4ikkvXVflDb5cwrju7sEYBBppjZizbI7AApjUv QSo2twTjhpB1Kr3KVjWgAV1qz2BMxFJ6Rk8Pl1mZsWW7KpKVMNWTBSTDFm1azLkF9wv4 pNUJAEdbQR6ieQ/9+BAOsUMnZXx8fC1nNhglCmzdklD5D/fDr0MDWJn6qiS8M2X6ynCG +HhS3scWN6pYG+QLDqImJ0fPjyse1C3LRLUdG3Ihag/LDZCH/DJii7f/8LyAJG81tTla zlbw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 38308e7fff4ca-2eeb348c534si3979341fa.461.2024.07.09.03.02.48; Tue, 09 Jul 2024 03:02:48 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; 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 1594068DC6B; Tue, 9 Jul 2024 13:02:44 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from relay.aitek.it (dns1.aitek.it [194.244.35.21]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 09F0A68DC03 for ; Tue, 9 Jul 2024 13:02:36 +0300 (EEST) Received: from mail-server.aitek.it (mail-server.aitek.it [172.30.0.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay.aitek.it (Postfix) with ESMTPS id 4369A18008F2 for ; Tue, 9 Jul 2024 12:02:36 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 relay.aitek.it 4369A18008F2 Message-ID: Date: Tue, 9 Jul 2024 12:02:30 +0200 MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Content-Language: en-US, it X-Aitek-Mail-Server-MailScanner-Information: Please contact the ISP for more information X-Aitek-Mail-Server-MailScanner-ID: 83D47805209.A3ABF X-Aitek-Mail-Server-MailScanner: Found to be clean X-Aitek-Mail-Server-MailScanner-From: bernardo.pilarz@aitek.it X-Spam-Status: No Subject: [FFmpeg-devel] [PATCH] avcodec/avformat: Store SDP attributes from RTSP stream into AVStream side data. 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: , X-Patchwork-Original-From: Bernardo Pilarz via ffmpeg-devel From: Bernardo Pilarz Reply-To: FFmpeg development discussions and patches Cc: Bernardo Pilarz Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: hAzS8NBbCuWu Connecting to an RTSP stream will now cause the SDP attributes of each media stream to be stored in the codecpar of the relative AVStream. The SDP attributes are stored in the coded_side_data using the (new) type AV_PKT_DATA_SDP_ATTRIBUTES (AVPacketSideDataType enum). Signed-off-by: bpilarz --- libavcodec/packet.h | 7 ++++ libavformat/rtsp.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/libavcodec/packet.h b/libavcodec/packet.h index 13667ffa36..3091c3ce56 --- a/libavcodec/packet.h +++ b/libavcodec/packet.h @@ -339,6 +339,13 @@ enum AVPacketSideDataType { */ AV_PKT_DATA_FRAME_CROPPING, + /** + * Attributes found in the SDP, associated with the stream. This is a + * list of zero terminated key/value strings. There is no end marker for + * the list, so it is required to rely on the side data size to stop. + */ + AV_PKT_DATA_SDP_ATTRIBUTES, + /** * The number of side data types. * This is not part of the public API/ABI in the sense that it may diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 19b93df839..10594e501a --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -283,6 +283,91 @@ static int init_satip_stream(AVFormatContext *s) } #endif +static int sdp_add_attribute_to_stream_side_data(AVFormatContext *s, + AVStream *st, + const char *p) +{ + AVPacketSideData *side_data = NULL; + AVDictionary* attributes_dict = NULL; + char *key = NULL, *value = NULL; + int ret = 0; + + /* Get the stream's attributes dictionary. + * If the stream has no attributes dictionary, it will be automatically + * created by av_dict_set. */ + side_data = av_packet_side_data_get(st->codecpar->coded_side_data, + st->codecpar->nb_coded_side_data, + AV_PKT_DATA_SDP_ATTRIBUTES); + if (side_data) { + ret = av_packet_unpack_dictionary(side_data->data, side_data->size, + &attributes_dict); + if (ret) { + av_log(s, AV_LOG_WARNING, + "Unable to unpack SDP attributes dictionary.\n"); + return -1; + } + } + + /* The attribute can either be a value attribute (key:value) or + * property attribute (just the key). + * Look for the ':' separator, and create the 'key' and 'value' + * appropriately. */ + const char *separator = strchr(p, ':'); + if (separator) { + /* Make a copy of the key and value. */ + key = av_strndup(p, separator - p); + value = av_strdup(separator + 1); + } else { + /* Copy the key and create an empty value. */ + key = av_strdup(p); + value = av_mallocz(1); + } + if (!key || !value) { + av_dict_free(&attributes_dict); + av_free(value); + av_free(key); + return -1; + } + + /* Add the attribute, then pack the dictionary again. */ + ret = av_dict_set(&attributes_dict, key, value, + AV_DICT_DONT_STRDUP_KEY | + AV_DICT_DONT_STRDUP_VAL | + AV_DICT_MULTIKEY); + if (ret) { + av_log(s, AV_LOG_WARNING, + "Unable to add SDL attribute to dictionary.\n"); + av_dict_free(&attributes_dict); + return -1; + } + size_t packed_dict_size = 0u; + uint8_t *packed_dict = av_packet_pack_dictionary(attributes_dict, + &packed_dict_size); + + /* Free the dictionary, which is not needed any longer. */ + av_dict_free(&attributes_dict); + + /* Make sure the dictionary was packet successfully, then add it + * back to the stream's side data. */ + if (!packed_dict) { + av_log(s, AV_LOG_WARNING, + "Unable to pack SDP attributes dictionary.\n"); + return -1; + } + side_data = av_packet_side_data_add(&st->codecpar->coded_side_data, + &st->codecpar->nb_coded_side_data, + AV_PKT_DATA_SDP_ATTRIBUTES, + packed_dict, packed_dict_size, + 0); + if (!side_data) { + av_log(s, AV_LOG_WARNING, + "Unable to add SDP attributes side data to stream.\n"); + return -1; + } + + return 0; +} + /* parse the rtpmap description: /[/] */ static int sdp_parse_rtpmap(AVFormatContext *s, AVStream *st, RTSPStream *rtsp_st, @@ -570,6 +655,18 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, sizeof(rtsp_st->control_url)); break; case 'a': + /* add all SDP attributes to the stream's side data */ + if (rt->nb_rtsp_streams > 0) { + rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1]; + if (rtsp_st->stream_index >= 0) { + st = s->streams[rtsp_st->stream_index]; + if (sdp_add_attribute_to_stream_side_data(s, st, p)) { + av_log(s, AV_LOG_WARNING, + "Failed to add SDP attribute to stream"); + } + } + } + /* now parse the SDP attribute line */ if (av_strstart(p, "control:", &p)) { if (rt->nb_rtsp_streams == 0) { if (!strncmp(p, "rtsp://", 7))