Message ID | E97D56BD-9E0C-45A1-A69C-EF16C5185117@codex.online |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel,v3] avformat/mxfdec: Read video range from PictureDescriptor | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/make | success | Make finished |
andriy/make_fate | success | Make fate finished |
ons 2020-08-12 klockan 13:43 +0100 skrev Harry Mallon: > @@ -2492,6 +2504,18 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) > } > if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den) > st->display_aspect_ratio = descriptor->aspect_ratio; > + if (descriptor->component_depth && > + descriptor->black_ref_level == 0 && > + descriptor->white_ref_level == ((1<<descriptor->component_depth) - 1) && > + descriptor->color_range == ((1<<descriptor->component_depth) - 1)) { > + st->codecpar->color_range = AVCOL_RANGE_JPEG; > + } > + else if (descriptor->component_depth >= 8 && > + descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) && > + descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) && > + descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1)) { > + st->codecpar->color_range = AVCOL_RANGE_MPEG; > + } Put a warning here in case levels are set but neither of these two ifs are true, perhaps using avpriv_request_sample(). I can imagine there's encoders that put off-by-one values in here. I'd like to see such files first though before we widen these if clauses, so we can put the samples in FATE. I'm testing the previous patch. Will push that one once FATE passes. /Tomas
> On 12 Aug 2020, at 14:59, Tomas Härdin <tjoppen@acc.umu.se> wrote: > > ons 2020-08-12 klockan 13:43 +0100 skrev Harry Mallon: >> @@ -2492,6 +2504,18 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) >> } >> if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den) >> st->display_aspect_ratio = descriptor->aspect_ratio; >> + if (descriptor->component_depth && >> + descriptor->black_ref_level == 0 && >> + descriptor->white_ref_level == ((1<<descriptor->component_depth) - 1) && >> + descriptor->color_range == ((1<<descriptor->component_depth) - 1)) { >> + st->codecpar->color_range = AVCOL_RANGE_JPEG; >> + } >> + else if (descriptor->component_depth >= 8 && >> + descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) && >> + descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) && >> + descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1)) { >> + st->codecpar->color_range = AVCOL_RANGE_MPEG; >> + } > > Put a warning here in case levels are set but neither of these two ifs > are true, perhaps using avpriv_request_sample(). I can imagine there's > encoders that put off-by-one values in here. I'd like to see such files > first though before we widen these if clauses, so we can put the > samples in FATE. > > I'm testing the previous patch. Will push that one once FATE passes. > > /Tomas > Thanks Tomas, here is an updated V4 From 5866d0dc5536a6ea3f6a899c3d09f19df083c16a Mon Sep 17 00:00:00 2001 From: Harry Mallon <harry.mallon@codex.online> Date: Wed, 12 Aug 2020 10:26:23 +0100 Subject: [PATCH v4] avformat/mxfdec: Read video range from PictureDescriptor * Capture black_ref, white_ref and color_range and recognise full and narrow range. Signed-off-by: Harry Mallon <harry.mallon@codex.online> --- libavformat/mxfdec.c | 29 +++++++++++++++++++++++++++++ tests/ref/fate/mxf-probe-dnxhd | 2 +- tests/ref/fate/mxf-probe-dv25 | 2 +- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 4b56984b77..0831ad5768 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -199,6 +199,9 @@ typedef struct MXFDescriptor { int bits_per_sample; int64_t duration; /* ContainerDuration optional property */ unsigned int component_depth; + unsigned int black_ref_level; + unsigned int white_ref_level; + unsigned int color_range; unsigned int horiz_subsampling; unsigned int vert_subsampling; UID *sub_descriptors_refs; @@ -1222,6 +1225,15 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int case 0x3302: descriptor->horiz_subsampling = avio_rb32(pb); break; + case 0x3304: + descriptor->black_ref_level = avio_rb32(pb); + break; + case 0x3305: + descriptor->white_ref_level = avio_rb32(pb); + break; + case 0x3306: + descriptor->color_range = avio_rb32(pb); + break; case 0x3308: descriptor->vert_subsampling = avio_rb32(pb); break; @@ -2492,6 +2504,23 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) } if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den) st->display_aspect_ratio = descriptor->aspect_ratio; + if (descriptor->component_depth && + descriptor->black_ref_level == 0 && + descriptor->white_ref_level == ((1<<descriptor->component_depth) - 1) && + descriptor->color_range == ((1<<descriptor->component_depth) - 1)) { + st->codecpar->color_range = AVCOL_RANGE_JPEG; + } + else if (descriptor->component_depth >= 8 && + descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) && + descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) && + descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1)) { + st->codecpar->color_range = AVCOL_RANGE_MPEG; + } + else if (descriptor->black_ref_level || descriptor->white_ref_level || descriptor->color_range) { + avpriv_request_sample(mxf->fc, "Unrecognized color range (range %d, b %d, w %d, depth %d)", + descriptor->color_range, descriptor->black_ref_level, + descriptor->white_ref_level, descriptor->component_depth); + } st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id; st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id; st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id; diff --git a/tests/ref/fate/mxf-probe-dnxhd b/tests/ref/fate/mxf-probe-dnxhd index 012d3ea1d9..5a6221b1d5 100644 --- a/tests/ref/fate/mxf-probe-dnxhd +++ b/tests/ref/fate/mxf-probe-dnxhd @@ -124,7 +124,7 @@ sample_aspect_ratio=1:1 display_aspect_ratio=4:3 pix_fmt=yuv422p level=-99 -color_range=unknown +color_range=tv color_space=bt709 color_transfer=bt709 color_primaries=bt709 diff --git a/tests/ref/fate/mxf-probe-dv25 b/tests/ref/fate/mxf-probe-dv25 index 810f145f41..ffd26c4dfd 100644 --- a/tests/ref/fate/mxf-probe-dv25 +++ b/tests/ref/fate/mxf-probe-dv25 @@ -16,7 +16,7 @@ sample_aspect_ratio=16:15 display_aspect_ratio=4:3 pix_fmt=yuv420p level=-99 -color_range=unknown +color_range=tv color_space=unknown color_transfer=bt470m color_primaries=unknown
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 4b56984b77..172210acfe 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -199,6 +199,9 @@ typedef struct MXFDescriptor { int bits_per_sample; int64_t duration; /* ContainerDuration optional property */ unsigned int component_depth; + unsigned int black_ref_level; + unsigned int white_ref_level; + unsigned int color_range; unsigned int horiz_subsampling; unsigned int vert_subsampling; UID *sub_descriptors_refs; @@ -1222,6 +1225,15 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int case 0x3302: descriptor->horiz_subsampling = avio_rb32(pb); break; + case 0x3304: + descriptor->black_ref_level = avio_rb32(pb); + break; + case 0x3305: + descriptor->white_ref_level = avio_rb32(pb); + break; + case 0x3306: + descriptor->color_range = avio_rb32(pb); + break; case 0x3308: descriptor->vert_subsampling = avio_rb32(pb); break; @@ -2492,6 +2504,18 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) } if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den) st->display_aspect_ratio = descriptor->aspect_ratio; + if (descriptor->component_depth && + descriptor->black_ref_level == 0 && + descriptor->white_ref_level == ((1<<descriptor->component_depth) - 1) && + descriptor->color_range == ((1<<descriptor->component_depth) - 1)) { + st->codecpar->color_range = AVCOL_RANGE_JPEG; + } + else if (descriptor->component_depth >= 8 && + descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) && + descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) && + descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1)) { + st->codecpar->color_range = AVCOL_RANGE_MPEG; + } st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id; st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id; st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id; diff --git a/tests/ref/fate/mxf-probe-dnxhd b/tests/ref/fate/mxf-probe-dnxhd index 012d3ea1d9..5a6221b1d5 100644 --- a/tests/ref/fate/mxf-probe-dnxhd +++ b/tests/ref/fate/mxf-probe-dnxhd @@ -124,7 +124,7 @@ sample_aspect_ratio=1:1 display_aspect_ratio=4:3 pix_fmt=yuv422p level=-99 -color_range=unknown +color_range=tv color_space=bt709 color_transfer=bt709 color_primaries=bt709 diff --git a/tests/ref/fate/mxf-probe-dv25 b/tests/ref/fate/mxf-probe-dv25 index 810f145f41..ffd26c4dfd 100644 --- a/tests/ref/fate/mxf-probe-dv25 +++ b/tests/ref/fate/mxf-probe-dv25 @@ -16,7 +16,7 @@ sample_aspect_ratio=16:15 display_aspect_ratio=4:3 pix_fmt=yuv420p level=-99 -color_range=unknown +color_range=tv color_space=unknown color_transfer=bt470m color_primaries=unknown