Re: [libav-devel] [PATCH 2/2] mov: Export spherical information

2016-11-03 Thread Diego Biurrun
On Wed, Nov 02, 2016 at 02:15:07PM -0400, Vittorio Giovara wrote:
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -3154,6 +3155,242 @@ static int mov_read_elst(MOVContext *c, AVIOContext 
> *pb, MOVAtom atom)
>  
> +static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +mode = avio_r8(pb);
> +switch(mode) {

switch (

> +static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
> +{
> +switch(tag) {
> +case MKTAG('c','b','m','p'):

same

> +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;
> +}
> +if (sc->stereo3d) {
> +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_STEREO3D;
> +sd->size = sizeof(*sc->stereo3d);
> +sd->data = (uint8_t *)sc->stereo3d;
> +sc->stereo3d = NULL;
> +}

The code duplication here should be refactored IMO.

Diego
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel


[libav-devel] [PATCH 2/2] mov: Export spherical information

2016-11-02 Thread Vittorio Giovara
Signed-off-by: Vittorio Giovara 
---
 libavformat/isom.h |   4 +
 libavformat/mov.c  | 277 +
 2 files changed, 281 insertions(+)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 58f0a20..2e22575 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -28,6 +28,8 @@
 #include "internal.h"
 #include "dv.h"
 
+#include "libavutil/stereo3d.h"
+
 /* isom.c */
 extern const AVCodecTag ff_mp4_obj_type[];
 extern const AVCodecTag ff_codec_movvideo_tags[];
@@ -145,6 +147,8 @@ typedef struct MOVStreamContext {
 int stsd_count;
 
 int32_t *display_matrix;
+AVSphericalVideo *spherical;
+AVStereo3D *stereo3d;
 } MOVStreamContext;
 
 typedef struct MOVContext {
diff --git a/libavformat/mov.c b/libavformat/mov.c
index fb2b7d6..d1f336b 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -37,6 +37,7 @@
 #include "libavutil/dict.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/stereo3d.h"
 #include "libavcodec/ac3tab.h"
 #include "avformat.h"
 #include "internal.h"
@@ -3154,6 +3155,242 @@ static int mov_read_elst(MOVContext *c, AVIOContext 
*pb, MOVAtom atom)
 return 0;
 }
 
+static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+AVStream *st;
+MOVStreamContext *sc;
+enum AVStereo3DType type;
+int mode;
+
+if (c->fc->nb_streams < 1)
+return 0;
+
+st = c->fc->streams[c->fc->nb_streams - 1];
+sc = st->priv_data;
+
+if (atom.size < 1) {
+av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
+return AVERROR_INVALIDDATA;
+}
+
+mode = avio_r8(pb);
+switch(mode) {
+case 0:
+type = AV_STEREO3D_2D;
+break;
+case 1:
+type = AV_STEREO3D_TOPBOTTOM;
+break;
+case 2:
+type = AV_STEREO3D_SIDEBYSIDE;
+break;
+default:
+av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
+return 0;
+}
+
+sc->stereo3d = av_stereo3d_alloc();
+if (!sc->stereo3d)
+return AVERROR(ENOMEM);
+
+sc->stereo3d->type = type;
+return 0;
+}
+
+static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+AVStream *st;
+MOVStreamContext *sc;
+int size;
+int32_t yaw, pitch, roll;
+uint32_t tag;
+enum AVSphericalType type;
+
+if (c->fc->nb_streams < 1)
+return 0;
+
+st = c->fc->streams[c->fc->nb_streams - 1];
+sc = st->priv_data;
+
+if (atom.size < 4) {
+av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
+return AVERROR_INVALIDDATA;
+}
+
+size = avio_rb32(pb);
+if (size > atom.size)
+return AVERROR_INVALIDDATA;
+
+tag = avio_rl32(pb);
+if (tag != MKTAG('s','v','h','d')) {
+av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
+return 0;
+}
+avio_skip(pb, size - 8); /* metadata_source */
+
+size = avio_rb32(pb);
+if (size > atom.size)
+return AVERROR_INVALIDDATA;
+
+tag = avio_rl32(pb);
+if (tag != MKTAG('p','r','o','j')) {
+av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
+return 0;
+}
+
+size = avio_rb32(pb);
+if (size > atom.size)
+return AVERROR_INVALIDDATA;
+
+tag = avio_rl32(pb);
+if (tag != MKTAG('p','r','h','d')) {
+av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
+return 0;
+}
+
+/* 16.16 fixed point */
+yaw   = avio_rb32(pb);
+pitch = avio_rb32(pb);
+roll  = avio_rb32(pb);
+
+avio_skip(pb, size - 20);
+
+size = avio_rb32(pb);
+if (size > atom.size)
+return AVERROR_INVALIDDATA;
+
+tag = avio_rl32(pb);
+switch(tag) {
+case MKTAG('c','b','m','p'):
+type = AV_SPHERICAL_CUBEMAP;
+break;
+case MKTAG('e','q','u','i'):
+type = AV_SPHERICAL_EQUIRECTANGULAR;
+break;
+case MKTAG('m','s','h','p'):
+type = AV_SPHERICAL_MESH;
+break;
+default:
+av_log(c->fc, AV_LOG_ERROR, "Unknown projection type\n");
+return 0;
+}
+
+sc->spherical = av_spherical_alloc(NULL);
+if (!sc->spherical)
+return AVERROR(ENOMEM);
+
+sc->spherical->type = type;
+
+sc->spherical->yaw   = ((double) yaw)   / (1 << 16);
+sc->spherical->pitch = ((double) pitch) / (1 << 16);
+sc->spherical->roll  = ((double) roll)  / (1 << 16);
+
+return 0;
+}
+
+static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, 
size_t len)
+{
+int ret = 0;
+uint8_t *buffer = av_malloc(len + 1);
+const char *val;
+
+if (!buffer)
+return AVERROR(ENOMEM);
+buffer[len] = '\0';
+
+ret = ffio_read_size(pb, buffer, len);
+if (ret < 0)
+goto out;
+
+/* Check for mandatory keys and values, try to support XML as best-effort 
*/
+if (av_stristr(buffer, "") &&
+(val = av_stristr(buffer, "")) &&
+av_stris