Index: stream/asf_streaming.c =================================================================== --- stream/asf_streaming.c (revision 22481) +++ stream/asf_streaming.c (working copy) @@ -25,6 +25,9 @@ #include "network.h" #include "tcp.h" +#include "../playtree.h" +extern int playtree_add_playlist(play_tree_t* entry); + #ifdef ARCH_X86 #define ASF_LOAD_GUID_PREFIX(guid) (*(uint32_t *)(guid)) #else @@ -765,11 +768,39 @@ mp_msg(MSGT_NETWORK,MSGL_DBG2,"Response [%s]\n", http_hdr->buffer ); } ret = asf_http_parse_response(asf_http_ctrl, http_hdr); + + if (strstr(url->url,".asx")!=NULL) { + mp_msg(MSGT_NETWORK,MSGL_V,"ASXPlaylist detected: url=%s, bodysize=%i\n",url->url,http_hdr->body_size); + ret = 0; + asf_http_ctrl->streaming_type=ASF_ASXPlaylist_e; + } + if( ret<0 ) { mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_HeaderParseFailed); goto err_out; } switch( asf_http_ctrl->streaming_type ) { + case ASF_ASXPlaylist_e: + + if( http_hdr->body_size>0 ) { + if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { + goto err_out; + } + } + + //TODO: read potentially remaining + //asx playlist data into buffer + //{ int r; + //for( r=?; r < http_hdr->body_size; ) { + //i = nop_streaming_read(fd,((char*)stream->streaming_ctrl->buffer)+r,http_hdr->body_size - r,stream->streaming_ctrl); + //if(i <= 0) return -1; + //r += i; + //} + //} + *demuxer_type = DEMUXER_TYPE_PLAYLIST; + done=1; + break; + case ASF_Live_e: case ASF_Prerecorded_e: case ASF_PlainText_e: @@ -817,7 +848,7 @@ } while(!done); stream->fd = fd; - if( asf_http_ctrl->streaming_type==ASF_PlainText_e || asf_http_ctrl->streaming_type==ASF_Redirector_e ) { + if( asf_http_ctrl->streaming_type==ASF_PlainText_e || asf_http_ctrl->streaming_type==ASF_Redirector_e || asf_http_ctrl->streaming_type==ASF_ASXPlaylist_e) { stream->streaming_ctrl->streaming_read = nop_streaming_read; stream->streaming_ctrl->streaming_seek = nop_streaming_seek; } else { @@ -852,20 +883,21 @@ url_free(url); mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_MPDEMUX_ASF_InfoStreamASFURL, stream->url); - if((!strncmp(stream->url, "http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN)) { + if((!strncmp(stream->url, "http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN && *file_format!=DEMUXER_TYPE_PLAYLIST)) { streaming_ctrl_free(stream->streaming_ctrl); stream->streaming_ctrl = NULL; return STREAM_UNSUPORTED; } + *file_format = DEMUXER_TYPE_ASF; if(asf_streaming_start(stream, file_format) < 0) { mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_MPDEMUX_ASF_StreamingFailed); streaming_ctrl_free(stream->streaming_ctrl); stream->streaming_ctrl = NULL; return STREAM_UNSUPORTED; } - - *file_format = DEMUXER_TYPE_ASF; + if (*file_format != DEMUXER_TYPE_PLAYLIST) + *file_format = DEMUXER_TYPE_ASF; stream->type = STREAMTYPE_STREAM; fixup_network_stream_cache(stream); return STREAM_OK; Index: mplayer.c =================================================================== --- mplayer.c (revision 22481) +++ mplayer.c (working copy) @@ -2864,6 +2864,8 @@ mp_msg(MSGT_CPLAYER,MSGL_V,"Parsing playlist %s...\n", filename_recode(filename)); entry = parse_playtree(mpctx->stream,0); + //TODO:limit depth of nested playlists + //to avoid following infinitely nested playlists. mpctx->eof=playtree_add_playlist(entry); goto goto_next_file; } Index: playtreeparser.c =================================================================== --- playtreeparser.c (revision 22481) +++ playtreeparser.c (working copy) @@ -51,18 +51,46 @@ play_tree_parser_get_line(play_tree_parser_t* p) { char *end,*line_end; int r,resize = 0; + int buffered_stream=0; + if (p==NULL) return NULL; + if (p->stream !=NULL && + p->stream->streaming_ctrl != NULL && + p->stream->streaming_ctrl->buffer != NULL && + p->stream->streaming_ctrl->buffer_size > 0) { + buffered_stream=1; + } + if(p->buffer == NULL) { - p->buffer = malloc(BUF_STEP); - p->buffer_size = BUF_STEP; + if (!buffered_stream) { + p->buffer = malloc(BUF_STEP); + p->buffer_size = BUF_STEP; + } else { + p->buffer_size = p->stream->streaming_ctrl->buffer_size + 1; + p->buffer = malloc(p->buffer_size); + memcpy( p->buffer, p->stream->streaming_ctrl->buffer, p->stream->streaming_ctrl->buffer_size ); + p->buffer[p->buffer_size - 1] = '\0'; + p->buffer_end = p->buffer_size; + p->stream->eof = 1; + free(p->stream->streaming_ctrl->buffer); + p->stream->streaming_ctrl->buffer=NULL; + p->stream->streaming_ctrl->buffer_size=0; + } p->iter = p->buffer; } if(p->stream->eof && (p->buffer_end == 0 || p->iter[0] == '\0')) return NULL; - - while(1) { + if (buffered_stream) { + + end = strchr(p->iter,'\n'); + if (!end) end = p->buffer + p->buffer_end; + + } else { + + while(1) { + if(resize) { r = p->iter - p->buffer; p->buffer = (char*)realloc(p->buffer,p->buffer_size+BUF_STEP); @@ -91,16 +119,18 @@ continue; } break; + } } line_end = ((*(end-1)) == '\r') ? end-1 : end; if(line_end - p->iter >= 0) p->line = (char*)realloc(p->line,line_end - p->iter+1); else - return NULL; + return NULL; if(line_end - p->iter > 0) strncpy(p->line,p->iter,line_end - p->iter); - p->line[line_end - p->iter] = '\0'; + p->line[line_end - p->iter] = '\0'; + if(end[0] != '\0') end++; @@ -792,7 +822,6 @@ assert(p != NULL); #endif - while(play_tree_parser_get_line(p) != NULL) { play_tree_parser_reset(p); Index: libmpdemux/asf.h =================================================================== --- libmpdemux/asf.h (revision 22481) +++ libmpdemux/asf.h (working copy) @@ -120,7 +120,8 @@ ASF_Prerecorded_e, ASF_Redirector_e, ASF_PlainText_e, - ASF_Authenticate_e + ASF_Authenticate_e, + ASF_ASXPlaylist_e } ASF_StreamType_e; typedef struct {