/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright 2014, OpenSpace Solutions LLC. All Right Reserved.
*/
package com.chiorichan.dvr.registry;
import com.chiorichan.ChatColor;
import com.chiorichan.Loader;
import com.chiorichan.dvr.DVRLoader;
import com.chiorichan.dvr.VideoWriter;
import com.chiorichan.dvr.utils.VideoUtils;
import com.github.sarxos.webcam.Webcam;
import com.google.common.collect.Lists;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joda.time.DateTime;
public class VideoInput implements Runnable
{
protected Webcam device;
protected BufferedImage img = null;
protected long lastTimeStamp = -1;
protected int currentFPS = 0;
protected String title = "Camera 0";
protected VideoWriter writer;
protected final static CopyOnWriteArrayList<VideoWriter> writers = Lists.newCopyOnWriteArrayList();
public Thread currentThread;
private boolean busy = false;
public VideoInput( Webcam w )
{
device = w;
// Temporary Testing Means
if ( w.getName().equals( "/dev/video0" ) )
DVRLoader.getExecutor().execute( this );
}
public String getChannelName()
{
return device.getName().replace( "/dev/", "" );
}
public Webcam getDevice()
{
return device;
}
public boolean open()
{
writer = new VideoWriter( this );
writers.add( writer );
return device.open( false );
}
public boolean close()
{
writer.detachedFromInput = true;
writers.remove( writer );
writer = null;
return device.close();
}
public static List<VideoWriter> getVideoWriters()
{
return writers;
}
public VideoWriter getVideoWriter()
{
return writer;
}
public void setTitle( String text )
{
title = text;
}
public BufferedImage getLastImage()
{
return img;
}
public int getHeight()
{
return 480;
}
public int getWidth()
{
return 640;
}
@Override
public void run()
{
currentThread = Thread.currentThread();
Loader.getLogger().info( "Starting Video Input Thread - " + currentThread.getName() );
do
{
try
{
if ( device.isOpen() )
{
img = device.getImage();
if ( img != null )
if ( busy == false )
{
busy = true;
long start = System.currentTimeMillis();
currentFPS = Math.round( 1000 / ((float) (System.currentTimeMillis() - lastTimeStamp)) );
lastTimeStamp = System.currentTimeMillis();
// Determine the current time for the timestamp and frame position
DateTime dt = new DateTime();
Graphics2D gd = img.createGraphics();
VideoUtils.adjustGraphics( gd );
Font font = new Font( "Sans", Font.PLAIN, 18 );
String text = dt.toString( "YYYY/MM/dd hh:mm:ss.SSS aa" );
TextLayout textLayout = new TextLayout( text, font, gd.getFontRenderContext() );
gd.setPaint( Color.WHITE );
gd.setFont( font );
FontMetrics fm = gd.getFontMetrics();
//int x = (img.getWidth() / 2) - (fm.stringWidth( text ) / 2);
int x = img.getWidth() - fm.stringWidth( text ) - 20;
int y = img.getHeight() - 20;
textLayout.draw( gd, x, y );
gd.dispose();
/*
* float ninth = 1.0f / 9.0f;
* float[] kernel = new float[9];
* for ( int z = 0; z < 9; z++ )
* {
* kernel[z] = ninth;
* }
* ConvolveOp op = new ConvolveOp( new Kernel( 3, 3, kernel ), ConvolveOp.EDGE_NO_OP, null );
* BufferedImage image2 = op.filter( bi, null );
* Graphics2D g2 = image2.createGraphics();
* //VideoUtils.adjustGraphics( g2 );
* g2.setPaint( Color.BLACK );
* textLayout.draw( g2, x, y );
*/
Loader.getLogger().info( ChatColor.BLUE + "Frame Saved: Current FPS: " + currentFPS + ", Device: " + this.getChannelName() + ", Time Taken: " + (System.currentTimeMillis() - start) + ", Thread: " + currentThread.getName() );
writer.addFrame( dt, img );
busy = false;
}
else
Loader.getLogger().warning( "Received a new Frame from Video Input Device but the processing subroutine was busy, Thread: " + currentThread.getName() + ", Device: " + this.getChannelName() );
}
// This should get us about 25 FPS if possible.
Thread.sleep( 100L );
}
catch ( Exception ex )
{
Loader.getLogger().severe( "Exception Encountered in the Video Input Thread, Thread: " + currentThread.getName() + ", Device: " + this.getChannelName(), ex );
}
}
while ( DVRLoader.isRunning );
Loader.getLogger().info( "Stopping Video Input Thread - " + currentThread.getName() );
}
}