From 5d3cea3a86a9b994591998fb05cacfc16ae4852d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 20 Nov 2002 13:08:04 +0000 Subject: [PATCH] aspect ratio cleanup Originally committed as revision 1254 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/avcodec.h | 19 ++++++++++++------- libavcodec/common.c | 26 ++++++++++++++++++++++++++ libavcodec/common.h | 2 ++ libavcodec/h263.c | 36 +++++++++++++++++++++++++++--------- libavcodec/h263dec.c | 20 +++++++++----------- libavcodec/mpegvideo.c | 6 ------ 6 files changed, 76 insertions(+), 33 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index f88184d504..b587298ce3 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -5,8 +5,8 @@ #define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION "0.4.6" -#define LIBAVCODEC_BUILD 4639 -#define LIBAVCODEC_BUILD_STR "4639" +#define LIBAVCODEC_BUILD 4640 +#define LIBAVCODEC_BUILD_STR "4640" enum CodecID { CODEC_ID_NONE, @@ -145,6 +145,7 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG, #define CODEC_FLAG_NORMALIZE_AQP 0x00020000 /* normalize adaptive quantization */ #define CODEC_FLAG_INTERLACED_DCT 0x00040000 /* use interlaced dct */ #define CODEC_FLAG_LOW_DELAY 0x00080000 /* force low delay / will fail on b frames */ +#define CODEC_FLAG_ALT_SCAN 0x00100000 /* use alternate scan */ /* codec capabilities */ @@ -222,8 +223,7 @@ typedef struct AVCodecContext { int width, height; /** - * encoding: set by user. 0 if not known - * decoding: set by lavc. 0 if not known + * Obsolete, will be removed */ int aspect_ratio_info; #define FF_ASPECT_SQUARE 1 @@ -646,9 +646,7 @@ typedef struct AVCodecContext { float rc_initial_cplx; /** - * custom aspect ratio, used if aspect_info==FF_ASPECT_EXTENDED - * encoding: set by user. - * decoding: set by lavc. + * Obsolete, will be removed */ int aspected_width; int aspected_height; @@ -795,6 +793,13 @@ typedef struct AVCodecContext { #define FF_PRED_LEFT 0 #define FF_PRED_PLANE 1 #define FF_PRED_MEDIAN 2 + + /** + * aspect ratio. (0 if unknown) + * encoding: set by user. + * decoding: set by lavc. + */ + float aspect_ratio; } AVCodecContext; typedef struct AVCodec { diff --git a/libavcodec/common.c b/libavcodec/common.c index 2344dc6be3..40ba49811d 100644 --- a/libavcodec/common.c +++ b/libavcodec/common.c @@ -326,3 +326,29 @@ int ff_gcd(int a, int b){ if(b) return ff_gcd(b, a%b); else return a; } + +void ff_float2fraction(int *nom_arg, int *denom_arg, double f, int max){ + double best_diff=1E10, diff; + int best_denom=1, best_nom=1; + int nom, denom, gcd; + + //brute force here, perhaps we should try continued fractions if we need large max ... + for(denom=1; denom<=max; denom++){ + nom= (int)(f*denom + 0.5); + if(nom<=0 || nom>max) continue; + + diff= ABS( f - (double)nom / (double)denom ); + if(diff < best_diff){ + best_diff= diff; + best_nom= nom; + best_denom= denom; + } + } + + gcd= ff_gcd(best_nom, best_denom); + best_nom /= gcd; + best_denom /= gcd; + + *nom_arg= best_nom; + *denom_arg= best_denom; +} diff --git a/libavcodec/common.h b/libavcodec/common.h index c214df9227..b657aba7ba 100644 --- a/libavcodec/common.h +++ b/libavcodec/common.h @@ -842,6 +842,8 @@ static inline int ff_get_fourcc(const char *s){ return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); } +void ff_float2fraction(int *nom_arg, int *denom_arg, double f, int max); + #ifdef ARCH_X86 #define MASK_ABS(mask, level)\ diff --git a/libavcodec/h263.c b/libavcodec/h263.c index b2c37ccb57..8bb23eac5f 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -120,6 +120,26 @@ int h263_get_picture_format(int width, int height) return format; } +static void init_aspect_info(MpegEncContext * s){ + double aspect; + + emms_c(); //paranoia ;) + + if(s->avctx->aspect_ratio==0) aspect= 1.0; + aspect= s->avctx->aspect_ratio; + + ff_float2fraction(&s->aspected_width, &s->aspected_height, aspect, 255); + + if(s->aspected_width == 4 && s->aspected_height == 3) + s->aspect_ratio_info= FF_ASPECT_4_3_625; + else if(s->aspected_width == 16 && s->aspected_height == 9) + s->aspect_ratio_info= FF_ASPECT_16_9_625; + else if(s->aspected_width == 1 && s->aspected_height == 1) + s->aspect_ratio_info= FF_ASPECT_SQUARE; + else + s->aspect_ratio_info= FF_ASPECT_EXTENDED; +} + void h263_encode_picture_header(MpegEncContext * s, int picture_number) { int format; @@ -196,11 +216,9 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) if (format == 7) { /* Custom Picture Format (CPFMT) */ - - if (s->aspect_ratio_info) - put_bits(&s->pb,4,s->aspect_ratio_info); - else - put_bits(&s->pb,4,2); /* Aspect ratio: CIF 12:11 (4:3) picture */ + init_aspect_info(s); + + put_bits(&s->pb,4,s->aspect_ratio_info); put_bits(&s->pb,9,(s->width >> 2) - 1); put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ put_bits(&s->pb,9,(s->height >> 2)); @@ -1508,10 +1526,10 @@ static void mpeg4_encode_vol_header(MpegEncContext * s) put_bits(&s->pb, 1, 1); /* is obj layer id= yes */ put_bits(&s->pb, 4, vo_ver_id); /* is obj layer ver id */ put_bits(&s->pb, 3, 1); /* is obj layer priority */ - if(s->aspect_ratio_info) - put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ - else - put_bits(&s->pb, 4, 1); /* aspect ratio info= sqare pixel */ + + init_aspect_info(s); + + put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) { put_bits(&s->pb, 8, s->aspected_width); diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 69e1617662..256dd8446e 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -348,6 +348,8 @@ static int h263_decode_frame(AVCodecContext *avctx, MpegEncContext *s = avctx->priv_data; int ret,i; AVPicture *pict = data; + float new_aspect; + #ifdef PRINT_FRAME_TIME uint64_t time= rdtsc(); #endif @@ -495,23 +497,19 @@ retry: /* and other parameters. So then we could init the picture */ /* FIXME: By the way H263 decoder is evolving it should have */ /* an H263EncContext */ + if(s->aspected_height) + new_aspect= (float)s->aspected_width / (float)s->aspected_height; + else + new_aspect=0; + if ( s->width != avctx->width || s->height != avctx->height - || avctx->aspect_ratio_info != s->aspect_ratio_info - || avctx->aspected_width != s->aspected_width - || avctx->aspected_height != s->aspected_height) { + || ABS(new_aspect - avctx->aspect_ratio) > 0.001) { /* H.263 could change picture size any time */ MPV_common_end(s); s->context_initialized=0; } if (!s->context_initialized) { - avctx->width = s->width; - avctx->height = s->height; - avctx->aspect_ratio_info= s->aspect_ratio_info; - if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) - { - avctx->aspected_width = s->aspected_width; - avctx->aspected_height = s->aspected_height; - } + avctx->aspect_ratio= new_aspect; goto retry; } diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 9f53c7fd3b..7f21f331e2 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -557,12 +557,6 @@ int MPV_encode_init(AVCodecContext *avctx) s->qcompress= avctx->qcompress; s->qblur= avctx->qblur; s->avctx = avctx; - s->aspect_ratio_info= avctx->aspect_ratio_info; - if (avctx->aspect_ratio_info == FF_ASPECT_EXTENDED) - { - s->aspected_width = avctx->aspected_width; - s->aspected_height = avctx->aspected_height; - } s->flags= avctx->flags; s->max_b_frames= avctx->max_b_frames; s->b_frame_strategy= avctx->b_frame_strategy;