cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Issue while writing a RTSP client

From: Christopher Conroy <cconroy_at_gmail.com>
Date: Wed, 4 Aug 2010 13:35:13 -0400

On Wed, Aug 4, 2010 at 1:52 AM, Harshdeep Singh <harshcalsoft_at_gmail.com> wrote:
> Hi,
>    I am writing a RTSP client program. I am having trouble getting the
> program to receive RTP packets Plz can anybody help in resolving this issue.
> How can i make my program to receive RTP packets. I tried using the
> CURL_RTSPREQ_RECEIVE option but it is waiting for a minute then any command
> after that is returning response code of 405 and no RTP packets are
> received. Thanks in advance. The code looks like this (I am using Live555 as
> a RTSP server):
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> #include <curl/curl.h>
>
> static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *stream){
>   printf("Size is: %d\n",size);
>   printf("Nmemb is: %d\n",nmemb);
>   return size*nmemb;
> }
>
> int main(int argc, char *argv[])
> {
>   CURL  *csession;
>   CURLcode res;
>   struct curl_slist *custom_msg = NULL;
>
>   char URL[256];
>   char temp_URL[256];
>   char request[256];
>   long rc;
>   int port = 48000;
>   FILE * protofile = NULL;
>   protofile = fopen("Dump","wb");
>   if (argc < 2)
>   {
>       fprintf (stderr, "ERROR: enter a valid URL\n");
>       return -1;
>   }
>
>   csession = curl_easy_init();
>
>   if (csession == NULL)
>       return -1;
>   printf("%s\n", argv[1]);
>   sprintf (URL, "%s", argv[1]);
>
>   curl_easy_setopt(csession, CURLOPT_URL, URL);
>   curl_easy_setopt(csession, CURLOPT_RTSP_STREAM_URI, URL);
>   curl_easy_setopt(csession, CURLOPT_FOLLOWLOCATION, 1);
>   curl_easy_setopt(csession, CURLOPT_HEADER, 1);
>   curl_easy_setopt(csession, CURLOPT_INTERLEAVEFUNCTION, rtp_write);
>   curl_easy_setopt(csession, CURLOPT_INTERLEAVEDATA, protofile);
>   //curl_easy_setopt(csession, CURLOPT_RANGE, NULL);
>   curl_easy_setopt(csession, CURLOPT_VERBOSE, 1);
>
>   /** retrieve OPTIONS */
>   curl_easy_setopt(csession, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
>   res = curl_easy_perform(csession);
>   res = curl_easy_getinfo(csession, CURLINFO_RESPONSE_CODE, &rc);
>   if((res == CURLE_OK) && rc)
>   {
>       fprintf(stderr, "OPTIONS Response Code: %ld\n\n", rc);
>   }
>   else
>       return -1;
>
>   /** send DESCRIBE */
>   custom_msg = curl_slist_append(custom_msg, "Accept: application/x-rtsp-mh,
> application/rtsl, application/sdp");
>   curl_easy_setopt(csession, CURLOPT_RTSPHEADER, custom_msg);
>   curl_easy_setopt(csession, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE);
>   res = curl_easy_perform(csession);
>
>   res = curl_easy_getinfo(csession, CURLINFO_RESPONSE_CODE, &rc);
>   if((res == CURLE_OK) && rc)
>   {
>       fprintf(stderr, "DESCRIBE Response Code: %ld\n\n", rc);
>   }
>   else
>       return -1;
>
>   /** send SETUP */
>   sprintf(temp_URL, "%s/track1", URL);
>   printf("%s\n",temp_URL);
>   curl_easy_setopt(csession, CURLOPT_RTSP_STREAM_URI, temp_URL);
>   sprintf (request, "RTP/AVP;unicast;client_port=%d", port);
>   curl_easy_setopt(csession, CURLOPT_RTSP_TRANSPORT, request);
>   curl_easy_setopt(csession, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
>   res = curl_easy_perform(csession);
>   res = curl_easy_getinfo(csession, CURLINFO_RESPONSE_CODE, &rc);
>
>   if((res == CURLE_OK) && rc)
>   {
>       fprintf(stderr, "SETUP Response Code: %ld\n\n", rc);
>   }
>   else
>       return -1;
>
>
>   sprintf(temp_URL, "%s/track2", URL);
>   printf("%s\n",temp_URL);
>   curl_easy_setopt(csession, CURLOPT_RTSP_STREAM_URI, temp_URL);
>   sprintf (request, "RTP/AVP;unicast;client_port=%d", port);
>   curl_easy_setopt(csession, CURLOPT_RTSP_TRANSPORT, request);
>   curl_easy_setopt(csession, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
>   res = curl_easy_perform(csession);
>   res = curl_easy_getinfo(csession, CURLINFO_RESPONSE_CODE, &rc);
>
>   if((res == CURLE_OK) && rc)
>   {
>       fprintf(stderr, "SETUP Response Code: %ld\n\n", rc);
>   }
>   else
>       return -1;
>
>   /** send PLAY */
>   curl_easy_setopt(csession, CURLOPT_RTSP_STREAM_URI, URL);
>   curl_easy_setopt(csession, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY);
>   res = curl_easy_perform(csession);
>
>   res = curl_easy_getinfo(csession, CURLINFO_RESPONSE_CODE, &rc);
>   if((res == CURLE_OK) && rc)
>   {
>       fprintf(stderr, "PLAY Response Code: %ld\n\n", rc);
>   }
>   else
>       return -1;
>
>   //curl_easy_setopt(csession, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_RECEIVE);
>
>   //res = curl_easy_perform(csession);
>
>   /** send GET_PARAMETER */
>   /** send TEARDOWN */
>   curl_easy_setopt(csession, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_TEARDOWN);
>   res = curl_easy_perform(csession);
>
>   res = curl_easy_getinfo(csession, CURLINFO_RESPONSE_CODE, &rc);
>   if((res == CURLE_OK) && rc)
>   {
>       fprintf(stderr, "TEARDOWN Response Code: %ld\n\n", rc);
>   }
>   else
>       return -1;
>
>   curl_easy_cleanup(csession);
>   fclose(protofile);
>   return 0;
> }
>
>
> The output is:
>
> [root_at_FC138 rtsp]# ./test rtsp://192.168.7.32/vobStream
> rtsp://192.168.7.32/vobStream
> * About to connect() to 192.168.7.32 port 554 (#0)
> *   Trying 192.168.7.32... * connected
> * Connected to 192.168.7.32 (192.168.7.32) port 554 (#0)
>> OPTIONS rtsp://192.168.7.32/vobStream RTSP/1.0
> CSeq: 1
>
> < RTSP/1.0 200 OK
> RTSP/1.0 200 OK
> < CSeq: 1
> CSeq: 1
> < Date: Wed, Aug 04 2010 11:14:25 GMT
> Date: Wed, Aug 04 2010 11:14:25 GMT
> < Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER,
> SET_PARAMETER
> Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER,
> SET_PARAMETER
>
> <
> * Connection #0 to host 192.168.7.32 left intact
> OPTIONS Response Code: 200
>
> * Re-using existing connection! (#0) with host 192.168.7.32
> * Connected to 192.168.7.32 (192.168.7.32) port 554 (#0)
>> DESCRIBE rtsp://192.168.7.32/vobStream RTSP/1.0
> CSeq: 2
> If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
> Accept: application/x-rtsp-mh, application/rtsl, application/sdp
>
> < RTSP/1.0 200 OK
> RTSP/1.0 200 OK
> < CSeq: 2
> CSeq: 2
> < Date: Wed, Aug 04 2010 11:14:25 GMT
> Date: Wed, Aug 04 2010 11:14:25 GMT
> < Content-Base: rtsp://192.168.7.32/vobStream/
> Content-Base: rtsp://192.168.7.32/vobStream/
> < Content-Type: application/sdp
> Content-Type: application/sdp
> < Content-Length: 566
> Content-Length: 566
> <
> v=0
> o=- 1280916789179493 1 IN IP4 192.168.7.32
> s=Session streamed by "vobStreamer"
> i=/root/media/VTS_01_1.VOB
> t=0 0
> a=tool:LIVE555 Streaming Media v2010.07.13
> a=type:broadcast
> a=control:*
> a=source-filter: incl IN IP4 * 192.168.7.32
> a=rtcp-unicast: reflection
> a=range:npt=0-
> a=x-qt-text-nam:Session streamed by "vobStreamer"
> a=x-qt-text-inf:/root/media/VTS_01_1.VOB
> m=audio 4444 RTP/AVP 96
> c=IN IP4 232.104.202.61/255
> b=AS:160
> a=rtpmap:96 AC3/48000
> a=control:track1
> m=video 8888 RTP/AVP 32
> c=IN IP4 232.104.202.61/255
> b=AS:4500
> a=control:track2
> * Connection #0 to host 192.168.7.32 left intact
> DESCRIBE Response Code: 200
>
> rtsp://192.168.7.32/vobStream/track1
> * Re-using existing connection! (#0) with host 192.168.7.32
> * Connected to 192.168.7.32 (192.168.7.32) port 554 (#0)
>> SETUP rtsp://192.168.7.32/vobStream/track1 RTSP/1.0
> CSeq: 3
> Transport: RTP/AVP;unicast;client_port=48000
> If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
> Accept: application/x-rtsp-mh, application/rtsl, application/sdp
>
> < RTSP/1.0 200 OK
> RTSP/1.0 200 OK
> < CSeq: 3
> CSeq: 3
> < Date: Wed, Aug 04 2010 11:14:25 GMT
> Date: Wed, Aug 04 2010 11:14:25 GMT
> < Transport:
> RTP/AVP;multicast;destination=232.104.202.61;source=192.168.7.32;port=4444-4445;ttl=255
> Transport:
> RTP/AVP;multicast;destination=232.104.202.61;source=192.168.7.32;port=4444-4445;ttl=255
> < Session: 07DA6D44
> Session: 07DA6D44
>
> <
> * Connection #0 to host 192.168.7.32 left intact
> SETUP Response Code: 200
>
> rtsp://192.168.7.32/vobStream/track2
> * Re-using existing connection! (#0) with host 192.168.7.32
> * Connected to 192.168.7.32 (192.168.7.32) port 554 (#0)
>> SETUP rtsp://192.168.7.32/vobStream/track2 RTSP/1.0
> CSeq: 4
> Session: 07DA6D44
> Transport: RTP/AVP;unicast;client_port=48000
> If-Modified-Since: Thu, 01 Jan 1970 00:00:00 GMT
> Accept: application/x-rtsp-mh, application/rtsl, application/sdp
>
> < RTSP/1.0 200 OK
> RTSP/1.0 200 OK
> < CSeq: 4
> CSeq: 4
> < Date: Wed, Aug 04 2010 11:14:25 GMT
> Date: Wed, Aug 04 2010 11:14:25 GMT
> < Transport:
> RTP/AVP;multicast;destination=232.104.202.61;source=192.168.7.32;port=8888-8889;ttl=255
> Transport:
> RTP/AVP;multicast;destination=232.104.202.61;source=192.168.7.32;port=8888-8889;ttl=255
> < Session: 07DA6D44
> Session: 07DA6D44
>
> <
> * Connection #0 to host 192.168.7.32 left intact
> SETUP Response Code: 200
>
> * Re-using existing connection! (#0) with host 192.168.7.32
> * Connected to 192.168.7.32 (192.168.7.32) port 554 (#0)
>> PLAY rtsp://192.168.7.32/vobStream RTSP/1.0
> CSeq: 5
> Session: 07DA6D44
> Accept: application/x-rtsp-mh, application/rtsl, application/sdp
>
> < RTSP/1.0 200 OK
> RTSP/1.0 200 OK
> < CSeq: 5
> CSeq: 5
> < Date: Wed, Aug 04 2010 11:14:25 GMT
> Date: Wed, Aug 04 2010 11:14:25 GMT
> < Session: 07DA6D44
> Session: 07DA6D44
> < RTP-Info:
> url=rtsp://192.168.7.32/vobStream/track1;seq=39869;rtptime=165007425,url=rtsp://192.168.7.32/vobStream/track2;seq=57787;rtptime=2778271849
> RTP-Info:
> url=rtsp://192.168.7.32/vobStream/track1;seq=39869;rtptime=165007425,url=rtsp://192.168.7.32/vobStream/track2;seq=57787;rtptime=2778271849
>
> <
> * Connection #0 to host 192.168.7.32 left intact
> PLAY Response Code: 200
>
> * Re-using existing connection! (#0) with host 192.168.7.32
> * Connected to 192.168.7.32 (192.168.7.32) port 554 (#0)
>> TEARDOWN rtsp://192.168.7.32/vobStream RTSP/1.0
> CSeq: 6
> Session: 07DA6D44
> Accept: application/x-rtsp-mh, application/rtsl, application/sdp
>
> < RTSP/1.0 200 OK
> RTSP/1.0 200 OK
> < CSeq: 6
> CSeq: 6
> < Date: Wed, Aug 04 2010 11:14:25 GMT
> Date: Wed, Aug 04 2010 11:14:25 GMT
>
> <
> * Connection #0 to host 192.168.7.32 left intact
> TEARDOWN Response Code: 200
>
> * Closing connection #0
>
>
> -------------------------------------------------------------------
> List admin: http://cool.haxx.se/list/listinfo/curl-library
> Etiquette:  http://curl.haxx.se/mail/etiquette.html
>

A quick read of your protocol dump indicates that the RTP data is
being sent to a multicast address (even though you are trying to tell
it to go to a unicast address) and is not being interleaved. The RTP
unit test uses the following transport line

  test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "RTP/AVP/TCP;interleaved=0-1");

which should work for your use case.

-- 
Chris Conroy
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
Received on 2010-08-04