Canta
Repos
27
Followers
7
Following
1

Events

issue comment
[Q] TSDuck to receive udp, encapsulate TS and then send udp again

just one more issue... ffmpeg and gstreamer work more or less "Real Time" on a normal PC? I mean... would it be able to process it in a way to have video conference, for instance? (supose my gnuradio app works RT) (...) Have to add... camera is not much bitrate, it will be less than 600kbps

Yes, they will work in "real time" in a "normal pc".

However, note you're entering a rabbit hole of possible configurations, contextual problems, and lots of stuff to learn: every single tool you'll pick for this tasks will be a whole new world to deal with. So take it easy and don't try to rush it, because it may be complex and slow to gasp. Just keep slowly learning and trying the available tools, and sooner than later you'll get there. I'll recommend you starting with ffmpeg, as it has lots of people using it and tips everywhere.

Created at 2 weeks ago
issue comment
[Q] TSDuck to receive udp, encapsulate TS and then send udp again

┬┐Can TSDuck receive MP4 from a camera via UDP, adapt from MP4/H264/etc. to TS, and send it via another UDP socket?

I believe TSDuck doesn't handle MP4, even when it contains H.264. The point being: TSDuck is for working with TS. So, in your diagram...

Camera (MP4/H.264 maybe?) ----> UDP Socket sending packets ------> something that encapsulates as TS format ------> another UDP Socket -----> GNURadio transmitter

... something that encapsulates as TS format should more likely be another tool: like ffmpeg or gstreamer for example. This is how to do it with ffmpeg:

ffmpeg -i "udp://UDP_CAMERA_IP:PORT" -c copy -f mpegts "udp://OUTPUT_IP:PORT"

However, using TSDuck's fork input plugin, you can actually make TSDuck's tools (tsp, tsswitch, and so on) to be able to handle the MP4 stream, by just delegating the translation to MPEG-TS to other forked tool. Like this:

tsp -v --timed-log \
-I fork 'ffmpeg -hide_banner -loglevel fatal -nostats -i "udp://UDP_CAMERA_IP:PORT" -c copy -f mpegts -' \
-O ip OUTPUT_IP:PORT

That could be useful for several reasons, but I'm not sure if you actually need it for your use case: it looks like your case is fine for using just ffmpeg or any other, without a strong need for TSDuck.

Created at 2 weeks ago
issue comment
tsswitch: strange switching order

My feeling is that all problems you encounter with that specific configuration come from the fact that you use a reception timeout (2s, the default) which is incompatible with the input sources. The timeout should trigger when there is obviously an error. If a source emits a packet every 2 or 3 seconds, 2s is not a valid timeout. Keep in mind that most TS sources produce megabits per second.

You are, of course, correct about this. I also speculated the timeout and the rate may be related. However, I assure you, I see this behaviour on real streams, and so far I wasn't able to understand why, nor how to trigger it. So, when I saw a reproducible way of triggering the same strange behaviour (at least in the logs), I brought it here.

So, just to let it noted: when I set 1920x1080 and 30fps for the original tsswitch command, it doesn't show the loop, either over the same stream nor between streams. The timeout is key.

But let me show you what I see with real streams. Here's a log from yesterday, with pre-1051 code running:

