|
14 | 14 | import org.bytedeco.ffmpeg.avcodec.AVCodecParameters; |
15 | 15 | import org.bytedeco.ffmpeg.avcodec.AVPacket; |
16 | 16 | import org.bytedeco.ffmpeg.avformat.AVFormatContext; |
| 17 | +import org.bytedeco.ffmpeg.avformat.AVIOInterruptCB; |
17 | 18 | import org.bytedeco.ffmpeg.avformat.AVInputFormat; |
18 | 19 | import org.bytedeco.ffmpeg.avutil.AVDictionary; |
19 | 20 | import org.bytedeco.ffmpeg.avutil.AVRational; |
20 | 21 | import org.bytedeco.ffmpeg.global.avcodec; |
21 | 22 | import org.bytedeco.ffmpeg.global.avformat; |
22 | 23 | import org.bytedeco.ffmpeg.global.avutil; |
| 24 | +import org.bytedeco.javacpp.Pointer; |
23 | 25 | import org.bytedeco.javacpp.PointerPointer; |
24 | 26 | import org.slf4j.Logger; |
25 | 27 | import org.slf4j.LoggerFactory; |
|
31 | 33 | import java.util.concurrent.atomic.AtomicBoolean; |
32 | 34 |
|
33 | 35 | 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.*; |
36 | 37 |
|
37 | 38 | /** |
38 | 39 | * The class provides a wrapper to bytedeco.org JavaCpp-Platform. |
@@ -98,6 +99,13 @@ public class MpegTsProcessor extends Thread { |
98 | 99 | */ |
99 | 100 | private AVFormatContext avFormatContext; |
100 | 101 |
|
| 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 | + |
101 | 109 | /** |
102 | 110 | * Flag indicating if processing of the transport stream should be terminated. |
103 | 111 | */ |
@@ -186,7 +194,17 @@ public boolean openStream() { |
186 | 194 | avformat.avformat_network_init(); |
187 | 195 |
|
188 | 196 | // 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); |
190 | 208 |
|
191 | 209 | AVInputFormat inputFormat = null; |
192 | 210 |
|
@@ -526,11 +544,8 @@ public void closeStream() { |
526 | 544 | */ |
527 | 545 | public void stopProcessingStream() { |
528 | 546 | logger.debug("stopProcessingStream"); |
529 | | - |
530 | | - if (streamOpened) { |
531 | | - loop = false; |
532 | | - terminateProcessing.set(true); |
533 | | - } |
| 547 | + loop = false; |
| 548 | + terminateProcessing.set(true); |
534 | 549 | } |
535 | 550 |
|
536 | 551 | /** |
|
0 commit comments