Web lists-archives.org

[MPlayer-dev-eng] [PATCH] Use tkhd matrix for proper display in mov demux




Hello all,

This is a patch to account for the transformation matrix contained in the tkhd atom for proper display width/height.

The video white_zombie_scrunch.mov, that I uploaded to MPlayer/incoming, plays at 160x240 when it should really be 320x240.
mplayer -demuxer mov white_zombie_scrunch.mov

If this is accepted and people would be interested, I would be glad to look at this for the lavf demuxer as well.

-John
Index: libmpdemux/demux_mov.c
===================================================================
--- libmpdemux/demux_mov.c	(revision 26751)
+++ libmpdemux/demux_mov.c	(working copy)
@@ -58,6 +58,7 @@
 
 #define char2short(x,y)	AV_RB16(&(x)[(y)])
 #define char2int(x,y) 	AV_RB32(&(x)[(y)])
+#define char2float(x,y,z) (float)AV_RB32(&(x)[(y)])/(1<<z)
 
 typedef struct {
     unsigned int pts; // duration
@@ -143,6 +144,40 @@
     void* desc; // image/sound/etc description (pointer to ImageDescription etc)
 } mov_track_t;
 
+/// Calculate the aspect ration based on the tkhd transformation matrix
+/// The transformation is outlined in ISO 14496-12, Section 6.2.2
+void mov_apply_tkhd_matrix(mov_track_t* trak, sh_video_t* sh) {
+  int i;
+  float disp_transform[3];
+  float tkhd_matrix[3][3];
+  
+  //read in matrix structure
+  tkhd_matrix[0][0] = char2float(trak->tkdata, 40, 16); //a
+  tkhd_matrix[0][1] = char2float(trak->tkdata, 44, 16); //b
+  tkhd_matrix[0][2] = char2float(trak->tkdata, 48, 30); //u
+  tkhd_matrix[1][0] = char2float(trak->tkdata, 52, 16); //c
+  tkhd_matrix[1][1] = char2float(trak->tkdata, 56, 16); //d
+  tkhd_matrix[1][2] = char2float(trak->tkdata, 60, 30); //v
+  tkhd_matrix[2][0] = char2float(trak->tkdata, 64, 16); //x
+  tkhd_matrix[2][1] = char2float(trak->tkdata, 68, 16); //y
+  tkhd_matrix[2][2] = char2float(trak->tkdata, 72, 30); //z
+  
+  //transform the display width/height according to the matrix
+  for (i=0; i<3; i++) 
+    disp_transform[i] = 
+      sh->disp_w * tkhd_matrix[0][i] +
+      sh->disp_h * tkhd_matrix[1][i] +
+      tkhd_matrix[2][i];
+  //ignore the scale factor as we currently only use the aspect ratio
+  //disp_transform[0] /= disp_transform[2];
+  //disp_transform[1] /= disp_transform[2];
+
+  //calculate the aspect based on the display width/height
+  sh->aspect = disp_transform[0] / disp_transform[1];
+  
+  return;
+}
+
 void mov_build_index(mov_track_t* trak,int timescale){
     int i,j,s;
     int last=trak->chunks_size;
@@ -1120,6 +1155,8 @@
 		
 		if(depth>32+8) mp_msg(MSGT_DEMUX, MSGL_INFO,"*** depth = 0x%X\n",depth);
 
+                mov_apply_tkhd_matrix(trak, sh);
+
 		// palettized?
 		gray = 0;
 		if (depth > 32) { depth&=31; gray = 1; } // depth > 32 means grayscale
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@xxxxxxxxxxxx
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng