mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-04-19 23:10:18 +00:00
Don't request IDR frame if the HDR metadata change was a no-op
This commit is contained in:
@@ -376,56 +376,71 @@ 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);
|
||||||
// This data is all in big-endian
|
BOOL metadataChanged = NO;
|
||||||
struct {
|
|
||||||
vector_ushort2 primaries[3];
|
if (hasMetadata && hdrMetadata.displayPrimaries[0].x != 0 && hdrMetadata.maxDisplayLuminance != 0) {
|
||||||
vector_ushort2 white_point;
|
// This data is all in big-endian
|
||||||
uint32_t luminance_max;
|
struct {
|
||||||
uint32_t luminance_min;
|
vector_ushort2 primaries[3];
|
||||||
} __attribute__((packed, aligned(4))) mdcv;
|
vector_ushort2 white_point;
|
||||||
|
uint32_t luminance_max;
|
||||||
|
uint32_t luminance_min;
|
||||||
|
} __attribute__((packed, aligned(4))) mdcv;
|
||||||
|
|
||||||
// mdcv is in GBR order while SS_HDR_METADATA is in RGB order
|
// mdcv is in GBR order while SS_HDR_METADATA is in RGB order
|
||||||
mdcv.primaries[0].x = __builtin_bswap16(hdrMetadata.displayPrimaries[1].x);
|
mdcv.primaries[0].x = __builtin_bswap16(hdrMetadata.displayPrimaries[1].x);
|
||||||
mdcv.primaries[0].y = __builtin_bswap16(hdrMetadata.displayPrimaries[1].y);
|
mdcv.primaries[0].y = __builtin_bswap16(hdrMetadata.displayPrimaries[1].y);
|
||||||
mdcv.primaries[1].x = __builtin_bswap16(hdrMetadata.displayPrimaries[2].x);
|
mdcv.primaries[1].x = __builtin_bswap16(hdrMetadata.displayPrimaries[2].x);
|
||||||
mdcv.primaries[1].y = __builtin_bswap16(hdrMetadata.displayPrimaries[2].y);
|
mdcv.primaries[1].y = __builtin_bswap16(hdrMetadata.displayPrimaries[2].y);
|
||||||
mdcv.primaries[2].x = __builtin_bswap16(hdrMetadata.displayPrimaries[0].x);
|
mdcv.primaries[2].x = __builtin_bswap16(hdrMetadata.displayPrimaries[0].x);
|
||||||
mdcv.primaries[2].y = __builtin_bswap16(hdrMetadata.displayPrimaries[0].y);
|
mdcv.primaries[2].y = __builtin_bswap16(hdrMetadata.displayPrimaries[0].y);
|
||||||
|
|
||||||
mdcv.white_point.x = __builtin_bswap16(hdrMetadata.whitePoint.x);
|
mdcv.white_point.x = __builtin_bswap16(hdrMetadata.whitePoint.x);
|
||||||
mdcv.white_point.y = __builtin_bswap16(hdrMetadata.whitePoint.y);
|
mdcv.white_point.y = __builtin_bswap16(hdrMetadata.whitePoint.y);
|
||||||
|
|
||||||
// These luminance values are in 10000ths of a nit
|
// These luminance values are in 10000ths of a nit
|
||||||
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;
|
||||||
if (hdrMetadata.maxContentLightLevel != 0 && hdrMetadata.maxFrameAverageLightLevel != 0) {
|
metadataChanged = YES;
|
||||||
// This data is all in big-endian
|
|
||||||
struct {
|
|
||||||
uint16_t max_content_light_level;
|
|
||||||
uint16_t max_frame_average_light_level;
|
|
||||||
} __attribute__((packed, aligned(2))) cll;
|
|
||||||
|
|
||||||
cll.max_content_light_level = __builtin_bswap16(hdrMetadata.maxContentLightLevel);
|
|
||||||
cll.max_frame_average_light_level = __builtin_bswap16(hdrMetadata.maxFrameAverageLightLevel);
|
|
||||||
|
|
||||||
contentLightLevelInfo = [NSData dataWithBytes:&cll length:sizeof(cll)];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (masteringDisplayColorVolume != nil) {
|
||||||
|
masteringDisplayColorVolume = nil;
|
||||||
|
metadataChanged = YES;
|
||||||
|
}
|
||||||
|
|
||||||
// Request an IDR frame to trigger us to re-create the format with the adjusted metadata
|
if (hasMetadata && hdrMetadata.maxContentLightLevel != 0 && hdrMetadata.maxFrameAverageLightLevel != 0) {
|
||||||
LiRequestIdrFrame();
|
// This data is all in big-endian
|
||||||
|
struct {
|
||||||
|
uint16_t max_content_light_level;
|
||||||
|
uint16_t max_frame_average_light_level;
|
||||||
|
} __attribute__((packed, aligned(2))) cll;
|
||||||
|
|
||||||
|
cll.max_content_light_level = __builtin_bswap16(hdrMetadata.maxContentLightLevel);
|
||||||
|
cll.max_frame_average_light_level = __builtin_bswap16(hdrMetadata.maxFrameAverageLightLevel);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the metadata changed, request an IDR frame to re-create the CMVideoFormatDescription
|
||||||
|
if (metadataChanged) {
|
||||||
|
LiRequestIdrFrame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user