tsduck / tsduck

MPEG Transport Stream Toolkit
https://tsduck.io
BSD 2-Clause "Simplified" License
829 stars 209 forks source link

[FEAT] Add an option to hls output plugin to calculate segment duration based on PTS #1166

Open bdudley-syncbak opened 1 year ago

bdudley-syncbak commented 1 year ago

Is your feature request related to a problem?

The hls output plugin estimates segment duration based on bitrate and file size. When segmenting on I-frames (--intra-close) provide an option to compute segment duration using video PTS.

Proposed solution:

Support a new option, --dur-from-pts perhaps, that will result in hls output plugin using the first video PTS of adjacent segments to compute the segment duration.

Thus, segment n's duration would be computed as follows: duration seg_n = (FirstVideoPTS(seg_n+1) - FirstVideoPTS(seg_n)) / 90_000

Alternatives:

Alternatively, compute it by multiplying the number of video frames by a supplied frame duration.
For example, given a 30/1.001 fps stream where each frame is 3003 90KHz ticks: 60frames * 3003 / 90_000 = 2.002

This alternative may actually be preferred since duration could be computed solely from the frames of the current segment and it's possible the next IDR frame doesn't arrive in time.

Additional information:

I was testing the following tsp pipeline: tsp -I hls -O srt ====> tsp -I srt -O hls and noticed the generated segment's duration did not match those of the source despite the fact that the segments were identical (except for the trailing PAT and PMT packets that resulted from use of --intra-close... it would be nice if those could be suppressed too). --dur-from-pts would result in the generated segment durations matching those of its source.

lelegard commented 1 year ago

Hi @bdudley-syncbak

Sorry for the late response. This one came under the radar.

Could be more specific? I am not sure to understand what you would like to do.

I initially assumed that you wanted to cut segments based on a duration which is measured from the PTS. However, some of your examples contradict this.

Thus, segment n's duration would be computed as follows: duration seg_n = (FirstVideoPTS(seg_n+1) - FirstVideoPTS(seg_n)) / 90_000

In that example, you compute a duration from existing segments. However, we do not have exiting segments, we generate them. We make the decision to cut a segment after reaching the target duration. The logic is reversed.

This alternative may actually be preferred since duration could be computed solely from the frames of the current segment and it's possible the next IDR frame doesn't arrive in time.

Counting frames is highly dependent on the video codec. TSDuck is a TS-level toolkit. There is some best effort to identify some video information (such as start of intra frames) in some video codecs, not more. Consider that AVS3, VVC, AV1 are currently pushing to be used in TS streaming. This would become an endless run against all future video codecs.

tsp -I hls -O srt ====> tsp -I srt -O hls and noticed the generated segment's duration did not match those of the source

There is no reason that the segments would match. The hls input plugin concatenates all segments to form a continuous transport stream, as it would be received from a broadcast signal for instance. At the end of the pipeline, the continuous TS is cut into segments by the hls output plugin. Depending on the various options, the segmentation strategy will vary. At best, the output segmentation will be similar to the input one, but never identical. There is no reason to.

except for the trailing PAT and PMT packets that resulted from use of --intra-close...

There is no trailing PAT and PMT in HLS segments, with or without --intra-close. Maybe you mean leading PAT and PMT.

it would be nice if those could be suppressed too).

No way, the leading PAT and PMT packets are mandatory by the HLS standard.