我的项目是用Swift编写的,我尝试在Objective-C中重写它。在Swift中很好用,但在Objective-C中崩溃。由于项目很复杂,我根据Apple的样本编写了一个演示应用程序代码“SquareCam”使其变得简单。您可以从Github获取代码:https://github.com/jaypeggy/SquareCam。
使用Xcode(7.2)使用iphone运行应用程序,通过点击工具栏中的段控件将相机切换到前面,几秒钟后,应用程序将崩溃:
- (void)run {
while (1) {
CVImageBufferRef a = [self getImageBuffer];
CVPixelBufferLockBaseAddress(a, 0);
sleep(1);
NSLog(@"111111");
CVPixelBufferUnlockBaseAddress(a, 0);// crash here
}
}
应用程序的工作方式如下:
(1)“SquareCamViewController.m”使用CMSampleBufferGetImageBuffer获取CVPixelBufferRef变量。
`- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
NSLog(@"captureOutput");
// got an image
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);`
(2)类测试的实例(抱歉名字不好)将“pixelBuffer”设置为自己的变量。
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); [t setImageBuffer:pixelBuffer]; //将“pixelBuffer”设置为自身。
(3)同时,类test(test.m)在另一个线程(队列)中运行,并尝试获取“CVImageBufferRef”varibale,并调用CVPixelBufferLockBaseAddress和CVPixelBufferUnlockBaseAddress进行进一步处理。
- (void)run {
while (1) {
CVImageBufferRef a = [self getImageBuffer];
CVPixelBufferLockBaseAddress(a, 0);
sleep(1);
NSLog(@"111111");
CVPixelBufferUnlockBaseAddress(a, 0); // crash here
}
}
在我的原始项目中,它甚至更快崩溃:
void CVImageBufferRef_to_cvGRAY(CVImageBufferRef imgBuf, cv::Mat &imgOut)
{
// lock the buffer
CVPixelBufferLockBaseAddress(imgBuf, 0); // maybe crash here
// get the address to the image data
void *imgBufAddr = CVPixelBufferGetBaseAddressOfPlane(imgBuf, 0);
// get image properties
int w = (int)CVPixelBufferGetWidth(imgBuf);
int h = (int)CVPixelBufferGetHeight(imgBuf);
cv::Mat mColor(h, w, CV_8UC4, (void*)imgBufAddr);
cv::cvtColor(mColor, (imgOut), COLOR_BGRA2GRAY); // maybe crash here
// unlock again
CVPixelBufferUnlockBaseAddress(imgBuf, 0);
mColor.~Mat();
}
我花了几天时间来处理这个问题,但我不知道如何解决这个问题,它是关于mutithread的吗?为什么Swift代码运行和Objective-C崩溃?
任何人都可以帮助我吗?非常感谢。