diff options
author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2006-06-23 18:22:19 +0000 |
---|---|---|
committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2006-06-23 18:22:19 +0000 |
commit | 5ba0560dad4cc01ec8560dcf41d2395357b3063b (patch) | |
tree | 334cedb5b24e125b42874b4cd860c1ee254654c4 | |
parent | 52e8f3c3d01ea5ba0d8827cfcc845072974e7904 (diff) | |
download | xine-lib-5ba0560dad4cc01ec8560dcf41d2395357b3063b.tar.gz xine-lib-5ba0560dad4cc01ec8560dcf41d2395357b3063b.tar.bz2 |
Frame duration calculation cleanups; more accurate calculation.
CVS patchset: 8072
CVS date: 2006/06/23 18:22:19
-rw-r--r-- | src/libmpeg2/decode.c | 57 |
1 files changed, 21 insertions, 36 deletions
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c index e6ce5be08..f20698520 100644 --- a/src/libmpeg2/decode.c +++ b/src/libmpeg2/decode.c @@ -29,6 +29,7 @@ #include <string.h> /* memcpy/memset, try to remove */ #include <stdlib.h> #include <inttypes.h> +#include <math.h> #define LOG_MODULE "decode" #define LOG_VERBOSE @@ -104,40 +105,22 @@ void mpeg2_init (mpeg2dec_t * mpeg2dec, 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 = 3754; /* actually it's 3753.75 */ - break; - case 2: /* 24 fps */ - frame->duration = 3750; - break; - case 3: /* 25 fps */ - frame->duration = 3600; - break; - case 4: /* 29.97 fps */ - frame->duration = 3003; - break; - case 5: /* 30 fps */ - frame->duration = 3000; - break; - case 6: /* 50 fps */ - frame->duration = 1800; - break; - case 7: /* 59.94 fps */ - frame->duration = 1502; /* actually it's 1501.5 */ - break; - case 8: /* 60 fps */ - frame->duration = 1500; - break; - default: - /* printf ("invalid/unknown frame rate code : %d \n", - frame->frame_rate_code); */ - frame->duration = 0; - } + static const double durations[] = { + 0, /* invalid */ + 3753.75, /* 23.976 fps */ + 3750, /* 24 fps */ + 3600, /* 25 fps */ + 3003, /* 29.97 fps */ + 3000, /* 30 fps */ + 1800, /* 50 fps */ + 1501.5, /* 59.94 fps */ + 1500, /* 60 fps */ + }; + double duration = ((unsigned) mpeg2dec->picture->frame_rate_code > 8u) + ? 0 : durations[mpeg2dec->picture->frame_rate_code]; - frame->duration = frame->duration * - ((mpeg2dec->picture->frame_rate_ext_n + 1) / - (mpeg2dec->picture->frame_rate_ext_d + 1)); + duration = duration * (mpeg2dec->picture->frame_rate_ext_n + 1.0) / + (mpeg2dec->picture->frame_rate_ext_d + 1.0); /* this should be used to detect any special rff pattern */ mpeg2dec->rff_pattern = mpeg2dec->rff_pattern << 1; @@ -147,7 +130,7 @@ static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) (mpeg2dec->rff_pattern & 0xff) == 0x55) && !mpeg2dec->picture->progressive_sequence ) { /* special case for ntsc 3:2 pulldown */ - frame->duration += frame->duration/4; + duration *= 5 / 4; } else { @@ -156,14 +139,16 @@ static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) frame->progressive_frame ) { /* decoder should output 3 fields, so adjust duration to count on this extra field time */ - frame->duration += frame->duration/2; + duration *= 3 / 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 *= (frame->top_field_first)?3:2; + duration *= (frame->top_field_first) ? 3 : 2; } } } + + frame->duration = (int) ceil (duration); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, frame->duration); /*printf("mpeg2dec: rff=%u\n",frame->repeat_first_field);*/ } |