2015-02-12 40 views
0

当我从- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection一个框架,我找回了以下数据:纵向模式下这些额外的字节来自iPhone相机是什么?

  • BytesPerRow:1,472长度:706560高度:480宽度:360格式: BGRA

这是从正面iPhone 6以上的相机。 这是没有意义的,因为每行的字节应该是(宽*通道)(在这种情况下通道是4)。但是,它是(宽度+ 8)*通道。这额外的8个字节来自哪里?

这里是我的代码: 输出附加到我的方向设置为纵向

bool attachOutputToSession(AVCaptureSession *session, id cameraDelegate) 
{ 
    assert(cameraDelegate); 

    AVCaptureVideoDataOutput *m_videoOutput = [[AVCaptureVideoDataOutput alloc] init]; 

    //create a queue for capturing frames 
    dispatch_queue_t captureQueue = dispatch_queue_create("captureQueue", DISPATCH_QUEUE_SERIAL); 

    //Use the AVCaptureVideoDataOutputSampleBufferDelegate capabilities of CameraDelegate: 
    [m_videoOutput setSampleBufferDelegate:cameraDelegate queue:captureQueue]; 

    //setup the video outputs 
    m_videoOutput.alwaysDiscardsLateVideoFrames = YES; 

    NSNumber *framePixelFormat = [NSNumber numberWithInt:kCVPixelFormatType_32BGRA];//This crashes with 24RGB b/c that isn't supported on iPhone 
    m_videoOutput.videoSettings = [ NSDictionary dictionaryWithObject:framePixelFormat forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 

    //Check if it already has an output from a previous session 
    if ([session canAddOutput:m_videoOutput]) 
    { 
     [session addOutput:m_videoOutput]; 
    } 

    //set connection settings 
    for (AVCaptureConnection *connection in m_videoOutput.connections) 
    { 
     if (connection.isVideoMirroringSupported) 
      connection.videoMirrored = true; 
     if (connection.isVideoOrientationSupported) 
      connection.videoOrientation = AVCaptureVideoOrientationPortrait; 
    } 

    return true; 
} 

当我设置为LandscapeRight我没有这个问题的方向会话。每行的字节数等于宽度*通道。

这里就是我得到上面提到的数字:

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer]; 

    CVPixelBufferLockBaseAddress(imageBuffer,0); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 
} 

回答

1

OK原来是这样的形象“步幅”的一部分。如果图像宽度不能被选定的内存分配整除,则会包含此额外填充。当我收到肖像图像时,它是360x480。由于360不能被16整除,所以增加8个额外的字节作为填充。在这种情况下,16是存储空间。 我之前没有遇到过这个问题,因为480可以被16整除。 你可以通过致电CVPixelBufferGetBytesPerRowOfPlane (imageBuffer, 1); 得到这个号码。但是,有什么不可思议的是,它第一次返回0,第二次返回1,依此类推,直到达到真正的缓冲级别(8)。然后在第九张图像上再次返回0。

根据该页面http://gstreamer-devel.966125.n4.nabble.com/iOS-capture-problem-td4656685.html

上rpappalax跨距是有效CVPixelBufferGetBytesPerRowOfPlane()和 包括填充(如果有的话)。当没有填充时 CVPixelBufferGetBytesPerRowOfPlane()将等于 CVPixelBufferGetWidth(),否则它会更大。

虽然这不完全是我的经验。

+0

32BRGA是一个单一的平面格式,所以没有理由搞乱CVPixelBufferGetBytesPerRowOfPlane。只需使用CVPixelBufferGetBytesPerRow即可获得步伐。 – user1055568 2015-02-12 18:50:27

+0

你是对的,这工作得很好。但是,我正在处理只占用字节,宽度,高度和总大小的图像结构。所以对我来说很重要的一点是如何计算这个数据,而不是我以后的数据。 – spfursich 2015-02-13 22:03:17

相关问题