[FFmpeg-devel] [PATCH] Realmedia / RTSP (RDT)
Michael Niedermayer
michaelni
Sun Jan 6 14:13:42 CET 2008
On Tue, Jan 01, 2008 at 03:34:44PM -0500, Ronald S. Bultje wrote:
[...]
> @@ -908,11 +921,39 @@
> rt->rtsp_hd = rtsp_hd;
> rt->seq = 0;
>
> + /* request options supported by the server */
> + snprintf(cmd, sizeof(cmd),
> + "OPTIONS %s RTSP/1.0\r\n"
> + "User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95\r\n"
> + "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
> + "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
> + "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
> + "GUID: 00000000-0000-0000-0000-000000000000\r\n"
> + "RegionData: 0\r\n"
> + "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586\r\n",
> + s->filename);
> + rtsp_send_cmd(s, cmd, reply, NULL);
> + if (reply->status_code != RTSP_STATUS_OK) {
> + err = AVERROR_INVALIDDATA;
> + goto fail;
> + }
Does this uncoditionally send this stuff for normal RTSP? I really think we
should attempt a clean RTSP/RTP connection first and only if that fails try
realcrap.
> + strcpy(challenge, reply->challenge);
> + is_real_datatype = !!challenge[0];
> +
> /* describe the stream */
> snprintf(cmd, sizeof(cmd),
> "DESCRIBE %s RTSP/1.0\r\n"
> + "%s"
> "Accept: application/sdp\r\n",
> - s->filename);
> + s->filename,
> + !is_real_datatype ? "" :
> + "Bandwidth: 250000\r\n"
> + "GUID: 00000000-0000-0000-0000-000000000000\r\n"
> + "RegionData: 0\r\n"
> + "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586\r\n"
> + "SupportsMaximumASMBandwidth: 1\r\n"
> + "Language: en-US\r\n"
> + "Require: com.real.retain-entity-for-setup\r\n");
no, use
if(is_real_datatype)
av_strlcat()
[...]
> + while (snum-- > 0) get_be16(pb);
url_fskip()
same for the other such cases
[...]
> + if (rm->audio_pkt_cnt == 0) {
> + int pos;
> +
> + url_open_buf (&pb, buf, len, URL_RDONLY);
> + flags = (flags & PKT_FLAG_KEY) ? 2 : 0;
> + rdt->rmctx->pb = pb;
> + res = ff_rm_parse_packet (rdt->rmctx, s->st, len, pkt,
> + &seq, &flags, timestamp);
> + pos = url_ftell(pb);
> + url_close_buf (pb);
> + if (res < 0)
> + return res;
> + if (rm->audio_pkt_cnt > 0 &&
> + s->st->codec->codec_id == CODEC_ID_AAC) {
> + memcpy (rdt->buffer, buf + pos, len - pos);
are you sure that this cant overflow the buffer?
> + url_open_buf (&pb, rdt->buffer, len - pos, URL_RDONLY);
> + rdt->rmctx->pb = pb;
> + }
> + } else {
> + ff_rm_retrieve_cache (rdt->rmctx, s->st, pkt);
> + if (rm->audio_pkt_cnt == 0 &&
> + s->st->codec->codec_id == CODEC_ID_AAC)
> + url_close_buf (pb);
> + }
> +
> + return (rm->audio_pkt_cnt > 0) ? 1 : 0;
the ? 1 : 0 is redundant
> +}
> +
> +static void
> +rdt_parse_b64buf (unsigned char **target, unsigned int *target_len, const char *p)
> +{
> + int len = strlen(p);
> + if (*p == '\"') {
> + p++;
> + len -= 2; /* skip embracing " at start/end */
> + }
> + *target_len = len * 3 / 4;
> + *target = av_mallocz(*target_len + FF_INPUT_BUFFER_PADDING_SIZE);
> + av_base64_decode(*target, p, *target_len);
> +}
instead of returning void returning target seems more logic
[...]
> +static void
> +rdt_free_extradata (void *d)
> +{
> + rdt_data *rdt = d;
> +
> + // FIXME: close rm ctx
> + if (rdt->rmctx) av_free (rdt->rmctx->priv_data);
yes, please close it
[...]
> Index: ffmpeg/libavformat/rtp.c
> ===================================================================
> --- ffmpeg.orig/libavformat/rtp.c 2008-01-01 15:14:46.000000000 -0500
> +++ ffmpeg/libavformat/rtp.c 2008-01-01 15:25:08.000000000 -0500
> @@ -641,22 +641,22 @@
> buf += consumed;
> len -= consumed;
> } else {
> - if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
> - return -1;
> - if (buf[1] >= 200 && buf[1] <= 204) {
> - rtcp_parse_packet(s, buf, len);
> - return -1;
> - }
> - payload_type = buf[1] & 0x7f;
> - seq = AV_RB16(buf + 2);
> - timestamp = AV_RB32(buf + 4);
> - ssrc = AV_RB32(buf + 8);
> - /* store the ssrc in the RTPDemuxContext */
> - s->ssrc = ssrc;
> + if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
> + return -1;
> + if (buf[1] >= 200 && buf[1] <= 204) {
> + rtcp_parse_packet(s, buf, len);
> + return -1;
> + }
> + payload_type = buf[1] & 0x7f;
> + seq = AV_RB16(buf + 2);
> + timestamp = AV_RB32(buf + 4);
> + ssrc = AV_RB32(buf + 8);
> + /* store the ssrc in the RTPDemuxContext */
> + s->ssrc = ssrc;
>
> - /* NOTE: we can handle only one payload type */
> - if (s->payload_type != payload_type)
> - return -1;
> + /* NOTE: we can handle only one payload type */
> + if (s->payload_type != payload_type)
> + return -1;
>
> buf += 12;
> len -= 12;
> Index: ffmpeg/libavformat/rtsp.c
> ===================================================================
> --- ffmpeg.orig/libavformat/rtsp.c 2008-01-01 15:17:41.000000000 -0500
> +++ ffmpeg/libavformat/rtsp.c 2008-01-01 15:24:30.000000000 -0500
> @@ -881,7 +881,7 @@
> RTSPHeader reply1, *reply = &reply1;
> unsigned char *content = NULL;
> RTSPStream *rtsp_st;
> - int protocol_mask = 0, is_real_datatype;
> + int protocol_mask = 0, is_real_datatype = 0;
> AVStream *st;
>
> /* extract hostname and port */
> @@ -922,23 +922,36 @@
> rt->seq = 0;
>
> /* request options supported by the server */
> - snprintf(cmd, sizeof(cmd),
> - "OPTIONS %s RTSP/1.0\r\n"
> - "User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95\r\n"
> - "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
> - "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
> - "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
> - "GUID: 00000000-0000-0000-0000-000000000000\r\n"
> - "RegionData: 0\r\n"
> - "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586\r\n",
> - s->filename);
> - rtsp_send_cmd(s, cmd, reply, NULL);
> - if (reply->status_code != RTSP_STATUS_OK) {
> - err = AVERROR_INVALIDDATA;
> - goto fail;
> + for (;;) {
> + if (!is_real_datatype)
> + snprintf(cmd, sizeof(cmd),
> + "OPTIONS %s RTSP/1.0\r\n"
> + "User-Agent: ffmpeg\r\n",
> + s->filename);
> + else
> + snprintf(cmd, sizeof(cmd),
> + "OPTIONS %s RTSP/1.0\r\n"
> + "User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95\r\n"
> + "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
> + "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
> + "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
> + "GUID: 00000000-0000-0000-0000-000000000000\r\n"
> + "RegionData: 0\r\n"
> + "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586\r\n",
> + s->filename);
> + rtsp_send_cmd(s, cmd, reply, NULL);
> + if (reply->status_code != RTSP_STATUS_OK) {
> + err = AVERROR_INVALIDDATA;
> + goto fail;
> + } else if (reply->challenge[0]) {
> + if (!is_real_datatype) {
> + is_real_datatype = 1;
> + continue;
> + }
> + strcpy(challenge, reply->challenge);
> + }
> + break;
> }
> - strcpy(challenge, reply->challenge);
> - is_real_datatype = !!challenge[0];
>
> /* describe the stream */
> snprintf(cmd, sizeof(cmd),
> @@ -1042,10 +1055,10 @@
> rtsp_st->control_url, res, csum, transport,
> rt->session_id);
> } else
> - snprintf(cmd, sizeof(cmd),
> - "SETUP %s RTSP/1.0\r\n"
> - "Transport: %s\r\n",
> - rtsp_st->control_url, transport);
> + snprintf(cmd, sizeof(cmd),
> + "SETUP %s RTSP/1.0\r\n"
> + "Transport: %s\r\n",
> + rtsp_st->control_url, transport);
> rtsp_send_cmd(s, cmd, reply, NULL);
> if (reply->status_code == 461 /* Unsupported protocol */ && i == 0 &&
> (protocol_mask = unset_lowest_protocol(protocol_mask)) != 0) {
this mixes cosmetics with functional changes
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
It is dangerous to be right in matters on which the established authorities
are wrong. -- Voltaire
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080106/c071065f/attachment.pgp>
More information about the ffmpeg-devel
mailing list