diff playtreeparser.c @ 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 36a474903e8a
children e305132d083b
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();