diff options
Diffstat (limited to 'src/xine-engine/metronom.c')
-rw-r--r-- | src/xine-engine/metronom.c | 186 |
1 files changed, 93 insertions, 93 deletions
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index eb9abb84a..a4058bce8 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.c @@ -1,18 +1,18 @@ -/* +/* * Copyright (C) 2000-2003 the xine project - * + * * This file is part of xine, a free video player. - * + * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA @@ -46,7 +46,7 @@ #define MAX_AUDIO_DELTA 1600 #define AUDIO_SAMPLE_NUM 32768 -#define WRAP_THRESHOLD 120000 +#define WRAP_THRESHOLD 120000 #define MAX_NUM_WRAP_DIFF 10 #define MAX_SCR_PROVIDERS 10 #define VIDEO_DRIFT_TOLERANCE 45000 @@ -63,7 +63,7 @@ /* * **************************************** - * primary SCR plugin: + * primary SCR plugin: * unix System Clock Reference * **************************************** */ @@ -88,19 +88,19 @@ static void unixscr_set_pivot (unixscr_t *this) { struct timeval tv; int64_t pts; - double pts_calc; + double pts_calc; xine_monotonic_clock(&tv, NULL); pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; -/* This next part introduces a one off inaccuracy - * to the scr due to rounding tv to pts. +/* This next part introduces a one off inaccuracy + * to the scr due to rounding tv to pts. */ this->cur_time.tv_sec=tv.tv_sec; this->cur_time.tv_usec=tv.tv_usec; - this->cur_pts=pts; + this->cur_pts=pts; return ; } @@ -141,7 +141,7 @@ static void unixscr_start (scr_plugin_t *scr, int64_t start_vpts) { this->cur_pts = start_vpts; pthread_mutex_unlock (&this->lock); - + unixscr_set_speed (&this->scr, XINE_FINE_SPEED_NORMAL); } @@ -150,16 +150,16 @@ static int64_t unixscr_get_current (scr_plugin_t *scr) { struct timeval tv; int64_t pts; - double pts_calc; + double pts_calc; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&tv, NULL); - + pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; - + pthread_mutex_unlock (&this->lock); return pts; @@ -176,7 +176,7 @@ static scr_plugin_t *XINE_MALLOC unixscr_init () { unixscr_t *this; this = calloc(1, sizeof(unixscr_t)); - + this->scr.interface_version = 3; this->scr.get_priority = unixscr_get_priority; this->scr.set_fine_speed = unixscr_set_speed; @@ -184,15 +184,15 @@ static scr_plugin_t *XINE_MALLOC unixscr_init () { this->scr.start = unixscr_start; this->scr.get_current = unixscr_get_current; this->scr.exit = unixscr_exit; - + pthread_mutex_init (&this->lock, NULL); - + unixscr_set_speed (&this->scr, XINE_SPEED_PAUSE); lprintf("xine-scr_init complete\n"); return &this->scr; } - + /* * **************************************** @@ -208,7 +208,7 @@ static void metronom_start_clock (metronom_clock_t *this, int64_t pts) { for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++) if (*scr) (*scr)->start(*scr, pts); - + this->speed = XINE_FINE_SPEED_NORMAL; } @@ -243,7 +243,7 @@ static int metronom_set_speed (metronom_clock_t *this, int speed) { int true_speed; true_speed = this->scr_master->set_fine_speed (this->scr_master, speed); - + this->speed = true_speed; for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++) @@ -267,33 +267,33 @@ static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts) { int64_t vpts; pthread_mutex_lock (&this->lock); - + if (this->master) { metronom_t *master = this->master; - + pthread_mutex_lock(&this->master->lock); pthread_mutex_unlock(&this->lock); - + this->vpts_offset = this->master->vpts_offset; this->spu_offset = this->master->spu_offset; - + /* no recursion, please */ this->master = NULL; vpts = master->got_spu_packet(this, pts); this->master = master; - + pthread_mutex_unlock(&this->master->lock); return vpts; } vpts = pts + this->vpts_offset + this->spu_offset; - + /* no vpts going backwards please */ if( vpts < this->spu_vpts ) vpts = this->spu_vpts; - + this->spu_vpts = vpts; - + pthread_mutex_unlock (&this->lock); return vpts; } @@ -353,7 +353,7 @@ static void metronom_handle_discontinuity (metronom_t *this, int type, this->vpts_offset = this->video_vpts - disc_off; break; } - + this->last_video_pts = 0; this->last_audio_pts = 0; } @@ -368,18 +368,18 @@ static void metronom_handle_video_discontinuity (metronom_t *this, int type, pthread_mutex_unlock(&this->lock); return; } - + this->video_discontinuity_count++; pthread_cond_signal (&this->video_discontinuity_reached); - + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video discontinuity #%d, type is %d, disc_off %" PRId64 "\n", this->video_discontinuity_count, type, disc_off); - + if (this->have_audio) { while (this->audio_discontinuity_count < this->video_discontinuity_count) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for audio discontinuity #%d\n", + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for audio discontinuity #%d\n", this->video_discontinuity_count); pthread_cond_wait (&this->audio_discontinuity_reached, &this->lock); @@ -399,15 +399,15 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { int64_t vpts; int64_t pts = img->pts; int64_t diff; - + pthread_mutex_lock (&this->lock); if (this->master) { metronom_t *master = this->master; - + pthread_mutex_lock(&this->master->lock); pthread_mutex_unlock(&this->lock); - + if (!this->discontinuity_handled_count) { /* we are not initialized yet */ if (this->master->video_vpts > this->master->audio_vpts) @@ -420,15 +420,15 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { this->force_video_jump = 1; this->discontinuity_handled_count++; } - + this->vpts_offset = this->master->vpts_offset; this->av_offset = this->master->av_offset; - + /* no recursion, please */ this->master = NULL; master->got_video_frame(this, img); this->master = master; - + pthread_mutex_unlock(&this->master->lock); return; } @@ -459,23 +459,23 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { } this->img_cpt = 0; this->last_video_pts = pts; - - + + /* * compare predicted (this->video_vpts) and given (pts+vpts_offset) * pts values - hopefully they will be the same * if not, for small diffs try to interpolate * for big diffs: jump */ - + vpts = pts + this->vpts_offset; if (this->video_mode == VIDEO_PREDICTION_MODE) { - + diff = this->video_vpts - vpts; lprintf("video diff is %" PRId64 " (predicted %" PRId64 ", given %" PRId64 ")\n", diff, this->video_vpts, vpts); - + if ((abs (diff) > VIDEO_DRIFT_TOLERANCE) || (this->force_video_jump)) { this->force_video_jump = 0; @@ -489,7 +489,7 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { this->video_drift = diff; this->video_drift_step = diff / 30; /* this will fix video drift with a constant compensation each - frame for about 1 second of video. */ + frame for about 1 second of video. */ if (diff) lprintf("video drift, drift is %" PRId64 "\n", this->video_drift); } @@ -503,7 +503,7 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { if (this->video_mode == VIDEO_PREDICTION_MODE) { lprintf("video vpts for %10"PRId64" : %10"PRId64" (duration:%d drift:%" PRId64 " step:%" PRId64 ")\n", - pts, this->video_vpts, img->duration, this->video_drift, this->video_drift_step ); + pts, this->video_vpts, img->duration, this->video_drift, this->video_drift_step ); if (this->video_drift * this->video_drift_step > 0) { img->duration -= this->video_drift_step; @@ -516,7 +516,7 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { * this->video_vpts is used as the next frame vpts if next frame pts=0 */ this->video_vpts += this->img_duration; - + pthread_mutex_unlock (&this->lock); } @@ -524,7 +524,7 @@ static void metronom_handle_audio_discontinuity (metronom_t *this, int type, int64_t disc_off) { pthread_mutex_lock (&this->lock); - + if (this->master) { /* slaves are currently not allowed to set discontinuities */ pthread_mutex_unlock(&this->lock); @@ -533,19 +533,19 @@ static void metronom_handle_audio_discontinuity (metronom_t *this, int type, this->audio_discontinuity_count++; pthread_cond_signal (&this->audio_discontinuity_reached); - + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio discontinuity #%d, type is %d, disc_off %" PRId64 "\n", this->audio_discontinuity_count, type, disc_off); if (this->have_video) { - + /* next_vpts_offset, in_discontinuity is handled in expect_video_discontinuity */ while ( this->audio_discontinuity_count > this->discontinuity_handled_count ) { - - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for in_discontinuity update #%d\n", + + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "waiting for in_discontinuity update #%d\n", this->audio_discontinuity_count); - + pthread_cond_wait (&this->video_discontinuity_reached, &this->lock); } } else { @@ -554,11 +554,11 @@ static void metronom_handle_audio_discontinuity (metronom_t *this, int type, this->audio_samples = 0; this->audio_drift_step = 0; - + pthread_mutex_unlock (&this->lock); } -static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, +static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, int nsamples) { int64_t vpts; @@ -568,34 +568,34 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, lprintf("AUDIO pts from last= %" PRId64 "\n", pts-this->last_audio_pts); pthread_mutex_lock (&this->lock); - + if (this->master) { metronom_t *master = this->master; - + pthread_mutex_lock(&this->master->lock); pthread_mutex_unlock(&this->lock); - + if (!this->discontinuity_handled_count) { /* we are not initialized yet */ if (this->master->video_vpts > this->master->audio_vpts) this->video_vpts = this->audio_vpts = this->master->video_vpts; else this->video_vpts = this->audio_vpts = this->master->audio_vpts; - this->audio_vpts_rmndr = 0; + this->audio_vpts_rmndr = 0; /* when being attached to the first master, do not drift into * his vpts values but adopt at once */ this->force_audio_jump = 1; this->force_video_jump = 1; this->discontinuity_handled_count++; } - + this->vpts_offset = this->master->vpts_offset; - + /* no recursion, please */ this->master = NULL; vpts = master->got_audio_samples(this, pts, nsamples); this->master = master; - + pthread_mutex_unlock(&this->master->lock); return vpts; } @@ -609,7 +609,7 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, if((abs(diff) > AUDIO_DRIFT_TOLERANCE) || (this->force_audio_jump)) { this->force_audio_jump = 0; this->audio_vpts = vpts; - this->audio_vpts_rmndr = 0; + this->audio_vpts_rmndr = 0; this->audio_drift_step = 0; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio jump, diff=%" PRId64 "\n", diff); } else { @@ -619,15 +619,15 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, diff *= AUDIO_SAMPLE_NUM; diff /= this->audio_samples * 4; - + /* drift_step is not allowed to change rate by more than 25% */ if( diff > this->pts_per_smpls/4 ) - diff = this->pts_per_smpls/4; + diff = this->pts_per_smpls/4; if( diff < -this->pts_per_smpls/4 ) diff = -this->pts_per_smpls/4; - + this->audio_drift_step = diff; - + lprintf("audio_drift = %" PRId64 ", pts_per_smpls = %" PRId64 "\n", diff, this->pts_per_smpls); } } @@ -635,12 +635,12 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, } vpts = this->audio_vpts; - /* drift here is caused by streams where nominal sample rate differs from + /* drift here is caused by streams where nominal sample rate differs from * the rate of which pts increments. fixing the audio_vpts won't do us any * good because sound card won't play it faster or slower just because * we want. however, adding the error to the vpts_offset will force video * to change it's frame rate to keep in sync with us. - * + * * Since we are using integer division below, it can happen that we lose * precision for the calculated duration in vpts for each audio buffer * (< 1 PTS, e.g. 0.25 PTS during playback of most DVDs with LPCM audio). @@ -658,7 +658,7 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, } this->audio_samples += nsamples; this->vpts_offset += nsamples * this->audio_drift_step / AUDIO_SAMPLE_NUM; - + lprintf("audio vpts for %10"PRId64" : %10"PRId64"\n", pts, vpts); pthread_mutex_unlock (&this->lock); @@ -669,7 +669,7 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, static void metronom_set_option (metronom_t *this, int option, int64_t value) { pthread_mutex_lock (&this->lock); - + if (this->master) { /* pass the option on to the master */ this->master->set_option(this->master, option, value); @@ -725,7 +725,7 @@ static void metronom_clock_set_option (metronom_clock_t *this, } static int64_t metronom_get_option (metronom_t *this, int option) { - + if (this->master) return this->master->get_option(this->master, option); @@ -756,7 +756,7 @@ static int64_t metronom_clock_get_option (metronom_clock_t *this, int option) { static void metronom_set_master(metronom_t *this, metronom_t *master) { metronom_t *old_master = this->master; - + pthread_mutex_lock(&this->lock); /* someone might currently be copying values from the old master, * so we need his lock too */ @@ -774,7 +774,7 @@ static scr_plugin_t* get_master_scr(metronom_clock_t *this) { /* find the SCR provider with the highest priority */ for (i=0; i<MAX_SCR_PROVIDERS; i++) if (this->scr_list[i]) { scr_plugin_t *scr = this->scr_list[i]; - + if (maxprio < scr->get_priority(scr)) { select = i; maxprio = scr->get_priority(scr); @@ -791,7 +791,7 @@ static int metronom_register_scr (metronom_clock_t *this, scr_plugin_t *scr) { int i; if (scr->interface_version != 3) { - xprintf(this->xine, XINE_VERBOSITY_NONE, + xprintf(this->xine, XINE_VERBOSITY_NONE, "wrong interface version for scr provider!\n"); return -1; } @@ -813,19 +813,19 @@ static void metronom_unregister_scr (metronom_clock_t *this, scr_plugin_t *scr) /* never unregister scr_list[0]! */ for (i=1; i<MAX_SCR_PROVIDERS; i++) - if (this->scr_list[i] == scr) + if (this->scr_list[i] == scr) break; if (i >= MAX_SCR_PROVIDERS) return; /* Not found */ - + this->scr_list[i] = NULL; time = this->get_current_time(this); - + /* master could have been adjusted, others must follow now */ for (i=0; i<MAX_SCR_PROVIDERS; i++) if (this->scr_list[i]) this->scr_list[i]->adjust(this->scr_list[i], time); - + this->scr_master = get_master_scr(this); } @@ -835,13 +835,13 @@ static int metronom_sync_loop (metronom_clock_t *this) { struct timespec ts; scr_plugin_t** scr; int64_t pts; - + while (this->thread_running) { /* synchronise every 5 seconds */ pthread_mutex_lock (&this->lock); pts = this->scr_master->get_current(this->scr_master); - + for (scr = this->scr_list; scr < this->scr_list+MAX_SCR_PROVIDERS; scr++) if (*scr && *scr != this->scr_master) (*scr)->adjust(*scr, pts); @@ -869,7 +869,7 @@ static void metronom_clock_exit (metronom_clock_t *this) { scr_plugin_t** scr; this->thread_running = 0; - + pthread_mutex_lock (&this->lock); pthread_cond_signal (&this->cancel); pthread_mutex_unlock (&this->lock); @@ -904,7 +904,7 @@ metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) { this->xine = xine; this->master = NULL; - + pthread_mutex_init (&this->lock, NULL); this->prebuffer = PREBUFFER_PTS_OFFSET; @@ -913,7 +913,7 @@ metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) { this->vpts_offset = 0; /* initialize video stuff */ - + this->video_vpts = this->prebuffer; this->video_drift = 0; this->video_drift_step = 0; @@ -924,8 +924,8 @@ metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) { this->img_cpt = 0; this->last_video_pts = 0; this->last_audio_pts = 0; - - + + /* initialize audio stuff */ this->have_video = have_video; @@ -934,7 +934,7 @@ metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) { this->audio_vpts_rmndr = 0; this->audio_discontinuity_count = 0; pthread_cond_init (&this->audio_discontinuity_reached, NULL); - + return this; } @@ -944,7 +944,7 @@ metronom_clock_t *_x_metronom_clock_init(xine_t *xine) { metronom_clock_t *this = calloc(1, sizeof(metronom_clock_t)); int err; - + this->set_option = metronom_clock_set_option; this->get_option = metronom_clock_get_option; this->start_clock = metronom_start_clock; @@ -956,19 +956,19 @@ metronom_clock_t *_x_metronom_clock_init(xine_t *xine) this->register_scr = metronom_register_scr; this->unregister_scr = metronom_unregister_scr; this->exit = metronom_clock_exit; - + this->xine = xine; this->scr_adjustable = 1; this->scr_list = calloc(MAX_SCR_PROVIDERS, sizeof(void*)); this->register_scr(this, unixscr_init()); - + pthread_mutex_init (&this->lock, NULL); pthread_cond_init (&this->cancel, NULL); - + this->thread_running = 1; if ((err = pthread_create(&this->sync_thread, NULL, - (void*(*)(void*)) metronom_sync_loop, this)) != 0) + (void*(*)(void*)) metronom_sync_loop, this)) != 0) xprintf(this->xine, XINE_VERBOSITY_NONE, "cannot create sync thread (%s)\n", strerror(err)); |