car-eye 车载流媒体开发中数据采集和编码传输

车载流媒体作为一个热点越来越引起大家的重视,car-eye 行车记录仪,是基于RTSP协议开发的开源android程序,支持最多四路视频录像,支持最多四路视频上传。传输视频采用RTSP协议。首先我们介绍一下,视频数据从摄像头获取到编码,到传输给流媒体服务器的过程:

1. 摄像头数据通过priewcallback获得数据为YV12的数据

设置好基本的预览的参数:

parameters.setPreviewSize(Constants.RECORD_VIDEO_WIDTH, Constants.RECORD_VIDEO_HEIGHT);

parameters.setPreviewFpsRange(20,20);

camera[index].startPreview();

在需要数据的时候打开预览callback:

camera[index].setPreviewCallback(preview[index]);

preview[0] = new PreviewCallback() {

  
@Override
public void onPreviewFrame(byte[] data, Camera camera1) {
// TODO Auto-generated method stub
MediaCodecManager.getInstance().onPreviewFrameUpload(data,0,camera[0]);
}
};

public void onPreviewFrameUpload(byte[] data,int index,Camera camera){

 if (data == null ) {
camera.addCallbackBuffer(data);
         return;
     }
     Camera.Size previewSize = camera.getParameters().getPreviewSize();
     if (data.length != Constants.UPLOAD_VIDEO_HEIGHT * Constants.UPLOAD_VIDEO_WIDTH * 3 / 2) {
    camera.addCallbackBuffer(data);
    Log.d("CMD", " onPreviewFrameUpload return"+data.length);
         return;
     }   
     MainService.getInstance().SetPreviewValid(index);
     
     if(mVC[index]!= null)
     {
    mVC[index].onVideo(data, previewFormat);
   
     }else
     {  
    camera.setPreviewCallback(null);    
     }
     camera.addCallbackBuffer(data);      
 }


}

2. 讲H264的数据流,传输到编码器进行编码传输:

 public int onVideo(byte[] data, int format) {
        if (!mVideoStarted)return 0;        
inputBuffers = mMediaCodec.getInputBuffers();
outputBuffers = mMediaCodec.getOutputBuffers();
        int bufferIndex = mMediaCodec.dequeueInputBuffer(0);        
       // MainService.mEasyPusher.addwatermarkScale(data, Scaler, data.length,Constants.RECORD_VIDEO_WIDTH,Constants.RECORD_VIDEO_HEIGHT,Constants.UPLOAD_VIDEO_WIDTH,Constants.UPLOAD_VIDEO_HEIGHT);
if (bufferIndex >= 0) {
   ByteBuffer buffer = null;
   buffer = inputBuffers[bufferIndex];   
   buffer.clear();
   buffer.put(data);
   buffer.clear();
   mMediaCodec.queueInputBuffer(bufferIndex, 0, data.length, System.nanoTime() / 1000, 0);
}
         /*if (time > 0)
try {
Thread.sleep(time / 2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lastPush = System.currentTimeMillis();*/
        return 0;
    }


    @Override
    public void run(){
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = 0;
        byte[] mPpsSps = new byte[0];
        byte[]h264 = new byte[mWidth*mHeight*3/2];        


        do {
            outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 30000);
            if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
                // no output available yet
            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                // not expected for an encoder
            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
               /* EasyMuxer muxer = mMuxer;
                if (muxer != null) {
                    // should happen before receiving buffers, and should only happen once
                    MediaFormat newFormat = mMediaCodec.getOutputFormat();
                    muxer.addTrack(newFormat, true);
                }*/
            } else if (outputBufferIndex < 0) {
                // let's ignore it
            } else {
                ByteBuffer outputBuffer;
                outputBuffer = outputBuffers[outputBufferIndex];        
                EasyMuxer muxer = mMuxer;
                if (muxer != null) {
                    muxer.pumpStream(outputBuffer, bufferInfo, true);
                }
                boolean sync = false;
                if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {// sps
                    sync = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0;
                    if (!sync) {
                        byte[] temp = new byte[bufferInfo.size];
                        outputBuffer.get(temp);
                        mPpsSps = temp;
                        mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
                        continue;
                    } else {
                        mPpsSps = new byte[0];
                    }
                }
                sync |= (bufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0;
                int len = mPpsSps.length + bufferInfo.size;
                if (len > h264.length){
                    h264 = new byte[len];
                }
                if (sync) {
                 System.arraycopy(mPpsSps, 0, h264, 0, mPpsSps.length);
                      outputBuffer.get(h264, mPpsSps.length, bufferInfo.size); 
                      int Time =(int)( ( bufferInfo.presentationTimeUs / 1000) &0xffffff);
                      mPusher.SendBuffer(0, h264,  mPpsSps.length + bufferInfo.size, 0, m_index); 
                      
                   }else{
                  int Time =(int)( ( bufferInfo.presentationTimeUs / 1000) &0xffffff);                                    
                      outputBuffer.get(h264, 0, bufferInfo.size);  
                      mPusher.SendBuffer(0, h264,  bufferInfo.size, 0, m_index);                      
                      
                  }


                mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
            }
        }
        while (mVideoStarted);
    }

其中 mPusher.SendBuffer(0, h264,  mPpsSps.length + bufferInfo.size, 0, m_index); 讲获得H264的流传输到多媒体平台。

相关代码下载car-eye开源平台网址:https://github.com/Car-eye-admin/  有关技术咨询可以加群590411159。 











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值