diff options
| author | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-05-01 21:55:23 +0000 | 
|---|---|---|
| committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2001-05-01 21:55:23 +0000 | 
| commit | 25f65c0adcd22712fe4f0b9c730d436ee05eca01 (patch) | |
| tree | be2e3190d72d8f4b3cb672274f5620cc613b748f | |
| parent | 6fa85d5188519997e3b8f19386a82f370610d39d (diff) | |
| download | xine-lib-25f65c0adcd22712fe4f0b9c730d436ee05eca01.tar.gz xine-lib-25f65c0adcd22712fe4f0b9c730d436ee05eca01.tar.bz2 | |
thread lock and pts wrap detection for metronom
CVS patchset: 53
CVS date: 2001/05/01 21:55:23
| -rw-r--r-- | src/xine-engine/metronom.c | 95 | ||||
| -rw-r--r-- | src/xine-engine/metronom.h | 9 | 
2 files changed, 99 insertions, 5 deletions
| diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index 014df6cc4..6b16ad695 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.c @@ -17,7 +17,7 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA   * - * $Id: metronom.c,v 1.2 2001/04/19 09:46:57 f1rmb Exp $ + * $Id: metronom.c,v 1.3 2001/05/01 21:55:23 guenter Exp $   */  #ifdef HAVE_CONFIG_H @@ -41,6 +41,8 @@  static void metronom_reset (metronom_t *this) { +  pthread_mutex_lock (&this->lock); +    this->video_vpts                = 0;    this->audio_vpts                = 0; @@ -50,17 +52,27 @@ static void metronom_reset (metronom_t *this) {    this->last_video_pts            = 0;    this->num_video_vpts_guessed    = 1;    this->num_audio_samples_guessed = 1; +  this->last_audio_pts            = 0;    this->sync_pts                  = 0;    this->sync_vpts                 = 0; +  this->video_wrap_offset         = 0; +  this->audio_wrap_offset         = 0; +    this->av_offset                 = 0;    this->stopped                   = 1; + +  pthread_mutex_unlock (&this->lock);  }  static void metronom_set_video_rate (metronom_t *this, uint32_t pts_per_frame) { +  pthread_mutex_lock (&this->lock); +    this->pts_per_frame = pts_per_frame; + +  pthread_mutex_unlock (&this->lock);  }  static uint32_t metronom_get_video_rate (metronom_t *this) { @@ -68,8 +80,12 @@ static uint32_t metronom_get_video_rate (metronom_t *this) {  }  static void metronom_set_audio_rate (metronom_t *this, uint32_t pts_per_smpls) { +  pthread_mutex_lock (&this->lock); +    this->pts_per_smpls = pts_per_smpls; +  pthread_mutex_unlock (&this->lock); +    xprintf (METRONOM | VERBOSE, "metronom: %d pts per %d samples\n", pts_per_smpls, AUDIO_SAMPLE_NUM);  } @@ -84,9 +100,26 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {    uint32_t vpts; +  pthread_mutex_lock (&this->lock); +    if (pts) {      /* +     * did a wrap-around occur? +     */ +    if ( (pts+this->video_wrap_offset)<this->last_video_pts) { + +      this->video_wrap_offset = this->last_video_pts - pts  +	+ this->num_video_vpts_guessed *(this->pts_per_frame + this->video_pts_delta); + +      printf ("metronom: video pts wraparound detected, wrap_offset = %d\n", +	      this->video_wrap_offset); + +    } + +    pts += this->video_wrap_offset; + +    /*       * calc delta to compensate wrong framerates        */ @@ -147,6 +180,8 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {    xprintf (METRONOM | VERBOSE, "metronom: video vpts for %10d : %10d\n", pts, vpts); +  pthread_mutex_unlock (&this->lock); +    return vpts + this->av_offset;  } @@ -158,9 +193,27 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts, uint    xprintf (METRONOM | VERBOSE, "metronom: got %d audio samples (pts=%d)\n",  	   nsamples,pts); +  pthread_mutex_lock (&this->lock); +    if (pts) {      int32_t diff; +    /* +     * did a wrap-around occur? +     */ + +    if ((pts+this->audio_wrap_offset)<this->last_audio_pts) { + +      this->audio_wrap_offset = this->last_audio_pts - pts +	+ this->num_audio_samples_guessed *(this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM ; + +      printf ("metronom: audio pts wraparound detected, wrap_offset = %d\n", +	      this->audio_wrap_offset); + +    } + +    pts += this->audio_wrap_offset; +      diff = pts - this->sync_pts;      if (this->sync_vpts && (pts>this->sync_pts)) { @@ -193,6 +246,7 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts, uint      this->sync_pts = pts;      this->sync_vpts = this->audio_vpts;      this->num_audio_samples_guessed = 0; +    this->last_audio_pts = pts;    }    vpts = this->audio_vpts; @@ -201,11 +255,19 @@ static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts, uint    xprintf (METRONOM | VERBOSE, "metronom: audio vpts for %10d : %10d\n", pts, vpts); +  pthread_mutex_unlock (&this->lock); +    return vpts;  }  static void metronom_set_av_offset (metronom_t *this, int32_t pts) { + +  pthread_mutex_lock (&this->lock); +    this->av_offset = pts; + +  pthread_mutex_unlock (&this->lock); +    printf ("metronom: av_offset=%d pts\n", pts);  } @@ -223,9 +285,15 @@ static int32_t metronom_get_av_offset (metronom_t *this) {  static void metronom_start_clock (metronom_t *this, uint32_t pts) { + +  pthread_mutex_lock (&this->lock); +    gettimeofday(&this->start_time, NULL);    this->last_pts = this->start_pts = pts;    this->stopped  = 0; + +  pthread_mutex_unlock (&this->lock); +  } @@ -234,6 +302,8 @@ static uint32_t metronom_get_current_time (metronom_t *this) {    uint32_t pts;    struct timeval tv; +  pthread_mutex_lock (&this->lock); +    gettimeofday(&tv, NULL);    pts  = (tv.tv_sec  - this->start_time.tv_sec) * 90000;    pts += (tv.tv_usec - this->start_time.tv_usec) / 10 * 9 / 10; @@ -244,13 +314,23 @@ static uint32_t metronom_get_current_time (metronom_t *this) {      pts = this->last_pts;    } +  pthread_mutex_unlock (&this->lock); +    return pts;  }  static void metronom_stop_clock(metronom_t *this) { + +  uint32_t current_time = this->get_current_time(this); + +  pthread_mutex_lock (&this->lock); +    this->stopped = 1; -  this->last_pts = this->get_current_time(this); +  this->last_pts = current_time; + +  pthread_mutex_unlock (&this->lock); +  } @@ -262,13 +342,18 @@ static void metronom_resume_clock(metronom_t *this) {  static void metronom_adjust_clock(metronom_t *this, uint32_t desired_pts)  { -  int delta; +  int      delta; +  uint32_t current_time = this->get_current_time(this); + +  pthread_mutex_lock (&this->lock);    /* FIXME: this should be softer than a brute force warp... */    delta  = desired_pts; -  delta -= this->get_current_time(this); +  delta -= current_time;    this->start_pts += delta;    /* printf("adjusting start_pts to %d\n", this->start_pts);  */ + +  pthread_mutex_unlock (&this->lock);  }  metronom_t * metronom_init () { @@ -289,6 +374,8 @@ metronom_t * metronom_init () {    this->resume_clock      = metronom_resume_clock;    this->get_current_time  = metronom_get_current_time;    this->adjust_clock      = metronom_adjust_clock; + +  pthread_mutex_init (&this->lock, NULL);    this->reset (this); diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h index 2ac1354cd..e051fc0da 100644 --- a/src/xine-engine/metronom.h +++ b/src/xine-engine/metronom.h @@ -17,7 +17,7 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA   * - * $Id: metronom.h,v 1.2 2001/04/27 10:42:38 f1rmb Exp $ + * $Id: metronom.h,v 1.3 2001/05/01 21:55:23 guenter Exp $   *   * metronom: general pts => virtual calculation/assoc   *                    @@ -34,6 +34,7 @@  #include <inttypes.h>  #include <sys/time.h> +#include <pthread.h>  typedef struct metronom_s metronom_t ; @@ -158,12 +159,16 @@ struct metronom_s {    uint32_t        sync_pts;    uint32_t        sync_vpts; +  uint32_t        video_wrap_offset; +  uint32_t        audio_wrap_offset; +    /* video delta for wrong framerates */    uint32_t        last_video_pts;    uint32_t        last_video_vpts;    int             num_video_vpts_guessed;    int32_t         video_pts_delta; +  uint32_t        last_audio_pts;    int             num_audio_samples_guessed;    int32_t         av_offset; @@ -171,6 +176,8 @@ struct metronom_s {    struct timeval  start_time;    uint32_t        start_pts, last_pts;    int             stopped ; + +  pthread_mutex_t lock;  };  metronom_t *metronom_init (); | 
