mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-08-09 09:32:43 +00:00
avformat/hls: set stream start_time for all playlist types
Rebase the first packet's timestamp onto the start of the segment list regardless of playlist type, and report it as start_time. Previously only EVENT playlists did this and live streams took start_time from the first loaded segment at the live edge. Which is not correct as some servers provide very deep (hours even) time shift in live playlist. The evicted segments are already tracked by EXT-X-MEDIA-SEQUENCE. This allows us to use all available segments, not only the future ones on live playlist. Also prefer PTS over DTS, as EXTINF durations and start_time are presentation time. Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
This commit is contained in:
@@ -2205,6 +2205,7 @@ static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls,
|
||||
/* add new subdemuxer streams to our context, if any */
|
||||
static int update_streams_from_subdemuxer(AVFormatContext *s, struct playlist *pls)
|
||||
{
|
||||
HLSContext *c = s->priv_data;
|
||||
int err;
|
||||
|
||||
while (pls->n_main_streams < pls->ctx->nb_streams) {
|
||||
@@ -2224,6 +2225,11 @@ static int update_streams_from_subdemuxer(AVFormatContext *s, struct playlist *p
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Match the start_time of streams created before playback began. */
|
||||
if (c->first_timestamp != AV_NOPTS_VALUE)
|
||||
st->start_time = av_rescale_q(c->first_timestamp,
|
||||
AV_TIME_BASE_Q, st->time_base);
|
||||
|
||||
if (ist->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
|
||||
if (pls->timed_id3_stream_index < 0)
|
||||
pls->timed_id3_stream_index = ist_idx;
|
||||
@@ -2740,26 +2746,28 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
if (pls->ts_offset == AV_NOPTS_VALUE &&
|
||||
pls->pkt->dts != AV_NOPTS_VALUE) {
|
||||
/* Packet timestamp rebased onto the start of the segment list. */
|
||||
int64_t seg_idx = pls->cur_seq_no - pls->start_seq_no;
|
||||
int64_t ts = av_rescale_q(pls->pkt->dts,
|
||||
get_timebase(pls), AV_TIME_BASE_Q);
|
||||
int64_t ts = av_rescale_q(pls->pkt->pts != AV_NOPTS_VALUE ?
|
||||
pls->pkt->pts : pls->pkt->dts,
|
||||
get_timebase(pls), AV_TIME_BASE_Q);
|
||||
|
||||
/* EVENT playlists preserve all segments from the start */
|
||||
if (pls->type == PLS_TYPE_EVENT)
|
||||
for (int64_t k = 0; k < seg_idx && k < pls->n_segments; k++)
|
||||
ts -= pls->segments[k]->duration;
|
||||
for (int64_t k = 0; k < seg_idx && k < pls->n_segments; k++)
|
||||
ts -= pls->segments[k]->duration;
|
||||
|
||||
if (c->first_timestamp == AV_NOPTS_VALUE) {
|
||||
c->first_timestamp = ts;
|
||||
c->first_timestamp_pls = pls;
|
||||
|
||||
if (pls->type == PLS_TYPE_EVENT)
|
||||
for (unsigned k = 0; k < s->nb_streams; k++) {
|
||||
AVStream *st = s->streams[k];
|
||||
if (st->start_time == AV_NOPTS_VALUE)
|
||||
st->start_time = av_rescale_q(ts,
|
||||
AV_TIME_BASE_Q, st->time_base);
|
||||
}
|
||||
/* start_time is the start of the segment list, the
|
||||
* origin of the timeline used for seeking. */
|
||||
for (unsigned k = 0; k < s->nb_streams; k++)
|
||||
s->streams[k]->start_time =
|
||||
av_rescale_q(ts, AV_TIME_BASE_Q,
|
||||
s->streams[k]->time_base);
|
||||
av_log(s, AV_LOG_DEBUG,
|
||||
"First timestamp %"PRId64" from playlist %d\n",
|
||||
ts, pls->index);
|
||||
}
|
||||
pls->ts_offset = ts - c->first_timestamp;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ fate-hls-live-no-endlist: tests/data/live_no_endlist.m3u8
|
||||
fate-hls-live-no-endlist: SRC = $(TARGET_PATH)/tests/data/live_no_endlist.m3u8
|
||||
fate-hls-live-no-endlist: CMD = md5 -i $(SRC) -af hdcd=process_stereo=false -t 6 -f s24le
|
||||
fate-hls-live-no-endlist: CMP = oneline
|
||||
fate-hls-live-no-endlist: REF = e038bb8e65d4c1745b9b3ed643e607a3
|
||||
fate-hls-live-no-endlist: REF = d41d8cd98f00b204e9800998ecf8427e
|
||||
|
||||
tests/data/event_no_endlist.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data
|
||||
$(M)$(TARGET_EXEC) $(TARGET_PATH)/$< -nostdin \
|
||||
|
||||
@@ -2,19 +2,19 @@ ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st:-1 flags:1 ts:-0.105833
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
ret: 0 st: 0 flags:0 ts: 0.788333
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 ts: 1.682500
|
||||
ret: 0 st: 1 flags:0 dts: 1.600000 pts: 1.600000 pos: 8836 size: 2330
|
||||
ret: 0 st: 0 flags:1 dts: 1.698078 pts: 1.698078 pos: 11092 size: 1253
|
||||
ret: 0 st: 1 flags:0 ts: 2.576667
|
||||
ret: 0 st: 0 flags:1 dts: 2.586233 pts: 2.586233 pos: 55836 size: 1254
|
||||
ret: 0 st: 1 flags:1 ts: 3.470833
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
ret: 0 st:-1 flags:0 ts: 4.365002
|
||||
ret: 0 st: 0 flags:1 dts: 4.388689 pts: 4.388689 pos: 45308 size: 1254
|
||||
ret: 0 st:-1 flags:1 ts:-0.740831
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
ret: 0 st: 0 flags:0 ts: 0.153333
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 ts: 1.047500
|
||||
@@ -22,7 +22,7 @@ ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 1 flags:0 ts: 1.941667
|
||||
ret: 0 st: 0 flags:1 dts: 1.959300 pts: 1.959300 pos: 24252 size: 1254
|
||||
ret: 0 st: 1 flags:1 ts: 2.835833
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
ret: 0 st:-1 flags:0 ts: 3.730004
|
||||
ret: 0 st: 0 flags:1 dts: 3.735622 pts: 3.735622 pos: -1 size: 1254
|
||||
ret: 0 st:-1 flags:1 ts: 4.624171
|
||||
@@ -34,20 +34,20 @@ ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 1 flags:0 ts: 1.306667
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 1 flags:1 ts: 2.200844
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
ret: 0 st:-1 flags:0 ts: 3.095006
|
||||
ret: 0 st: 0 flags:1 dts: 3.108689 pts: 3.108689 pos: 82156 size: 1254
|
||||
ret: 0 st:-1 flags:1 ts: 3.989173
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
ret: 0 st: 0 flags:0 ts: 4.883344
|
||||
ret: 0 st: 1 flags:0 dts: 4.800000 pts: 5.100000 pos: 20492 size: 3860
|
||||
ret: 0 st: 0 flags:1 dts: 4.885011 pts: 4.885011 pos: -1 size: 1253
|
||||
ret: 0 st: 0 flags:1 ts:-0.222489
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 1 flags:0 ts: 0.671678
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 1 flags:1 ts: 1.565844
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
ret: 0 st:-1 flags:0 ts: 2.460008
|
||||
ret: 0 st: 0 flags:1 dts: 2.481744 pts: 2.481744 pos: 50572 size: 1254
|
||||
ret: 0 st:-1 flags:1 ts: 3.354175
|
||||
ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913
|
||||
ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254
|
||||
|
||||
Reference in New Issue
Block a user