summaryrefslogtreecommitdiff
path: root/SmartDeviceLink/public/SDLVideoStreamingRange.m
blob: d887e98c88a1d92b798ce5adae56a23815e4cea2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//
//  SDLVideoStreamingRange.m
//  SmartDeviceLink
//
//  Created on 6/11/20.
//

#import "SDLVideoStreamingRange.h"

#import "SDLError.h"
#import "SDLImageResolution+StreamingVideoExtensions.h"
#import "SDLLogMacros.h"

NS_ASSUME_NONNULL_BEGIN

@implementation SDLVideoStreamingRange

- (instancetype)init {
    return [self initWithMinimumResolution:[[SDLImageResolution alloc] initWithWidth:0.0 height:0.0] maximumResolution:[[SDLImageResolution alloc] initWithWidth:0.0 height:0.0]];
}

- (instancetype)initWithMinimumResolution:(nullable SDLImageResolution *)minResolution maximumResolution:(nullable SDLImageResolution *)maxResolution {
    return [self initWithMinimumResolution:minResolution maximumResolution:maxResolution minimumAspectRatio:1.0 maximumAspectRatio:9999.0 minimumDiagonal:0.0];
}

- (instancetype)initWithMinimumResolution:(nullable SDLImageResolution *)minResolution maximumResolution:(nullable SDLImageResolution *)maxResolution minimumAspectRatio:(float)minimumAspectRatio maximumAspectRatio:(float)maximumAspectRatio minimumDiagonal:(float)minimumDiagonal {
    self = [super init];
    if (!self) { return nil; }

    // Min must be below max, if this `if` passes, this is an invalid check, throw an exception.
    if ((minResolution != nil && maxResolution != nil) &&
        ((minResolution.resolutionWidth.floatValue > maxResolution.resolutionWidth.floatValue) ||
        (minResolution.resolutionHeight.floatValue > maxResolution.resolutionHeight.floatValue))) {
        SDLLogE(@"VideoStreamingRange minResolution is bigger than maxResolution (%@ <> %@)", minResolution, maxResolution);
        @throw [NSException sdl_invalidVideoStreamingRange];
    }

    _minimumResolution = minResolution;
    _maximumResolution = maxResolution;
    self.minimumDiagonal = minimumDiagonal;
    self.minimumAspectRatio = minimumAspectRatio;
    self.maximumAspectRatio = maximumAspectRatio;

    return self;
}

+ (instancetype)disabled {
    return [[self alloc] init];
}

#pragma mark - Setters

- (void)setMinimumAspectRatio:(float)minimumAspectRatio {
    if (minimumAspectRatio < 1.0) {
        _minimumAspectRatio = 1.0;
    } else {
        _minimumAspectRatio = minimumAspectRatio;
    }
}

- (void)setMaximumAspectRatio:(float)maximumAspectRatio {
    if (maximumAspectRatio < 1.0) {
        _maximumAspectRatio = 1.0;
    } else {
        _maximumAspectRatio = maximumAspectRatio;
    }
}

- (void)setMinimumDiagonal:(float)minimumDiagonal {
    if (minimumDiagonal < 0.0) {
        _minimumDiagonal = 0.0;
    } else {
        _minimumDiagonal = minimumDiagonal;
    }
}

#pragma mark - Instance Methods

- (BOOL)sdl_isImageResolutionRangeValid {
    return ((self.minimumResolution != nil) || (self.maximumResolution != nil));
}

- (BOOL)isImageResolutionInRange:(SDLImageResolution *)imageResolution {
    if (!imageResolution) {
        return NO;
    }
    if (![self sdl_isImageResolutionRangeValid]) {
        // no min & max resolutions - no restriction, no resolution pass
        return NO;
    }
    const CGSize size = imageResolution.makeSize;
    BOOL isAboveMin = YES;
    BOOL isBelowMax = YES;
    if (self.minimumResolution) {
        // is the size bigger than min? (no check if not set)
        const CGSize minSize = self.minimumResolution.makeSize;
        isAboveMin = ((size.width >= minSize.width) && (size.height >= minSize.height));
    }
    if (self.maximumResolution) {
        // is the size smaller than max? (no check if not set)
        const CGSize maxSize = self.maximumResolution.makeSize;
        isBelowMax = ((size.width <= maxSize.width) && (size.height <= maxSize.height));
    }
    return isAboveMin && isBelowMax;
}

- (BOOL)isAspectRatioInRange:(float)aspectRatio {
    if (self.minimumAspectRatio <= 1.f && self.maximumAspectRatio <= 1.f) {
        // min/max ratio not specified - any aspectRatio is OK
        return YES;
    }

    BOOL isInRange = YES;
    if (self.minimumAspectRatio >= 1.f) {
        isInRange = (aspectRatio >= self.minimumAspectRatio);
    }
    if (isInRange && (self.maximumAspectRatio >= 1.f)) {
        isInRange = (aspectRatio <= self.maximumAspectRatio);
    }
    return isInRange;
}

- (NSString *)description {
    NSString *strClass = NSStringFromClass(self.class);
    NSString *strRatio = [NSString stringWithFormat:@"ratio-min/max:[%2.2f/%2.2f]", self.minimumAspectRatio, self.maximumAspectRatio];
    NSString *strDiagonal = [NSString stringWithFormat:@"min-diagonal:%2.2f", self.minimumDiagonal];
    NSString *strResolution = [NSString stringWithFormat:@"resolution-min/max:[%@x%@/%@x%@]", self.minimumResolution.resolutionWidth, self.minimumResolution.resolutionHeight, self.maximumResolution.resolutionWidth, self.maximumResolution.resolutionHeight];
    return [NSString stringWithFormat:@"%@: {%@, %@, %@}", strClass, strRatio, strDiagonal, strResolution];
}

#pragma mark - NSCopying

- (id)copyWithZone:(nullable NSZone *)zone {
    typeof(self) aCopy = [[self.class allocWithZone:zone] init];
    // create a deep copy to prevent resolutions from outside update
    aCopy.minimumResolution = [self.minimumResolution copyWithZone:zone];
    aCopy.maximumResolution = [self.maximumResolution copyWithZone:zone];
    aCopy->_minimumAspectRatio = self->_minimumAspectRatio;
    aCopy->_maximumAspectRatio = self->_maximumAspectRatio;
    aCopy->_minimumDiagonal = self->_minimumDiagonal;
    return aCopy;
}

@end

NS_ASSUME_NONNULL_END