Quoting Vittorio Giovara (2016-11-01 20:23:35)
> This includes both versions of the spec, XML and mp4 box.
> 
> Signed-off-by: Vittorio Giovara <vittorio.giov...@gmail.com>
> ---
>  avprobe.c            |  20 ++++
>  libavcodec/avcodec.h |  44 ++++++++
>  libavformat/dump.c   |  28 ++++++
>  libavformat/isom.h   |   4 +
>  libavformat/mov.c    | 277 
> +++++++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 373 insertions(+)
> 
> diff --git a/avprobe.c b/avprobe.c
> index eff9c0d..474b325 100644
> --- a/avprobe.c
> +++ b/avprobe.c
> @@ -729,6 +729,7 @@ static void show_stream(InputFile *ifile, InputStream 
> *ist)
>          for (i = 0; i < stream->nb_side_data; i++) {
>              const AVPacketSideData* sd = &stream->side_data[i];
>              AVStereo3D *stereo;
> +            AVSphericalVideo *spherical;
>  
>              switch (sd->type) {
>              case AV_PKT_DATA_DISPLAYMATRIX:
> @@ -749,6 +750,25 @@ static void show_stream(InputFile *ifile, InputStream 
> *ist)
>                            !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
>                  probe_object_footer("stereo3d");
>                  break;
> +            case AV_PKT_DATA_SPHERICAL:
> +                spherical = (AVSphericalVideo *)sd->data;
> +                probe_object_header("spherical");
> +
> +                if (spherical->type == AV_SPHERICAL_EQUIRECTANGULAR)
> +                    probe_str("projection", "equirectangular");
> +                else if (spherical->type == AV_SPHERICAL_CUBEMAP)
> +                    probe_str("projection", "cubemap");
> +                else if (spherical->type == AV_SPHERICAL_MESH)
> +                    probe_str("projection", "mesh");
> +                else
> +                    probe_str("projection", "unknown");
> +
> +                probe_int("yaw", spherical->yaw);
> +                probe_int("pitch", spherical->pitch);
> +                probe_int("roll", spherical->roll);
> +
> +                probe_object_footer("spherical");
> +                break;
>              }
>          }
>          probe_object_footer("sidedata");
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 88e6c62..c301977 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -702,6 +702,44 @@ enum AVAudioServiceType {
>      AV_AUDIO_SERVICE_TYPE_NB                   , ///< Not part of ABI
>  };
>  
> +/**
> + * Video surface should be mapped on a sphere, and probably needs additional
> + * processing before it can be displayed.
> + */
> +enum AVSphericalType {
> +    AV_SPHERICAL_EQUIRECTANGULAR,
> +    AV_SPHERICAL_CUBEMAP,
> +    AV_SPHERICAL_MESH,
> +    AV_SPHERICAL_NB, ///< Not part of ABI

-ENEEDMOREDOCS

> +};
> +
> +/**
> + * @note Size of this struct is not part of ABI.
> + */
> +typedef struct AVSphericalVideo {

This needs a constructor. Cf. e.g. to the av_cpb_* API.

> +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)) && !sc->spherical) {
> +        size_t len = atom.size - sizeof(uuid);
> +        ret = mov_parse_uuid_spherical(sc, pb, len);
> +        if (ret < 0)
> +            return ret;
> +        if (!sc->spherical)
> +            av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata 
> found\n");
> +    } else {
> +        int i;
> +        av_log(c->fc, AV_LOG_WARNING, "Unknown UUID found: 0x");

Should this be a warning? It's just some unknown data we can safely
ignore, no? So verbose or debug.

> +        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 },
> @@ -3217,6 +3454,9 @@ 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('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
> +{ MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
> +{ MKTAG('u','u','i','d'), mov_read_uuid }, /* universal unique identifier */
>  { MKTAG('-','-','-','-'), mov_read_custom },
>  { 0, NULL }
>  };
> @@ -3445,6 +3685,9 @@ static int mov_read_close(AVFormatContext *s)
>              av_free(sc->extradata[j]);
>          av_freep(&sc->extradata);
>          av_freep(&sc->extradata_size);
> +
> +        av_freep(&sc->spherical);
> +        av_freep(&sc->stereo3d);
>      }
>  
>      if (mov->dv_demux) {
> @@ -3543,6 +3786,40 @@ 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;
> +            }
> +            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;
> +            }

nit: the three if() blocks here are pretty much identical, might be nice
to de-duplicate them a bit.

Also, missing apichanges+bump. And I'd split the part adding the new
API and actually making use of it.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to