NSData over GameKit和EXC_BAD_ACCESS奇怪的问题

时间:2010-12-05 06:58:30

标签: iphone objective-c c nsdata gamekit

我正在尝试通过使用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 变量以某种方式迷路了。

几个问题:

  1. data.bytes 投射到 CMSampleBufferRef 以正确的方式解压缩NSData?

  2. 如何断言所接收的数据实际上是CMSampleBuffer对象?我想保护我的代码,但我不确定如何完成Core Foundation类的类验证。

  3. 提前致谢!

2 个答案:

答案 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函数来做你的缓冲区大小跟踪工作。)