Fix seeking when using Apple HTTP Live Streaming

The Apple HTTP Live Streaming demuxer's implementation of seeking searches for
the MPEG TS segment which contains the requested timestamp.  In its current
implementation it assumes that the first segment will start from 0.

But, MPEG TS streams do not necessarily start with timestamp (near) 0, causing
seeking to fail for those streams.

This also occurs when using live streaming of HTTP Live Streams. In this case
sliding playlists may be used, which means that in that case only the last x
encoded segments are stored, the earlier segments get deleted from disk and
removed from the playlist. Because of this, when starting playback of a stream
in the middle of such a broadcast, the initial segment fetched after parsing
the m3u8 playlist will not start from timestamp (near) 0, causing (the
admittedly limited live) seeking to fail.

This patch changes this demuxers seeking implementation to use the initial DTS
as an offset for searching the segments containing the requested timestamp.
parent bf0ca404
...@@ -99,6 +99,7 @@ typedef struct AppleHTTPContext { ...@@ -99,6 +99,7 @@ typedef struct AppleHTTPContext {
int cur_seq_no; int cur_seq_no;
int end_of_segment; int end_of_segment;
int first_packet; int first_packet;
int64_t first_timestamp;
AVIOInterruptCB *interrupt_callback; AVIOInterruptCB *interrupt_callback;
} AppleHTTPContext; } AppleHTTPContext;
...@@ -527,6 +528,7 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap) ...@@ -527,6 +528,7 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
} }
c->first_packet = 1; c->first_packet = 1;
c->first_timestamp = AV_NOPTS_VALUE;
return 0; return 0;
fail: fail:
...@@ -591,6 +593,9 @@ start: ...@@ -591,6 +593,9 @@ start:
if (!url_feof(&var->pb)) if (!url_feof(&var->pb))
return ret; return ret;
reset_packet(&var->pkt); reset_packet(&var->pkt);
} else {
if (c->first_timestamp == AV_NOPTS_VALUE)
c->first_timestamp = var->pkt.dts;
} }
} }
/* Check if this stream has the packet with the lowest dts */ /* Check if this stream has the packet with the lowest dts */
...@@ -639,7 +644,10 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index, ...@@ -639,7 +644,10 @@ static int applehttp_read_seek(AVFormatContext *s, int stream_index,
for (i = 0; i < c->n_variants; i++) { for (i = 0; i < c->n_variants; i++) {
/* Reset reading */ /* Reset reading */
struct variant *var = c->variants[i]; struct variant *var = c->variants[i];
int64_t pos = 0; int64_t pos = av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ?
s->streams[stream_index]->time_base.den :
AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
AV_ROUND_DOWN : AV_ROUND_UP);
if (var->input) { if (var->input) {
ffurl_close(var->input); ffurl_close(var->input);
var->input = NULL; var->input = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment