From ec072669f7398f40d8001c8cb0868880569c6cd9 Mon Sep 17 00:00:00 2001 From: John Schmiederer Date: Thu, 24 Jul 2008 07:55:11 +0000 Subject: Use tkhd matrix for proper display in mov. 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 Originally committed as revision 14365 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/mov.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'libavformat/mov.c') diff --git a/libavformat/mov.c b/libavformat/mov.c index c13f877e23..2f406c402d 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -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; } -- cgit v1.2.3