5 // Created by 柳 on 09/09/12.
6 // Copyright 2009 __MyCompanyName__. All rights reserved.
11 static float convertQTTimeToSecond(QTTime t)
13 return (float)t.timeValue/t.timeScale;
16 @implementation ElisLayer
26 effects = [[NSMutableArray alloc] init];
27 pxKeyframe = [[ElisKeyframe alloc] init];
28 pyKeyframe = [[ElisKeyframe alloc] init];
29 [pxKeyframe setValueForTime:0.0 time:QTZeroTime];
30 [pyKeyframe setValueForTime:0.0 time:QTZeroTime];
32 [self addEffect:@"CIOpacity"]; //デフォルトで透過度フィルタと
33 // [self addEffect:@"CILanczosScaleTransform"]; // 拡大縮小フィルタと
34 [self addEffect:@"CIAffineTransform"]; // アフィン変換フィルタはつけておく。
40 - (void)setAlayer:(CALayer *)layer
44 [layer setValue:self forKey:@"ElisLayer"];
47 [layer addObserver:self
49 options:(NSKeyValueObservingOptionNew)
53 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
58 - (void)addEffect:(NSString*)name
60 [effects addObject:[[ElisEffect alloc] initWithName:name]];
65 CGRect frame = alayer.frame;
66 QTTime begin = QTMakeTime(frame.origin.x*DEFAULT_FPS/timeLineScale, DEFAULT_FPS);
67 QTTime d = QTMakeTime(frame.size.width*DEFAULT_FPS/timeLineScale, DEFAULT_FPS);
69 trackNumber = floor(frame.origin.y/51.0);
70 mapping = QTMakeTimeRange(begin, d);
72 // mappingとtrackNumberを変化させる。
75 - (void)changeOffset:(float)df
77 QTTime new_offset = QTTimeIncrement(offset, QTMakeTime(df*DEFAULT_FPS/timeLineScale, DEFAULT_FPS));
82 - (BOOL)canChangeMapping:(CGRect)rect
84 QTTime duration = [media duration];
85 QTTime wantDuration = QTMakeTime(rect.size.width*DEFAULT_FPS/timeLineScale, DEFAULT_FPS);
86 float d = convertQTTimeToSecond(duration) - convertQTTimeToSecond(offset);
87 float wd = convertQTTimeToSecond(wantDuration);
89 return 0.5 <= wd && wd <= d;
92 - (BOOL)canChangeOffset:(float)df
94 float now_offset = convertQTTimeToSecond(offset);
95 float duration = convertQTTimeToSecond([media duration]);
98 return 0.0 <= df + now_offset && df + now_offset <= duration;
101 - (BOOL)isInclude:(QTTime)time
103 float t = convertQTTimeToSecond(time);
104 float begin = convertQTTimeToSecond(mapping.time);
105 return begin <= t && t <= begin + convertQTTimeToSecond(mapping.duration);
106 // return QTTimeInTimeRange(time, mapping); // これだとマルチスレッドにできなくね?
114 - (void)setPositionX:(float)x forTime:(QTTime)time
117 [pxKeyframe setValueForTime:x time:time];
119 [pxKeyframe setValueForTime:x time:QTZeroTime];
122 - (void)setPositionY:(float)y forTime:(QTTime)time
125 [pyKeyframe setValueForTime:y time:time];
127 [pyKeyframe setValueForTime:y time:QTZeroTime];
130 - (CIImage*)getEffectedImage:(CVTimeStamp*)timeStamp forTime:(QTTime)time
132 QTTime innerTime = QTTimeDecrement(time, mapping.time);
133 CIImage* image = [media getFrameForTime:timeStamp];
134 if(image == nil) return nil;
136 return [self applyEffects:image forTime:QTTimeIncrement(innerTime, offset)];
139 - (CIImage*)getEffectedImageWithoutStamp:(QTTime)time
141 QTTime innerTime = QTTimeDecrement(time, mapping.time);
142 CIImage* image = [media getFrameForQTTime:QTTimeIncrement(innerTime, offset)];
143 if(image == nil) return nil;
145 return [self applyEffects:image forTime:QTTimeIncrement(innerTime, offset)];
148 - (CIImage*)applyEffects:(CIImage*)image forTime:(QTTime)time
150 int i, size = [effects count];
153 for(i = 0; i < size; i++){
154 ef = [effects objectAtIndex:i];
155 [ef setInputImage:image];
156 image = [ef getImage:time];
162 - (NSPoint)getPositionForTime:(QTTime)time
164 float x = [pxKeyframe getValueForTime:time];
165 float y = [pyKeyframe getValueForTime:time];
167 return NSMakePoint(x, y);
180 - (void)releaseContext
182 [media releaseContext];
185 - (QTTimeRange)mapping
190 - (void)seek:(QTTime)time
192 if([self isInclude:time]){
193 QTTime innerTime = QTTimeDecrement(time, mapping.time); // レイヤー内相対時間へ変換
194 [media setCurrentTime:QTTimeIncrement(innerTime, offset)];
196 [media setCurrentTime:offset];
201 // for Property Table
202 - (void)createPropertyTableDataSource:(NSMutableArray*)t_effects
203 property:(NSMutableArray*)t_propertyNames
204 value:(NSMutableArray*)t_valueNames
206 NSMutableDictionary* params;
208 NSString* paramName, *effectName;
211 [t_propertyNames addObject:@"Position X"];
212 [t_effects addObject:self];
213 [t_valueNames addObject:@""];
214 [t_propertyNames addObject:@"Position Y"];
215 [t_effects addObject:self];
216 [t_valueNames addObject:@""];
218 int i, size = [effects count];
219 for(i = 0; i < size; i++){
220 params = [[effects objectAtIndex:i] getParamDictionary];
221 arr = [params allKeys];
222 arr = [arr sortedArrayUsingSelector:@selector(compare:)];
223 effectName = [[effects objectAtIndex:i] getName];
224 for(paramName in arr){
225 [t_propertyNames addObject:[NSString stringWithFormat:@"%@ %@", effectName, [paramName substringFromIndex:5]]];
226 [t_effects addObject:[effects objectAtIndex:i]];
227 [t_valueNames addObject:paramName];
232 - (QTTime)convertToInnnerTime:(QTTime)globalTime
234 return QTTimeIncrement(QTTimeDecrement(globalTime, mapping.time), offset);
237 - (QTTime)plusOffsetTime:(QTTime)time
239 return QTTimeIncrement(time, offset);
244 [alayer removeObserver:self forKeyPath:@"frame"];
248 - (void)removePositionXKeyframe
250 pxKeyframe = [[ElisKeyframe alloc] init];
251 [pxKeyframe setValueForTime:0.0 time:QTZeroTime];
254 - (void)removePositionYKerframe
256 pyKeyframe = [[ElisKeyframe alloc] init];
257 [pyKeyframe setValueForTime:0.0 time:QTZeroTime];
260 - (void)removeEffect:(ElisEffect*)ef
262 [effects removeObject:ef];