---
Updated to the new side data.
Vittorio
libavformat/isom.h | 1 +
libavformat/mov.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+)
diff --git a/libavformat/isom.h b/libavformat/isom.h
index aec623b..1221446 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -138,6 +138,7 @@ typedef struct MOVStreamContext {
MOVSbgp *rap_group;
int32_t *display_matrix;
+ AVSphericalVideo *spherical;
} MOVStreamContext;
typedef struct MOVContext {
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 9d271f8..40a87c7 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -36,6 +36,7 @@
#include "libavutil/avstring.h"
#include "libavutil/dict.h"
#include "libavutil/opt.h"
+#include "libavutil/stereo3d.h"
#include "libavcodec/ac3tab.h"
#include "avformat.h"
#include "internal.h"
@@ -3082,6 +3083,75 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb,
MOVAtom atom)
return 0;
}
+static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+ MOVStreamContext *sc;
+ int ret;
+
+ uint8_t uuid[16];
+ static const uint8_t uuid_spherical[] = {
+ 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
+ 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
+ };
+
+ if (atom.size < sizeof(uuid) || atom.size == INT64_MAX)
+ return AVERROR_INVALIDDATA;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams - 1];
+ sc = st->priv_data;
+
+ ret = ffio_read_size(pb, uuid, sizeof(uuid));
+ if (ret < 0)
+ return ret;
+
+ if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
+ size_t len = atom.size - sizeof(uuid);
+ uint8_t *buffer = av_malloc(len + 1);
+ if (!buffer)
+ return AVERROR(ENOMEM);
+ buffer[len] = '\0';
+
+ ret = ffio_read_size(pb, buffer, len);
+ if (ret < 0) {
+ av_free(buffer);
+ return ret;
+ }
+
+ /* Mandatory tags (StitchingSoftware ignored) */
+ if (av_stristr(buffer,
"<GSpherical:Spherical>true</GSpherical:Spherical>") &&
+ av_stristr(buffer,
"<GSpherical:Stitched>true</GSpherical:Stitched>") &&
+ av_stristr(buffer,
"<GSpherical:ProjectionType>equirectangular</GSpherical:ProjectionType>")) {
+ sc->spherical = av_mallocz(sizeof(*sc->spherical));
+ if (!sc->spherical) {
+ av_free(buffer);
+ return AVERROR(ENOMEM);
+ }
+
+ sc->spherical->type = AV_SPHERICAL_EQUIRECTANGULAR;
+ sc->spherical->mode = AV_STEREO3D_2D;
+
+ if (av_stristr(buffer,
"<GSpherical:StereoMode>left-right</GSpherical:StereoMode>"))
+ sc->spherical->mode = AV_STEREO3D_SIDEBYSIDE;
+ else if (av_stristr(buffer,
"<GSpherical:StereoMode>top-bottom</GSpherical:StereoMode>"))
+ sc->spherical->mode = AV_STEREO3D_TOPBOTTOM;
+ } else {
+ av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata
found\n");
+ }
+ av_free(buffer);
+ } else {
+ int i;
+ av_log(c->fc, AV_LOG_WARNING, "Unknown UUID found: 0x");
+ for (i = 0; i < sizeof(uuid); i++)
+ av_log(c->fc, AV_LOG_WARNING, "%02x", uuid[i]);
+ av_log(c->fc, AV_LOG_WARNING, "\n");
+ }
+
+ return 0;
+}
+
static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('a','v','s','s'), mov_read_extradata },
{ MKTAG('c','h','p','l'), mov_read_chpl },
@@ -3143,6 +3213,7 @@ static const MOVParseTableEntry mov_default_parse_table[]
= {
{ MKTAG('d','v','c','1'), mov_read_dvc1 },
{ MKTAG('s','b','g','p'), mov_read_sbgp },
{ MKTAG('h','v','c','C'), mov_read_glbl },
+{ MKTAG('u','u','i','d'), mov_read_uuid },
{ MKTAG('-','-','-','-'), mov_read_custom },
{ 0, NULL }
};
@@ -3366,6 +3437,7 @@ static int mov_read_close(AVFormatContext *s)
av_freep(&sc->stps_data);
av_freep(&sc->rap_group);
av_freep(&sc->display_matrix);
+ av_freep(&sc->spherical);
}
if (mov->dv_demux) {
@@ -3464,6 +3536,23 @@ static int mov_read_header(AVFormatContext *s)
sd->data = (uint8_t*)sc->display_matrix;
sc->display_matrix = NULL;
}
+ if (sc->spherical) {
+ AVPacketSideData *sd, *tmp;
+
+ tmp = av_realloc_array(st->side_data,
+ st->nb_side_data + 1, sizeof(*tmp));
+ if (!tmp)
+ 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_SPHERICAL;
+ sd->size = sizeof(*sc->spherical);
+ sd->data = (uint8_t *)sc->spherical;
+ sc->spherical = NULL;
+ }
break;
}
}
--
2.8.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel