请选择 进入手机版 | 继续访问电脑版
查看: 3776|回复: 1

[经验分享]iOS网络通话本地回调画面(美颜)相关的格式转换

[复制链接]

353

主题

373

帖子

9万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
99944
发表于 2017-11-23 15:12:38 | 显示全部楼层 |阅读模式
1. kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 转换为 kCVPixelFormatType_32BGRA 格式

某些 iOS 第三方美颜 SDK 不接受 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 格式的 pixelBuffer,这里分享把它转成
kCVPixelFormatType_32BGRA 格式的示例代码。

VideoBufferConverter.zip (43 K) 下载次数:365


用到了云信改过的第三方库libyuv,二进制已经包含在云信SDK里面,需要把include里面libyuv的头文件都放到你得工程目录下,并在你得工程中正确设置 Header Search Paths。
这个改过的libyuv只能通过c++/object c++ 源文件调用,如果感觉不适,请自行编译libyuv,和云信并不冲突。


NTESVideoBufferConverter 类提供创建 BGRA 格式的pixelBuffer/sampleBuffer 的方法,创建并使用完以后需要你自己手动释放。


比如收到云信本地画面回调的sampleBuffer以后:
[url=]复制代码[/url]
  • CMSampleBufferRef sampleBufferBGRA = [NTESVideoBufferConverter createBGRASampleBufferFromNV12:sampleBuffer];
  • if (sampleBufferBGRA) {
  •     //use the sampleBuffer
  •     CFRelease(sampleBufferBGRA);
  • }



2. 第三方的yuv420p(I420)转换成sampleBuffer给云信发送

某些 iOS 第三方美颜 SDK 输出的画面是yuv420p/I420 格式的,这里贴一段把它转成 pixelBuffer的示例代码:
[url=]复制代码[/url]
  • - (CVPixelBufferRef)i420FrameToPixelBufferNVSI420Frame *)i420Frame
  • {
  •     if (i420Frame == nil) {
  •         return NULL;
  •     }
  •     CVPixelBufferRef pixelBuffer = NULL;
  •     NSDictionary *pixelBufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
  •     [NSDictionary dictionary], (id)kCVPixelBufferIOSurfacePropertiesKey, nil];
  •     CVReturn result = CVPixelBufferCreate(kCFAllocatorDefault,
  •                                                                           i420Frame.width,
  •                                                                           i420Frame.height,
  •                                                                           kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
  •                                                                           (__bridge CFDictionaryRef)pixelBufferAttributes,
  •                                                                           &pixelBuffer);
  •     if (result != kCVReturnSuccess) {
  •         NVSLogErr(@"Failed to create pixel buffer: %d", result);
  •         return NULL;
  •     }
  •     result = CVPixelBufferLockBaseAddress(pixelBuffer, 0);
  •     if (result != kCVReturnSuccess) {
  •         CFRelease(pixelBuffer);
  •         NVSLogErr(@"Failed to lock base address: %d", result);
  •         return NULL;
  •     }
  •     uint8 *dstY = (uint8 *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
  •     int dstStrideY = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0);
  •     uint8* dstUV = (uint8*)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
  •     int dstStrideUV = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1);
  •     int ret = libyuv_nvs::I420ToNV12([i420Frame dataOfPlane:NVSI420FramePlaneY], [i420Frame strideOfPlane:NVSI420FramePlaneY],
  •                                                             [i420Frame dataOfPlane:NVSI420FramePlaneU], [i420Frame strideOfPlane:NVSI420FramePlaneU],
  •                                                             [i420Frame dataOfPlane:NVSI420FramePlaneV], [i420Frame strideOfPlane:NVSI420FramePlaneV],
  •                                                             dstY, dstStrideY, dstUV, dstStrideUV,
  •                                                             i420Frame.width, i420Frame.height);
  •     CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
  •     if (ret) {
  •         NVSLogErr(@"Error converting I420 VideoFrame to NV12: %d", result);
  •         CFRelease(pixelBuffer);
  •         return NULL;
  •     }
  •     return pixelBuffer;
  • }


NVSI420Frame 是我自己的内部格式,你需要从你的第三方 SDK 获取 yuv 数据的地址data、宽高信息width、height,以及stride。一般来说,各个分量地址的计算如下:
plane0 = data
plane1 = data + stride * height
plane2 = plane1 + stride * height / 4

stride0 = stride
stride1 = stride2 = stride /2

有兴趣的同学可以百度下yuv数据格式,方便理解

pixelBuffer 转成 sampleBuffer 的方法可以参考上面 NTESVideoBufferConverter 里面的实现。

用到了云信改过的 libyuv,头文件请去上面的压缩包里面获取。
回复

使用道具 举报

0

主题

1

帖子

4

积分

云客

Rank: 1

积分
4
发表于 2018-11-2 10:37:51 | 显示全部楼层
你好,你的这个demo能不能发我看下 496668219@qq.com,谢了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表