Adding support for writing spherical metadata in MP4 files.
From 8eb03f706e5c490be7a9644018dd3efaf0154a81 Mon Sep 17 00:00:00 2001 From: Aaron Colwell <acolw...@google.com> Date: Fri, 27 Jan 2017 10:07:44 -0800 Subject: [PATCH] movenc: Add support for writing st3d and sv3d boxes.
Adding support for writing spherical metadata in MP4 files. --- libavformat/movenc.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index dc19838ed6..aa9ee2cccd 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1603,6 +1603,92 @@ static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track) return update_size(pb, pos); } +static int mov_write_st3d_tag(AVIOContext *pb, AVStereo3D *stereo_3d) +{ + int8_t stereo_mode; + + if (stereo_3d->flags != 0) { + av_log(pb, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags); + return 0; + } + + switch (stereo_3d->type) { + case AV_STEREO3D_2D: + stereo_mode = 0; + break; + case AV_STEREO3D_TOPBOTTOM: + stereo_mode = 1; + break; + case AV_STEREO3D_SIDEBYSIDE: + stereo_mode = 2; + break; + default: + av_log(pb, AV_LOG_WARNING, "Unsupported stereo_3d type %d. st3d not written.\n", stereo_3d->type); + return 0; + } + avio_wb32(pb, 13); /* size */ + ffio_wfourcc(pb, "st3d"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_w8(pb, stereo_mode); + return 13; +} + +static int mov_write_sv3d_tag(AVIOContext *pb, AVSphericalMapping *spherical_mapping) +{ + int64_t sv3d_pos = avio_tell(pb); + int64_t svhd_pos, proj_pos; + + if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR && + spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) { + av_log(pb, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", + spherical_mapping->projection); + return 0; + } + + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "sv3d"); + + svhd_pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "svhd"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_put_str(pb, LIBAVFORMAT_IDENT); /* metadata_source */ + update_size(pb, svhd_pos); + + proj_pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "proj"); + + avio_wb32(pb, 24); /* size */ + ffio_wfourcc(pb, "prhd"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_wb32(pb, spherical_mapping->yaw); + avio_wb32(pb, spherical_mapping->pitch); + avio_wb32(pb, spherical_mapping->roll); + + switch (spherical_mapping->projection) { + case AV_SPHERICAL_EQUIRECTANGULAR: + avio_wb32(pb, 28); /* size */ + ffio_wfourcc(pb, "equi"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_wb32(pb, 0); /* projection_bounds_top */ + avio_wb32(pb, 0); /* projection_bounds_bottom */ + avio_wb32(pb, 0); /* projection_bounds_left */ + avio_wb32(pb, 0); /* projection_bounds_right */ + break; + case AV_SPHERICAL_CUBEMAP: + avio_wb32(pb, 20); /* size */ + ffio_wfourcc(pb, "cbmp"); + avio_wb32(pb, 0); /* version = 0 & flags = 0 */ + avio_wb32(pb, 0); /* layout */ + avio_wb32(pb, 0); /* padding */ + break; + } + update_size(pb, proj_pos); + + return update_size(pb, sv3d_pos); +} + static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track) { AVRational sar; @@ -1748,6 +1834,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr int64_t pos = avio_tell(pb); char compressor_name[32] = { 0 }; int avid = 0; + AVSphericalMapping* spherical_mapping; avio_wb32(pb, 0); /* size */ if (mov->encryption_scheme != MOV_ENC_NONE) { @@ -1873,6 +1960,14 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n"); } + spherical_mapping = (AVSphericalMapping*)av_stream_get_side_data(track->st, AV_PKT_DATA_SPHERICAL, NULL); + if (spherical_mapping) { + AVStereo3D* stereo_3d = (AVStereo3D*) av_stream_get_side_data(track->st, AV_PKT_DATA_STEREO3D, NULL); + if (stereo_3d) + mov_write_st3d_tag(pb, stereo_3d); + mov_write_sv3d_tag(pb, spherical_mapping); + } + if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) { mov_write_pasp_tag(pb, track); } -- 2.11.0.483.g087da7b7c-goog
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel