Index: stream/asf_streaming.c =================================================================== --- stream/asf_streaming.c (revision 22505) +++ stream/asf_streaming.c (working copy) @@ -765,11 +765,42 @@ 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: + + //read potentially remaining + //asx playlist data into buffer + do { + i = recv( fd, buffer, BUFFER_SIZE, 0 ); + if( i<0 ) { + perror("read"); + goto err_out; + } + if (i>0) http_response_append( http_hdr, buffer, i ); + } while(i>0); + + //move buffer from header to stream + if( http_hdr->body_size>0 ) { + if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { + goto err_out; + } + } + + *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,12 +883,13 @@ 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); @@ -865,7 +897,8 @@ 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 22505) +++ 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 22505) +++ 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,6 +119,7 @@ continue; } break; + } } line_end = ((*(end-1)) == '\r') ? end-1 : end; Index: libmpdemux/asf.h =================================================================== --- libmpdemux/asf.h (revision 22505) +++ 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 {