[FFmpeg-devel] [PATCH v12 8/9] avformat/mxfdec: Workaround for RGB pc/video level detection.
Martin Schitter
ms+git at mur.at
Mon Oct 21 22:57:21 EEST 2024
In case of RGB content wrapped in MXF containers we can not use
CDCIDescriptor fields for the video level detection.
The corresponding information in RGBA Descriptors uses a significant
differnt structure. As a workaround we pick the first found channel
depth info value of the RGBALayout array and us it instead of the
more general CDCI component_depth.
---
libavformat/mxfdec.c | 51 +++++++++++++++++++++++++++++-------
tests/ref/fate/mxf-probe-j2k | 2 +-
2 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 27e8e0c..eb51585 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -212,6 +212,9 @@ typedef struct MXFDescriptor {
unsigned int component_depth;
unsigned int black_ref_level;
unsigned int white_ref_level;
+ uint32_t component_max_ref;
+ uint32_t component_min_ref;
+ uint8_t red_component_depth;
unsigned int color_range;
unsigned int horiz_subsampling;
unsigned int vert_subsampling;
@@ -1316,6 +1319,9 @@ static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor)
value = avio_r8(pb);
av_log(NULL, AV_LOG_TRACE, "pixel layout: code %#x\n", code);
+ if (code == 'R')
+ descriptor->red_component_depth = value;
+
if (ofs <= 14) {
layout[ofs++] = code;
layout[ofs++] = value;
@@ -1424,6 +1430,12 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
case 0x3401:
mxf_read_pixel_layout(pb, descriptor);
break;
+ case 0x3406:
+ descriptor->component_max_ref = avio_rb32(pb);
+ break;
+ case 0x3407:
+ descriptor->component_min_ref = avio_rb32(pb);
+ break;
default:
/* Private uid used by SONY C0023S01.mxf */
if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
@@ -2511,19 +2523,38 @@ static int mxf_add_metadata_stream(MXFContext *mxf, MXFTrack *track)
static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *descriptor)
{
- if (descriptor->black_ref_level || descriptor->white_ref_level || descriptor->color_range) {
+ unsigned int depth, black_ref_level, white_ref_level;
+
+ // The red channel component depth value of the
+ // RGBALayout array is used as component_depth indicator
+ // for the pc/tv level detection in case of RGB content
+ // and their RGBA Descriptors instead of CDCI entries.
+
+ if (descriptor->red_component_depth) { // RGBA Descriptor
+ depth = descriptor->red_component_depth;
+ black_ref_level = descriptor->component_min_ref;
+ white_ref_level = descriptor->component_max_ref;
+ } else { // CDCI Descriptor
+ depth = descriptor->component_depth;
+ black_ref_level = descriptor->black_ref_level;
+ white_ref_level = descriptor->white_ref_level;
+ }
+
+ if (black_ref_level || white_ref_level) {
/* CDCI range metadata */
- if (!descriptor->component_depth)
+ if (!depth)
return AVCOL_RANGE_UNSPECIFIED;
- if (descriptor->black_ref_level == 0 && descriptor->component_depth < 31 &&
- descriptor->white_ref_level == ((1<<descriptor->component_depth) - 1) &&
- (descriptor->color_range == (1<<descriptor->component_depth) ||
- descriptor->color_range == ((1<<descriptor->component_depth) - 1)))
+ if (black_ref_level == 0 && depth < 31 &&
+ white_ref_level == ((1 << depth) - 1) &&
+ (descriptor->red_component_depth ||
+ descriptor->color_range == (1 << descriptor->component_depth) ||
+ descriptor->color_range == ((1 << descriptor->component_depth) - 1)))
return AVCOL_RANGE_JPEG;
- if (descriptor->component_depth >= 8 && descriptor->component_depth < 31 &&
- 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))
+ if (depth >= 8 && depth < 31 &&
+ black_ref_level == (1 << (depth - 4)) &&
+ white_ref_level == (235 << (depth - 8)) &&
+ ( descriptor->red_component_depth ||
+ descriptor->color_range == ((14 << (descriptor->component_depth - 4))) + 1))
return AVCOL_RANGE_MPEG;
avpriv_request_sample(mxf->fc, "Unrecognized CDCI color range (color diff range %d, b %d, w %d, depth %d)",
descriptor->color_range, descriptor->black_ref_level,
diff --git a/tests/ref/fate/mxf-probe-j2k b/tests/ref/fate/mxf-probe-j2k
index f1dadf4..6287980 100644
--- a/tests/ref/fate/mxf-probe-j2k
+++ b/tests/ref/fate/mxf-probe-j2k
@@ -16,7 +16,7 @@ sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=rgb48
level=-99
-color_range=unknown
+color_range=pc
color_space=unknown
color_transfer=bt709
color_primaries=bt709
--
2.45.2
More information about the ffmpeg-devel
mailing list