changeset 22242:4cabf7499fef

Add support for smil playlist served over realrtsp (audio and video playback only, not full smil support)
author rtogni
date Sun, 18 Feb 2007 15:57:50 +0000
parents be27c7642939
children e085c85b29af
files playtreeparser.c stream/librtsp/rtsp_session.c stream/realrtsp/real.c stream/realrtsp/real.h
diffstat 4 files changed, 82 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/playtreeparser.c	Sun Feb 18 15:06:54 2007 +0000
+++ b/playtreeparser.c	Sun Feb 18 15:57:50 2007 +0000
@@ -76,6 +76,8 @@
       if(r > 0) {
 	p->buffer_end += r;
 	p->buffer[p->buffer_end] = '\0';
+	while(strlen(p->buffer + p->buffer_end - r) != r)
+	  p->buffer[p->buffer_end - r + strlen(p->buffer + p->buffer_end - r)] = '\n';
       }
     }
     
@@ -433,8 +435,10 @@
 static play_tree_t*
 parse_smil(play_tree_parser_t* p) {
   int entrymode=0;
-  char* line,source[512],*pos,*s_start,*s_end;
+  char* line,source[512],*pos,*s_start,*s_end,*src_line;
   play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL;
+  int is_rmsmil = 0;
+  unsigned int npkt, ttlpkt;
 
   mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying smil playlist...\n");
 
@@ -443,7 +447,8 @@
     strstrip(line);
     if(line[0] == '\0') // Ignore empties
       continue;
-    if (strncasecmp(line,"<smil",5)==0 || strncasecmp(line,"<?wpl",5)==0)
+    if (strncasecmp(line,"<smil",5)==0 || strncasecmp(line,"<?wpl",5)==0 ||
+      strncasecmp(line,"(smil-document",14)==0)
       break; // smil header found
     else
       return NULL; //line not smil exit
@@ -452,10 +457,63 @@
   mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected smil playlist format\n");
   play_tree_parser_stop_keeping(p);
 
+  if (strncasecmp(line,"(smil-document",14)==0) {
+    mp_msg(MSGT_PLAYTREE,MSGL_V,"Special smil-over-realrtsp playlist header\n");
+    is_rmsmil = 1;
+    if (sscanf(line, "(smil-document (ver 1.0)(npkt %u)(ttlpkt %u", &npkt, &ttlpkt) != 2) {
+      mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: header parsing failure, assuming single packet.\n");
+      npkt = ttlpkt = 1;
+    }
+    if (ttlpkt == 0 || npkt > ttlpkt) {
+      mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: bad packet counters (npkk = %u, ttlpkt = %u), assuming single packet.\n",
+        npkt, ttlpkt);
+      npkt = ttlpkt = 1;
+    }
+  }
 
   //Get entries from smil 
-  while((line = play_tree_parser_get_line(p)) != NULL) {
-    strstrip(line);
+  line = NULL;
+  while((src_line = play_tree_parser_get_line(p)) != NULL) {
+    strstrip(src_line);
+    if (line) {
+      free(line);
+      line = NULL;
+    }
+    /* If we're parsing smil over realrtsp and this is not the last packet and
+     * this is the last line in the packet (terminating with ") ) we must get
+     * the next line, strip the header, and concatenate it to the current line.
+     */
+    if (is_rmsmil && npkt != ttlpkt && strstr(src_line,"\")")) {
+      char *payload;
+
+      line = strdup(src_line);
+      if(!(src_line = play_tree_parser_get_line(p))) {
+        mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't get line from packet %u/%u.\n", npkt, ttlpkt);
+        break;
+      }
+      strstrip(src_line);
+      // Skip header, packet starts after "
+      if(!(payload = strchr(src_line,'\"'))) {
+        mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't find start of packet, using complete line.\n");
+        payload = src_line;
+      } else
+        payload++;
+      // Skip ") at the end of the last line from the current packet
+      line[strlen(line)-2] = 0;
+      line = realloc(line, strlen(line)+strlen(payload));
+      strcat (line, payload);
+      npkt++;
+    } else
+      line = strdup(src_line);
+    /* Unescape \" to " for smil-over-rtsp */
+    if (is_rmsmil && line[0] != '\0') {
+      int i, j;
+
+      for (i = 0; i < strlen(line); i++)
+        if (line[i] == '\\' && line[i+1] == '"')
+          for (j = i; line[j]; j++)
+            line[j] = line[j+1];
+    }
     if (line[0]=='\0')
       continue;
     if (!entrymode) { // all entries filled so far 
@@ -512,6 +570,9 @@
     }
   }
 
+  if (line)
+    free(line);
+
   if(!list) return NULL; // Nothing found
 
   entry = play_tree_new();
--- a/stream/librtsp/rtsp_session.c	Sun Feb 18 15:06:54 2007 +0000
+++ b/stream/librtsp/rtsp_session.c	Sun Feb 18 15:57:50 2007 +0000
@@ -140,6 +140,12 @@
     }
 	
     rtsp_session->real_session = init_real_rtsp_session ();
