AV Foundation ⑮ 使用高帧率捕捉

AVFoundation 中关于高帧率的支持

    在 高帧率捕捉是开发者在一些场景中希望使用的技术。苹果公司并没有单独推出这一个功能,而是通过 AV Foundation 框架为这个功能给出了强大的支撑。

  • 捕捉: 支持每秒 60 帧 (fps) 的完整 720p(1280 x 720 像素)分辨率,包括视频稳定和支持启动 droppable P-frames (H.264 编码的特性 ),即使在较慢和较旧的硬件上也可以流畅地播放电影。
  • 播放: AVPlayer 已经支持以多种播放帧率播放资源内容,增强了对慢速和快速播放的音频支持,AVPlayerItem 有一个 audioTimePitchAlgorithm 可以允许以较慢或较快的速度设置算法。
  • 编辑:全面支持可变组合成中执行缩放编辑。
  • 导出:AV Foundation 提供了保存原始帧率的功能,所以 60 fps 影片可以被导出,或者将电影转换为任意较慢的帧速率,例如每秒 30 帧。

高帧率捕捉概述

    使用高帧率捕捉的首先要获取到设备的最高质量格式,找到它相关的帧时长,之后手动设置捕捉设备的格式和帧时长。AVCaptureDeviceFormat 类确定设备的捕获能力。此类具有返回支持的媒体类型、帧速率、视野、最大缩放系数、是否支持视频稳定等的方法,其具有一个 videoSupportedFrameRateRanges 属性,包含了一个 AVFrameRateRange 对象数组,其中带有格式所支持的最小帧率、最大帧率和时长信息。

支持高帧率捕捉

由于查找设备最大帧率的过程较为麻烦,通过给 AVCaptureDevice 添加分类的方法来实现,开启高帧率率捕捉的功能:

  1. 新增分类声明两个方法 - (BOOL)supportsHighFrameRateCapture 判断当前设备是否支持高帧率捕捉和 - (BOOL)enableMaxFrameRateCapture;开启高帧率捕捉
  2. 实现 findHighestQualityOfService 遍历所有的捕捉设备的支持 formats,并对每一个元素获取相应的 codeType,这里筛选出 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 格式,接着遍历 AVFrameRateRange 对象数组,获取最大的 AVFrameRateRange,最终找到提供的最高的format 和帧率并将其存储起来。
  3. 实现 supportsHighFrameRateCapture,若最大帧率大于 30 fps,则支持高帧率;
  4. 实现 enableMaxFrameRateCapture,修改捕捉设备的 format 、最小帧时长 activeVideoMinFrameDuration 和最大帧时长activeVideoMaxFrameDuration

@interface AVCaptureDevice (QualityOfService)

- (BOOL)supportsHighFrameRateCapture;
- (BOOL)enableMaxFrameRateCapture;

@end
const void* kMaxFormat = &kMaxFormat;
const void* kMaxFrameRateRange = &kMaxFrameRateRange;
@implementation AVCaptureDevice (QualityOfService)

- (void)setMaxFormat:(AVCaptureDeviceFormat *)maxFormat{
    objc_setAssociatedObject(self, kMaxFormat, maxFormat, OBJC_ASSOCIATION_RETAIN);
}

- (AVCaptureDeviceFormat *)maxFormat{
    return objc_getAssociatedObject(self, &kMaxFormat);
}

- (void)setMaxFrameRateRange:(AVFrameRateRange*)maxFrameRateRange{
    objc_setAssociatedObject(self, kMaxFrameRateRange, maxFrameRateRange, OBJC_ASSOCIATION_RETAIN);
}

- (AVFrameRateRange *)maxFrameRateRange{
    return objc_getAssociatedObject(self, &kMaxFrameRateRange);
}

- (BOOL)supportsHighFrameRateCapture {
    if (![self hasMediaType:AVMediaTypeVideo]) {                            // 1
        return NO;
    }
    return [self isHighFrameRate];              // 2
}

- (BOOL)enableMaxFrameRateCapture{

    if (![self isHighFrameRate]) {                                             // 1
        
        return NO;
    }

    if ([self lockForConfiguration:nil]) {                                // 2

        CMTime minFrameDuration = [self maxFrameRateRange].minFrameDuration;

        self.activeFormat = [self maxFormat];                                     // 3
        self.activeVideoMinFrameDuration = minFrameDuration;                // 4
        self.activeVideoMaxFrameDuration = minFrameDuration;

        [self unlockForConfiguration];
        return YES;
    }
    return NO;
}

- (void)findHighestQualityOfService {

    AVCaptureDeviceFormat *maxFormat = nil;
    AVFrameRateRange *maxFrameRateRange = nil;

    for (AVCaptureDeviceFormat *format in self.formats) {

        FourCharCode codecType =                                           
            CMVideoFormatDescriptionGetCodecType(format.formatDescription);

        if (codecType == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) { 

            NSArray *frameRateRanges = format.videoSupportedFrameRateRanges;

            for (AVFrameRateRange *range in frameRateRanges) {              
                if (range.maxFrameRate > maxFrameRateRange.maxFrameRate) {
                    maxFormat = format;
                    maxFrameRateRange = range;
                }
            }
        }
    }

    [self setMaxFormat:maxFormat];
    [self setMaxFrameRateRange:maxFrameRateRange];


}

- (BOOL)isHighFrameRate {
    AVFrameRateRange *frameRateRange = [self maxFrameRateRange]
    if(!frameRateRange){
       [self findHighestQualityOfService];
    }
    return [self maxFrameRateRange].maxFrameRate > 30.0f;
}

@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356