Android拍传中如何才能实现不丢帧呢?



首先跟大家说下我做的一个拍传项目:

这个拍传的项目呢,是通过获取Camera的预览帧数据,然后经过H264的编码,然后发送到服务器端进行的,协议是公司自己制定的协议。

获取预览帧的接口是:
  1. private byte[] prewframe;
  2. @Override
  3. public void onPreviewFrame(byte[] data, Camera arg1) {
  4. prewframe = data;
  5. }
复制代码
在里面我就是这样做,然后在surfaceChanged中启动一个编码线程一个数据发送线程,编码线程不断的循环编码prewframe原始数据,编码之后通过本地数据报包传递给数据报包接受线程,然后通过Socket将数据发送出去。

编码线程的核心代码如下:
  1. while(isPrewRunning)
  2. {
  3. buffer = changeYUV420SP2P(prewframe,prewframe.length);

  4. iLen = H264Encoder.encode(handle, buffer, buffer.length, outBuf, outBuf.length);

  5. dataPacket.setLength(iLen);
  6. udpSocket.send(dataPacket);

  7. Log.e("SendLen", ""+iLen);
  8. try {
  9. sender.setSendBufferSize(iLen);
  10. } catch (IOException e) {
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. }
  14. }
复制代码
首先跟大家说下,我为什么这样做!

原因非常简单,保证传输给观看段的是最新采集到的图像,弊端是观看段看的时候界面会非常的不流畅。

为什么呢?

onPrewFrame中prewframe只指向了最新采集到得图片数据,那么咱们假设下:

假设这个时候编码线程正在编码的是100帧,进入H264Encoder.encoder的时候编码的是第100帧,编码完后,再循环在编码,这个时候prewframe指向的是第101帧吗?铁定不是的,prewframe也许已经指向了105帧,中间的4帧都被我忽略不计了,
那么服务器端观看视频的流畅性就完全的取决于编码器的效率了。

可惜啊,我这边的编码器的效率真是底下,1秒才2帧。

后来参考了几个同类型的软件,人家做的都是保证流畅优先,因此这2天我煞费苦心决定采取缓冲机制来一帧都不丢的传输H264编码数据。


先给大家说下我是怎么弄的吧?

我还是借助DatagramSocket和DatagramPacket来实现的,原理和核心思路请参见:
http://www.shouyanwang.org/thread-43-1-1.html

在onPrewFrame中我获取到了预览帧数据后就直接通过DatagramSocket的send来进行发送
  1. try {
  2. outBuf = tempBuf;
  3. dataPacket.setLength(tempBuf.length);
  4. dataPacket.setData(outBuf, 0, outBuf.length);
  5. udpSocket.send(dataPacket);
  6. // Log.e("", "length:"+tempBuf.length);
  7. } catch (IOException e) {
  8. // TODO Auto-generated catch block
  9. e.printStackTrace();
  10. }
复制代码
接受后呢,就直接的编码发送,这样做呢?

有一个很有意思的问题:
数据发送端发送速度肯定会远远的高于数据接收端,因为接受端要接受数据并进行编码,那么底层是怎么来存储那些还没有进行编码的数据的呢,采用的是什么缓冲机制?

正确的情况下咱们应该怎么弄?
其实应该借助SDCARD来进行存储,在onPrewFrame中咱们获取到了预览帧的数据之后,就只管将数据存储在缓存文件中,然后咱们再开一个线程,不断的从这个缓存文件中读取预览帧数据编码发送就行了,存取为异步操作.

Android存在这样的机制吗?
借助FileDescripter能够实现这种效果吗?

????这方面的高手能够帮助分析一下吗?


本文转载自:http://www.shouyanwang.org/thread-64-1-1.html


你可能感兴趣的:(Android拍传中如何才能实现不丢帧呢?)