Adding support for writing spherical metadata in Matroska.
From 5a9cf56bf3114186412bb5572b153f886edb6ddb Mon Sep 17 00:00:00 2001
From: Aaron Colwell <acolw...@google.com>
Date: Fri, 27 Jan 2017 12:07:25 -0800
Subject: [PATCH] matroskaenc: Add support for writing video projection
 element.

Adding support for writing spherical metadata in Matroska.
---
 libavformat/matroskaenc.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index f731b678b9..1b186db223 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -1038,6 +1038,67 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
     return ret;
 }
 
+static int mkv_write_video_projection(AVIOContext *pb, AVStream *st)
+{
+    AVSphericalMapping *spherical_mapping = (AVSphericalMapping*)av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL, NULL);
+    ebml_master projection;
+    int projection_type = 0;
+
+    AVIOContext *dyn_cp;
+    uint8_t *projection_private_ptr = NULL;
+    int ret, projection_private_size;
+
+    if (!spherical_mapping)
+        return 0;
+
+    if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
+        spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
+        av_log(pb, AV_LOG_WARNING, "Unsupported projection %d. projection not written.\n", spherical_mapping->projection);
+        return 0;
+    }
+
+    ret = avio_open_dyn_buf(&dyn_cp);
+    if (ret < 0)
+        return ret;
+
+    switch (spherical_mapping->projection) {
+    case AV_SPHERICAL_EQUIRECTANGULAR:
+        projection_type = 1;
+
+        /* Create ProjectionPrivate contents */
+        avio_wb32(dyn_cp, 0); /* version = 0 & flags = 0 */
+        avio_wb32(dyn_cp, 0); /* projection_bounds_top */
+        avio_wb32(dyn_cp, 0); /* projection_bounds_bottom */
+        avio_wb32(dyn_cp, 0); /* projection_bounds_left */
+        avio_wb32(dyn_cp, 0); /* projection_bounds_right */
+        break;
+    case AV_SPHERICAL_CUBEMAP:
+        projection_type = 2;
+
+        /* Create ProjectionPrivate contents */
+        avio_wb32(dyn_cp, 0); /* version = 0 & flags = 0 */
+        avio_wb32(dyn_cp, 0); /* layout */
+        avio_wb32(dyn_cp, 0); /* padding */
+        break;
+    }
+
+    projection_private_size = avio_close_dyn_buf(dyn_cp, &projection_private_ptr);
+
+    projection = start_ebml_master(pb, MATROSKA_ID_VIDEOPROJECTION, 0);
+    put_ebml_uint(pb, MATROSKA_ID_VIDEOPROJECTIONTYPE, projection_type);
+    if (projection_private_size)
+        put_ebml_binary(pb, MATROSKA_ID_VIDEOPROJECTIONPRIVATE, projection_private_ptr, projection_private_size);
+
+    put_ebml_float(pb, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, (float)(spherical_mapping->yaw) / (1 << 16));
+    put_ebml_float(pb, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, (float)(spherical_mapping->pitch) / (1 << 16));
+    put_ebml_float(pb, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, (float)(spherical_mapping->roll) / (1 << 16));
+    end_ebml_master(pb, projection);
+
+    av_free(projection_private_ptr);
+
+    return 0;
+}
+
 static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
                            int i, AVIOContext *pb, int default_stream_exists)
 {
@@ -1251,6 +1312,9 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
         ret = mkv_write_video_color(pb, par, st);
         if (ret < 0)
             return ret;
+        ret = mkv_write_video_projection(pb, st);
+        if (ret < 0)
+            return ret;
         end_ebml_master(pb, subinfo);
         break;
 
-- 
2.11.0.483.g087da7b7c-goog

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to