[FFmpeg-devel] [PATCH v2] avformat/dashdec: control download speed when in live stream mode
Steven Liu
lq at chinaffmpeg.org
Fri Jan 11 05:45:55 EET 2019
fix ticket: 7369
check the duration is less than the fragment duration,
retry when the condition is true.
don't control the download speed when reading header
Signed-off-by: Steven Liu <lq at chinaffmpeg.org>
---
libavformat/dashdec.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index f4f4e935de..473adb9bfb 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -108,6 +108,7 @@ struct representation {
int64_t cur_seg_offset;
int64_t cur_seg_size;
struct fragment *cur_seg;
+ int64_t last_load_time;
/* Currently active Media Initialization Section */
struct fragment *init_section;
@@ -121,6 +122,9 @@ struct representation {
typedef struct DASHContext {
const AVClass *class;
+
+ int read_init_sections;
+
char *base_url;
char *adaptionset_contenttype_val;
char *adaptionset_par_val;
@@ -1084,6 +1088,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
}
}
+ if (rep)
+ rep->last_load_time = get_current_time_in_sec();
video_rep_idx += type == AVMEDIA_TYPE_VIDEO;
audio_rep_idx += type == AVMEDIA_TYPE_AUDIO;
subtitle_rep_idx += type == AVMEDIA_TYPE_SUBTITLE;
@@ -1382,6 +1388,9 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls)
} else {
num = pls->first_seq_no;
}
+
+ if (pls)
+ pls->last_load_time = get_current_time_in_sec();
return num;
}
@@ -1461,6 +1470,7 @@ static int refresh_manifest(AVFormatContext *s)
{
int ret = 0, i;
+ int64_t cur_time = get_current_time_in_sec();
DASHContext *c = s->priv_data;
// save current context
@@ -1505,6 +1515,11 @@ static int refresh_manifest(AVFormatContext *s)
for (i = 0; i < n_videos; i++) {
struct representation *cur_video = videos[i];
struct representation *ccur_video = c->videos[i];
+ if (cur_video)
+ cur_video->last_load_time = cur_time;
+ if (ccur_video)
+ ccur_video->last_load_time = cur_time;
+
if (cur_video->timelines) {
// calc current time
int64_t currentTime = get_segment_start_time_based_on_timeline(cur_video, cur_video->cur_seq_no) / cur_video->fragment_timescale;
@@ -1521,6 +1536,11 @@ static int refresh_manifest(AVFormatContext *s)
for (i = 0; i < n_audios; i++) {
struct representation *cur_audio = audios[i];
struct representation *ccur_audio = c->audios[i];
+ if (cur_audio)
+ cur_audio->last_load_time = cur_time;
+ if (ccur_audio)
+ ccur_audio->last_load_time = cur_time;
+
if (cur_audio->timelines) {
// calc current time
int64_t currentTime = get_segment_start_time_based_on_timeline(cur_audio, cur_audio->cur_seq_no) / cur_audio->fragment_timescale;
@@ -1629,6 +1649,8 @@ static struct fragment *get_current_fragment(struct representation *pls)
av_free(tmpfilename);
seg->size = -1;
}
+ if (pls)
+ pls->last_load_time = get_current_time_in_sec();
return seg;
}
@@ -1747,6 +1769,11 @@ static int read_data(void *opaque, uint8_t *buf, int buf_size)
DASHContext *c = v->parent->priv_data;
restart:
+ if (!c->read_init_sections && c->is_live && v->fragment_duration != 0 && v->fragment_timescale != 0)
+ if (get_current_time_in_sec() - v->last_load_time < (v->fragment_duration / v->fragment_timescale)) {
+ av_usleep(100*1000);
+ goto restart;
+ }
if (!v->input) {
free_fragment(&v->cur_seg);
v->cur_seg = get_current_fragment(v);
@@ -2002,6 +2029,7 @@ static int dash_read_header(AVFormatContext *s)
av_dict_set(&c->avio_opts, "seekable", "0", 0);
+ c->read_init_sections = 1;
if ((ret = parse_manifest(s, s->url, s->pb)) < 0)
goto fail;
@@ -2146,6 +2174,7 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt)
recheck_discard_flags(s, c->audios, c->n_audios);
recheck_discard_flags(s, c->subtitles, c->n_subtitles);
+ c->read_init_sections = 0;
for (i = 0; i < c->n_videos; i++) {
struct representation *pls = c->videos[i];
if (!pls->ctx)
--
2.15.2 (Apple Git-101.1)
More information about the ffmpeg-devel
mailing list