Quoting Vittorio Giovara (2016-10-14 00:23:10) > This matrix needs to be applied after all others have (currently only > display matrix from trak), but cannot be handled in movie box, since > streams are not allocated yet. > > So store it in main context and if not identity, apply it when appropriate, > handling the case when trak display matrix is identity and when it is not. > > Fate tests are updated accordingly. > > Signed-off-by: Vittorio Giovara <vittorio.giov...@gmail.com> > --- > libavformat/isom.h | 2 ++ > libavformat/mov.c | 57 > +++++++++++++++++++++++++++++---------- > tests/ref/fate/mov-ar | 4 +-- > tests/ref/fate/mov-display-matrix | 2 +- > 4 files changed, 48 insertions(+), 17 deletions(-) > > diff --git a/libavformat/isom.h b/libavformat/isom.h > index 58f0a20..1aa2091 100644 > --- a/libavformat/isom.h > +++ b/libavformat/isom.h > @@ -167,6 +167,8 @@ typedef struct MOVContext { > int export_all; > int export_xmp; > int enable_drefs; > + > + int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd > } MOVContext; > > int ff_mp4_read_descr_len(AVIOContext *pb); > diff --git a/libavformat/mov.c b/libavformat/mov.c > index 36e75d5..c082ee4 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 */ > @@ -2747,17 +2753,34 @@ static int mov_read_meta(MOVContext *c, AVIOContext > *pb, MOVAtom atom) > return 0; > } > > +// return 0 when matrix is identity, 1 otherwise > +#define IS_MATRIX_FULL(matrix) \
nit: I'd flip the meaning and make it IS_MATRIX_ID(ENTITY), since "full" is confusing in this context. > + (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]) > + > +// fixed point to double > +#define CONV_FP(x, sh) ((double) (x)) / (1 << (sh)) > + > +// double to fixed point > +#define CONV_DB(x, sh) ((int32_t) ((x) * (1 << (sh)))) > + > 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]; > AVStream *st; > MOVStreamContext *sc; > int version; > int flags; > + double val = 0; > > if (c->fc->nb_streams < 1) > return 0; > @@ -2803,15 +2826,21 @@ 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 > + for (i = 0; i < 3; i++) { > + for (j = 0; j < 3; j++) { > + int sh = j == 2 ? 30 : 16; > + for (e = 0; e < 3; e++) { > + val += CONV_FP(display_matrix[i][e], sh) * > + CONV_FP(c->movie_display_matrix[e][j], sh); > + } > + res_display_matrix[i][j] = CONV_DB(val, sh); > + val = 0; This reinitialization is weird, just make val local to this block. Making the multiplication floating point is unpleasant, but I guess fixed point is more effort. -- Anton Khirnov _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel