+static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
+{
+ const uint8_t *side_data;
+ const AVContentLightMetadata *content_light_metadata;
+
+ side_data = av_stream_get_side_data(track->st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL, NULL);
+ if (!side_data) {
+ return 0;
+ }
+ content_light_metadata = (const AVContentLightMetadata*)side_data;
+
+ avio_wb32(pb, 12); // size
+ ffio_wfourcc(pb, "clli");
+ avio_wb16(pb, content_light_metadata->MaxCLL);
+ avio_wb16(pb, content_light_metadata->MaxFALL);
+ return 12;
+}
+
+static inline int64_t rescale_mdcv(AVRational q, int b)
+{
+ return av_rescale(q.num, b, q.den);
+}
+
+static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
+{
+ const int chroma_den = 50000;
+ const int luma_den = 10000;
+ const uint8_t *side_data;
+ const AVMasteringDisplayMetadata *metadata;
+
+ side_data = av_stream_get_side_data(track->st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL);
+ metadata = (const AVMasteringDisplayMetadata*)side_data;
+ if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
+ return 0;
+ }
+
+ avio_wb32(pb, 32); // size
+ ffio_wfourcc(pb, "mdcv");
+ avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][0], chroma_den));
+ avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][1], chroma_den));
+ avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][0], chroma_den));
+ avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][1], chroma_den));
+ avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][0], chroma_den));
+ avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][1], chroma_den));
+ avio_wb16(pb, rescale_mdcv(metadata->white_point[0], chroma_den));
+ avio_wb16(pb, rescale_mdcv(metadata->white_point[1], chroma_den));
+ avio_wb32(pb, rescale_mdcv(metadata->max_luminance, luma_den));
+ avio_wb32(pb, rescale_mdcv(metadata->min_luminance, luma_den));
+ return 32;
+}
+