yuv420_to_nv21



#include <string.h>


void convert_yuv420_to_nv21(unsigned char * dest, const unsigned char * source, int width, int height)
{
int area = height * width;
int sqarea = area >> 3;
int qarea = area >> 2;


int count = sqarea;
const unsigned short * su = (const unsigned short *) (source + area);
const unsigned short * sv = (const unsigned short *) (source + area + qarea);
unsigned int * uv = (unsigned int *)(dest + area);

/* copy y as is */
memcpy(dest, source, area);


do
{
unsigned int u = *su++;
unsigned int v = *sv++;

*uv++ = ( ( (u & 0x00FF) << 8 ) |
( (u & 0xFF00) << 16) |
( (v & 0x00FF) )      |
( (v & 0xFF00) << 8) );
} while (--count);

}


注:这种转换是小端法机器上的转换

对于高效率的YUV420_888转NV21,我们可以使用Android提供的RenderScript库进行加速。RenderScript是Android中的高性能计算框架,可以在各种设备上进行优化的计算操作。以下是使用RenderScript进行高效率YUV420_888转NV21的示例代码: ```java public static void convertYUV420888ToNV21(Image image, byte[] nv21) { RenderScript rs = RenderScript.create(context); ScriptC_yuv420888 script = new ScriptC_yuv420888(rs); int width = image.getWidth(); int height = image.getHeight(); Type.Builder yuvType = new Type.Builder(rs, Element.YUV(rs)); yuvType.setX(width).setY(height).setYuvFormat(ImageFormat.YUV_420_888); Allocation yuvAllocation = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); Type.Builder nv21Type = new Type.Builder(rs, Element.createPixel(rs, Element.DataType.UNSIGNED_8, Element.DataKind.PIXEL_YUV)); nv21Type.setX(width).setY(height).setYuvFormat(ImageFormat.NV21); Allocation nv21Allocation = Allocation.createTyped(rs, nv21Type.create(), Allocation.USAGE_SCRIPT); ByteBuffer yBuffer = image.getPlanes()[0].getBuffer(); ByteBuffer uBuffer = image.getPlanes()[1].getBuffer(); ByteBuffer vBuffer = image.getPlanes()[2].getBuffer(); int ySize = yBuffer.remaining(); int uSize = uBuffer.remaining(); int vSize = vBuffer.remaining(); byte[] yBytes = new byte[ySize]; byte[] uBytes = new byte[uSize]; byte[] vBytes = new byte[vSize]; yBuffer.get(yBytes); uBuffer.get(uBytes); vBuffer.get(vBytes); yuvAllocation.copyFromUnchecked(new byte[][] {yBytes, uBytes, vBytes}); script.invoke_setup(yuvAllocation, nv21Allocation); script.invoke_yuv420888_to_nv21(); nv21Allocation.copyTo(nv21); yuvAllocation.destroy(); nv21Allocation.destroy(); script.destroy(); rs.destroy(); } ``` 这个方法首先创建一个RenderScript实例和一个ScriptC_yuv420888实例。然后,创建一个YUV420_888格式的Allocation和一个NV21格式的Allocation。接下来,将Y、U、V分量的ByteBuffer转换为对应的字节数组,并将它们复制到YUV420_888的Allocation中。调用ScriptC_yuv420888中的`invoke_setup`方法将YUV420_888和NV21的Allocation传递给RenderScript。接下来,调用`invoke_yuv420888_to_nv21`方法进行转换。最后,将转换后的字节流写入nv21数组中。 使用RenderScript可以大大提高YUV420_888转NV21的效率,特别是处理大型图像时。但是,使用RenderScript需要一定的学习成本,并且需要在您的应用中添加RenderScript库的依赖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值