[1/2] mov: Rewrite aspect ratio handling from display matrix

Message ID 20161005211656.89604-1-vittorio.giovara@gmail.com
State Superseded
Headers show

Commit Message

Vittorio Giovara Oct. 5, 2016, 9:16 p.m.
From: Michael Niedermayer <michaelni@gmx.at>

This should make this code more robust and simpler.
The use of hypot is by Ganesh Ajjanagadde.

Also use the context display matrix instead of the local one.

Signed-off-by: Vittorio Giovara <vittorio.giovare@gmail.com>
---
 libavformat/mov.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 36e75d5..00ecdc7 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2752,7 +2752,6 @@  static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     int i;
     int width;
     int height;
-    int64_t disp_transform[2];
     int display_matrix[3][3];
     AVStream *st;
     MOVStreamContext *sc;
@@ -2824,19 +2823,18 @@  static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     // transform the display width/height according to the matrix
     // skip this when the display matrix is the identity one
-    // to keep the same scale, use [width height 1<<16]
     if (width && height && sc->display_matrix) {
+        double disp_transform[2];
+
         for (i = 0; i < 2; i++)
-            disp_transform[i] =
-                (int64_t)  width  * display_matrix[0][i] +
-                (int64_t)  height * display_matrix[1][i] +
-                ((int64_t) display_matrix[2][i] << 16);
-
-        //sample aspect ratio is new width/height divided by old width/height
-        if (disp_transform[0] > 0 && disp_transform[1] > 0)
-            st->sample_aspect_ratio = av_d2q(
-                ((double) disp_transform[0] * height) /
-                ((double) disp_transform[1] * width), INT_MAX);
+            disp_transform[i] = hypot(display_matrix[i][0], display_matrix[i][1]);
+
+        // only sane values allowed (no zeros or overflows)
+        if (disp_transform[0] > 0 && disp_transform[0] < (1 << 24) &&
+            disp_transform[1] > 0 && disp_transform[1] < (1 << 24) &&
+            fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01) {
+            st->sample_aspect_ratio = av_d2q(disp_transform[0] / disp_transform[1], INT_MAX);
+        }
     }
     return 0;
 }