踩坑之视频的清晰度和java之间的引用

来源:互联网 发布:政务数据共享开放平台 编辑:程序博客网 时间:2024/06/09 20:16
马云说过,不要学习别人的成功,要学习别人的失败。今记录我踩过的坑,望总结失败教训。
    今天经理牛人让我把从录像应用采集到的摄像头数据,传到网关程序,然后编码通过p2p传递到客户端,实时编码播放,弄了一天了,差不多弄完了,但是出现了几个问题,客户端实时视频卡顿,有的模糊不清,此刻根据以往经验,应该调调视频的帧率,码流率了,直接上代码:
public NewsmyVideoEncoder(int width,int height, int framerate, int bitrate, ArrayBlockingQueue<byte[]> YUVQueue) {
    m_width = width;
    m_height = height;
    m_framerate = framerate;
    mYUVQueue = YUVQueue;
    MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
    mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
    //mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 200*1024*8);
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
    try {
        mediaCodec = MediaCodec.createEncoderByType("video/avc");
    } catch (Exception e) {
        e.printStackTrace();
    }
    mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mediaCodec.start();
}

帧率的大小代表了视频的流畅度,帧率越大,流畅度越好,我评估以现有的网络条件,15的帧率最合适,我调节摄像头采集的数据速率,帧率就是每秒采集图像的个数,好了,定了帧率之后,我试着调节码流率,他是每一秒传输的数据,数据越大,视频越清晰,我从小到大的调节,发现问题的解决不是很理想,依然存在卡顿,不清晰。然后经理牛人过来看了一下,猜测我的问题出现在哪里。是编码的数据问题。靠。我踩了一个很大很大的坑。上代码

@Overridepublic void onFrame(byte[] buffer) {
    Log.d("CameraEncoder","拿到数据啦---------- "+buffer.length);
    if (mYUVQueue.size() >= 10) {
        mYUVQueue.poll();
    }
    byte[] mVideoBuffer = new byte[BUFFER_SIZE];
    System.arraycopy(buffer,0,mVideoBuffer,0,BUFFER_SIZE);
     mYUVQueue.add(mVideoBuffer);
}

从共享内存读到的数据我回调到这里,由于之前我只建立了一个缓存区来存储数据,传到这里,我直接添加到我的队列里了,注意了,问题就出现在这里,这里add方法添加的是引用,buffer数组一直在更新,意味着传过去的编码数据随时可能改变,这就不对了,所以我必须拷贝一份,在传过去,改完,测试,发现问题比以前好多了,视频不清晰,有混乱画面的问题解决了,果然是视频编码数据的问题。但还是有不流畅的问题,经理牛人问我的分辨率是多少,我说1920*1080,经理牛人说太大了,改小点,图像清晰点,码流率改成200*1024*8,我照做了,测试,OK,完美解决了我的问题,茅塞顿开,弄了好久的音视频,果然还需得亲自去踩这些坑,才明白这些原理和技术。总之,时刻记着,java如果传递的是引用,都是对应同一块内存,改变都改变。 
原创粉丝点击