diff --git a/veejay-current/veejay-server/bio2jack/bio2jack.c b/veejay-current/veejay-server/bio2jack/bio2jack.c index ea0a6c7a..cbe624d9 100644 --- a/veejay-current/veejay-server/bio2jack/bio2jack.c +++ b/veejay-current/veejay-server/bio2jack/bio2jack.c @@ -70,9 +70,9 @@ a 'TIMER("stop\n")' at the end of any function and this does the rest (naturally you can place any printf-compliant text you like in the argument along with the associated values). */ -static struct timeval timer_now; +static struct timespec timer_now; #define TIMER(format,args...) gettimeofday(&timer_now,0); \ - veejay_msg(4, "%ld.%06ld: %s::%s(%d) "format, timer_now.tv_sec, timer_now.tv_usec, __FILE__, __FUNCTION__, __LINE__, ##args) + veejay_msg(4, "%ld.%06ld: %s::%s(%d) "format, timer_now.tv_sec, timer_now.tv_nsec, __FILE__, __FUNCTION__, __LINE__, ##args) #else #define TIMER(...) #endif @@ -150,7 +150,7 @@ typedef struct jack_driver_s unsigned long rw_buffer1_size; /* number of bytes in the buffer allocated for processing data in JACK_(Read|Write) */ char *rw_buffer1; - struct timeval previousTime; /* time of last JACK_Callback() write to jack, allows for MS accurate bytes played */ + struct timespec previousTime; /* time of last JACK_Callback() write to jack, allows for MS accurate bytes played */ unsigned long num_ticks; unsigned long chunk_size; @@ -192,7 +192,7 @@ typedef struct jack_driver_s /* variables used for trying to restart the connection to jack */ bool jackd_died; /* true if jackd has died and we should try to restart it */ - struct timeval last_reconnect_attempt; + struct timespec last_reconnect_attempt; } jack_driver_t; @@ -247,19 +247,27 @@ static void JACK_CleanupDriver(jack_driver_t * drv); /* Return the difference between two timeval structures in terms of milliseconds */ + long -TimeValDifference(struct timeval *start, struct timeval *end) +TimeValDifference1(struct timespec *start, struct timespec *end) { double long ms; /* milliseconds value */ ms = end->tv_sec - start->tv_sec; /* compute seconds difference */ ms *= (double) 1000; /* convert to milliseconds */ - ms += (double) (end->tv_usec - start->tv_usec) / (double) 1000; /* add on microseconds difference */ + // ms += (double) (end->tv_usec - start->tv_usec) / (double) 1000; /* add on microseconds difference */ return (long) ms; } +long +TimeValDifference( struct timespec *start, struct timespec *end) +{ + return (( end->tv_sec * 1000000000) + end->tv_nsec ) - + (( start->tv_sec * 1000000000) + start->tv_nsec ); +} + /* get a device and lock the devices mutex */ /* */ /* also attempt to reconnect to jack since this function is called from */ @@ -293,8 +301,8 @@ getDriver(int deviceID) /* should we try to restart the jack server? */ if(drv->jackd_died && drv->client == 0) { - struct timeval now; - gettimeofday(&now, 0); + struct timespec now; + clock_gettime( CLOCK_REALTIME, &now); /* wait 250ms before trying again */ if(TimeValDifference(&drv->last_reconnect_attempt, &now) >= 250) @@ -516,8 +524,8 @@ JACK_callback(nframes_t nframes, void *arg) drv->chunk_size = nframes; TIMER("start\n"); - gettimeofday(&drv->previousTime, 0); /* record the current time */ - +// gettimeofday(&drv->previousTime, 0); /* record the current time */ + clock_gettime( CLOCK_REALTIME, &drv->previousTime ); CALLBACK_TRACE("nframes %ld, sizeof(sample_t) == %d\n", (long) nframes, sizeof(sample_t)); @@ -550,9 +558,6 @@ JACK_callback(nframes_t nframes, void *arg) long read = 0; - CALLBACK_TRACE("playing... jackFramesAvailable = %ld inputFramesAvailable = %ld\n", - jackFramesAvailable, inputFramesAvailable); - #if JACK_CLOSE_HACK if(drv->in_use == FALSE) { @@ -570,8 +575,6 @@ JACK_callback(nframes_t nframes, void *arg) (&drv->callback_buffer2, &drv->callback_buffer2_size, jackBytesAvailable)) { - - return -1; } @@ -2287,7 +2290,7 @@ JACK_GetPositionFromDriver(jack_driver_t * drv, enum pos_enum position, int type) { long return_val = 0; - struct timeval now; + struct timespec now; long elapsedMS; double sec2msFactor = 1000; @@ -2312,7 +2315,8 @@ JACK_GetPositionFromDriver(jack_driver_t * drv, enum pos_enum position, { type_str = "PLAYED"; return_val = drv->played_client_bytes; - gettimeofday(&now, 0); +// gettimeofday(&now, 0); + clock_gettime( CLOCK_REALTIME, &now ); elapsedMS = TimeValDifference(&drv->previousTime, &now); /* find the elapsed milliseconds since last JACK_Callback() */ @@ -2526,8 +2530,9 @@ JACK_CleanupDriver(jack_driver_t * drv) drv->output_sample_rate_ratio = 1.0; drv->input_sample_rate_ratio = 1.0; drv->jackd_died = FALSE; - gettimeofday(&drv->previousTime, 0); /* record the current time */ - gettimeofday(&drv->last_reconnect_attempt, 0); + clock_gettime(CLOCK_REALTIME, &drv->previousTime); /* record the current time */ +// gettimeofday(&drv->last_reconnect_attempt, 0); + memcpy( &drv->last_reconnect_attempt, &drv->previousTime, sizeof(struct timespec)); } /* Initialize the jack porting library to a clean state */ @@ -2677,11 +2682,11 @@ JACK_SetClientName(char *name) } } -long JACK_OutputStatus(int deviceID,long int *sec, long int *usec) +long JACK_OutputStatus(int deviceID,long *sec, long *usec) { jack_driver_t *this = &outDev[deviceID]; - *sec = (long int) this->previousTime.tv_sec; - *usec = (long int) this->previousTime.tv_usec; + *sec = this->previousTime.tv_sec; + *usec = this->previousTime.tv_nsec; return (this->num_ticks * this->chunk_size); } diff --git a/veejay-current/veejay-server/bio2jack/bio2jack.h b/veejay-current/veejay-server/bio2jack/bio2jack.h index 7a295681..64e304d0 100644 --- a/veejay-current/veejay-server/bio2jack/bio2jack.h +++ b/veejay-current/veejay-server/bio2jack/bio2jack.h @@ -138,7 +138,7 @@ enum JACK_PORT_CONNECTION_MODE /* defaults to CONNECT_ALL */ void JACK_SetPortConnectionMode(enum JACK_PORT_CONNECTION_MODE mode); -long JACK_OutputStatus(int deviceID,long int *sec, long int *usec); +long JACK_OutputStatus(int deviceID,long *sec, long *usec); #ifdef __cplusplus } diff --git a/veejay-current/veejay-server/veejay/liblavplayvj.c b/veejay-current/veejay-server/veejay/liblavplayvj.c index 2e476acb..bb7be96e 100644 --- a/veejay-current/veejay-server/veejay/liblavplayvj.c +++ b/veejay-current/veejay-server/veejay/liblavplayvj.c @@ -1239,6 +1239,7 @@ static void veejay_mjpeg_software_frame_sync(veejay_t * info, { video_playback_setup *settings = (video_playback_setup *) info->settings; +// int skip = 0; if (info->uc->use_timer ) { @@ -1251,33 +1252,26 @@ static void veejay_mjpeg_software_frame_sync(veejay_t * info, struct timespec nsecsleep; int usec_since_lastframe=0; - for (;;) { clock_gettime( CLOCK_REALTIME, &now ); //gettimeofday(&now, 0); - usec_since_lastframe = (now.tv_nsec / 1000) - (settings->lastframe_completion.tv_nsec / 1000); + usec_since_lastframe = (now.tv_nsec - settings->lastframe_completion.tv_nsec)/1000; - - // usec_since_lastframe = - // now.tv_usec - settings->lastframe_completion.tv_usec; - //usec_since_lastframe = vj_get_relative_time(); - - while (usec_since_lastframe < 0) + if (usec_since_lastframe < 0) usec_since_lastframe += 1000000; +// usec_since_lastframe += 1000000000; if (now.tv_sec > settings->lastframe_completion.tv_sec + 1) usec_since_lastframe = 1000000; - if (settings->first_frame || (frame_periods * settings->usec_per_frame - usec_since_lastframe) < (1000000 / HZ)) - break; - - /* Assume some other process will get a time-slice before - * we do... and hence the worst-case delay of 1/HZ after - * sleep timer expiry will apply. Reasonable since X will - * probably do something... - */ - nsecsleep.tv_nsec = (frame_periods * settings->usec_per_frame - usec_since_lastframe - 1000000 / HZ) * 1000; + if (settings->first_frame || (frame_periods * settings->usec_per_frame - usec_since_lastframe) < (1000000 / HZ)) { + + break; + } + + nsecsleep.tv_nsec = (settings->usec_per_frame - usec_since_lastframe - 1000000 / HZ) * 1000; + // nsecsleep.tv_nsec = (frame_periods * settings->usec_per_frame - usec_since_lastframe - 1000000 / HZ) * 1000; nsecsleep.tv_sec = 0; nanosleep(&nsecsleep, NULL); } @@ -1286,8 +1280,17 @@ static void veejay_mjpeg_software_frame_sync(veejay_t * info, settings->first_frame = 0; /* We are done with writing the picture - Now update all surrounding info */ - + struct timespec lasttime; + memcpy( &lasttime, &(settings->lastframe_completion), sizeof(struct timespec)); clock_gettime( CLOCK_REALTIME, &(settings->lastframe_completion) ); +/* + if( skip) { + long d1 = (settings->lastframe_completion.tv_sec * 1000000000) + settings->lastframe_completion.tv_nsec; + long d2 = (lasttime.tv_sec * 1000000000) + lasttime.tv_nsec; + + double diff = ( ( double) d1-d2)/1000000000.0; + }*/ + // gettimeofday(&(settings->lastframe_completion), 0); settings->syncinfo[settings->currently_processed_frame].timestamp = settings->lastframe_completion; } @@ -2635,8 +2638,13 @@ static void veejay_playback_cycle(veejay_t * info) stats.nsync++; clock_gettime( CLOCK_REALTIME, &time_now); - stats.tdiff = ( time_now.tv_sec - bs.timestamp.tv_sec ) + - ( ( time_now.tv_nsec - bs.timestamp.tv_nsec / 1000 ) * 1.e-6); + long d1 = (time_now.tv_sec * 1000000000) + time_now.tv_nsec; + long n1 = (bs.timestamp.tv_sec * 1000000000) + bs.timestamp.tv_nsec; + + double dn = ( (double) (d1 - n1) )/10000000.0; // * 1.e7; + + stats.tdiff = dn; // ( time_now.tv_sec - bs.timestamp.tv_sec ) + + // ( ( time_now.tv_nsec - bs.timestamp.tv_nsec / 1000 ) * 1.e-6); } while (stats.tdiff > settings->spvf && (stats.nsync - first_free) < (QUEUE_LEN-1)); @@ -2653,25 +2661,33 @@ static void veejay_playback_cycle(veejay_t * info) long int sec=0; long int usec=0; long num_audio_bytes_written = vj_jack_get_status( &sec,&usec); - long as = (el->audio_rate / el->video_fps) * el->audio_bps; - long musec = time_now.tv_nsec / 1000; - long msec = time_now.tv_sec; audio_tmstmp.tv_sec = sec; - audio_tmstmp.tv_nsec = (1000 * usec); + audio_tmstmp.tv_nsec = usec; //(1000 * usec); if( audio_tmstmp.tv_sec ) { //@ measure against bytes written to jack tdiff1 = settings->spvf * (stats.nsync - nvcorr) - settings->spas * num_audio_bytes_written; - - //tdiff2 = (bs.timestamp.tv_sec - audio_tmstmp.tv_sec) + (bs.timestamp.tv_usec - audio_tmstmp.tv_usec) * 1.e-6; - tdiff2 = (bs.timestamp.tv_sec - audio_tmstmp.tv_sec ) + ( (bs.timestamp.tv_nsec - audio_tmstmp.tv_nsec )/1000) * 1.e-6; + //1000000000 + long d1 = (bs.timestamp.tv_sec * 1000000000) + bs.timestamp.tv_nsec; + long n1 = (audio_tmstmp.tv_sec * 1000000000) + audio_tmstmp.tv_nsec; + tdiff2 = ( (double) (d1 - n1) )/ 1000000000.0; // * 1.e7; + //10000000 last_tdiff = tdiff1; - + double tt = tdiff1 - tdiff2; + + if( tt > settings->spvf && tt <= (settings->spvf *1.01) ) { + tdiff2 += 0.01; + } + + + //@ tt > spvf + // tdiff2 = (bs.timestamp.tv_sec - audio_tmstmp.tv_sec ) + ( (bs.timestamp.tv_nsec - audio_tmstmp.tv_nsec )/1000) * 1.e-6; + } } #endif @@ -2689,16 +2705,15 @@ static void veejay_playback_cycle(veejay_t * info) if (info->sync_correction) { if (stats.tdiff > settings->spvf) { skipa = 1; - //skipv = 1; + // skipv = 1; if (info->sync_ins_frames && current_speed != 0) { skipi = 1; } - nvcorr++; stats.num_corrs_a++; stats.tdiff -= settings->spvf; - stats.stats_changed = 1; - } + stats.stats_changed = 1; + } if (stats.tdiff < -settings->spvf) { /* Video is behind audio */ skipv = 1; @@ -2750,8 +2765,9 @@ static void veejay_playback_cycle(veejay_t * info) #endif if( info->real_fps > (1000* settings->spvf ) && info->audio ) { veejay_msg(VEEJAY_MSG_WARNING, "Rendering video frame takes too long! (measured %ld ms).", info->real_fps); - } - + continue; + } + if(!info->audio && skipv ) continue; veejay_mjpeg_queue_buf(info,frame, 1 );