summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-03-10 21:16:14 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-03-10 21:16:14 +0000
commit5c281d37ea0630f177a5d7088408741cc8e7be66 (patch)
treef4c55b58cc2be81c168d1d47955546cf274c9d93
parenta77fa76ce51ca69bffabe463bc865516e47325f0 (diff)
downloadxine-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.c4
-rw-r--r--src/libmpeg2/decode.c33
-rw-r--r--src/libmpeg2/mpeg2.h1
-rw-r--r--src/xine-engine/metronom.c41
-rw-r--r--src/xine-engine/metronom.h5
-rw-r--r--src/xine-engine/video_decoder.c6
-rw-r--r--src/xine-engine/video_out.h3
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 */