2013-05-31 44 views
5

我已經建立了一些代碼,通過幀處理OSX上的視頻文件,幀。以下是構建OK的代碼提取,打開文件,找到視頻軌道(僅軌道),並開始閱讀CMSampleBuffers沒有問題。但是,當我嘗試提取像素緩衝區框架時,獲取的每個CMSampleBufferRef都返回NULL。在iOS文檔中沒有跡象表明爲什麼我可以期待NULL返回值或者我可以期望如何解決這個問題。無論採集源還是編解碼器,它都會在我測試過的所有視頻中發生。爲什麼CMSampleBufferGetImageBuffer返回NULL

任何幫助非常感謝。

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看起來罰款等

回答

2

FWIW:下面是官方文檔說的CMSampleBufferGetImageBuffer的返回值:

「結果是媒體數據的CVImageBuffer如果其結果將是NULL CMSampleBuffer不包含CVImageBuffer,或者CMSampleBuffer包含CMBlockBuffer,或者存在其他錯誤。「

還要注意的是主叫方不擁有從CMSampleBufferGetImageBuffer返回了DataBuffer,並且調用者需要保持對它的引用必須明確保留。

希望這有助於信息。

+0

謝謝!出於興趣,你在哪裏找到那個報價?因爲這裏:https://developer.apple.com/library/mac/#documentation/CoreMedia/Reference/CMSampleBuffer/Reference/Reference.html,並在我的XCode版本downlaoded的文檔存在一樣絕對沒有評論! –

+0

在頭文件中。 Apple對每種方法都有非常詳細的文檔。在xcode中,右鍵單擊代碼中的方法名稱,然後單擊「轉到定義」(措辭可能不準確),然後它將帶您訪問正確的.h文件和方法定義,其中包含文檔 – Aki

+0

Doh!我猜我認爲,由於文檔不在生成的文檔中,因此不在源代碼中。再次感謝阿基。 –

9

創建AVAssetReaderTrackOutput當你有沒有指定任何outputSettings。在撥打copyNextSampleBuffer時,爲了接收視頻軌道的原始像素格式,指定「nil」時遇到了您的問題。在我的應用程序中,我希望確保在爲了提高性能而調用copyNextSampleBuffer時沒有發生轉換,如果這不是您最關心的問題,請在輸出設置中指定像素格式。

以下是基於硬件功能蘋果的建議像素格式:

kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange kCVPixelFormatType_420YpCbCr8BiPlanarFullRange

+1

這應該被接受的答案,因爲目前接受的帖子不能解決任何問題。 –

+1

@nenchev你是如何解決問題以確保沒有發生轉換的? –

+0

@nenchev您是如何解決問題以確保沒有轉換髮生的? –

2

因爲你沒有提供你不得不使用任何outputSettings包含在框架內的原始數據。

你必須讓使用CMSampleBufferGetDataBuffer(sampleBuffer)樣品緩衝塊緩衝區,你有後,你需要使用

size_t blockBufferLength; char *blockBufferPointer; CMBlockBufferGetDataPointer(blockBuffer, 0, NULL, &blockBufferLength, &blockBufferPointer);

只看得到塊緩衝區的實際位置在*blockBufferPointer和解碼字節使用您所需編解碼器的幀頭信息。