diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-03-10 21:16:14 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-03-10 21:16:14 +0000 |
commit | 5c281d37ea0630f177a5d7088408741cc8e7be66 (patch) | |
tree | f4c55b58cc2be81c168d1d47955546cf274c9d93 | |
parent | a77fa76ce51ca69bffabe463bc865516e47325f0 (diff) | |
download | xine-lib-5c281d37ea0630f177a5d7088408741cc8e7be66.tar.gz xine-lib-5c281d37ea0630f177a5d7088408741cc8e7be66.tar.bz2 |
- mpeg2 frame duration fixes
- metronom fixes, drift calculation
CVS patchset: 1548
CVS date: 2002/03/10 21:16:14
-rw-r--r-- | src/dxr3/dxr3_decoder.c | 4 | ||||
-rw-r--r-- | src/libmpeg2/decode.c | 33 | ||||
-rw-r--r-- | src/libmpeg2/mpeg2.h | 1 | ||||
-rw-r--r-- | src/xine-engine/metronom.c | 41 | ||||
-rw-r--r-- | src/xine-engine/metronom.h | 5 | ||||
-rw-r--r-- | src/xine-engine/video_decoder.c | 6 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 3 |
7 files changed, 43 insertions, 50 deletions
diff --git a/src/dxr3/dxr3_decoder.c b/src/dxr3/dxr3_decoder.c index 8a1c08d58..651f6c8eb 100644 --- a/src/dxr3/dxr3_decoder.c +++ b/src/dxr3/dxr3_decoder.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: dxr3_decoder.c,v 1.63 2002/03/08 00:24:40 jcdutton Exp $ + * $Id: dxr3_decoder.c,v 1.64 2002/03/10 21:16:16 miguelfreitas Exp $ * * dxr3 video and spu decoder plugin. Accepts the video and spu data * from XINE and sends it directly to the corresponding dxr3 devices. @@ -439,7 +439,7 @@ static int get_duration(int framecode, int repeat_first_field) /*duration=3600;*/ break; case 4: /* 29.970 */ - duration=repeat_first_field ? 3754 : 3003; + duration=repeat_first_field ? 4505 : 3003; /*duration=3003;*/ break; case 5: /* 30.000 */ diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c index d3639e882..68db8b3d5 100644 --- a/src/libmpeg2/decode.c +++ b/src/libmpeg2/decode.c @@ -88,49 +88,48 @@ static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) switch (mpeg2dec->picture->frame_rate_code) { case 1: /* 23.976 fps */ frame->duration = 3913; - frame->pts_corrector = 0; break; case 2: /* 24 fps */ frame->duration = 3750; - frame->pts_corrector = 0; break; case 3: /* 25 fps */ - frame->duration = mpeg2dec->picture->repeat_first_field ? 5400 : 3600; - frame->pts_corrector = 0; + frame->duration = 3600; break; case 4: /* 29.97 fps */ - if ((mpeg2dec->picture->repeat_first_field) || (mpeg2dec->last_repeat_first_field)) { - frame->duration = 3754; - frame->pts_corrector = frame->repeat_first_field ? 375 : -375; - } else { - frame->duration = 3003; - frame->pts_corrector = 0; - } + frame->duration = 3003; break; case 5: /* 30 fps */ frame->duration = 3000; - frame->pts_corrector = 0; break; case 6: /* 50 fps */ frame->duration = 1800; - frame->pts_corrector = 0; break; case 7: /* 59.94 fps */ frame->duration = 1525; - frame->pts_corrector = 0; break; case 8: /* 60 fps */ frame->duration = 1509; - frame->pts_corrector = 0; break; default: /* printf ("invalid/unknown frame rate code : %d \n", frame->frame_rate_code); */ frame->duration = 3000; - frame->pts_corrector = 0; } + + if( mpeg2dec->picture->repeat_first_field ) { + if( !mpeg2dec->picture->progressive_sequence && + mpeg2dec->picture->progressive_frame ) { + /* decoder should output 3 fields, so adjust duration to + count on this extra field time */ + frame->duration += frame->duration/2; + } else if( mpeg2dec->picture->progressive_sequence ) { + /* for progressive sequences the output should repeat the + frame 1 or 2 times depending on top_field_first flag. */ + frame->duration *= (mpeg2dec->picture->top_field_first)?3:2; + } + } + /* printf("mpeg2dec: rff=%u\n",frame->repeat_first_field); */ - mpeg2dec->last_repeat_first_field = frame->repeat_first_field; } static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h index cd4f9610a..c2ee5f6ec 100644 --- a/src/libmpeg2/mpeg2.h +++ b/src/libmpeg2/mpeg2.h @@ -44,7 +44,6 @@ typedef struct mpeg2dec_s { uint8_t code; uint32_t pts, scr; - uint32_t last_repeat_first_field; xine_t *xine; } mpeg2dec_t ; diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index a51544559..b578ea5cf 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.63 2002/03/08 19:17:05 guenter Exp $ + * $Id: metronom.c,v 1.64 2002/03/10 21:16:15 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -289,10 +289,12 @@ static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts, return vpts; } -static void metronom_expect_video_discontinuity (metronom_t *this) { +static void metronom_expect_video_discontinuity (metronom_t *this, int starting) { pthread_mutex_lock (&this->lock); + this->video_starting = starting; + this->video_discontinuity = 10; this->video_discontinuity_count++; @@ -330,7 +332,7 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { pthread_mutex_lock (&this->lock); /* check for pts discontinuities against the predicted pts value */ - if (pts) { + if (pts && this->last_video_pts) { int64_t diff, predicted_pts; @@ -369,7 +371,9 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { * check if there was any pending SCR discontinuity (video_discontinuity * is set from the decoder loop) together with pts discont. */ - if (this->video_discontinuity && pts_discontinuity) { + if ( this->video_discontinuity && + (pts_discontinuity || this->video_starting) ) { + this->video_starting = 0; this->video_discontinuity = 0; this->wrap_diff_counter = 0; @@ -429,30 +433,22 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { this->video_vpts = vpts; this->video_drift = 0; - /* following line is useless (wrap_offset=wrap_offset) */ - /* this->video_wrap_offset = vpts - pts; */ #ifdef LOG - printf ("metronom: video jump, wrap offset is now %lld\n", - this->video_wrap_offset); + printf ("metronom: video jump, ignoring predicted vpts\n"); #endif } else if (diff) { - this->video_drift = diff; - - /* this->video_vpts -= diff / 8;*/ /* FIXME: better heuristics ? */ - /* make wrap_offset consistent with the drift correction */ - /* this->video_wrap_offset = this->video_vpts - pts; */ - /* don't touch wrap here, wrap offsets are used for wrap compensation */ + this->video_drift = diff / 30; #ifdef LOG - printf ("metronom: video drift, wrap offset is now %lld\n", - this->video_wrap_offset); + printf ("metronom: video drift, compensation will be %lld pts/frame\n", + this->video_drift); #endif } } - + this->last_video_pts = pts; } else this->last_video_pts = this->video_vpts - this->video_wrap_offset; @@ -460,13 +456,12 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { img->vpts = this->video_vpts + this->av_offset; #ifdef LOG - printf ("metronom: video vpts for %10lld : %10lld\n", - pts, this->video_vpts); + printf ("metronom: video vpts for %10lld : %10lld (duration:%lld)\n", + pts, this->video_vpts, duration); #endif - - this->video_vpts += duration - this->video_drift/30; - - this->video_drift -= this->video_drift/30; + + this->video_vpts += duration - this->video_drift; + img->duration -= this->video_drift; pthread_mutex_unlock (&this->lock); } diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h index 617206ca1..dd0cd703d 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.19 2002/03/08 19:17:06 guenter Exp $ + * $Id: metronom.h,v 1.20 2002/03/10 21:16:15 miguelfreitas Exp $ * * metronom: general pts => virtual calculation/assoc * @@ -137,7 +137,7 @@ struct metronom_s { * */ void (*expect_audio_discontinuity) (metronom_t *this); - void (*expect_video_discontinuity) (metronom_t *this); + void (*expect_video_discontinuity) (metronom_t *this, int starting); /* * manually correct audio <-> video sync @@ -228,6 +228,7 @@ struct metronom_s { pthread_mutex_t lock; int have_audio; + int video_starting; int video_discontinuity; int video_discontinuity_count; int audio_discontinuity; diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index d8cef1ed1..d5b1f9d4c 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.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: video_decoder.c,v 1.74 2002/03/01 09:29:50 guenter Exp $ + * $Id: video_decoder.c,v 1.75 2002/03/10 21:16:14 miguelfreitas Exp $ * */ @@ -106,7 +106,7 @@ void *video_decoder_loop (void *this_gen) { pthread_mutex_unlock (&this->finished_lock); - this->metronom->expect_video_discontinuity (this->metronom); + this->metronom->expect_video_discontinuity (this->metronom, 1); break; @@ -186,7 +186,7 @@ void *video_decoder_loop (void *this_gen) { this->video_in_discontinuity = 1; - this->metronom->expect_video_discontinuity (this->metronom); + this->metronom->expect_video_discontinuity (this->metronom, 0); this->video_in_discontinuity = 0; break; diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index 6a4d8037e..96b7927c5 100644 --- a/src/xine-engine/video_out.h +++ b/src/xine-engine/video_out.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: video_out.h,v 1.47 2002/03/05 22:31:06 jcdutton Exp $ + * $Id: video_out.h,v 1.48 2002/03/10 21:16:14 miguelfreitas Exp $ * * * xine version of video_out.h @@ -75,7 +75,6 @@ struct vo_frame_s { int64_t pts; /* presentation time stamp (1/90000 sec) */ int64_t vpts; /* virtual pts, generated by metronom */ - int64_t pts_corrector; /* used for pepeat first field tricks */ int64_t scr; /* system clock reference (discont. detection) */ int bad_frame; /* e.g. frame skipped or based on skipped frame */ int duration; /* frame length in time, in 1/90000 sec */ |