OSX でビデオ ファイルをフレームごとに処理するコードを作成しました。以下は、正常にビルドされ、ファイルが開かれ、ビデオ トラック (トラックのみ) が特定され、問題なく CMSampleBuffers の読み取りが開始されるコードからの抜粋です。ただし、取得した各 CMSampleBufferRef は、ピクセル バッファー フレームを抽出しようとすると NULL を返します。iOS のドキュメントには、なぜ NULL の戻り値が期待できるのか、または問題をどのように修正できるのかについては示されていません。キャプチャ ソースや CODEC に関係なく、テストしたすべてのビデオで発生します。
どんな助けでも大歓迎です。
NSString *assetInPath = @"/Users/Dave/Movies/movie.mp4";
NSURL *assetInUrl = [NSURL fileURLWithPath:assetInPath];
AVAsset *assetIn = [AVAsset assetWithURL:assetInUrl];
NSError *error;
AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:assetIn error:&error];
AVAssetTrack *track = [assetIn.tracks objectAtIndex:0];
AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderTrackOutput alloc]
initWithTrack:track
outputSettings:nil];
[assetReader addOutput:assetReaderOutput];
// Start reading
[assetReader startReading];
CMSampleBufferRef sampleBuffer;
do {
sampleBuffer = [assetReaderOutput copyNextSampleBuffer];
/**
** At this point, sampleBuffer is non-null, has all appropriate attributes to indicate that
** it's a video frame, 320x240 or whatever and looks perfectly fine. But the next
** line always returns NULL without logging any obvious error message
**/
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
if( pixelBuffer != NULL ) {
size_t width = CVPixelBufferGetWidth(pixelBuffer);
size_t height = CVPixelBufferGetHeight(pixelBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
...
other processing removed here for clarity
}
} while( ... );
明確にするために、すべてのエラー チェック コードを取り除きましたが、そのコードには問題が示されていませんでした。つまり、AVAssetReader が読み取られている、CMSampleBufferRef が問題ないように見えるなどです。