1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

Add transformation matrix API.

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>
This commit is contained in:
Vittorio Giovara 2014-05-15 22:06:49 -04:00 committed by Anton Khirnov
parent 9929b3564c
commit bddd8cbf68
9 changed files with 179 additions and 1 deletions

View File

@ -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:

View File

@ -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

View File

@ -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 {

View File

@ -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;
} }

View File

@ -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 \

64
libavutil/display.c Normal file
View File

@ -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;
}

77
libavutil/display.h Normal file
View File

@ -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 */

View File

@ -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 {

View File

@ -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, \