参考链接:https://blog.csdn.net/mozushixin_1/article/details/91968090

参考链接:https://www.jianshu.com/p/ac53e9595940

最近的项目是使用mediacodec进行硬解码,然后直接使用surface进行渲染时发现了一个问题:

(1)对于1920*1080的图片,mediacodec解码出来后,然后直接将其渲染到绑定的surface中,此时在实际得到的渲染图片可以看出底部会出现绿边或者底部的图像出现马赛克的问题。

==》发生这类问题可以追溯到mediacodec解码出来数据会存在数据对其的问题,例如假设解码出来的数据格式为15x15,而GPU需要渲染的格式是16位对其即16x16,此时将会出现绿边的情况,如下图所示:

 

详细的讲解可以参考:https://www.jianshu.com/p/ac53e9595940

(2)由于上述的问题的存在,因此考虑先进行mediacodec硬解码,然后将解码后的数据不直接渲染,而是提取出来进行YUV渲染,具体代码操作如下:

//mediacodec相关的yuv渲染变量
byte[] getBuffer = null;
ByteBuffer outputBuffer = null;
byte[] dstY = null;
byte[] dstU = null;
byte[] dstV = null;
int yBufferSize;
int uBufferSize;
int vBufferSize;
int yuvWidth;
int yuvHeight;
mediaCodec.configure(mediaFormat,null,null,0);//获取相应的解码后的数据,不直接使用surface进行渲染 
yBufferSize=width*height;
uBufferSize=width/2*height/2;
vBufferSize=width/2*height/2;
dstY=newbyte[yBufferSize];
dstU=newbyte[uBufferSize];
dstV=newbyte[vBufferSize];
yuvWidth=width;
yuvHeight=height;
getBuffer=newbyte[info.size];
outputBuffer=mediaCodec.getOutputBuffer(outputBufferIndex);
outputBuffer.get(getBuffer);//获取得到yuv数据
System.arraycopy(getBuffer,0,dstY,0,yBufferSize);
System.arraycopy(getBuffer,yBufferSize,dstU,0,uBufferSize);
System.arraycopy(getBuffer,yBufferSize+uBufferSize,dstV,0,vBufferSize);

(1)对于mediacodec初始化时不绑定surface,而是直接传入null:

mediaCodec.configure(mediaFormat,null,null,0);//获取相应的解码后的数据,不直接使用surface进行渲染 

(2)然后再使用上面的代码流程在java程序中获取相应的y、u和v的数据,在我的项目中使用mediacodec解码出来的数据格式为yuv420,且yuv的排列为UVUVUV即获取得到的getBuffer的前面width*height/2为Y分量数据,后面的U和V分量数据均为width*height/4。如此进行后即可得到Y、U和V分量的数据,然后即可再对其进行渲染或者处理后再渲染,我的项目中只需操作完获取得到YUV分量数据后再进行渲染,即可去掉了绿边,如果还未能处理的话可能考虑需要对获取得到的YUV数据进行处理了。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