1

我在 QTKit 中打开了 QTMovie。

我需要以 YV12 格式(kYUV420PixelFormat)实时获取该视频的每一帧(即,我将其传递给仅接受 YV12 并需要实时播放视频的外部代码)。

似乎应该完成的方式是为当前帧调用[movie frameImageAtTime: [movie currentTime] withAttributes: error: ],然后[movie stepForward]进入下一帧,依此类推,直到我得到所有帧. 但是,就我的研究而言,我找不到让 QTKit 以 YV12 格式或任何其他 YUV 格式为我提供数据的方法。frameImageAtTime:调用可以将其转换为:

  • NSImage(但 NSImage 不能存储平面 YUV),
  • CGImage(同样的事情),
  • CIImage(同样的事情),
  • CVPixelBuffer(这个可以存储YUV,但是好像没有办法配置调用从中获取YUV,默认返回ARGB32数据)
  • OpenGL纹理(这可能也可以配置,但我在OpenGL中不需要这些数据,我需要它在内存中)

因此,使用这种据称是新的和优化的 QTKit 技术的唯一方法似乎是从中获取 ARGB 数据,使用自定义代码将每一帧转换为 YV12,并希望它仍然足够快以用于实时。还是我错过了什么?

在旧的 QuickTime 中,使用kYUV420PixelFormat设置 GWorld 相对容易,并对其进行电影渲染,并且可以正常工作。但旧的 QuickTime 调用是遗留的、已弃用的调用,不再使用......

我应该怎么做才能在没有不必要的转换的情况下获得 YUV420 平面框架?

4

1 回答 1

0

根据旧苹果邮件列表之一上的这个线程,我会说这至少过去是不可能的。我现在正在尝试找出是否可以使用较低级别的 API 来完成。

http://lists.apple.com/archives/quicktime-api/2008/Nov/msg00049.html

2008 年 11 月 5 日下午 12:08,尼尔·克莱顿写道:

我想从电影中得到一个 YUV 帧(电影是用 YUV 编码的,这些帧最初是 k2vuyPixelFormat 并且编码器格式会与之兼容 - 例如:H264 或 AIC 等)。

当我这样做时:

NSError *error = nil;
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
    QTMovieFrameImageTypeCVPixelBufferRef, QTMovieFrameImageType,
    [NSNumber numberWithBool:YES], QTMovieFrameImageHighQuality,
    nil];
CVPixelBufferRef buffer = [qtMovie frameImageAtTime:QTMakeTime(lastFrame, movie.timeScale)
    withAttributes:dict error:&error];

框架看起来有效。它具有正确的宽度和高度。但是当我这样做时,它似乎是 k32ARGBPixelFormat 类型:

OSType type = CVPixelBufferGetPixelFormatType(buffer);

假设我这样做是错误的 - 从电影中获取 k2vuyPixelFormat 类型的帧的正确方法是什么?或者,如果这不可能,将 RGB-YUV 转换为 k2vuyPixelFormat 类型的 CVPixelBuffer 的最简单方法是什么?我在这里不需要速度(这是一次性的,一帧操作)。

2008 年 11 月 7 日,QuickTime Engineering 的 Tim Monroe 回应:

目前没有办法通过 frameImageAtTime 做你想做的事。我建议提交增强请求。

于 2011-09-04T07:39:35.413 回答