[Mplayerxp-cvslog] SF.net SVN: mplayerxp:[223] mplayerxp
Brought to you by:
olov
From: <nic...@us...> - 2012-10-27 07:38:55
|
Revision: 223 http://mplayerxp.svn.sourceforge.net/mplayerxp/?rev=223&view=rev Author: nickols_k Date: 2012-10-27 07:38:46 +0000 (Sat, 27 Oct 2012) Log Message: ----------- NEW: next version of XP-CORE Modified Paths: -------------- mplayerxp/dump.c mplayerxp/libmpcodecs/dec_video.c mplayerxp/libmpdemux/cache2.c mplayerxp/libvo/sub.c mplayerxp/mplayer.c mplayerxp/mplayer.h mplayerxp/sig_hand.c mplayerxp/sig_hand.h mplayerxp/xmp_core.c mplayerxp/xmp_core.h Modified: mplayerxp/dump.c =================================================================== --- mplayerxp/dump.c 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/dump.c 2012-10-27 07:38:46 UTC (rev 223) @@ -39,7 +39,7 @@ int len; FILE *f; const char *ext,*name; - MP_UNIT(xp_id,"dumpstream"); + MP_UNIT("dumpstream"); stream_reset(stream); stream_seek(stream,stream->start_pos); ext=".ext"; @@ -306,7 +306,7 @@ int in_size,aeof,veof,seof,cmd; if(!priv) return; - MP_UNIT(xp_id,"dump"); + MP_UNIT("dump"); priv->my_use_pts=use_pts; /* test stream property */ MSG_INFO("%s using PTS method\n",use_pts?"":"not"); Modified: mplayerxp/libmpcodecs/dec_video.c =================================================================== --- mplayerxp/libmpcodecs/dec_video.c 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/libmpcodecs/dec_video.c 2012-10-27 07:38:46 UTC (rev 223) @@ -300,12 +300,12 @@ if(mp_subtitles && v_pts>0){ float pts=v_pts; if(sub_fps==0) sub_fps=sh_video->fps; - MP_UNIT(xp_id,"find_sub"); + MP_UNIT("find_sub"); if (pts > sub_last_pts || pts < sub_last_pts-1.0 ) { find_sub(mp_subtitles,sub_uses_time?(100*pts):(pts*sub_fps),vo_data); // FIXME! frame counter... sub_last_pts = pts; } - MP_UNIT(xp_id,NULL); + MP_UNIT(NULL); } #endif @@ -325,7 +325,7 @@ if(vo_data->spudec){ unsigned char* packet=NULL; int len,timestamp; - MP_UNIT(xp_id,"spudec"); + MP_UNIT("spudec"); spudec_now_pts(vo_data->spudec,90000*v_pts); if(spudec_visible(vo_data->spudec)) { vo_draw_spudec_direct(vo_data,xp_idx); @@ -347,7 +347,7 @@ } /* detect wether the sub has changed or not */ if(spudec_changed(vo_data->spudec)) vo_draw_spudec_direct(vo_data,xp_idx); - MP_UNIT(xp_id,NULL); + MP_UNIT(NULL); } } } Modified: mplayerxp/libmpdemux/cache2.c =================================================================== --- mplayerxp/libmpdemux/cache2.c 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/libmpdemux/cache2.c 2012-10-27 07:38:46 UTC (rev 223) @@ -54,12 +54,7 @@ /* thread related stuff */ int in_fill; pthread_mutex_t mutex; - pthread_attr_t cache2_attr; - pthread_t cache2_thread_id; - pid_t cache2_pid; /* Only for testing */ - pthread_t cache2_pth_id; - volatile int cache2_is_living; - volatile int cache2_end_of_work; + mpxp_thread_t* pth; /* for optimization: */ cache_packet_t *packets; char * mem; @@ -242,7 +237,7 @@ { MSG_V("cache2 segfault\n"); mp_msg_flush(); - killall_threads(pthread_self()); + xmp_killall_threads(pthread_self()); __exit_sighandler(); } @@ -254,42 +249,37 @@ static any_t*cache2_routine(any_t*arg) { - double tt; - unsigned int t=0; - unsigned int t2; - int xp_id,cfill; - cache_vars_t* c=(cache_vars_t*)arg; - c->cache2_is_living=1; - xp_id=init_signal_handling(sig_cache2,stream_unlink_cache); - MP_UNIT(xp_id,"cache2_routine"); - c->cache2_pid = pinfo[xp_id].pid = getpid(); /* Only for testing */ - c->cache2_pth_id = pinfo[xp_id].pth_id = pthread_self(); - pinfo[xp_id].thread_name = "cache2"; - while(1) - { - if(mp_conf.benchmark) t=GetTimer(); - cfill=c2_cache_fill(c); - if(mp_conf.benchmark) - { - t2=GetTimer();t=t2-t; - tt = t*0.000001f; - time_usage.c2+=tt; - if(tt > time_usage.max_c2) time_usage.max_c2=tt; - if(tt < time_usage.min_c2) time_usage.min_c2=tt; + mpxp_thread_t* priv=arg; + + double tt; + unsigned int t=0; + unsigned int t2; + int cfill; + cache_vars_t* c=(cache_vars_t*)arg; + + priv->state=Pth_Run; + priv->pid = getpid(); + + while(1) { + if(mp_conf.benchmark) t=GetTimer(); + cfill=c2_cache_fill(c); + if(mp_conf.benchmark) { + t2=GetTimer();t=t2-t; + tt = t*0.000001f; + time_usage.c2+=tt; + if(tt > time_usage.max_c2) time_usage.max_c2=tt; + if(tt < time_usage.min_c2) time_usage.min_c2=tt; + } + if(!cfill) usleep(FILL_USLEEP_TIME); // idle + if(priv->state==Pth_Canceling) break; } - if(!cfill) - usleep(FILL_USLEEP_TIME); // idle - if(c->cache2_end_of_work) break; - } - c->cache2_is_living=0; - uninit_signal_handling(xp_id); - return arg; + priv->state=Pth_Stand; + return arg; } int stream_enable_cache(stream_t *stream,int size,int _min,int prefill){ int ss=stream->sector_size>1?stream->sector_size:STREAM_BUFFER_SIZE; cache_vars_t* c; - int retval; if (!(stream->type&STREAMTYPE_SEEKABLE) && stream->fd < 0) { // The stream has no 'fd' behind it, so is non-cacheable @@ -304,20 +294,10 @@ c->stream=stream; c->prefill=size*prefill; c->read_filepos=stream->start_pos; - - pthread_attr_init(&c->cache2_attr); - retval = pthread_attr_setdetachstate(&c->cache2_attr,PTHREAD_CREATE_DETACHED); - if(retval) - { - if(mp_conf.verbose) printf("running thread: attr_setdetachstate fault!!!\n"); - return retval; - } - pthread_attr_setscope(&c->cache2_attr,PTHREAD_SCOPE_SYSTEM); - c->cache2_end_of_work=0; - retval = pthread_create(&c->cache2_thread_id,&c->cache2_attr,cache2_routine,c); - if(retval) return 0; - + unsigned rc; + if((rc=xmp_register_thread(sig_cache2,cache2_routine,"cache2"))==UINT_MAX) return 0; + c->pth=&xp_core.mpxp_threads[rc]; // wait until cache is filled at least prefill_init % MSG_V("CACHE_PRE_INIT: %lld [%lld] %lld pre:%d eof:%d SS=%u \n", START_FILEPOS(c),c->read_filepos,END_FILEPOS(c),_min,c->eof,ss); @@ -343,15 +323,11 @@ { cache_vars_t* c; c=st->cache_data; - if(c) - { - if(c->cache2_thread_id && c->cache2_is_living) - { - c->cache2_end_of_work=1; - while(c->cache2_is_living && !was_killed) usleep(0); - c->cache2_is_living=0; + if(c) { + if(c->pth && c->pth->state==Pth_Run) { + c->pth->state=Pth_Canceling; + while(c->pth->state==Pth_Canceling && !was_killed) usleep(0); } - pthread_attr_destroy(&c->cache2_attr); free(c->packets); free(c->mem); free(c); Modified: mplayerxp/libvo/sub.c =================================================================== --- mplayerxp/libvo/sub.c 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/libvo/sub.c 2012-10-27 07:38:46 UTC (rev 223) @@ -7,16 +7,17 @@ #include <malloc.h> #endif -#include "../mplayer.h" +#include "mplayer.h" +#include "xmp_core.h" #include "video_out.h" #include "font_load.h" #include "sub.h" #include "osd.h" #include "libmpsub/spudec.h" #include "libmpsub/vobsub.h" -#include "../libmpdemux/stream.h" +#include "libmpdemux/stream.h" #define MSGT_CLASS MSGT_OSD -#include "../__mp_msg.h" +#include "__mp_msg.h" static const char * __sub_osd_names[]={ "Seekbar", @@ -534,7 +535,7 @@ // obj->flags&=~OSDFLAG_OLD_BBOX; if(obj->cleared_frames>=0) { obj->cleared_frames++; - if(obj->cleared_frames>=xp_num_frames) + if(obj->cleared_frames>=xp_core.num_v_buffs) obj->cleared_frames=-1; // All cleared stop } } Modified: mplayerxp/mplayer.c =================================================================== --- mplayerxp/mplayer.c 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/mplayer.c 2012-10-27 07:38:46 UTC (rev 223) @@ -94,7 +94,6 @@ #include "xmp_core.h" volatile unsigned xp_drop_frame_cnt=0; -unsigned xp_num_frames=0; float xp_screen_pts; float playbackspeed_factor=1.0; int mpxp_seek_time=-1; @@ -108,9 +107,6 @@ subtitle* mp_subtitles=NULL; #endif -int xp_id=0; -pthread_t mplayer_pth_id; - int use_pts_fix2=-1; /************************************************************************ @@ -525,7 +521,7 @@ MSG_DBG2("decoded audio %d diff %d\n", l, l - len); if( ret <= 0 && d_audio->eof) { - MSG_V("xp_audio_eof\n"); + MSG_V("audio eof\n"); audio_buffer.eof=1; pthread_mutex_unlock( &audio_buffer.head_mutex ); pthread_mutex_lock( &audio_buffer.tail_mutex ); @@ -617,79 +613,79 @@ fflush(stderr); mask=inited_flags&mask; - MP_UNIT(xp_id,"uninit_xp"); - uninit_dec_ahead(0); + MP_UNIT("uninit_xp"); + xmp_uninit_engine(0); if (mask&INITED_SPUDEC){ inited_flags&=~INITED_SPUDEC; - MP_UNIT(xp_id,"uninit_spudec"); + MP_UNIT("uninit_spudec"); spudec_free(vo_data->spudec); vo_data->spudec=NULL; } if (mask&INITED_VOBSUB){ inited_flags&=~INITED_VOBSUB; - MP_UNIT(xp_id,"uninit_vobsub"); + MP_UNIT("uninit_vobsub"); vobsub_close(vo_data->vobsub); vo_data->vobsub=NULL; } if(mask&INITED_VCODEC){ inited_flags&=~INITED_VCODEC; - MP_UNIT(xp_id,"uninit_vcodec"); + MP_UNIT("uninit_vcodec"); mpcv_uninit(sh_video); sh_video=NULL; } if(mask&INITED_VO){ inited_flags&=~INITED_VO; - MP_UNIT(xp_id,"uninit_vo"); + MP_UNIT("uninit_vo"); vo_uninit(vo_data); } if(mask&INITED_ACODEC){ inited_flags&=~INITED_ACODEC; - MP_UNIT(xp_id,"uninit_acodec"); + MP_UNIT("uninit_acodec"); mpca_uninit(sh_audio); sh_audio=NULL; } if(mask&INITED_AO){ inited_flags&=~INITED_AO; - MP_UNIT(xp_id,"uninit_ao"); + MP_UNIT("uninit_ao"); ao_uninit(ao_data); } if(mask&INITED_GETCH2){ inited_flags&=~INITED_GETCH2; - MP_UNIT(xp_id,"uninit_getch2"); + MP_UNIT("uninit_getch2"); // restore terminal: getch2_disable(); } if(mask&INITED_DEMUXER){ inited_flags&=~INITED_DEMUXER; - MP_UNIT(xp_id,"free_demuxer"); + MP_UNIT("free_demuxer"); FREE_DEMUXER(demuxer); } if(mask&INITED_STREAM){ inited_flags&=~INITED_STREAM; - MP_UNIT(xp_id,"uninit_stream"); + MP_UNIT("uninit_stream"); if(stream) free_stream(stream); stream=NULL; } if(mask&INITED_INPUT){ inited_flags&=~INITED_INPUT; - MP_UNIT(xp_id,"uninit_input"); + MP_UNIT("uninit_input"); mp_input_uninit(); } #ifdef USE_SUB if(mask&INITED_SUBTITLE){ inited_flags&=~INITED_SUBTITLE; - MP_UNIT(xp_id,"sub_free"); + MP_UNIT("sub_free"); mp_input_uninit(); sub_free( mp_subtitles ); sub_name=NULL; @@ -697,7 +693,7 @@ mp_subtitles=NULL; } #endif - MP_UNIT(xp_id,NULL); + MP_UNIT(NULL); } void exit_player(char* how){ @@ -706,7 +702,7 @@ fflush(stderr); uninit_player(INITED_ALL); - MP_UNIT(xp_id,"exit_player"); + MP_UNIT("exit_player"); sws_uninit(); if(how) MSG_HINT(MSGTR_Exiting,how); @@ -732,7 +728,7 @@ } uninit_player((INITED_ALL)&(~(INITED_STREAM|INITED_DEMUXER))); - MP_UNIT(xp_id,"exit_player"); + MP_UNIT("exit_player"); MSG_HINT(MSGTR_Exiting,MSGTR_Exit_quit); MSG_DBG2("max framesize was %d bytes\n",max_framesize); if(mconfig) m_config_free(mconfig); @@ -740,17 +736,6 @@ exit(0); } -void killall_threads(pthread_t pth_id) -{ - unsigned i; - for(i=0;i < MAX_XPTHREADS;i++) { - if(pth_id && pinfo[i].pth_id && pinfo[i].pth_id != mplayer_pth_id) { - pthread_kill(pinfo[i].pth_id,SIGKILL); - if(pinfo[i].unlink) pinfo[i].unlink(pth_id); - } - } -} - void __exit_sighandler(void) { static int sig_count=0; @@ -768,7 +753,7 @@ void exit_sighandler(void) { - killall_threads(pthread_self()); + xmp_killall_threads(pthread_self()); __exit_sighandler(); } @@ -1000,7 +985,7 @@ //if(playsize>outburst) playsize=outburst; // Update buffer if needed - MP_UNIT(xp_id,"mpca_decode"); // Enter AUDIO decoder module + MP_UNIT("mpca_decode"); // Enter AUDIO decoder module t=GetTimer(); while(sh_audio->a_buffer_len<playsize && !audio_eof){ if(mp_conf.xp>=XP_VideoAudio) { @@ -1021,14 +1006,14 @@ { MSG_V("audio_stream_eof\n"); inited_flags&=~INITED_AO; - MP_UNIT(xp_id,"uninit_ao"); + MP_UNIT("uninit_ao"); ao_uninit(ao_data); } audio_eof=1; break; } } - MP_UNIT(xp_id,"play_audio"); // Leave AUDIO decoder module + MP_UNIT("play_audio"); // Leave AUDIO decoder module t=GetTimer()-t; tt = t*0.000001f; time_usage.audio+=tt; @@ -1139,7 +1124,7 @@ fflush(stdout); } -static void show_status_line(float v_pts,float AV_delay) { +static void show_status_line(float v_pts) { float a_pts=0; float delay=ao_get_delay(ao_data); float video_pts = v_pts; @@ -1157,6 +1142,7 @@ a_pts+=(ds_tell_pts_r(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; } if( !mp_conf.av_sync_pts && mp_conf.xp>=XP_VideoAudio ) delay += get_delay_audio_buffer(); + float AV_delay; AV_delay = a_pts-delay-video_pts; __show_status_line(a_pts,video_pts,delay,AV_delay); } @@ -1187,6 +1173,85 @@ fflush(stdout); } +static void vplayer_check_chapter_change(frame_attr_t* shva_prev,float v_pts) +{ + if(use_pts_fix2 && sh_audio) { + if(sh_video->chapter_change == -1) { /* First frame after seek */ + while(v_pts < 1.0 && sh_audio->timer==0.0 && ao_get_delay(ao_data)==0.0) + usleep(0); /* Wait for audio to start play */ + if(sh_audio->timer > 2.0 && v_pts < 1.0) { + MSG_V("Video chapter change detected\n"); + sh_video->chapter_change=1; + } else { + sh_video->chapter_change=0; + } + } else if(v_pts < 1.0 && shva_prev->v_pts > 2.0) { + MSG_V("Video chapter change detected\n"); + sh_video->chapter_change=1; + } + if(sh_video->chapter_change && sh_audio->chapter_change) { + MSG_V("Reset chapter change\n"); + sh_video->chapter_change=0; + sh_audio->chapter_change=0; + } + } +} + +static float vplayer_compute_sleep_time(frame_attr_t* shva_prev) +{ + float sleep_time=0; + if(sh_audio) { + /* FIXME!!! need the same technique to detect audio_eof as for video_eof! + often ao_get_delay() never returns 0 :( */ + if(audio_eof && !get_delay_audio_buffer()) goto nosound_model; + if((!audio_eof || ao_get_delay(ao_data)) && + (!use_pts_fix2 || (!sh_audio->chapter_change && !sh_video->chapter_change))) + sleep_time=xp_screen_pts-(sh_audio->timer-ao_get_delay(ao_data)); + else if(use_pts_fix2 && sh_audio->chapter_change) + sleep_time=0; + else + goto nosound_model; + } else { + nosound_model: + sleep_time=shva_prev->duration; + } + return sleep_time; +} + +static int vplayer_do_sleep(int rtc_fd,float sleep_time,float v_pts) +{ +#define XP_MIN_TIMESLICE 0.010 /* under Linux on x86 min time_slice = 10 ms */ +#define XP_MIN_AUDIOBUFF 0.05 +#define XP_MAX_TIMESLICE 0.1 + if(sh_audio && (!audio_eof || ao_get_delay(ao_data)) && sleep_time>XP_MAX_TIMESLICE) { + float t; + if(mp_conf.benchmark) show_status_line(v_pts); + + if( mp_conf.xp < XP_VAPlay ) { + t=ao_get_delay(ao_data)-XP_MIN_AUDIOBUFF; + if(t>XP_MAX_TIMESLICE) + t=XP_MAX_TIMESLICE; + } else + t = XP_MAX_TIMESLICE; + + usleep(t*1000000); + sleep_time-=GetRelativeTime(); + if(mp_conf.xp >= XP_VAPlay || t<XP_MAX_TIMESLICE || sleep_time>XP_MAX_TIMESLICE) { + // exit due no sound in soundcard + return 0; + } + } + + while(sleep_time>XP_MIN_TIMESLICE) { + /* free cpu for threads */ + usleep(1); + sleep_time-=GetRelativeTime(); + } + MP_UNIT("sleep_usleep"); + sleep_time=SleepTime(rtc_fd,mp_conf.softsleep,sleep_time); + return 1; +} + typedef struct osd_args_s { int visible; int info_factor; @@ -1195,47 +1260,26 @@ static float max_pts_correction=0; int mpxp_play_video( int rtc_fd, float *v_pts ) { - float time_frame=0; + float sleep_time=0; float AV_delay=0; /* average of A-V timestamp differences */ - int blit_frame=0; + int can_blit=0; int delay_corrected=1; int final_frame=0; frame_attr_t shva_prev,shva; shva_prev=dae_played_fra(xp_core.video); final_frame = shva_prev.eof; - if(xp_eof && final_frame) return 1; + if(xp_core.eof && final_frame) return 1; - blit_frame=dae_inc_played(xp_core.video); /* <-- SWITCH TO NEXT FRAME */ - + can_blit=dae_try_inc_played(xp_core.video); /* <-- TRY SWITCH TO NEXT FRAME */ shva=dae_played_fra(xp_core.video); - *v_pts = shva.v_pts; /*------------------------ frame decoded. --------------------*/ /* blit frame */ - if(xp_eof) blit_frame=1; /* force blitting until end of stream will be reached */ - if(use_pts_fix2 && sh_audio) { - if(sh_video->chapter_change == -1) { /* First frame after seek */ - while(*v_pts < 1.0 && sh_audio->timer==0.0 && ao_get_delay(ao_data)==0.0) - usleep(0); /* Wait for audio to start play */ - if(sh_audio->timer > 2.0 && *v_pts < 1.0) { - MSG_V("Video chapter change detected\n"); - sh_video->chapter_change=1; - } else { - sh_video->chapter_change=0; - } - } else if(*v_pts < 1.0 && shva_prev.v_pts > 2.0) { - MSG_V("Video chapter change detected\n"); - sh_video->chapter_change=1; - } - if(sh_video->chapter_change && sh_audio->chapter_change) { - MSG_V("Reset chapter change\n"); - sh_video->chapter_change=0; - sh_audio->chapter_change=0; - } - } + if(xp_core.eof) can_blit=1; /* force blitting until end of stream will be reached */ + vplayer_check_chapter_change(&shva_prev,*v_pts); #if 0 MSG_INFO("initial_audio_pts=%f a_eof=%i a_pts=%f sh_audio->timer=%f v_pts=%f stream_pts=%f duration=%f\n" ,initial_audio_pts @@ -1246,69 +1290,28 @@ ,shva[dec_ahead_active_frame].stream_pts ,shva[dec_ahead_active_frame].duration); #endif - if(blit_frame) { + if(can_blit) { xp_screen_pts=*v_pts-(mp_conf.av_sync_pts?0:initial_audio_pts); #ifdef USE_OSD /*--------- add OSD to the next frame contents ---------*/ MSG_D("dec_ahead_main: draw_osd to %u\n",player_idx); - MP_UNIT(xp_id,"draw_osd"); + MP_UNIT("draw_osd"); update_osd(shva.stream_pts); - vo_draw_osd(vo_data,dae_curr_vplayed()); + vo_draw_osd(vo_data,dae_next_played(xp_core.video)); #endif } /* It's time to sleep ;)...*/ - MP_UNIT(xp_id,"sleep"); + MP_UNIT("sleep"); GetRelativeTime(); /* reset timer */ - if(sh_audio) { - /* FIXME!!! need the same technique to detect audio_eof as for video_eof! - often ao_get_delay() never returns 0 :( */ - if(audio_eof && !get_delay_audio_buffer()) goto nosound_model; - if((!audio_eof || ao_get_delay(ao_data)) && - (!use_pts_fix2 || (!sh_audio->chapter_change && !sh_video->chapter_change))) - time_frame=xp_screen_pts-(sh_audio->timer-ao_get_delay(ao_data)); - else if(use_pts_fix2 && sh_audio->chapter_change) - time_frame=0; - else - goto nosound_model; - } else { - nosound_model: - time_frame=shva_prev.duration; - } - if(mp_conf.benchmark && time_frame < 0 && time_frame < max_av_resync) max_av_resync=time_frame; + sleep_time=vplayer_compute_sleep_time(&shva_prev); + + if(mp_conf.benchmark && sleep_time < 0 && sleep_time < max_av_resync) max_av_resync=sleep_time; if(!(vo_data->flags&256)){ /* flag 256 means: libvo driver does its timing (dvb card) */ -#define XP_MIN_TIMESLICE 0.010 /* under Linux on x86 min time_slice = 10 ms */ -#define XP_MIN_AUDIOBUFF 0.05 -#define XP_MAX_TIMESLICE 0.1 - - if(sh_audio && (!audio_eof || ao_get_delay(ao_data)) && time_frame>XP_MAX_TIMESLICE) { - float t; - if(mp_conf.benchmark) show_status_line(*v_pts,AV_delay); - - if( mp_conf.xp < XP_VAPlay ) { - t=ao_get_delay(ao_data)-XP_MIN_AUDIOBUFF; - if(t>XP_MAX_TIMESLICE) - t=XP_MAX_TIMESLICE; - } else - t = XP_MAX_TIMESLICE; - - usleep(t*1000000); - time_frame-=GetRelativeTime(); - if(mp_conf.xp >= XP_VAPlay || t<XP_MAX_TIMESLICE || time_frame>XP_MAX_TIMESLICE) { - return 0; - } - } - - while(time_frame>XP_MIN_TIMESLICE) { - /* free cpu for threads */ - usleep(1); - time_frame-=GetRelativeTime(); - } - MP_UNIT(xp_id,"sleep_usleep"); - time_frame=SleepTime(rtc_fd,mp_conf.softsleep,time_frame); + if(!vplayer_do_sleep(rtc_fd,sleep_time,*v_pts)) return 0; } - MP_UNIT(xp_id,"change_frame2"); + MP_UNIT("change_frame2"); /* don't flip if there is nothing new to display */ - if(!blit_frame) { + if(!can_blit) { static int drop_message=0; if(!drop_message && xp_core.video->num_slow_frames > 50) { drop_message=1; @@ -1324,8 +1327,9 @@ unsigned int t2=GetTimer(); double tt; unsigned player_idx; - player_idx=dae_curr_vplayed(); + player_idx=dae_next_played(xp_core.video); vo_select_frame(vo_data,player_idx); + dae_inc_played(xp_core.video); MSG_D("\ndec_ahead_main: schedule %u on screen\n",player_idx); t2=GetTimer()-t2; tt = t2*0.000001f; @@ -1337,7 +1341,7 @@ bench_dropped_frames ++; } } - MP_UNIT(xp_id,NULL); + MP_UNIT(NULL); /*================ A-V TIMESTAMP CORRECTION: =========================*/ /* FIXME: this block was added to fix A-V resync caused by some strange things @@ -1367,7 +1371,7 @@ MSG_DBG2("### A:%8.3f (%8.3f) V:%8.3f A-V:%7.4f \n",a_pts,a_pts-delay,*v_pts,(a_pts-delay)-*v_pts); - if(delay_corrected && blit_frame){ + if(delay_corrected && can_blit){ float x; AV_delay=(a_pts-delay)-*v_pts; x=AV_delay*0.1f; @@ -1392,7 +1396,6 @@ void mpxp_seek( int _xp_id, osd_args_t *osd,float v_pts,const seek_args_t* seek) { int seek_rval=1; - xp_core.in_lseek=Seek; audio_eof=0; if(seek->secs || seek->flags&DEMUX_SEEK_SET) { seek_rval=demux_seek_r(demuxer,seek); @@ -1421,20 +1424,20 @@ fflush(stdout); if(sh_video){ - MP_UNIT(xp_id,"seek_video_reset"); + MP_UNIT("seek_video_reset"); mpcv_resync_stream(sh_video); vo_reset(vo_data); sh_video->chapter_change=-1; } if(sh_audio){ - MP_UNIT(xp_id,"seek_audio_reset"); + MP_UNIT("seek_audio_reset"); mpca_resync_stream(sh_audio); ao_reset(ao_data); // stop audio, throwing away buffered data } if (vo_data->vobsub) { - MP_UNIT(xp_id,"seek_vobsub_reset"); + MP_UNIT("seek_vobsub_reset"); vobsub_seek_r(vo_data->vobsub, seek); } @@ -1468,8 +1471,7 @@ { unsigned i; seek_args_t seek = { 0, DEMUX_SEEK_CUR|DEMUX_SEEK_SECONDS }; - for(i=0;i<xp_threads;i++) if(strcmp(pinfo[i].thread_name,"main")==0) break; - if(sh_video) mpxp_seek(i,NULL,dae_played_fra(xp_core.video).v_pts,&seek); + if(sh_video) mpxp_seek(main_id,NULL,dae_played_fra(xp_core.video).v_pts,&seek); return; } @@ -1552,7 +1554,7 @@ #endif fifo_make_pipe(&keyb_fifo_get,&keyb_fifo_put); /* Init input system */ - MP_UNIT(xp_id,"init_input"); + MP_UNIT("init_input"); mp_input_init(); if(keyb_fifo_get > 0) mp_input_add_key_fd(keyb_fifo_get,1,NULL,NULL); @@ -1590,7 +1592,7 @@ MSG_WARN("Menu init failed\n"); } } - MP_UNIT(xp_id,"init_osd"); + MP_UNIT("init_osd"); vo_init_osd(); } @@ -1608,14 +1610,14 @@ video_driver[i] = '\0'; } } - MP_UNIT(xp_id,"vo_register"); + MP_UNIT("vo_register"); vo_inited = (vo_register(vo_data,video_driver)!=NULL)?1:0; if(!vo_inited){ MSG_FATAL(MSGTR_InvalidVOdriver,video_driver?video_driver:"?"); exit_player(MSGTR_Exit_error); } - MP_UNIT(xp_id,"vo_init"); + MP_UNIT("vo_init"); if((i=vo_init(vo_data,vo_conf.subdevice))!=0) { MSG_FATAL("Error opening/initializing the selected video_out (-vo) device!\n"); @@ -1623,7 +1625,7 @@ } // check audio_out driver name: - MP_UNIT(xp_id,"ao_init"); + MP_UNIT("ao_init"); if (audio_driver) if ((i=strcspn(audio_driver, ":")) > 0) { @@ -1646,7 +1648,7 @@ static int mpxp_init_vobsub(const char *filename) { int forced_subs_only=0; - MP_UNIT(xp_id,"vobsub"); + MP_UNIT("vobsub"); if (vobsub_name){ vo_data->vobsub=vobsub_open(vobsub_name,mp_conf.spudec_ifo,1,&vo_data->spudec); if(vo_data->vobsub==NULL) @@ -1677,7 +1679,7 @@ int eof=0; play_tree_t* entry; // Handle playlist - MP_UNIT(xp_id,"handle_playlist"); + MP_UNIT("handle_playlist"); MSG_V("Parsing playlist %s...\n",filename); entry = parse_playtree(stream); if(!entry) { @@ -1711,7 +1713,7 @@ /* Add NLS support here */ char *lang; if(!mp_conf.audio_lang) mp_conf.audio_lang=nls_get_screen_cp(); - MP_UNIT(xp_id,"dvd lang->id"); + MP_UNIT("dvd lang->id"); if(mp_conf.audio_lang) { lang=malloc(max(strlen(mp_conf.audio_lang)+1,4)); strcpy(lang,mp_conf.audio_lang); @@ -1757,7 +1759,7 @@ } static void mpxp_read_video_properties(void) { - MP_UNIT(xp_id,"video_read_properties"); + MP_UNIT("video_read_properties"); if(!video_read_properties(sh_video)) { MSG_ERR("Video: can't read properties\n"); sh_video=d_video->sh=NULL; @@ -1781,20 +1783,20 @@ static void mpxp_read_subtitles(const char *filename,int forced_subs_only,int stream_dump_type) { if (mp_conf.spudec_ifo) { unsigned int palette[16], width, height; - MP_UNIT(xp_id,"spudec_init_vobsub"); + MP_UNIT("spudec_init_vobsub"); if (vobsub_parse_ifo(NULL,mp_conf.spudec_ifo, palette, &width, &height, 1, -1, NULL) >= 0) vo_data->spudec=spudec_new_scaled(palette, sh_video->src_w, sh_video->src_h); } if (vo_data->spudec==NULL) { unsigned *pal; - MP_UNIT(xp_id,"spudec_init"); + MP_UNIT("spudec_init"); if(stream->driver->control(stream,SCTRL_VID_GET_PALETTE,&pal)==SCTRL_OK) vo_data->spudec=spudec_new_scaled(pal,sh_video->src_w, sh_video->src_h); } if (vo_data->spudec==NULL) { - MP_UNIT(xp_id,"spudec_init_normal"); + MP_UNIT("spudec_init_normal"); vo_data->spudec=spudec_new_scaled(NULL, sh_video->src_w, sh_video->src_h); spudec_set_font_factor(vo_data->spudec,font_factor); } @@ -1809,7 +1811,7 @@ // after reading video params we should load subtitles because // we know fps so now we can adjust subtitles time to ~6 seconds AST // check .sub - MP_UNIT(xp_id,"read_subtitles_file"); + MP_UNIT("read_subtitles_file"); if(sub_name){ mp_subtitles=sub_read_file(sub_name, sh_video->fps); if(!mp_subtitles) MSG_ERR(MSGTR_CantLoadSub,sub_name); @@ -1869,7 +1871,7 @@ static int mpxp_find_vcodec(void) { int rc=0; - MP_UNIT(xp_id,"init_video_codec"); + MP_UNIT("init_video_codec"); /* Go through the codec.conf and find the best codec...*/ sh_video->inited=0; vo_data->flags=0; @@ -1913,7 +1915,7 @@ static int mpxp_configure_audio(void) { int rc=0; const ao_info_t *info=ao_get_info(); - MP_UNIT(xp_id,"setup_audio"); + MP_UNIT("setup_audio"); MSG_V("AO: [%s] %iHz %s %s\n", info->short_name, force_srate?force_srate:sh_audio->samplerate, @@ -1931,7 +1933,7 @@ if(strlen(info->comment) > 0) MSG_V("AO: Comment: %s\n", info->comment); - MP_UNIT(xp_id,"af_preinit"); + MP_UNIT("af_preinit"); ao_data->samplerate=force_srate?force_srate:sh_audio->samplerate; ao_data->channels=audio_output_channels?audio_output_channels:sh_audio->channels; ao_data->format=sh_audio->sample_format; @@ -1957,7 +1959,7 @@ if(sh_video == NULL) rc=-1; } else { inited_flags|=INITED_AO; - MP_UNIT(xp_id,"af_init"); + MP_UNIT("af_init"); if(!mpca_init_filters(sh_audio, (int)(sh_audio->samplerate), sh_audio->channels, sh_audio->sample_format, sh_audio->samplesize, @@ -1971,17 +1973,17 @@ } static void mpxp_run_ahead_engine(void) { - MP_UNIT(xp_id,"init_xp"); - if(sh_video && xp_num_frames < 5) {/* we need at least 5 buffers to suppress screen judering */ - MSG_FATAL("Not enough buffers for DECODING AHEAD!\nNeed %u buffers but exist only %u\n",5,xp_num_frames); + MP_UNIT("init_xp"); + if(sh_video && xp_core.num_v_buffs < 3) {/* we need at least 3 buffers to suppress screen judering */ + MSG_FATAL("Not enough buffers for DECODING AHEAD!\nNeed %u buffers but exist only %u\n",3,xp_core.num_v_buffs); exit_player("Try other '-vo' driver.\n"); } - if(init_dec_ahead(sh_video,sh_audio)!=0) + if(xmp_init_engine(sh_video,sh_audio)!=0) exit_player("Can't initialize decoding ahead!\n"); - if(run_dec_ahead()!=0) + if(xmp_run_decoders()!=0) exit_player("Can't run decoding ahead!\n"); - if(sh_video) MSG_OK("Using DECODING AHEAD mplayer's core with %u video buffers\n",xp_num_frames); - else MSG_OK("Using DECODING AHEAD mplayer's core with %u audio buffers\n",ao_da_buffs); + if(sh_video) MSG_OK("Using DECODING AHEAD mplayer's core with %u video buffers\n",xp_core.num_v_buffs); + else MSG_OK("Using DECODING AHEAD mplayer's core with %u audio buffers\n",xp_core.num_a_buffs); /* reset counters */ xp_drop_frame_cnt=0; } @@ -2340,13 +2342,11 @@ seek_args_t seek_args = { 0, DEMUX_SEEK_CUR|DEMUX_SEEK_SECONDS }; mpxp_init_structs(); - vo_data=vo_preinit_structs(); + init_signal_handling(); - pinfo[xp_id].pid=getpid(); - mplayer_pth_id= - pinfo[xp_id].pth_id=pthread_self(); - pinfo[xp_id].thread_name = "main"; + xmp_init(); + xmp_register_main(exit_sighandler); mp_msg_init(MSGL_STATUS); MSG_INFO("%s",banner_text); @@ -2391,7 +2391,7 @@ } } - ao_da_buffs = vo_conf.da_buffs; + xp_core.num_a_buffs = vo_conf.da_buffs; init_player(); @@ -2414,9 +2414,8 @@ // ========== Init keyboard FIFO (connection to libvo) ============ mpxp_init_keyboard_fifo(); - MP_UNIT(xp_id,NULL); + MP_UNIT(NULL); - xp_id = init_signal_handling(exit_sighandler,NULL); // ******************* Now, let's see the per-file stuff ******************** play_next_file: @@ -2433,7 +2432,7 @@ forced_subs_only=mpxp_init_vobsub(filename); - MP_UNIT(xp_id,"mplayer"); + MP_UNIT("mplayer"); if(!input_state.after_dvdmenu) { stream=NULL; demuxer=NULL; @@ -2452,7 +2451,7 @@ } if(stream_dump_type) mp_conf.s_cache_size=0; - MP_UNIT(xp_id,"open_stream"); + MP_UNIT("open_stream"); if(!input_state.after_dvdmenu) stream=open_stream(filename,&file_format,stream_dump_type>1?dump_stream_event_handler:mpxp_stream_event_handler); if(!stream) { // error... eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY); @@ -2468,11 +2467,11 @@ /* Add NLS support here */ mpxp_init_dvd_nls(); - MP_UNIT(xp_id,NULL); + MP_UNIT(NULL); // CACHE2: initial prefill: 20% later: 5% (should be set by -cacheopts) if(mp_conf.s_cache_size && !stream_dump_type){ - MP_UNIT(xp_id,"enable_cache"); + MP_UNIT("enable_cache"); if(!stream_enable_cache(stream,mp_conf.s_cache_size*1024,mp_conf.s_cache_size*1024/5,mp_conf.s_cache_size*1024/20)) if((eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY))) goto goto_next_file; } @@ -2486,7 +2485,7 @@ if(!has_video) mp_conf.video_id=-2; // do NOT read video packets... if(!has_dvdsub) mp_conf.dvdsub_id=-2;// do NOT read subtitle packets... - MP_UNIT(xp_id,"demux_open"); + MP_UNIT("demux_open"); if(!input_state.after_dvdmenu) demuxer=demux_open(stream,file_format,mp_conf.audio_id,mp_conf.video_id,mp_conf.dvdsub_id); if(!demuxer) goto goto_next_file; // exit_player(MSGTR_Exit_error); // ERROR @@ -2517,7 +2516,7 @@ if(sh_video) mpxp_read_subtitles(filename,forced_subs_only,stream_dump_type); //================== Init AUDIO (codec) ========================== - MP_UNIT(xp_id,"init_audio_codec"); + MP_UNIT("init_audio_codec"); if(sh_audio) mpxp_find_acodec(); @@ -2553,7 +2552,7 @@ /*================== Init VIDEO (codec & libvo) ==========================*/ if(!sh_video) goto main; - MP_UNIT(xp_id,"init_video_filters"); + MP_UNIT("init_video_filters"); if(sh_video->vfilter_inited<=0) { sh_video->vfilter=vf_init(sh_video); sh_video->vfilter_inited=1; @@ -2563,7 +2562,7 @@ goto main; } - xp_num_frames=vo_get_num_frames(vo_data); /* that really known after init_vcodecs */ + xp_core.num_v_buffs=vo_get_num_frames(vo_data); /* that really known after init_vcodecs */ if(mp_conf.autoq>0){ /* Auto quality option enabled*/ @@ -2579,7 +2578,7 @@ inited_flags|=INITED_VO; MSG_V("INFO: Video OUT driver init OK!\n"); - MP_UNIT(xp_id,"init_libvo"); + MP_UNIT("init_libvo"); fflush(stdout); //================== MAIN: ========================== @@ -2591,7 +2590,7 @@ if(sh_audio) if((mpxp_configure_audio())!=0) goto goto_next_file; - MP_UNIT(xp_id,"av_init"); + MP_UNIT("av_init"); if(mp_conf.av_force_pts_fix2==1 || (mp_conf.av_force_pts_fix2==-1 && mp_conf.av_sync_pts && @@ -2660,11 +2659,16 @@ if(sh_video) { do { usleep(0); - }while(dae_get_decoder_outrun(xp_core.video) < xp_num_frames/2 && !xp_eof); + }while(dae_get_decoder_outrun(xp_core.video) < xp_core.num_v_buffs/2 && !xp_core.eof); } - if(run_xp_aplayers()!=0) exit_player("Can't run xp players!\n"); - MSG_OK("Using the next %i threads:\n",xp_threads); - for(i=0;i<xp_threads;i++) MSG_OK("[%i] %s (id=%u, pth_id=%lu)\n",i,pinfo[i].thread_name,pinfo[i].pid,pinfo[i].pth_id); + if(xmp_run_players()!=0) exit_player("Can't run xp players!\n"); + MSG_OK("Using the next %i threads:\n",xp_core.num_threads); + for(i=0;i<xp_core.num_threads;i++) + MSG_OK("[%i] %s (id=%u, pth_id=%lu)\n" + ,i + ,xp_core.mpxp_threads[i]->name + ,xp_core.mpxp_threads[i]->pid + ,xp_core.mpxp_threads[i]->pth_id); //==================== START PLAYING ======================= MSG_OK(MSGTR_StartPlaying);fflush(stdout); @@ -2680,9 +2684,9 @@ } if( mp_conf.xp < XP_VAPlay ) - eof |= decore_audio(xp_id); + eof |= decore_audio(main_id); /*========================== UPDATE TIMERS ============================*/ - MP_UNIT(xp_id,"Update timers"); + MP_UNIT("Update timers"); if(!sh_video) { if(mp_conf.benchmark && mp_conf.verbose) show_benchmark_status(); else mpxp_print_audio_status(); @@ -2743,9 +2747,9 @@ } if(seek_args.secs || (seek_args.flags&DEMUX_SEEK_SET)) { - MP_UNIT(xp_id,"seek"); + MP_UNIT("seek"); - dec_ahead_halt_threads(0); + xmp_halt_threads(0); if(seek_args.secs && sh_video) { frame_attr_t shvap = dae_played_fra(xp_core.video); @@ -2753,15 +2757,15 @@ seek_args.secs -= (xp_is_bad_pts?shvad.v_pts:d_video->pts)-shvap.v_pts; } - mpxp_seek(xp_id,&osd,v_pts,&seek_args); + mpxp_seek(main_id,&osd,v_pts,&seek_args); audio_eof=0; seek_args.secs=0; seek_args.flags=DEMUX_SEEK_CUR|DEMUX_SEEK_SECONDS; - dec_ahead_restart_threads(xp_id); + xmp_restart_threads(main_id); /* Disable threads for DVD menus */ - MP_UNIT(xp_id,NULL); + MP_UNIT(NULL); } #ifdef USE_OSD update_osd(d_video->pts); Modified: mplayerxp/mplayer.h =================================================================== --- mplayerxp/mplayer.h 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/mplayer.h 2012-10-27 07:38:46 UTC (rev 223) @@ -47,15 +47,12 @@ }mp_conf_t; extern mp_conf_t mp_conf; -extern unsigned xp_num_frames; -extern int xp_id; extern unsigned mplayer_accel; extern int use_pts_fix2; extern void exit_player(char* how); extern void mpxp_resync_audio_stream(void); extern void mpxp_reset_vcache(void); -extern void killall_threads(pthread_t pth_id); extern void __exit_sighandler(void); extern void mplayer_put_key(int code); Modified: mplayerxp/sig_hand.c =================================================================== --- mplayerxp/sig_hand.c 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/sig_hand.c 2012-10-27 07:38:46 UTC (rev 223) @@ -8,6 +8,7 @@ #endif #include <string.h> #include <stdio.h> +#include <stdlib.h> #include <signal.h> #include <sys/resource.h> #include "sig_hand.h" @@ -17,9 +18,6 @@ #include "xmp_core.h" #include "mp_msg.h" -pth_info_t pinfo[MAX_XPTHREADS]; -int xp_threads = 0; - #ifdef HAVE_BACKTRACE #include <execinfo.h> /* Obtain a backtrace and print it to stdout. */ @@ -50,32 +48,28 @@ static void my_callback(int signo) { int i; - for(i=0; i < MAX_XPTHREADS && !pthread_equal(pinfo[i].pth_id, pthread_self()); i++); - if(i >= MAX_XPTHREADS || i >= xp_threads || !pthread_equal(pinfo[i].pth_id, pthread_self())) { - i = 0; /* Use 0 as default handler */ - } + pthread_t _self = pthread_self(); + for(i=0; i < xp_core.num_threads && !pthread_equal(xp_core.mpxp_threads[i]->pth_id, _self); i++); + if(i >= xp_core.num_threads || + !pthread_equal(xp_core.mpxp_threads[i]->pth_id, _self)) i = 0; /* Use 0 as default handler */ - mp_msg(MSGT_CPLAYER,MSGL_FATAL,__FILE__,__LINE__,"catching signal: %s in thread: %s (%i) in module: %s\n",strsignal(signo),pinfo[i].thread_name,i,pinfo[i].current_module); + mp_msg(MSGT_CPLAYER,MSGL_FATAL,__FILE__,__LINE__,"catching signal: %s in thread: %s (%i) in module: %s\n" + ,strsignal(signo) + ,xp_core.mpxp_threads[i]->name + ,i + ,xp_core.mpxp_threads[i]->unit); #ifdef HAVE_BACKTRACE - dump_trace(); + dump_trace(); #endif - pinfo[i].sig_handler(); + xp_core.mpxp_threads[i]->sigfunc(); - signal(signo,SIG_DFL); - /* try coredump*/ - return; + signal(signo,SIG_DFL); /* try coredump*/ + + return; } -int init_signal_handling( void (*callback)( void ),void (*_unlink)(int)) +void init_signal_handling( void ) { - if(xp_threads >= MAX_XPTHREADS) - return MAX_XPTHREADS-1; - pinfo[xp_threads].sig_handler = callback; - pinfo[xp_threads].pid = getpid(); - pinfo[xp_threads].pth_id = pthread_self(); - pinfo[xp_threads].current_module = NULL; - pinfo[xp_threads].unlink = _unlink; - xp_threads++; #ifndef MP_DEBUG /*========= Catch terminate signals: ================*/ /* terminate requests:*/ @@ -102,18 +96,4 @@ setrlimit(RLIMIT_CORE,&rl); } #endif - return xp_threads-1; } - -void uninit_signal_handling(int xp_id) -{ - pinfo[xp_id].pid = 0; - pinfo[xp_id].pth_id = 0; - pinfo[xp_id].current_module = NULL; - pinfo[xp_id].sig_handler = NULL; - - if(xp_threads == xp_id+1) { - while( xp_threads > 0 && pinfo[xp_threads-1].pid == 0 ) - xp_threads--; - } -} Modified: mplayerxp/sig_hand.h =================================================================== --- mplayerxp/sig_hand.h 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/sig_hand.h 2012-10-27 07:38:46 UTC (rev 223) @@ -5,28 +5,14 @@ #define __SIG_HAND_H 1 #include <sys/types.h> +#include "xmp_core.h" -#define MAX_XPTHREADS 16 +#define __MP_UNIT(id,name) (xp_core.mpxp_threads[id]->unit=name) +#define MP_UNIT(name) (xp_core.mpxp_threads[main_id]->unit=name) -typedef void (*mysighandler)(void); +extern void init_signal_handling( void ); +extern void uninit_signal_handling( int xp_id ); -typedef struct pth_info -{ - mysighandler sig_handler; - pid_t pid; - const char *thread_name; - const char *current_module; - void (*unlink)(int force); - pthread_t pth_id; -} pth_info_t; - -extern pth_info_t pinfo[MAX_XPTHREADS]; -extern int xp_threads; -#define MP_UNIT(id,name) (pinfo[id].current_module=name) - -int init_signal_handling( void (*callback)( void ),void (*unlink)(int)); -void uninit_signal_handling( int xp_id ); - #endif Modified: mplayerxp/xmp_core.c =================================================================== --- mplayerxp/xmp_core.c 2012-10-26 13:01:26 UTC (rev 222) +++ mplayerxp/xmp_core.c 2012-10-27 07:38:46 UTC (rev 223) @@ -36,13 +36,45 @@ xp_core_t xp_core; -void xp_core_init(void) { +void xmp_init(void) { memset(&xp_core,0,sizeof(xp_core_t)); - xp_core.in_lseek=NoSeek; } -void xp_core_uninit(void) {} +void xmp_uninit(void) {} +unsigned xmp_register_main(sig_handler_t sigfunc) { + unsigned idx=0; + xp_core.mpxp_threads[idx]=malloc(sizeof(mpxp_thread_t)); + memset(xp_core.mpxp_threads[idx],0,sizeof(mpxp_thread_t)); + xp_core.mpxp_threads[idx]->p_idx=idx; + xp_core.mpxp_threads[idx]->pid=getpid(); + xp_core.main_pth_id=xp_core.mpxp_threads[idx]->pth_id=pthread_self(); + xp_core.mpxp_threads[idx]->name = "main"; + xp_core.mpxp_threads[idx]->sigfunc = sigfunc; + xp_core.num_threads++; + + return idx; +} + +static void print_stopped_thread(unsigned idx) { + MSG_OK("*** stop thread: [%i] %s\n",idx,xp_core.mpxp_threads[idx]->name); +} + +void xmp_killall_threads(pthread_t _self) +{ + unsigned i; + for(i=0;i < MAX_MPXP_THREADS;i++) { + if( _self && + xp_core.mpxp_threads[i]->pth_id && + xp_core.mpxp_threads[i]->pth_id != xp_core.main_pth_id) { + pthread_kill(xp_core.mpxp_threads[i]->pth_id,SIGKILL); + print_stopped_thread(i); + free(xp_core.mpxp_threads[i]); + xp_core.mpxp_threads[i]=NULL; + } + } +} + void dae_reset(dec_ahead_engine_t* it) { it->player_idx=0; it->decoder_idx=0; @@ -61,7 +93,7 @@ void dae_uninit(dec_ahead_engine_t* it) { free(it->fra); it->fra=0; } /* returns 1 - on success 0 - if busy */ -int dae_inc_played(dec_ahead_engine_t* it) { +int dae_try_inc_played(dec_ahead_engine_t* it) { unsigned new_idx; new_idx=(it->player_idx+1)%it->nframes; if(new_idx==it->decoder_idx) { @@ -73,6 +105,15 @@ it->num_played_frames++; return 1; } + +int dae_inc_played(dec_ahead_engine_t* it) { + unsigned new_idx; + new_idx=(it->player_idx+1)%it->nframes; + if(new_idx==it->decoder_idx) return 0; + it->player_idx=new_idx; + return 1; +} + /* returns 1 - on success 0 - if busy */ int dae_inc_decoded(dec_ahead_engine_t* it) { unsigned new_idx; @@ -113,15 +154,10 @@ extern volatile unsigned xp_drop_frame_cnt; extern int output_quality; -int ao_da_buffs; - extern volatile float xp_screen_pts; volatile int dec_ahead_can_aseek=0; /* It is safe to seek audio */ volatile int dec_ahead_can_adseek=1; /* It is safe to seek audio buffer thread */ -static pthread_t pthread_id=0; -static pthread_attr_t our_attr; -static pthread_attr_t audio_attr; static sh_video_t *sh_video; static sh_audio_t *sh_audio; extern demux_stream_t *d_video; @@ -136,9 +172,6 @@ extern int mpxp_seek_time; extern void update_osd( float v_pts ); -volatile int xp_eof=0; -int xp_audio_eof=0; -#define NORM_FRAME(a) ((a)%xp_num_frames) /* To let audio decoder thread sleep as long as player */ struct timespec audio_play_timeout; @@ -155,13 +188,6 @@ any_t* audio_play_routine( any_t* arg ); -static volatile int pthread_is_living=0; -static volatile int a_pthread_is_living=0; -static volatile int pthread_audio_is_living=0; -static volatile int pthread_end_of_work=0; -static volatile int a_pthread_end_of_work=0; -static volatile int pthread_audio_end_of_work=0; - int xp_is_bad_pts=0; /* this routine decodes video+audio but intends to be video only */ @@ -176,7 +202,7 @@ "*********************************************\n" "Try increase number of buffer for decoding ahead\n" "Exist: %u, need: %u\n" - ,xp_num_frames,(unsigned)(max_frame_delay*3*sh_video->fps)+3); + ,xp_core.num_v_buffs,(unsigned)(max_frame_delay*3*sh_video->fps)+3); prev_warn_delay=max_frame_delay; } } @@ -190,7 +216,7 @@ /* TODO: Replace the constants with some values which are depended on - xp_num_frames and max_frame_delay to find out the smoothest way + xp_core.num_v_buffs and max_frame_delay to find out the smoothest way to display frames on slow machines. MAYBE!!!: (won't work with some realmedia streams for example) Try to borrow avifile's logic (btw, GPL'ed ;) for very slow systems: @@ -200,7 +226,7 @@ */ delta=v_pts-xp_screen_pts; if(max_frame_delay*3 > drop_barrier) { - if(drop_barrier < (float)(xp_num_frames-2)/sh_video->fps) drop_barrier += 1/sh_video->fps; + if(drop_barrier < (float)(xp_core.num_v_buffs-2)/sh_video->fps) drop_barrier += 1/sh_video->fps; else if(mp_conf.verbose) show_warn_cant_sync(max_frame_delay); } @@ -243,7 +269,7 @@ fra[idx2].stream_pts = fra[idx2].v_pts; fra[idx2].duration = fra[idx1].v_pts - fra[idx2].v_pts; - idx3=(idx2-1)%xp_num_frames; + idx3=(idx2-1)%xp_core.num_v_buffs; if(fra[idx2].v_pts > fra[idx3].v_pts && fra[idx2].v_pts - fra[idx3].v_pts < 1.0) fra[idx3].duration = fra[idx2].v_pts - fra[idx3].v_pts; @@ -252,32 +278,30 @@ idx0 = idx1; idx1 = idx2; - idx2=(idx2-1)%xp_num_frames; + idx2=(idx2-1)%xp_core.num_v_buffs; } } any_t* Va_dec_ahead_routine( any_t* arg ) { + mpxp_thread_t* priv=arg; + float duration=0; float drop_barrier; int blit_frame=0; int drop_param=0; unsigned xp_n_frame_to_drop; - int _xp_id; float v_pts,mpeg_timer=HUGE; - pthread_is_living=1; - xp_eof = 0; - xp_audio_eof=0; + priv->state=Pth_Run; + xp_core.eof = 0; + xp_core.a_eof=0; MSG_T("\nDEC_AHEAD: entering...\n"); - _xp_id=init_signal_handling(sig_dec_ahead_video,uninit_dec_ahead); - MP_UNIT(_xp_id,"dec_ahead"); - pinfo[_xp_id].pid = getpid(); /* Only for testing */ - pinfo[_xp_id].pth_id = pthread_self(); - pinfo[_xp_id].thread_name = (xp_core.has_audio && mp_conf.xp < XP_VAFull) ? - "video+audio decoding+filtering ahead" : - "video decoding+vf ahead"; - drop_barrier=(float)(xp_num_frames/2)*(1/sh_video->fps); + __MP_UNIT(priv->p_idx,"dec_ahead"); + priv->pid = getpid(); + if(!(xp_core.has_audio && mp_conf.xp < XP_VAFull)) + priv->name = "video decoder+vf"; + drop_barrier=(float)(xp_core.num_v_buffs/2)*(1/sh_video->fps); if(mp_conf.av_sync_pts == -1 && !use_pts_fix2) xp_is_bad_pts = d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_ES || d_video->demuxer->file_format == DEMUXER_TYPE_MPEG4_ES || @@ -286,48 +310,38 @@ d_video->demuxer->file_format == DEMUXER_TYPE_MPEG_TS; else xp_is_bad_pts = mp_conf.av_sync_pts?0:1; -while(!xp_eof){ +while(!xp_core.eof){ unsigned char* start=NULL; int in_size; - if(pthread_end_of_work) break; - if(xp_core.in_lseek==PreSeek) { - MP_UNIT(_xp_id,"Pre seek"); - xp_core.in_lseek=Seek; + if(priv->state==Pth_Canceling) break; + if(priv->state==Pth_Sleep) { +pt_sleep: + priv->state=Pth_ASleep; + while(priv->state==Pth_ASleep) usleep(0); + if(xp_is_bad_pts) mpeg_timer=HUGE; + continue; } - MP_UNIT(_xp_id,"dec_ahead 1"); + __MP_UNIT(priv->p_idx,"dec_ahead 1"); /* get it! */ #if 0 /* prevent reent access to non-reent demuxer */ //if(sh_video->num_frames>200) *((char*)0x100) = 1; // Testing crash if(xp_core.has_audio && mp_conf.xp<XP_VAFull) { - MP_UNIT(_xp_id,"decode audio"); + __MP_UNIT(priv->p_idx,"decode audio"); while(2==xp_thread_decode_audio()) ; - MP_UNIT(_xp_id,"dec_ahead 2"); + __MP_UNIT(priv->p_idx,"dec_ahead 2"); } #endif /*-------------------- Decode a frame: -----------------------*/ in_size=video_read_frame_r(sh_video,&duration,&v_pts,&start,sh_video->fps); - if(xp_core.in_lseek==Seek) { - MP_UNIT(_xp_id,"Post seek"); - if(xp_is_bad_pts) mpeg_timer=HUGE; - xp_core.in_lseek=NoSeek; - MP_UNIT(_xp_id,"dec_ahead 3"); - } if(in_size<0) { xp_core.video->fra[xp_core.video->decoder_idx].eof=1; - xp_eof=1; - if(xp_core.in_lseek) { - xp_eof=0; - continue; - } + xp_core.eof=1; break; } /* in_size==0: it's or broken stream or demuxer's bug */ - if(in_size==0 && !pthread_end_of_work) { - xp_core.in_lseek=NoSeek; - continue; - } + if(in_size==0 && priv->state!=Pth_Canceling) continue; /* frame was decoded into current decoder_idx */ if(xp_is_bad_pts) { if(mpeg_timer==HUGE) mpeg_timer=v_pts; @@ -343,9 +357,8 @@ int cur_time; cur_time = GetTimerMS(); /* Ugly solution: disable frame dropping right after seeking! */ - if(cur_time - mpxp_seek_time > (xp_num_frames/sh_video->fps)*100) xp_n_frame_to_drop=compute_frame_dropping(v_pts,drop_barrier); + if(cur_time - mpxp_seek_time > (xp_core.num_v_buffs/sh_video->fps)*100) xp_n_frame_to_drop=compute_frame_dropping(v_pts,drop_barrier); } /* if( mp_conf.frame_dropping ) */ - if(xp_core.in_lseek!=NoSeek) continue; #if 0 /* We can't seriously examine question of too slow machines @@ -362,7 +375,7 @@ else drop_param=0; /* decode: */ if(output_quality) { - unsigned total = xp_num_frames/2; + unsigned total = xp_core.num_v_buffs/2; unsigned distance = dae_get_decoder_outrun(xp_core.video); int our_quality; our_quality = output_quality*distance/total; @@ -397,66 +410,68 @@ while(!dae_inc_decoded(xp_core.video)) { MSG_T("DEC_AHEAD: sleep: player=%i decoder=%i)\n" ,dae_curr_vplayed(),dae_curr_vdecoded()); - if(pthread_end_of_work) goto pt_exit; - if(xp_core.in_lseek!=NoSeek) break; + if(priv->state==Pth_Canceling) goto pt_exit; + if(priv->state==Pth_Sleep) goto pt_sleep; if(xp_core.has_audio && mp_conf.xp<XP_VAFull) { - MP_UNIT(_xp_id,"decode audio"); + __MP_UNIT(priv->p_idx,"decode audio"); xp_thread_decode_audio(); - MP_UNIT(_xp_id,"dec_ahead 5"); + __MP_UNIT(priv->p_idx,"dec_ahead 5"); } usleep(1); } /*------------------------ frame decoded. --------------------*/ -} /* while(!xp_eof)*/ +} /* while(!xp_core.eof)*/ if(xp_core.has_audio && mp_conf.xp<XP_VAFull) { - while(!xp_audio_eof && !xp_core.in_lseek && !pthread_end_of_work) { - MP_UNIT(_xp_id,"decode audio"); + while(!xp_core.a_eof && priv->state!=Pth_Canceling && priv->state!=Pth_Sleep) { + __MP_UNIT(priv->p_idx,"decode audio"); if(!xp_thread_decode_audio()) usleep(1); - MP_UNIT(_xp_id,NULL); + __MP_UNIT(priv->p_idx,NULL); } } pt_exit: MSG_T("\nDEC_AHEAD: leaving...\n"); - pthread_is_living=0; - pthread_end_of_work=0; - uninit_signal_handling(_xp_id); + priv->state=Pth_Stand; return arg; /* terminate thread here !!! */ } /* this routine decodes audio only */ any_t* a_dec_ahead_routine( any_t* arg ) { - int xp_id; + mpxp_thread_t* priv=arg; + int ret, retval; struct timeval now; struct timespec timeout; float d; - a_pthread_is_living=1; - xp_eof = 0; - xp_audio_eof=0; + priv->state=Pth_Run; + xp_core.eof = 0; + xp_core.a_eof=0; MSG_T("\nDEC_AHEAD: entering...\n"); - xp_id=init_signal_handling(sig_audio_decode,uninit_dec_ahead); - MP_UNIT(xp_id,"dec_ahead"); - pinfo[xp_id].thread_name = "audio decoding+af ahead"; + priv->pid = getpid(); + __MP_UNIT(priv->p_idx,"dec_ahead"); dec_ahead_can_adseek=0; - while(!a_pthread_end_of_work) { - MP_UNIT(xp_id,"decode audio"); - while((ret = xp_thread_decode_audio()) == 2) /* Almost empty buffer */ - if(xp_audio_eof) break; - + while(priv->state!=Pth_Canceling) { + if(priv->state==Pth_Sleep) { + priv->state=Pth_ASleep; + while(priv->state==Pth_ASleep) usleep(0); + continue; + } + __MP_UNIT(priv->p_idx,"decode audio"); + while((ret = xp_thread_decode_audio()) == 2) {/* Almost empty buffer */ + if(xp_core.a_eof) break; + } dec_ahead_can_adseek=1; - - if(a_pthread_end_of_work) - break; - - MP_UNIT(xp_id,"sleep"); + + if(priv->state==Pth_Canceling) break; + + __MP_UNIT(priv->p_idx,"sleep"); LOCK_AUDIO_DECODE(); - if( !xp_core.in_lseek && !a_pthread_end_of_work) { - if(xp_audio_eof) { - MP_UNIT(xp_id,"wait end of work"); + if(priv->state!=Pth_Canceling) { + if(xp_core.a_eof) { + __MP_UNIT(priv->p_idx,"wait end of work"); pthread_cond_wait( &audio_decode_cond, &audio_decode_mutex ); } else if(ret==0) { /* Full buffer or end of file */ if(audio_play_in_sleep) { /* Sleep a little longer than player thread */ @@ -484,13 +499,13 @@ usleep(1); } UNLOCK_AUDIO_DECODE(); - - if(a_pthread_end_of_work) - break; - - MP_UNIT(xp_id,"seek"); + + if(priv->state==Pth_Canceling) break; + + __MP_UNIT(priv->p_idx,"seek"); LOCK_AUDIO_DECODE(); - while( xp_core.in_lseek!=NoSeek && !a_pthread_end_of_work) { +#if 0 + while(priv->state==Pth_Sleep && priv->state!=Pth_Canceling) { gettimeofday(&now,NULL); timeout.tv_nsec = now.tv_usec * 1000; timeout.tv_sec = now.tv_sec + 1; @@ -498,69 +513,42 @@ if( retval == ETIMEDOUT ) MSG_V("Audio decode seek timeout\n"); } +#endif dec_ahead_can_adseek = 0; /* Not safe to seek */ UNLOCK_AUDIO_DECODE(); } - MP_UNIT(xp_id,"exit"); + __MP_UNIT(priv->p_idx,"exit"); dec_ahead_can_adseek = 1; - a_pthread_is_living=0; - a_pthread_end_of_work=0; - uninit_signal_handling(xp_id); + priv->state=Pth_Stand; return arg; /* terminate thread here !!! */ } -void uninit_dec_ahead( int force ) +void xmp_uninit_engine( int force ) { - if(pthread_id && pthread_is_living && xp_core.has_video) - { - pthread_end_of_work=1; - while(pthread_is_living && !force) usleep(0); - pthread_is_living=0; - pthread_attr_destroy(&our_attr); - dae_uninit(xp_core.video); - xp_core.has_video=0; - } + xmp_stop_threads(force); - if(xp_core.has_audio && !force) { /* audio state doesn't matter on segfault :( */ - a_pthread_end_of_work=1; - xp_audio_eof=1; - if(a_pthread_is_living) { - __MP_SYNCHRONIZE(audio_decode_mutex,pthread_cond_signal(&audio_decode_cond)); - } - while(a_pthread_is_living && !force) usleep(0); - a_pthread_is_living=0; - if( pthread_audio_is_living ) { - pthread_audio_end_of_work=1; - LOCK_AUDIO_PLAY(); - pthread_cond_signal(&audio_play_cond); - uninit_audio_buffer(); - xp_core.has_audio=0; - UNLOCK_AUDIO_PLAY(); - while(pthread_audio_is_living && !force) - usleep(0); - pthread_audio_is_living=0; - pthread_attr_destroy(&audio_attr); - } - if(xp_core.has_audio) { - uninit_audio_buffer(); - xp_core.has_audio=0; - } - } - xp_core_uninit(); + if(xp_core.has_video) { + dae_uninit(xp_core.video); + xp_core.has_video=0; + } + + if(xp_core.has_audio) { /* audio state doesn't matter on segfault :( */ + uninit_audio_buffer(); + xp_core.has_audio=0; + } + xmp_uninit(); } /* Min audio buffer to keep free, used to tell differ between full and empty buffer */ #define MIN_BUFFER_RESERV 8 -int init_dec_ahead(sh_video_t *shv, sh_audio_t *sha) +int xmp_init_engine(sh_video_t *shv, sh_audio_t *sha) { - pthread_attr_init(&our_attr); - xp_core_init(); if(shv) { sh_video = shv; xp_core.has_video=1; xp_core.video=malloc(sizeof(dec_ahead_engine_t)); - dae_init(xp_core.video,xp_num_frames); + dae_init(xp_core.video,xp_core.num_v_buffs); } else {/* if (mp_conf.xp >= XP_VAFull) mp_conf.xp = XP_VAPlay;*/ } if(sha) sh_audio = sha; /* currently is unused */ @@ -570,111 +558,119 @@ unsigned o_bps; unsigned min_reserv; o_bps=sh_audio->afilter_inited?sh_audio->af_bps:sh_audio->o_bps; - if(xp_core.has_video) asize = max(3*sha->audio_out_minsize,max(3*MAX_OUTBURST,o_bps*xp_num_frames/sh_video->fps))+MIN_BUFFER_RESERV; - else asize = o_bps*ao_da_buffs; + if(xp_core.has_video) asize = max(3*sha->audio_out_minsize,max(3*MAX_OUTBURST,o_bps*xp_core.num_v_buffs/sh_video->fps))+MIN_BUFFER_RESERV; + else asize = o_bps*xp_core.num_a_buffs; /* FIXME: get better indices from asize/real_audio_packet_size */ min_reserv = sha->audio_out_minsize; if (o_bps > sha->o_bps) min_reserv = (float)min_reserv * (float)o_bps / (float)sha->o_bps; init_audio_buffer(asize+min_reserv,min_reserv+MIN_BUFFER_RESERV,asize/(sha->audio_out_minsize<10000?sha->audio_out_minsize:4000)+100,sha); xp_core.has_audio=1; - if( mp_conf.xp >= XP_VAPlay ) - pthread_attr_init(&audio_attr); } - return 0; } -int run_dec_ahead( void ) -{ - int retval; - retval = pthread_attr_setdetachstate(&our_attr,PTHREAD_CREATE_DETACHED); - if(retval) - { - if(mp_conf.verbose) printf("running thread: attr_setdetachstate fault!!!\n"); - return retval; - } - pthread_attr_setscope(&our_attr,PTHREAD_SCOPE_SYSTEM); - - if( xp_core.has_audio && mp_conf.xp >= XP_VAPlay ) { - retval = pthread_attr_setdetachstate(&audio_attr,PTHREAD_CREATE_DETACHED); - if(retval) { - if(mp_conf.verbose) printf("running audio thread: attr_setdetachstate fault!!!\n"); - return retval; - } - pthread_attr_setscope(&audio_attr,PTHREAD_SCOPE_SYSTEM); - } - +unsigned xmp_register_thread(sig_handler_t sigfunc,mpxp_routine_t routine,const char *name) { + unsigned idx=xp_core.num_threads; + int rc; + if(idx>=MAX_MPXP_THREADS) return UINT_MAX; + pthread_attr_t attr; + pthread_attr_init(&attr); + rc=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); + if(rc) { + MSG_ERR("running thread: attr_setdetachstate fault!!!\n"); + pthread_attr_destroy(&attr); + return rc; + } + pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM); #if 0 - /* requires root privelegies */ - pthread_attr_setschedpolicy(&our_attr,SCHED_FIFO); + /* requires root privelegies */ + pthread_attr_setschedpolicy(&attr,SCHED_FIFO); #endif - if( (xp_core.has_audio && mp_conf.xp >= XP_VAFull) || !xp_core.has_video ) - { - retval = pthread_create(&pthread_id,&audio_attr,a_dec_ahead_routine,NULL); - if( retval ) return retval; - while(!a_pthread_is_living) usleep(0); - } - if( xp_core.has_video ) { - retval = pthread_create(&pthread_id,&our_attr,Va_dec_ahead_routine,NULL); - if(retval) return retval; - while(!pthread_is_living) usleep(0); - } - return 0; + xp_core.mpxp_threads[idx]=malloc(sizeof(mpxp_thread_t)); + memset(xp_core.mpxp_threads[idx],0,sizeof(mpxp_thread_t)); + + xp_core.mpxp_threads[idx]->p_idx=idx; + xp_core.mpxp_threads[idx]->name=name; + xp_core.mpxp_threads[idx]->routine=routine; + xp_core.mpxp_threads[idx]->sigfunc=sigfunc; + xp_core.mpxp_threads[idx]->state=Pth_Stand; + + rc=pthread_create(&xp_core.mpxp_threads[idx]->pth_id,&attr,routine,xp_core.mpxp_threads[idx]); + pthread_attr_destroy(&attr); + + xp_core.num_threads++; + return (rc?UINT_MAX:idx); } -int run_xp_aplayers(void) +int xmp_run_decoders( void ) { - int retval; - if( xp_core.has_audio && mp_conf.xp >= XP_VAPlay ) - { - retval = pthread_create(&pthread_id,&audio_attr,audio_play_routine,NULL); - if( retval ) return retval; - while(!pthread_audio_is_living) usleep(0); - } - return 0; + unsigned rc; + if((xp_core.has_audio && mp_conf.xp >= XP_VAFull) || !xp_core.has_video) { + if((rc=xmp_register_thread(sig_audio_decode,a_dec_ahead_routine,"audio decoder+af"))==UINT_MAX) return rc; + while(xp_core.mpxp_threads[rc]->state!=Pth_Run) usleep(0); + } + if(xp_core.has_video) { + if((rc=xmp_register_thread(sig_dec_ahead_video,Va_dec_ahead_routine,"video+audio decoders & af+vf"))==UINT_MAX) return rc; + while(xp_core.mpxp_threads[rc]->state!=Pth_Run) usleep(0); + } + return 0; } - -/* Halt threads before seek */ -void dec_ahead_halt_threads(int is_reset_vcache) +int xmp_run_players(void) { - xp_core.in_lseek = PreSeek; - - if(pthread_audio_is_living) { - LOCK_AUDIO_PLAY(); - while(!dec_ahead_can_aseek) - usleep(1); - UNLOCK_AUDIO_PLAY(); + unsigned rc; + if( xp_core.has_audio && mp_conf.xp >= XP_VAPlay ) { + if((rc=xmp_register_thread(sig_audio_play,audio_play_routine,"audio player"))==UINT_MAX) return rc; + while(xp_core.mpxp_threads[rc]->state!=Pth_Run) usleep(0); } + return 0; +} - if(a_pthread_is_living) { - LOCK_AUDIO_DECODE(); - while(!dec_ahead_can_adseek) - usleep(1); - UNLOCK_AUDIO_DECODE(); +/* Stops threads before seek */ +void xmp_stop_threads(int force) +{ + unsigned i; + for(i=1;i<xp_core.num_threads;i++) { + if(force) pthread_kill(xp_core.mpxp_threads[i]->pth_id,SIGKILL); + else { + xp_core.mpxp_threads[i]->state=Pth_Canceling; + while(xp_core.mpxp_threads[i]->state==Pth_Canceling) usleep(0); + } + print_stopped_thread(i); + free(xp_core.mpxp_threads[i]); + xp_core.mpxp_threads[i]=NULL; } +} - if(pthread_is_living) { - while(xp_core.in_lseek==PreSeek) - usleep(1); +/* Halt threads before seek */ +void xmp_halt_threads(int is_reset_vcache) +{ + unsigned i; + for(i=1;i<xp_core.num_threads;i++) { + xp_core.mpxp_threads[i]->state=Pth_Sleep; + while(xp_core.mpxp_threads[i]->state==Pth_Sleep) usleep(0); } - xp_core.in_lseek = Seek; } /* Restart threads after seek */ -void dec_ahead_restart_threads(int xp_id) +void xmp_restart_threads(int xp_id) { /* reset counters */ dae_reset(xp_core.video); - /* tempoarry solution */ + /* temporary solution */ reset_audio_buffer(); /* Ugly hack: but we should read audio packet before video after seeking. Else we'll get picture destortion on the screen */ initial_audio_pts=HUGE; + unsigned i; + for(i=1;i<xp_core.num_threads;i++) { + xp_core.mpxp_threads[i]->state=Pth_Run; + while(xp_core.mpxp_threads[i]->state==Pth_ASleep) usleep(0); + } +#if 0 if... [truncated message content] |