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

时间:2015-03-10 10:22:28

标签: ios decode h.264 rtsp live555

好的,我知道这个问题几乎和get-rtsp-stream-from-live555-and-decode-with-avfoundation一样,但是现在用于iOS8的VideoToolbox公开使用,虽然我知道可以使用这个框架完成,但我不知道如何使用做这个。

我的目标是:

  • 使用rtsp协议连接WiFiCamera并接收流数据(使用live555完成)
  • 解码数据并转换为UIImages以显示在屏幕上(类似于motionJPEG)
  • 并将流式数据保存在.mov文件

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

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

  • ffmpeg:由于公司的政策,不能使用这段时间。 (不要问我为什么)

  • libVLC:显示滞后约2秒,我无法访问流数据以保存到.mov文件...

  • gstreamer:与上述相同

我相信live555 + VideoToolbox会完成这项工作,只是无法弄清楚如何做到这一点......

1 个答案:

答案 0 :(得分:3)

我做到了。 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);

现在,困难的部分(因为我是视频编程的noob):用here所述的4字节长度代码替换NALunit标头

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上转换的流数据

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