summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--playtreeparser.c69
-rw-r--r--stream/librtsp/rtsp_session.c9
-rw-r--r--stream/realrtsp/real.c7
-rw-r--r--stream/realrtsp/real.h4
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);