On 2014-05-15 22:06:49 -0400, Vittorio Giovara wrote:
> Add AV_PKT_DATA_DISPLAYMATRIX and AV_FRAME_DATA_DISPLAYMATRIX as stream and
> frame side data (respectively) to describe a display transformation matrix
> for linear transformation operations on the decoded video.
> 
> Add APIs to easily convert a matrix to a rotation angle, or an angle to a
> matrix, and to set flipping and translation operations.
> ---
>  Changelog            |  1 +
>  doc/APIchanges       |  8 ++++++
>  libavcodec/avcodec.h |  7 +++++
>  libavcodec/utils.c   |  9 ++++++
>  libavcodec/version.h |  2 +-
>  libavutil/Makefile   |  2 ++
>  libavutil/display.c  | 78 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  libavutil/display.h  | 78 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  libavutil/frame.h    |  6 ++++
>  libavutil/version.h  |  2 +-
>  10 files changed, 191 insertions(+), 2 deletions(-)
>  create mode 100644 libavutil/display.c
>  create mode 100644 libavutil/display.h
> 
> diff --git a/Changelog b/Changelog
> index 0348ff7..f157f7d 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -26,6 +26,7 @@ version <next>:
>  - support for decoding through DXVA2 in avconv
>  - libbs2b-based stereo-to-binaural audio filter
>  - native Opus decoder
> +- display matrix export and rotation api
>  
>  
>  version 10:
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 57ef04f..3052d9a 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -13,6 +13,14 @@ libavutil:     2013-12-xx
>  
>  API changes, most recent first:
>  
> +2014-05-xx - xxxxxxx - lavu 53.15.0 - frame.h, display.h
> +  Add AV_FRAME_DATA_DISPLAYMATRIX for exporting frame-level
> +  spatial rendering on the video frame for proper display.
> +
> +2014-05-xx - xxxxxxx - lavc 55.52.0 - avcodec.h
> +  Add AV_PKT_DATA_DISPLAYMATRIX for exporting stream-level
> +  spatial rendering on the video frame for proper display.
> +
>  2014-05-xx - xxxxxxx - lavf 55.17.0 - avformat.h
>    Add AVMFT_FLAG_BITEXACT flag. Muxers now use it instead of checking
>    CODEC_FLAG_BITEXACT on the first stream.
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index c76ee04..2737f9a 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -959,6 +959,13 @@ enum AVPacketSideDataType {
>       * ReplayGain information in form of the AVReplayGain struct.
>       */
>      AV_PKT_DATA_REPLAYGAIN,
> +
> +    /**
> +     * This side data contains a 3x3 matrix describing two dimensional
> +     * transformations to be applied on the decoded video frame.
> +     * See libavutil/display.h for an explicative use.
> +     */
> +    AV_PKT_DATA_DISPLAYMATRIX,
>  };
>  
>  typedef struct AVPacketSideData {
> diff --git a/libavcodec/utils.c b/libavcodec/utils.c
> index d5c3070..43909c9 100644
> --- a/libavcodec/utils.c
> +++ b/libavcodec/utils.c
> @@ -598,6 +598,15 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame 
> *frame)
>  
>          memcpy(frame_sd->data, packet_sd, size);
>      }
> +    /* copy the displaymatrix to the output frame */
> +    packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX, 
> &size);
> +    if (packet_sd) {
> +        frame_sd = av_frame_new_side_data(frame, 
> AV_FRAME_DATA_DISPLAYMATRIX, size);
> +        if (!frame_sd)
> +            return AVERROR(ENOMEM);
> +
> +        memcpy(frame_sd->data, packet_sd, size);
> +    }
>  
>      return 0;
>  }
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index 22343d5..d42e963 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 51
> +#define LIBAVCODEC_VERSION_MINOR 52
>  #define LIBAVCODEC_VERSION_MICRO  0
>  
>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> diff --git a/libavutil/Makefile b/libavutil/Makefile
> index d5c1636..0f8ed08 100644
> --- a/libavutil/Makefile
> +++ b/libavutil/Makefile
> @@ -16,6 +16,7 @@ HEADERS = adler32.h                                         
>             \
>            common.h                                                      \
>            cpu.h                                                         \
>            crc.h                                                         \
> +          display.h                                                     \
>            downmix_info.h                                                \
>            error.h                                                       \
>            eval.h                                                        \
> @@ -69,6 +70,7 @@ OBJS = adler32.o                                            
>             \
>         cpu.o                                                            \
>         crc.o                                                            \
>         des.o                                                            \
> +       display.o                                                        \
>         downmix_info.o                                                   \
>         error.o                                                          \
>         eval.o                                                           \
> diff --git a/libavutil/display.c b/libavutil/display.c
> new file mode 100644
> index 0000000..c8327a0
> --- /dev/null
> +++ b/libavutil/display.c
> @@ -0,0 +1,78 @@
> +/*
> + * Copyright (c) 2014 Vittorio Giovara <[email protected]>
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include <stdint.h>
> +#include <string.h>
> +#include <math.h>
> +
> +#include "display.h"
> +#include "mem.h"
> +
> +// fixed point to double
> +#define CONV_FP(x) ((double) (x)) / (1 << 16)
> +
> +// double to fixed point
> +#define CONV_DB(x) (int32_t) ((x) * (1 << 16))
> +
> +int av_display_rotation_get(const int32_t *matrix)

type should probably be const int32_t matrix[9], compatible to 'const 
int32_t *' but shows the expected length.

> +{
> +    double rotationf, scale[2];
> +
> +    scale[0] = sqrt(CONV_FP(matrix[0]) * CONV_FP(matrix[0]) +
> +                    CONV_FP(matrix[3]) * CONV_FP(matrix[3]));
> +    scale[1] = sqrt(CONV_FP(matrix[1]) * CONV_FP(matrix[1]) +
> +                    CONV_FP(matrix[4]) * CONV_FP(matrix[4]));
> +
> +    rotationf = atan2(CONV_FP(matrix[1]) / scale[1],
> +                      CONV_FP(matrix[0]) / scale[0]) * 180 / M_PI;
> +
> +    return (int) floor(rotationf);

was it decided that int DEG is what users want? strange that get returns an 
int angle but set uses double

> +}
> +
> +int32_t *av_display_rotation_set(double angle)
> +{
> +    int32_t *matrix = av_mallocz(sizeof(int32_t) * 9);

malloc return value not checked, also it's a little strange that rotate 
returns a new matrix and translate/flip modifies a existing one. It also 
makes the support for h264/hevc sei a little awkward since you allocate the 
matrix twice just to memcpy

> +    double radians = angle * M_PI / 180.0f;
> +
> +    matrix[0] = CONV_DB(cos(radians));
> +    matrix[1] = CONV_DB(-sin(radians));
> +    matrix[3] = CONV_DB(sin(radians));
> +    matrix[4] = CONV_DB(cos(radians));
> +    matrix[8] = 1 << 30;
> +
> +    return matrix;
> +}
> +
> +void av_display_matrix_translate(int32_t *matrix,
> +                                 unsigned int x, unsigned int y)

same about the type applies, minus const

> +{
> +    matrix[6] = x << 16;
> +    matrix[7] = y << 16;
> +}
> +
> +void av_display_matrix_flip(int32_t *matrix, int hflip, int vflip)

see above, the rest is more or less sane

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

Reply via email to