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 functions to easily extract a rotation angle from a matrix and conversely to setup a matrix for a given rotation angle. Signed-off-by: Anton Khirnov <anton@khirnov.net>tags/n2.3
| @@ -26,6 +26,7 @@ version <next>: | |||||
| - support for decoding through DXVA2 in avconv | - support for decoding through DXVA2 in avconv | ||||
| - libbs2b-based stereo-to-binaural audio filter | - libbs2b-based stereo-to-binaural audio filter | ||||
| - native Opus decoder | - native Opus decoder | ||||
| - display matrix export and rotation api | |||||
| version 10: | version 10: | ||||
| @@ -13,6 +13,14 @@ libavutil: 2013-12-xx | |||||
| API changes, most recent first: | 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 video frames for proper display. | |||||
| 2014-05-xx - xxxxxxx - lavc 55.52.0 - avcodec.h | |||||
| Add AV_PKT_DATA_DISPLAYMATRIX for exporting packet-level | |||||
| spatial rendering on video frames for proper display. | |||||
| 2014-05-xx - xxxxxxx - lavf 55.17.1 - avformat.h | 2014-05-xx - xxxxxxx - lavf 55.17.1 - avformat.h | ||||
| Deprecate AVStream.pts and the AVFrac struct, which was its only use case. | Deprecate AVStream.pts and the AVFrac struct, which was its only use case. | ||||
| Those fields were poorly defined and not meant to be public, so there is | Those fields were poorly defined and not meant to be public, so there is | ||||
| @@ -959,6 +959,15 @@ enum AVPacketSideDataType { | |||||
| * ReplayGain information in form of the AVReplayGain struct. | * ReplayGain information in form of the AVReplayGain struct. | ||||
| */ | */ | ||||
| AV_PKT_DATA_REPLAYGAIN, | AV_PKT_DATA_REPLAYGAIN, | ||||
| /** | |||||
| * This side data contains a 3x3 transformation matrix describing an affine | |||||
| * transformation that needs to be applied to the decoded video frames for | |||||
| * correct presentation. | |||||
| * | |||||
| * See libavutil/display.h for a detailed description of the data. | |||||
| */ | |||||
| AV_PKT_DATA_DISPLAYMATRIX, | |||||
| }; | }; | ||||
| typedef struct AVPacketSideData { | typedef struct AVPacketSideData { | ||||
| @@ -598,6 +598,15 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) | |||||
| memcpy(frame_sd->data, packet_sd, size); | 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; | return 0; | ||||
| } | } | ||||
| @@ -16,6 +16,7 @@ HEADERS = adler32.h \ | |||||
| common.h \ | common.h \ | ||||
| cpu.h \ | cpu.h \ | ||||
| crc.h \ | crc.h \ | ||||
| display.h \ | |||||
| downmix_info.h \ | downmix_info.h \ | ||||
| error.h \ | error.h \ | ||||
| eval.h \ | eval.h \ | ||||
| @@ -69,6 +70,7 @@ OBJS = adler32.o \ | |||||
| cpu.o \ | cpu.o \ | ||||
| crc.o \ | crc.o \ | ||||
| des.o \ | des.o \ | ||||
| display.o \ | |||||
| downmix_info.o \ | downmix_info.o \ | ||||
| error.o \ | error.o \ | ||||
| eval.o \ | eval.o \ | ||||
| @@ -0,0 +1,64 @@ | |||||
| /* | |||||
| * Copyright (c) 2014 Vittorio Giovara <vittorio.giovara@gmail.com> | |||||
| * | |||||
| * 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" | |||||
| // 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)) | |||||
| double av_display_rotation_get(const int32_t matrix[9]) | |||||
| { | |||||
| double rotation, 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])); | |||||
| if (scale[0] == 0.0 || scale[1] == 0.0) | |||||
| return NAN; | |||||
| rotation = atan2(CONV_FP(matrix[1]) / scale[1], | |||||
| CONV_FP(matrix[0]) / scale[0]) * 180 / M_PI; | |||||
| return rotation; | |||||
| } | |||||
| void av_display_rotation_set(int32_t matrix[9], double angle) | |||||
| { | |||||
| double radians = angle * M_PI / 180.0f; | |||||
| double c = cos(radians); | |||||
| double s = sin(radians); | |||||
| memset(matrix, 0, 9 * sizeof(int32_t)); | |||||
| matrix[0] = CONV_DB(c); | |||||
| matrix[1] = CONV_DB(-s); | |||||
| matrix[3] = CONV_DB(s); | |||||
| matrix[4] = CONV_DB(c); | |||||
| matrix[8] = 1 << 30; | |||||
| } | |||||
| @@ -0,0 +1,77 @@ | |||||
| /* | |||||
| * Copyright (c) 2014 Vittorio Giovara <vittorio.giovara@gmail.com> | |||||
| * | |||||
| * 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 | |||||
| */ | |||||
| #ifndef AVUTIL_DISPLAY_H | |||||
| #define AVUTIL_DISPLAY_H | |||||
| #include <stdint.h> | |||||
| /** | |||||
| * The display transformation matrix specifies an affine transformation that | |||||
| * should be applied to video frames for correct presentation. It is compatible | |||||
| * with the matrices stored in the ISO/IEC 14496-12 container format. | |||||
| * | |||||
| * The data is a 3x3 matrix represented as a 9-element array: | |||||
| * | |||||
| * | a b u | | |||||
| * (a, b, u, c, d, v, x, y, w) -> | c d v | | |||||
| * | x y w | | |||||
| * | |||||
| * All numbers are stored in native endianness, as 16.16 fixed-point values, | |||||
| * except for u, v and w, which are stored as 2.30 fixed-point values. | |||||
| * | |||||
| * The transformation maps a point (p, q) in the source (pre-transformation) | |||||
| * frame to the point (p', q') in the destination (post-transformation) frame as | |||||
| * follows: | |||||
| * | a b u | | |||||
| * (p, q, 1) . | c d v | = z * (p', q', 1) | |||||
| * | x y w | | |||||
| * | |||||
| * The transformation can also be more explicitly written in components as | |||||
| * follows: | |||||
| * p' = (a * p + c * q + x) / z; | |||||
| * q' = (b * p + d * q + y) / z; | |||||
| * z = u * p + v * q + w | |||||
| */ | |||||
| /** | |||||
| * Extract the rotation component of the transformation matrix. | |||||
| * | |||||
| * @param matrix the transformation matrix | |||||
| * @return the angle (in degrees) by which the transformation rotates the frame. | |||||
| * The angle will be in range [-180.0, 180.0], or NaN if the matrix is | |||||
| * singular. | |||||
| * | |||||
| * @note floating point numbers are inherently inexact, so callers are | |||||
| * recommended to round the return value to nearest integer before use. | |||||
| */ | |||||
| double av_display_rotation_get(const int32_t matrix[9]); | |||||
| /** | |||||
| * Initialize a transformation matrix describing a pure rotation by the | |||||
| * specified angle (in degrees). | |||||
| * | |||||
| * @param matrix an allocated transformation matrix (will be fully overwritten | |||||
| * by this function) | |||||
| * @param angle rotation angle in degrees. | |||||
| */ | |||||
| void av_display_rotation_set(int32_t matrix[9], double angle); | |||||
| #endif /* AVUTIL_DISPLAY_H */ | |||||
| @@ -73,6 +73,14 @@ enum AVFrameSideDataType { | |||||
| * ReplayGain information in the form of the AVReplayGain struct. | * ReplayGain information in the form of the AVReplayGain struct. | ||||
| */ | */ | ||||
| AV_FRAME_DATA_REPLAYGAIN, | AV_FRAME_DATA_REPLAYGAIN, | ||||
| /** | |||||
| * This side data contains a 3x3 transformation matrix describing an affine | |||||
| * transformation that needs to be applied to the frame for correct | |||||
| * presentation. | |||||
| * | |||||
| * See libavutil/display.h for a detailed description of the data. | |||||
| */ | |||||
| AV_FRAME_DATA_DISPLAYMATRIX, | |||||
| }; | }; | ||||
| typedef struct AVFrameSideData { | typedef struct AVFrameSideData { | ||||
| @@ -54,7 +54,7 @@ | |||||
| */ | */ | ||||
| #define LIBAVUTIL_VERSION_MAJOR 53 | #define LIBAVUTIL_VERSION_MAJOR 53 | ||||
| #define LIBAVUTIL_VERSION_MINOR 14 | |||||
| #define LIBAVUTIL_VERSION_MINOR 15 | |||||
| #define LIBAVUTIL_VERSION_MICRO 0 | #define LIBAVUTIL_VERSION_MICRO 0 | ||||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | ||||