【问题标题】:Which YCbCr matrix to use? BT.709 or BT.601使用哪个 YCbCr 矩阵? BT.709 或 BT.601
【发布时间】: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. 如何确定要使用的转换?
  2. 如果无法解决 [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


【解决方案1】:

使用takeUnretainedValue() 将为您提供CFTypeRef。这需要从downcastCFString。例如,您的代码可能如下所示:

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)
}

哪些打印:

ITU_R_601_4
true
false

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    相关资源
    最近更新 更多