Sep 11 23:56:41 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:41 - receive timeout, switching to next plugin
Sep 11 23:56:41 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:41 - receive timeout, switching to next plugin
Sep 11 23:56:43 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:43 - receive timeout, switching to next plugin
Sep 11 23:56:43 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:43 - receive timeout, switching to next plugin
Sep 11 23:56:45 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:45 - receive timeout, switching to next plugin
Sep 11 23:56:45 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:45 - receive timeout, switching to next plugin
Sep 11 23:56:47 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:47 - receive timeout, switching to next plugin
Sep 11 23:56:47 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:47 - receive timeout, switching to next plugin
Sep 11 23:56:49 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:49 - receive timeout, switching to next plugin
Sep 11 23:56:49 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:49 - receive timeout, switching to next plugin
Sep 11 23:56:51 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:51 - receive timeout, switching to next plugin
Sep 11 23:56:51 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:51 - receive timeout, switching to next plugin
Sep 11 23:56:53 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:53 - receive timeout, switching to next plugin
Sep 11 23:56:53 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:53 - receive timeout, switching to next plugin
Sep 11 23:56:55 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:55 - receive timeout, switching to next plugin
Sep 11 23:56:55 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:55 - receive timeout, switching to next plugin
Sep 11 23:56:57 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:57 - receive timeout, switching to next plugin
Sep 11 23:56:57 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:57 - receive timeout, switching to next plugin
Sep 11 23:56:59 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:56:59 - receive timeout, switching to next plugin
Sep 11 23:56:59 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:56:59 - receive timeout, switching to next plugin
Sep 11 23:57:01 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:57:01 - receive timeout, switching to next plugin
Sep 11 23:57:01 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:57:01 - receive timeout, switching to next plugin
Sep 11 23:57:03 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:57:03 - receive timeout, switching to next plugin
Sep 11 23:57:03 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:57:03 - receive timeout, switching to next plugin
Sep 11 23:57:05 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:57:05 - receive timeout, switching to next plugin
Sep 11 23:57:05 live1 tsswitch_realstream1[2455]: * 2022/09/11 23:57:05 - receive timeout, switching to next plugin
Sep 11 23:57:07 live1 tsswitch_realstream2[2455]: * 2022/09/11 23:57:07 - receive timeout, switching to next plugin
(...)

I run tsswitch as a service, outputing its logs to the common syslog. That's why you see extra logging there. This is implementing the use case with 3 inputs, described in my original post. And I have multiple of those commands: one per signal. I want to achieve both redundancy between two alternate inputs AND a blackout fallback in case both inputs turn offline for some reason.

Here's the command line for that:

  tsswitch -v --timed-log --primary-input 1 --remote 127.0.0.1:$CONTROL_PORT --delayed-switch \
    -I fork "ffmpeg -hide_banner -nostats -y -loglevel error -i 'REDACTED_INPUT_1' -map 0:v -map 0:a -c copy -fflags '+flush_packets +genpts' -avioflags direct -movflags faststart -pcr_period 20 -max_muxing_queue_size 9999 -muxdelay 0 -muxpreload 0 -mpegts_service_id 100 -streamid 0:0x0001 -streamid 1:0x0002 -f mpegts -" \
    -I fork "ffmpeg -hide_banner -nostats -y -loglevel error -i 'REDACTED_INPUT_2' -map 0:v -map 0:a -c copy -fflags '+flush_packets +genpts' -avioflags direct -movflags faststart -pcr_period 20 -max_muxing_queue_size 9999 -muxdelay 0 -muxpreload 0 -mpegts_service_id 100 -streamid 0:0x0001 -streamid 1:0x0002 -f mpegts -" \
    -I fork "ffmpeg -hide_banner -nostats -y -loglevel error -fflags nobuffer -flags low_delay -use_wallclock_as_timestamps 1 -f lavfi -re -i 'color=black:s=1280x720:r=30' -fflags nobuffer -flags low_delay -use_wallclock_as_timestamps 1 -f lavfi -i 'anullsrc' -map 0:v -map 1:a -c:v h264 -preset ultrafast -r 30 -c:a aac -ar 48k -b:a 128k -fflags '+flush_packets +genpts' -avioflags direct -movflags faststart -pcr_period 20 -max_muxing_queue_size 9999 -muxdelay 0 -muxpreload 0 -mpegts_service_id 100 -streamid 0:0x0001 -streamid 1:0x0002 -f mpegts -" \
    -O ip $OUTPUT_IP_AND_PORT 2>&1

As explained before, that may be working fine for days, switching properly on events of input timeouts and also switching back to the primary stream when it comes back. But it also may suddenly fall into that loop described before, to never recover. That is: the input streams do recover, but tsswitch doesn't.

Note --primary-input 1, and not 0. That is intended. So it will switch first to the black screen. There's another story behind that, not related to tsswitch but the origin streams context. Just know the 1 value is not a mistake.

