libyuv使用

RGBA转I420,缩放后转NV12

int transfer_32bgra_to_I420_ScaleToSize(CVPixelBufferRef source_pixelBuffer,CGSize targetSize,CVPixelBufferRef dst_pixelBuffer) {
    
    CVPixelBufferLockBaseAddress(source_pixelBuffer, 0);
    CVPixelBufferLockBaseAddress(dst_pixelBuffer, 0);
    
    //source-size
    size_t width = CVPixelBufferGetWidth(source_pixelBuffer);//图像宽度(像素)
    size_t height = CVPixelBufferGetHeight(source_pixelBuffer);//图像高度(像素)
    uint8_t *rgbaBuffer = (uint8_t *)CVPixelBufferGetBaseAddress(source_pixelBuffer);
    
    int yuvBufSize = width * height * 3 / 2;
    uint8_t* yuvBuf= new uint8_t[yuvBufSize];
    
    //source-stride
    int Dst_Stride_Y = width;
    const int32 uv_stride = (width+1) / 2;
    
    //source-length
    const int y_length = width * height;
    int uv_length = uv_stride * ((height+1) / 2);
    
    //source-data
    unsigned char *Y_data_Dst = yuvBuf;
    unsigned char *U_data_Dst = yuvBuf + y_length;
    unsigned char *V_data_Dst = U_data_Dst + uv_length;
    
    //BGRAToI420, 内存顺序是BGRA,所以用方法得反过来ARGB
    libyuv::ARGBToI420(rgbaBuffer,
                       width * 4,
                       Y_data_Dst, Dst_Stride_Y,
                       U_data_Dst, uv_stride,
                       V_data_Dst, uv_stride,
                       width, height);

    //scale-size
    int scale_yuvBufSize = targetSize.width * targetSize.height * 3 / 2;
    uint8_t* scale_yuvBuf= new uint8_t[scale_yuvBufSize];
    
    //scale-stride
    int scale_Dst_Stride_Y = targetSize.width;
    const int32 scale_uv_stride = (targetSize.width+1) / 2;
    
    //scale-length
    const int scale_y_length = targetSize.width * targetSize.height;
    int scale_uv_length = scale_uv_stride * ((targetSize.height+1) / 2);
    
    //scale-data
    unsigned char *scale_Y_data_Dst = scale_yuvBuf;
    unsigned char *scale_U_data_Dst = scale_yuvBuf + scale_y_length;
    unsigned char *scale_V_data_Dst = scale_U_data_Dst + scale_uv_length;
    
    libyuv::I420Scale(Y_data_Dst, Dst_Stride_Y,
                      U_data_Dst, uv_stride,
                      V_data_Dst, uv_stride,
                      width, height,
                      scale_Y_data_Dst, scale_Dst_Stride_Y,
                      scale_U_data_Dst, scale_uv_stride,
                      scale_V_data_Dst, scale_uv_stride,
                      targetSize.width, targetSize.height,
                      libyuv::kFilterNone);
    
    //final-data
    uint8_t *final_y_buffer = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(dst_pixelBuffer, 0);
    uint8_t *final_uv_buffer = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(dst_pixelBuffer, 1);
    
    libyuv::I420ToNV12(scale_Y_data_Dst, scale_Dst_Stride_Y,
                       scale_U_data_Dst, scale_uv_stride,
                       scale_V_data_Dst, scale_uv_stride,
                       final_y_buffer, scale_Dst_Stride_Y,
                       final_uv_buffer, scale_uv_stride*2,  //因为u的宽度 = y * 0.5,v的宽度 = y * 0.5
                       targetSize.width, targetSize.height);
    
    CVPixelBufferUnlockBaseAddress(source_pixelBuffer, 0);
    CVPixelBufferUnlockBaseAddress(dst_pixelBuffer, 0);
    
    delete [] yuvBuf;
    delete [] scale_yuvBuf;
    
    return yuvBufSize;
}

RGB直接缩放后转NV12

int transfer_32bgra_to_NV12_ScaleToSize(CVPixelBufferRef source_pixelBuffer,CGSize targetSize,CVPixelBufferRef dst_pixelBuffer) {
    
    CVPixelBufferLockBaseAddress(source_pixelBuffer, 0);
    CVPixelBufferLockBaseAddress(dst_pixelBuffer, 0);
    
    //source-size
    size_t width = CVPixelBufferGetWidth(source_pixelBuffer);//图像宽度(像素)
    size_t height = CVPixelBufferGetHeight(source_pixelBuffer);//图像高度(像素)
    uint8_t *rgbaBuffer = (uint8_t *)CVPixelBufferGetBaseAddress(source_pixelBuffer);
    int rgb_length = width * height * 4;
    
    //scale-size
    uint8_t* argb_scale_dst_buf= new uint8_t[rgb_length];
    
    //BGRA--Scale
    libyuv::ARGBScale(rgbaBuffer, width * 4,
                      width, height,
                      argb_scale_dst_buf, targetSize.width * 4,
                      targetSize.width, targetSize.height,
                      libyuv::kFilterNone);
    
    //yuv-stride
    int Dst_Stride_Y = targetSize.width;
    const int32 uv_stride = (targetSize.width+1) / 2;

    //yuv-data
    uint8_t *final_y_buffer = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(dst_pixelBuffer, 0);
    uint8_t *final_uv_buffer = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(dst_pixelBuffer, 1);
    
    //trans
    libyuv::ARGBToNV12(argb_scale_dst_buf, targetSize.width * 4,
                       final_y_buffer, Dst_Stride_Y,
                       final_uv_buffer, uv_stride*2,
                       targetSize.width, targetSize.height);
    
    CVPixelBufferUnlockBaseAddress(source_pixelBuffer, 0);
    CVPixelBufferUnlockBaseAddress(dst_pixelBuffer, 0);
    
    delete [] argb_scale_dst_buf;
    
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转自http://www.jianshu.com/p/a91502c00fb0 YUV YUV是一种颜色空间,基于...
    沃伦盖茨阅读 1,136评论 0 2
  • 第一步:引入chart.js文件。此工具库在全局命名空间中定义了chart变量。 chart.js文件下载Rele...
    西可目阅读 3,751评论 2 4
  • http://blog.csdn.net/x454045816/article/details/52153250 ...
    G风阅读 7,236评论 0 1
  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,779评论 2 32
  • 今天办公室里的老师说, 人生总要经历一次轰轰烈烈的爱情,到老可以留作回忆。 我在想,我的这段假装快要忘记的往事,是...
    Sissel_F阅读 283评论 0 0