Android:关于mediacodec编码camera yuv数据帧率过低的问题
来源:互联网 发布:mac怎么输入法 编辑:程序博客网 时间:2024/05/21 19:32
网上有很多android平台关于mediacodec编码yuv数据为H264数据出现帧率过低的问题
主要是
在while (isRuning) {中有NV21ToNV12(input,yuv420sp,m_width,m_height);这样一段代码,其实大部分博客里面都是直接在java层处理的代码如下:private void NV21ToNV12(byte[] nv21,byte[] nv12,int width,int height){ if(nv21 == null || nv12 == null)return; int framesize = width*height; int i = 0,j = 0; System.arraycopy(nv21, 0, nv12, 0, framesize); for(i = 0; i < framesize; i++){ nv12[i] = nv21[i]; } for (j = 0; j < framesize/2; j+=2) { nv12[framesize + j-1] = nv21[j+framesize]; } for (j = 0; j < framesize/2; j+=2) { nv12[framesize + j] = nv21[j+framesize-1]; }}测试机器:三星note5的机器上测试了一下 这个过程一般要消耗70-100ms在cameracallback的回调获取的buffer是 30fps最终编码出来的数据 只有10fps说明处理一帧数据一般消耗100ms。而处理 NV21ToNV12 的过程就花了大部分时间
优化1:用JNI调用底层来处理啊,这一部分优化后发现话费的时间在30-50ms之间。优化2:System.arraycopy(nv21, 0, nv12, 0, framesize); for(i = 0; i < framesize; i++){ nv12[i] = nv21[i]; }这部分代码发现重复了,本来直接把nv21的前framesize中的内容copy到nv12中,而这里等于重复了两次的。可以把for(i = 0; i < framesize; i++){ nv12[i] = nv21[i]; }这部分代码去掉发现优化后的结果,这部分花费的时间在10-30ms之间。再次编码帧率基本稳定在30fps左右的最终代码如下:java层的调用方法:jni_handle_nv21_to_nv12(input,yuv420sp,m_width,m_height);底层的具体实现:JNIEXPORT jbyteArray JNICALLJava_com_example_lyc_sampleffpeg_VideoPlayer_jni_1handle_1nv21_1to_1nv12(JNIEnv *env, jclass type, jbyteArray input_, jbyteArray yuv420sp_, jint m_width, jint m_height) { jbyte *input = env->GetByteArrayElements(input_, NULL); jbyte *yuv420sp = env->GetByteArrayElements(yuv420sp_, NULL); int framesize = m_width*m_height; int i = 0,j = 0; memcpy(yuv420sp, input, framesize); for (j = 0; j < framesize/2; j+=2) { yuv420sp[framesize + j-1] = input[j+framesize]; } for (j = 0; j < framesize/2; j+=2) { yuv420sp[framesize + j] = input[j+framesize-1]; } // TODO jbyteArray it = env->NewByteArray(framesize * 3 / 2); env->SetByteArrayRegion(it, 0, framesize * 3 / 2 , yuv420sp); env->ReleaseByteArrayElements(input_, input, 0); env->ReleaseByteArrayElements(yuv420sp_, yuv420sp, 0); return it;}----------------------------------------分割线------------------------------------发现目前还是不能满足我现在的处理速度的其实这个处理 就是在uv的数据调换位置的 ,其实就是一个交换数值的算法的。根本不用进行memcpy代码如下:JNIEXPORT jbyteArray JNICALLJava_com_example_lyc_sampleffpeg_VideoPlayer_jni_1handle_1nv21_1to_1nv12(JNIEnv *env, jclass type, jbyteArray input_, jint m_width, jint m_height) { jbyte *input = env->GetByteArrayElements(input_, NULL); int framesize = m_width*m_height; int i = 0,j = 0; jbyte temp; for (j = 0; j < framesize/2; j+=2) { temp = input[ j + framesize - 1]; input[framesize + j - 1 ] =input[ j + framesize]; input[ j + framesize ] = temp; } jbyteArray it = env->NewByteArray(framesize * 3 / 2); env->SetByteArrayRegion(it, 0, framesize * 3 / 2 , input); env->ReleaseByteArrayElements(input_, input, 0); return it;}
0 0
- Android:关于mediacodec编码camera yuv数据帧率过低的问题
- 【Android】Android Camera实时数据采集及通过MediaCodec硬编码编码数据的流程
- 【Android】Android Camera实时数据采集及通过MediaCodec硬编码编码数据的流程
- 【Android】Android Camera实时数据采集及通过MediaCodec硬编码编码数据的流程
- Mediacodec编码Camera摄像头数据技术要点总结
- Android 用MediaCodec实现编码camera再解码
- 关于Android MediaCodec 的内容
- 关于Android MediaCodec 的内容
- iOS获取camera的yuv数据
- Android MediaCodec 视频编码
- Android Camera2 Mediacodec编码
- Mediacodec编码UDP传输,接收到数据不能解码显示的问题
- android camera yuv帧水平翻转
- android camera yuv帧水平翻转
- MediaCodec 编码H264 编码一帧后dequeueOutputBuffer为-1的问题
- MediaCodec 编码H264 编码一帧后dequeueOutputBuffer为-1的问题
- 关于android的camera平滑切换问题
- android中MediaCodec硬编码中关键帧间隔时间设置问题
- 二维码 ThoughtWorks.QRCode 之 index was outside bounds of the array
- CRTP 奇异递归模板模式
- MemCache超详细解读
- 在Java中使用Jedis操作Redis,在高并发的情况下,应用卡死、报无法获取连接错误的处理方式
- 字典序
- Android:关于mediacodec编码camera yuv数据帧率过低的问题
- webpack入门
- leetcode-150-Evaluate Reverse Polish Notation
- Codeforces 557B Pasha and Tea【二分+思维】
- 树莓派3B安装Chromium
- 二维码 ThoughtWorks.QRCode 简单使用实例
- 如何关闭TortoiseSVN的TSVNCache.exe进程
- vs2010软件使用总结
- public、private、protected区别-访问权限