海康IPC接入TRTC时,从海康中获取的数据显示时色差不正确
2021/1
记录海康IPC接入TRTC时的历史日志
从海康sdk接口获取数据,进行解码
org.MediaPlayer.PlayM4.Player.T_YV12;private void setDecodeCB() {Player.getInstance().setDecodeCB(m_iPort, (nPort, data, nDataLen, nWidth, nHeight, nFrameTime, nDataType, arg7) -> {if (nDataType == T_YV12 ) {byte[] i420bytes = swapYV12toI420(data, nWidth, nHeight);callback.afterCall(context, i420bytes.length, i420bytes, nWidth, nHeight, nFrameTime);}});}
解码后如下展示的时候,出现图片偏差
byte[] nv12bytes = RSNV12ToBitmap.getInstance(context).swapI420toNV12(data, nWidth, nHeight);//额外转换 3msBitmap buffBitmap = RSNV12ToBitmap.getInstance(context).nv12ToBitmap(nv12bytes, nWidth, nHeight);//20毫秒
可能是android.renderscript.ScriptIntrinsicYuvToRGB接受的YUV是nv21而不是nv12
byte[] nv21bytes = RSNV12ToBitmap.getInstance(context).swapI420toNV21(data, nWidth, nHeight);//额外转换 3msBitmap buffBitmap = RSNV12ToBitmap.getInstance(context).nv21ToBitmap(nv21bytes, nWidth, nHeight);//20毫秒
图像格式转换函数
package com.sunshine.mhs.pension.doctormodule.trct.ipc.util;/*** 作者:Administrator on 2020/3/26* 邮箱:9611153@qq.com*/import android.content.Context;
import android.graphics.Bitmap;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type;public class RSNV21ToBitmap {private static RSNV21ToBitmap instance;private RenderScript rs;private ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;private byte[] nv21bytes;private RSNV21ToBitmap(Context context) {nv21bytes = null;rs = RenderScript.create(context);yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));}public static RSNV21ToBitmap getInstance(Context context) {if (instance == null) {instance = new RSNV21ToBitmap( context);}return instance;}public static void destory() {if (instance != null) {instance.yuvToRgbIntrinsic.destroy();instance.rs.destroy();instance = null;}}public Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {if (nv21 == null) return null;Type.Builder yuvType, rgbaType;Allocation in, out;yuvType = new Type.Builder(rs, Element.U8(rs)).setX(nv21.length);in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height);out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);Bitmap bmpout = null;try {in.copyFrom(nv21);yuvToRgbIntrinsic.setInput(in);yuvToRgbIntrinsic.forEach(out);bmpout = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);out.copyTo(bmpout);} catch (Exception e) {e.printStackTrace();}return bmpout;}public byte[] swapI420toNV21(byte[] I420bytes, int width, int height) {if (null == nv21bytes) {nv21bytes = new byte[I420bytes.length];}if (I420bytes.length != nv21bytes.length)return null;int nLenY = width * height;int nLenU = nLenY / 4;System.arraycopy(I420bytes, 0, nv21bytes, 0, nLenY);for (int i = 0; i < nLenU; i++) {nv21bytes[nLenY + 2 * i + 1] = I420bytes[nLenY + i];//先v后Unv21bytes[nLenY + 2 * i] = I420bytes[nLenY + nLenU + i];}return nv21bytes;}}