Чтение BufferedInputStream из именованного канала Linux работает только один раз
Я в отчаянии,... Я много пробовал и искал, не повезло. Пожалуйста помоги
Немного фона: используя Raspberry Pi 3, я разрабатываю сервер потоковой передачи веб-камеры, так как не хочу, чтобы он был доступен. При raspistill частота кадров в секунду очень низкая (4 кадра в секунду), поэтому я рассматриваю вариант v4l2 для потоковой передачи веб-камеры. Для этого я вывожу видео mjpeg в трубу.
При чтении из этого канала показывается первое изображение в формате JPEG, но последовательные чтения возвращают ноль.
Чтобы исследовать это дальше, я сделал небольшую демонстрационную программу - тот же результат.
Вот код, который я использую:
Итерация 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 - Попытка с использованием метки и сброса (не повезло) - Чтение из потока с использованием чтения вместо ImageIO (чтение всегда с частотой примерно 20 кадров в секунду)
Когда я выполняю программу, v4l2 сообщает, что фреймы использованы, поэтому канал освобождается / читается программой java, поэтому в нее можно вводить новые фреймы. Только первое изображение и только во время первого выполнения программы возвращает мне одно изображение. Второе выполнение программы дает нулевое значение и для первого изображения.
Вот пример вывода:
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-документ утверждает нечто странное, чего я не могу понять:
(...) InputStream заключен в ImageInputStream. Если ни один зарегистрированный ImageReader не утверждает, что может прочитать результирующий поток, возвращается значение null (...)
Заранее спасибо за вашу помощь и совет.
1 ответ
Однажды бессонной ночью я получил кое-что работающее.
Эврика: Я передаю 1000 кадров с помощью библиотеки v4l2 в канал Linux и могу читать все 1000 кадров. Сохранение каждого файла в каталоге занимает около 103 секунд или 10 кадров в секунду. Ни один кадр не пропущен.
Вот как:
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
Совет: Считыватель протестирован с
if(ImageIO.getImageReaders(stream).hasNext())