QTMovie при поддержке Movie работает изначально, но не другим способом - PullRequest
0 голосов
/ 01 июля 2010

Далее следует метод инициализатора. Он создает структуру фильма из файла с целью извлечения необработанных пикселей для обработки в соответствии с Apple QA1443 . Затем для удобства он оборачивается в QTMovie - sourceMovie = [QTMovie movieWithQuickTimeMovie: ...].

После инициализации такого объекта вызывается второй метод, и мы пытаемся использовать sourceMovie. Однако оказывается, что любая попытка доступа к sourceMovie здесь приводит к EXC_BAD_ACCESS. Например, NSLog(@"%@", sourceMovie) невозможна. Похоже, фильм был освобожден, хотя неясно, почему.

Кроме того, в этом втором методе обычные методы для получения CVPixelBufferRef не работают должным образом: QTVisualContextIsNewImageAvailable, кажется, всегда возвращает NO, а QTVisualContextCopyImageForTime всегда дает вам imageBuffer, указывающий на 0x00. (Я думаю, это не удивительно, если 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 Ответ

1 голос
/ 01 июля 2010

[QTMovie movieWithQuickTimeMovie:disposeWhenDone:error:] возвращает автоматически выпущенный фильм. Если вы хотите, чтобы он оставался позади этого одного метода, вам нужно сохранить его.

...