由电影支持的QTMovie最初工作,但不是另一种方法

时间:2010-06-30 21:17:37

标签: c objective-c cocoa memory-management quicktime

以下是初始化方法。它根据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!
    ....
}

1 个答案:

答案 0 :(得分:1)

[QTMovie movieWithQuickTimeMovie:disposeWhenDone:error:]正在返回一张自动释放的电影。如果你希望它坚持使用这一种方法,你需要保留它。