直播预览层(AVCaptureVideoPreviewLayer)底层实现
来源:互联网 发布:适合编程的输入法 编辑:程序博客网 时间:2024/06/05 16:54
分析sampleBuffer(帧数据)
通过设置AVCaptureVideoDataOutput的代理,就能获取捕获到一帧一帧数据
[videoOutputsetSampleBufferDelegate:selfqueue:videoQue];
拿到这一帧一帧数据(sampleBuffer)怎么显示到屏幕上了
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
sampleBuffer(帧数据)
视频本质是由很多帧图片组成
表示一帧视频/音频数据
通过sampleBuffer可以获取当前帧信息
CVImageBufferRef(CMSampleBufferGetImageBuffer):编码前,解码后,图片信息
CMSampleBufferGetDuration获取当前帧播放时间:用于记录视频播放时间
CMSampleBufferGetPresentationTimeStamp获取当前帧开始时间(PTS):用于做音视频同步
PTS:Presentation Time Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来
DTS:Decode Time Stamp。DTS主要是标识读入内存中的比特流在什么时候开始送入解码器中进行解码
(CMVideoFormatDescription)CMSampleBufferGetFormatDescription:视频编码,解码格式描述信息,通过它能获取sps,pps,编码成H264,就会生成一段NALU,这里面就包含sps,pps。
(CMBlockBuffer)CMSampleBufferGetDataBuffer:编码后,图像数据;
视频帧的格式,可以在采集端的AVCaptureVideoDataOutput配置
// RGBvideoOutput.videoSettings = @{(NSString *)kCVPixelBufferPixelFormatTypeKey :@(kCVPixelFormatType_32BGRA) }
//
YUV(Full)[videoOutputsetVideoSettings:[NSDictionarydictionaryWithObject:[NSNumbernumberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
//
YUV[videoOutputsetVideoSettings:[NSDictionarydictionaryWithObject:[NSNumbernumberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
显示原理
预览层实现原理:
取出捕获到的帧(CMSampleBufferRef) -> 获取帧里面图片信息(CVImageBufferRef) -> 转换成UIImage -> 设置为UIImageView的image就能实时显示捕获的画面.
因为是连续采集,每一帧都会变成图片显示出来,就相当于一串连贯的图片在播放,就形成视频了。
CVImageBufferRef 如何转换成 UIImage
使用CoreImage框架,前提CVImageBufferRef是RGB格式
CVImageBufferRef -> CIImage -> UIImage
注意点:设置UIImageView一定要放在主线程,默认接收到CMSampleBufferRef的代理方法不在主线程
- (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection{
if(_videoConnection == connection) {
// 获取图片信息
CVImageBufferRef imageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);
// 转换为CIImageCIImage*ciImage = [CIImageimageWithCVImageBuffer:imageBuffer];
// 转换UIImageUIImage*image = [UIImageimageWithCIImage:ciImage];
// 回到主线程更新UIdispatch_sync(dispatch_get_main_queue(), ^{self.imageView.image = image;
});
}}
注意点二:CIImage和UIView坐标系是反的,需要设置UIImageView宽度为屏幕高度,长度为屏幕宽度,在旋转90度,还得设置锚点,自己画图就知道怎么旋转了
- (UIImageView *)imageView{if(_imageView==nil) {
_imageView= [[UIImageView alloc] init];
_imageView.bounds = CGRectMake(0,0, self.view.bounds.size.height, self.view.bounds.size.width);
_imageView.layer.anchorPoint = CGPointMake(0,0);
_imageView.layer.position= CGPointMake(self.view.bounds.size.width,0);
_imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
[self.view addSubview:_imageView];
}
return_imageView;
}
YUV与RGB视频格式讲解
YUV:流媒体的常用编码方式, 对于图像每一点,Y确定其亮度,UV确认其彩度.
为什么流媒体需要用到YUV,相对于RGB24(RGB三个分量各8个字节)的编码格式,只需要一半的存储容量。在流数据传输时降低了带宽压力。
YUV存储方式主要分为两种:Packeted 和 Planar。
Packeted方式类似RGB的存储方式,以像素矩阵为存储方式。
Planar方式将YUV分量分别存储到矩阵,每一个分量矩阵称为一个平面。
YUV420即以平面方式存储,色度抽样为4:2:0的色彩编码格式。其中YUV420P为三平面存储,YUV420SP为两平面存储。
RGB:在渲染时,不管是OpenGL还是iOS,都不支持直接渲染YUV数据,底层都是转为RGB,所以在显示到屏幕,必须用RGB.
- 直播预览层(AVCaptureVideoPreviewLayer)底层实现
- 直播预览层添加滤镜效果(CIFilter使用场景)
- iOS直播app——GPUImage渲染底层实现
- j2me网上直播第2课 UI组件和在底层屏幕实现贪食蛇
- 应用层和驱动层的同步与异步的处理逻辑及底层实现
- 应用层和驱动层的同步与异步的处理逻辑及底层实现
- 应用层和驱动层的同步与异步的处理逻辑及底层实现
- iOS-直播开发(开发从底层做起)
- Android开发 摄像头SurfaceView预览 背景带矩形框 实现(原理:双surfaceview,顶层画矩形框,底层预览视频)
- 摄像头预览的背景带矩形框效果的实现(原理:双surfaceview,顶层画矩形框,底层预览视频)
- Android开发 摄像头SurfaceView预览 背景带矩形框 实现(原理:双surfaceview,顶层画矩形框,底层预览视频)
- css弹出层 覆盖底层
- 只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理:底层SurfaceView+上层绘制ImageView)
- position:fixed;实现底层页面不跟随浮层模块滚动
- 从底层谈WebGIS 原理设计与实现(八):WebGIS中栅格图层的设计
- 4-安卓底层-HAL层-实现安卓控制LED
- 弹出层 图片预览功能
- iphone直播的实现
- 无人驾驶技术系列(干货)
- 协作多线程和抢占多线程
- C++编程风格
- 直播预览层添加滤镜效果(CIFilter使用场景)
- 集合框架
- 直播预览层(AVCaptureVideoPreviewLayer)底层实现
- 各种机器学习的应用场景分别是什么
- nodejs笔记
- dpkg error: package `x' contains empty filename 和 pakage missing 解决办法...
- docker server gave HTTP response to HTTPS client 问题处理办法
- Linux下用SCP无需输入密码传输文件
- Spring面向切面编程(AOP-execution表达式)
- hikaricp配置数据源
- R语言长小数计算精度不准确