-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Open
Description
我看您是通过glReadPixels获得像素的
GLES20.glViewport(0, 0, mInputWidth, mInputHeight);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mGLFboId[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glReadPixels(0, 0, mInputWidth, mInputHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mGLFboBuffer);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight);
但是在有些机子上效率还是不够,尽管我已经用了beautify_fragment_low
目前只有发现grafika的方法效率可以,但是我又发现MediaCodec的KEY_FRAME_RATE设置了无效,我查了google说它是由输入源确定的(比如摄像头),所以如果我想录制15帧视频,就只有2个方法
1、修改Camera的fps,但是当我设置成为15帧时会明显出现卡顿
2、先编码成h264然后在解码成yuvi420,最后在进行一次编码,这样做明显非常多余
请问您有什么好方法吗?
Activity
begeekmyfriend commentedon Feb 17, 2017
你说的没错,
glReadPixels
的效率问题,#324 已经吐槽过了,并没有太好的兼容性方法,估计只有魔改了~MediaCodec
直接从surface读取编码,然后再解码,加特效(包括旋转翻转等),这种做法也很难看。只能说一些机子上设备驱动太差了(glReadPixels也可以看做设备驱动读接口),不过建议你对比一下不开美颜时的帧率,美颜再怎么优化也不可能比原始帧率高。如果原始帧率就很低,那就不单单是
glReadPixels
的问题,估计只能考虑换机型了。a483210 commentedon Feb 20, 2017
谢谢您的回答,我用glReadPixels测试过一些机型,在索尼三星等机子上效率非常高,但是在国产机子上效率就非常差,这是不是因为国产的接口优化差呢?
还有从native上gles动刀大概怎么做?我不太理解您的意思。
notedit commentedon Feb 20, 2017
你可以google EGLImageKHR
begeekmyfriend commentedon Feb 20, 2017
建议你先跑一个non-gpuimage分支测试一下fps,如果还是太差就别浪费时间了。
a483210 commentedon Feb 20, 2017
@notedit 事实上我查找过EGLImageKHR,但是我找不到GraphicBuffer.h,我看他好像在android的源码里面,我在ndk里面引用不到,然后有人说从源码里提取,事实上我觉得这不太靠谱。所以我最终放弃了EGLImageKHR。
http://stackoverflow.com/questions/23261662/how-to-use-graphicbuffer-in-android-ndk 例子
您有什么好方法可以解决该问题吗?
@begeekmyfriend 我测试过https://github.com/wuhaoyu1990/MagicCamera 项目采用low的情况下大部分机子都能保持流畅,如果实在没办法我只能用grafika的方法了。
begeekmyfriend commentedon Feb 20, 2017
Grafika用什么方式将GPU memory的数据拷贝到CPU memory的?
a483210 commentedon Feb 20, 2017
它通过MediaCodec
format.setInteger(MediaFormat.KEY_COLOR_FORMAT,MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)
将surface里的数据直接编码
https://github.com/wuhaoyu1990/MagicCamera/blob/master/Project-AndroidStudio/magicfilter/src/main/java/com/seu/magicfilter/encoder/video/VideoEncoderCore.java
详细做法
notedit commentedon Feb 20, 2017
Grafika 的做法必须4.3 以上
begeekmyfriend commentedon Feb 20, 2017
哦,就是上面第二种啊,多一道编解码,效果反而比
glReadPixels
好,太悲催了notedit commentedon Feb 20, 2017
EGLImageKHR 为什么不靠谱 我身边认识的公司 就有用的
begeekmyfriend commentedon Feb 20, 2017
@notedit Grafika的方式要解码一遍,加特效后还要再编码一遍,这种效率反而好也是没谁了
a483210 commentedon Feb 20, 2017
@notedit 您知道使用EGLImageKHR 具体应该怎么做吗?我对这里不是十分了解
notedit commentedon Feb 20, 2017
知道 @a483210
a483210 commentedon Feb 20, 2017
@notedit 额,能教下我吗?拜托了!
notedit commentedon Feb 20, 2017
不是几行代码可以搞定的 之前搞了很长时间才搞定
4.3 以下的机器可以不支持了, 直接渲染到Surface 上 然后用Mediacodec 就可以
4 remaining items
begeekmyfriend commentedon Feb 20, 2017
试试修改摄像头的帧率设置
a483210 commentedon Feb 20, 2017
我试过了,的确可以,但是如果我修改为低于24帧,就会感到明显的卡顿,所以这里我非常纠结
notedit commentedon Feb 20, 2017
我这边设置15帧 也没感觉卡
a483210 commentedon Feb 20, 2017
@notedit 额,您把摄像头浏览的fps设置成15帧不会感觉稍微有些卡顿么
notedit commentedon Feb 20, 2017
不会 在音视频通话里面15帧 很正常
a483210 commentedon Feb 20, 2017
@notedit 好的,我明天实验下,非常感谢
a483210 commentedon Feb 21, 2017
@notedit 我测试了下设置摄像头为15帧,但是从MediaCodec得到sps pps显示还是30帧,用FFmpeg检测出来的是24帧,也就是说当我放这个h264时是快进的
begeekmyfriend commentedon Feb 21, 2017
你的设备是手机?报上名来
a483210 commentedon Feb 21, 2017
索尼z2 应该说我没理解MediaCodec的sps pps是靠什么确定的
begeekmyfriend commentedon Feb 21, 2017
摄像头和编码器都设成15吗?
a483210 commentedon Feb 21, 2017
对,我也试过低于15帧的,也一样没用
jtyang commentedon Apr 8, 2017
请问下MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface具体要咋改呢?试了下@begeekmyfriend说的,“这段代码不要了”,貌似预览都有问题。
a483210 commentedon Apr 8, 2017
@jtyang 你可以看下我写的《Android 关于美颜/滤镜 从OpenGl录制视频的一种方案》希望能对你有所帮助
hirudo-zy commentedon Jul 6, 2017
@notedit 您好,想向您请教下EGLImageKHR获取数据的问题。当我使用
buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &ptr);
memcpy(pixels, ptr, wh4);
buffer->unlock();
获取数据时,我只能得到一个数据为空的ptr(有地址),不知道您遇到过这个问题吗?有什么好的建议吗?
Stack Overflow上类似的问题https://stackoverflow.com/questions/21151259/replacing-glreadpixels-with-egl-khr-image-base-for-faster-pixel-copy?noredirect=1&lq=1
liouvilles commentedon Nov 21, 2023
23年再回一句用ImageReader读合适吗