Skip to content

Commit

Permalink
avformat: validate dovi config in muxers
Browse files Browse the repository at this point in the history
  • Loading branch information
gnattu committed Oct 21, 2024
1 parent 845992e commit 8e5841c
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ Index: FFmpeg/libavformat/movenc.c
===================================================================
--- FFmpeg.orig/libavformat/movenc.c
+++ FFmpeg/libavformat/movenc.c
@@ -8124,6 +8124,7 @@ static const AVCodecTag codec_mp4_tags[]
@@ -8128,6 +8128,7 @@ static const AVCodecTag codec_mp4_tags[]
{ AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
{ AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
{ AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
+ { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', 'e') },
{ AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
{ AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
{ AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
@@ -8137,6 +8138,7 @@ static const AVCodecTag codec_mp4_tags[]
@@ -8141,6 +8142,7 @@ static const AVCodecTag codec_mp4_tags[]
{ AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
{ AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
{ AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
Expand Down Expand Up @@ -117,16 +117,65 @@ Index: FFmpeg/libavformat/mpegtsenc.c
static int get_dvb_stream_type(AVFormatContext *s, AVStream *st)
{
MpegTSWrite *ts = s->priv_data;
@@ -803,7 +850,16 @@ static int mpegts_write_pmt(AVFormatCont
@@ -803,7 +850,65 @@ static int mpegts_write_pmt(AVFormatCont
} else if (stream_type == STREAM_TYPE_VIDEO_VC1) {
put_registration_descriptor(&q, MKTAG('V', 'C', '-', '1'));
} else if (stream_type == STREAM_TYPE_VIDEO_HEVC && s->strict_std_compliance <= FF_COMPLIANCE_NORMAL) {
- put_registration_descriptor(&q, MKTAG('H', 'E', 'V', 'C'));
+ const AVPacketSideData *sd = av_packet_side_data_get(st->codecpar->coded_side_data,
+ st->codecpar->nb_coded_side_data, AV_PKT_DATA_DOVI_CONF);
+ const AVDOVIDecoderConfigurationRecord *dovi = sd ? (const AVDOVIDecoderConfigurationRecord *)sd->data : NULL;
+ int is_dovi_config_valid = dovi != NULL;
+
+ if (dovi && dovi->bl_present_flag && s->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
+ if (dovi) {
+ switch (dovi->dv_level) {
+ case 4:
+ case 5:
+ case 7:
+ case 8:
+ if (st->codecpar->codec_id != AV_CODEC_ID_HEVC) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ default:
+ is_dovi_config_valid = 0;
+ break;
+ }
+
+ switch (dovi->dv_bl_signal_compatibility_id) {
+ case 1:
+ case 6:
+ if (st->codecpar->color_trc != AVCOL_TRC_SMPTE2084 ||
+ st->codecpar->color_primaries != AVCOL_PRI_BT2020 ||
+ st->codecpar->color_space != AVCOL_SPC_BT2020_NCL ||
+ st->codecpar->color_range != AVCOL_RANGE_MPEG ||
+ st->codecpar->format != AV_PIX_FMT_YUV420P10) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 2:
+ // Don't check range or color info for SDR base layer as a lot of them will set to unspecified
+ // And a lot of players assumes unspecified as BT709 in tv range
+ if (st->codecpar->format != AV_PIX_FMT_YUV420P) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 4:
+ if (st->codecpar->color_trc != AVCOL_TRC_ARIB_STD_B67 ||
+ st->codecpar->color_primaries != AVCOL_PRI_BT2020 ||
+ st->codecpar->color_space != AVCOL_SPC_BT2020_NCL ||
+ st->codecpar->color_range != AVCOL_RANGE_MPEG ||
+ st->codecpar->format != AV_PIX_FMT_YUV420P10) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ default:
+ // others are reserved value, don't check
+ break;
+ }
+ }
+
+ if (dovi && is_dovi_config_valid && dovi->bl_present_flag && s->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
+ if (put_dovi_descriptor(s, &q, dovi) < 0)
+ break;
+ } else {
Expand Down
204 changes: 204 additions & 0 deletions debian/patches/0078-validate-dovi-config-for-muxers.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
Index: FFmpeg/libavformat/movenc.c
===================================================================
--- FFmpeg.orig/libavformat/movenc.c
+++ FFmpeg/libavformat/movenc.c
@@ -2538,8 +2538,79 @@ static int mov_write_video_tag(AVFormatC
mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
if (spherical_mapping)
mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
- if (dovi)
- mov_write_dvcc_dvvc_tag(s, pb, (AVDOVIDecoderConfigurationRecord *)dovi->data);
+ if (dovi) {
+ AVDOVIDecoderConfigurationRecord* dovi_config = (AVDOVIDecoderConfigurationRecord *) dovi->data;
+ int is_dovi_config_valid = 1;
+ switch (dovi_config->dv_level) {
+ case 4:
+ case 5:
+ case 7:
+ case 8:
+ case 20:
+ if (track->par->codec_id != AV_CODEC_ID_HEVC) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 9:
+ if (track->par->codec_id != AV_CODEC_ID_H264) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 10:
+ if (track->par->codec_id != AV_CODEC_ID_AV1) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ default:
+ is_dovi_config_valid = 0;
+ break;
+ }
+
+ switch (dovi_config->dv_bl_signal_compatibility_id) {
+ case 0:
+ if (track->par->color_range != AVCOL_RANGE_JPEG ||
+ track->par->format != AV_PIX_FMT_YUV420P10 ||
+ !(track->tag == MKTAG('d', 'v', 'h', '1') ||
+ track->tag == MKTAG('d', 'v', 'h', 'e') ||
+ track->tag == MKTAG('d', 'a', 'v', '1'))) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 1:
+ case 6:
+ if (track->par->color_trc != AVCOL_TRC_SMPTE2084 ||
+ track->par->color_primaries != AVCOL_PRI_BT2020 ||
+ track->par->color_space != AVCOL_SPC_BT2020_NCL ||
+ track->par->color_range != AVCOL_RANGE_MPEG ||
+ track->par->format != AV_PIX_FMT_YUV420P10) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 2:
+ // Don't check range or color info for SDR base layer as a lot of them will set to unspecified
+ // And a lot of players assumes unspecified as BT709 in tv range
+ if (track->par->format != AV_PIX_FMT_YUV420P) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 4:
+ if (track->par->color_trc != AVCOL_TRC_ARIB_STD_B67 ||
+ track->par->color_primaries != AVCOL_PRI_BT2020 ||
+ track->par->color_space != AVCOL_SPC_BT2020_NCL ||
+ track->par->color_range != AVCOL_RANGE_MPEG ||
+ track->par->format != AV_PIX_FMT_YUV420P10) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ default:
+ // others are reserved value, don't check
+ break;
+ }
+
+ if (is_dovi_config_valid) {
+ mov_write_dvcc_dvvc_tag(s, pb, dovi_config);
+ }
+ }
}

if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
Index: FFmpeg/libavformat/matroskaenc.c
===================================================================
--- FFmpeg.orig/libavformat/matroskaenc.c
+++ FFmpeg/libavformat/matroskaenc.c
@@ -1719,28 +1719,96 @@ static void mkv_write_blockadditionmappi

dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
if (dovi->dv_profile <= 10) {
- ebml_master mapping;
- uint8_t buf[ISOM_DVCC_DVVC_SIZE];
- uint32_t type;
-
- uint64_t expected_size = (2 + 1 + (sizeof(DVCC_DVVC_BLOCK_TYPE_NAME) - 1))
- + (2 + 1 + 4) + (2 + 1 + ISOM_DVCC_DVVC_SIZE);
-
- if (dovi->dv_profile > 7) {
- type = MATROSKA_BLOCK_ADD_ID_TYPE_DVVC;
- } else {
- type = MATROSKA_BLOCK_ADD_ID_TYPE_DVCC;
+ int is_dovi_config_valid = 1;
+ switch (dovi->dv_level) {
+ case 4:
+ case 5:
+ case 7:
+ case 8:
+ case 20:
+ if (par->codec_id != AV_CODEC_ID_HEVC) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 9:
+ if (par->codec_id != AV_CODEC_ID_H264) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 10:
+ if (par->codec_id != AV_CODEC_ID_AV1) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ default:
+ is_dovi_config_valid = 0;
+ break;
}

- ff_isom_put_dvcc_dvvc(s, buf, dovi);
+ switch (dovi->dv_bl_signal_compatibility_id) {
+ case 0:
+ if (par->color_range != AVCOL_RANGE_JPEG ||
+ par->format != AV_PIX_FMT_YUV420P10 ||
+ !(par->codec_tag == MKTAG('d', 'v', 'h', '1') ||
+ par->codec_tag == MKTAG('d', 'v', 'h', 'e') ||
+ par->codec_tag == MKTAG('d', 'a', 'v', '1'))) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 1:
+ case 6:
+ if (par->color_trc != AVCOL_TRC_SMPTE2084 ||
+ par->color_primaries != AVCOL_PRI_BT2020 ||
+ par->color_space != AVCOL_SPC_BT2020_NCL ||
+ par->color_range != AVCOL_RANGE_MPEG ||
+ par->format != AV_PIX_FMT_YUV420P10) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 2:
+ // Don't check range or color info for SDR base layer as a lot of them will set to unspecified
+ // And a lot of players assumes unspecified as BT709 in tv range
+ if (par->format != AV_PIX_FMT_YUV420P) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ case 4:
+ if (par->color_trc != AVCOL_TRC_ARIB_STD_B67 ||
+ par->color_primaries != AVCOL_PRI_BT2020 ||
+ par->color_space != AVCOL_SPC_BT2020_NCL ||
+ par->color_range != AVCOL_RANGE_MPEG ||
+ par->format != AV_PIX_FMT_YUV420P10) {
+ is_dovi_config_valid = 0;
+ }
+ break;
+ default:
+ // others are reserved value, don't check
+ break;
+ }
+ if (is_dovi_config_valid) {
+ ebml_master mapping;
+ uint8_t buf[ISOM_DVCC_DVVC_SIZE];
+ uint32_t type;
+
+ uint64_t expected_size = (2 + 1 + (sizeof(DVCC_DVVC_BLOCK_TYPE_NAME) - 1))
+ + (2 + 1 + 4) + (2 + 1 + ISOM_DVCC_DVVC_SIZE);
+
+ if (dovi->dv_profile > 7) {
+ type = MATROSKA_BLOCK_ADD_ID_TYPE_DVVC;
+ } else {
+ type = MATROSKA_BLOCK_ADD_ID_TYPE_DVCC;
+ }

- mapping = start_ebml_master(pb, MATROSKA_ID_TRACKBLKADDMAPPING, expected_size);
+ ff_isom_put_dvcc_dvvc(s, buf, dovi);

- put_ebml_string(pb, MATROSKA_ID_BLKADDIDNAME, DVCC_DVVC_BLOCK_TYPE_NAME);
- put_ebml_uint(pb, MATROSKA_ID_BLKADDIDTYPE, type);
- put_ebml_binary(pb, MATROSKA_ID_BLKADDIDEXTRADATA, buf, sizeof(buf));
+ mapping = start_ebml_master(pb, MATROSKA_ID_TRACKBLKADDMAPPING, expected_size);

- end_ebml_master(pb, mapping);
+ put_ebml_string(pb, MATROSKA_ID_BLKADDIDNAME, DVCC_DVVC_BLOCK_TYPE_NAME);
+ put_ebml_uint(pb, MATROSKA_ID_BLKADDIDTYPE, type);
+ put_ebml_binary(pb, MATROSKA_ID_BLKADDIDEXTRADATA, buf, sizeof(buf));
+
+ end_ebml_master(pb, mapping);
+ }
}
#endif
}
1 change: 1 addition & 0 deletions debian/patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,4 @@
0075-allow-vpl-qsv-to-init-with-the-legacy-msdk-path.patch
0076-alway-set-videotoolboxenc-pixel-buffer-info.patch
0077-add-remove-dovi-hdr10plus-bsf.patch
0078-validate-dovi-config-for-muxers.patch

0 comments on commit 8e5841c

Please sign in to comment.