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]];
63 // mappingとtrackNumberを変化させる。
66 CGRect frame = alayer.frame;
67 QTTime begin = QTMakeTime(frame.origin.x*DEFAULT_FPS/timeLineScale, DEFAULT_FPS);
68 QTTime d = QTMakeTime(frame.size.width*DEFAULT_FPS/timeLineScale, DEFAULT_FPS);
70 trackNumber = floor(frame.origin.y/51.0);
71 mapping = QTMakeTimeRange(begin, d);
74 - (void)changeOffset:(float)df
76 QTTime new_offset = QTTimeIncrement(offset, QTMakeTime(df*DEFAULT_FPS/timeLineScale, DEFAULT_FPS));
81 - (BOOL)canChangeMapping:(CGRect)rect
85 if([[media type] isEqualToString:@"image"])
86 duration = QTMakeTime(60*10, 1);
88 duration = [media duration];
90 QTTime wantDuration = QTMakeTime(rect.size.width*DEFAULT_FPS/timeLineScale, DEFAULT_FPS);
91 float d = convertQTTimeToSecond(duration) - convertQTTimeToSecond(offset);
92 float wd = convertQTTimeToSecond(wantDuration);
94 return 0.5 <= wd && wd <= d;
97 - (BOOL)canChangeOffset:(float)df
99 float now_offset = convertQTTimeToSecond(offset);
100 float duration = convertQTTimeToSecond([media duration]);
103 return 0.0 <= df + now_offset && df + now_offset <= duration;
106 - (BOOL)isInclude:(QTTime)time
108 float t = convertQTTimeToSecond(time);
109 float begin = convertQTTimeToSecond(mapping.time);
110 return begin <= t && t <= begin + convertQTTimeToSecond(mapping.duration);
111 // return QTTimeInTimeRange(time, mapping); // これだとマルチスレッドにできなくね?
119 - (void)setPositionX:(float)x forTime:(QTTime)time
122 [pxKeyframe setValueForTime:x time:time];
124 [pxKeyframe setValueForTime:x time:QTZeroTime];
127 - (void)setPositionY:(float)y forTime:(QTTime)time
130 [pyKeyframe setValueForTime:y time:time];
132 [pyKeyframe setValueForTime:y time:QTZeroTime];
135 - (CIImage*)getEffectedImage:(CVTimeStamp*)timeStamp forTime:(QTTime)time
137 QTTime innerTime = QTTimeDecrement(time, mapping.time);
138 CIImage* image = [media getFrameForTime:timeStamp];
139 if(image == nil) return nil;
141 return [self applyEffects:image forTime:QTTimeIncrement(innerTime, offset)];
144 - (CIImage*)getEffectedImageWithoutStamp:(QTTime)time
146 QTTime innerTime = QTTimeDecrement(time, mapping.time);
147 CIImage* image = [media getFrameForQTTime:QTTimeIncrement(innerTime, offset)];
148 if(image == nil) return nil;
150 return [self applyEffects:image forTime:QTTimeIncrement(innerTime, offset)];
153 - (CIImage*)applyEffects:(CIImage*)image forTime:(QTTime)time
155 int i, size = [effects count];
158 for(i = 0; i < size; i++){
159 ef = [effects objectAtIndex:i];
160 [ef setInputImage:image];
161 image = [ef getImage:time];
167 - (NSPoint)getPositionForTime:(QTTime)time
169 float x = [pxKeyframe getValueForTime:time];
170 float y = [pyKeyframe getValueForTime:time];
172 return NSMakePoint(x, y);
185 - (void)releaseContext
187 [media releaseContext];
190 - (QTTimeRange)mapping
195 - (void)seek:(QTTime)time
197 if([self isInclude:time]){
198 QTTime innerTime = QTTimeDecrement(time, mapping.time); // レイヤー内相対時間へ変換
199 [media setCurrentTime:QTTimeIncrement(innerTime, offset)];
201 [media setCurrentTime:offset];
206 // for Property Table
207 - (void)createPropertyTableDataSource:(NSMutableArray*)t_effects
208 property:(NSMutableArray*)t_propertyNames
209 value:(NSMutableArray*)t_valueNames
211 NSMutableDictionary* params;
213 NSString* paramName, *effectName;
216 [t_propertyNames addObject:@"Position X"];
217 [t_effects addObject:self];
218 [t_valueNames addObject:@""];
219 [t_propertyNames addObject:@"Position Y"];
220 [t_effects addObject:self];
221 [t_valueNames addObject:@""];
223 int i, size = [effects count];
224 for(i = 0; i < size; i++){
225 params = [[effects objectAtIndex:i] getParamDictionary];
226 arr = [params allKeys];
227 arr = [arr sortedArrayUsingSelector:@selector(compare:)];
228 effectName = [[effects objectAtIndex:i] getName];
229 for(paramName in arr){
230 [t_propertyNames addObject:[NSString stringWithFormat:@"%@ %@", effectName, [paramName substringFromIndex:5]]];
231 [t_effects addObject:[effects objectAtIndex:i]];
232 [t_valueNames addObject:paramName];
237 - (QTTime)convertToInnnerTime:(QTTime)globalTime
239 return QTTimeIncrement(QTTimeDecrement(globalTime, mapping.time), offset);
242 - (QTTime)plusOffsetTime:(QTTime)time
244 return QTTimeIncrement(time, offset);
249 [alayer removeObserver:self forKeyPath:@"frame"];
253 - (void)removePositionXKeyframe
255 pxKeyframe = [[ElisKeyframe alloc] init];
256 [pxKeyframe setValueForTime:0.0 time:QTZeroTime];
259 - (void)removePositionYKerframe
261 pyKeyframe = [[ElisKeyframe alloc] init];
262 [pyKeyframe setValueForTime:0.0 time:QTZeroTime];
265 - (void)removeEffect:(ElisEffect*)ef
267 [effects removeObject:ef];
270 - (void)getSoundTrack:(NSMutableArray*)soundTrack
273 t = [media getSoundTrack];
275 [soundTrack addObject:t];
276 [soundTrack addObject:[NSValue valueWithQTTime:offset]];
277 [soundTrack addObject:[NSValue valueWithQTTimeRange:mapping]];
281 - (void)encodeWithCoder:(NSCoder*)encoder
283 [encoder encodeObject:media forKey:@"media"];
284 [encoder encodeInt:trackNumber forKey:@"trackNumber"];
285 [encoder encodeObject:QTStringFromTimeRange(mapping) forKey:@"mapping"];
286 [encoder encodeObject:QTStringFromTime(offset) forKey:@"offset"];
287 [encoder encodeObject:effects forKey:@"effects"];
288 [encoder encodeObject:pxKeyframe forKey:@"pxKerframe"];
289 [encoder encodeObject:pyKeyframe forKey:@"pyKeyframe"];
291 NSLog(@"encoding layer");
294 - (id)initWithCoder:(NSCoder*)coder
296 media = [coder decodeObjectForKey:@"media"];
297 trackNumber = [coder decodeIntForKey:@"trackNumber"];
298 mapping = QTTimeRangeFromString([coder decodeObjectForKey:@"mapping"]);
299 offset = QTTimeFromString([coder decodeObjectForKey:@"offset"]);
300 effects = [coder decodeObjectForKey:@"effects"];
301 pxKeyframe = [coder decodeObjectForKey:@"pxKeyframe"];
302 pyKeyframe = [coder decodeObjectForKey:@"pyKeyframe"];
304 NSLog(@"decoding layer");
309 - (void)setLayer:(CALayer*)layer
311 layer.frame = CGRectMake(convertQTTimeToSecond(mapping.time)*timeLineScale, trackNumber*51+1,
312 (convertQTTimeToSecond(mapping.time) + convertQTTimeToSecond(mapping.duration))*timeLineScale, 50);
313 [self setAlayer:layer];
318 return convertQTTimeToSecond(mapping.time) + convertQTTimeToSecond(mapping.duration);
323 return [[media path] lastPathComponent];