【问题标题】:Convert CVPixelBufferRef sample from 4:3 to 16:9将 CVPixelBufferRef 样本从 4:3 转换为 16:9
【发布时间】:2023-12-13 04:53:01
【问题描述】:

我尝试在视频捕获管道中将 4:3 帧转换为 16:9 帧。转换后的帧需要进一步处理。因此我需要将覆盖框架保持为CVImageBufferRef。 我查看了这个堆栈溢出线程,并从中借鉴了一些想法 iOS - Scale and crop CMSampleBufferRef/CVImageBufferRef

这就是我所做的:

int cropX0 = 0, cropY0 = 60, cropHeight = 360, cropWidth = 640, outWidth = 640, outHeight = 360;
//get CVPixel buffer from CMSampleBuffer
CVPixelBufferRef imageBuffer = CMSampleBufferGetImageBuffer(cmSampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer,0);
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);

size_t startpos = cropY0 * bytesPerRow;
void* cropStartAddr = ((char*)baseAddress) + startpos;

CVPixelBufferRef cropPixelBuffer = NULL;
int status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,
                                          outWidth,
                                          outHeight,
                                          CVPixelBufferGetPixelFormatType(imageBuffer),
                                          cropStartAddr,
                                          bytesPerRow,
                                          NULL, 
                                          0,
                                          NULL, 
                                          &cropPixelBuffer);
if(status == 0){
    OSStatus result = 0;
}

但是在这个方法之后。如果我们从 Xcode 检查cropPixelBuffer。它看起来像一个损坏的图像。

原图是这样的

我认为可能是因为颜色格式是 NV12 yuv 像素格式 感谢您的帮助

【问题讨论】:

    标签: image avfoundation crop cmsamplebuffer


    【解决方案1】:

    如果您的图像数据是 yuv,那么您可能会处理多个平面数据(例如多个 rowbytes、多个 baseAddrs 和多个 widthheights 和多个裁剪)在这种情况下,您将有使用

    CVPixelBufferCreateWithPlanarBytes()
    

    那么CVPixelBufferGetPixelFormatType(imageBuffer) 返回什么?

    【讨论】:

    • 格式为 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange。我想我需要单独处理紫外线
    • 是的,这意味着您需要裁剪两个位图