使用哪种YCbCr矩阵? BT.709或BT.601

时间:2016-12-19 07:20:59

标签: ios avfoundation color-space

我正在开发iOS上的视频播放器项目。

它使用AVFoundation从视频文件中提取CVPixelBuffer,然后将该缓冲区作为纹理发送到OpenGL。

概念验证代码的灵感来自Apple's sample code。 AVFoundation在YCbCr颜色空间中提供每个帧,并且需要将其转换为RGB以在OpenGL中渲染。根据不同的YCbCr标准(例如ITU-R BT.709, ITU-R BT.601),该变换似乎具有多个变换矩阵选项。示例代码通过以下代码确定要使用哪一个:

CFTypeRef colorAttachments = CVBufferGetAttachment(pixelBuffer, kCVImageBufferYCbCrMatrixKey, NULL);
if (colorAttachments == kCVImageBufferYCbCrMatrix_ITU_R_601_4) {
    _preferredConversion = kColorConversion601;
}
else {
    _preferredConversion = kColorConversion709;
}

但是,我使用的是swift,返回colorAttachment的类型为Unmanaged<CFTypeRef>,而常量kCVImageBufferYCbCrMatrix_ITU_R_601_4的类型为CFString,因此无法直接等效。我做了一些研究,结果是:

CFEqual(colorAttachments, kCVImageBufferYCbCrMatrix_ITU_R_601_4) // returns false
CFEqual(colorAttachments, kCVImageBufferYCbCrMatrix_ITU_R_709_2) // returns false too!!
//-----------------------------------------
CFGetType(colorAttachments) // returns 1
CFStringGetType() // returns 7, note kCVImageBufferYCbCrMatrix_ITU_R_601_4 is of type CFString
// so I still can't check their equality 
// because the retrieved  colorAttachments is not of type CFString at all

我通过对矩阵进行硬编码逐个尝试了两次变换,结果(渲染场景)似乎与人眼没有区别,这是可预测的,因为两个变换矩阵没有太大区别。

我的问题:

  1. 如何确定要使用哪种转换?
  2. 如果无法解决[1.],我可以硬编码吗?这样做的后果是什么?

1 个答案:

答案 0 :(得分:0)

使用takeUnretainedValue()会为您提供Name。然后,这需要downcastCFTypeRef。例如,您的代码可能如下所示:

CFString

打印哪些:

if let colorAttachment = CVBufferGetAttachment(image, kCVImageBufferYCbCrMatrixKey, nil)?.takeUnretainedValue(),
    CFGetTypeID(colorAttachment) == CFStringGetTypeID() {
    let colorAttachmentString = colorAttachment as! CFString
    print(colorAttachmentString)
    print(colorAttachmentString == kCVImageBufferYCbCrMatrix_ITU_R_601_4)
    print(colorAttachmentString == kCVImageBufferYCbCrMatrix_ITU_R_709_2)
}