2017-10-03 1 views
2

내 iPhone 장치에서 내 Mac으로 화면을 녹화하고 있습니다. 미리보기 레이어로서 AVCaptureVideoDataOutput에서 직접 샘플 버퍼를 수집하고 있습니다.이 버퍼에서 텍스처를 만들고 Metal으로 렌더링합니다. 내가 가지고있는 문제는 10.13으로 업데이트 한 후 10.13 이전에 macOS에서 작동했던 코드가 작동을 멈춘 것입니다. 즉,CVMetalTextureCacheCreateTextureFromImage는 macOS에서 -6660을 반환합니다. 10.13

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(_currentSampleBuffer); 

if (!imageBuffer) return; 

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

CVMetalTextureRef metalTexture = NULL; 
CVReturn result = CVMetalTextureCacheCreateTextureFromImage(nil, 
                  self.textureCache, 
                  imageBuffer, 
                  nil, 
                  self.pixelFormat, 
                  width, 
                  height, 
                  0, 
                  &metalTexture); 

if (result == kCVReturnSuccess) { 
    self.texture = CVMetalTextureGetTexture(metalTexture); 
} 

on the official Apple docs을 알 수있는 바와 같이, 일반적인 kCVReturnError로 변환 반환 result = -6660, 그리고 metalTexture = NULL.

카메라에서 가져 오는 샘플이 2vuy이므로 사용중인 픽셀 형식은 MTLPixelFormatBGRG422입니다. 해결 방법으로

sampleBuffer에서 metalTexture을 만드는, 그래서 같은 중간 NSImage를 작성 지금 오전 :

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(_currentSampleBuffer); 
    NSCIImageRep *imageRep = [NSCIImageRep imageRepWithCIImage:[CIImage imageWithCVImageBuffer:imageBuffer]]; 

    NSImage *image = [[NSImage alloc] initWithSize:[imageRep size]]; 
    [image addRepresentation:imageRep]; 

그에서 MTLTexture를 작성. 그것은 바로 CVMetalTextureCacheCreateTextureFromImage을 사용하는 명백한 해결책입니다.

다시 한번이 코드는 macOS < 10.13에서 완벽하게 작동합니다. 비슷한 문제가있는 사람이 있는지 알고 싶습니다. 그렇다면이 문제를 해결하는 방법에 대해 알고 계십니까?

답변

3

동일한 문제가 발생했습니다. AVCaptureVideoDataOutput을 구성 할 때 금속 호환성을 요구하지 않는 문제가있었습니다. 나는 시스템이 macOS 10.13에서 이것을 체크하기 시작했는데 요청하지 않을 때 최적화를 적용 할 가능성이 있다고 생각한다.

videoSettings 속성에 kCVPixelBufferMetalCompatibilityKey을 추가하는 것이 해결책이다. AVCaptureVideoDataOutput. 오브젝티브 C에서

:

outputCapture.videoSettings = @{ 
    /* ... */ 
    (NSString *)kCVPixelBufferMetalCompatibilityKey: @YES 
}; 

스위프트에서는 :

outputCapture.videoSettings = [ 
    /* ... */ 
    kCVPixelBufferMetalCompatibilityKey as String: true 
] 

나는 이것이이 발생했을 때 적어도 경고 메시지를 인쇄하는 애플을 물어, 레이더를 보증 생각합니다. 내가이 사실을 알게되면 이것을 업데이트 할 것이다.

+0

정말 멋지다! 분할 된 이미지와 이상한 색상을 얻고 있기 때문에 픽셀 버퍼의 출력 형식을 확인해야합니다. 나중에 참조 할 수 있도록 다른 해결책으로 해결 방법을 게시하겠습니다. –

0

픽셀 버퍼에 2vuy 형식을 유지하는 해결 방법이 있지만 성능에 영향을주는 픽셀 버퍼 데이터 복사본을 만드는 것이 좋습니다. 나중에 참조 할 수 있도록 게시하거나 다른 사람이 유용하다고 생각하는 경우 게시합니다. 기본적으로 픽셀 버퍼를 가로 채고 데이터를 복사하는 동안 특성을 추가합니다.

NSDictionary *attributes = @{ 
          @"IOSurfaceCoreAnimationCompatibility": @YES 
          }; 
CVPixelBufferRef copy = NULL; 

CVPixelBufferCreate(kCFAllocatorDefault, 
        CVPixelBufferGetWidth(pixelBuffer), 
        CVPixelBufferGetHeight(pixelBuffer), 
        CVPixelBufferGetPixelFormatType(pixelBuffer), 
        (__bridge CFDictionaryRef)attributes, 
        &copy); 

CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); 
CVPixelBufferLockBaseAddress(copy, 0); 

void *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer); 
void *copyBaseAddress = CVPixelBufferGetBaseAddress(copy); 

memcpy(copyBaseAddress, baseAddress, CVPixelBufferGetDataSize(pixelBuffer)); 

CVPixelBufferUnlockBaseAddress(copy, 0); 
CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); 
관련 문제