summaryrefslogtreecommitdiff
path: root/libavformat/hls.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2013-07-29 10:26:02 +0300
committerMartin Storsjö <martin@martin.st>2013-07-29 20:15:50 +0300
commitc44191039944526dd7eb6e536990b555837961f5 (patch)
treee5452a60aa0b9bd70baec0320af2f6e97204bba0 /libavformat/hls.c
parente1d5b244761cf69db655ad7ece1dbf2c13dd4fce (diff)
hls: Store all durations in AV_TIME_BASE
Also parse segment durations as floating point, which is allowed since HLS version 3. This is based on a patch by Zhang Rui. Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavformat/hls.c')
-rw-r--r--libavformat/hls.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 5eb98c51a8..0c836c7536 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -56,7 +56,7 @@ enum KeyType {
};
struct segment {
- int duration;
+ int64_t duration;
char url[MAX_URL_SIZE];
char key[MAX_URL_SIZE];
enum KeyType key_type;
@@ -81,7 +81,7 @@ struct variant {
int stream_offset;
int finished;
- int target_duration;
+ int64_t target_duration;
int start_seq_no;
int n_segments;
struct segment **segments;
@@ -202,7 +202,8 @@ static void handle_key_args(struct key_info *info, const char *key,
static int parse_playlist(HLSContext *c, const char *url,
struct variant *var, AVIOContext *in)
{
- int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+ int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+ int64_t duration = 0;
enum KeyType key_type = KEY_NONE;
uint8_t iv[16] = "";
int has_iv = 0;
@@ -257,7 +258,7 @@ static int parse_playlist(HLSContext *c, const char *url,
goto fail;
}
}
- var->target_duration = atoi(ptr);
+ var->target_duration = atoi(ptr) * AV_TIME_BASE;
} else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
if (!var) {
var = new_variant(c, 0, url, NULL);
@@ -272,7 +273,7 @@ static int parse_playlist(HLSContext *c, const char *url,
var->finished = 1;
} else if (av_strstart(line, "#EXTINF:", &ptr)) {
is_segment = 1;
- duration = atoi(ptr);
+ duration = atof(ptr) * AV_TIME_BASE;
} else if (av_strstart(line, "#", NULL)) {
continue;
} else if (line[0]) {
@@ -383,7 +384,6 @@ restart:
int64_t reload_interval = v->n_segments > 0 ?
v->segments[v->n_segments - 1]->duration :
v->target_duration;
- reload_interval *= 1000000;
reload:
if (!v->finished &&
@@ -393,7 +393,7 @@ reload:
/* If we need to reload the playlist again below (if
* there's still no more segments), switch to a reload
* interval of half the target duration. */
- reload_interval = v->target_duration * 500000;
+ reload_interval = v->target_duration / 2;
}
if (v->cur_seq_no < v->start_seq_no) {
av_log(NULL, AV_LOG_WARNING,
@@ -481,7 +481,7 @@ static int hls_read_header(AVFormatContext *s)
int64_t duration = 0;
for (i = 0; i < c->variants[0]->n_segments; i++)
duration += c->variants[0]->segments[i]->duration;
- s->duration = duration * AV_TIME_BASE;
+ s->duration = duration;
}
/* Open the demuxer for each variant */
@@ -717,7 +717,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
s->streams[stream_index]->time_base.den,
flags & AVSEEK_FLAG_BACKWARD ?
AV_ROUND_DOWN : AV_ROUND_UP);
- timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
+ timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE, stream_index >= 0 ?
s->streams[stream_index]->time_base.den :
AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
AV_ROUND_DOWN : AV_ROUND_UP);
@@ -730,9 +730,8 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
for (i = 0; i < c->n_variants; i++) {
/* Reset reading */
struct variant *var = c->variants[i];
- int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
- av_rescale_rnd(c->first_timestamp, 1, AV_TIME_BASE,
- flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
+ int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
+ 0 : c->first_timestamp;
if (var->input) {
ffurl_close(var->input);
var->input = NULL;