blob: 0f60665a62109b418847629847c034e41ac2a51f [file] [log] [blame]
package org.frc971;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
public class DebugServerRun {
private final static Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
final OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(-1);
private ServerSocketChannel sock;
private SocketChannel client;
/** Constructs a formatted boundary header from a timestamp and content length. */
private ByteBuffer CreateTransmission(long content_length, double timestamp) {
StringBuilder ret = new StringBuilder();
ret.append("\r\n--boundarydonotcross\r\n");
ret.append("Content-Type: image/jpeg\r\n");
ret.append("Content-Length: ");
ret.append(content_length);
ret.append("\r\n");
ret.append("X-Timestamp: ");
ret.append(timestamp);
ret.append("\r\n\r\n");
return ByteBuffer.wrap(ret.toString().getBytes());
}
/** Loop that pushes a data stream to the client. */
private void push() {
try {
grabber.start();
}
catch (Exception e) {
LOG.severe("Could not start frame grabber.");
return;
}
IplImage img;
long content_size;
File buff_file;
InputStream input;
double timestamp;
while (true) {
//get some image data
try {
img = grabber.grab();
timestamp = System.currentTimeMillis();
/*We buffer through /dev/shm, just to make the conversion process easier.
* I know this is really ugly, but it works a lot better than what
* I was doing before, which segfaulted.
*/
cvSaveImage("/dev/shm/DebugServerBuffer.jpg", img);
buff_file = new File("/dev/shm/DebugServerBuffer.jpg");
content_size = buff_file.length();
int totalBytesRead = 0;
input = new BufferedInputStream(new FileInputStream(buff_file));
byte[] result = new byte[(int)content_size];
while(totalBytesRead < result.length){
int bytesRemaining = result.length - totalBytesRead;
//input.read() returns -1, 0, or more :
int bytesRead = input.read(result, totalBytesRead, bytesRemaining);
if (bytesRead > 0){
totalBytesRead = totalBytesRead + bytesRead;
}
}
ByteBuffer header = CreateTransmission(content_size, timestamp);
ByteBuffer bbuf = ByteBuffer.wrap(result);
ByteBuffer to_send = ByteBuffer.allocate(header.capacity() + bbuf.capacity());
to_send.put(header);
to_send.put(bbuf);
to_send.rewind();
SocketCommon.sendAll(client, to_send);
}
catch (Exception e) {
LOG.warning("Could not grab frame.");
continue;
}
}
}
/** Constructor to start the server and bind it to a port. */
public DebugServerRun(final int port) throws IOException {
sock = ServerSocketChannel.open();
sock.socket().bind(new InetSocketAddress(9714));
client = sock.accept();
client.configureBlocking(false);
//we are now connected to our client. Wait for them to send us a header.
LOG.info("Reading headers...");
SocketCommon.readtoBoundary(client, "\r\n\r\n");
//send one back
LOG.info("Writing headers...");
SocketCommon.sendAll(client, "donotcross\r\n");
}
/** Runs the server, and concurrently starts the vision processor with -vision flag. */
public static void main(final String args[]) throws IOException {
//main function for server
//set logger to log everything
LOG.setLevel(Level.ALL);
try {
LogHandler handler = new LogHandler("ds_vision.log");
TimeFormatter formatter = new TimeFormatter();
handler.setFormatter(formatter);
LOG.addHandler(handler);
}
catch (FileNotFoundException e) {
System.err.println("Warning: Logging initialization failed.");
}
if (args[0].equals("-vision")) {
LOG.info("Starting vision processor.");
new TestClient();
}
DebugServerRun server = new DebugServerRun(9714);
server.push();
}
}