第二次读取双视频轨道电影时,copyNextSampleBuffer返回NULL

时间:2017-01-19 06:04:10

标签: objective-c avfoundation avasset avassetreader

我有一部有两个视频轨道的电影。我需要从交错的两个轨道中读取帧 - 即,轨道1中的一帧,然后是轨道2中的一帧,然后是轨道1,依此类推。 我正在使用带有两个AVAssetReaders的AVAsset来读取帧并且它可以工作;但是,如果我释放所有内容并再次尝试,则copyNextSampleBuffer会在第一帧返回null,并且错误为-11829(无法打开)。如果我尝试单轨电影,或者我尝试从同一部电影中只读一首曲目,就不会发生这种情况。

这是我的精简代码:

NSURL *url = /* url to movie */;
NSError *localError = nil;
AVAssetReader *assetReader[2];
AVAssetReaderOutput *assetReaderOutput[2];
NSDictionary *assetOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
NSDictionary *decompressionVideoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                                [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey,
                                                [NSDictionary dictionary], (id)kCVPixelBufferIOSurfacePropertiesKey,
                                                nil];
for (int loop = 0; loop < 2; ++loop)
{
    AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:assetOptions];
    float durationInSeconds = CMTimeGetSeconds(asset.duration);
    NSArray *videoTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    NSUInteger numTracks = [videoTracks count];
    float framesPerSecond = [videoTracks[0] nominalFrameRate];
    int numFrames = (int)(durationInSeconds * framesPerSecond);
    for (NSUInteger trackNum = 0; trackNum < numTracks; ++trackNum)
    {
        assetReader[trackNum] = [[AVAssetReader alloc] initWithAsset:asset error:&localError];
        assetReaderOutput[trackNum] = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTracks[trackNum] outputSettings:decompressionVideoSettings];
        [assetReader[trackNum] addOutput:assetReaderOutput[trackNum]];
        [assetReader[trackNum] startReading];
    }

    for (int frameNum = 0; frameNum < numFrames; ++frameNum)
    {
        for (int trackNum = 0; trackNum < numTracks; ++trackNum)
        {
            CMSampleBufferRef sampleBuffer = [assetReaderOutput[trackNum] copyNextSampleBuffer];
            if (sampleBuffer == NULL)
            {
                NSError *error = [assetReader[trackNum] error];
                /* Handle error */
            }
            else
            {
                CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
                if (imageBuffer && (CFGetTypeID(imageBuffer) == CVPixelBufferGetTypeID()))
                {
                    CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)imageBuffer;
                    CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
                    void* ptr = CVPixelBufferGetBaseAddress(pixelBuffer);
                    CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
                    /* Do something with ptr */
                }
                CFRelease(sampleBuffer);
                sampleBuffer = NULL;
            }
        }
    }

    [asset release];
    asset = nil;
    for (int trackNum = 0; trackNum < numTracks; ++trackNum)
    {
        [assetReader[trackNum] release];
        assetReader[trackNum] = nil;
        [assetReaderOutput[trackNum] release];
        assetReaderOutput[trackNum] = nil;
    }

    int userInput;
    scanf("%i", &userInput);
}

所以在外循环的第二次迭代中,我在第一个轨道的第一帧上得到句柄错误代码。需要明确的是,例如,如果我替换了行

,就不会发生这种情况
NSUInteger numTracks = [videoTracks count];

NSUInteger numTracks = 1;

有什么想法吗? 这可能与this(尚未回答)问题有关。

0 个答案:

没有答案