以下是初始化方法。它根据Apple QA1443从文件创建一个Movie结构,着眼于提取原始像素以进行处理。然后将其包装在QTMovie中 - sourceMovie = [QTMovie movieWithQuickTimeMovie: ...]
- 为方便起见。
初始化此类对象后,将调用第二个方法,并尝试使用sourceMovie
。但是,事实证明在此处访问sourceMovie的任何尝试会导致EXC_BAD_ACCESS例如,NSLog(@"%@", sourceMovie)
是不可能的。电影似乎已被解除分配,但目前尚不清楚原因。
此外,在第二种方法中,获取CVPixelBufferRef的常用方法无法正常运行:QTVisualContextIsNewImageAvailable似乎总是返回NO,而QTVisualContextCopyImageForTime总是为您提供指向0x00的imageBuffer。 (我想如果QTMovie,Movie或visualContext以某种方式被解除分配,这并不奇怪。)
那么问题是,为什么第二种方法无法访问sourceMovie
?是否正在取消分配?如果是这样,为什么?
现在是代码,并提前抱歉。
// From the .h, we have the following inst var declarations:
Movie myMovie;
QTMovie *sourceMovie;
QTVisualContextRef visualContext;
CVPixelBufferRef imageBuffer;
pixels_xy sourceSize;
MovieAnalyzer *analyzer;
// And now to the @implementation...
-(id)initWithFileString:(NSString *)file {
if (self = [super init]) {
NSError *e;
// Bit of a hack - get the movie size using temporary QTMovie.
sourceMovie = [QTMovie movieWithFile:file error:&e];
if (e) {
[self release];
NSLog(@"Could not open movie.");
return nil;
}
NSSize movieSize = [[sourceMovie posterImage] size];
CGRect bounds = CGRectMake(0, 0, movieSize.width, movieSize.height);
// Save the size in pixels.
sourceSize.x = (int)movieSize.width, sourceSize.y = (int)movieSize.height;
CFStringRef movieLocation = (CFStringRef) file;
// Get a QT Visual Context, and create a movie inialized to use it for output.
visualContext = NULL;
OSStatus status = CreatePixelBufferContext(k32ARGBPixelFormat, &bounds, &visualContext);
if (noErr != status && NULL == visualContext) {
[self release];
NSLog(@"Problem initializing QT Visual Context.");
return nil;
}
/*** Instantiate the Movie ***/
myMovie = NULL;
Boolean trueValue = true;
QTNewMoviePropertyElement newMovieProperties[3] = {0};
// Setup movie location
newMovieProperties[0].propClass = kQTPropertyClass_DataLocation;
newMovieProperties[0].propID = kQTDataLocationPropertyID_CFStringPosixPath;
newMovieProperties[0].propValueSize = sizeof(CFStringRef);
newMovieProperties[0].propValueAddress = &movieLocation;
// Assign the visual context - could also be NULL
newMovieProperties[1].propClass = kQTPropertyClass_Context;
newMovieProperties[1].propID = kQTContextPropertyID_VisualContext;
newMovieProperties[1].propValueSize = sizeof(visualContext);
newMovieProperties[1].propValueAddress = &visualContext;
// Make the movie active
newMovieProperties[2].propClass = kQTPropertyClass_NewMovieProperty;
newMovieProperties[2].propID = kQTNewMoviePropertyID_Active;
newMovieProperties[2].propValueSize = sizeof(trueValue);
newMovieProperties[2].propValueAddress = &trueValue;
status = NewMovieFromProperties(3, newMovieProperties, 0, NULL, &myMovie);
if (status != noErr || myMovie == NULL) {
NSLog(@"Problem initializing theMovie"); // problem
[self release];
return nil;
}
// Create a new QTMovie with the Movie as its backing object
sourceMovie = [QTMovie movieWithQuickTimeMovie:myMovie disposeWhenDone:NO error:&e];
if (e) {
NSLog(@"Could not initialize QTMovie from Movie.");
[self release];
return nil;
}
[sourceMovie stepForward];
analyzer = [[MovieAnalyzer alloc] initWithColorString:"BGRA" andSourceSize:sourceSize];
}
return self;
}
-(NSImage*) supplyCalibrationImage {
NSLog(@"%x", &sourceMovie);
[sourceMovie stepForward]; // This fails!
....
}
答案 0 :(得分:1)
[QTMovie movieWithQuickTimeMovie:disposeWhenDone:error:]
正在返回一张自动释放的电影。如果你希望它坚持使用这一种方法,你需要保留它。