diff --git a/libmpdemux/Makefile b/libmpdemux/Makefile index b6d3b6ea72..c027b9db82 100644 --- a/libmpdemux/Makefile +++ b/libmpdemux/Makefile @@ -3,7 +3,7 @@ LIBNAME = libmpdemux.a include ../config.mak -SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c opt-reg.c +SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c opt-reg.c mpdemux.c ifeq ($(STREAMING),yes) SRCS += asf_streaming.c url.c http.c network.c rtp.c endif diff --git a/libmpdemux/cache2.c b/libmpdemux/cache2.c index 4b6deb0cdc..a925920370 100644 --- a/libmpdemux/cache2.c +++ b/libmpdemux/cache2.c @@ -8,7 +8,7 @@ #define READ_USLEEP_TIME 10000 #define FILL_USLEEP_TIME 50000 -#define PREFILL_USLEEP_TIME 200000 +#define PREFILL_SLEEP_TIME 200 #include #include @@ -196,7 +196,7 @@ static void exit_sighandler(int x){ exit(0); } -void stream_enable_cache(stream_t *stream,int size,int min,int prefill){ +int stream_enable_cache(stream_t *stream,int size,int min,int prefill){ int ss=(stream->type==STREAMTYPE_VCD)?VCD_SECTOR_DATA:STREAM_BUFFER_SIZE; cache_vars_t* s=cache_init(size,ss); stream->cache_data=s; @@ -213,9 +213,10 @@ void stream_enable_cache(stream_t *stream,int size,int min,int prefill){ s->max_filepos-s->read_filepos ); if(s->eof) break; // file is smaller than prefill size - usleep(PREFILL_USLEEP_TIME); + if(mpdemux_check_interrupt(PREFILL_SLEEP_TIME)) + return 0; } - return; // parent exits + return 1; // parent exits } // cache thread mainloop: diff --git a/libmpdemux/network.c b/libmpdemux/network.c index 91a55cb741..ddd243eef3 100644 --- a/libmpdemux/network.c +++ b/libmpdemux/network.c @@ -19,6 +19,7 @@ #include "stream.h" #include "demuxer.h" #include "../cfgparser.h" +#include "mpdemux.h" #include "network.h" #include "http.h" @@ -124,7 +125,7 @@ int connect2Server(char *host, int port) { int socket_server_fd; int err, err_len; - int ret; + int ret,count = 0; fd_set set; struct timeval tv; struct sockaddr_in server_address; @@ -160,16 +161,24 @@ connect2Server(char *host, int port) { return -1; } } - tv.tv_sec = 15; // 15 seconds timeout on connection - tv.tv_usec = 0; + tv.tv_sec = 0; + tv.tv_usec = 500000; FD_ZERO( &set ); FD_SET( socket_server_fd, &set ); // When the connection will be made, we will have a writable fd - ret = select(socket_server_fd+1, NULL, &set, NULL, &tv); - if( ret<=0 ) { - if( ret<0 ) perror("select failed"); - else printf("Connection timeout\n"); + while((ret = select(socket_server_fd+1, NULL, &set, NULL, &tv)) == 0) { + if( ret<0 ) perror("select failed"); + else if(ret > 0) break; + else if(count > 15 || mpdemux_check_interrupt(500)) { + if(count > 15) + printf("Connection timeout\n"); + else + printf("Connection interuppted by user\n"); return -1; + } + count++; + FD_ZERO( &set ); + FD_SET( socket_server_fd, &set ); } // Turn back the socket as blocking diff --git a/libmpdemux/stream.h b/libmpdemux/stream.h index 0ef3d622cf..2d87336df4 100644 --- a/libmpdemux/stream.h +++ b/libmpdemux/stream.h @@ -46,12 +46,12 @@ typedef struct { } stream_t; #ifdef USE_STREAM_CACHE -void stream_enable_cache(stream_t *stream,int size,int min,int prefill); +int stream_enable_cache(stream_t *stream,int size,int min,int prefill); #else // no cache #define cache_stream_fill_buffer(x) stream_fill_buffer(x) #define cache_stream_seek_long(x,y) stream_seek_long(x,y) -#define stream_enable_cache(x,y) +#define stream_enable_cache(x,y) 1 #endif int cache_stream_fill_buffer(stream_t *s); diff --git a/mplayer.c b/mplayer.c index 5760ceee6f..60eb7ec511 100644 --- a/mplayer.c +++ b/mplayer.c @@ -343,7 +343,7 @@ void uninit_player(unsigned int mask){ stream=NULL; } -#ifdef HAVE_LIRC +#if defined(HAVE_LIRC) && ! defined(HAVE_NEW_INPUT) if(mask&INITED_LIRC){ inited_flags&=~INITED_LIRC; current_module="uninit_lirc"; @@ -422,6 +422,34 @@ if ((conffile = get_path("")) == NULL) { } } +// When libmpdemux perform a blocking operation (network connection or cache filling) +// if the operation fail we use this function to check if it was interrupted by the user. +// The function return a new value for eof. +static int libmpdemux_was_interrupted(int eof) { +#ifdef HAVE_NEW_INPUT + mp_cmd_t* cmd; + if((cmd = mp_input_get_cmd(0,0)) != NULL) { + switch(cmd->id) { + case MP_CMD_QUIT: + exit_player(MSGTR_Exit_quit); + case MP_CMD_PLAY_TREE_STEP: { + eof = (cmd->args[0].v.i > 0) ? PT_NEXT_ENTRY : PT_PREV_ENTRY; + } break; + case MP_CMD_PLAY_TREE_UP_STEP: { + eof = (cmd->args[0].v.i > 0) ? PT_UP_NEXT : PT_UP_PREV; + } break; + case MP_CMD_PLAY_ALT_SRC_STEP: { + eof = (cmd->args[0].v.i > 0) ? PT_NEXT_SRC : PT_PREV_SRC; + } break; + } + mp_cmd_free(cmd); + } + return eof; +#else + return 0; +#endif +} + int main(int argc,char* argv[], char *envp[]){ #ifdef USE_SUB @@ -724,6 +752,11 @@ current_module = NULL; play_next_file: +if(!use_stdin && !slave_mode){ + getch2_enable(); // prepare stdin for hotkeys... + inited_flags|=INITED_GETCH2; +} + #ifdef HAVE_NEW_GUI if ( use_gui ) { @@ -891,11 +924,24 @@ play_dvd: } } +#ifdef HAVE_NEW_INPUT + if(!slave_mode && filename && !use_stdin && !strcmp(filename,"-")) { + mp_input_rm_key_fd(0); + use_stdin = 1; + } + else if(!slave_mode && use_stdin && (!filename || strcmp(filename,"-"))) { + mp_input_add_key_fd(0,1,NULL,NULL); + use_stdin = 0; + } +#else + use_stdin=filename && (!strcmp(filename,"-")); +#endif + current_module="open_stream"; stream=open_stream(filename,vcd_track,&file_format); if(!stream) { // error... - uninit_player(inited_flags-(INITED_GUI+INITED_LIRC+INITED_INPUT)); - goto goto_next_file_src; + eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY); + goto goto_next_file; } inited_flags|=INITED_STREAM; if(stream->type == STREAMTYPE_PLAYLIST) { @@ -905,23 +951,29 @@ play_dvd: entry = parse_playtree(stream); if(!entry) { entry = playtree_iter->tree; - if(play_tree_iter_step(playtree_iter,1,0) != PLAY_TREE_ITER_ENTRY) + if(play_tree_iter_step(playtree_iter,1,0) != PLAY_TREE_ITER_ENTRY) { + eof = PT_NEXT_ENTRY; goto goto_next_file; - if(playtree_iter->tree == entry) { // Loop with a single file - if(play_tree_iter_up_step(playtree_iter,1,0) != PLAY_TREE_ITER_ENTRY) + } + if(playtree_iter->tree == entry ) { // Loop with a single file + if(play_tree_iter_up_step(playtree_iter,1,0) != PLAY_TREE_ITER_ENTRY) { + eof = PT_NEXT_ENTRY; goto goto_next_file; + } } play_tree_remove(entry,1,1); - uninit_player(inited_flags-(INITED_GUI+INITED_LIRC+INITED_INPUT)); - goto goto_next_file_src; + eof = PT_NEXT_SRC; + goto goto_next_file; } play_tree_insert_entry(playtree_iter->tree,entry); entry = playtree_iter->tree; - if(play_tree_iter_step(playtree_iter,1,0) != PLAY_TREE_ITER_ENTRY) + if(play_tree_iter_step(playtree_iter,1,0) != PLAY_TREE_ITER_ENTRY) { + eof = PT_NEXT_ENTRY; goto goto_next_file; + } play_tree_remove(entry,1,1); - uninit_player(inited_flags-(INITED_GUI+INITED_LIRC+INITED_INPUT)); - goto goto_next_file_src; + eof = PT_NEXT_SRC; + goto goto_next_file; } stream->start_pos+=seek_to_byte; @@ -954,20 +1006,11 @@ current_module=NULL; #endif // initial prefill: 20% later: 5% (should be set by -cacheopts) - if(stream_cache_size) stream_enable_cache(stream,stream_cache_size*1024,stream_cache_size*1024/5,stream_cache_size*1024/20); - -#ifdef HAVE_NEW_INPUT - if(!slave_mode && filename && !use_stdin && !strcmp(filename,"-")) { - mp_input_rm_key_fd(0); - use_stdin = 1; - } - else if(!slave_mode && use_stdin && (!filename || strcmp(filename,"-"))) { - mp_input_add_key_fd(0,1,NULL,NULL); - use_stdin = 0; - } -#else - use_stdin=filename && (!strcmp(filename,"-")); -#endif + if(stream_cache_size && ! stream_enable_cache(stream,stream_cache_size*1024,stream_cache_size*1024/5,stream_cache_size*1024/20)) { + eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY); + if(eof) + goto goto_next_file; + } #ifdef HAVE_LIBCSS current_module="libcss"; @@ -1532,7 +1575,12 @@ while(sh_audio){ ao_data.pts=sh_audio->timer*90000.0; playsize=audio_out->get_space(); - if(!playsize) break; // buffer is full, do not block here!!! + if(!playsize) { + if(sh_video) + break; // buffer is full, do not block here!!! + usec_sleep(10000); // Wait a tick before retry + continue; + } if(playsize>MAX_OUTBURST) playsize=MAX_OUTBURST; // we shouldn't exceed it! //if(playsize>outburst) playsize=outburst; @@ -1592,7 +1640,6 @@ if(!sh_video) { ,(sh_audio->timer>0.5)?100.0*audio_time_usage/(double)sh_audio->timer:0 ,cache_fill_status ); - usec_sleep(sh_audio->a_buffer_len/(float)sh_audio->o_bps*1000000); goto read_input; } @@ -2827,8 +2874,6 @@ if(eof == PT_NEXT_ENTRY || eof == PT_PREV_ENTRY) { eof = eof == PT_PREV_SRC ? -1 : 1; } -goto_next_file_src: // When we have multiple src for file - if(eof == 0) eof = 1; #ifdef HAVE_NEW_GUI