我正在尝试通过使用GameKit创建的点对点连接来传输视频数据。我有一个接收NSData对象并使用它将视频流绘制到CALayer上的方法:
- (void)recieveVideoFromData:(NSData *)data;
以下是该方法的前几行,它将NSData转换为CMSampleBufferRefs并开始处理:
CMSampleBufferRef imgData = (CMSampleBufferRef)data.bytes;
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(imgData);
CVPixelBufferLockBaseAddress(imageBuffer,0);
现在,当我将来自本地相机的视频流输入到此方法中时,一切正常,视频流显示在屏幕上:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
NSData *data = [[NSData alloc] initWithBytes:sampleBuffer length:malloc_size(sampleBuffer)];
[self recieveVideoFromData:data];
}
但是,当我通过点对点连接发送这些NSData数据包的流并以下列方式接收它们时,我收到一个EXC_BAD_ACCESS错误:
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
[self recieveVideoFromData:data];
}
使用调试器,我了解到此行发生了错误的访问:
CVPixelBufferLockBaseAddress(imageBuffer,0);
我不知道为什么通过网络发送的NSData应该与从同一设备上的另一个方法发送的NSData有任何不同。我已经检查过通过网络接收的数据是以相同的间隔接收的,并且与本地设备上产生的数据长度相同(336字节)。我还检查了数据对象的保留计数在使用之前为1。似乎 imageBuffer 变量以某种方式迷路了。
几个问题:
将 data.bytes 投射到 CMSampleBufferRef 以正确的方式解压缩NSData?
如何断言所接收的数据实际上是CMSampleBuffer对象?我想保护我的代码,但我不确定如何完成Core Foundation类的类验证。
提前致谢!
答案 0 :(得分:1)
为什么要通过转换CMSampleBuffer
的字节来“解包”(不解包)NSData
?这永远不会起作用,因为CMSampleBuffer
不是内存中的连续块。
您必须在发送之前从CMSampleBuffer
自己检索所有相关数据,将其填入和NSData
对象,并通过
OSStatus CMSampleBufferCreate (
CFAllocatorRef allocator,
CMBlockBufferRef dataBuffer,
Boolean dataReady,
CMSampleBufferMakeDataReadyCallback makeDataReadyCallback,
void *makeDataReadyRefcon,
CMFormatDescriptionRef formatDescription,
CMItemCount numSamples,
CMItemCount numSampleTimingEntries,
const CMSampleTimingInfo *sampleTimingArray,
CMItemCount numSampleSizeEntries,
const size_t *sampleSizeArray,
CMSampleBufferRef *sBufOut
);
此功能中的数据类型可能会提示您在打包数据时要从CMSampleBuffer
中提取的内容。
答案 1 :(得分:0)
这可能不是完整的答案,但你对malloc_size
的使用对我来说似乎是一个巨大的红旗。这似乎是一个不可移植的扩展,不受ANSI,ISO或POSIX之类的任何约束,如果传递的缓冲区不是来自malloc
,我对它的行为方式有一些疑问。这看起来像是一件粗略的事情。 (我会说,如果调用malloc_size
你作为C编码器已经做错了,因为C只是知道你的缓冲区有多大,而不依赖于非便携式libc函数来做你的缓冲区大小跟踪工作。)