2017-05-25 98 views
1

你有沒有遇到過的問題不正確CVPixelBufferRef時相同的視頻copyPixelBufferForItemTime是不正確iOS上?AVPlayerItemVideoOutput copyPixelBufferForItemTime給出了iOS上的特定視頻

我有AVPlayerItemVideoOutput,聯繫到合適AVPlayerItem。 我打電話copyPixelBufferForItemTime,收到CVPixelBufferRef然後從中檢索的OpenGL紋理。

CVPixelBufferRef pb = [_playerVideoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil]; 

對於這個sample video有錯誤與CVPixelBufferRef:

int bpr = (int)CVPixelBufferGetBytesPerRow(pb); 
int width_real = (int)CVPixelBufferGetWidth(pb); 
int width_working = (int)CVPixelBufferGetBytesPerRow(pb)/4; 

Mac的輸出
BPR =
width_real = 596
width_working =

iOS的輸出
BPR =
width_real = 596
width_working =

它是如何呈現在iOS上:
enter image description here

它是如何呈現在Mac上:
enter image description here

CVPixelBufferGetPixelFormatType返回兩個平臺上的BGRA

編輯 在創建iOS上的質感,我通過CVPixelBufferGetBaseAddress讀取像素緩衝區中的數據,並使用所提供的尺寸CVPixelBufferGetWidth/CVPixelBufferGetHeight

- (GLuint)createTextureFromMovieFrame:(CVPixelBufferRef)movieFrame 
{ 
    int bufferWidth = (int) CVPixelBufferGetWidth(movieFrame); 
    int bufferHeight = (int) CVPixelBufferGetHeight(movieFrame); 

    // Upload to texture 
    CVPixelBufferLockBaseAddress(movieFrame, 0); 

    CVOpenGLTextureRef texture=0; 
    GLuint tex = 0; 

#if TARGET_OS_IOS==1 
    void * data = CVPixelBufferGetBaseAddress(movieFrame); 
    CVReturn err = 0; 
    tex = algotest::MyGL::createRGBATexture(bufferWidth, bufferHeight, data, algotest::MyGL::KLinear); 

#else 
    CVReturn err = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 
                  getGlobalTextureCache(), movieFrame, 0, &texture); 
#endif 

    CVPixelBufferUnlockBaseAddress(movieFrame, 0); 

    return tex; 
} 

所以width_working只是爲了調試。由於它不匹配width_real,並通過既不width_workingwidth_real不工作,我想這是與像素緩衝區的錯誤。

+1

看起來你錯誤地處理了iOS情況下的每行填充(當width_real * 4!= CVPixelBufferGetBytesPerRow(pb)'。你能說明你是如何創建紋理的?你到底在做什麼'width_working'? –

+0

@RhythmicFistman看起來我誤將變量命名:)'width_working'用於調試。更新了帖子。 –

回答

1

像素緩衝器對iOS和MAC,推測用於對準原因每行填充像素。不同的是,mac CVOpenGLTextureCacheCreateTextureFromImage函數理解這一點,而iOS createRGBATexture函數不能,不是沒有字節每行參數。

您既可以包括在寬度填充像素,後來裁剪出來:

tex = algotest::MyGL::createRGBATexture(CVPixelBufferGetBytesPerRow(movieFrame)/4, bufferHeight, data, algotest::MyGL::KLinear); 

或者你可以使用CVOpenGLESTextureCache,iOS的等效CVOpenGLTextureCacheCVOpenGLESTextureCacheCreateTextureFromImage()取代createRGBATexture()。那麼你的iOS代碼會類似於&由於iOS上的紋理緩存可以避免冗餘複製紋理數據,所以iOS代碼甚至可能運行得更快。

相關問題