Fix IndexOutOfBoundsException and remove Sleep. (#11089)

Signed-off-by: Matthew Skinner <matt@pcmus.com>
This commit is contained in:
Matthew Skinner 2021-08-11 20:02:19 +10:00 committed by GitHub
parent 9f35e7ba31
commit 333e7d2ef2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 158 additions and 141 deletions

View File

@ -768,6 +768,10 @@ public class IpCameraHandler extends BaseThingHandler {
}
}
private void openMjpegStream() {
sendHttpGET(mjpegUri);
}
// If start is true the CTX is added to the list to stream video to, false stops
// the stream.
public void setupMjpegStreaming(boolean start, ChannelHandlerContext ctx) {
@ -777,13 +781,8 @@ public class IpCameraHandler extends BaseThingHandler {
if (mjpegUri.isEmpty() || "ffmpeg".equals(mjpegUri)) {
sendMjpegFirstPacket(ctx);
setupFfmpegFormat(FFmpegFormat.MJPEG);
} else {
try {
// fix Dahua reboots when refreshing a mjpeg stream.
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
}
sendHttpGET(mjpegUri);
} else {// Delay fixes Dahua reboots when refreshing a mjpeg stream.
threadPool.schedule(this::openMjpegStream, 500, TimeUnit.MILLISECONDS);
}
} else if (ffmpegMjpeg != null) {// not first stream and we will use ffmpeg
sendMjpegFirstPacket(ctx);
@ -1779,7 +1778,6 @@ public class IpCameraHandler extends BaseThingHandler {
public void dispose() {
isOnline = false;
snapshotPolling = false;
onvifCamera.disconnect();
Future<?> localFuture = pollCameraJob;
if (localFuture != null) {
localFuture.cancel(true);
@ -1832,6 +1830,7 @@ public class IpCameraHandler extends BaseThingHandler {
localFfmpeg.stopConverting();
}
channelTrackingMap.clear();
onvifCamera.disconnect();
}
public void setStreamServerHandler(StreamServerHandler streamServerHandler2) {

View File

@ -27,6 +27,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.TimeZone;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault;
@ -110,6 +112,7 @@ public class OnvifConnection {
}
private final Logger logger = LoggerFactory.getLogger(getClass());
private ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(2);
private @Nullable Bootstrap bootstrap;
private EventLoopGroup mainEventLoopGroup = new NioEventLoopGroup();
private String ipAddress = "";
@ -162,7 +165,8 @@ public class OnvifConnection {
}
}
String getXml(RequestType requestType) {
private String getXml(RequestType requestType) {
try {
switch (requestType) {
case AbsoluteMove:
return "<AbsoluteMove xmlns=\"http://www.onvif.org/ver20/ptz/wsdl\"><ProfileToken>"
@ -286,6 +290,14 @@ public class OnvifConnection {
return "<GetPresets xmlns=\"http://www.onvif.org/ver20/ptz/wsdl\"><ProfileToken>"
+ mediaProfileTokens.get(mediaProfileIndex) + "</ProfileToken></GetPresets>";
}
} catch (IndexOutOfBoundsException e) {
if (!isConnected) {
logger.debug("IndexOutOfBoundsException occured, camera is not connected via ONVIF: {}",
e.getMessage());
} else {
logger.debug("IndexOutOfBoundsException occured, {}", e.getMessage());
}
}
return "notfound";
}
@ -805,6 +817,10 @@ public class OnvifConnection {
}
public void sendPTZRequest(RequestType requestType) {
if (!isConnected) {
logger.debug("ONVIF was not connected when a PTZ request was made, connecting now");
connect(usingEvents);
}
sendOnvifRequest(requestBuilder(requestType, ptzXAddr));
}
@ -823,26 +839,28 @@ public class OnvifConnection {
return isConnected;
}
public void disconnect() {
if (usingEvents && isConnected) {
sendOnvifRequest(requestBuilder(RequestType.Unsubscribe, subscriptionXAddr));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
private void cleanup() {
mainEventLoopGroup.shutdownGracefully();
isConnected = false;
presetTokens.clear();
mediaProfileTokens.clear();
if (!mainEventLoopGroup.isShutdown()) {
try {
mainEventLoopGroup.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
logger.info("Onvif was not shutdown correctly due to being interrupted");
logger.warn("ONVIF was not cleanly shutdown, due to being interrupted");
} finally {
logger.debug("Eventloop is shutdown:{}", mainEventLoopGroup.isShutdown());
mainEventLoopGroup = new NioEventLoopGroup();
bootstrap = null;
}
}
threadPool.shutdown();
}
public void disconnect() {
if (usingEvents && isConnected && !mainEventLoopGroup.isShuttingDown()) {
sendOnvifRequest(requestBuilder(RequestType.Unsubscribe, subscriptionXAddr));
}
// Some cameras may continue to send event callbacks even when they cant reach a server.
threadPool.schedule(this::cleanup, 500, TimeUnit.MILLISECONDS);
}
}