这些额外的字节来自iPhone相机的纵向模式?

时间:2015-02-12 01:37:15

标签: iphone ios8 avfoundation avcapturesession

当我从- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection获得一个帧时,我将收到以下数据:

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

这是来自iPhone 6 plus的前置摄像头。 这没有意义,因为每行的字节数应该是(宽*通道)(在这种情况下,通道为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 个答案:

答案 0 :(得分:1)

好的结果证明这是图像的一部分" stride"。如果图像宽度不能被所选择的存储器分配整除,则包括这个额外的填充。当我收到肖像图像时,它是360x480。由于360不能被16整除,因此添加了8个额外字节作为填充。 16是这种情况下的存储空间。 之前我没有遇到过这个问题,因为480可以被16整除。 您可以致电CVPixelBufferGetBytesPerRowOfPlane (imageBuffer, 1);获取此号码 但奇怪的是,它第一次返回0,第二次返回1,依此类推,直到达到实际缓冲级别(8)。然后它在第九张图像上再次返回0。

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

  

步幅实际上是CVPixelBufferGetBytesPerRowOfPlane()和   包括填充(如果有的话)。没有填充时   CVPixelBufferGetBytesPerRowOfPlane()将等于   CVPixelBufferGetWidth(),否则它会更大。

虽然这不是我的经历。