【发布时间】:2017-05-04 05:03:29
【问题描述】:
我正在开发 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.],我可以对其中任何一个进行硬编码吗?这样做的后果是什么?
【问题讨论】:
-
为了知道使用哪个解码矩阵,您需要知道哪个解码矩阵用于对您的视频进行编码,这里没有真正安全的假设,但 BT.709 将是我选择的那个BT.601 适用于逐步淘汰的 SDTV。
-
@KelSolaar,我应该如何查询用于在 AVFoundation 中编码的矩阵?
-
老实说,我不知道,我对 AVFoundation 一无所知,但是作为使用 BT.709 作为解码矩阵的假设的后续,这里是一张显示 Youtube 编码色彩空间的图像统计:lh5.googleusercontent.com/…。 BT.709 是当今 Youtube 上使用最多的色彩空间,这意味着大多数人都在用它来编码他们的视频。
-
BOOL 支持 = (CFStringCompare(CVBufferGetAttachment(cvPixelBuffer, kCVImageBufferYCbCrMatrixKey, NULL), kCVImageBufferYCbCrMatrix_ITU_R_709_2, 0) == kCFCompareEqualTo);
标签: ios avfoundation color-space