Implement exporting rotation angle from mov.
---
This is redone following more what has been done for replaygain.
Note that showinfo still reports the display orientation data only ONCE, and I
am not sure if this is the expected behaviour.
Note 2, the hflip and vflip computation are theoretical as I couldn't find a
sample implementing it, but they still might be useful later on.
It has been requested that an enum might be added to represent simple tranforms
but I'm not sure if AVDisplayOrientation is the right place to it.
Cheers,
Vittorio
Changelog | 1 +
doc/APIchanges | 7 ++++++
libavcodec/avcodec.h | 6 +++++
libavcodec/utils.c | 9 +++++++
libavformat/isom.h | 3 +++
libavformat/mov.c | 53 ++++++++++++++++++++++++++++++++++++++++++
libavutil/Makefile | 1 +
libavutil/displayorientation.h | 47 +++++++++++++++++++++++++++++++++++++
libavutil/frame.h | 4 ++++
libavutil/version.h | 2 +-
10 files changed, 132 insertions(+), 1 deletion(-)
create mode 100644 libavutil/displayorientation.h
diff --git a/Changelog b/Changelog
index 76eca07..53b62b0 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,7 @@ version <next>:
- libx265 encoder
- shuffleplanes filter
- replaygain data export
+- rotation angle export
version 10:
diff --git a/doc/APIchanges b/doc/APIchanges
index d800253..8ae734c 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,13 @@ libavutil: 2013-12-xx
API changes, most recent first:
+2014-02-xx - xxxxxxx - lavu 53.09.0 - frame.h, displayorientation.h
+ Add AV_FRAME_DATA_DISPLAYORIENTATION for exporting further
+ spatial rendering the video should do for proper display.
+
+2014-02-11 - xxxxxxx - lavc 55.37.0 - avcodec.h
+ Add AV_PKT_DATA_DISPLAYORIENTATION for exporting display orientation.
+
2014-02-xx - xxxxxxx - lavu 53.08.0 - frame.h
Add av_frame_remove_side_data() for removing a single side data
instance from a frame.
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 4fda36e..e8425b8 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -929,6 +929,12 @@ enum AVPacketSideDataType {
* ReplayGain information in form of the AVReplayGain struct.
*/
AV_PKT_DATA_REPLAYGAIN,
+
+ /**
+ * An AV_PKT_DATA_ROTATION side data packet contains further spatial
information
+ * to be applied to the decoded video.
+ */
+ AV_PKT_DATA_DISPLAYORIENTATION,
};
typedef struct AVPacketSideData {
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index e04f455..1c031e0 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -597,6 +597,15 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame
*frame)
memcpy(frame_sd->data, packet_sd, size);
}
+ /* copy rotation angle to the output frame */
+ packet_sd = av_packet_get_side_data(pkt, AV_PKT_DATA_DISPLAYORIENTATION,
&size);
+ if (packet_sd) {
+ frame_sd = av_frame_new_side_data(frame,
AV_FRAME_DATA_DISPLAYORIENTATION, size);
+ if (!frame_sd)
+ return AVERROR(ENOMEM);
+
+ memcpy(frame_sd->data, packet_sd, size);
+ }
return 0;
}
diff --git a/libavformat/isom.h b/libavformat/isom.h
index bf0792c..b3da4cb 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -135,6 +135,9 @@ typedef struct MOVStreamContext {
int64_t track_end; ///< used for dts generation in fragmented movie
files
unsigned int rap_group_count;
MOVSbgp *rap_group;
+ int hflip; ///< horizontal translation derived from the
display_matrix
+ int vflip; ///< vertical translation derived from the
display_matrix
+ int32_t rotation; ///< rotation angle derived from the display_matrix
} MOVStreamContext;
typedef struct MOVContext {
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 6375847..e35fe44 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -31,6 +31,7 @@
#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
+#include "libavutil/displayorientation.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/mathematics.h"
@@ -2254,6 +2255,28 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb,
MOVAtom atom)
sc->width = width >> 16;
sc->height = height >> 16;
+ // get display orientation info 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;
+
+ sc->hflip = ( display_matrix[0][0] < 0 &&
+ !display_matrix[1][0] &&
+ !display_matrix[2][0]);
+ sc->vflip = ( display_matrix[1][1] < 0 &&
+ !display_matrix[0][1] &&
+ !display_matrix[2][1]);
+ sc->rotation = (int32_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
@@ -2965,6 +2988,36 @@ static int mov_read_packet(AVFormatContext *s, AVPacket
*pkt)
sc->has_palette = 0;
}
}
+ if (sc->hflip || sc->vflip || sc->rotation) {
+ AVPacketSideData *sd, *tmp;
+ AVDisplayOrientation *display;
+
+ display = av_mallocz(sizeof(*display));
+ if (!display)
+ return AVERROR(ENOMEM);
+
+ tmp = av_realloc_array(st->side_data, st->nb_side_data + 1,
sizeof(*tmp));
+ if (!tmp) {
+ av_freep(&display);
+ return AVERROR(ENOMEM);
+ }
+
+ st->side_data = tmp;
+ st->nb_side_data++;
+
+ sd = &st->side_data[st->nb_side_data - 1];
+ sd->type = AV_PKT_DATA_DISPLAYORIENTATION;
+ sd->data = (uint8_t *)display;
+ sd->size = sizeof(*display);
+
+ display->hflip = sc->hflip;
+ display->vflip = sc->vflip;
+ display->rotation = sc->rotation;
+
+ sc->hflip = 0;
+ sc->vflip = 0;
+ sc->rotation = 0;
+ }
#if CONFIG_DV_DEMUXER
if (mov->dv_demux && sc->dv_audio_container) {
avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
diff --git a/libavutil/Makefile b/libavutil/Makefile
index d5c1636..4f5cae8 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -16,6 +16,7 @@ HEADERS = adler32.h
\
common.h \
cpu.h \
crc.h \
+ displayorientation.h \
downmix_info.h \
error.h \
eval.h \
diff --git a/libavutil/displayorientation.h b/libavutil/displayorientation.h
new file mode 100644
index 0000000..ef096bb
--- /dev/null
+++ b/libavutil/displayorientation.h
@@ -0,0 +1,47 @@
+/*
+ * 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_DISPLAYORIENTATION_H
+#define AVUTIL_DISPLAYORIENTATION_H
+
+#include <stdint.h>
+
+/**
+ * Spatial transformation information that should be applied to video
+ * after decoding.
+ *
+ * Note that these values are not mutually exclusive.
+ *
+ * The size of this struct is a part of the public ABI.
+ */
+typedef struct AVDisplayOrientation {
+ /**
+ * Video should be orizontally flipped.
+ */
+ int hflip;
+ /**
+ * Video should be vertically flipped.
+ */
+ int vflip;
+ /**
+ * Rotation angle to be applied in degrees.
+ */
+ int32_t rotation;
+} AVDisplayOrientation;
+
+#endif /* AVUTIL_DISPLAYORIENTATION_H */
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 3bec8e5..51b5ad5 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -73,6 +73,10 @@ enum AVFrameSideDataType {
* ReplayGain information in the form of the AVReplayGain struct.
*/
AV_FRAME_DATA_REPLAYGAIN,
+ /**
+ * Display orientation information in the form of the AVDisplayOrientation
struct.
+ */
+ AV_FRAME_DATA_DISPLAYORIENTATION,
};
typedef struct AVFrameSideData {
diff --git a/libavutil/version.h b/libavutil/version.h
index 7f439d7..f8bb447 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -54,7 +54,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 53
-#define LIBAVUTIL_VERSION_MINOR 8
+#define LIBAVUTIL_VERSION_MINOR 9
#define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
--
1.8.3.4 (Apple Git-47)
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel