【发布时间】:2017-10-26 01:37:32
【问题描述】:
您是否遇到过相同视频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 = 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 仅用于调试。由于它不匹配width_real,并且既不传递width_working 也不传递width_real 不起作用,我想这是像素缓冲区的错误。
【问题讨论】:
-
看起来你在 iOS 案例中处理错了每行填充(
width_real*4 != CVPixelBufferGetBytesPerRow(pb)时。你能展示你是如何创建纹理的吗?你到底在用width_working做什么? ? -
@RhythmicFistman 看来我错误地命名了变量。 :)
width_working用于调试。更新了帖子。
标签: ios avfoundation avplayeritem core-video cvpixelbuffer