我正在尝试使用udp套接字将JPEG帧从相机流式传输到我的电脑,但我遇到了一些问题。
所以我设置了一个摄像头并添加了预览帧事件的回调:
@Override
public void onPreviewFrame(byte[] data, Camera camera)
{
final YuvImage image = new YuvImage(data, mPreviewFormat, mPreviewWidth, mPreviewHeight, null); //Create the Yuv image
image.compressToJpeg(mPreviewRect, 80, stream); //Compress to JPEG
Bitmap b = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()); //Convert to Bitmap
Bitmap resizedBitmap = Bitmap.createScaledBitmap(b, 320, 240, false); //Scale to 320x240
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); //Compress back to JPEG
byte[] byteArray = stream.toByteArray();
DatagramPacket sendPacket = new DatagramPacket(byteArray, byteArray.length, IPAddress, 37654);
try
{
socket.send(sendPacket); //Send frame to address
}
catch (IOException e)
{
e.printStackTrace();
}
stream.reset();
}
我的问题是这需要大约0.2秒,所以我的帧速率约为5 FPS。有什么方法可以加快我的目标FPS是15到20 FPS。从我的计时测试来看,我认为问题可能出在Bitmap b = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
这似乎花了最长的时间约0.1秒。有没有办法直接缩放Yuv图像?
谢谢!
答案 0 :(得分:2)
我做了类似的事情并最终将其转移到本机代码中并进行了JNI调用以从NV21转换并粘贴到循环缓冲区。
让第二个线程读取缓冲区并执行网络IO,以便您可以尽快从onPreviewFrame返回。
更好的是,将nv21数据复制到循环缓冲区,让第二个线程在网络上发送数据之前进行jpg转换。
顺便说一下,我为视频聊天客户端做了这个。它运作良好,但我已经开始发送H.263帧。如果您还在做视频聊天客户端,它比发送JPG更有效。