diff --git a/sensors/video/sensorhub-driver-ffmpeg/README.md b/sensors/video/sensorhub-driver-ffmpeg/README.md index f03b24fd6..d573bd383 100644 --- a/sensors/video/sensorhub-driver-ffmpeg/README.md +++ b/sensors/video/sensorhub-driver-ffmpeg/README.md @@ -60,6 +60,9 @@ When added to an OpenSensorHub node, the driver has the following configuration - **Inject Extradata:** Only for H264. When checked, injects Annex B extradata into the video stream before every keyframe. This is necessary for late-join decoders (those that receive live data from the driver after the driver has started). + - **Register Devices:** + Register external A/V device libraries. Enable if input is not from a network stream or file (e.g. Direct Show, V4L). + Disable this option if the driver fails to start and produces the error `java.lang.UnsatisfiedLinkError: no jniavdevice in java.library.path`. - **Position:** - **Location:** (Optional) diff --git a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/FFMPEGSensor.java b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/FFMPEGSensor.java index dfcedd1d9..53764ea32 100644 --- a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/FFMPEGSensor.java +++ b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/FFMPEGSensor.java @@ -211,6 +211,7 @@ protected boolean openStream() { mpegTsProcessor = new MpegTsProcessor(config.connection.connectionString, config.connection.commandLineArgs); } mpegTsProcessor.setInjectVideoExtradata(config.connection.injectExtradata); + mpegTsProcessor.registerDevices(config.connection.registerDevices); } if (mpegTsProcessor.isStreamOpened()) { diff --git a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/config/Connection.java b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/config/Connection.java index 38384f000..7adaf931f 100644 --- a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/config/Connection.java +++ b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/impl/sensor/ffmpeg/config/Connection.java @@ -43,4 +43,7 @@ public class Connection { @DisplayInfo(label = "Inject Extradata for Streaming", desc = "Injects extradata into the video stream. Set true if this driver is being used to output a live video stream for late-join decoders.") public boolean injectExtradata = true; + + @DisplayInfo(label = "Register Devices", desc = "Registers devices for the video stream. Set true if input is not from a network stream or file (e.g. dshow).") + public boolean registerDevices = false; } diff --git a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/MpegTsProcessor.java b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/MpegTsProcessor.java index a8773e9c0..1ad0f423d 100644 --- a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/MpegTsProcessor.java +++ b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/MpegTsProcessor.java @@ -94,6 +94,8 @@ public class MpegTsProcessor extends Thread { private String formatString; + private boolean registerDevices = false; + /** * Context used by underlying FFmpeg library to decode stream. */ @@ -193,6 +195,10 @@ public boolean openStream() { avformat.avformat_network_init(); + if (registerDevices) { + avdevice_register_all(); + } + // Create a new AV Format Context for I/O avFormatContext = avformat_alloc_context(); @@ -210,15 +216,12 @@ public int call(Pointer opaque) { // Set timeout var options = new AVDictionary(null); - avdevice_register_all(); String cmdFormat; cmdFormat = populateOptions(options, optionsString); if (cmdFormat != null && !cmdFormat.isBlank()) { inputFormat = av_find_input_format(cmdFormat); } - //avutil.av_dict_set(options, "timeout", "3000000", 0); - int returnCode = avformat.avformat_open_input(avFormatContext, streamSource, inputFormat, options); logger.debug("returnCode: {}", returnCode); @@ -415,6 +418,10 @@ public void setInjectVideoExtradata(boolean injectVideoExtradata) { videoStreamContext.setInjectingExtradata(injectVideoExtradata); } + public void registerDevices(boolean registerDevices) { + this.registerDevices = registerDevices; + } + /** * Registers a data buffer listener to call if clients are interested in demuxed data buffers * diff --git a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/StreamContext.java b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/StreamContext.java index b4730fb18..f2ffa8b9f 100644 --- a/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/StreamContext.java +++ b/sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/StreamContext.java @@ -3,8 +3,6 @@ import org.bytedeco.ffmpeg.avcodec.*; import org.bytedeco.ffmpeg.avformat.AVFormatContext; import org.bytedeco.ffmpeg.global.avcodec; -import org.bytedeco.javacpp.BytePointer; -import org.bytedeco.javacpp.PointerPointer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -164,16 +162,9 @@ public void openCodecContext(AVFormatContext avFormatContext) throws IllegalStat AVCodecParameters params = avFormatContext.streams(getStreamId()).codecpar(); - // Get the associated codec from the ID stored in the context - AVCodec codec = avcodec.avcodec_find_decoder(params.codec_id()); - - if (codec == null) { - throw new IllegalStateException("Unsupported codec"); - } - // Store the codec name - setCodecName(codec.name().getString()); - setCodecId(codec.id()); + setCodecName(avcodec.avcodec_get_name(params.codec_id()).getString()); + setCodecId(params.codec_id()); if (isInjectingExtradata) { String bsfNames = selectBsfName(codecId, avFormatContext);