第22讲 录像使用persistentinputsurface -凯发k8旗舰厅

本讲是android camera性能分析专题的第22讲,我们介绍录像使用persistinputsurface,包括如下内容:

  1. 为什么要使用persistentinputsurface
  2. 使用persistentinputsurface的步骤
  3. geekcamera2 录像使用persistinputsurface实战
  4. 录像使用persistinputsurface trace简单分析
资源 描述
在线课程
知识星球 星球名称:深入浅出android camera
星球id: 17296815
wechat 极客笔记圈

为什么要使用persistentinputsurface

  1. app完全掌控录像surface的生命周期,可以避免如下难以处理的问题
    • 当video encoder发生错误时(比如storage满了,无法正常写入),会先release recording surface再返回错误给camera app,而此时可能camera framework正在送buffer给recording surface,surface如果被突然销毁,camera framework会抛exception
  2. 当重复录像时,第二次录像可以省掉mediarecorder.prepare时间
    • 理论上可行,留给同学们去验证

使用persistentinputsurface的步骤

可以分为如下步骤:

surface persistsurface = mediacodec.createpersistentinputsurface()
mediarecorder.setinputsurface(persistsurface)
mediarecorder.prepare()
createcapturesession with persist input surface
persistsurface.release()
  1. 通过mediacodec.createpersistentinputsurface()创建一个surface,此时surface的属性,比如宽、高、format、usage等都未指定
  2. 将创建好的persistent input surface通过mediarecorder.setinputsurface设置给mediarecorder
  3. 调用mediarecorder的prepare方法,这样该surface就可以拿去用了
  4. 创建camera capture session时可以使用该surface了
  5. 当退出video模式时(切其他模式或进入setting去切录像分辨率),销毁persistent input surface,否则每次录像可以重用该surface

该surface的生命周期完全可以由app来控制

geekcamera2 录像使用persistentinputsurface实战

具体见视频讲解,核心函数如下:

public void copytomediarecorder(mediarecorder media_recorder, boolean slow_motion, surface persistsurface) {
    if( mydebug.log )
        log.d(tag, "copytomediarecorder: "   media_recorder   tostring());
    if( record_audio && !slow_motion) {
        if( mydebug.log )
            log.d(tag, "record audio");
        media_recorder.setaudiosource(this.audiosource);
    }
    media_recorder.setvideosource(this.videosource);
    // n.b., order may be important - output format should be first, at least
    // also match order of mediarecorder.setprofile() just to be safe, see https://stackoverflow.com/questions/5524672/is-it-possible-to-use-camcorderprofile-without-audio-source
    media_recorder.setoutputformat(this.fileformat);
    if (slow_motion) {
        media_recorder.setvideoframerate(30);
    } else {
        media_recorder.setvideoframerate(this.videoframerate);
    }
    media_recorder.setcapturerate(this.videocapturerate);
    media_recorder.setvideosize(this.videoframewidth, this.videoframeheight);
    media_recorder.setvideoencodingbitrate(this.videobitrate);
    media_recorder.setvideoencoder(this.videocodec);
    if( record_audio && !slow_motion) {
        media_recorder.setaudioencodingbitrate(this.audiobitrate);
        media_recorder.setaudiochannels(this.audiochannels);
        media_recorder.setaudiosamplingrate(this.audiosamplerate);
        media_recorder.setaudioencoder(this.audiocodec);
    }
    if( mydebug.log )
        log.d(tag, "done: "   media_recorder);
    if (persistsurface != null) {
        media_recorder.setinputsurface(persistsurface);
    }
}

注意,使用persistent input surface后不能再从mediarecorder去getsurface()了。

录像使用persistentinputsurface trace简单分析

从geekcamera app的进程我们能看到graphicbuffersource的trace

录像使用persistentinputsurface trace简单分析

camera课程

python教程

java教程

web教程

数据库教程

图形图像教程

办公软件教程

linux教程

计算机教程

大数据教程

开发工具教程

android camera性能分析

网站地图