[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