aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorClément Bœsch <cboesch@gopro.com>2017-07-21 10:30:19 +0200
committerClément Bœsch <u@pkh.me>2017-07-24 14:43:40 +0200
commit850a45aef10b50a2344a71055a30987aea23e48a (patch)
treefa9aebdda85454e3ea09f20f681b4a80d3c926e1 /libavformat
parentf21457f8e0db369bd1624e9a17c84ad00b7ac40d (diff)
downloadffmpeg-850a45aef10b50a2344a71055a30987aea23e48a.tar.gz
lavf/movenc: support GPMF track (gpmd) remuxing
See https://github.com/gopro/gpmf-parser for more information on the data stream itself.
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/movenc.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 3989ac167e..0e5b45d150 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2060,6 +2060,18 @@ static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
return update_size(pb, pos);
}
+static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
+{
+ int64_t pos = avio_tell(pb);
+ avio_wb32(pb, 0); /* size */
+ ffio_wfourcc(pb, "gpmd");
+ avio_wb32(pb, 0); /* Reserved */
+ avio_wb16(pb, 0); /* Reserved */
+ avio_wb16(pb, 1); /* Data-reference index */
+ avio_wb32(pb, 0); /* Reserved */
+ return update_size(pb, pos);
+}
+
static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
@@ -2077,6 +2089,8 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
mov_write_rtp_tag(pb, track);
else if (track->par->codec_tag == MKTAG('t','m','c','d'))
mov_write_tmcd_tag(pb, track);
+ else if (track->par->codec_tag == MKTAG('g','p','m','d'))
+ mov_write_gpmd_tag(pb, track);
return update_size(pb, pos);
}
@@ -2377,6 +2391,12 @@ static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
ffio_wfourcc(pb, "tmcd");
mov_write_tcmi_tag(pb, track);
update_size(pb, tmcd_pos);
+ } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
+ int64_t gpmd_pos = avio_tell(pb);
+ avio_wb32(pb, 0); /* size */
+ ffio_wfourcc(pb, "gpmd");
+ avio_wb32(pb, 0); /* version */
+ update_size(pb, gpmd_pos);
}
return update_size(pb, pos);
}
@@ -2443,6 +2463,9 @@ static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
} else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
hdlr_type = "tmcd";
descr = "TimeCodeHandler";
+ } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
+ hdlr_type = "meta";
+ descr = "GoPro MET"; // GoPro Metadata
} else {
av_log(s, AV_LOG_WARNING,
"Unknown hldr_type for %s, writing dummy values\n",
@@ -2514,6 +2537,8 @@ static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
mov_write_nmhd_tag(pb);
else
mov_write_gmhd_tag(pb, track);
+ } else if (track->tag == MKTAG('g','p','m','d')) {
+ mov_write_gmhd_tag(pb, track);
}
if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
mov_write_hdlr_tag(s, pb, NULL);