Please also note I did test LOTS of configurations:

  • ip and srt inputs instead of fork.
  • Other tools instead of ffmpeg.
  • Hundreds of calibrations for the streams (timestamps, bitrates, codecs, buffers...)
  • All calibrations I could find for tsswitch (timeouts, primary, fast vs delayed...)

All of that with the same results: tsswitch sometimes does the stuff we're seeing here.

But here's also a recent log, with the new logging strings and the fixes from this very ticket:

Sep 12 11:52:06 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:06 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:08 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:08 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:10 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:10 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:12 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:12 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:14 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:14 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:16 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:16 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:18 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:18 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:20 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:20 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:22 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:22 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:24 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:24 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:26 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:26 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:28 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:28 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:30 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:30 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:32 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:32 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:34 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:34 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:35 live1 tsswitch_realstream1[2455]: * 2022/09/12 11:52:35 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:36 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:36 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:37 live1 tsswitch_realstream1[2455]: * 2022/09/12 11:52:37 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:38 live1 tsswitch_realstream4[2455]: * 2022/09/12 11:52:38 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:52:39 live1 tsswitch_realstream1[2455]: * 2022/09/12 11:52:39 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:53:19 live1 tsswitch_realstream1[2455]: * 2022/09/12 11:53:19 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:53:21 live1 tsswitch_realstream1[2455]: * 2022/09/12 11:53:21 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:53:23 live1 tsswitch_realstream1[2455]: * 2022/09/12 11:53:23 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 11:53:25 live1 tsswitch_realstream1[2455]: * 2022/09/12 11:53:25 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:02:04 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:02:04 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:02:06 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:02:06 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:02:08 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:02:08 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:02:10 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:02:10 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:02:12 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:02:12 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:02:14 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:02:14 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:21 live1 tsswitch_realstream3[2455]: * 2022/09/12 12:19:21 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:22 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:19:22 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:22 live1 tsswitch_realstream2[2455]: * 2022/09/12 12:19:22 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:23 live1 tsswitch_realstream3[2455]: * 2022/09/12 12:19:23 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:24 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:19:24 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:24 live1 tsswitch_realstream2[2455]: * 2022/09/12 12:19:24 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:26 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:19:26 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:26 live1 tsswitch_realstream2[2455]: * 2022/09/12 12:19:26 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:28 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:19:28 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:28 live1 tsswitch_realstream2[2455]: * 2022/09/12 12:19:28 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:30 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:19:30 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:30 live1 tsswitch_realstream2[2455]: * 2022/09/12 12:19:30 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:32 live1 tsswitch_realstream1[2455]: * 2022/09/12 12:19:32 - receive timeout, switching to next plugin (#1 to #2)
Sep 12 12:19:32 live1 tsswitch_realstream2[2455]: * 2022/09/12 12:19:32 - receive timeout, switching to next plugin (#1 to #2)

This actually DID fixed itself: the tsswitch loop eventually stopped, and the stream was graciously recovered. But yesterday's loop kept stuck forever, disregaring the input streams status. And that previous run also recovered itself some days ago: just yesterday kept stuck, and not "every time there's some error".

So... it's hard to diagnose. I had hope the "low bitrate" example would lead to an easier to debug situation.

I believe the last logs indicate something like timeout #1, then recovered before starting #2, then timeout #1 again in a loop. And this time, we're talking about a real 1080p ~5Mbps stream, sent remotely by a third party.

I'll keep it running for days, and let you know if something new happens.

Thank you.

Created at 2 weeks ago
issue comment
tsswitch: strange switching order

The first problem is a false impression from successive verbose messages such as "switching to next plugin (# 0 to # 1)", with always the same switch, here "# 0 to # 1". You use option --primary-input 0, meaning that the primary plugin is never stopped and whenever a packet arrives from it, if the current plugin is another one, we immediately switch back to the primary plugin. But there is no verbose message to say that we switched back. So, the two successive switching on timeout "(# 0 to # 1)" were in fact separated by a switch back to the primary plugin # 0 because of a packet arriving from it.

I see. If that's the case, I believe --fast-switch should change that. But I saw somewhere an open issue regarding --fast-switch and --infinity, so I decided to use only --infinity.

The absence of verbose message at that point was due to the same reason I explained in https://github.com/tsduck/tsduck/issues/1051: I do not like the idea of logging a verbose message while the mutex is held. Anyway, since it creates trouble in the users mind, I added it. In case of performance issue, just omit the --verbose option.

Very well.

The second problem is due to the fact that, sometimes, not always (why?), the ffmpeg process takes a long time to die when killed, for some reason I ignore.

Not sure, but probably can be handled with SIGKILL. Will take a look at it.

I do not know exactly what this type of ffmpeg does (what is the testsrc input?) but it produces packets at a very very slow bitrate. The default reception timeout (2 seconds) is too small in that case.

I figured that out (the bitrate/timeout situation), but let it fail anyway, so I could reproduce the issue I've seen with real streams. But I can explain that ffmpeg command.

  • -f lafvi as input means "use the lavfi decoder". lavfi refers to Lib AV Filter, which is the component from the whole "libav" collection of libraries used for audio and video filtering. In the case of the ffmpeg command line, it's tipically used when you utilize the -filter_complex flag, as well as the -vf ("video filter") and -af ("audio filter") flags. But it also has the ability to generate streams using the filter library, by means of working as a "decoder" or "demuxer" (not entirely sure which one), which is the case in the example before. So, when you use -f lavfi, you can later pass it -i "filter_syntax_here".
  • testsrc is one of the many lavfi available filters. It creates a testing screen video, with some colours and a counter. The rest of the syntax after testsrc are filter parameters. One of them is the screen size.
  • But the last parameter for testsrc is r=1. "r" is for "rate", and that means "1 fps". And that's the reason for the low bitrate. The streams were configured that way in order to avoid unwanted CPU usage during my tests. But if you change that to r=30, you'll have a "normal" 30fps stream, with obviously higher bitrate. The and same goes for the screen size: set it to 1920x1080 if you want to.
  • You may also add some bitrate output parameters. I didn't needed them for this example, so I kept it simple.

When I developed tsswitch, I realised that the number of possible scenarios was very high, depending on switching modes, primary input or not, etc. A simple state machine would not be sufficient since there was no simple state transition. Some kind of virtual code was necessary. However, this is not yet a miraculous strategy and problems remain such as the long-standing bug https://github.com/tsduck/tsduck/issues/324.

Thank you very much for the insights.

I'm building right now the new code, and will deploy it to some server in order to test it with real streams. Please give me some days to see if it somehow fails (I've had a fail yesterday, with pre-1051 code, after days of working fine), so we can check out the new logs, trying to find if something's still going on or it is actually fixed. Is it ok to keep the ticket open until next Friday, so I can test it the whole week?

Best regards.

Created at 2 weeks ago
opened issue
tsswitch: strange switching order

Hi there.

I'm curious about some situations where tsswitch doesn't seem to switch to the proper stream, or just does it kinda erratically. This is related to #1051 : I actually wanted that functionality in order to monitor and track this other issue.

I saw a few times, working with streams received from remote sources, that tsswitch may kept stuck in some kind of unintended loop on a single stream. But this was quite cumbersome to diagnose, as the log didn't tell the current and next stream when switching. However, today I built tsswitch again after #1051, and could see this behaviour locally, using test streams:

$ bin/release-x86_64-HOSTNAME/tsswitch \
-v --infinite --primary-input 0 --timed-log  \
-I fork 'ffmpeg -hide_banner -loglevel fatal -f lavfi -re -i "testsrc=320x240:r=1" -c:v h264 -preset ultrafast -t 60 -f mpegts -' \
-I fork 'ffmpeg -hide_banner -loglevel fatal -f lavfi -re -i "testsrc=320x240:r=1" -c:v h264 -preset ultrafast -t 120 -f mpegts -' \
-O ip 127.0.0.1:12345
* 2022/09/09 14:04:28 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:04:30 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:04:38 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:04:40 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:04:43 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:04:45 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:04:49 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:04:51 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:04:54 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:04:56 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:04:59 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:01 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:04 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:09 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:11 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:17 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:20 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:22 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:26 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:28 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:30 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:32 - receive timeout, switching to next plugin (#0 to #1)
* 2022/09/09 14:05:35 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:37 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:39 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:41 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:43 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:45 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:47 - receive timeout, switching to next plugin (#1 to #0)
* 2022/09/09 14:05:50 - receive timeout, switching to next plugin (#1 to #0)
^C

Note the following points:

  • Sometimes, not always, it keeps "switching to next plugin" while never actually changing the current stream index.
  • Sometimes, not always, the switching timing matches the default 2000 ms. But other times that's not the case.
  • The input streams are forks that I don't change. Yet, tsswitch behaviour is not predictable/constant/always-the-same.

This was obviously a test. But I saw this kind of strange behaviour working with real streams.

My real use case would be having 3 inputs:

  1. Real stream, primary, using either ip, srt, or fork input plugins.
  2. Real stream, secondary, using either ip, srt, or fork input plugins.
  3. Locally generated black screen stream, most likely using fork input plugin, but could also be ip.

I did a lot of calibrations working with real streams on that situation (timeouts, priorities, packet sizes, bitrates, input filters, and so on), and eventually felt that tsswitch's behaviour wasn't actually under my control: sometimes it was deciding to correctly change streams as I told it, but other times it kept in weird loops never reconnecting to the proper inputs (usually stated with --primary-input). Sometimes it switched to the black screen to never return to main streams (keeping the black screen forever), other times it didn't even connected to the black screen stream. And sometimes it worked great for days, without me changing anything.

Could this be indication of some bug? Perhaps I'm missunderstanding something? I would appreciate your insights on this.

Thanks.

Created at 2 weeks ago
issue comment
tsswitch: log stream indexes when changing streams.

Oh, thank you very much! :)

I have several of this little modifications in my agenda. I was originally planning to make pull requests, because I wouldn't want to add extra work to your own agenda, and this kind of changes are actually pretty small. However, even when I mostly understand what to do, I'm not actually a C++ programmer, so I wasn't really sure about "just doing PRs and then we'll see": dealing with C++ novice code may be even more annoying for you than dealing with small requests.

I'll like to adapt to your way of working. So, let me ask you: would you prefer the creation of several issues from time to time asking for little modifications like this one, or would you rather prefer PRs to take a look at?

Thanks.

Created at 3 weeks ago
opened issue
tsswitch: log stream indexes when changing streams.

Hi there.

When using tsswitch, the -v and --timed-log add status data to the process output. One of those status data looks like this: * 2022/09/06 10:12:56 - receive timeout, switching to next plugin.

I would like to ask for a modification on this notification: to also log the current stream index, and the next stream index.

I've done some modifications to my local tsswitch build, so this log now looks like this: * 2022/09/06 16:31:08 - receive timeout, switching to next plugin. Actual: #0. Next: #1 * 2022/09/06 16:31:10 - receive timeout, switching to next plugin. Actual: #1. Next: #0

Here are my experimental code changes for that:

diff --git a/src/libtsduck/plugins/private/tstsswitchCore.cpp b/src/libtsduck/plugins/private/tstsswitchCore.cpp
index 2766ab14..b7ad18f6 100644
--- a/src/libtsduck/plugins/private/tstsswitchCore.cpp
+++ b/src/libtsduck/plugins/private/tstsswitchCore.cpp
@@ -260,10 +260,15 @@ void ts::tsswitch::Core::setInputLocked(size_t index, bool abortCurrent)
 
 void ts::tsswitch::Core::handleWatchDogTimeout(WatchDog& watchdog)
 {
-    _log.verbose(u"receive timeout, switching to next plugin");
+    size_t next = (_curPlugin + 1) % _inputs.size();
+    _log.verbose(u"receive timeout, switching to next plugin. Actual: #" 
+      + UString::Format(u"%d", {_curPlugin})
+      + u". Next: #"
+      + UString::Format(u"%d", {next})
+    );
 
     GuardMutex lock(_mutex);
-    setInputLocked((_curPlugin + 1) % _inputs.size(), true);
+    setInputLocked(next, true);
 }

What do you think about this change?

Best regards.

Created at 3 weeks ago