[FFmpeg-devel] [PATCH 1/3] avformat/rtsp: add support for satip://
Andriy Gelman
andriy.gelman at gmail.com
Tue Dec 22 22:15:35 EET 2020
On Mon, 21. Dec 16:35, Aman Karmani wrote:
> From: Aman Karmani <aman at tmm1.net>
>
> The SAT>IP protocol[1] is similar to RTSP. However SAT>IP servers
> are assumed to speak only MP2T, so DESCRIBE is not used in the same
> way. When no streams are active, DESCRIBE will return 404 according
> to the spec (see section 3.5.7). When streams are active, DESCRIBE
> will return a list of all current streams along with information
> about their signal strengths.
>
> Previously, attemping to use ffmpeg with a rtsp:// url that points
> to a SAT>IP server would work with some devices and fail due to 404
> response on others. Further, if the SAT>IP server was already
> streaming, ffmpeg would incorrectly consume the DESCRIBE SDP response
> and join an existing tuner instead of requesting a new session with
> the URL provided by the user. These issues have been noted by many
> users across the internet[2][3].
>
> This commit adds proper spec-compliant support for SAT>IP, including:
>
> - support for the satip:// psuedo-protocol
> - avoiding the use of DESCRIBE
> - parsing and consuming the com.ses.streamID response header
> - using "Transport: RTP/AVP;unicast" because the optional "/UDP"
> suffix confuses some servers
>
> [1] https://www.satip.info/sites/satip/files/resource/satip_specification_version_1_2_2.pdf
> [2] https://stackoverflow.com/questions/61194344/does-ffmpeg-violate-the-satip-specification-describe-syntax
> [3] https://github.com/kodi-pvr/pvr.iptvsimple/issues/196
> ---
> libavformat/rtsp.c | 52 ++++++++++++++++++++++++++++++++++++++-----
> libavformat/rtsp.h | 6 +++++
> libavformat/rtspdec.c | 1 +
> 3 files changed, 53 insertions(+), 6 deletions(-)
>
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index c7ffa07d9e..4a863dbac3 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -252,6 +252,24 @@ static void finalize_rtp_handler_init(AVFormatContext *s, RTSPStream *rtsp_st,
> }
> }
>
> +static int init_satip_stream(AVFormatContext *s)
> +{
> + RTSPState *rt = s->priv_data;
> + RTSPStream *rtsp_st;
> + rtsp_st = av_mallocz(sizeof(RTSPStream));
> + if (!rtsp_st)
> + return AVERROR(ENOMEM);
> + rtsp_st->stream_index = -1;
> + dynarray_add(&rt->rtsp_streams,
> + &rt->nb_rtsp_streams, rtsp_st);
> + av_strlcpy(rtsp_st->control_url,
> + rt->control_uri, sizeof(rtsp_st->control_url));
> + rtsp_st->sdp_payload_type = 33; // MP2T
> + init_rtp_handler(&ff_mpegts_dynamic_handler, rtsp_st, NULL);
> + finalize_rtp_handler_init(s, rtsp_st, NULL);
> + return 0;
> +}
> +
> /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
> static int sdp_parse_rtpmap(AVFormatContext *s,
> AVStream *st, RTSPStream *rtsp_st,
> @@ -1116,6 +1134,9 @@ void ff_rtsp_parse_line(AVFormatContext *s,
> } else if (av_stristart(p, "Content-Type:", &p)) {
> p += strspn(p, SPACE_CHARS);
> av_strlcpy(reply->content_type, p, sizeof(reply->content_type));
> + } else if (av_stristart(p, "com.ses.streamID:", &p)) {
> + p += strspn(p, SPACE_CHARS);
> + av_strlcpy(reply->stream_id, p, sizeof(reply->stream_id));
> }
> }
>
> @@ -1495,8 +1516,10 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
> rtp_opened:
> port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
> have_port:
> - snprintf(transport, sizeof(transport) - 1,
> - "%s/UDP;", trans_pref);
> + av_strlcat(transport, trans_pref, sizeof(transport));
transport needs to be initialized to an empty string. Otherwise av_strlcat will
keep all the random bytes before the first NULL.
--
Andriy
More information about the ffmpeg-devel
mailing list