Don't request IDR frame if the HDR metadata change was a no-op

This commit is contained in:
Cameron Gutman
2023-03-04 12:11:33 -06:00
parent 64803d9715
commit bdb7d08c57
+26 -11
View File
@@ -376,14 +376,12 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
} }
- (void)setHdrMode:(BOOL)enabled { - (void)setHdrMode:(BOOL)enabled {
// Free old metadata
masteringDisplayColorVolume = nil;
contentLightLevelInfo = nil;
// Update metadata from host if provided
SS_HDR_METADATA hdrMetadata; SS_HDR_METADATA hdrMetadata;
if (enabled && LiGetHdrMetadata(&hdrMetadata)) {
if (hdrMetadata.displayPrimaries[0].x != 0 && hdrMetadata.maxDisplayLuminance != 0) { BOOL hasMetadata = enabled && LiGetHdrMetadata(&hdrMetadata);
BOOL metadataChanged = NO;
if (hasMetadata && hdrMetadata.displayPrimaries[0].x != 0 && hdrMetadata.maxDisplayLuminance != 0) {
// This data is all in big-endian // This data is all in big-endian
struct { struct {
vector_ushort2 primaries[3]; vector_ushort2 primaries[3];
@@ -407,10 +405,18 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
mdcv.luminance_max = __builtin_bswap32((uint32_t)hdrMetadata.maxDisplayLuminance * 10000); mdcv.luminance_max = __builtin_bswap32((uint32_t)hdrMetadata.maxDisplayLuminance * 10000);
mdcv.luminance_min = __builtin_bswap32(hdrMetadata.minDisplayLuminance); mdcv.luminance_min = __builtin_bswap32(hdrMetadata.minDisplayLuminance);
masteringDisplayColorVolume = [NSData dataWithBytes:&mdcv length:sizeof(mdcv)]; NSData* newMdcv = [NSData dataWithBytes:&mdcv length:sizeof(mdcv)];
if (masteringDisplayColorVolume == nil || ![newMdcv isEqualToData:masteringDisplayColorVolume]) {
masteringDisplayColorVolume = newMdcv;
metadataChanged = YES;
}
}
else if (masteringDisplayColorVolume != nil) {
masteringDisplayColorVolume = nil;
metadataChanged = YES;
} }
if (hdrMetadata.maxContentLightLevel != 0 && hdrMetadata.maxFrameAverageLightLevel != 0) { if (hasMetadata && hdrMetadata.maxContentLightLevel != 0 && hdrMetadata.maxFrameAverageLightLevel != 0) {
// This data is all in big-endian // This data is all in big-endian
struct { struct {
uint16_t max_content_light_level; uint16_t max_content_light_level;
@@ -420,12 +426,21 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit);
cll.max_content_light_level = __builtin_bswap16(hdrMetadata.maxContentLightLevel); cll.max_content_light_level = __builtin_bswap16(hdrMetadata.maxContentLightLevel);
cll.max_frame_average_light_level = __builtin_bswap16(hdrMetadata.maxFrameAverageLightLevel); cll.max_frame_average_light_level = __builtin_bswap16(hdrMetadata.maxFrameAverageLightLevel);
contentLightLevelInfo = [NSData dataWithBytes:&cll length:sizeof(cll)]; NSData* newCll = [NSData dataWithBytes:&cll length:sizeof(cll)];
if (contentLightLevelInfo == nil || ![newCll isEqualToData:contentLightLevelInfo]) {
contentLightLevelInfo = newCll;
metadataChanged = YES;
} }
} }
else if (contentLightLevelInfo != nil) {
contentLightLevelInfo = nil;
metadataChanged = YES;
}
// Request an IDR frame to trigger us to re-create the format with the adjusted metadata // If the metadata changed, request an IDR frame to re-create the CMVideoFormatDescription
if (metadataChanged) {
LiRequestIdrFrame(); LiRequestIdrFrame();
} }
}
@end @end