Skip to content

Commit c5a1302

Browse files
authored
Merge pull request #27 from Botts-Innovative-Research/rtmp-driver
Rtmp driver
2 parents f9199b8 + c528b47 commit c5a1302

11 files changed

Lines changed: 834 additions & 8 deletions

File tree

sensors/video/sensorhub-driver-ffmpeg/src/main/java/org/sensorhub/mpegts/MpegTsProcessor.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
import org.bytedeco.ffmpeg.avcodec.AVCodecParameters;
1515
import org.bytedeco.ffmpeg.avcodec.AVPacket;
1616
import org.bytedeco.ffmpeg.avformat.AVFormatContext;
17+
import org.bytedeco.ffmpeg.avformat.AVIOInterruptCB;
1718
import org.bytedeco.ffmpeg.avformat.AVInputFormat;
1819
import org.bytedeco.ffmpeg.avutil.AVDictionary;
1920
import org.bytedeco.ffmpeg.avutil.AVRational;
2021
import org.bytedeco.ffmpeg.global.avcodec;
2122
import org.bytedeco.ffmpeg.global.avformat;
2223
import org.bytedeco.ffmpeg.global.avutil;
24+
import org.bytedeco.javacpp.Pointer;
2325
import org.bytedeco.javacpp.PointerPointer;
2426
import org.slf4j.Logger;
2527
import org.slf4j.LoggerFactory;
@@ -31,8 +33,7 @@
3133
import java.util.concurrent.atomic.AtomicBoolean;
3234

3335
import static org.bytedeco.ffmpeg.global.avdevice.avdevice_register_all;
34-
import static org.bytedeco.ffmpeg.global.avformat.av_find_input_format;
35-
import static org.bytedeco.ffmpeg.global.avformat.av_read_frame;
36+
import static org.bytedeco.ffmpeg.global.avformat.*;
3637

3738
/**
3839
* The class provides a wrapper to bytedeco.org JavaCpp-Platform.
@@ -98,6 +99,13 @@ public class MpegTsProcessor extends Thread {
9899
*/
99100
private AVFormatContext avFormatContext;
100101

