package com.dronecontrol.droneapi;
import com.dronecontrol.droneapi.components.AddressComponent;
import com.dronecontrol.droneapi.components.ErrorListenerComponent;
import com.dronecontrol.droneapi.components.ReadyStateListenerComponent;
import com.dronecontrol.droneapi.components.TcpComponent;
import com.dronecontrol.droneapi.components.ThreadComponent;
import com.dronecontrol.droneapi.listeners.ImageListener;
import com.dronecontrol.droneapi.listeners.VideoDataListener;
import com.dronecontrol.droneapi.video.H264VideoDecoder;
import com.google.inject.Inject;
import org.apache.log4j.Logger;
import java.awt.image.BufferedImage;
import static com.dronecontrol.droneapi.helpers.ThreadHelper.sleep;
public class VideoRetrieverH264 extends VideoRetrieverAbstract implements ImageListener
{
private final Logger logger = Logger.getLogger(VideoRetrieverP264.class);
private final TcpComponent tcpComponent;
private final H264VideoDecoder videoDecoder;
@Inject
public VideoRetrieverH264(ThreadComponent threadComponent, AddressComponent addressComponent, TcpComponent tcpComponent,
ReadyStateListenerComponent readyStateListenerComponent, ErrorListenerComponent errorListenerComponent,
H264VideoDecoder videoDecoder)
{
super(threadComponent, addressComponent, readyStateListenerComponent, errorListenerComponent);
this.tcpComponent = tcpComponent;
this.videoDecoder = videoDecoder;
}
@Override
public void stop()
{
super.stop();
videoDecoder.stopDecoding();
}
@Override
protected void doRun()
{
connectToVideoDataPort();
initializeCommunication();
setReady();
while (!isStopped())
{
tryDecoding();
if (!isStopped())
{
reconnectVideoPort();
}
}
disconnectFromVideoDataPort();
}
private void tryDecoding()
{
try
{
videoDecoder.startDecoding(tcpComponent, this);
} catch (Exception e)
{
logger.warn("Exception while decoding video stream: " + e.getMessage());
}
}
private void reconnectVideoPort()
{
logger.warn("Reconnecting video data port");
tcpComponent.disconnect();
sleep(4000);
tcpComponent.connect(getDroneAddress(), getVideoDataPort());
}
private void connectToVideoDataPort()
{
logger.info(String.format("Connecting to video data port %d", getVideoDataPort()));
tcpComponent.connect(getDroneAddress(), getVideoDataPort());
}
private void initializeCommunication()
{
tcpComponent.sendKeepAlivePacket();
}
private void disconnectFromVideoDataPort()
{
logger.info(String.format("Disconnecting from video data port %d", getVideoDataPort()));
tcpComponent.disconnect();
}
@Override
public void onImage(BufferedImage image)
{
for (VideoDataListener listener : getVideoDataListeners())
{
listener.onVideoData(image);
}
}
}