Have you met the problem when for the same video copyPixelBufferForItemTime
is incorrect on iOS?
I have AVPlayerItemVideoOutput
, linked to appropriate AVPlayerItem
.
I call copyPixelBufferForItemTime
, receive CVPixelBufferRef
and then retrieve OpenGL texture from it.
CVPixelBufferRef pb = [_playerVideoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil];
For this sample video there's bug with CVPixelBufferRef:
int bpr = (int)CVPixelBufferGetBytesPerRow(pb);
int width_real = (int)CVPixelBufferGetWidth(pb);
int width_working = (int)CVPixelBufferGetBytesPerRow(pb)/4;
Mac output:
bpr = 2400
width_real = 596
width_working = 600
iOS output:
bpr = 2432
width_real = 596
width_working = 608
CVPixelBufferGetPixelFormatType
returns BGRA
on both platforms.
Edit
When creating texture on iOS, I read data from pixel buffer via CVPixelBufferGetBaseAddress
and use provided size 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;
}
So width_working
is just for debug. As it mismatch width_real
, and passing neither width_working
not width_real
doesn't work, I suppose that it's a bug with pixel buffer.