我有一个10位的ProRes4444文件,我正在渲染到CAOpenGLLayer
,因此我可以在播放期间对其进行一些处理。但是,由于这是一个10位视频,我希望获得一个具有完整10位(或更多,因此浮动背景)的IOSurface,因此任何处理都可以使用全彩色。不幸的是,我无法弄清楚如何在纹理中获得更高的颜色深度。
这是我在设置过程中所拥有的:
NSDictionary *pixelBufferAttributes = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA),
(id)kCVPixelBufferIOSurfacePropertiesKey: @{(id)kCVPixelBufferIOSurfacePropertiesKey: @(kCVPixelFormatType_128RGBAFloat)}, // doesn't appear to do anything
(id)kCVPixelBufferOpenGLCompatibilityKey: @YES};
将kCVPixelBufferPixelFormatTypeKey
设置为kCVPixelFormatType_128RGBAFloat
会使解码器崩溃,并在日志中打印出以下内容:
[15:58:12.307] <<<< VMC >>>> vmc2PostDecodeError: posting DecodeError (-12905) -- PTS was 0.000 = 0/1
[15:58:14.248] <<<< VMC >>>> vmc2PostDecodeError: posting DecodeError (-12905) -- PTS was 0.000 = 0/1
[15:58:14.253] <<<< VMC >>>> vmc2PostDecodeError: posting DecodeError (-12905) -- PTS was 0.050 = 50000000/1000000000
...
在kCVPixelBufferIOSurfacePropertiesKey
字典中添加任何内容似乎都没有做任何事情。然后,实际绘制东西:
- (void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
{
// Set the current context to the one given to us.
CGLSetCurrentContext(glContext);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
CMTime outputItemTime = [videoOutput itemTimeForHostTime:timeInterval];
if ([videoOutput hasNewPixelBufferForItemTime:outputItemTime]) {
CVPixelBufferRef pixelBuffer = NULL;
pixelBuffer = [videoOutput copyPixelBufferForItemTime:outputItemTime itemTimeForDisplay:NULL];
if (lastPixelBuffer) CVPixelBufferRelease(lastPixelBuffer);
lastPixelBuffer = pixelBuffer;
NSLog(@"New Frame at %f", CMTimeGetSeconds(outputItemTime));
}
if (lastPixelBuffer) {
IOSurfaceRef newSurface = CVPixelBufferGetIOSurface(lastPixelBuffer);
if (currentSurface != newSurface && newSurface) {
// IOSurfaceDecrementUseCount(currentSurface); // crashes
currentSurface = newSurface;
// IOSurfaceIncrementUseCount(currentSurface); // crashes
GLsizei texWidth = (int) IOSurfaceGetWidth(currentSurface);
GLsizei texHeight = (int) IOSurfaceGetHeight(currentSurface);
NSLog(@"Copying %f", CMTimeGetSeconds(outputItemTime));
if (!videoTextureName) {
GLuint name;
glGenTextures(1, &name);
videoTextureName = name;
}
GLenum anError = glGetError( );
if (anError != GL_NO_ERROR) {
NSLog(@"get context error=%x", anError);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, videoTextureName);
GetError(); // prints glGetError
CGLError error = CGLTexImageIOSurface2D(glContext, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, texWidth, texHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, currentSurface, 0);
if (error != kCGLNoError) {
NSLog(@"Consumer CGLTexImageIOSurface2D error: %d[%x]", error, error);
} else {
NSLog(@"No CGL error creating texture");
}
GetError();
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}
}
// more stuff here...
if (videoTextureName)
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, videoTextureName);
glBegin(GL_QUADS);
glTexCoord2f(0, 1080); glVertex2f(-1, -1);
glTexCoord2f(0, 0); glVertex2f(-1, 1);
glTexCoord2f(2048, 0); glVertex2f(1, 1);
glTexCoord2f(2048, 1080); glVertex2f(1, -1);
glEnd();
glDisable(GL_TEXTURE_RECTANGLE_ARB);
[super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
}
更改CGLTexImageIOSurface2D
行以使用GL_RGBA
和GL_FLOAT
会导致10008
错误。
即使媒体本身的颜色深度超过10位,也无法直接使用它?