3

我在 iOS 6.1 下有一个 CADisplayLink 和一个 AVPlayerItemVideoOutput。我现在有一个 CVPixelBufferRef 并想修改它(例如在视频上显示时间码等)。我想我已经正确实现了修改部分,现在有了一个新框架的 CGImageRef 或 CGContextRef 。

我现在的问题是:我应该如何显示它?我找到了适用于 OS X 的特殊课程,但没有找到适用于 iOS 的课程。有吗?我可以使用 GPUImage 框架作为快捷方式吗?(但专用的 GPUImage 电影播放器​​不播放音频:()。

(Advanced AVFoundation 有什么好书吗?)

这是我的代码,但是视频上没有显示绘制的文本(视频和音频播放得很好)。代码通过 CADisplayLink 回调调用(我检查过)。

CVPixelBufferRef ref = [_playerItemVideoOutput copyPixelBufferForItemTime:_playerItem.currentTime itemTimeForDisplay:nil];
size_t width = CVPixelBufferGetWidth(ref);
size_t height = CVPixelBufferGetHeight(ref);
size_t bytes_per_row = CVPixelBufferGetBytesPerRow(ref);

CVPixelBufferLockBaseAddress(ref, 0);
void *pxdata = CVPixelBufferGetBaseAddress(ref);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, width,
        height, 8, bytes_per_row, rgbColorSpace, kCGImageAlphaNoneSkipFirst);
CGContextRetain(context);

CGContextSelectFont(context, "Helvetica", 10, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextShowTextAtPoint(context, 0.0, 0.0, "O BROTHER WHERE ARE THOU?", 20);

CGColorSpaceRelease(rgbColorSpace);
CVPixelBufferUnlockBaseAddress(ref, 0);
CGContextRelease(context);
CVBufferRelease(ref);

编辑:我的问题是/曾经是,您无法使用 AVPlayerLayer 显示修改后的像素缓冲区。您必须通过其他方法输出它(在 Mac 上有一个 AVSampleBufferOutput,但在 iOS 上没有公共等效项:/)。

4

1 回答 1

3

我想你问错问题了。似乎您想实时处理视频,但您问的是CGImageRef

我建议你学习WWDC 2012 的 Session 517。有OSX 和 iOS 的示例代码,下载所有 [相关] AVFoundation 示例并查看它们。搜索新的 iOS 6 方法来缩小您的搜索范围。

一旦代码到位(基本上是一个CADisplayLink回调,您将copyPixelBufferForItemTime:itemTimeForDisplay:在正确的时间提取像素缓冲区),您可以使用 GPUImage、Core Image 或您自己的 OpenGL 代码修改像素缓冲区。所有这些都必须在视频即将播放时完成AVPlayer,否则您将只能显示图像而不能显示音频。至少不同步音频。

如果您问一些具体的问题,我可能会为您提供更多帮助。

于 2013-05-03T09:58:56.873 回答