从手机摄像头流式传输JPEG

时间:2013-07-20 21:53:30

标签: java android udp

我正在尝试使用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图像?

谢谢!

1 个答案:

答案 0 :(得分:2)

我做了类似的事情并最终将其转移到本机代码中并进行了JNI调用以从NV21转换并粘贴到循环缓冲区。

让第二个线程读取缓冲区并执行网络IO,以便您可以尽快从onPreviewFrame返回。

更好的是,将nv21数据复制到循环缓冲区,让第二个线程在网络上发送数据之前进行jpg转换。

顺便说一下,我为视频聊天客户端做了这个。它运作良好,但我已经开始发送H.263帧。如果您还在做视频聊天客户端,它比发送JPG更有效。

相关问题