Mercurial > mplayer.hg
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);