原YUV格式的解析 Android(安卓)NV21 视频采集
16lz
2021-01-24
最近在搞视频分析类的项目,android默认视频采集格式是NV21,Y Cr Cb格式,4.2.0.方式采样 还有其他采样方式,默认使用NV21
Sets the image format for preview pictures.
If this is never called, the default format will beNV21
, which uses the NV21 encoding format.
int | JPEG | Encoded formats. |
int | NV16 | YCbCr format, used for video. |
int | NV21 | YCrCb format used for images, which uses the NV21 encoding format. |
int | RGB_565 | RGB format used for pictures encoded as RGB_565 seesetPictureFormat(int) . |
int | UNKNOWN | |
int | YUY2 | YCbCr format used for images, which uses YUYV (YUY2) encoding format. |
int | YV12 | Android YUV format: This format is exposed to software decoders and applications. |
X X X X O O X X X X 即每4个Y对应一个U和一个V Y0U0V0 Y1 Y2U2V2 Y3 Y4 Y5 Y6 Y7 Y8U8V8 Y9 Y10U10V10 Y11 Y12 Y13 Y14 Y15 通过对采样数组的研究其存放规律是 YYYYY...(采样宽度width)...YYYYY ... ...(采样高度height) ... YYYYY...(采样宽度width)...YYYYY (vu)(vu)(vu)...(采样宽度)...(vu)(vu)(vu) ...(采样高度除以2,height/2,遇单加1) (vu)(vu)(vu)...(采样宽度)...(vu)(vu)(vu) 即width=320,height=480,采样Y值长度320×480,采样VU长度320×480/2.yuv420sp=data;总长度为宽高乘积的一点五倍
// YUV转RGB rgb长度即width×heght static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); } } }
以上是android自带的YUV420SP转RGB的函数,但是坑爹的问题在于函数处理数据的能力有限,我们有的时候并不需要全部转完毕再解析。 以下是更改后的方法,用于取值某点的RGB,在一些实时性要求的应用中可以用到 // 自定义RGB static public int myDecodeYUV420SP(byte[] yuv420sp, int width, int height, int mWidth, int mHeight) { // Y矩阵长度frameSize , V和U矩阵第一位即frameSize final int frameSize = width * height; // yp为Y在矩阵中的位置,yph为所需要点的高mHeight-1,ypw为所需要点的宽mWidth int yp, yph = mHeight - 1, ypw = mWidth; yp = width * yph + ypw; // uvp为 // uv在数组中的位置,V和U矩阵第一位即frameSize,yph>>1取值范围(0,0,1,1,2,2...)yph从0开始,即UV数组为Y数组的1/2. int uvp = frameSize + (yph >> 1) * width, u = 0, v = 0; // 获取Y的数值 int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((ypw & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp]) - 128; } else { u = (0xff & yuv420sp[uvp--]) - 128; v = (0xff & yuv420sp[uvp]) - 128; }
int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143;
return (0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff));
}
两套函数出来的数据int型需要转换成r/g/b。亮点就是转换方式
public static intred(int color)
Since: API Level 1Return the red component of a color int. This is the same as saying(color >> 16) & 0xFF
public static intgreen(int color)
Since: API Level 1Return the green component of a color int. This is the same as saying(color >> 8) & 0xFF
public static intblue(int color)
Since: API Level 1Return the blue component of a color int. This is the same as sayingcolor & 0xFF
至此yuv取点rgb完成 1 需要代码的童鞋可以留下你的email 2 如果描述有误请指正 3 感谢 幸福的起点 博主,更多视频格式说明请参照 http://hi.baidu.com/joygogo0130/blog/item/04b707529efbec090df3e345.html 4 更多视频问题 请参照 http://developer.android.com/reference/android/graphics/Camera.html http://ai4work.blog.163.com/blog/static/189873306201171883316264/更多相关文章
- Android(安卓)UI学习 - GridView和ImageView的使用
- Android实现圆角矩形和圆形ImageView的方式
- android 里 meta-data 的使用
- Android(安卓)创建与解析XML(二)—— Dom方式
- Android(安卓)OpenGL射线拾取&手势旋转(二)
- ConstraintLayout 实现水平方向 权重 效果
- Android如何设置圆角按钮 类似微信的登陆按钮
- android4.4 Launcher主菜单界面同样采用背景图片的方式
- Android实现ImageView图片双击放大及缩小