【问题标题】:The continuance of YUV-NV12 video buffer's y plane and uv planeYUV-NV12 video buffer的y平面和uv平面的延续
【发布时间】:2016-07-08 19:42:43
【问题描述】:

我有一个(CMSampleBufferRef)imageBuffer,它是 yuv_nv12(4:2:0) 的类型。

现在我运行下面的代码,发现结果很混乱。

UInt8 *baseSRC = (UInt8 *)CVPixelBufferGetBaseAddress(imageBuffer);
UInt8 *yBaseSRC = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
UInt8 *uvBaseSRC = (UInt8 *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 1);
int width = (int)CVPixelBufferGetWidthOfPlane(imageBuffer, 0);    //width = 480;
int height = (int)CVPixelBufferGetHeightOfPlane(imageBuffer, 0);  //height = 360;

int y_base = yBaseSRC - baseSRC;     //y_base = 64;
int uv_y = uvBaseSRC-yBaseSRC;       //uv_y = 176640;
int delta = uv_y - width*height;     //delta = 3840;

我对这个结果有几个问题。

1:为什么baseSRC 不等于yBaseSRC

2:为什么yBaseSRC+width*height 不等于uvBaseSRC?理论上,y平面数据后面跟着uv平面数据,没有任何中断,对吧?现在它被大小为 3840 字节的东西打断了,我不明白。

3:我尝试使用以下代码将此示例像素转换为 cvmat,在大多数 iOS 设备上,这可以正常工作,但不适用于 iPhone 4s。在 iPhone 4s 上, 转换后,像素缓冲区的旁边有一些绿线。

Mat nv12Mat(height*1.5,width,CV_8UC1,(unsigned char *)yBaseSRC);
Mat rgbMat;
cvtColor(nv12Mat, rgbMat, CV_YUV2RGB_NV12);

现在 rgbMat 看起来像这样:

【问题讨论】:

  • CVPixelBuffers 是不透明类型,我会推断您找到的增量是 CVPixelBuffer 数据类型的一部分。由于没有记录数据类型并且 Apple 提供了 api 来提取您需要的数据,因此我不会对应该如何组织数据做出假设。至于opencv垫,你为什么使用(高度* 1.5)的高度。你应该只传递“高度”。
  • @blackirishman 因为'height'是y平面的高度,所以uv平面的高度等于'height/2.0',所以缓冲区的总大小应该是'widthheight+ widthheight/2.0',和'width*height*1.5'同义。
  • 当你第一次写这篇文章时,你正在创建一个平面的垫子,对吧?您对 CVPixelBufferGetWidthOfPlane 和 CVPixelBufferGetHeightOfPlane 的调用为您提供了应输入到 Mat 中的宽度和高度。
  • @blackirishman 不,我正在创建一个包含所有平面(包括 y、u、v)的 Mat。
  • 绿色数据必须是 CVPixelBuffer 中的任何内容。增量除以高度为 10.66,在您刚刚发布的图像中看起来像 10 像素。

标签: ios opencv video-processing yuv cvpixelbuffer


【解决方案1】:

终于找到了解决办法,基本上解决办法就是分配一块新的内存,把y平面数据和uv平面数据拼接起来,然后转成cvmat就可以了。

这里是sn-p的代码:

UInt8 *newBase = (UInt8 *)malloc(landscapeWidth*landscapeHeight*1.5);
memcpy(newBase, yBaseSRC, landscapeWidth*landscapeHeight);
memcpy(newBase+landscapeWidth*landscapeHeight, uvBaseSRC, landscapeWidth*landscapeHeight*0.5);
Mat nv12Mat(landscapeHeight*1.5,landscapeWidth,CV_8UC1,(unsigned char *)newBase);

【讨论】:

    猜你喜欢
    • 2013-07-03
    • 2018-03-13
    • 2017-07-27
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2017-05-12
    相关资源
    最近更新 更多