diff options
| author | phintuka <phintuka> | 2008-12-03 22:50:04 +0000 |
|---|---|---|
| committer | phintuka <phintuka> | 2008-12-03 22:50:04 +0000 |
| commit | c57f0ea73db9b524e7f2621f8028008a3a9d038f (patch) | |
| tree | b059eec84d49b52eb95c4b3b0347373c33e3e413 | |
| parent | a9313a3c3a0a44d65939aa835837a3bbad267e2d (diff) | |
| download | xineliboutput-c57f0ea73db9b524e7f2621f8028008a3a9d038f.tar.gz xineliboutput-c57f0ea73db9b524e7f2621f8028008a3a9d038f.tar.bz2 | |
Moved SCR code from xine_input_vdr.c to own module
| -rw-r--r-- | xine/adjustable_scr.c | 309 | ||||
| -rw-r--r-- | xine/adjustable_scr.h | 37 |
2 files changed, 346 insertions, 0 deletions
diff --git a/xine/adjustable_scr.c b/xine/adjustable_scr.c new file mode 100644 index 00000000..cb1d2758 --- /dev/null +++ b/xine/adjustable_scr.c @@ -0,0 +1,309 @@ +/* + * adjustable_scr.c: + * + * See the main source file 'xineliboutput.c' for copyright information and + * how to reach the author. + * + * $Id: adjustable_scr.c,v 1.1 2008-12-03 22:50:04 phintuka Exp $ + * + */ + + +#include <xine/xine_internal.h> +#include <xine/xineutils.h> +#include <xine/metronom.h> + +#include "adjustable_scr.h" + +/* + * SCR code is mostly copied from xine-lib (src/input/input_pvr.c) + * + * + * Copyright (C) 2000-2005 the xine project + * March 2003 - Miguel Freitas + * This plugin was sponsored by 1Control + * + * 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 + * + */ + +typedef struct scr_impl_s scr_impl_t; + +struct scr_impl_s { + union { + scr_plugin_t scr; + adjustable_scr_t ascr; + }; + + xine_t *xine; + + struct timeval cur_time; + int64_t cur_pts; + int xine_speed; + int scr_speed_base; + double speed_factor; + double speed_tuning; + + pthread_mutex_t lock; + + struct timeval last_time; +}; + +/* Only call set_pivot when already mutex locked ! */ +static void set_pivot (scr_impl_t *this) +{ + struct timeval tv; + int64_t pts; + 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->cur_time.tv_sec=tv.tv_sec; + this->cur_time.tv_usec=tv.tv_usec; + this->cur_pts=pts; + + this->last_time.tv_sec = tv.tv_sec; + this->last_time.tv_usec = tv.tv_usec; + + return ; +} + +/* + * xine interface (scr_plugin_t) + */ + +static int scr_get_priority (scr_plugin_t *scr) +{ + return 50; /* high priority */ +} + +static int scr_set_fine_speed (scr_plugin_t *scr, int speed) +{ + scr_impl_t *this = (scr_impl_t*) scr; + + pthread_mutex_lock (&this->lock); + + set_pivot( this ); + this->xine_speed = speed; + this->speed_factor = (double) speed * (double)this->scr_speed_base /*90000.0*/ / + (1.0*XINE_FINE_SPEED_NORMAL) * + this->speed_tuning; + + pthread_mutex_unlock (&this->lock); + + return speed; +} + +static void scr_adjust (scr_plugin_t *scr, int64_t vpts) +{ + scr_impl_t *this = (scr_impl_t*) scr; + struct timeval tv; + + pthread_mutex_lock (&this->lock); + + xine_monotonic_clock(&tv,NULL); + this->cur_time.tv_sec=tv.tv_sec; + this->cur_time.tv_usec=tv.tv_usec; + this->cur_pts = vpts; + + this->last_time.tv_sec = tv.tv_sec; + this->last_time.tv_usec = tv.tv_usec; + + pthread_mutex_unlock (&this->lock); +} + +static void scr_start (scr_plugin_t *scr, int64_t start_vpts) +{ + scr_impl_t *this = (scr_impl_t*) scr; + + pthread_mutex_lock (&this->lock); + + xine_monotonic_clock(&this->cur_time, NULL); + this->cur_pts = start_vpts; + + this->last_time.tv_sec = this->cur_time.tv_sec; + this->last_time.tv_usec = this->cur_time.tv_usec; + + pthread_mutex_unlock (&this->lock); + + scr_set_fine_speed (&this->scr, XINE_FINE_SPEED_NORMAL); +} + +static int64_t scr_get_current (scr_plugin_t *scr) +{ + scr_impl_t *this = (scr_impl_t*) scr; + + struct timeval tv; + int64_t pts; + 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; + + this->last_time.tv_sec = tv.tv_sec; + this->last_time.tv_usec = tv.tv_usec; + + pthread_mutex_unlock (&this->lock); + + return pts; +} + +static void scr_exit (scr_plugin_t *scr) +{ + scr_impl_t *this = (scr_impl_t*) scr; + + pthread_mutex_destroy (&this->lock); + free(this); +} + +/* + * adjusteble_scr_t + */ + +/* + * speed_tuning() + * + * - fine-tune SCR speed. Actual speed is base_speed * factor. + */ +static void adjustable_scr_speed_tuning (adjustable_scr_t *scr, double factor) +{ + scr_impl_t *this = (scr_impl_t*) scr; + + pthread_mutex_lock (&this->lock); + + set_pivot( this ); + this->speed_tuning = factor; + this->speed_factor = (double) this->xine_speed * (double)this->scr_speed_base /*90000.0*/ / + (1.0*XINE_FINE_SPEED_NORMAL) * + this->speed_tuning; + + pthread_mutex_unlock (&this->lock); +} + +/* + * speed_base() + * + * - set base speed of SCR (default is 90kHz) + */ +static void adjustable_scr_speed_base (adjustable_scr_t *scr, int hz) +{ + scr_impl_t *this = (scr_impl_t*) scr; + + pthread_mutex_lock (&this->lock); + + set_pivot( this ); + this->scr_speed_base = hz; + this->speed_factor = (double) this->xine_speed * (double)this->scr_speed_base /*90000.0*/ / + (1.0*XINE_FINE_SPEED_NORMAL) * + this->speed_tuning; + + pthread_mutex_unlock (&this->lock); +} + +/* + * jump() + * + * - Move SCR 'pts' ticks forward + */ +static void adjustable_scr_jump (adjustable_scr_t *scr, int pts) +{ + scr_impl_t *this = (scr_impl_t*) scr; + + pthread_mutex_lock (&this->lock); + + set_pivot( this ); + this->cur_pts += pts; + + pthread_mutex_unlock (&this->lock); +} + +/* + * dispose() + * + * - unregister, stop and free resources + */ +static void adjustable_scr_dispose(adjustable_scr_t *scr) +{ + scr_impl_t *this = (scr_impl_t*)scr; + + /* unregister */ + if (this->xine) + this->xine->clock->unregister_scr(this->xine->clock, &this->scr); + + /* exit and dispose */ + this->scr.exit(&this->scr); +} + +/* + * adjusteble_scr_start() + * + */ +adjustable_scr_t* adjustable_scr_start (xine_t *xine) +{ + scr_impl_t *this; + + this = calloc(1, sizeof(scr_impl_t)); + + /* xine scr plugin interface */ + this->scr.interface_version = 3; + this->scr.set_fine_speed = scr_set_fine_speed; + this->scr.get_priority = scr_get_priority; + this->scr.adjust = scr_adjust; + this->scr.start = scr_start; + this->scr.get_current = scr_get_current; + this->scr.exit = scr_exit; + + /* tuning / management interface */ + this->ascr.set_speed_tuning = adjustable_scr_speed_tuning; + this->ascr.set_speed_base = adjustable_scr_speed_base; + this->ascr.jump = adjustable_scr_jump; + this->ascr.dispose = adjustable_scr_dispose; + + /* initialize */ + + pthread_mutex_init (&this->lock, NULL); + + this->xine = xine; + this->scr_speed_base = 90000; + + adjustable_scr_speed_tuning(&this->ascr, 1.0 ); + scr_set_fine_speed (&this->scr, XINE_SPEED_PAUSE); + + /* start and register */ + + uint64_t time = xine->clock->get_current_time(xine->clock); + this->scr.start(&this->scr, time); + + if (xine->clock->register_scr(xine->clock, &this->scr)) { + scr_exit(&this->scr); + return NULL; + } + + return &this->ascr; +} diff --git a/xine/adjustable_scr.h b/xine/adjustable_scr.h new file mode 100644 index 00000000..61707684 --- /dev/null +++ b/xine/adjustable_scr.h @@ -0,0 +1,37 @@ +/* + * adjustable_scr.h: + * + * See the main source file 'xineliboutput.c' for copyright information and + * how to reach the author. + * + * $Id: adjustable_scr.h,v 1.1 2008-12-03 22:50:04 phintuka Exp $ + * + */ + +#ifndef XINELIBOUTPUT_ADJUSTABLE_SCR_H_ +#define XINELIBOUTPUT_ADJUSTABLE_SCR_H_ + +/******************************* SCR ************************************* + * + * unix System Clock Reference + fine tuning + * + * fine tuning is used to change playback speed in live mode + * to keep in sync with mpeg source + *************************************************************************/ + +typedef struct adjustable_scr_s adjustable_scr_t; + +struct adjustable_scr_s { + scr_plugin_t scr; + + void (*set_speed_tuning)(adjustable_scr_t *this, double factor); + void (*set_speed_base) (adjustable_scr_t *this, int hz); + void (*jump) (adjustable_scr_t *this, int pts); + + void (*dispose) (adjustable_scr_t *this); +}; + +adjustable_scr_t *adjustable_scr_start (xine_t *xine); + + +#endif /* XINELIBOUTPUT_ADJUSTABLE_SCR_H_ */ |
