您是否遇到过相同视频copyPixelBufferForItemTime
在 iOS 上不正确的问题?
我有AVPlayerItemVideoOutput
,挂合适AVPlayerItem
。我调用copyPixelBufferForItemTime
、接收CVPixelBufferRef
然后从中检索 OpenGL 纹理。
CVPixelBufferRef pb = [_playerVideoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil];
对于此示例视频,CVPixelBufferRef 存在错误:
int bpr = (int)CVPixelBufferGetBytesPerRow(pb);
int width_real = (int)CVPixelBufferGetWidth(pb);
int width_working = (int)CVPixelBufferGetBytesPerRow(pb)/4;
Mac 输出:
bpr = 2400
width_real = 596
width_working = 600
iOS 输出:
bpr = 2432
width_real = 596
width_working = 608
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
只是为了调试。由于它 mismatch ,并且两者都没有width_real
传递不起作用,我认为这是像素缓冲区的错误。width_working
width_real