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

Reply via email to