+    if(!strncmp(h->streams[0]->mime_type, "application/vnd.rn-rmadriver", h->streams[0]->mime_type_size)) {
+      rtsp_session->real_session->header_len = 0;
+      rtsp_session->real_session->recv_size = 0;
+      rtsp_session->real_session->rdt_rawdata = 1;
+      mp_msg(MSGT_OPEN, MSGL_V, "smil-over-realrtsp playlist, switching to raw rdt mode\n");
+    } else {
     rtsp_session->real_session->header_len =
       rmff_dump_header (h, (char *) rtsp_session->real_session->header, 1024);
 
@@ -150,6 +156,7 @@
 
     rtsp_session->real_session->recv_size =
       rtsp_session->real_session->header_len;
+    }
     rtsp_session->real_session->recv_read = 0;
   } else /* not a Real server : try RTP instead */
   {
@@ -219,7 +226,7 @@
     dest += fill;
     this->real_session->recv_read = 0;
     this->real_session->recv_size =
-      real_get_rdt_chunk (this->s, (char **)&(this->real_session->recv));
+      real_get_rdt_chunk (this->s, (char **)&(this->real_session->recv), this->real_session->rdt_rawdata);
     if (this->real_session->recv_size < 0) {
       this->real_session->rdteof = 1;
       this->real_session->recv_size = 0;
--- a/stream/realrtsp/real.c	Sun Feb 18 15:06:54 2007 +0000
+++ b/stream/realrtsp/real.c	Sun Feb 18 15:57:50 2007 +0000
@@ -342,7 +342,7 @@
   return header;
 }
 
-int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer) {
+int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer, int rdt_rawdata) {
 
   int n=1;
   uint8_t header[8];
@@ -414,6 +414,10 @@
   else
     ph.flags=0;
   *buffer = xbuffer_ensure_size(*buffer, 12+size);
+  if(rdt_rawdata) {
+    n=rtsp_read_data(rtsp_session, *buffer, size-12);
+    return (n <= 0) ? 0 : n;
+  }
   rmff_dump_pheader(&ph, *buffer);
   size-=12;
   n=rtsp_read_data(rtsp_session, (*buffer)+12, size);
@@ -650,6 +654,7 @@
   real_rtsp_session = malloc (sizeof (struct real_rtsp_session_t));
   real_rtsp_session->recv = xbuffer_init (BUF_SIZE);
   real_rtsp_session->rdteof = 0;
+  real_rtsp_session->rdt_rawdata = 0;
 
   return real_rtsp_session;
 }
--- a/stream/realrtsp/real.h	Sun Feb 18 15:06:54 2007 +0000
+++ b/stream/realrtsp/real.h	Sun Feb 18 15:57:50 2007 +0000
@@ -47,9 +47,11 @@
   int header_read;
 
   int rdteof;
+
+  int rdt_rawdata;
 };
 
-int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer);
+int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer, int rdt_rawdata);
 rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth,
   char *username, char *password);
 struct real_rtsp_session_t *init_real_rtsp_session (void);