summaryrefslogtreecommitdiff
path: root/libavformat/mov.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r--libavformat/mov.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 5a46f9440a..194daebc6e 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -950,6 +950,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
+ int i;
time_t creation_time;
int version = avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -973,7 +974,12 @@ static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
avio_skip(pb, 10); /* reserved */
- avio_skip(pb, 36); /* display matrix */
+ /* movie display matrix, store it in main context and use it later on */
+ for (i = 0; i < 3; i++) {
+ c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
+ c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
+ c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
+ }
avio_rb32(pb); /* preview time */
avio_rb32(pb); /* preview duration */
@@ -2748,13 +2754,23 @@ static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+// return 1 when matrix is identity, 0 otherwise
+#define IS_MATRIX_IDENT(matrix) \
+ ( (matrix)[0][0] == (1 << 16) && \
+ (matrix)[1][1] == (1 << 16) && \
+ (matrix)[2][2] == (1 << 30) && \
+ !(matrix)[0][1] && !(matrix)[0][2] || \
+ !(matrix)[1][0] && !(matrix)[1][2] || \
+ !(matrix)[2][0] && !(matrix)[2][1])
+
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
- int i;
+ int i, j, e;
int width;
int height;
int64_t disp_transform[2];
int display_matrix[3][3];
+ int res_display_matrix[3][3] = { { 0 } };
AVStream *st;
MOVStreamContext *sc;
int version;
@@ -2804,15 +2820,20 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
sc->width = width >> 16;
sc->height = height >> 16;
- // save the matrix when it is not the default identity
- if (display_matrix[0][0] != (1 << 16) ||
- display_matrix[1][1] != (1 << 16) ||
- display_matrix[2][2] != (1 << 30) ||
- display_matrix[0][1] || display_matrix[0][2] ||
- display_matrix[1][0] || display_matrix[1][2] ||
- display_matrix[2][0] || display_matrix[2][1]) {
- int i, j;
+ // apply the moov display matrix (after the tkhd one)
+ for (i = 0; i < 3; i++) {
+ const int sh[3] = { 16, 16, 30 };
+ for (j = 0; j < 3; j++) {
+ for (e = 0; e < 3; e++) {
+ res_display_matrix[i][j] +=
+ ((int64_t) display_matrix[i][e] *
+ c->movie_display_matrix[e][j]) >> sh[e];
+ }
+ }
+ }
+ // save the matrix when it is not the default identity
+ if (!IS_MATRIX_IDENT(res_display_matrix)) {
av_freep(&sc->display_matrix);
sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
if (!sc->display_matrix)
@@ -2820,7 +2841,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
- sc->display_matrix[i * 3 + j] = display_matrix[i][j];
+ sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
}
// transform the display width/height according to the matrix
@@ -2829,9 +2850,9 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (width && height && sc->display_matrix) {
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);
+ (int64_t) width * sc->display_matrix[0 + i] +
+ (int64_t) height * sc->display_matrix[3 + i] +
+ ((int64_t) sc->display_matrix[6 + i] << 16);
//sample aspect ratio is new width/height divided by old width/height
if (disp_transform[0] > 0 && disp_transform[1] > 0)