Regulate plugin as BITRATE LIMITER Issue 79 tsduck tsduck GitHub
Regulate plugin as BITRATE LIMITER · Issue #79 · tsduck/tsduck · GitHub Skip to content Toggle navigation Sign up In this repository All GitHub ↵ Jump to ↵ No suggested jump to results In this repository All GitHub ↵ Jump to ↵ In this organization All GitHub ↵ Jump to ↵ In this repository All GitHub ↵ Jump to ↵ Sign in Sign up {{ message }} tsduck / tsduck Public Notifications Fork 159 Star 596 New issue Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community. Pick a username Email Address Password Sign up for GitHub By clicking "Sign up for GitHub", you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails. Already on GitHub? Sign in to your account Jump to bottom Regulate plugin as BITRATE LIMITER #79 Closed lars18th opened this issue Jul 2, 2018 · 15 comments Closed Regulate plugin as BITRATE LIMITER #79 lars18th opened this issue Jul 2, 2018 · 15 comments Labels enhancement Comments Copy link Contributor lars18th commented Jul 2 2018 Hi @lelegard , Let me to explain this user-case: When doing a MUXING (using TSDuck merge or an external tool) it's good to have some kind of lifeline for the input streams. For example, imagine that one of your IP multicast inputs begins to receive a lot of erroneous data because a network loop. Or imagine one HTTP input that floods the stream with an excesive burst of data. In such scenarios a bandwith limiter can be a life preserver. The idea is that when one entry is in trouble, other entries are not disturbed. This can be done limiting the maximum bitrate of the input (without taking any further action). For example with something like -P regulate --max-bandwith 15000000. In this case, with a mux of 38Mbps and 4 VBR inputs the glitches when one input goes in troubles will be minimized. What you think? The text was updated successfully, but these errors were encountered: All reactions Copy link Member lelegard commented Jul 3 2018 Two scenarios need to be specified: What should we do when the bitrate is lower or significantly lower than the max ? What should we do when the bitrate is higher than the max ? In the first case, what is the current behaviour of -P regulate --bitrate 1500000 ? Is it ok for you ? I haven't made such tests myself but tsp cannot accelerate the stream. So, lower bitrates should remain unchanged. In the second case, what should we do with the extra packets? Currently, regulate passes all packets but slow them down to the target bitrate. So, they accumulate and the complete chain is temporarily blocked when the global buffer is full. This is the intended behaviour for input files for instance. If the input is a real-time UDP/IP stream, then input packets are dropped and, as a result, regulate --bitrate already acts as a bandwidth limiter. We may object that, while effectively limiting the bandwidth, there is probably a latency effect because of the buffer and the resulting stream can be somewhat chaotic. One possibility could be to add a --drop option in regulate so that the plugin would drop packets in excess instead of making them wait. As a synthesis, could you specify precisely what should be done, in details ? All reactions Sorry, something went wrong. Copy link Contributor Author lars18th commented Jul 3 2018 Hi @lelegard , As a synthesis, could you specify precisely what should be done, in details ? I'll try. ? The target user-case is INPUTS before a MUXER. I feel this scenario explains the problem: If some input goes bad, then it's best to not disturb other inputs. The idea is leave the muxer (aka merge plugin or an external tool) to complete the task without generating errors with the programs that are ok. So, a first mesure is to apply a hard limit to the bitrate of each input to a maximum value. So, in case of a burst (temporal or permanent) in one input the muxer will never be saturated or collapsed for this reason. I know that this countermeasure never be perfect. For example, using VBR inputs, is quite easy to overpass the limit. However, using CBR inputs, or inputs with small bitrate variations, this measure can resolve a lot of cases. What should we do when the bitrate is higher than the max ? It needs to drop packets. No more, no less. However, it will be interesting if the drop is done in a smart way. For example, if the bitrate rebases the maximum, it's best to drop video packets in one chunk than drop N packets every M... or drop packets from any pid. This behaviour will generate errors in the video, but it maintains the integrity of the rest. Even if PCR packets are never discarded, and also are recomputed, then the stream will be "limited" but "processable". This is only an example, but (I hope) it illustrates the objective. ? At time, the "input buffer" can be used to achieve partially this behaviour. So, if the bitrate is very high then it's cutted. However, this buffer isn't related to the bitrate. Futhermore, it only drops a large number of consecutive packets, that's the worst action. I hope you can understand the problem and provide a simple and smart solution. In my opinion, this functionality can be incorporated in the regulate plugin, but if you prefer you can add a new limiter one. What you think? More clear now? All reactions Sorry, something went wrong. Copy link Member lelegard commented Jul 3 2018 Several remarks : A plugin cannot have a global view on the input buffer or a group of packets in general. A plugin processes all packets one by one, one at a time. This is a limitation by design of tsp. It can be problematic sometimes. But it also makes TSDuck much simpler to maintainn and enhance. We can start from the hypothesis that a plugin drops packets when the bitrate becomes higher that some limit. This plugin would: Constantly re-evaluate bitrate, based on PCR's, with a fast instantaneous rate, typically all pairs of consecutive PCR's. Analyze all PSI to keep a permanent map of all PID's (which is video, audio, etc.) When regulate would typically wait, this plugin drops packets instead. But when a packet should be dropped, we consider the usage of this packet. Packets with video but without PCR are the first candidates for elimination. When a packet should be dropped but is not a good candidate (PCR, PSI, etc), it is not dropped but this increases some kind of "packet credit". This credit must be paid back later. It should also not exceed some limit, after which more precious packets will be dropped anyway. In the case of a merge, this plugin should be used in the merged tsp command, before actual merging. If you use the new plugin after merge, there is no way to know from which branch a packet comes. Will this answer your problem? Do you see other constraint or specification? All reactions Sorry, something went wrong. Copy link Member lelegard commented Jul 3 2018 Moreover, when selecting packets for elimination, what should be the strategy to select among good candidates? Should we eliminate video packets without PCR if they belong to distinct PID's? Or give the priority to one video PID? And which one? Dropping one video packet usually extends the damages beyond this packet. So, it could be more interesting to degrade one single video PID's instead of several ones. But, this also increase the "packet credit" and possible side effects. All reactions Sorry, something went wrong. Copy link Contributor Author lars18th commented Jul 3 2018 Hi @lelegard , You're very good picking up the specs! ? As a summarize: Plugin name: limiter. A new plugin is required to not disturb the complexity. This plugin "removes" and not "erases" packets. That's any removed packet is discarded and not replaced by nulls. However, for more flexibility, an optional parameter like --erase can modify this default behaviour. It can be applied to any stream, MPTS or SPTS. Parameters: -P limiter --vpid XXX --bitrate NNN --vpid YYY --bitrate MMM --bitrate-max LLL. Where, --vpid & --bitrate pair indicates at which video pid apply the limit. Multiple pairs are possible for MPTS streams. Only pids indicated can be smart limited. When a video pid is limited, the strategy is simple: remove a consecutive number of packets to achieve the target bitrate for this pid. Packets with PCR aren't discarded. If it's possible, discard packets are between two PUSI marks. The --bitrate-max indicates the total maximum bitrate of the entire stream. So this task is done after complete the video pid limiting. When it's required to drop packets at the end, any packet can be droped. So here a big chunk of consecutive packets are directly removed. For a more flexibility, in fact --vpid can be applied to any type of stream. However, when it's not a video stream then no smart strategy is used. This can be useful for data streams. You agree? All reactions Sorry, something went wrong. Copy link Member lelegard commented Jul 3 2018 So, you would like to limit the bitrate per PID, not only the TS bitrate ? And with a different limit per PID ? It seems a bit complicated. My understanding was that this plugin would be used to protect from input or merging plugins becoming crazy. So, in that case, the packet removal does not need to be so surgical. All reactions Sorry, something went wrong. Copy link Contributor Author lars18th commented Jul 5 2018 Dear @lelegard , Sorry for the mistake! Your work is impresive, but sometimes I forget that this is an open project. I like to collaborate, and not disturb. And you're right, I'm mixing in my last post incorrect specifications. So, let me summarize (again): Plugin name: limiter. Objective: Limit the total bitrate of an stream. Target: Mainly for SPTS, as for MPTS only burden limit can be applied. Parameters: -P limiter --pid XXX --bitrate NNN. Param --bitrate: Required. Is the maximum bitrate permited for the stream. Over this limit packets are discarded in secuential chunks. Param --pid: Optional. If it's used then a first stage removal is done only over this pid. If this substream is video, then a smart strategy is used. This strategy consist in try to remove chunks of consecutive packets between two PUSI marks. And all PCR packets are preserved. Discard method: Pure packet removing, not erase them, so the output bitrate is reduced. Now I feel the specifications are more simple and clear. ? The idea is to use this plugin only with SPTS's before a mux/merge action. You agree now? All reactions Sorry, something went wrong. lelegard added the enhancement label Jul 5, 2018 Copy link Member lelegard commented Sep 14 2018 Hi @lars18th I just added plugin limit. Please review it and give us your feedback. All reactions Sorry, something went wrong. Copy link Contributor Author lars18th commented Sep 20 2018 Hi @lelegard , Interesting implementation. I'm reading the documentation and it seems nice. Thank you! However, one suggestion: Why not add too a --threshold4 for any audio PID and leave --threshold3 only for video? I prefer to discard only video packets and not touch audio packets! With the current implementation, audio doesn't have any preference over video. In brief: -3 only for video, and new -4 only for audio. All reactions Sorry, something went wrong. Copy link Contributor Author lars18th commented Sep 21 2018 Hi @lelegard , Another simple enhancement to the limit plugin: Can you add support for the value "-1" in the thresholds? The idea is to "disable" the threshold (so, "-1" equals to disabled). Why this? Well, the first threshold is for NULL packets. But, in case you like to remove only from specific pids then you can use a two stages like this: tsp ... \ -P limit -b 10000 --threshold1 -1 -p 2222 --threshold2 1 --threshold3 -1 \ -P limit -b 10000 --threshold1 10 --threshold3 1000 \ ... In this case, in the first stage you remove only packets from pid 2222. And in the second stage you can remove the rest. Just to comment: another parameter like --no-strict can be required in the first stage to not drop more packets at last, so the bitrate can be exceeded. The idea is leave to the user the option to stablish the preference of the thresholds. You got it? PD: Perhaps "0" is preferable, as "1" is the real minimum, and "-1" can be confused with the -1|--threshold1. All reactions Sorry, something went wrong. Copy link Contributor Author lars18th commented Jan 4 2019 Hi @lelegard , I'm working in implementing some enhancements (separate thresholds for audio and video in the pid list, and the disable mode). However, I feel I found one BUG in your code: See https://github.com/tsduck/tsduck/blob/master/src/tsplugins/tsplugin_limit.cpp#L210 I feel the correct code should be: _thresholdAV = _pids1.any() ? _threshold2 : _threshold1; Because in this check https://github.com/tsduck/tsduck/blob/master/src/tsplugins/tsplugin_limit.cpp#L425 the threshold to check is _threshold2 when -pid is used and _threshold1 when not. I'm right? All reactions Sorry, something went wrong. Copy link Contributor Author lars18th commented Jan 4 2019 Hi @lelegard , I created this PR #190 to implement the improvements I requested. If you merge it, then we will be able to close this issue. Just one comment: with my enhancement only audio/video pids from the pid list are discarded. I don't see any sense to discard "other" pids from a service. Regards. All reactions Sorry, something went wrong. Copy link Member lelegard commented Jan 4 2019 Just one comment: with my enhancement only audio/video pids from the pid list are discarded. I don't see any sense to discard "other" pids from a service. On the contrary, large data PID's could be good candidates to sacrifice in case of overflow. For instance, a large EPG PID can be considered as less important than other audio/video PID. Your choice. No need to add a 5th threshold. I will integrate your PR and will modify it so that below threshold 3 all selected --pid are dropped (not only audio). So, specified video is dropped first, then audio or data. ? 1 lars18th reacted with thumbs up emoji All reactions ? 1 reaction Sorry, something went wrong. Copy link Member lelegard commented Jan 4 2019 I feel the correct code should be: _thresholdAV = _pids1.any() ? _threshold2 : _threshold1; You are right ? ? 1 lars18th reacted with thumbs up emoji All reactions ? 1 reaction Sorry, something went wrong. lelegard added the close pending label Jan 4, 2019 Copy link Contributor Author lars18th commented Jan 4 2019 Hi, I close this issue as the PR is merged: #190 (comment) Thank you! All reactions Sorry, something went wrong. lars18th closed this as completed Jan 4, 2019 lelegard removed the close pending label Sep 23, 2022 Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment Assignees No one assigned Labels enhancement Projects None yet Milestone No milestone Development No branches or pull requests 2 participants You can’t perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.