aspect ratio cleanup
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 20 Nov 2002 13:08:04 +0000 (13:08 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 20 Nov 2002 13:08:04 +0000 (13:08 +0000)
Originally committed as revision 1254 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/avcodec.h
libavcodec/common.c
libavcodec/common.h
libavcodec/h263.c
libavcodec/h263dec.c
libavcodec/mpegvideo.c

index f88184d..b587298 100644 (file)
@@ -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 {
index 2344dc6..40ba498 100644 (file)
@@ -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;
+}
index c214df9..b657aba 100644 (file)
@@ -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)\
index b2c37cc..8bb23ea 100644 (file)
@@ -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);
index 69e1617..256dd84 100644 (file)
@@ -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;
     }
index 9f53c7f..7f21f33 100644 (file)
@@ -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;