NDK 图像处理遇到的相关问题
NDK 图像处理遇到的相关问题
写在前面的话:
博主最近在学习Android NDK 视频处理相关东西,出现很多诡异问题,记录一下。
文章地址:http://blog.csdn.net/mikulee/article/details/46865139
欢迎转载,请注明出处,谢谢。
1、SEGV_ACCERR
我在一个函数里面创建了一个640*480大小的一维数组,作为图像数据,例如
int testPixels(){int len=640*480;int pixels[len];int index=0;for(;index<len;index++){pixels[index]=0xffff0000;}
return 0;
}
代码没问题,但是在真机上运行的话,会抛出SEGV_ACCERR错误,而且通过堆栈无法定位问题所在。
通过错误日志看出是在数组index达到45000以后,pixels就无法访问了,就会出现SEGV_ACCERR。上网查找资料,无果。怀疑是int的数值范围不够,sizeof(int)=4,是可以容纳640*480数值的。
最后,灵光一现,会不会是函数栈大小的问题。这个应该和编译器或什么有关。所以决定尝试在堆上建立pixels的存储空间,如下面代码:
int* pixels=NULL;
int testPixels(){
int len=640*480;
if(pixels==NULL){//这里如果为空,就创建一个。暂时不考虑释放问题。pixels=(int*)malloc(len*sizeof(int));}int index=0;for(;index<len;index++){pixels[index]=0xffff0000;}
return 0;
}
问题得以解决。
2、JNI 中填充bitmap颜色不正确
在网上找了个函数,为YUV转argb的,原文在这里(Android视频渲染: YUV转RGB ),我稍作改动,可以直接填充java传过来的bitmap,以免每次都重复创建,导致app不断GC.但是颜色总是有问题,经多方查究,终于解决。
int g_v_table[256],g_u_table[256],y_table[256];
int r_yv_table[256][256],b_yu_table[256][256];
int inited = 0;
void initTable()
{if (inited == 0){inited = 1;int m = 0,n=0;for (; m < 256; m++){g_v_table[m] = 833 * (m - 128);g_u_table[m] = 400 * (m - 128);y_table[m] = 1192 * (m - 16);}int temp = 0;for (m = 0; m < 256; m++)for (n = 0; n < 256; n++){temp = 1192 * (m - 16) + 1634 * (n - 128);if (temp < 0) temp = 0; else if (temp > 262143) temp = 262143;r_yv_table[m][n] = temp;temp = 1192 * (m - 16) + 2066 * (n - 128);if (temp < 0) temp = 0; else if (temp > 262143) temp = 262143;b_yu_table[m][n] = temp;}}
}
jint Java_com_miku_jni_ImageUtilEngine_decodeYUV420SP(JNIEnv * env,jobject thiz, jbyteArray buf, jobject bitmap, jint width, jint height) {AndroidBitmapInfo info;int* pixels = NULL;if (AndroidBitmap_getInfo(env, bitmap, &info) >= 0) {AndroidBitmap_lockPixels(env, bitmap, (void **) &pixels);jbyte * yuv420sp = (*env)->GetByteArrayElements(env, buf, 0);int frameSize = width * height;initTable();int i = 0, j = 0, yp = 0;int uvp = 0, u = 0, v = 0;for (j = 0, yp = 0; j < height; j++) {uvp = frameSize + (j >> 1) * width;u = 0;v = 0;for (i = 0; i < width; i++, yp++) {int y = (0xff & ((int) yuv420sp[yp]));if (y < 0)y = 0;if ((i & 1) == 0) {v = (0xff & yuv420sp[uvp++]);u = (0xff & yuv420sp[uvp++]);}int y1192 = y_table[y];int r = r_yv_table[y][v];int g = (y1192 - g_v_table[v] - g_u_table[u]);int b = b_yu_table[y][u];if (g < 0)g = 0;else if (g > 262143)g = 262143;//原文这里如果直接赋值给bitmap的像素的话就有问题(并不是函数有问题),//因为bitmap的数 据是RGBARGBA这样的序列//但这里pixels[yp]为整形,数据格式是(小端格式)LittleEndian//直接赋值一个整数,例如pixels[yp]=0xff051003(ff为A,05为R,10为G,03为B)的话,//在内存中是这样的存储的[031005ff],并不是你直接赋的值[ff051003]。对比[031005ff]//和RGBA顺序,03(B)和05(R)的位置刚好倒置了,所以在机器上,显示的颜色就不正确了。//pixels[yp] = 0xff000000 | ((r << 6) & 0xff0000)// | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);//改为下面,颜色即可正确pixels[yp] = 0xff000000 | ((b << 6) & 0xff0000)| ((g >> 2) & 0xff00) | ((r >> 10) & 0xff);}}(*env)->ReleaseByteArrayElements(env, buf, yuv420sp, 0);AndroidBitmap_unlockPixels(env, bitmap);}return 1;
}
3、FFmpeg相关
FFmpeg编译可以参考这位大神的编译指南FFmpeg的Android平台移植,我编译的是当前最新的2.7.1版本,按步骤来,能正常编译出各个so库文件。
在我的nexus 5下,使用没任何问题。但在小米4.1系统下,遇到如下的问题:
Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1891]: 150 could not load needed library ‘libswresample-1.so’ for ‘libavcodec-56.so’ (load_library[1093]: Library ‘libswresample-1.so’ not found)。
明明lib目录下是有libswresample-1.so,怎么就说没找到呢。
网上搜索并无真正答案。
最后灵光一现,libswresample-1.so’ for ‘libavcodec-56.so’ 的意思应该是libswresample-1.so必须先于libavcodec-56.so之前加载,其他库也是,有先后顺序之分的。在高版本的android上面没问题,但低版本要注意次序
经过几下尝试,加载顺序如下:
static {//先按顺序加ffmpeg动态库System.loadLibrary("avutil-54");System.loadLibrary("swresample-1");System.loadLibrary("avcodec-56");System.loadLibrary("swscale-3");System.loadLibrary("avformat-56");System.loadLibrary("avfilter-5");System.loadLibrary("avdevice-56");//最后才加载自己写的库System.loadLibrary("ffmpegNative");}
NDK 图像处理遇到的相关问题相关推荐
- 各种与视频编解码以及视频图像处理的应用相关的新技术,新方法,各种软件开发相关的算法,思想。...
1. 各种视频压缩标准(MPEG2, MPEG4, H261/2/3/4,X264, T264以及H264(AVC)和HEVC(H265)等的优化,改进,创新. 2. 各种不同平台的(CPU, GPU ...
- 图像处理的一些相关知识(Related knowledge for IQA)
图像处理的一些相关知识 logistic transform 一般的logistic function 逻辑回归的向量化实现样例 - Ufldl 可向量化编程 分类问题中常用,代替开关函数 IQA算法 ...
- Opencv-python学习路线与图像处理方面的相关技能树(西瓜6总结)
可能是因为Opencv的博客不能写得太水,我个人不太想写Opencv的博客,但又不得不写. Opencv-python学习路线与图像处理方面的相关技能树(西瓜6总结) 标题 Opencv-python ...
- matlab相位相关图像配准,数字图像处理,相位相关图像配准
前言 图像配准是图像处理的基本任务之一,用于将不同时间.不同传感器.不同视角及不同拍摄条件下获取的关于同一目标或场景的两幅或多幅图像进行主要是几何意义上的匹配套和的过程.在对图像配准的研究过程中,大量 ...
- 数字图像处理:空间相关与卷积操作
目录 1.数字图像处理中相关和卷积的区别 2.线性滤波 3.卷积的操作 3.1.卷积介绍 3.2.边界补充方法 3.3.常用卷积核及其意义 3.4.卷积的计算 3.4.1.空域计算-直接2D卷积 3. ...
- 图像处理基础——图像相关术语总结
一.图像的概念 1.图像: "图"是物体反射或透射光的分布,"像"是人的视觉系统所接受的图在人脑中所形版的印象或认识,照片.绘画.剪贴画.地图.书法作品.手写汉 ...
- 图像处理与计算机视觉基础相关领域的经典书籍以及论文
原文的链接是http://www.iask.sina.com.cn/u/2252291285/ish. 我非常感谢原作者杨晓冬辛勤地编写本文章,并愿意共享出来.我也希望转载本文的各位朋友,要注明原作者 ...
- 数字图像处理:理解什么是卷积(滤波)、卷积核以及相关参考资料
☞ ░ 前往老猿Python博文目录 ░ 一.概述 在图像处理领域,滤波.卷积都是相同的含义,都是一种图像的卷积操作,与此相对应通过卷积处理图像时,需要使用一个用于计算图像像素的参考矩阵,这个矩阵称为 ...
- matlab图像处理命令(一)
转自:http://blog.csdn.net/langyuewu/archive/2009/05/02/4144120.aspx(非原处) 1.applylut 功能: 在二进制图像中利用looku ...
最新文章
- C语言字符串处理的库函数
- RandLA-Net测试
- python实现文件下载-Python+django实现文件下载
- EF 4.1中内部经常提交的 exec sp_reset_connection 的用途原来是为了重用池中的连接...
- Redis缓存雪崩、缓存穿透、热点Key
- SpringBoot 自带工具类~StringUtils
- android NullPointerException (转)
- 什么是 10x 程序员
- Meteor:用户账号管理添加密码和微博weibo账号系统支持
- 计算机流水线作业员做什么,电子厂普通作业员的工作流程是什么
- 物联网技术或颠覆传统高等教育
- 玩游戏?或许游戏正在拯救部分人
- 《团队-科学计算器-项目进度》
- 使用div模拟table
- scratch编程小游戏——黄金矿工
- 学习笔记 java学习(三)
- 使用jQuery快速高效制作网页交互特效 第五章 上机练习四 制作广告图片轮播切换效果
- 最近微信上很火的小游戏【壹秒】android版——开发分享
- google新搜索网站
- 干货满满【JVM监控及诊断工具-GUI篇】