Compute the full rotatation angle exported by display_matrix.
---
Updated patch using u32le as descriptor and AV_WL32 instead of the memcpy.
The side data apparently survives after probing. I do not think it's worthwhile
adding a metadata entry too.
Cheers,
    Vittorio
 Changelog            |  1 +
 doc/APIchanges       |  4 ++++
 libavcodec/avcodec.h |  6 ++++++
 libavcodec/version.h |  2 +-
 libavformat/isom.h   |  1 +
 libavformat/mov.c    | 28 ++++++++++++++++++++++++++++
 6 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/Changelog b/Changelog
index 6c54281..178d55d 100644
--- a/Changelog
+++ b/Changelog
@@ -57,6 +57,7 @@ version 10:
 - framepack filter
 - Mirillis FIC video decoder
 - Support DNx444
+- mov rotation exported as AVPacketSideData
 
 
 version 9:
diff --git a/doc/APIchanges b/doc/APIchanges
index 41c848f..8c5b44f 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,10 @@ libavutil:     2013-12-xx
 
 API changes, most recent first:
 
+2014-02-11 - xxxxxxx - lavc 55.34.0
+  Add AV_PKT_DATA_ROTATION as AVPacketSideData to export the full rotation
+  angle as integer degrees.
+
 2014-02-04 - d9ae103 - lavf 55.11.0 - avformat.h
   Add AVFormatContext.max_interleave_delta for controlling amount of buffering
   when interleaving.
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 54c60a9..f4e993b 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -923,6 +923,12 @@ enum AVPacketSideDataType {
      * @endcode
      */
     AV_PKT_DATA_H263_MB_INFO,
+
+    /**
+     * An AV_PKT_DATA_ROTATION side data packet contains the full
+     * rotation angle as u32le degrees.
+     */
+    AV_PKT_DATA_ROTATION,
 };
 
 /**
diff --git a/libavcodec/version.h b/libavcodec/version.h
index f4d8716..4253074 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 33
+#define LIBAVCODEC_VERSION_MINOR 34
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
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 dc5b42b..abf637d 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2253,6 +2253,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
@@ -2964,6 +2983,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(uint32_t));
+            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.4

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

Reply via email to