Compute the full rotatation angle exported by display_matrix.
---
Changelog | 1 +
doc/APIchanges | 3 +++
libavcodec/avcodec.h | 6 ++++++
libavformat/isom.h | 1 +
libavformat/mov.c | 28 ++++++++++++++++++++++++++++
5 files changed, 39 insertions(+)
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..e42d5bf 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@ libavutil: 2013-12-xx
API changes, most recent first:
+2014-02-11 - xxxxxxx - lavc 55.37.0 - avcodec.h
+ Add AV_PKT_DATA_ROTATION for exporting video rotation angle.
+
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..f753ba2 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 the full
+ * rotation angle as u32le degrees.
+ */
+ AV_PKT_DATA_ROTATION,
};
typedef struct AVPacketSideData {
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 6375847..24b1702 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2254,6 +2254,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;
+
+ if (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
@@ -2965,6 +2984,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(sc->rotation));
+ if (rotation) {
+ AV_WL32(rotation, sc->rotation);
+ sc->rotation = 0;
+ } 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);
--
1.8.3.4 (Apple Git-47)
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel