@@ -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,
@@ -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