美文网首页
转一个yuv的stride知识

转一个yuv的stride知识

作者: miniminiming | 来源:发表于2019-01-15 12:12 被阅读0次

作者:远方的枸杞
链接:https://www.jianshu.com/p/68e05ad85490
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

image

前言

ios调用系统框架采集出的视频YUV格式为NV12.
为满足不同业务需求,我们需要把nv12转换为i420或者rgba等格式.
libYUV库和ffmpeg都可以帮助我们轻松搞定.(推荐libyuv库,性能比ffmpeg高出很多).

libyuv

libyuv是Google开源的实现各种YUV与RGB之间相互转换、旋转、缩放的库。它是跨平台的,可在Windows、Linux、Mac、Android等操作系统,x86、x64、arm架构上进行编译运行,支持SSE、AVX、NEON等SIMD指令加速.

使用libyuv

libyuv下载和编译网上教程较多,可去官网下载
我们来看一下NV12转换为i420的接口

// Convert NV12 to I420.
LIBYUV_API
int NV12ToI420(const uint8* src_y, int src_stride_y,
               const uint8* src_uv, int src_stride_uv,
               uint8* dst_y, int dst_stride_y,
               uint8* dst_u, int dst_stride_u,
               uint8* dst_v, int dst_stride_v,
               int width, int height);

src_ 为我们需要转换的NV12格式数据,dst_ 为转换后的i420数据
那么stride代表啥???

跨距-stride

我们都知道现在计算机的cpu都是32位或者64位的cpu,他们一次最少读取4、8个字节,如果少于这些,反而要做一些额外的工作,会花更长的时间。所有会有一个概念叫做内存对齐,将结构体的长度设为4、8的倍数。

跨距也是因为同样的理由出现的。因为图像的操作通常按行操作的,如果图像的所有数据都紧密排列,那么会发生非常多次的读取非对齐内存。会影响效率。而图像的处理本就是一个分秒必争的操作,所以为了性能的提高就引入了跨距这个概念。
跨距就是指图像中的一行图像数据所占的存储空间的长度,它是一个大于等于图像宽度的内存对齐的长度。这样每次以行为基准读取数据的时候就能内存对齐,虽然可能会有一点内存浪费,但是在内存充裕的今天已经无所谓了。

CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        //表示开始操作数据
        CVPixelBufferLockBaseAddress(pixelBuffer, 0);
        //图像宽度(像素)
        size_t pixelWidth = CVPixelBufferGetWidth(pixelBuffer);
        //图像高度(像素)
        size_t pixelHeight = CVPixelBufferGetHeight(pixelBuffer);
        //获取CVImageBufferRef中的y数据
        uint8_t *y_frame = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
        //获取CMVImageBufferRef中的uv数据
        uint8_t *uv_frame = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
        //y stride
        size_t plane1_stride = CVPixelBufferGetBytesPerRowOfPlane (pixelBuffer, 0);
        //uv stride
        size_t plane2_stride = CVPixelBufferGetBytesPerRowOfPlane (pixelBuffer, 1);
       //y_size
        size_t plane1_size = plane1_stride * CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
        //uv_size
        size_t plane2_size = CVPixelBufferGetBytesPerRowOfPlane (pixelBuffer, 1) * CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
        //yuv_size
        size_t frame_size = plane1_size + plane2_size;

        uint8* buffer = malloc(frame_size);
        uint8* dst_u = buffer + plane1_size;
        uint8* dst_v = dst_u + plane1_size/4;

        // Let libyuv convert
       NV12ToI420(/*const uint8* src_y=*/y_frame, /*int src_stride_y=*/plane1_stride,
                           /*const uint8* src_uv=*/uv_frame, /*int src_stride_uv=*/plane2_stride,
                           /*uint8* dst_y=*/buffer, /*int dst_stride_y=*/plane1_stride,
                           /*uint8* dst_u=*/dst_u, /*int dst_stride_u=*/plane2_stride/2,
                           /*uint8* dst_v=*/dst_v, /*int dst_stride_v=*/plane2_stride/2,
                           pixelWidth, pixelHeight);
        CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
       free(buffer);

以上为NV12转化为i420的所有代码.

相关文章

  • 转一个yuv的stride知识

    作者:远方的枸杞链接:https://www.jianshu.com/p/68e05ad85490來源:简书简书著...

  • YUV格式转换中的stride

    前言 ios调用系统框架采集出的视频YUV格式为NV12.为满足不同业务需求,我们需要把nv12转换为i420或者...

  • YUV420转换RGB公式

    YUV420转换RGB YUV420转换RGB公式

  • YUV基础知识(转)

    本文均为原文截取片段。文中我在原文作者的内容上再补充一些注释,对重点也会以红色字体标记出来。 四,视频编码 4.1...

  • 转码的四个案例

    一,swcale实现rgb24转yuv420p 二,swcale实现YUV转RGB

  • rgba / yuv buffer 转 UIImage

    1.rgba转UIimage 1.yuv 转UIimage a.YUV(NV12)-->CIImage--->UI...

  • Opengl ES之YUV数据渲染

    YUV回顾 记得在音视频基础知识介绍中,笔者专门介绍过YUV的相关知识,可以参考:《音视频基础知识-YUV图像》[...

  • LibYUV转码裁剪缩放 C++

    32bgra to yuv420转换 yuv420 旋转和镜像 yuv420镜像 yuv保持最大可视范围缩放和裁剪...

  • FFmpeg实践记录九:视频基础知识

    视频基础知识 分辨率与帧率 YUV YUV常见格式 YUV的存储 参考资料: 问题:都有哪些库可以对YUV进行操作...

  • YUV色彩格式总结

    YUV色彩格式总结 上一篇文章结合OpenCV的源代码介绍了BGR转YUV的方法(YUV444)。本文主要介绍YU...

网友评论

      本文标题:转一个yuv的stride知识

      本文链接:https://www.haomeiwen.com/subject/mzoedqtx.html