On 2014-02-11 12:08:56 +0100, Vittorio Giovara wrote:
> Compute the full rotatation angle exported by display_matrix.
> ---
> Micro optimization, don't do the math when you get the identity matrix!
> Part of the code based on how VLC does it (in modules/demux/mp4/libmp4.c).
> Cheers,
>     Vittorio
> ---
>  Changelog            |  1 +
>  doc/APIchanges       |  4 ++++
>  libavcodec/avcodec.h |  6 ++++++
>  libavcodec/version.h |  2 +-
>  libavformat/isom.h   |  1 +
>  libavformat/mov.c    | 28 ++++++++++++++++++++++++++++
>  6 files changed, 41 insertions(+), 1 deletion(-)
> 
> diff --git a/Changelog b/Changelog
> index 6c54281..178d55d 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -57,6 +57,7 @@ version 10:
>  - framepack filter
>  - Mirillis FIC video decoder
>  - Support DNx444
> +- mov rotation exported as AVPacketSideData
>  
>  
>  version 9:
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 41c848f..8c5b44f 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -13,6 +13,10 @@ libavutil:     2013-12-xx
>  
>  API changes, most recent first:
>  
> +2014-02-11 - xxxxxxx - lavc 55.34.0
> +  Add AV_PKT_DATA_ROTATION as AVPacketSideData to export the full rotation
> +  angle as integer degrees.
> +
>  2014-02-04 - d9ae103 - lavf 55.11.0 - avformat.h
>    Add AVFormatContext.max_interleave_delta for controlling amount of 
> buffering
>    when interleaving.
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 54c60a9..e06d220 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -923,6 +923,12 @@ enum AVPacketSideDataType {
>       * @endcode
>       */
>      AV_PKT_DATA_H263_MB_INFO,
> +
> +    /**
> +     * An AV_PKT_DATA_SCREEN_ORIENTATION side data packet contains the full
> +     * rotation angle as integer degrees.

integer is underspecified in this contents, needs size and endianess.

> +     */
> +    AV_PKT_DATA_ROTATION,
>  };
>  
>  /**
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index f4d8716..4253074 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -29,7 +29,7 @@
>  #include "libavutil/version.h"
>  
>  #define LIBAVCODEC_VERSION_MAJOR 55
> -#define LIBAVCODEC_VERSION_MINOR 33
> +#define LIBAVCODEC_VERSION_MINOR 34
>  #define LIBAVCODEC_VERSION_MICRO  0
>  
>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> diff --git a/libavformat/isom.h b/libavformat/isom.h
> index bf0792c..5409713 100644
> --- a/libavformat/isom.h
> +++ b/libavformat/isom.h
> @@ -135,6 +135,7 @@ typedef struct MOVStreamContext {
>      int64_t track_end;    ///< used for dts generation in fragmented movie 
> files
>      unsigned int rap_group_count;
>      MOVSbgp *rap_group;
> +    uint32_t rotation;    ///< rotation angle derived from the display_matrix
>  } MOVStreamContext;
>  
>  typedef struct MOVContext {
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index dc5b42b..76e348a 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -2253,6 +2253,25 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>      sc->width = width >> 16;
>      sc->height = height >> 16;
>  
> +    // get full orientation angle when the matrix is not the identity one
> +    if (display_matrix[0][1] || display_matrix[1][0] ||
> +        display_matrix[2][0] || display_matrix[2][1]) {
> +        double rotationf, scale[2];
> +#define CONV_FP(x) ((double) (x)) / 65536
> +        scale[0] = sqrt(CONV_FP(display_matrix[0][0]) * 
> CONV_FP(display_matrix[0][0]) +
> +                        CONV_FP(display_matrix[1][0]) * 
> CONV_FP(display_matrix[1][0]));
> +        scale[1] = sqrt(CONV_FP(display_matrix[0][1]) * 
> CONV_FP(display_matrix[0][1]) +
> +                        CONV_FP(display_matrix[1][1]) * 
> CONV_FP(display_matrix[1][1]));
> +
> +        rotationf = atan2(CONV_FP(display_matrix[0][1]) / scale[1],
> +                          CONV_FP(display_matrix[0][0]) / scale[0]) * 180 / 
> M_PI;
> +
> +        while (rotationf < 0)
> +            rotationf += 360.0f;
> +
> +        sc->rotation = (uint32_t) floor(rotationf);
> +    }
> +
>      // transform the display width/height according to the matrix
>      // skip this if the display matrix is the default identity matrix
>      // or if it is rotating the picture, ex iPhone 3GS
> @@ -2964,6 +2983,15 @@ static int mov_read_packet(AVFormatContext *s, 
> AVPacket *pkt)
>                  sc->has_palette = 0;
>              }
>          }
> +        if (sc->rotation != 0) {
> +            uint8_t *rotation;
> +            rotation = av_packet_new_side_data(pkt, AV_PKT_DATA_ROTATION, 
> sizeof(uint32_t));
> +            if (rotation) {
> +                memcpy(rotation, &sc->rotation, sizeof(uint32_t));

one of AV_W?32 from libavutil/intreadwrite.h

> +                sc->rotation = 0;

have you tested if it is passed through after probing?

> +            } else
> +                av_log(mov->fc, AV_LOG_ERROR, "Cannot append rotation angle 
> to packet\n");
> +        }
>  #if CONFIG_DV_DEMUXER
>          if (mov->dv_demux && sc->dv_audio_container) {
>              avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, 
> pkt->size);

What about setting rotation metadata in libavformat/utils.c for ffmpeg
compatiblity?

Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to