NSData over GameKit 和 EXC_BAD_ACCESS 奇怪的问题
Posted
技术标签:
【中文标题】NSData over GameKit 和 EXC_BAD_ACCESS 奇怪的问题【英文标题】:NSData over GameKit and EXC_BAD_ACCESS strange problem 【发布时间】:2010-12-05 06:58:30 【问题描述】:我正在尝试通过使用 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 字节)相同。在使用之前,我还检查了 data 对象的保留计数是否为 1。 imageBuffer 变量似乎丢失了。
几个问题:
将 data.bytes 转换为 CMSampleBufferRef 是否是解包 NSData 的正确方法?
如何断言接收到的数据实际上是一个 CMSampleBuffer 对象?我想保护我的代码,但我不确定如何完成 Core Foundation 类的类验证。
提前致谢!
【问题讨论】:
【参考方案1】:为什么要通过转换 NSData
的字节来“解包”(不是解包)CMSampleBuffer
?这永远行不通,因为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
中提取什么。
【讨论】:
您能提供任何示例或教程吗?谢谢【参考方案2】:这可能不是完整的答案,但您对malloc_size
的使用对我来说似乎是一个巨大的危险信号。这似乎是一个不可移植的扩展,不受 ANSI、ISO 或 POSIX 之类的约束,我怀疑如果传递一个不是来自malloc
的缓冲区,它会如何表现。这似乎是一个粗略的依赖。 (我想说,如果要调用malloc_size
,作为 C 编码器,你已经在做错事了,因为 C 就是要知道你的缓冲区有多大,而不是依赖不可移植的 libc 函数来做你的缓冲区-尺寸跟踪适合您。)
【讨论】:
老实说,我对 C 的了解并不多,我试图拼凑我能做的工作,其中包括复制代码和猜测诸如 malloc_size 之类的东西。是否有可靠的方法来检查 CMSampleBuffer 的大小?以上是关于NSData over GameKit 和 EXC_BAD_ACCESS 奇怪的问题的主要内容,如果未能解决你的问题,请参考以下文章
iPhone 到 iPhone 传输的 GameKIt 的替代品
使用 GameKit 通过 NSDictionary 在 iPhone 之间传输 CoreData 数据
OpenGL ES glReadPixels exc_bad_access