如何使用 iOS8 的 VideoToolbox 解码 live555 rtsp 流 (h.264) MediaSink 数据?

How to decode a live555 rtsp stream (h.264) MediaSink data using iOS8's VideoToolbox?

好的,我知道这个问题和 get-rtsp-stream-from-live555-and-decode-with-avfoundation 几乎一样,但是现在 VideoToolbox for iOS8 变成了 public for use 虽然我知道可以使用这个框架,我不知道该怎么做。

我的目标是:

我使用 ffmpeg 达到了所有这些目标,但不幸的是,由于我公司的政策,我不能使用它。

我知道我也可以使用openGL在屏幕上显示,但这次我必须转换为UIImages。我还尝试使用以下库:

我相信 live555 + VideoToolbox 可以完成这项工作,只是不知道如何做到这一点...

我做到了。 VideoToolbox 的文档仍然很少,我们没有太多关于视频编程的信息(不使用 ffmpeg)所以我花费的时间比我真正预期的要多。

对于使用 live555 的流,我得到了 SPS 和 PPS 信息来创建 CMVideoFormatDescription,如下所示:

const uint8_t *props[] = {[spsData bytes], [ppsData bytes]};
size_t sizes[] = {[spsData length], [ppsData length]};

OSStatus result = CMVideoFormatDescriptionCreateFromH264ParameterSets(NULL, 2, props, sizes, 4, &videoFormat);

现在,困难的部分(因为我对视频编程一窍不通):将 NALunit header 替换为描述的 4 字节长度代码 here

int headerEnd = 23; //where the real data starts
uint32_t hSize = (uint32_t)([rawData length] - headerEnd - 4);
uint32_t bigEndianSize = CFSwapInt32HostToBig(hSize);
NSMutableData *videoData = [NSMutableData dataWithBytes:&bigEndianSize length:sizeof(bigEndianSize)];

[videoData appendData:[rawData subdataWithRange:NSMakeRange(headerEnd + 4, [rawData length] - headerEnd - 4)]];

现在我能够使用此原始数据成功创建 CMBlockBuffer 并将缓冲区传递给 VTDecompressionSessionDecodeFrame。从这里很容易将响应 CVImageBufferRef 转换为 UIImage... 我使用 this stack overflow thread 作为参考。

最后,按照How do I export UIImage array as a movie?

的解释保存UIImage转换后的流数据

我只是发布了一些我的代码,因为我认为这是重要的部分,或者换句话说,这是我遇到问题的地方。