102+
/**
103+
* Callbacks allow some blocking AVFormatContext operations to terminate early on
104+
* stream close. These are global for GC purposes; do not directly modify.
105+
*/
106+
private AVIOInterruptCB.Callback_Pointer callbackPointer;
107+
private AVIOInterruptCB interruptCallback;
108+
101109
/**
102110
* Flag indicating if processing of the transport stream should be terminated.
103111
*/
@@ -186,7 +194,17 @@ public boolean openStream() {
186194
avformat.avformat_network_init();
187195

188196
// Create a new AV Format Context for I/O
189-
avFormatContext = new AVFormatContext(null);
197+
avFormatContext = avformat_alloc_context();
198+
199+
// Allow for context to be interrupted after attempt to stop stream
200+
interruptCallback = avFormatContext.interrupt_callback();
201+
callbackPointer = new AVIOInterruptCB.Callback_Pointer() {
202+
@Override
203+
public int call(Pointer opaque) {
204+
return terminateProcessing.get() ? 1 : 0;
205+
}
206+
};
207+
interruptCallback.callback(callbackPointer);
190208

191209
AVInputFormat inputFormat = null;
192210

@@ -526,11 +544,8 @@ public void closeStream() {
526544
*/
527545
public void stopProcessingStream() {
528546
logger.debug("stopProcessingStream");
529-
530-
if (streamOpened) {
531-
loop = false;
532-
terminateProcessing.set(true);
533-
}
547+
loop = false;
548+
terminateProcessing.set(true);
534549
}
535550

536551
/**
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# FFmpeg RTMP Driver
2+
3+
OSH sensor driver using FFmpeg to listen to RTMP streams.
4+
5+
This driver depends on the following modules at runtime:
6+
* sensorhub-driver-ffmpeg
7+
8+
## Config
9+
10+
### Connection
11+
12+
* **Host**
13+
- RTMP server host
14+
- **UNSPECIFIED**: listen for remote connections.
15+
- **LOCALHOST**: listen for local connections.
16+
- **DOCKER_INTERNAL**: listen for connections inside a docker container.
17+
* **Port**
18+
- RTMP server port
19+
- 1935 is the default port for RTMP.
20+
- Any port may be used as long as it is not in use by another listener (or any other application).
21+
- RTMP sensor driver modules track ports in use. To release ownership of a port, STOP the module.
22+
23+
## Usage
24+
25+
### Initialization
26+
27+
<p>To initialize the driver, provide a unique serial number in the configuration.
28+
In connection, set the host and provide an unused port. Once initialized, other RTMP sensor driver modules cannot
29+
use the same port.
30+
<br><br><strong>Stop</strong> the module to free the port.</p>
31+
32+
### Listening
33+
34+
<p>Once initialized, start the module to begin listening for RTMP connections. <strong>After</strong> the driver
35+
is started, begin publishing the RTMP stream.
36+
<br><br><strong>Note</strong>: The module does NOT attempt to validate the
37+
username, password, RTMP app, or RTMP playpath. Only the host and port need to match.</p>
38+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
description = 'RTMP Video Driver'
2+
ext.details = 'Driver to listen for and demux RTMP video streams'
3+
version = '1.0.0'
4+
5+
dependencies {
6+
implementation 'org.sensorhub:sensorhub-core:' + oshCoreVersion
7+
implementation project(':sensorhub-driver-ffmpeg')
8+
}
9+
10+
// add info to OSGi manifest
11+
osgi {
12+
manifest {
13+
attributes('Bundle-Vendor': 'GeoRobotix Innovative Research')
14+
attributes('Bundle-Activator': 'org.sensorhub.impl.sensor.rtmp.Activator')
15+
}
16+
}
17+
18+
// add info to maven pom
19+
ext.pom >>= {
20+
developers {
21+
developer {
22+
id 'kyle-fitzp'
23+
name 'Kyle Fitzpatrick'
24+
organization 'GeoRobotix Innovative Research'
25+
organizationUrl 'https://georobotix.us'
26+
}
27+
}
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/***************************** BEGIN LICENSE BLOCK ***************************
2+
The contents of this file are subject to the Mozilla Public License, v. 2.0.
3+
If a copy of the MPL was not distributed with this file, You can obtain one
4+
at http://mozilla.org/MPL/2.0/.
5+
6+
Software distributed under the License is distributed on an "AS IS" basis,
7+
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8+
for the specific language governing rights and limitations under the License.
9+
10+
Copyright (C) 2026 GeoRobotix Innovative Research, Inc. All Rights Reserved.
11+
******************************* END LICENSE BLOCK ***************************/
12+
13+
package org.sensorhub.impl.sensor.rtmp;
14+
15+
import org.osgi.framework.BundleActivator;
16+
import org.sensorhub.utils.OshBundleActivator;
17+
18+
19+
/*
20+
* Needed to expose java services as OSGi services
21+
*/
22+
public class Activator extends OshBundleActivator implements BundleActivator
23+
{
24+
25+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/***************************** BEGIN LICENSE BLOCK ***************************
2+
The contents of this file are subject to the Mozilla Public License, v. 2.0.
3+
If a copy of the MPL was not distributed with this file, You can obtain one
4+
at http://mozilla.org/MPL/2.0/.
5+
6+
Software distributed under the License is distributed on an "AS IS" basis,
7+
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8+
for the specific language governing rights and limitations under the License.
9+
10+
Copyright (C) 2026 GeoRobotix Innovative Research, Inc. All Rights Reserved.
11+
******************************* END LICENSE BLOCK ***************************/
12+
13+
package org.sensorhub.impl.sensor.rtmp;
14+
15+
import org.sensorhub.api.module.IModule;
16+
import org.sensorhub.api.module.IModuleProvider;
17+
import org.sensorhub.api.module.ModuleConfig;
18+
import org.sensorhub.impl.module.JarModuleProvider;
19+
import org.sensorhub.impl.sensor.rtmp.config.RtmpConfig;
20+
21+
22+
public class RtmpDescriptor extends JarModuleProvider implements IModuleProvider
23+
{
24+
25+
@Override
26+
public Class<? extends IModule<?>> getModuleClass()
27+
{
28+
return RtmpDriver.class;
29+
}
30+
31+
32+
@Override
33+
public Class<? extends ModuleConfig> getModuleConfigClass()
34+
{
35+
return RtmpConfig.class;
36+
}
37+
38+
}

0 commit comments

Comments
 (0)