aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/movenc.c
diff options
context:
space:
mode:
authorJan Ekström <jan.ekstrom@24i.com>2021-07-15 09:57:48 +0300
committerJan Ekström <jeebjp@gmail.com>2021-10-04 17:55:27 +0300
commit7a446b1179301b6b9d05a7d39574e75e8fa5a862 (patch)
tree543651142a0d40eb59d970c2c450a612a51f690b /libavformat/movenc.c
parent847fd8de7c13abe41ca59464014f17c56555ef7b (diff)
downloadffmpeg-7a446b1179301b6b9d05a7d39574e75e8fa5a862.tar.gz
avformat/{isom,mov,movenc}: add support for CMAF DASH roles
This information is coded in a standard MP4 KindBox and utilizes the scheme and values as per the DASH role scheme defined in MPEG-DASH. Other schemes are technically allowed, but where multiple schemes define the same concepts, the DASH scheme should be utilized. Such flagging is additionally utilized by the DASH-IF CMAF ingest specification, enabling an encoder to inform the following component of the roles of the incoming media streams. A test is added for this functionality in a similar manner to the matroska test. Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r--libavformat/movenc.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 1a2f24c410..d43a086f4b 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3322,6 +3322,52 @@ static int mov_write_track_metadata(AVIOContext *pb, AVStream *st,
return update_size(pb, pos);
}
+static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
+ const char *value)
+{
+ int64_t pos = avio_tell(pb);
+
+ /* Box|FullBox basics */
+ avio_wb32(pb, 0); /* size placeholder */
+ ffio_wfourcc(pb, (const unsigned char *)"kind");
+ avio_w8(pb, 0); /* version = 0 */
+ avio_wb24(pb, 0); /* flags = 0 */
+
+ /* Required null-terminated scheme URI */
+ avio_write(pb, (const unsigned char *)scheme_uri,
+ strlen(scheme_uri));
+ avio_w8(pb, 0);
+
+ /* Optional value string */
+ if (value && value[0])
+ avio_write(pb, (const unsigned char *)value,
+ strlen(value));
+
+ avio_w8(pb, 0);
+
+ return update_size(pb, pos);
+}
+
+static int mov_write_track_kinds(AVIOContext *pb, AVStream *st)
+{
+ int ret = AVERROR_BUG;
+
+ for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
+ const struct MP4TrackKindMapping map = ff_mov_track_kind_table[i];
+
+ for (int j = 0; map.value_maps[j].disposition; j++) {
+ const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
+ if (!(st->disposition & value_map.disposition))
+ continue;
+
+ if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
AVStream *st)
{
@@ -3339,6 +3385,11 @@ static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
if (mov->mode & (MODE_MP4|MODE_MOV))
mov_write_track_metadata(pb_buf, st, "name", "title");
+ if (mov->mode & MODE_MP4) {
+ if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
+ return ret;
+ }
+
if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
avio_wb32(pb, size + 8);
ffio_wfourcc(pb, "udta");