java - 从命名的 Linux 管道读取 BufferedInputStream 只能工作一次

标签 java linux pipe javax.imageio bufferedinputstream

我很绝望,......我已经尝试并搜索了很多,但没有运气。请帮忙

一点背景: 使用 raspberry Pi 3,我开发了一个网络摄像头流媒体服务器,因为我不希望这些服务器可用。使用 raspistill 时,fps 非常低 (4fps),这就是为什么我研究用于流式传输网络摄像头的 v4l2 选项。为此,我将 mjpeg 视频输出到管道中。

从该管道读取时,会显示第一个 jpeg 图像,但连续读取会返回 null。

为了进一步研究这个问题,我制作了一个小型演示程序 - 结果相同。

这里是我使用的代码:

迭代 20 次从 bufferedinputstream 读取

private void standardRead()
    {
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(new File(image_path)));           


        } catch (FileNotFoundException e) {         
            e.printStackTrace();
        }

        System.out.println("Is mark supported? "+bis.markSupported());

        try {
            for(int i=0;i<20;i++)
            {
                readingImage(bis,i);
                TimeUnit.MILLISECONDS.sleep(250);
            }

        } catch (IOException | InterruptedException e) {            
            e.printStackTrace();
        }
    }

读取方法(增强了一些System.out)

private void readingImage(BufferedInputStream bis,int iteration) throws IOException
    {
        System.out.println("Available bytes to read:"+bis.available());
        System.out.println("Reading image"+iteration);

        BufferedImage read = ImageIO.read(bis);

        if(read!=null){
            System.out.println(read.getRGB(25, 25)+" h:"+read.getHeight());System.out.println();
        }else
        {
            System.out.println("image is null");
        }
        read = null;
    }

我已经尝试过的: - 为每次迭代创建一个新的 BufferedInputStream - 关闭并创建一个新的 BufferedInputStream - 尝试使用标记和重置(没有运气) - 使用 read 而不是 ImageIO 从流中读取(显然以大约 20fps 的速度读取)

当我执行程序时,v4l2 通知帧已被消耗,因此管道正在被 java 程序清空/读取,以便可以将新帧输入其中。 只有第一张图片并且只有在程序第一次执行期间才会给我一个图片。该程序的第二次执行也为第一张图像提供了 null。

这里是一个示例输出:

Is mark supported? true
Available bytes to read:65536
Reading image0
image is null
Available bytes to read:73720
Reading image1
image is null
Available bytes to read:73712
Reading image2
image is null
Available bytes to read:73704
Reading image3
image is null
Available bytes to read:73696
Reading image4
image is null
Available bytes to read:73688
Reading image5
image is null

一个注释,如果有帮助的话。对于 ImageIO.read(InputStream) 函数,Java 文档说明了一些我无法理解的奇怪内容:

(...) The InputStream is wrapped in an ImageInputStream. If no registered ImageReader claims to be able to read the resulting stream, null is returned (...)

在此先感谢您的帮助和建议。

最佳答案

一个不眠之夜后,我得到了一些工作。

Eureka:我使用 v4l2 库将 1000 帧流式传输到 linux 管道中,并且可以读取所有 1000 帧。将每个文件保存到一个目录大约需要 103 秒,也就是 10fps。没有跳过任何一帧。

方法如下:

private void ReadImages(File path)
    {
        BufferedInputStream bis = null;
        int index = 0;

        ImageReader reader = null;

            try {
                bis = new BufferedInputStream(new FileInputStream(path));
                ImageInputStream stream = ImageIO.createImageInputStream(bis);

                while(bis.available()>0)
                {
                    if(gotReader(stream))
                    {
                        reader = ImageIO.getImageReaders(stream).next();
                        reader.setInput(stream);
                        BufferedImage read = reader.read(index);
                        System.out.println("Image height"+read.getHeight() +" image width:"+read.getWidth()) ;

                        stream.flush();                 
                    index = 0;
                    }

                }
            } catch (IOException e) {
                System.err.println(e.getMessage());
                //e.printStackTrace();
            }
    }

提示:经常刷新流并重置索引。如果不刷新,不断增长的内存会显着破坏性能。

提示:标准 ImageIO 不读取 BGR3、RGB3、YU12、YUYV、YV12、YVYU,但读取 H264 和 MJPEG

提示:Reader 是用

测试的
if(ImageIO.getImageReaders(stream).hasNext())

关于java - 从命名的 Linux 管道读取 BufferedInputStream 只能工作一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42962476/

相关文章:

java - 如何在ConcurrentHashMap(JDK1.8或更高版本)的addCount函数中实现条件(sc == rs + 1 || sc == rs + MAX_RESIZERS)

Java 字典对象和数组/链表

Linux:获取空闲空间物理 block 号(空闲空间位图)

linux - 约 250,000 张图像的最佳 Web 文件夹结构

c - 将2个结构作为参数传递给C中的pthread

angularjs - Angular : Use Filter and OR Operator Pipe

linux - 我需要在多线程读取调用中保护 fd 吗?

python - OpenCV Python,从命名管道读取视频

java - 如何使用 JPA 2 和 HBN maven 插件创建 hibernate 友好的 MySQL 数据库字段?

Java 回调 - 获取参数