AVPlayerItemVideoOutput copyPixelBufferForItemTime给出了iOS上的特定视频

问题描述:

你有没有遇到过的问题不正确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'用于调试。更新了帖子。 –

像素缓冲器对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代码甚至可能运行得更快。