package resa.evaluation.topology.tomVLD; import org.bytedeco.javacpp.opencv_core; import redis.clients.jedis.Jedis; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.util.PriorityQueue; /** * Created by Tom Fu * RedisStreamProducerBeta keeps a timer for each frame, if the expected frame is late, it starts the time and wait until timeout, * then it simply drops this frame and come to the next expected frame. (suitable for loss insensitive application) */ public class RedisStreamProducerBeta implements Runnable { /** * Ordered queue for putting frames in order */ private PriorityQueue<StreamFrame> stream; /** * Has the last expected frame come? */ private boolean finished; //private static final byte[] END = new String("END").getBytes(); private String host; private int port; private byte[] queueName; //private BlockingQueue<byte[]> dataQueue = new ArrayBlockingQueue<>(10000); private Jedis jedis; private long sleepTime; private int startFrameID; private int maxWaitCount; /** * Creates a producer expecting frames in range [firstFrameId, lastFrameId) */ public RedisStreamProducerBeta(String host, int port, String queueName) { stream = new PriorityQueue<>(); this.host = host; this.port = port; this.queueName = queueName.getBytes(); finished = false; jedis = new Jedis(host, port); this.maxWaitCount = 4; this.startFrameID = 1; this.sleepTime = 10; } /** * Creates a producer expecting frames in range [firstFrameId, lastFrameId), with an additional parameter qSize */ public RedisStreamProducerBeta(String host, int port, String queueName, int startFrameID, int maxWaitCount, int sleepTime) { stream = new PriorityQueue<>(); this.host = host; this.port = port; this.queueName = queueName.getBytes(); finished = false; jedis = new Jedis(host, port); this.startFrameID = startFrameID; this.maxWaitCount = maxWaitCount; this.sleepTime = sleepTime; System.out.println("Check_init_RedisStreamProducerBeta, " + System.currentTimeMillis() + ", host: " + this.host + ", port: " + this.port + ", qName: " + this.queueName + ", stFrameID: " + this.startFrameID + ", sleepTime: " + this.sleepTime + ", mWaitCnt: " + this.maxWaitCount); } /** * Add frame to the queue if it is fully processed */ public void addFrame(StreamFrame streamFrame) { synchronized (stream) { stream.add(streamFrame); } } /** * Get expected frame from the queue. * * @return next expected frame, or null if it has not come yet. */ public StreamFrame pollFrame() { synchronized (stream) { return stream.poll(); } } public StreamFrame getPeekFrame() { synchronized (stream) { return stream.isEmpty() ? null : stream.peek(); } } public int getStreamSize() { synchronized (stream) { return stream.size(); } } @Override public void run() { int currentFrameID = startFrameID; int waitCount = 0; while (!finished) { try { StreamFrame peekFrame = getPeekFrame(); if (peekFrame == null) { //System.out.println("peekFrame == null"); Thread.sleep(sleepTime); } else { if (peekFrame.frameId <= currentFrameID) { //System.out.println("peekFrame.frameId (" + peekFrame.frameId +") <= currentFrameID: " + currentFrameID); pollFrame(); } else if (peekFrame.frameId == (currentFrameID + 1)) { //System.out.println("peekFrame.frameId (" + peekFrame.frameId +") == 1 + currentFrameID: " + currentFrameID); StreamFrame nextFrame = pollFrame(); opencv_core.IplImage iplImage = nextFrame.image.asIplImage(); BufferedImage bufferedImage = iplImage.getBufferedImage(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "JPEG", baos); jedis.rpush(this.queueName, baos.toByteArray()); System.out.println("finishedAdd: " + System.currentTimeMillis() + ",Fid: " + nextFrame.frameId); currentFrameID++; } else { //System.out.println("peekFrame.frameId (" + peekFrame.frameId +") >> currentFrameID: " + currentFrameID); Thread.sleep(sleepTime); waitCount++; if (waitCount >= maxWaitCount) { System.out.println("frameTimeout, traceID: " + currentFrameID + ", peek: " + peekFrame.frameId + ", qSize: " + stream.size()); currentFrameID++; waitCount = 0; } } } } catch (Exception e) { System.out.print("Exception: "); e.printStackTrace(); } } } }