diff options
-rw-r--r-- | playtreeparser.c | 69 | ||||
-rw-r--r-- | stream/librtsp/rtsp_session.c | 9 | ||||
-rw-r--r-- | stream/realrtsp/real.c | 7 | ||||
-rw-r--r-- | stream/realrtsp/real.h | 4 |
4 files changed, 82 insertions, 7 deletions
diff --git a/playtreeparser.c b/playtreeparser.c index 39378281f3..e94ea0fdc9 100644 --- a/playtreeparser.c +++ b/playtreeparser.c @@ -76,6 +76,8 @@ play_tree_parser_get_line(play_tree_parser_t* p) { 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 @@ parse_m3u(play_tree_parser_t* p) { 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 @@ parse_smil(play_tree_parser_t* p) { 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 @@ parse_smil(play_tree_parser_t* p) { 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 @@ parse_smil(play_tree_parser_t* p) { } } + if (line) + free(line); + if(!list) return NULL; // Nothing found entry = play_tree_new(); diff --git a/stream/librtsp/rtsp_session.c b/stream/librtsp/rtsp_session.c index a5c6655cf5..ecc07501f9 100644 --- a/stream/librtsp/rtsp_session.c +++ b/stream/librtsp/rtsp_session.c @@ -140,6 +140,12 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, } 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_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, 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 @@ int rtsp_session_read (rtsp_session_t *this, char *data, int len) { 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; diff --git a/stream/realrtsp/real.c b/stream/realrtsp/real.c index 23fb74f0b3..ec75b3ea57 100644 --- a/stream/realrtsp/real.c +++ b/stream/realrtsp/real.c @@ -342,7 +342,7 @@ static rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t b 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 @@ int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer) { 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 @@ init_real_rtsp_session (void) 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; } diff --git a/stream/realrtsp/real.h b/stream/realrtsp/real.h index 4abc58cbd1..c37f5af5d1 100644 --- a/stream/realrtsp/real.h +++ b/stream/realrtsp/real.h @@ -47,9 +47,11 @@ struct real_rtsp_session_t { 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); |