FFmpeg Javacv-延迟问题

FFmpeg Javacv-延迟问题,java,android,ffmpeg,h.264,javacv,Java,Android,Ffmpeg,H.264,Javacv,我正在使用android v21设备将数据流传输到javafx应用程序。工作正常,但我有大约2秒的延迟 到目前为止,基本交通是这样的 android webrtc/自定义实现16ms android packetizer(udp)6毫秒 假定udp传输速度小于5ms windows解包器缓冲区中无数据累积 windows ffmpeg framgrabber未知延迟 javafx imageview我编辑了上面的问题,因为我在几天的时间里解决了这个问题,但让我为那些可能需要它们的人提供详细信息

我正在使用android v21设备将数据流传输到javafx应用程序。工作正常,但我有大约2秒的延迟

到目前为止,基本交通是这样的

  • android webrtc/自定义实现16ms
  • android packetizer(udp)6毫秒
  • 假定udp传输速度小于5ms
  • windows解包器缓冲区中无数据累积
  • windows ffmpeg framgrabber未知延迟

  • javafx imageview我编辑了上面的问题,因为我在几天的时间里解决了这个问题,但让我为那些可能需要它们的人提供详细信息

    安卓-我最终使用了这个库 它打开webrtc功能,允许您逐帧编码视频。这就是我在一部糟糕的旧手机上对16毫秒帧进行编码的基准

    线程计数=0指示x264使用足够的线程来加载所有线程 您的CPU核心在编码过程中。因此,您可能在双通道上运行测试 取芯机(2芯将有3条螺纹)。要获得x264编码,无需 延迟,设置线程计数=1

    您可能会发现无数关于通过javacv设置选项的建议,但是我从未让javacv拒绝我设置的选项,并且多次了解到我影响了错误的因素。这是我试过的东西的清单

                    //grabber.setFrameRate(12);
                    //grabber.setVideoBitrate(10000);
    
                    //grabber.setOption("g", "2");
                   // grabber.setOption("bufsize", "10000");
                    //grabber.setOption("af", "delay 20");
                    //grabber.setNumBuffers(0);
                    //grabber.setOption("flush_packets", "1");
                    //grabber.setOption("probsize", "32");
                    //grabber.setOption("analyzeduration", "0");
                    //grabber.setOption("preset", "ultrafast");
    
                    //grabber.setOption("fflags", "nobuffer");
                    //grabber.setVideoOption("nobuffer", "1");
                    //grabber.setOption("fflags", "discardcorrupt");
                    //grabber.setOption("framedrop", "\\");
                   //grabber.setOption("flags","low_delay");
                    //grabber.setOption("strict","experimental");
                    //grabber.setOption("avioflags", "direct");
                    //grabber.setOption("filter:v", "fps=fps=30");
                    //grabber.setOptions("look_ahead", "0");
                    //Map options = new HashMap();
                    //options.put("tune", "zerolatency");
                    grabber.setVideoOption("look_ahead", "0");
                    //grabber.setFrameNumber(60);
    
    它们都不起作用,当您阅读文档时,您将了解到,当ffmpeg启动时,有不同的编码器(avcontext、videocontext、audiocontext)采用不同的值,有不同的api framegrabber和ffply采用不同的标志(我相信),因此将东西扔到墙上是徒劳的

    首先尝试向流中添加额外的帧。此外,如果您只需要一个图像,只需向输入流添加一个空数据包,它就会刷新缓冲区

    如果你需要为机器人视觉流视频查看我的博客文章

    可能与编码有关。您可以尝试将IFRAME_INTERVAL设置为-1而不是5。v21没有其他许多选项可以减少延迟。感谢您的回复。我注意到大多数视频通话应用程序都需要4.4。您是否有指向任何示例项目的链接?大多数视频通话应用程序可能没有使用MediaCodec api。如果这是您要去的路线,请查看WebRTC。我认为您的答案是正确的。我会检查一下。这项更改至少应该考虑启动时间:如果没有,请告诉我。您要查找的是
    setVideoOption(“threads”,“1”)
    ,这里有详细的文档记录:
                VideoRenderer.I420Frame frame = new VideoRenderer.I420Frame(width, height, rotation, texId, tranformMatrix, 0,timestamp);
                avccEncoder.renderFrame(frame);
                videoView.renderFrame(frame);
                surfaceTextureHelper.returnTextureFrame();
    
            }
    
     @Override
        public void renderFrame(VideoRenderer.I420Frame i420Frame) {
            start = System.nanoTime();
            bufferque++;
    
            mediaCodecHandler.post(new Runnable() {
                @Override
                public void run() {
                    videoEncoder.encodeTexture(false, i420Frame.textureId, i420Frame.samplingMatrix, TimeUnit.NANOSECONDS.toMicros(i420Frame.timestamp));
                }
            });
    
    
        }
    
        /**
         * Called to retrieve an encoded frame
         */
        @Override
        public void onEncodedFrame(MediaCodecVideoEncoder.OutputBufferInfo frame, MediaCodec.BufferInfo bufferInfo) {
    
            b = new byte[frame.buffer().remaining()];
            frame.buffer().get(b);
            synchronized (lock)
            {
                encodedBuffer.add(b);
                lock.notifyAll();
                if(encodedBuffer.size() > 1)
                {
                    Log.e(TAG, "drainEncoder: too big: " + encodedBuffer.size(),null );
    
                }
            }
            duration = System.nanoTime() - start;
            bufferque--;
            calcAverage();
            if (bufferque > 0)
            {
            Log.d(TAG, "onEncodedFrame: bufferque size: " + bufferque);
    
    
        }
    
    }
    
                    //grabber.setFrameRate(12);
                    //grabber.setVideoBitrate(10000);
    
                    //grabber.setOption("g", "2");
                   // grabber.setOption("bufsize", "10000");
                    //grabber.setOption("af", "delay 20");
                    //grabber.setNumBuffers(0);
                    //grabber.setOption("flush_packets", "1");
                    //grabber.setOption("probsize", "32");
                    //grabber.setOption("analyzeduration", "0");
                    //grabber.setOption("preset", "ultrafast");
    
                    //grabber.setOption("fflags", "nobuffer");
                    //grabber.setVideoOption("nobuffer", "1");
                    //grabber.setOption("fflags", "discardcorrupt");
                    //grabber.setOption("framedrop", "\\");
                   //grabber.setOption("flags","low_delay");
                    //grabber.setOption("strict","experimental");
                    //grabber.setOption("avioflags", "direct");
                    //grabber.setOption("filter:v", "fps=fps=30");
                    //grabber.setOptions("look_ahead", "0");
                    //Map options = new HashMap();
                    //options.put("tune", "zerolatency");
                    grabber.setVideoOption("look_ahead", "0");
                    //grabber.setFrameNumber(60);