2010-12-05 34 views
1

我试图通过使用GameKit创建的对等连接来流式传输视频数据。我具有接收一个NSData对象,并使用它来绘制一个视频流到的CALayer的方法:通过GameKit的NSData和EXC_BAD_ACCESS奇怪的问题

- (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。看起来,变量不知怎么会迷路了。

几个问题:

  1. 是铸造data.bytesCMSampleBufferRef正确的方式去拆包的NSData?

  2. 如何声明接收的数据实际上是一个CMSampleBuffer对象?我想保护我的代码,但我不知道如何完成Core Foundation类的类验证。

在此先感谢!

回答

0

这可能不是整个答案,但你对malloc_size的使用看起来像是一个巨大的红旗给我。这似乎是一个不可移植的扩展,不受ANSI,ISO或POSIX之类的任何控制,我对如果传递的缓冲区不是来自malloc的行为有疑问。这似乎是一个粗略的东西,依靠。 (我想说,如果是调用malloc_size,那么你已经在做一些C代码错误的事情了,因为C完全知道你的缓冲区有多大,并且不依赖于不可移植的libc函数来执行缓冲区大小调整,跟踪你的工作。)

+0

老实说,我并不是真的知道C的一大堆,我试图缝合在一起,我可以做这个工作,涉及到复制代码和猜测诸如malloc_size之类的东西。有没有可靠的方法来检查CMSampleBuffer的大小? – Arman 2010-12-05 07:36:51

1

为什么你'拆包'(这不是拆包)你的CMSampleBuffer通过投下NSData字节?这永远不会起作用,因为CMSampleBuffer不是内存中的连续块。

你发送的东西成和NSData对象之前检索从CMSampleBuffer自己所有的相关数据,并通过

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 
); 

reasemble它的另一面在该函数的数据类型,可能会给你打包数据时提示您想从CMSampleBuffer中提取什么。

+0

你能提供任何样本或教程吗?谢谢 – 2014-08-27 07:16:03