]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/commitdiff
Use tkhd matrix for proper display in mov.
authorbenoit <benoit@9553f0bf-9b14-0410-a0b8-cfaf0461ba5b>
Thu, 24 Jul 2008 07:55:11 +0000 (07:55 +0000)
committerbenoit <benoit@9553f0bf-9b14-0410-a0b8-cfaf0461ba5b>
Thu, 24 Jul 2008 07:55:11 +0000 (07:55 +0000)
Patch by John Schmiederer jschmiederer on2 com
Original thread: [PATCH] Use tkhd matrix for proper display in mov
Date: 05/23/2008 09:31 PM

git-svn-id: file:///var/local/repositories/ffmpeg/trunk@14365 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b

libavformat/mov.c

index c13f877e23ac92781ed7de733a09aa5d112f4611..2f406c402d82da1422d0181f65b50e5b6ca233c7 100644 (file)
@@ -1371,6 +1371,11 @@ static int mov_read_udta(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
 
 static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
 {
+    int i;
+    int width;
+    int height;
+    int64_t disp_transform[2];
+    int display_matrix[3][2];
     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
     int version = get_byte(pb);
 
@@ -1402,12 +1407,36 @@ static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
     get_be16(pb); /* volume */
     get_be16(pb); /* reserved */
 
-    url_fskip(pb, 36); /* display matrix */
-
-    /* those are fixed-point */
-    get_be32(pb); /* track width */
-    get_be32(pb); /* track height */
+    //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
+    // they're kept in fixed point format through all calculations
+    // ignore u,v,z b/c we don't need the scale factor to calc aspect ratio
+    for (i = 0; i < 3; i++) {
+        display_matrix[i][0] = get_be32(pb);   // 16.16 fixed point
+        display_matrix[i][1] = get_be32(pb);   // 16.16 fixed point
+        get_be32(pb);           // 2.30 fixed point (not used)
+    }
 
+    width = get_be32(pb);       // 16.16 fixed point track width
+    height = get_be32(pb);      // 16.16 fixed point track height
+
+    //transform the display width/height according to the matrix
+    // skip this if the display matrix is the default identity matrix
+    // to keep the same scale, use [width height 1<<16]
+    if (width && height &&
+        (display_matrix[0][0] != 65536 || display_matrix[0][1]           ||
+        display_matrix[1][0]           || display_matrix[1][1] != 65536  ||
+        display_matrix[2][0]           || display_matrix[2][1])) {
+        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
+        st->codec->sample_aspect_ratio = av_d2q(
+            ((double) disp_transform[0] * height) /
+            ((double) disp_transform[1] * width), INT_MAX);
+    }
     return 0;
 }