0

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

谢谢!

4

1 回答 1

2

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

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

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

顺便说一句,我是为视频聊天客户端做的。它运作良好,但后来我开始发送 H.263 帧。如果您也在做视频聊天客户端,它比发送 JPG 更有效。

于 2013-07-21T06:24:14.857 回答