我有一部有两个视频轨道的电影。我需要从交错的两个轨道中读取帧 - 即,轨道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(尚未回答)问题有关。